diff options
Diffstat (limited to 'WebCore/platform/graphics/mac')
25 files changed, 0 insertions, 4630 deletions
diff --git a/WebCore/platform/graphics/mac/ColorMac.h b/WebCore/platform/graphics/mac/ColorMac.h deleted file mode 100644 index 3be9094..0000000 --- a/WebCore/platform/graphics/mac/ColorMac.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2007 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of Apple Inc. ("Apple") 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 APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 ColorMac_h -#define ColorMac_h - -#include "Color.h" - -#ifdef __OBJC__ -@class NSColor; -#else -class NSColor; -#endif - -namespace WebCore { - - Color colorFromNSColor(NSColor *); - NSColor* nsColor(const Color&); - - bool usesTestModeFocusRingColor(); - void setUsesTestModeFocusRingColor(bool); - -} - -#endif diff --git a/WebCore/platform/graphics/mac/ColorMac.mm b/WebCore/platform/graphics/mac/ColorMac.mm deleted file mode 100644 index 96fdc39..0000000 --- a/WebCore/platform/graphics/mac/ColorMac.mm +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. - */ - -#import "config.h" -#import "Color.h" -#import "ColorMac.h" - -#import <wtf/Assertions.h> -#import <wtf/RetainPtr.h> - -@interface WebCoreControlTintObserver : NSObject -+ (void)controlTintDidChange; -@end - -namespace WebCore { - -// NSColor calls don't throw, so no need to block Cocoa exceptions in this file - -static RGBA32 oldAquaFocusRingColor = 0xFF7DADD9; -static RGBA32 systemFocusRingColor; -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])); -} - -Color colorFromNSColor(NSColor *c) -{ - return Color(makeRGBAFromNSColor(c)); -} - -NSColor* nsColor(const Color& color) -{ - unsigned c = color.rgb(); - switch (c) { - case 0: { - // Need this to avoid returning nil because cachedRGBAValues will default to 0. - static RetainPtr<NSColor> clearColor = [NSColor clearColor]; - return clearColor.get(); - } - case Color::black: { - static RetainPtr<NSColor> blackColor = [NSColor blackColor]; - return blackColor.get(); - } - case Color::white: { - static RetainPtr<NSColor> whiteColor = [NSColor whiteColor]; - return whiteColor.get(); - } - default: { - const int cacheSize = 32; - static unsigned cachedRGBAValues[cacheSize]; - static RetainPtr<NSColor> cachedColors[cacheSize]; - - for (int i = 0; i != cacheSize; ++i) - if (cachedRGBAValues[i] == c) - return cachedColors[i].get(); - -#ifdef COLORMATCH_EVERYTHING - NSColor* result = [NSColor colorWithCalibratedRed:color.red() / 255.0f - green:color.green() / 255.0f - blue:color.blue() / 255.0f - alpha:color.alpha() /255.0f]; -#else - NSColor* result = [NSColor colorWithDeviceRed:color.red() / 255.0f - green:color.green() / 255.0f - blue:color.blue() / 255.0f - alpha:color.alpha() /255.0f]; -#endif - - static int cursor; - cachedRGBAValues[cursor] = c; - cachedColors[cursor] = result; - if (++cursor == cacheSize) - cursor = 0; - return result; - } - } -} - -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 }; - static CGColorSpaceRef deviceRGBColorSpace = CGColorSpaceCreateDeviceRGB(); - CGColorRef cgColor = CGColorCreate(deviceRGBColorSpace, components); - return cgColor; -} - -CGColorRef cgColor(const Color& c) -{ - // We could directly create a CGColor here, but that would - // skip any RGB caching the nsColor method does. A direct - // creation could be investigated for a possible performance win. - return CGColorFromNSColor(nsColor(c)); -} - -Color focusRingColor() -{ - static bool tintIsKnown = false; - if (!tintIsKnown) { - [[NSNotificationCenter defaultCenter] addObserver:[WebCoreControlTintObserver class] - selector:@selector(controlTintDidChange) - name:NSControlTintDidChangeNotification - object:NSApp]; - [WebCoreControlTintObserver controlTintDidChange]; - tintIsKnown = true; - } - - if (usesTestModeFocusRingColor()) - return oldAquaFocusRingColor; - - return systemFocusRingColor; -} - -bool usesTestModeFocusRingColor() -{ - return useOldAquaFocusRingColor; -} - -void setUsesTestModeFocusRingColor(bool newValue) -{ - useOldAquaFocusRingColor = newValue; -} - -} - -@implementation WebCoreControlTintObserver - -+ (void)controlTintDidChange -{ -#ifdef COLORMATCH_EVERYTHING -#error Not yet implemented. -#else - NSColor* color = [[NSColor keyboardFocusIndicatorColor] colorUsingColorSpaceName:NSDeviceRGBColorSpace]; - WebCore::systemFocusRingColor = WebCore::makeRGBAFromNSColor(color); -#endif -} - -@end diff --git a/WebCore/platform/graphics/mac/CoreTextController.cpp b/WebCore/platform/graphics/mac/CoreTextController.cpp deleted file mode 100644 index 171a7ec..0000000 --- a/WebCore/platform/graphics/mac/CoreTextController.cpp +++ /dev/null @@ -1,533 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 "config.h" -#include "CoreTextController.h" - -#if USE(CORE_TEXT) - -#include "CharacterNames.h" -#include "Font.h" -#include "FontCache.h" -#include "SimpleFontData.h" -#include "TextBreakIterator.h" -#include <wtf/MathExtras.h> - -using namespace std; - -namespace WebCore { - -static inline CGFloat roundCGFloat(CGFloat f) -{ - if (sizeof(CGFloat) == sizeof(float)) - return roundf(static_cast<float>(f)); - return static_cast<CGFloat>(round(f)); -} - -static inline CGFloat ceilCGFloat(CGFloat f) -{ - if (sizeof(CGFloat) == sizeof(float)) - return ceilf(static_cast<float>(f)); - return static_cast<CGFloat>(ceil(f)); -} - -CoreTextController::CoreTextRun::CoreTextRun(CTRunRef ctRun, const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength) - : m_CTRun(ctRun) - , m_fontData(fontData) - , m_characters(characters) - , m_stringLocation(stringLocation) - , m_stringLength(stringLength) -{ - m_glyphCount = CTRunGetGlyphCount(ctRun); - m_indices = CTRunGetStringIndicesPtr(ctRun); - if (!m_indices) { - m_indicesData.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, m_glyphCount * sizeof(CFIndex))); - CFDataIncreaseLength(m_indicesData.get(), m_glyphCount * sizeof(CFIndex)); - m_indices = reinterpret_cast<const CFIndex*>(CFDataGetMutableBytePtr(m_indicesData.get())); - CTRunGetStringIndices(ctRun, CFRangeMake(0, 0), const_cast<CFIndex*>(m_indices)); - } -} - -// Missing glyphs run constructor. Core Text will not generate a run of missing glyphs, instead falling back on -// glyphs from LastResort. We want to use the primary font's missing glyph in order to match the fast text code path. -CoreTextController::CoreTextRun::CoreTextRun(const SimpleFontData* fontData, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr) - : m_fontData(fontData) - , m_characters(characters) - , m_stringLocation(stringLocation) - , m_stringLength(stringLength) -{ - Vector<CFIndex, 16> indices; - unsigned r = 0; - while (r < stringLength) { - indices.append(r); - if (U_IS_SURROGATE(characters[r])) { - ASSERT(r + 1 < stringLength); - ASSERT(U_IS_SURROGATE_LEAD(characters[r])); - ASSERT(U_IS_TRAIL(characters[r + 1])); - r += 2; - } else - r++; - } - m_glyphCount = indices.size(); - if (!ltr) { - for (unsigned r = 0, end = m_glyphCount - 1; r < m_glyphCount / 2; ++r, --end) - std::swap(indices[r], indices[end]); - } - m_indicesData.adoptCF(CFDataCreateMutable(kCFAllocatorDefault, m_glyphCount * sizeof(CFIndex))); - CFDataAppendBytes(m_indicesData.get(), reinterpret_cast<const UInt8*>(indices.data()), m_glyphCount * sizeof(CFIndex)); - m_indices = reinterpret_cast<const CFIndex*>(CFDataGetBytePtr(m_indicesData.get())); -} - -CoreTextController::CoreTextController(const Font* font, const TextRun& run, bool mayUseNaturalWritingDirection) - : m_font(*font) - , m_run(run) - , m_mayUseNaturalWritingDirection(mayUseNaturalWritingDirection) - , m_currentCharacter(0) - , m_end(run.length()) - , m_totalWidth(0) - , m_runWidthSoFar(0) - , m_numGlyphsSoFar(0) - , m_currentRun(0) - , m_glyphInCurrentRun(0) - , m_finalRoundingWidth(0) - , m_lastRoundingGlyph(0) -{ - m_padding = m_run.padding(); - if (!m_padding) - m_padPerSpace = 0; - else { - float numSpaces = 0; - for (int s = 0; s < m_run.length(); s++) - if (Font::treatAsSpace(m_run[s])) - numSpaces++; - - if (numSpaces == 0) - m_padPerSpace = 0; - else - m_padPerSpace = ceilf(m_run.padding() / numSpaces); - } - - collectCoreTextRuns(); - adjustGlyphsAndAdvances(); -} - -int CoreTextController::offsetForPosition(int h, bool includePartialGlyphs) -{ - // FIXME: For positions occurring within a ligature, we should return the closest "ligature caret" or - // approximate it by dividing the width of the ligature by the number of characters it encompasses. - // However, Core Text does not expose a low-level API for directly finding - // out how many characters a ligature encompasses (the "attachment count"). - if (h >= m_totalWidth) - return m_run.ltr() ? m_end : 0; - if (h < 0) - return m_run.ltr() ? 0 : m_end; - - CGFloat x = h; - - size_t runCount = m_coreTextRuns.size(); - size_t offsetIntoAdjustedGlyphs = 0; - - for (size_t r = 0; r < runCount; ++r) { - const CoreTextRun& coreTextRun = m_coreTextRuns[r]; - for (unsigned j = 0; j < coreTextRun.glyphCount(); ++j) { - CGFloat adjustedAdvance = m_adjustedAdvances[offsetIntoAdjustedGlyphs + j].width; - if (x <= adjustedAdvance) { - CFIndex hitIndex = coreTextRun.indexAt(j); - int stringLength = coreTextRun.stringLength(); - TextBreakIterator* characterIterator = characterBreakIterator(coreTextRun.characters(), stringLength); - int clusterStart; - if (isTextBreak(characterIterator, hitIndex)) - clusterStart = hitIndex; - else { - clusterStart = textBreakPreceding(characterIterator, hitIndex); - if (clusterStart == TextBreakDone) - clusterStart = 0; - } - - if (!includePartialGlyphs) - return coreTextRun.stringLocation() + clusterStart; - - int clusterEnd = textBreakFollowing(characterIterator, hitIndex); - if (clusterEnd == TextBreakDone) - clusterEnd = stringLength; - - CGFloat clusterWidth = adjustedAdvance; - // FIXME: The search stops at the boundaries of coreTextRun. In theory, it should go on into neighboring CoreTextRuns - // derived from the same CTLine. In practice, we do not expect there to be more than one CTRun in a CTLine, as no - // 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) { - CGFloat width = m_adjustedAdvances[offsetIntoAdjustedGlyphs + firstGlyphBeforeCluster].width; - clusterWidth += width; - x += width; - firstGlyphBeforeCluster--; - } - unsigned firstGlyphAfterCluster = j + 1; - while (firstGlyphAfterCluster < coreTextRun.glyphCount() && coreTextRun.indexAt(firstGlyphAfterCluster) >= clusterStart && coreTextRun.indexAt(firstGlyphAfterCluster) < clusterEnd) { - clusterWidth += m_adjustedAdvances[offsetIntoAdjustedGlyphs + firstGlyphAfterCluster].width; - firstGlyphAfterCluster++; - } - } - if (x <= clusterWidth / 2) - return coreTextRun.stringLocation() + (m_run.ltr() ? clusterStart : clusterEnd); - else - return coreTextRun.stringLocation() + (m_run.ltr() ? clusterEnd : clusterStart); - } - x -= adjustedAdvance; - } - offsetIntoAdjustedGlyphs += coreTextRun.glyphCount(); - } - - ASSERT_NOT_REACHED(); - return 0; -} - -void CoreTextController::collectCoreTextRuns() -{ - if (!m_end) - return; - - // We break up glyph run generation for the string by FontData and (if needed) the use of small caps. - const UChar* cp = m_run.characters(); - bool hasTrailingSoftHyphen = m_run[m_end - 1] == softHyphen; - - if (m_font.isSmallCaps() || hasTrailingSoftHyphen) - m_smallCapsBuffer.resize(m_end); - - unsigned indexOfFontTransition = m_run.rtl() ? m_end - 1 : 0; - const UChar* curr = m_run.rtl() ? cp + m_end - 1 : cp; - const UChar* end = m_run.rtl() ? cp - 1 : cp + m_end; - - // FIXME: Using HYPHEN-MINUS rather than HYPHEN because Times has a HYPHEN-MINUS glyph that looks like its - // SOFT-HYPHEN glyph, and has no HYPHEN glyph. - static const UChar hyphen = '-'; - - if (hasTrailingSoftHyphen && m_run.rtl()) { - collectCoreTextRunsForCharacters(&hyphen, 1, m_end - 1, m_font.glyphDataForCharacter(hyphen, false).fontData); - indexOfFontTransition--; - curr--; - } - - GlyphData glyphData; - GlyphData nextGlyphData; - - bool isSurrogate = U16_IS_SURROGATE(*curr); - if (isSurrogate) { - if (m_run.ltr()) { - if (!U16_IS_SURROGATE_LEAD(curr[0]) || curr + 1 == end || !U16_IS_TRAIL(curr[1])) - return; - nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[0], curr[1]), false); - } else { - if (!U16_IS_TRAIL(curr[0]) || curr -1 == end || !U16_IS_SURROGATE_LEAD(curr[-1])) - return; - nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[-1], curr[0]), false); - } - } else - nextGlyphData = m_font.glyphDataForCharacter(*curr, false); - - UChar newC = 0; - - bool isSmallCaps; - bool nextIsSmallCaps = !isSurrogate && m_font.isSmallCaps() && !(U_GET_GC_MASK(*curr) & U_GC_M_MASK) && (newC = u_toupper(*curr)) != *curr; - - if (nextIsSmallCaps) - m_smallCapsBuffer[curr - cp] = newC; - - while (true) { - curr = m_run.rtl() ? curr - (isSurrogate ? 2 : 1) : curr + (isSurrogate ? 2 : 1); - if (curr == end) - break; - - glyphData = nextGlyphData; - isSmallCaps = nextIsSmallCaps; - int index = curr - cp; - isSurrogate = U16_IS_SURROGATE(*curr); - UChar c = *curr; - bool forceSmallCaps = !isSurrogate && isSmallCaps && (U_GET_GC_MASK(c) & U_GC_M_MASK); - if (isSurrogate) { - if (m_run.ltr()) { - if (!U16_IS_SURROGATE_LEAD(curr[0]) || curr + 1 == end || !U16_IS_TRAIL(curr[1])) - return; - nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[0], curr[1]), false); - } else { - if (!U16_IS_TRAIL(curr[0]) || curr -1 == end || !U16_IS_SURROGATE_LEAD(curr[-1])) - return; - nextGlyphData = m_font.glyphDataForCharacter(U16_GET_SUPPLEMENTARY(curr[-1], curr[0]), false); - } - } else - nextGlyphData = m_font.glyphDataForCharacter(*curr, false, forceSmallCaps); - - if (!isSurrogate && m_font.isSmallCaps()) { - nextIsSmallCaps = forceSmallCaps || (newC = u_toupper(c)) != c; - if (nextIsSmallCaps) - m_smallCapsBuffer[index] = forceSmallCaps ? c : newC; - } - - if (nextGlyphData.fontData != glyphData.fontData || nextIsSmallCaps != isSmallCaps || !nextGlyphData.glyph != !glyphData.glyph) { - int itemStart = m_run.rtl() ? index + 1 : indexOfFontTransition; - int itemLength = m_run.rtl() ? indexOfFontTransition - index : index - indexOfFontTransition; - collectCoreTextRunsForCharacters((isSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, glyphData.glyph ? glyphData.fontData : 0); - indexOfFontTransition = index; - } - } - - int itemLength = m_run.rtl() ? indexOfFontTransition + 1 : m_end - indexOfFontTransition - (hasTrailingSoftHyphen ? 1 : 0); - if (itemLength) { - int itemStart = m_run.rtl() ? 0 : indexOfFontTransition; - collectCoreTextRunsForCharacters((nextIsSmallCaps ? m_smallCapsBuffer.data() : cp) + itemStart, itemLength, itemStart, nextGlyphData.glyph ? nextGlyphData.fontData : 0); - } - - if (hasTrailingSoftHyphen && m_run.ltr()) - collectCoreTextRunsForCharacters(&hyphen, 1, m_end - 1, m_font.glyphDataForCharacter(hyphen, false).fontData); -} - -void CoreTextController::advance(unsigned offset, GlyphBuffer* glyphBuffer) -{ - // FIXME: For offsets falling inside a ligature, we should advance only as far as the appropriate "ligature caret" - // or divide the width of the ligature by the number of offsets it encompasses and make an advance proportional - // to the offsets into the ligature. However, Core Text does not expose a low-level API for - // directly finding out how many characters a ligature encompasses (the "attachment count"). - if (static_cast<int>(offset) > m_end) - offset = m_end; - - if (offset <= m_currentCharacter) - return; - - m_currentCharacter = offset; - - size_t runCount = m_coreTextRuns.size(); - - bool ltr = m_run.ltr(); - - unsigned k = ltr ? m_numGlyphsSoFar : m_adjustedGlyphs.size() - 1 - m_numGlyphsSoFar; - while (m_currentRun < runCount) { - const CoreTextRun& coreTextRun = m_coreTextRuns[ltr ? m_currentRun : runCount - 1 - m_currentRun]; - size_t glyphCount = coreTextRun.glyphCount(); - unsigned g = ltr ? m_glyphInCurrentRun : glyphCount - 1 - m_glyphInCurrentRun; - while (m_glyphInCurrentRun < glyphCount) { - if (coreTextRun.indexAt(g) + coreTextRun.stringLocation() >= m_currentCharacter) - return; - CGSize adjustedAdvance = m_adjustedAdvances[k]; - if (glyphBuffer) - glyphBuffer->add(m_adjustedGlyphs[k], coreTextRun.fontData(), adjustedAdvance); - m_runWidthSoFar += adjustedAdvance.width; - m_numGlyphsSoFar++; - m_glyphInCurrentRun++; - if (ltr) { - g++; - k++; - } else { - g--; - k--; - } - } - m_currentRun++; - m_glyphInCurrentRun = 0; - } - if (!ltr && m_numGlyphsSoFar == m_adjustedAdvances.size()) - m_runWidthSoFar += m_finalRoundingWidth; -} - -void CoreTextController::collectCoreTextRunsForCharacters(const UChar* cp, unsigned length, unsigned stringLocation, const SimpleFontData* fontData) -{ - if (!fontData) { - // Create a run of missing glyphs from the primary font. - m_coreTextRuns.append(CoreTextRun(m_font.primaryFont(), cp, stringLocation, length, m_run.ltr())); - return; - } - - RetainPtr<CFStringRef> string(AdoptCF, CFStringCreateWithCharactersNoCopy(NULL, cp, length, kCFAllocatorNull)); - - RetainPtr<CFAttributedStringRef> attributedString(AdoptCF, CFAttributedStringCreate(NULL, string.get(), fontData->getCFStringAttributes())); - - RetainPtr<CTTypesetterRef> typesetter; - - if (!m_mayUseNaturalWritingDirection || m_run.directionalOverride()) { - static const void* optionKeys[] = { kCTTypesetterOptionForcedEmbeddingLevel }; - static const void* ltrOptionValues[] = { kCFBooleanFalse }; - static const void* rtlOptionValues[] = { kCFBooleanTrue }; - static RetainPtr<CFDictionaryRef> ltrTypesetterOptions(AdoptCF, CFDictionaryCreate(kCFAllocatorDefault, optionKeys, ltrOptionValues, sizeof(optionKeys) / sizeof(*optionKeys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - static RetainPtr<CFDictionaryRef> rtlTypesetterOptions(AdoptCF, CFDictionaryCreate(kCFAllocatorDefault, optionKeys, rtlOptionValues, sizeof(optionKeys) / sizeof(*optionKeys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - typesetter.adoptCF(CTTypesetterCreateWithAttributedStringAndOptions(attributedString.get(), m_run.ltr() ? ltrTypesetterOptions.get() : rtlTypesetterOptions.get())); - } else - typesetter.adoptCF(CTTypesetterCreateWithAttributedString(attributedString.get())); - - RetainPtr<CTLineRef> line(AdoptCF, CTTypesetterCreateLine(typesetter.get(), CFRangeMake(0, 0))); - - CFArrayRef runArray = CTLineGetGlyphRuns(line.get()); - - CFIndex runCount = CFArrayGetCount(runArray); - - for (CFIndex r = 0; r < runCount; r++) { - CTRunRef ctRun = static_cast<CTRunRef>(CFArrayGetValueAtIndex(runArray, r)); - ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID()); - m_coreTextRuns.append(CoreTextRun(ctRun, fontData, cp, stringLocation, length)); - } -} - -void CoreTextController::adjustGlyphsAndAdvances() -{ - size_t runCount = m_coreTextRuns.size(); - for (size_t r = 0; r < runCount; ++r) { - const CoreTextRun& coreTextRun = m_coreTextRuns[r]; - unsigned glyphCount = coreTextRun.glyphCount(); - const SimpleFontData* fontData = coreTextRun.fontData(); - - Vector<CGGlyph, 256> glyphsVector; - const CGGlyph* glyphs; - - Vector<CGSize, 256> advancesVector; - const CGSize* advances; - - if (coreTextRun.ctRun()) { - glyphs = CTRunGetGlyphsPtr(coreTextRun.ctRun()); - if (!glyphs) { - glyphsVector.grow(glyphCount); - CTRunGetGlyphs(coreTextRun.ctRun(), CFRangeMake(0, 0), glyphsVector.data()); - glyphs = glyphsVector.data(); - } - - advances = CTRunGetAdvancesPtr(coreTextRun.ctRun()); - if (!advances) { - advancesVector.grow(glyphCount); - CTRunGetAdvances(coreTextRun.ctRun(), CFRangeMake(0, 0), advancesVector.data()); - advances = advancesVector.data(); - } - } else { - // Synthesize a run of missing glyphs. - glyphsVector.fill(0, glyphCount); - glyphs = glyphsVector.data(); - advancesVector.fill(CGSizeMake(fontData->widthForGlyph(0), 0), glyphCount); - advances = advancesVector.data(); - } - - bool lastRun = r + 1 == runCount; - const UChar* cp = coreTextRun.characters(); - CGFloat roundedSpaceWidth = roundCGFloat(fontData->m_spaceWidth); - bool roundsAdvances = !m_font.isPrinterFont() && fontData->platformData().roundsGlyphAdvances(); - bool hasExtraSpacing = (m_font.letterSpacing() || m_font.wordSpacing() || m_padding) && !m_run.spacingDisabled(); - - - for (unsigned i = 0; i < glyphCount; i++) { - CFIndex characterIndex = coreTextRun.indexAt(i); - UChar ch = *(cp + characterIndex); - bool lastGlyph = lastRun && i + 1 == glyphCount; - UChar nextCh; - if (lastGlyph) - nextCh = ' '; - else if (i + 1 < glyphCount) - nextCh = *(cp + coreTextRun.indexAt(i + 1)); - else - 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]; - - 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; - } - - float roundedAdvanceWidth = roundf(advance.width); - if (roundsAdvances) - advance.width = roundedAdvanceWidth; - - advance.width += fontData->m_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 (hasExtraSpacing) { - // If we're a glyph with an advance, go ahead and add in letter-spacing. - // That way we weed out zero width lurkers. This behavior matches the fast text code path. - if (advance.width && m_font.letterSpacing()) - advance.width += m_font.letterSpacing(); - - // Handle justification and word-spacing. - if (glyph == fontData->m_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) { - // Use leftover padding if not evenly divisible by number of spaces. - if (m_padding < m_padPerSpace) { - advance.width += m_padding; - m_padding = 0; - } else { - advance.width += m_padPerSpace; - m_padding -= m_padPerSpace; - } - } - - // Account for word-spacing. - if (treatAsSpace && characterIndex > 0 && !Font::treatAsSpace(*m_run.data(characterIndex - 1)) && m_font.wordSpacing()) - advance.width += m_font.wordSpacing(); - } - } - - // Deal with the float/integer impedance mismatch between CG and WebCore. "Words" (characters - // followed by a character defined by isRoundingHackCharacter()) are always an integer width. - // We adjust the width of the last character of a "word" to ensure an integer width. - // Force characters that are used to determine word boundaries for the rounding hack - // to be integer width, so the following words will start on an integer boundary. - if (m_run.applyWordRounding() && Font::isRoundingHackCharacter(ch)) - advance.width = ceilCGFloat(advance.width); - - // Check to see if the next character is a "rounding hack character", if so, adjust the - // width so that the total run width will be on an integer boundary. - if (m_run.applyWordRounding() && !lastGlyph && Font::isRoundingHackCharacter(nextCh) || m_run.applyRunRounding() && lastGlyph) { - CGFloat totalWidth = m_totalWidth + advance.width; - CGFloat extraWidth = ceilCGFloat(totalWidth) - totalWidth; - if (m_run.ltr()) - advance.width += extraWidth; - else { - m_totalWidth += extraWidth; - if (m_lastRoundingGlyph) - m_adjustedAdvances[m_lastRoundingGlyph - 1].width += extraWidth; - else - m_finalRoundingWidth = extraWidth; - m_lastRoundingGlyph = m_adjustedAdvances.size() + 1; - } - } - - m_totalWidth += advance.width; - advance.height *= -1; - m_adjustedAdvances.append(advance); - m_adjustedGlyphs.append(glyph); - } - } -} - -} // namespace WebCore - -#endif // USE(CORE_TEXT) diff --git a/WebCore/platform/graphics/mac/CoreTextController.h b/WebCore/platform/graphics/mac/CoreTextController.h deleted file mode 100644 index 8dbb7fb..0000000 --- a/WebCore/platform/graphics/mac/CoreTextController.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 APPLE INC. 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 CoreTextController_h -#define CoreTextController_h - -#if USE(CORE_TEXT) - -#include "Font.h" -#include "GlyphBuffer.h" -#include <wtf/RetainPtr.h> -#include <wtf/Vector.h> - -namespace WebCore { - -class CoreTextController { -public: - CoreTextController(const Font*, const TextRun&, bool mayUseNaturalWritingDirection = false); - - // Advance and emit glyphs up to the specified character. - void advance(unsigned to, GlyphBuffer* = 0); - - // Compute the character offset for a given x coordinate. - int offsetForPosition(int x, bool includePartialGlyphs); - - // Returns the width of everything we've consumed so far. - float runWidthSoFar() const { return m_runWidthSoFar; } - - float totalWidth() const { return m_totalWidth; } - - // Extra width to the left of the leftmost glyph. - float finalRoundingWidth() const { return m_finalRoundingWidth; } - -private: - class CoreTextRun { - public: - CoreTextRun(CTRunRef, const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength); - CoreTextRun(const SimpleFontData*, const UChar* characters, unsigned stringLocation, size_t stringLength, bool ltr); - - CTRunRef ctRun() const { return m_CTRun.get(); } - unsigned glyphCount() const { return m_glyphCount; } - const SimpleFontData* fontData() const { return m_fontData; } - const UChar* characters() const { return m_characters; } - unsigned stringLocation() const { return m_stringLocation; } - size_t stringLength() const { return m_stringLength; } - CFIndex indexAt(size_t i) const { return m_indices[i]; } - - private: - RetainPtr<CTRunRef> m_CTRun; - unsigned m_glyphCount; - const SimpleFontData* m_fontData; - const UChar* m_characters; - unsigned m_stringLocation; - size_t m_stringLength; - const CFIndex* m_indices; - // Used only if CTRunGet*Ptr fails or if this is a missing glyphs run. - RetainPtr<CFMutableDataRef> m_indicesData; - }; - - void collectCoreTextRuns(); - void collectCoreTextRunsForCharacters(const UChar*, unsigned length, unsigned stringLocation, const SimpleFontData*); - void adjustGlyphsAndAdvances(); - - const Font& m_font; - const TextRun& m_run; - bool m_mayUseNaturalWritingDirection; - - Vector<UChar, 256> m_smallCapsBuffer; - - Vector<CoreTextRun, 16> m_coreTextRuns; - Vector<CGSize, 256> m_adjustedAdvances; - Vector<CGGlyph, 256> m_adjustedGlyphs; - - unsigned m_currentCharacter; - int m_end; - - CGFloat m_totalWidth; - - float m_runWidthSoFar; - unsigned m_numGlyphsSoFar; - size_t m_currentRun; - unsigned m_glyphInCurrentRun; - float m_finalRoundingWidth; - float m_padding; - float m_padPerSpace; - - unsigned m_lastRoundingGlyph; -}; - -} // namespace WebCore -#endif // USE(CORE_TEXT) -#endif // CoreTextController_h diff --git a/WebCore/platform/graphics/mac/FloatPointMac.mm b/WebCore/platform/graphics/mac/FloatPointMac.mm deleted file mode 100644 index 2f73314..0000000 --- a/WebCore/platform/graphics/mac/FloatPointMac.mm +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2004, 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2005 Nokia. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h" -#include "FloatPoint.h" - -namespace WebCore { - -#ifndef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - -FloatPoint::FloatPoint(const NSPoint& p) : m_x(p.x), m_y(p.y) -{ -} - -FloatPoint::operator NSPoint() const -{ - return NSMakePoint(m_x, m_y); -} - -#endif - -} diff --git a/WebCore/platform/graphics/mac/FloatRectMac.mm b/WebCore/platform/graphics/mac/FloatRectMac.mm deleted file mode 100644 index 1d6b045..0000000 --- a/WebCore/platform/graphics/mac/FloatRectMac.mm +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2005 Nokia. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h" -#include "FloatRect.h" - -namespace WebCore { - -#ifndef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - -FloatRect::FloatRect(const NSRect& r) : m_location(r.origin), m_size(r.size) -{ -} - -FloatRect::operator NSRect() const -{ - return NSMakeRect(x(), y(), width(), height()); -} - -#endif - -} diff --git a/WebCore/platform/graphics/mac/FloatSizeMac.mm b/WebCore/platform/graphics/mac/FloatSizeMac.mm deleted file mode 100644 index 01efbe9..0000000 --- a/WebCore/platform/graphics/mac/FloatSizeMac.mm +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2005 Nokia. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h" -#include "FloatSize.h" - -namespace WebCore { - -#ifndef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - -FloatSize::FloatSize(const NSSize& s) : m_width(s.width), m_height(s.height) -{ -} - -FloatSize::operator NSSize() const -{ - return NSMakeSize(m_width, m_height); -} - -#endif - -} diff --git a/WebCore/platform/graphics/mac/FontCacheMac.mm b/WebCore/platform/graphics/mac/FontCacheMac.mm deleted file mode 100644 index e7cda66..0000000 --- a/WebCore/platform/graphics/mac/FontCacheMac.mm +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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. - */ - -#import "config.h" -#import "FontCache.h" - -#import "Font.h" -#import "SimpleFontData.h" -#import "FontPlatformData.h" -#import "WebCoreSystemInterface.h" -#import "WebFontCache.h" - -#ifdef BUILDING_ON_TIGER -typedef int NSInteger; -#endif - -namespace WebCore { - -static void fontCacheATSNotificationCallback(ATSFontNotificationInfoRef, void*) -{ - FontCache::invalidate(); -} - -void FontCache::platformInit() -{ - wkSetUpFontCache(); - // FIXME: Passing kATSFontNotifyOptionReceiveWhileSuspended may be an overkill and does not seem to work anyway. - ATSFontNotificationSubscribe(fontCacheATSNotificationCallback, kATSFontNotifyOptionReceiveWhileSuspended, 0, 0); -} - -static int toAppKitFontWeight(FontWeight fontWeight) -{ - static int appKitFontWeights[] = { - 2, // FontWeight100 - 3, // FontWeight200 - 4, // FontWeight300 - 5, // FontWeight400 - 6, // FontWeight500 - 8, // FontWeight600 - 9, // FontWeight700 - 10, // FontWeight800 - 12, // FontWeight900 - }; - return appKitFontWeights[fontWeight]; -} - -static inline bool isAppKitFontWeightBold(NSInteger appKitFontWeight) -{ - return appKitFontWeight >= 7; -} - -const SimpleFontData* FontCache::getFontDataForCharacters(const Font& font, const UChar* characters, int length) -{ - const FontPlatformData& platformData = font.fontDataAt(0)->fontDataForCharacter(characters[0])->platformData(); - NSFont *nsFont = platformData.font(); - - NSString *string = [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(characters) length:length freeWhenDone:NO]; - NSFont *substituteFont = wkGetFontInLanguageForRange(nsFont, string, NSMakeRange(0, length)); - [string release]; - - if (!substituteFont && length == 1) - substituteFont = wkGetFontInLanguageForCharacter(nsFont, characters[0]); - if (!substituteFont) - return 0; - - // Use the family name from the AppKit-supplied substitute font, requesting the - // traits, weight, and size we want. One way this does better than the original - // AppKit request is that it takes synthetic bold and oblique into account. - // But it does create the possibility that we could end up with a font that - // doesn't actually cover the characters we need. - - NSFontManager *fontManager = [NSFontManager sharedFontManager]; - - NSFontTraitMask traits; - NSInteger weight; - CGFloat size; - - if (nsFont) { - traits = [fontManager traitsOfFont:nsFont]; - if (platformData.m_syntheticBold) - traits |= NSBoldFontMask; - if (platformData.m_syntheticOblique) - traits |= NSFontItalicTrait; - weight = [fontManager weightOfFont:nsFont]; - size = [nsFont pointSize]; - } else { - // For custom fonts nsFont is nil. - traits = font.italic() ? NSFontItalicTrait : 0; - weight = toAppKitFontWeight(font.weight()); - size = font.pixelSize(); - } - - if (NSFont *bestVariation = [fontManager fontWithFamily:[substituteFont familyName] traits:traits weight:weight size:size]) - substituteFont = bestVariation; - - substituteFont = font.fontDescription().usePrinterFont() ? [substituteFont printerFont] : [substituteFont screenFont]; - - NSFontTraitMask substituteFontTraits = [fontManager traitsOfFont:substituteFont]; - NSInteger substituteFontWeight = [fontManager weightOfFont:substituteFont]; - - FontPlatformData alternateFont(substituteFont, - !font.isPlatformFont() && isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(substituteFontWeight), - !font.isPlatformFont() && (traits & NSFontItalicTrait) && !(substituteFontTraits & NSFontItalicTrait)); - return getCachedFontData(&alternateFont); -} - -FontPlatformData* FontCache::getSimilarFontPlatformData(const Font& font) -{ - // Attempt to find an appropriate font using a match based on - // the presence of keywords in the the requested names. For example, we'll - // match any name that contains "Arabic" to Geeza Pro. - FontPlatformData* platformData = 0; - const FontFamily* currFamily = &font.fontDescription().family(); - while (currFamily && !platformData) { - if (currFamily->family().length()) { - static String matchWords[3] = { String("Arabic"), String("Pashto"), String("Urdu") }; - static AtomicString geezaStr("Geeza Pro"); - for (int j = 0; j < 3 && !platformData; ++j) - if (currFamily->family().contains(matchWords[j], false)) - platformData = getCachedFontPlatformData(font.fontDescription(), geezaStr); - } - currFamily = currFamily->next(); - } - - return platformData; -} - -FontPlatformData* FontCache::getLastResortFallbackFont(const FontDescription& fontDescription) -{ - static AtomicString timesStr("Times"); - static AtomicString lucidaGrandeStr("Lucida Grande"); - - // 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 any prefs. - FontPlatformData* platformFont = getCachedFontPlatformData(fontDescription, timesStr); - if (!platformFont) - // The Times fallback will almost always work, but in the highly unusual case where - // the user doesn't have it, we fall back on Lucida Grande because that's - // guaranteed to be there, according to Nathan Taylor. This is good enough - // to avoid a crash at least. - platformFont = getCachedFontPlatformData(fontDescription, lucidaGrandeStr); - - return platformFont; -} - -void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks) -{ - [WebFontCache getTraits:traitsMasks inFamily:familyName]; -} - -FontPlatformData* FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) -{ - NSFontTraitMask traits = fontDescription.italic() ? NSFontItalicTrait : 0; - NSInteger weight = toAppKitFontWeight(fontDescription.weight()); - float size = fontDescription.computedPixelSize(); - - NSFont *nsFont = [WebFontCache fontWithFamily:family traits:traits weight:weight size:size]; - if (!nsFont) - return 0; - - NSFontManager *fontManager = [NSFontManager sharedFontManager]; - NSFontTraitMask actualTraits = 0; - if (fontDescription.italic()) - actualTraits = [fontManager traitsOfFont:nsFont]; - NSInteger actualWeight = [fontManager weightOfFont:nsFont]; - - FontPlatformData* result = new FontPlatformData; - - // Use the correct font for print vs. screen. - result->setFont(fontDescription.usePrinterFont() ? [nsFont printerFont] : [nsFont screenFont]); - result->m_syntheticBold = isAppKitFontWeightBold(weight) && !isAppKitFontWeightBold(actualWeight); - result->m_syntheticOblique = (traits & NSFontItalicTrait) && !(actualTraits & NSFontItalicTrait); - return result; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp b/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp deleted file mode 100644 index 1fb144c..0000000 --- a/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2007 Apple Computer, Inc. - * - * 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 - * along 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" -#include "FontCustomPlatformData.h" - -#include <ApplicationServices/ApplicationServices.h> -#include "SharedBuffer.h" -#include "FontPlatformData.h" - -namespace WebCore { - -FontCustomPlatformData::~FontCustomPlatformData() -{ - ATSFontDeactivate(m_atsContainer, NULL, kATSOptionFlagsDefault); - CGFontRelease(m_cgFont); -} - -FontPlatformData FontCustomPlatformData::fontPlatformData(int size, bool bold, bool italic, FontRenderingMode) -{ - return FontPlatformData(m_cgFont, (ATSUFontID)m_atsFont, size, bold, italic); -} - -FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer) -{ - ASSERT_ARG(buffer, buffer); - - // Use ATS to activate the font. - ATSFontContainerRef containerRef = 0; - - // The value "3" means that the font is private and can't be seen by anyone else. - ATSFontActivateFromMemory((void*)buffer->data(), buffer->size(), 3, kATSFontFormatUnspecified, NULL, kATSOptionFlagsDefault, &containerRef); - if (!containerRef) - return 0; - ItemCount fontCount; - ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 0, NULL, &fontCount); - - // We just support the first font in the list. - if (fontCount == 0) { - ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); - return 0; - } - - ATSFontRef fontRef = 0; - ATSFontFindFromContainer(containerRef, kATSOptionFlagsDefault, 1, &fontRef, NULL); - if (!fontRef) { - ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); - return 0; - } - - CGFontRef cgFontRef = CGFontCreateWithPlatformFont(&fontRef); -#ifndef BUILDING_ON_TIGER - // Workaround for <rdar://problem/5675504>. - if (!CGFontGetNumberOfGlyphs(cgFontRef)) { - CFRelease(cgFontRef); - cgFontRef = 0; - } -#endif - if (!cgFontRef) { - ATSFontDeactivate(containerRef, NULL, kATSOptionFlagsDefault); - return 0; - } - - return new FontCustomPlatformData(containerRef, fontRef, cgFontRef); -} - -} diff --git a/WebCore/platform/graphics/mac/FontCustomPlatformData.h b/WebCore/platform/graphics/mac/FontCustomPlatformData.h deleted file mode 100644 index 1e73ae0..0000000 --- a/WebCore/platform/graphics/mac/FontCustomPlatformData.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2007 Apple Computer, Inc. - * - * 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 - * along 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 FontCustomPlatformData_h -#define FontCustomPlatformData_h - -#include "FontRenderingMode.h" -#include <wtf/Noncopyable.h> - -typedef struct CGFont* CGFontRef; -typedef UInt32 ATSFontContainerRef; -typedef UInt32 ATSFontRef; - -namespace WebCore { - -class FontPlatformData; -class SharedBuffer; - -struct FontCustomPlatformData : Noncopyable { - FontCustomPlatformData(ATSFontContainerRef container, ATSFontRef atsFont, CGFontRef cgFont) - : m_atsContainer(container), m_atsFont(atsFont), m_cgFont(cgFont) - {} - ~FontCustomPlatformData(); - - FontPlatformData fontPlatformData(int size, bool bold, bool italic, FontRenderingMode = NormalRenderingMode); - - ATSFontContainerRef m_atsContainer; - ATSFontRef m_atsFont; - CGFontRef m_cgFont; -}; - -FontCustomPlatformData* createFontCustomPlatformData(SharedBuffer* buffer); - -} - -#endif diff --git a/WebCore/platform/graphics/mac/FontMac.mm b/WebCore/platform/graphics/mac/FontMac.mm deleted file mode 100644 index bef18d0..0000000 --- a/WebCore/platform/graphics/mac/FontMac.mm +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2006 Apple Computer, Inc. - * - * 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 - * along 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. - */ - -#import "config.h" -#import "Font.h" - -#import "GlyphBuffer.h" -#import "GraphicsContext.h" -#import "Logging.h" -#import "SimpleFontData.h" -#import "WebCoreSystemInterface.h" -#import "WebCoreTextRenderer.h" - -#define SYNTHETIC_OBLIQUE_ANGLE 14 - -#ifdef __LP64__ -#define URefCon void* -#else -#define URefCon UInt32 -#endif - -using namespace std; - -namespace WebCore { - -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(); - - if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing) - CGContextSetShouldSmoothFonts(cgContext, newShouldUseFontSmoothing); - - const FontPlatformData& platformData = font->platformData(); - NSFont* drawFont; - if (!isPrinterFont()) { - drawFont = [platformData.font() screenFont]; - if (drawFont != platformData.font()) - // We are getting this in too many places (3406411); use ERROR so it only prints on debug versions for now. (We should debug this also, eventually). - LOG_ERROR("Attempting to set non-screen font (%@) when drawing to screen. Using screen font anyway, may result in incorrect metrics.", - [[[platformData.font() fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]); - } else { - drawFont = [platformData.font() printerFont]; - if (drawFont != platformData.font()) - NSLog(@"Attempting to set non-printer font (%@) when printing. Using printer font anyway, may result in incorrect metrics.", - [[[platformData.font() fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]); - } - - CGContextSetFont(cgContext, platformData.cgFont()); - - CGAffineTransform matrix = CGAffineTransformIdentity; - if (drawFont) - memcpy(&matrix, [drawFont matrix], sizeof(matrix)); - matrix.b = -matrix.b; - matrix.d = -matrix.d; - if (platformData.m_syntheticOblique) - matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, -tanf(SYNTHETIC_OBLIQUE_ANGLE * acosf(0) / 90), 1, 0, 0)); - CGContextSetTextMatrix(cgContext, matrix); - - if (drawFont) { - wkSetCGFontRenderingMode(cgContext, drawFont); - CGContextSetFontSize(cgContext, 1.0f); - } else - CGContextSetFontSize(cgContext, platformData.m_size); - - IntSize shadowSize; - int shadowBlur; - Color shadowColor; - context->getShadow(shadowSize, shadowBlur, shadowColor); - - bool hasSimpleShadow = context->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur; - if (hasSimpleShadow) { - // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing. - context->clearShadow(); - Color fillColor = context->fillColor(); - Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); - 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()); - CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); - } - context->setFillColor(fillColor); - } - - 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()); - CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); - } - - if (hasSimpleShadow) - context->setShadow(shadowSize, shadowBlur, shadowColor); - - if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing) - CGContextSetShouldSmoothFonts(cgContext, originalShouldUseFontSmoothing); -} - -} diff --git a/WebCore/platform/graphics/mac/FontMacATSUI.mm b/WebCore/platform/graphics/mac/FontMacATSUI.mm deleted file mode 100644 index 9a45c5a..0000000 --- a/WebCore/platform/graphics/mac/FontMacATSUI.mm +++ /dev/null @@ -1,623 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2000 Dirk Mueller (mueller@kde.org) - * Copyright (C) 2003, 2006 Apple Computer, Inc. - * - * 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 - * along 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. - */ - -#import "config.h" -#import "Font.h" - -#if USE(ATSUI) - -#import "CharacterNames.h" -#import "GraphicsContext.h" -#import "Logging.h" -#import "ShapeArabic.h" -#import "SimpleFontData.h" -#import <wtf/OwnArrayPtr.h> - -#define SYNTHETIC_OBLIQUE_ANGLE 14 - -#ifdef __LP64__ -#define URefCon void* -#else -#define URefCon UInt32 -#endif - -using namespace std; - -namespace WebCore { - -struct ATSULayoutParameters : Noncopyable -{ - ATSULayoutParameters(const TextRun& run) - : m_run(run) - , m_font(0) - , m_hasSyntheticBold(false) - , m_syntheticBoldPass(false) - , m_padPerSpace(0) - {} - - ~ATSULayoutParameters() - { - ATSUDisposeTextLayout(m_layout); - } - - void initialize(const Font*, const GraphicsContext* = 0); - - const TextRun& m_run; - - const Font* m_font; - - ATSUTextLayout m_layout; - OwnArrayPtr<const SimpleFontData*> m_fonts; - - OwnArrayPtr<UChar> m_charBuffer; - bool m_hasSyntheticBold; - bool m_syntheticBoldPass; - float m_padPerSpace; -}; - -static TextRun copyRunForDirectionalOverrideIfNecessary(const TextRun& run, OwnArrayPtr<UChar>& charactersWithOverride) -{ - if (!run.directionalOverride()) - return run; - - charactersWithOverride.set(new UChar[run.length() + 2]); - charactersWithOverride[0] = run.rtl() ? rightToLeftOverride : leftToRightOverride; - memcpy(&charactersWithOverride[1], run.data(0), sizeof(UChar) * run.length()); - charactersWithOverride[run.length() + 1] = popDirectionalFormatting; - - TextRun result = run; - result.setText(charactersWithOverride.get(), run.length() + 2); - return result; -} - -static bool fontHasMirroringInfo(ATSUFontID fontID) -{ - ByteCount propTableSize; - OSStatus status = ATSFontGetTable(fontID, 'prop', 0, 0, 0, &propTableSize); - if (status == noErr) // naively assume that if a 'prop' table exists then it contains mirroring info - return true; - else if (status != kATSInvalidFontTableAccess) // anything other than a missing table is logged as an error - LOG_ERROR("ATSFontGetTable failed (%d)", status); - - return false; -} - -static void disableLigatures(const SimpleFontData* fontData) -{ - // 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 (fontData->platformData().allowsLigatures()) - return; - - ATSUFontFeatureType featureTypes[] = { kLigaturesType }; - ATSUFontFeatureSelector featureSelectors[] = { kCommonLigaturesOffSelector }; - OSStatus status = ATSUSetFontFeatures(fontData->m_ATSUStyle, 1, featureTypes, featureSelectors); - if (status != noErr) - LOG_ERROR("ATSUSetFontFeatures failed (%d) -- ligatures remain enabled", status); -} - -static void initializeATSUStyle(const SimpleFontData* fontData) -{ - if (fontData->m_ATSUStyleInitialized) - return; - - ATSUFontID fontID = fontData->platformData().m_atsuFontID; - if (!fontID) { - LOG_ERROR("unable to get ATSUFontID for %@", fontData->m_font.font()); - return; - } - - OSStatus status = ATSUCreateStyle(&fontData->m_ATSUStyle); - if (status != noErr) - // Who knows how many ATSU functions will crash when passed a NULL style... - LOG_ERROR("ATSUCreateStyle failed (%d)", status); - - CGAffineTransform transform = CGAffineTransformMakeScale(1, -1); - if (fontData->m_font.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) }; - // Turn off automatic kerning until it is supported in the CG code path (bug 6136) - Fract kerningInhibitFactor = FloatToFract(1.0); - - ATSUAttributeTag styleTags[4] = { kATSUSizeTag, kATSUFontTag, kATSUFontMatrixTag, kATSUKerningInhibitFactorTag }; - ATSUAttributeValuePtr styleValues[4] = { &fontSize, &fontID, &transform, &kerningInhibitFactor }; - status = ATSUSetAttributes(fontData->m_ATSUStyle, 4, styleTags, styleSizes, styleValues); - if (status != noErr) - LOG_ERROR("ATSUSetAttributes failed (%d)", status); - - fontData->m_ATSUMirrors = fontHasMirroringInfo(fontID); - - // Turn off ligatures such as 'fi' to match the CG code path's behavior, until bug 6135 is fixed. - disableLigatures(fontData); - - fontData->m_ATSUStyleInitialized = true; -} - -static OSStatus overrideLayoutOperation(ATSULayoutOperationSelector iCurrentOperation, ATSULineRef iLineRef, URefCon iRefCon, - void *iOperationCallbackParameterPtr, ATSULayoutOperationCallbackStatus *oCallbackStatus) -{ - ATSULayoutParameters* params = reinterpret_cast<ATSULayoutParameters*>(iRefCon); - OSStatus status; - ItemCount count; - ATSLayoutRecord *layoutRecords; - - if (params->m_run.applyWordRounding()) { - status = ATSUDirectGetLayoutDataArrayPtrFromLineRef(iLineRef, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, true, (void **)&layoutRecords, &count); - if (status != noErr) { - *oCallbackStatus = kATSULayoutOperationCallbackStatusContinue; - return status; - } - - Fixed lastNativePos = 0; - float lastAdjustedPos = 0; - const UChar* characters = params->m_charBuffer ? params->m_charBuffer.get() : params->m_run.characters(); - const SimpleFontData** renderers = params->m_fonts.get(); - const SimpleFontData* renderer; - const SimpleFontData* lastRenderer = 0; - ByteCount offset = layoutRecords[0].originalOffset; - UChar nextCh = *(UChar *)(((char *)characters)+offset); - 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. - // Here it is applied in visual left-to-right order, which may be better. - ItemCount lastRoundingChar = 0; - ItemCount i; - 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; - } else { - width = FixedToFloat(layoutRecords[i].realPos - lastNativePos); - 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; - } - lastNativePos = layoutRecords[i].realPos; - - if (hasExtraSpacing) { - if (width && params->m_font->letterSpacing()) - width +=params->m_font->letterSpacing(); - if (Font::treatAsSpace(nextCh)) { - if (params->m_run.padding()) { - if (padding < params->m_padPerSpace) { - width += padding; - padding = 0; - } else { - width += params->m_padPerSpace; - padding -= params->m_padPerSpace; - } - } - if (offset != 0 && !Font::treatAsSpace(*((UChar *)(((char *)characters)+offset) - 1)) && params->m_font->wordSpacing()) - width += params->m_font->wordSpacing(); - } - } - - UChar ch = nextCh; - offset = layoutRecords[i].originalOffset; - // Use space for nextCh at the end of the loop so that we get inside the rounding hack code. - // We won't actually round unless the other conditions are satisfied. - nextCh = isLastChar ? ' ' : *(UChar *)(((char *)characters)+offset); - - if (Font::isRoundingHackCharacter(ch)) - width = ceilf(width); - lastAdjustedPos = lastAdjustedPos + width; - if (Font::isRoundingHackCharacter(nextCh) && (!isLastChar || params->m_run.applyRunRounding())){ - if (params->m_run.ltr()) - lastAdjustedPos = ceilf(lastAdjustedPos); - else { - float roundingWidth = ceilf(lastAdjustedPos) - lastAdjustedPos; - Fixed rw = FloatToFixed(roundingWidth); - ItemCount j; - for (j = lastRoundingChar; j < i; j++) - layoutRecords[j].realPos += rw; - lastRoundingChar = i; - lastAdjustedPos += roundingWidth; - } - } - if (syntheticBoldPass) { - if (syntheticBoldOffset) - layoutRecords[i-1].realPos += syntheticBoldOffset; - else - layoutRecords[i-1].glyphID = spaceGlyph; - } - layoutRecords[i].realPos = FloatToFixed(lastAdjustedPos); - } - - status = ATSUDirectReleaseLayoutDataArrayPtr(iLineRef, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent, (void **)&layoutRecords); - } - *oCallbackStatus = kATSULayoutOperationCallbackStatusHandled; - return noErr; -} - -static inline bool isArabicLamWithAlefLigature(UChar c) -{ - return c >= 0xfef5 && c <= 0xfefc; -} - -static void shapeArabic(const UChar* source, UChar* dest, unsigned totalLength, unsigned shapingStart) -{ - while (shapingStart < totalLength) { - unsigned shapingEnd; - // We do not want to pass a Lam with Alef ligature followed by a space to the shaper, - // since we want to be able to identify this sequence as the result of shaping a Lam - // followed by an Alef and padding with a space. - bool foundLigatureSpace = false; - for (shapingEnd = shapingStart; !foundLigatureSpace && shapingEnd < totalLength - 1; ++shapingEnd) - foundLigatureSpace = isArabicLamWithAlefLigature(source[shapingEnd]) && source[shapingEnd + 1] == ' '; - shapingEnd++; - - UErrorCode shapingError = U_ZERO_ERROR; - unsigned charsWritten = shapeArabic(source + shapingStart, shapingEnd - shapingStart, dest + shapingStart, shapingEnd - shapingStart, U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_NEAR, &shapingError); - - if (U_SUCCESS(shapingError) && charsWritten == shapingEnd - shapingStart) { - for (unsigned j = shapingStart; j < shapingEnd - 1; ++j) { - if (isArabicLamWithAlefLigature(dest[j]) && dest[j + 1] == ' ') - dest[++j] = zeroWidthSpace; - } - if (foundLigatureSpace) { - dest[shapingEnd] = ' '; - shapingEnd++; - } else if (isArabicLamWithAlefLigature(dest[shapingEnd - 1])) { - // u_shapeArabic quirk: if the last two characters in the source string are a Lam and an Alef, - // the space is put at the beginning of the string, despite U_SHAPE_LENGTH_FIXED_SPACES_NEAR. - ASSERT(dest[shapingStart] == ' '); - dest[shapingStart] = zeroWidthSpace; - } - } else { - // Something went wrong. Abandon shaping and just copy the rest of the buffer. - LOG_ERROR("u_shapeArabic failed(%d)", shapingError); - shapingEnd = totalLength; - memcpy(dest + shapingStart, source + shapingStart, (shapingEnd - shapingStart) * sizeof(UChar)); - } - shapingStart = shapingEnd; - } -} - -void ATSULayoutParameters::initialize(const Font* font, const GraphicsContext* graphicsContext) -{ - m_font = font; - - const SimpleFontData* fontData = font->primaryFont(); - m_fonts.set(new const SimpleFontData*[m_run.length()]); - if (font->isSmallCaps()) - m_charBuffer.set(new UChar[m_run.length()]); - - ATSUTextLayout layout; - OSStatus status; - ATSULayoutOperationOverrideSpecifier overrideSpecifier; - - initializeATSUStyle(fontData); - - // FIXME: This is currently missing the following required features that the CoreGraphics code path has: - // - \n, \t, and nonbreaking space render as a space. - - UniCharCount runLength = m_run.length(); - - if (m_charBuffer) - memcpy(m_charBuffer.get(), m_run.characters(), runLength * sizeof(UChar)); - - status = ATSUCreateTextLayoutWithTextPtr( - (m_charBuffer ? m_charBuffer.get() : m_run.characters()), - 0, // offset - runLength, // length - runLength, // total length - 1, // styleRunCount - &runLength, // length of style run - &fontData->m_ATSUStyle, - &layout); - if (status != noErr) - LOG_ERROR("ATSUCreateTextLayoutWithTextPtr failed(%d)", status); - m_layout = layout; - ATSUSetTextLayoutRefCon(m_layout, (URefCon)this); - - // FIXME: There are certain times when this method is called, when we don't have access to a GraphicsContext - // measuring text runs with floatWidthForComplexText is one example. - // ATSUI requires that we pass a valid CGContextRef to it when specifying kATSUCGContextTag (crashes when passed 0) - // ATSUI disables sub-pixel rendering if kATSUCGContextTag is not specified! So we're in a bind. - // Sometimes [[NSGraphicsContext currentContext] graphicsPort] may return the wrong (or no!) context. Nothing we can do about it (yet). - CGContextRef cgContext = graphicsContext ? graphicsContext->platformContext() : (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; - - ATSLineLayoutOptions lineLayoutOptions = kATSLineKeepSpacesOutOfMargin | kATSLineHasNoHangers; - Boolean rtl = m_run.rtl(); - overrideSpecifier.operationSelector = kATSULayoutOperationPostLayoutAdjustment; - overrideSpecifier.overrideUPP = overrideLayoutOperation; - ATSUAttributeTag tags[] = { kATSUCGContextTag, kATSULineLayoutOptionsTag, kATSULineDirectionTag, kATSULayoutOperationOverrideTag }; - ByteCount sizes[] = { sizeof(CGContextRef), sizeof(ATSLineLayoutOptions), sizeof(Boolean), sizeof(ATSULayoutOperationOverrideSpecifier) }; - ATSUAttributeValuePtr values[] = { &cgContext, &lineLayoutOptions, &rtl, &overrideSpecifier }; - - status = ATSUSetLayoutControls(layout, (m_run.applyWordRounding() ? 4 : 3), tags, sizes, values); - if (status != noErr) - LOG_ERROR("ATSUSetLayoutControls failed(%d)", status); - - status = ATSUSetTransientFontMatching(layout, YES); - if (status != noErr) - LOG_ERROR("ATSUSetTransientFontMatching failed(%d)", status); - - m_hasSyntheticBold = false; - ATSUFontID ATSUSubstituteFont; - UniCharArrayOffset substituteOffset = 0; - UniCharCount substituteLength; - UniCharArrayOffset lastOffset; - const SimpleFontData* substituteFontData = 0; - - while (substituteOffset < runLength) { - // FIXME: Using ATSUMatchFontsToText() here results in several problems: the CSS font family list is not necessarily followed for the 2nd - // and onwards unmatched characters; segmented fonts do not work correctly; behavior does not match the simple text and Uniscribe code - // paths. Change this function to use Font::glyphDataForCharacter() for each character instead. - lastOffset = substituteOffset; - status = ATSUMatchFontsToText(layout, substituteOffset, kATSUToTextEnd, &ATSUSubstituteFont, &substituteOffset, &substituteLength); - if (status == kATSUFontsMatched || status == kATSUFontsNotMatched) { - const FontData* fallbackFontData = m_font->fontDataForCharacters(m_run.characters() + substituteOffset, substituteLength); - substituteFontData = fallbackFontData ? fallbackFontData->fontDataForCharacter(m_run[0]) : 0; - if (substituteFontData) { - initializeATSUStyle(substituteFontData); - if (substituteFontData->m_ATSUStyle) - ATSUSetRunStyle(layout, substituteFontData->m_ATSUStyle, substituteOffset, substituteLength); - } else - substituteFontData = fontData; - } else { - substituteOffset = runLength; - substituteLength = 0; - } - - bool shapedArabic = false; - bool isSmallCap = false; - UniCharArrayOffset firstSmallCap = 0; - const SimpleFontData *r = fontData; - UniCharArrayOffset i; - for (i = lastOffset; ; i++) { - if (i == substituteOffset || i == substituteOffset + substituteLength) { - if (isSmallCap) { - isSmallCap = false; - initializeATSUStyle(r->smallCapsFontData(m_font->fontDescription())); - ATSUSetRunStyle(layout, r->smallCapsFontData(m_font->fontDescription())->m_ATSUStyle, firstSmallCap, i - firstSmallCap); - } - if (i == substituteOffset && substituteLength > 0) - r = substituteFontData; - else - break; - } - if (!shapedArabic && WTF::Unicode::isArabicChar(m_run[i]) && !r->shapesArabic()) { - shapedArabic = true; - if (!m_charBuffer) { - m_charBuffer.set(new UChar[runLength]); - memcpy(m_charBuffer.get(), m_run.characters(), i * sizeof(UChar)); - ATSUTextMoved(layout, m_charBuffer.get()); - } - shapeArabic(m_run.characters(), m_charBuffer.get(), runLength, i); - } - if (m_run.rtl() && !r->m_ATSUMirrors) { - UChar mirroredChar = u_charMirror(m_run[i]); - if (mirroredChar != m_run[i]) { - if (!m_charBuffer) { - m_charBuffer.set(new UChar[runLength]); - memcpy(m_charBuffer.get(), m_run.characters(), runLength * sizeof(UChar)); - ATSUTextMoved(layout, m_charBuffer.get()); - } - m_charBuffer[i] = mirroredChar; - } - } - if (m_font->isSmallCaps()) { - const SimpleFontData* smallCapsData = r->smallCapsFontData(m_font->fontDescription()); - UChar c = m_charBuffer[i]; - UChar newC; - if (U_GET_GC_MASK(c) & U_GC_M_MASK) - m_fonts[i] = isSmallCap ? smallCapsData : r; - else if (!u_isUUppercase(c) && (newC = u_toupper(c)) != c) { - m_charBuffer[i] = newC; - if (!isSmallCap) { - isSmallCap = true; - firstSmallCap = i; - } - m_fonts[i] = smallCapsData; - } else { - if (isSmallCap) { - isSmallCap = false; - initializeATSUStyle(smallCapsData); - ATSUSetRunStyle(layout, smallCapsData->m_ATSUStyle, firstSmallCap, i - firstSmallCap); - } - m_fonts[i] = r; - } - } else - m_fonts[i] = r; - if (m_fonts[i]->m_syntheticBoldOffset) - m_hasSyntheticBold = true; - } - substituteOffset += substituteLength; - } - if (m_run.padding()) { - float numSpaces = 0; - unsigned k; - for (k = 0; k < runLength; k++) - if (Font::treatAsSpace(m_run[k])) - numSpaces++; - - if (numSpaces == 0) - m_padPerSpace = 0; - else - m_padPerSpace = ceilf(m_run.padding() / numSpaces); - } else - m_padPerSpace = 0; -} - -FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int from, int to) const -{ - OwnArrayPtr<UChar> charactersWithOverride; - TextRun adjustedRun = copyRunForDirectionalOverrideIfNecessary(run, charactersWithOverride); - if (run.directionalOverride()) { - from++; - to++; - } - - ATSULayoutParameters params(adjustedRun); - params.initialize(this); - - ATSTrapezoid firstGlyphBounds; - ItemCount actualNumBounds; - - OSStatus status = ATSUGetGlyphBounds(params.m_layout, 0, 0, from, to - from, kATSUseFractionalOrigins, 1, &firstGlyphBounds, &actualNumBounds); - if (status != noErr || actualNumBounds != 1) { - static ATSTrapezoid zeroTrapezoid = { {0, 0}, {0, 0}, {0, 0}, {0, 0} }; - firstGlyphBounds = zeroTrapezoid; - } - - float beforeWidth = MIN(FixedToFloat(firstGlyphBounds.lowerLeft.x), FixedToFloat(firstGlyphBounds.upperLeft.x)); - float afterWidth = MAX(FixedToFloat(firstGlyphBounds.lowerRight.x), FixedToFloat(firstGlyphBounds.upperRight.x)); - - FloatRect rect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h); - - return rect; -} - -void Font::drawComplexText(GraphicsContext* graphicsContext, const TextRun& run, const FloatPoint& point, int from, int to) const -{ - OSStatus status; - - int drawPortionLength = to - from; - OwnArrayPtr<UChar> charactersWithOverride; - TextRun adjustedRun = copyRunForDirectionalOverrideIfNecessary(run, charactersWithOverride); - if (run.directionalOverride()) - from++; - - ATSULayoutParameters params(adjustedRun); - params.initialize(this, graphicsContext); - - // ATSUI can't draw beyond -32768 to +32767 so we translate the CTM and tell ATSUI to draw at (0, 0). - CGContextRef context = graphicsContext->platformContext(); - CGContextTranslateCTM(context, point.x(), point.y()); - - IntSize shadowSize; - int shadowBlur; - Color shadowColor; - graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor); - - bool hasSimpleShadow = graphicsContext->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur; - if (hasSimpleShadow) { - // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing. - graphicsContext->clearShadow(); - Color fillColor = graphicsContext->fillColor(); - Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); - graphicsContext->setFillColor(shadowFillColor); - CGContextTranslateCTM(context, shadowSize.width(), shadowSize.height()); - status = ATSUDrawText(params.m_layout, from, drawPortionLength, 0, 0); - if (status == noErr && params.m_hasSyntheticBold) { - // Force relayout for the bold pass - ATSUClearLayoutCache(params.m_layout, 0); - params.m_syntheticBoldPass = true; - status = ATSUDrawText(params.m_layout, from, drawPortionLength, 0, 0); - // Force relayout for the next pass - ATSUClearLayoutCache(params.m_layout, 0); - params.m_syntheticBoldPass = false; - } - CGContextTranslateCTM(context, -shadowSize.width(), -shadowSize.height()); - graphicsContext->setFillColor(fillColor); - } - - status = ATSUDrawText(params.m_layout, from, drawPortionLength, 0, 0); - if (status == noErr && params.m_hasSyntheticBold) { - // Force relayout for the bold pass - ATSUClearLayoutCache(params.m_layout, 0); - params.m_syntheticBoldPass = true; - status = ATSUDrawText(params.m_layout, from, drawPortionLength, 0, 0); - } - CGContextTranslateCTM(context, -point.x(), -point.y()); - - if (status != noErr) - // Nothing to do but report the error (dev build only). - LOG_ERROR("ATSUDrawText() failed(%d)", status); - - if (hasSimpleShadow) - graphicsContext->setShadow(shadowSize, shadowBlur, shadowColor); -} - -float Font::floatWidthForComplexText(const TextRun& run) const -{ - if (run.length() == 0) - return 0; - - ATSULayoutParameters params(run); - params.initialize(this); - - OSStatus status; - - ATSTrapezoid firstGlyphBounds; - ItemCount actualNumBounds; - status = ATSUGetGlyphBounds(params.m_layout, 0, 0, 0, run.length(), kATSUseFractionalOrigins, 1, &firstGlyphBounds, &actualNumBounds); - if (status != noErr) - LOG_ERROR("ATSUGetGlyphBounds() failed(%d)", status); - if (actualNumBounds != 1) - LOG_ERROR("unexpected result from ATSUGetGlyphBounds(): actualNumBounds(%d) != 1", actualNumBounds); - - return MAX(FixedToFloat(firstGlyphBounds.upperRight.x), FixedToFloat(firstGlyphBounds.lowerRight.x)) - - MIN(FixedToFloat(firstGlyphBounds.upperLeft.x), FixedToFloat(firstGlyphBounds.lowerLeft.x)); -} - -int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const -{ - OwnArrayPtr<UChar> charactersWithOverride; - TextRun adjustedRun = copyRunForDirectionalOverrideIfNecessary(run, charactersWithOverride); - - ATSULayoutParameters params(adjustedRun); - params.initialize(this); - - UniCharArrayOffset primaryOffset = 0; - - // FIXME: No idea how to avoid including partial glyphs. - // Not even sure if that's the behavior this yields now. - Boolean isLeading; - UniCharArrayOffset secondaryOffset = 0; - OSStatus status = ATSUPositionToOffset(params.m_layout, FloatToFixed(x), FloatToFixed(-1), &primaryOffset, &isLeading, &secondaryOffset); - unsigned offset; - if (status == noErr) { - offset = (unsigned)primaryOffset; - if (run.directionalOverride() && offset > 0) - offset--; - } else - // Failed to find offset! Return 0 offset. - offset = 0; - - return offset; -} - -} -#endif // USE(ATSUI) diff --git a/WebCore/platform/graphics/mac/FontMacCoreText.cpp b/WebCore/platform/graphics/mac/FontMacCoreText.cpp deleted file mode 100644 index 5fb9d5d..0000000 --- a/WebCore/platform/graphics/mac/FontMacCoreText.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h" -#include "Font.h" - -#if USE(CORE_TEXT) - -#include "CoreTextController.h" -#include "FontFallbackList.h" -#include "GlyphBuffer.h" -#include "GraphicsContext.h" -#include "IntRect.h" -#include "SimpleFontData.h" -#include <wtf/MathExtras.h> - -namespace WebCore { - -FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, - int from, int to) const -{ - CoreTextController controller(this, run); - controller.advance(from); - float beforeWidth = controller.runWidthSoFar(); - controller.advance(to); - float afterWidth = controller.runWidthSoFar(); - - // Using roundf() rather than ceilf() for the right edge as a compromise to ensure correct caret positioning - if (run.rtl()) { - float totalWidth = controller.totalWidth(); - return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), h); - } - - return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), h); -} - -void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, - int from, int to) const -{ - // This glyph buffer holds our glyphs + advances + font data for each glyph. - GlyphBuffer glyphBuffer; - - float startX = point.x(); - CoreTextController controller(this, run); - controller.advance(from); - float beforeWidth = controller.runWidthSoFar(); - controller.advance(to, &glyphBuffer); - - // We couldn't generate any glyphs for the run. Give up. - if (glyphBuffer.isEmpty()) - return; - - float afterWidth = controller.runWidthSoFar(); - - if (run.rtl()) { - startX += controller.totalWidth() + controller.finalRoundingWidth() - afterWidth; - for (int i = 0, end = glyphBuffer.size() - 1; i < glyphBuffer.size() / 2; ++i, --end) - glyphBuffer.swap(i, end); - } else - startX += beforeWidth; - - // Draw the glyph buffer now at the starting point returned in startX. - FloatPoint startPoint(startX, point.y()); - drawGlyphBuffer(context, glyphBuffer, run, startPoint); -} - -float Font::floatWidthForComplexText(const TextRun& run) const -{ - CoreTextController controller(this, run, true); - return controller.totalWidth(); -} - -int Font::offsetForPositionForComplexText(const TextRun& run, int x, bool includePartialGlyphs) const -{ - CoreTextController controller(this, run); - return controller.offsetForPosition(x, includePartialGlyphs); -} - -} -#endif // USE(CORE_TEXT) diff --git a/WebCore/platform/graphics/mac/FontPlatformData.h b/WebCore/platform/graphics/mac/FontPlatformData.h deleted file mode 100644 index 40a2dbd..0000000 --- a/WebCore/platform/graphics/mac/FontPlatformData.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of the internal font implementation. - * It should not be included by source files outside it. - * - * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. - * - * 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 - * along 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 FontPlatformData_h -#define FontPlatformData_h - -#include "StringImpl.h" - -#ifdef __OBJC__ -@class NSFont; -#else -class NSFont; -#endif - -typedef struct CGFont* CGFontRef; -typedef UInt32 ATSUFontID; -#ifndef BUILDING_ON_TIGER -typedef const struct __CTFont* CTFontRef; -#endif - -#include <CoreFoundation/CFBase.h> -#include <objc/objc-auto.h> -#include <wtf/RetainPtr.h> - -namespace WebCore { - -#ifndef BUILDING_ON_TIGER -inline CTFontRef toCTFontRef(NSFont *nsFont) { return reinterpret_cast<CTFontRef>(nsFont); } -#endif - -struct FontPlatformData { - FontPlatformData(float size, bool syntheticBold, bool syntheticOblique) - : m_syntheticBold(syntheticBold) - , m_syntheticOblique(syntheticOblique) - , m_atsuFontID(0) - , m_size(size) - , m_font(0) -#ifdef BUILDING_ON_TIGER - , m_cgFont(0) -#endif - { - } - - FontPlatformData(NSFont * = 0, bool syntheticBold = false, bool syntheticOblique = false); - - FontPlatformData(CGFontRef f, ATSUFontID fontID, float s, bool b , bool o) - : m_syntheticBold(b), m_syntheticOblique(o), m_atsuFontID(fontID), m_size(s), m_font(0), m_cgFont(f) - { - } - - FontPlatformData(const FontPlatformData&); - - ~FontPlatformData(); - - FontPlatformData(WTF::HashTableDeletedValueType) : m_font(hashTableDeletedFontValue()) { } - bool isHashTableDeletedValue() const { return m_font == hashTableDeletedFontValue(); } - - float size() const { return m_size; } - - bool m_syntheticBold; - bool m_syntheticOblique; - - ATSUFontID m_atsuFontID; - float m_size; - - unsigned hash() const - { - ASSERT(m_font != 0 || m_cgFont == 0); - uintptr_t hashCodes[2] = { (uintptr_t)m_font, m_syntheticBold << 1 | m_syntheticOblique }; - return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar)); - } - - const FontPlatformData& operator=(const FontPlatformData& f); - - bool operator==(const FontPlatformData& other) const - { - return m_font == other.m_font && m_syntheticBold == other.m_syntheticBold && m_syntheticOblique == other.m_syntheticOblique && - m_cgFont == other.m_cgFont && m_size == other.m_size && m_atsuFontID == other.m_atsuFontID; - } - - NSFont *font() const { return m_font; } - void setFont(NSFont *font); - - bool roundsGlyphAdvances() const; - bool allowsLigatures() const; - -#ifndef BUILDING_ON_TIGER - CGFontRef cgFont() const { return m_cgFont.get(); } -#else - CGFontRef cgFont() const { return m_cgFont; } -#endif - -private: - static NSFont *hashTableDeletedFontValue() { return reinterpret_cast<NSFont *>(-1); } - - NSFont *m_font; -#ifndef BUILDING_ON_TIGER - RetainPtr<CGFontRef> m_cgFont; -#else - CGFontRef m_cgFont; // It is not necessary to refcount this, since either an NSFont owns it or some CachedFont has it referenced. -#endif -}; - -} - -#endif diff --git a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm b/WebCore/platform/graphics/mac/FontPlatformDataMac.mm deleted file mode 100644 index 15e573d..0000000 --- a/WebCore/platform/graphics/mac/FontPlatformDataMac.mm +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This file is part of the internal font implementation. - * - * Copyright (C) 2006-7 Apple Computer, Inc. - * - * 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 - * along 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. - * - */ - -#import "config.h" -#import "FontPlatformData.h" - -#import "WebCoreSystemInterface.h" - -namespace WebCore { - -FontPlatformData::FontPlatformData(NSFont *f, bool b , bool o) -: m_syntheticBold(b), m_syntheticOblique(o), m_font(f) -{ - if (f) - CFRetain(f); - m_size = f ? [f pointSize] : 0.0f; -#ifndef BUILDING_ON_TIGER - m_cgFont = CTFontCopyGraphicsFont(toCTFontRef(f), 0); - m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(f), 0); -#else - m_cgFont = wkGetCGFontFromNSFont(f); - m_atsuFontID = wkGetNSFontATSUFontId(f); -#endif -} - -FontPlatformData::FontPlatformData(const FontPlatformData& f) -{ - m_font = f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1) ? static_cast<const NSFont *>(CFRetain(f.m_font)) : f.m_font; - m_syntheticBold = f.m_syntheticBold; - m_syntheticOblique = f.m_syntheticOblique; - m_size = f.m_size; - m_cgFont = f.m_cgFont; - m_atsuFontID = f.m_atsuFontID; -} - -FontPlatformData:: ~FontPlatformData() -{ - if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) - CFRelease(m_font); -} - -const FontPlatformData& FontPlatformData::operator=(const FontPlatformData& f) -{ - m_syntheticBold = f.m_syntheticBold; - m_syntheticOblique = f.m_syntheticOblique; - m_size = f.m_size; - m_cgFont = f.m_cgFont; - m_atsuFontID = f.m_atsuFontID; - if (m_font == f.m_font) - return *this; - if (f.m_font && f.m_font != reinterpret_cast<NSFont *>(-1)) - CFRetain(f.m_font); - if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) - CFRelease(m_font); - m_font = f.m_font; - return *this; -} - -void FontPlatformData::setFont(NSFont *font) -{ - if (m_font == font) - return; - if (font) - CFRetain(font); - if (m_font && m_font != reinterpret_cast<NSFont *>(-1)) - CFRelease(m_font); - m_font = font; - m_size = font ? [font pointSize] : 0.0f; -#ifndef BUILDING_ON_TIGER - m_cgFont = CTFontCopyGraphicsFont(toCTFontRef(font), 0); - m_atsuFontID = CTFontGetPlatformFont(toCTFontRef(font), 0); -#else - m_cgFont = wkGetCGFontFromNSFont(font); - m_atsuFontID = wkGetNSFontATSUFontId(font); -#endif -} - -bool FontPlatformData::roundsGlyphAdvances() const -{ - return [m_font renderingMode] == NSFontAntialiasedIntegerAdvancementsRenderingMode; -} - -bool FontPlatformData::allowsLigatures() const -{ - return ![[m_font coveredCharacterSet] characterIsMember:'a']; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp b/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp deleted file mode 100644 index 143e665..0000000 --- a/WebCore/platform/graphics/mac/GlyphPageTreeNodeMac.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple 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: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 "config.h" -#include "GlyphPageTreeNode.h" - -#include "SimpleFontData.h" -#include "WebCoreSystemInterface.h" -#include <ApplicationServices/ApplicationServices.h> - -namespace WebCore { - -bool GlyphPage::fill(unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData) -{ - bool haveGlyphs = false; - -#ifndef BUILDING_ON_TIGER - Vector<CGGlyph, 512> glyphs(bufferLength); - wkGetGlyphsForCharacters(fontData->platformData().cgFont(), buffer, glyphs.data(), bufferLength); - - for (unsigned i = 0; i < length; ++i) { - if (!glyphs[i]) - setGlyphDataForIndex(offset + i, 0, 0); - else { - setGlyphDataForIndex(offset + i, glyphs[i], fontData); - haveGlyphs = true; - } - } -#else - // Use an array of long so we get good enough alignment. - long glyphVector[(GLYPH_VECTOR_SIZE + sizeof(long) - 1) / sizeof(long)]; - - OSStatus status = wkInitializeGlyphVector(GlyphPage::size, &glyphVector); - if (status != noErr) - // This should never happen, perhaps indicates a bad font! If it does the - // font substitution code will find an alternate font. - return false; - - wkConvertCharToGlyphs(fontData->m_styleGroup, buffer, bufferLength, &glyphVector); - - unsigned numGlyphs = wkGetGlyphVectorNumGlyphs(&glyphVector); - if (numGlyphs != length) { - // This should never happen, perhaps indicates a bad font? - // If it does happen, the font substitution code will find an alternate font. - wkClearGlyphVector(&glyphVector); - return false; - } - - ATSLayoutRecord* glyphRecord = (ATSLayoutRecord*)wkGetGlyphVectorFirstRecord(glyphVector); - for (unsigned i = 0; i < length; i++) { - Glyph glyph = glyphRecord->glyphID; - if (!glyph) - setGlyphDataForIndex(offset + i, 0, 0); - else { - setGlyphDataForIndex(offset + i, glyph, fontData); - haveGlyphs = true; - } - glyphRecord = (ATSLayoutRecord *)((char *)glyphRecord + wkGetGlyphVectorRecordSize(glyphVector)); - } - wkClearGlyphVector(&glyphVector); -#endif - - return haveGlyphs; -} - -} // namespace WebCore diff --git a/WebCore/platform/graphics/mac/GraphicsContextMac.mm b/WebCore/platform/graphics/mac/GraphicsContextMac.mm deleted file mode 100644 index 3f9176c..0000000 --- a/WebCore/platform/graphics/mac/GraphicsContextMac.mm +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. - */ - -#import "config.h" -#import "GraphicsContext.h" - -#import "../cg/GraphicsContextPlatformPrivateCG.h" - -#import "WebCoreSystemInterface.h" - -// FIXME: More of this should use CoreGraphics instead of AppKit. -// FIXME: More of this should move into GraphicsContextCG.cpp. - -namespace WebCore { - -// NSColor, NSBezierPath, and NSGraphicsContext -// calls in this file are all exception-safe, so we don't block -// exceptions for those. - -void GraphicsContext::drawFocusRing(const Color& color) -{ - if (paintingDisabled()) - return; - - int radius = (focusRingWidth() - 1) / 2; - int offset = radius + focusRingOffset(); - CGColorRef colorRef = color.isValid() ? cgColor(color) : 0; - - CGMutablePathRef focusRingPath = CGPathCreateMutable(); - const Vector<IntRect>& rects = focusRingRects(); - unsigned rectCount = rects.size(); - for (unsigned i = 0; i < rectCount; i++) - CGPathAddRect(focusRingPath, 0, CGRectInset(rects[i], -offset, -offset)); - - CGContextRef context = platformContext(); -#ifdef BUILDING_ON_TIGER - CGContextBeginTransparencyLayer(context, NULL); -#endif - CGContextBeginPath(context); - CGContextAddPath(context, focusRingPath); - wkDrawFocusRing(context, colorRef, radius); -#ifdef BUILDING_ON_TIGER - CGContextEndTransparencyLayer(context); -#endif - CGColorRelease(colorRef); - - CGPathRelease(focusRingPath); -} - -#ifdef BUILDING_ON_TIGER // Post-Tiger's setCompositeOperation() is defined in GraphicsContextCG.cpp. -void GraphicsContext::setCompositeOperation(CompositeOperator op) -{ - if (paintingDisabled()) - return; - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - [[NSGraphicsContext graphicsContextWithGraphicsPort:platformContext() flipped:YES] - setCompositingOperation:(NSCompositingOperation)op]; - [pool drain]; -} -#endif - -void GraphicsContext::drawLineForMisspellingOrBadGrammar(const IntPoint& point, int width, bool grammar) -{ - if (paintingDisabled()) - return; - - // Constants for spelling pattern color - static RetainPtr<NSColor> spellingPatternColor = nil; - static bool usingDotForSpelling = false; - - // Constants for grammar pattern color - static RetainPtr<NSColor> grammarPatternColor = nil; - static bool usingDotForGrammar = false; - - // These are the same for misspelling or bad grammar - int patternHeight = cMisspellingLineThickness; - int patternWidth = cMisspellingLinePatternWidth; - - // Initialize pattern color if needed - if (!grammar && !spellingPatternColor) { - NSImage *image = [NSImage imageNamed:@"SpellingDot"]; - ASSERT(image); // if image is not available, we want to know - NSColor *color = (image ? [NSColor colorWithPatternImage:image] : nil); - if (color) - usingDotForSpelling = true; - else - color = [NSColor redColor]; - spellingPatternColor = color; - } - - if (grammar && !grammarPatternColor) { - NSImage *image = [NSImage imageNamed:@"GrammarDot"]; - ASSERT(image); // if image is not available, we want to know - NSColor *color = (image ? [NSColor colorWithPatternImage:image] : nil); - if (color) - usingDotForGrammar = true; - else - color = [NSColor greenColor]; - grammarPatternColor = color; - } - - bool usingDot; - NSColor *patternColor; - if (grammar) { - usingDot = usingDotForGrammar; - patternColor = grammarPatternColor.get(); - } else { - usingDot = usingDotForSpelling; - patternColor = spellingPatternColor.get(); - } - - // Make sure to draw only complete dots. - // NOTE: Code here used to shift the underline to the left and increase the width - // to make sure everything gets underlined, but that results in drawing out of - // bounds (e.g. when at the edge of a view) and could make it appear that the - // space between adjacent misspelled words was underlined. - if (usingDot) { - // allow slightly more considering that the pattern ends with a transparent pixel - int widthMod = width % patternWidth; - if (patternWidth - widthMod > cMisspellingLinePatternGapWidth) - width -= widthMod; - } - - // FIXME: This code should not use NSGraphicsContext currentContext - // In order to remove this requirement we will need to use CGPattern instead of NSColor - // FIXME: This code should not be using wkSetPatternPhaseInUserSpace, as this approach is wrong - // for transforms. - - // Draw underline - NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; - CGContextRef context = (CGContextRef)[currentContext graphicsPort]; - CGContextSaveGState(context); - - [patternColor set]; - - wkSetPatternPhaseInUserSpace(context, point); - - NSRectFillUsingOperation(NSMakeRect(point.x(), point.y(), width, patternHeight), NSCompositeSourceOver); - - CGContextRestoreGState(context); -} - -} diff --git a/WebCore/platform/graphics/mac/IconMac.mm b/WebCore/platform/graphics/mac/IconMac.mm deleted file mode 100644 index 63abe59..0000000 --- a/WebCore/platform/graphics/mac/IconMac.mm +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * 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 - * along 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. - * - */ - -#import "config.h" -#import "Icon.h" - -#import "GraphicsContext.h" -#import "LocalCurrentGraphicsContext.h" -#import "PlatformString.h" -#import <wtf/PassRefPtr.h> - -namespace WebCore { - -Icon::Icon(NSImage *image) - : m_nsImage(image) -{ - // Need this because WebCore uses AppKit's flipped coordinate system exclusively. - [image setFlipped:YES]; -} - -Icon::~Icon() -{ -} - -PassRefPtr<Icon> Icon::createIconForFile(const String& filename) -{ - // Don't pass relative filenames -- we don't want a result that depends on the current directory. - // Need 0U here to disambiguate String::operator[] from operator(NSString*, int)[] - if (filename.isEmpty() || filename[0U] != '/') - return 0; - - NSImage* image = [[NSWorkspace sharedWorkspace] iconForFile:filename]; - if (!image) - return 0; - - return adoptRef(new Icon(image)); -} - -PassRefPtr<Icon> Icon::createIconForFiles(const Vector<String>& filenames) -{ - if (filenames.isEmpty()) - return 0; -#ifdef BUILDING_ON_TIGER - // FIXME: find a better image to use on Tiger. - return createIconForFile(filenames[0]); -#else - NSImage* image = [NSImage imageNamed:NSImageNameMultipleDocuments]; - if (!image) - return 0; - - return adoptRef(new Icon(image)); -#endif -} - -void Icon::paint(GraphicsContext* context, const IntRect& rect) -{ - if (context->paintingDisabled()) - return; - - LocalCurrentGraphicsContext localCurrentGC(context); - - [m_nsImage.get() drawInRect:rect - fromRect:NSMakeRect(0, 0, [m_nsImage.get() size].width, [m_nsImage.get() size].height) - operation:NSCompositeSourceOver fraction:1.0f]; -} - -} diff --git a/WebCore/platform/graphics/mac/ImageMac.mm b/WebCore/platform/graphics/mac/ImageMac.mm deleted file mode 100644 index a0d257b..0000000 --- a/WebCore/platform/graphics/mac/ImageMac.mm +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2008 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. - */ - -#import "config.h" -#import "BitmapImage.h" - -#import "FloatRect.h" -#import "FoundationExtras.h" -#import "GraphicsContext.h" -#import "PlatformString.h" - -@interface WebCoreBundleFinder : NSObject -@end - -@implementation WebCoreBundleFinder -@end - -namespace WebCore { - -void BitmapImage::initPlatformData() -{ -} - -void BitmapImage::invalidatePlatformData() -{ - if (m_frames.size() != 1) - return; - - m_nsImage = 0; - m_tiffRep = 0; -} - -PassRefPtr<Image> Image::loadPlatformResource(const char *name) -{ - NSBundle *bundle = [NSBundle bundleForClass:[WebCoreBundleFinder class]]; - NSString *imagePath = [bundle pathForResource:[NSString stringWithUTF8String:name] ofType:@"tiff"]; - NSData *namedImageData = [NSData dataWithContentsOfFile:imagePath]; - if (namedImageData) { - RefPtr<Image> image = BitmapImage::create(); - image->setData(SharedBuffer::wrapNSData(namedImageData), true); - return image.release(); - } - - // We have reports indicating resource loads are failing, but we don't yet know the root cause(s). - // Two theories are bad installs (image files are missing), and too-many-open-files. - // See rdar://5607381 - ASSERT_NOT_REACHED(); - return Image::nullImage(); -} - -CFDataRef BitmapImage::getTIFFRepresentation() -{ - if (m_tiffRep) - return m_tiffRep.get(); - - unsigned numFrames = frameCount(); - - // If numFrames is zero, we know for certain this image doesn't have valid data - // Even though the call to CGImageDestinationCreateWithData will fail and we'll handle it gracefully, - // in certain circumstances that call will spam the console with an error message - if (!numFrames) - return 0; - - Vector<CGImageRef> images; - for (unsigned i = 0; i < numFrames; ++i ) { - CGImageRef cgImage = frameAtIndex(i); - if (cgImage) - images.append(cgImage); - } - - unsigned numValidFrames = images.size(); - - RetainPtr<CFMutableDataRef> data(AdoptCF, CFDataCreateMutable(0, 0)); - // FIXME: Use type kCGImageTypeIdentifierTIFF constant once is becomes available in the API - CGImageDestinationRef destination = CGImageDestinationCreateWithData(data.get(), CFSTR("public.tiff"), numValidFrames, 0); - - if (!destination) - return 0; - - for (unsigned i = 0; i < numValidFrames; ++i) - CGImageDestinationAddImage(destination, images[i], 0); - - CGImageDestinationFinalize(destination); - CFRelease(destination); - - m_tiffRep = data; - return m_tiffRep.get(); -} - -NSImage* BitmapImage::getNSImage() -{ - if (m_nsImage) - return m_nsImage.get(); - - CFDataRef data = getTIFFRepresentation(); - if (!data) - return 0; - - m_nsImage.adoptNS([[NSImage alloc] initWithData:(NSData*)data]); - return m_nsImage.get(); -} - -} diff --git a/WebCore/platform/graphics/mac/IntPointMac.mm b/WebCore/platform/graphics/mac/IntPointMac.mm deleted file mode 100644 index 7a2e730..0000000 --- a/WebCore/platform/graphics/mac/IntPointMac.mm +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006 Apple Computer, 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h" -#include "IntPoint.h" - -namespace WebCore { - -#ifndef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - -IntPoint::IntPoint(const NSPoint& p) : m_x(static_cast<int>(p.x)), m_y(static_cast<int>(p.y)) -{ -} - -IntPoint::operator NSPoint() const -{ - return NSMakePoint(m_x, m_y); -} - -#endif - -} diff --git a/WebCore/platform/graphics/mac/IntRectMac.mm b/WebCore/platform/graphics/mac/IntRectMac.mm deleted file mode 100644 index 738618a..0000000 --- a/WebCore/platform/graphics/mac/IntRectMac.mm +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2003, 2006 Apple Computer, 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h" -#include "IntRect.h" - -namespace WebCore { - -#ifndef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - -IntRect::operator NSRect() const -{ - return NSMakeRect(x(), y(), width(), height()); -} - -IntRect enclosingIntRect(const NSRect& rect) -{ - int l = static_cast<int>(floorf(rect.origin.x)); - int t = static_cast<int>(floorf(rect.origin.y)); - int r = static_cast<int>(ceilf(NSMaxX(rect))); - int b = static_cast<int>(ceilf(NSMaxY(rect))); - return IntRect(l, t, r - l, b - t); -} - -#endif - -} diff --git a/WebCore/platform/graphics/mac/IntSizeMac.mm b/WebCore/platform/graphics/mac/IntSizeMac.mm deleted file mode 100644 index c7dcd88..0000000 --- a/WebCore/platform/graphics/mac/IntSizeMac.mm +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 "config.h" -#include "IntSize.h" - -namespace WebCore { - -#ifndef NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES - -IntSize::IntSize(const NSSize& s) : m_width(static_cast<int>(s.width)), m_height(static_cast<int>(s.height)) -{ -} - -IntSize::operator NSSize() const -{ - return NSMakeSize(m_width, m_height); -} - -#endif - -} diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h deleted file mode 100644 index 3f18ab4..0000000 --- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2007 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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 MediaPlayerPrivateQTKit_h -#define MediaPlayerPrivateQTKit_h - -#if ENABLE(VIDEO) - -#include "MediaPlayer.h" -#include "Timer.h" -#include <wtf/RetainPtr.h> - -#ifdef __OBJC__ -#import <QTKit/QTTime.h> -@class QTMovie; -@class QTMovieView; -@class QTVideoRendererWebKitOnly; -@class WebCoreMovieObserver; -#else -class QTMovie; -class QTMovieView; -class QTTime; -class QTVideoRendererWebKitOnly; -class WebCoreMovieObserver; -#endif - -#ifndef DRAW_FRAME_RATE -#define DRAW_FRAME_RATE 0 -#endif - -namespace WebCore { - -class MediaPlayerPrivate : Noncopyable { -public: - MediaPlayerPrivate(MediaPlayer*); - ~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 time); - - void setRate(float); - void setVolume(float); - - int dataRate() const; - - MediaPlayer::NetworkState networkState() const { return m_networkState; } - MediaPlayer::ReadyState readyState() const { return m_readyState; } - - float maxTimeBuffered() const; - float maxTimeSeekable() const; - unsigned bytesLoaded() const; - bool totalBytesKnown() const; - unsigned totalBytes() const; - - void setVisible(bool); - void setRect(const IntRect& r); - - void loadStateChanged(); - void rateChanged(); - void sizeChanged(); - void timeChanged(); - void didEnd(); - - void repaint(); - void paint(GraphicsContext*, const IntRect&); - - static void getSupportedTypes(HashSet<String>& types); - static bool isAvailable(); - -private: - void createQTMovie(const String& url); - void setUpVideoRendering(); - void tearDownVideoRendering(); - void createQTMovieView(); - void detachQTMovieView(); - void createQTVideoRenderer(); - void destroyQTVideoRenderer(); - QTTime createQTTime(float time) const; - - void updateStates(); - void doSeek(); - void cancelSeek(); - void seekTimerFired(Timer<MediaPlayerPrivate>*); - void endPointTimerFired(Timer<MediaPlayerPrivate>*); - float maxTimeLoaded() const; - void startEndPointTimerIfNeeded(); - void disableUnsupportedTracks(unsigned& enabledTrackCount); - - MediaPlayer* m_player; - RetainPtr<QTMovie> m_qtMovie; - RetainPtr<QTMovieView> m_qtMovieView; - RetainPtr<QTVideoRendererWebKitOnly> m_qtVideoRenderer; - RetainPtr<WebCoreMovieObserver> m_objcObserver; - float m_seekTo; - float m_endTime; - Timer<MediaPlayerPrivate> m_seekTimer; - Timer<MediaPlayerPrivate> m_endPointTimer; - MediaPlayer::NetworkState m_networkState; - MediaPlayer::ReadyState m_readyState; - bool m_startedPlaying; - bool m_isStreaming; - bool m_visible; -#if DRAW_FRAME_RATE - int m_frameCountWhilePlaying; - double m_timeStartedPlaying; - double m_timeStoppedPlaying; -#endif -}; - -} - -#endif -#endif diff --git a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm b/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm deleted file mode 100644 index 0ec56d6..0000000 --- a/WebCore/platform/graphics/mac/MediaPlayerPrivateQTKit.mm +++ /dev/null @@ -1,1024 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple 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: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``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 APPLE COMPUTER, INC. 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. - */ - -#import "config.h" - -#if ENABLE(VIDEO) - -#import "MediaPlayerPrivateQTKit.h" - -#import "BlockExceptions.h" -#import "GraphicsContext.h" -#import "KURL.h" -#import "FrameView.h" -#import "SoftLinking.h" -#import "WebCoreSystemInterface.h" -#import <QTKit/QTKit.h> -#import <objc/objc-runtime.h> - -#if DRAW_FRAME_RATE -#import "Font.h" -#import "Frame.h" -#import "Document.h" -#import "RenderObject.h" -#import "RenderStyle.h" -#endif - -#ifdef BUILDING_ON_TIGER -static IMP method_setImplementation(Method m, IMP imp) -{ - IMP result = m->method_imp; - m->method_imp = imp; - return result; -} -#endif - -SOFT_LINK_FRAMEWORK(QTKit) - -SOFT_LINK(QTKit, QTMakeTime, QTTime, (long long timeValue, long timeScale), (timeValue, timeScale)) - -SOFT_LINK_CLASS(QTKit, QTMovie) -SOFT_LINK_CLASS(QTKit, QTMovieView) - -SOFT_LINK_POINTER(QTKit, QTMediaTypeAttribute, NSString *) -SOFT_LINK_POINTER(QTKit, QTMediaTypeBase, NSString *) -SOFT_LINK_POINTER(QTKit, QTMediaTypeSound, NSString *) -SOFT_LINK_POINTER(QTKit, QTMediaTypeText, NSString *) -SOFT_LINK_POINTER(QTKit, QTMediaTypeVideo, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieAskUnresolvedDataRefsAttribute, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieDataSizeAttribute, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieDidEndNotification, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieHasVideoAttribute, NSString *) -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, QTMoviePreventExternalURLLinksAttribute, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieRateDidChangeNotification, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieSizeDidChangeNotification, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieTimeDidChangeNotification, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieTimeScaleAttribute, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieURLAttribute, NSString *) -SOFT_LINK_POINTER(QTKit, QTMovieVolumeDidChangeNotification, NSString *) -SOFT_LINK_POINTER(QTKit, QTSecurityPolicyNoCrossSiteAttribute, NSString *) -SOFT_LINK_POINTER(QTKit, QTVideoRendererWebKitOnlyNewImageAvailableNotification, NSString *) - -#define QTMovie getQTMovieClass() -#define QTMovieView getQTMovieViewClass() - -#define QTMediaTypeAttribute getQTMediaTypeAttribute() -#define QTMediaTypeBase getQTMediaTypeBase() -#define QTMediaTypeSound getQTMediaTypeSound() -#define QTMediaTypeText getQTMediaTypeText() -#define QTMediaTypeVideo getQTMediaTypeVideo() -#define QTMovieAskUnresolvedDataRefsAttribute getQTMovieAskUnresolvedDataRefsAttribute() -#define QTMovieDataSizeAttribute getQTMovieDataSizeAttribute() -#define QTMovieDidEndNotification getQTMovieDidEndNotification() -#define QTMovieHasVideoAttribute getQTMovieHasVideoAttribute() -#define QTMovieIsActiveAttribute getQTMovieIsActiveAttribute() -#define QTMovieLoadStateAttribute getQTMovieLoadStateAttribute() -#define QTMovieLoadStateDidChangeNotification getQTMovieLoadStateDidChangeNotification() -#define QTMovieNaturalSizeAttribute getQTMovieNaturalSizeAttribute() -#define QTMoviePreventExternalURLLinksAttribute getQTMoviePreventExternalURLLinksAttribute() -#define QTMovieRateDidChangeNotification getQTMovieRateDidChangeNotification() -#define QTMovieSizeDidChangeNotification getQTMovieSizeDidChangeNotification() -#define QTMovieTimeDidChangeNotification getQTMovieTimeDidChangeNotification() -#define QTMovieTimeScaleAttribute getQTMovieTimeScaleAttribute() -#define QTMovieURLAttribute getQTMovieURLAttribute() -#define QTMovieVolumeDidChangeNotification getQTMovieVolumeDidChangeNotification() -#define QTSecurityPolicyNoCrossSiteAttribute getQTSecurityPolicyNoCrossSiteAttribute() -#define QTVideoRendererWebKitOnlyNewImageAvailableNotification getQTVideoRendererWebKitOnlyNewImageAvailableNotification() - -// 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 -enum { - QTMovieLoadStateError = -1L, - QTMovieLoadStateLoaded = 2000L, - QTMovieLoadStatePlayable = 10000L, - QTMovieLoadStatePlaythroughOK = 20000L, - QTMovieLoadStateComplete = 100000L -}; -#endif - -using namespace WebCore; -using namespace std; - -@interface WebCoreMovieObserver : NSObject -{ - MediaPlayerPrivate* m_callback; - NSView* m_view; - BOOL m_delayCallbacks; -} --(id)initWithCallback:(MediaPlayerPrivate*)callback; --(void)disconnect; --(void)setView:(NSView*)view; --(void)repaint; --(void)setDelayCallbacks:(BOOL)shouldDelay; --(void)loadStateChanged:(NSNotification *)notification; --(void)rateChanged:(NSNotification *)notification; --(void)sizeChanged:(NSNotification *)notification; --(void)timeChanged:(NSNotification *)notification; --(void)didEnd:(NSNotification *)notification; -@end - -@protocol WebKitVideoRenderingDetails --(void)setMovie:(id)movie; --(void)drawInRect:(NSRect)rect; -@end - -namespace WebCore { - -static const float endPointTimerInterval = 0.020f; - -#ifdef BUILDING_ON_TIGER -static const long minimumQuickTimeVersion = 0x07300000; // 7.3 -#endif - -MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player) - : m_player(player) - , m_objcObserver(AdoptNS, [[WebCoreMovieObserver alloc] initWithCallback:this]) - , m_seekTo(-1) - , m_endTime(numeric_limits<float>::infinity()) - , m_seekTimer(this, &MediaPlayerPrivate::seekTimerFired) - , m_endPointTimer(this, &MediaPlayerPrivate::endPointTimerFired) - , m_networkState(MediaPlayer::Empty) - , m_readyState(MediaPlayer::DataUnavailable) - , m_startedPlaying(false) - , m_isStreaming(false) - , m_visible(false) -#if DRAW_FRAME_RATE - , m_frameCountWhilePlaying(0) - , m_timeStartedPlaying(0) - , m_timeStoppedPlaying(0) -#endif -{ -} - -MediaPlayerPrivate::~MediaPlayerPrivate() -{ - tearDownVideoRendering(); - - [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()]; - [m_objcObserver.get() disconnect]; -} - -void MediaPlayerPrivate::createQTMovie(const String& url) -{ - [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get()]; - - if (m_qtMovie) { - destroyQTVideoRenderer(); - m_qtMovie = 0; - } - - // Disable streaming support for now, <rdar://problem/5693967> - if (protocolIs(url, "rtsp")) - return; - - NSURL *cocoaURL = KURL(url); - NSDictionary *movieAttributes = [NSDictionary dictionaryWithObjectsAndKeys: - cocoaURL, QTMovieURLAttribute, - [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 - nil]; - - NSError* error = nil; - m_qtMovie.adoptNS([[QTMovie alloc] initWithAttributes:movieAttributes error:&error]); - - // FIXME: Find a proper way to detect streaming content. - m_isStreaming = protocolIs(url, "rtsp"); - - if (!m_qtMovie) - return; - - [m_qtMovie.get() setVolume:m_player->volume()]; - - [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() - selector:@selector(loadStateChanged:) - name:QTMovieLoadStateDidChangeNotification - object:m_qtMovie.get()]; - [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() - selector:@selector(rateChanged:) - name:QTMovieRateDidChangeNotification - object:m_qtMovie.get()]; - [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() - selector:@selector(sizeChanged:) - name:QTMovieSizeDidChangeNotification - object:m_qtMovie.get()]; - [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() - selector:@selector(timeChanged:) - name:QTMovieTimeDidChangeNotification - object:m_qtMovie.get()]; - [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() - selector:@selector(didEnd:) - name:QTMovieDidEndNotification - object:m_qtMovie.get()]; -} - -static void mainThreadSetNeedsDisplay(id self, SEL _cmd) -{ - id movieView = [self superview]; - ASSERT(!movieView || [movieView isKindOfClass:[QTMovieView class]]); - if (!movieView || ![movieView isKindOfClass:[QTMovieView class]]) - return; - - WebCoreMovieObserver* delegate = [movieView delegate]; - ASSERT(!delegate || [delegate isKindOfClass:[WebCoreMovieObserver class]]); - if (!delegate || ![delegate isKindOfClass:[WebCoreMovieObserver class]]) - return; - - [delegate repaint]; -} - -static Class QTVideoRendererClass() -{ - static Class QTVideoRendererWebKitOnlyClass = NSClassFromString(@"QTVideoRendererWebKitOnly"); - return QTVideoRendererWebKitOnlyClass; -} - -void MediaPlayerPrivate::createQTMovieView() -{ - detachQTMovieView(); - - static bool addedCustomMethods = false; - if (!addedCustomMethods) { - Class QTMovieContentViewClass = NSClassFromString(@"QTMovieContentView"); - ASSERT(QTMovieContentViewClass); - - Method mainThreadSetNeedsDisplayMethod = class_getInstanceMethod(QTMovieContentViewClass, @selector(_mainThreadSetNeedsDisplay)); - ASSERT(mainThreadSetNeedsDisplayMethod); - - method_setImplementation(mainThreadSetNeedsDisplayMethod, reinterpret_cast<IMP>(mainThreadSetNeedsDisplay)); - addedCustomMethods = true; - } - - m_qtMovieView.adoptNS([[QTMovieView alloc] init]); - setRect(m_player->rect()); - NSView* parentView = m_player->m_frameView->documentView(); - [parentView addSubview:m_qtMovieView.get()]; -#ifdef BUILDING_ON_TIGER - // setDelegate: isn't a public call in Tiger, so use performSelector to keep the compiler happy - [m_qtMovieView.get() performSelector:@selector(setDelegate:) withObject:m_objcObserver.get()]; -#else - [m_qtMovieView.get() setDelegate:m_objcObserver.get()]; -#endif - [m_objcObserver.get() setView:m_qtMovieView.get()]; - [m_qtMovieView.get() setMovie:m_qtMovie.get()]; - [m_qtMovieView.get() setControllerVisible:NO]; - [m_qtMovieView.get() setPreservesAspectRatio:NO]; - // the area not covered by video should be transparent - [m_qtMovieView.get() setFillColor:[NSColor clearColor]]; - - // If we're in a media document, allow QTMovieView to render in its default mode; - // otherwise tell it to draw synchronously. - // Note that we expect mainThreadSetNeedsDisplay to be invoked only when synchronous drawing is requested. - if (!m_player->inMediaDocument()) - wkQTMovieViewSetDrawSynchronously(m_qtMovieView.get(), YES); -} - -void MediaPlayerPrivate::detachQTMovieView() -{ - if (m_qtMovieView) { - [m_objcObserver.get() setView:nil]; -#ifdef BUILDING_ON_TIGER - // setDelegate: isn't a public call in Tiger, so use performSelector to keep the compiler happy - [m_qtMovieView.get() performSelector:@selector(setDelegate:) withObject:nil]; -#else - [m_qtMovieView.get() setDelegate:nil]; -#endif - [m_qtMovieView.get() removeFromSuperview]; - m_qtMovieView = nil; - } -} - -void MediaPlayerPrivate::createQTVideoRenderer() -{ - destroyQTVideoRenderer(); - - m_qtVideoRenderer.adoptNS([[QTVideoRendererClass() alloc] init]); - if (!m_qtVideoRenderer) - return; - - // associate our movie with our instance of QTVideoRendererWebKitOnly - [(id<WebKitVideoRenderingDetails>)m_qtVideoRenderer.get() setMovie:m_qtMovie.get()]; - - // listen to QTVideoRendererWebKitOnly's QTVideoRendererWebKitOnlyNewImageDidBecomeAvailableNotification - [[NSNotificationCenter defaultCenter] addObserver:m_objcObserver.get() - selector:@selector(newImageAvailable:) - name:QTVideoRendererWebKitOnlyNewImageAvailableNotification - object:m_qtVideoRenderer.get()]; -} - -void MediaPlayerPrivate::destroyQTVideoRenderer() -{ - if (!m_qtVideoRenderer) - return; - - // stop observing the renderer's notifications before we toss it - [[NSNotificationCenter defaultCenter] removeObserver:m_objcObserver.get() - name:QTVideoRendererWebKitOnlyNewImageAvailableNotification - object:m_qtVideoRenderer.get()]; - - // disassociate our movie from our instance of QTVideoRendererWebKitOnly - [(id<WebKitVideoRenderingDetails>)m_qtVideoRenderer.get() setMovie:nil]; - - m_qtVideoRenderer = nil; -} - -void MediaPlayerPrivate::setUpVideoRendering() -{ - if (!m_player->m_frameView || !m_qtMovie) - return; - - if (m_player->inMediaDocument() || !QTVideoRendererClass() ) - createQTMovieView(); - else - createQTVideoRenderer(); -} - -void MediaPlayerPrivate::tearDownVideoRendering() -{ - if (m_qtMovieView) - detachQTMovieView(); - else - destroyQTVideoRenderer(); -} - -QTTime MediaPlayerPrivate::createQTTime(float time) const -{ - if (!m_qtMovie) - return QTMakeTime(0, 600); - long timeScale = [[m_qtMovie.get() attributeForKey:QTMovieTimeScaleAttribute] longValue]; - return QTMakeTime(time * timeScale, timeScale); -} - -void MediaPlayerPrivate::load(const String& url) -{ - if (m_networkState != MediaPlayer::Loading) { - m_networkState = MediaPlayer::Loading; - m_player->networkStateChanged(); - } - if (m_readyState != MediaPlayer::DataUnavailable) { - m_readyState = MediaPlayer::DataUnavailable; - m_player->readyStateChanged(); - } - cancelSeek(); - m_endPointTimer.stop(); - - [m_objcObserver.get() setDelayCallbacks:YES]; - - createQTMovie(url); - - [m_objcObserver.get() loadStateChanged:nil]; - [m_objcObserver.get() setDelayCallbacks:NO]; -} - -void MediaPlayerPrivate::play() -{ - if (!m_qtMovie) - return; - m_startedPlaying = true; -#if DRAW_FRAME_RATE - m_frameCountWhilePlaying = 0; -#endif - [m_objcObserver.get() setDelayCallbacks:YES]; - [m_qtMovie.get() setRate:m_player->rate()]; - [m_objcObserver.get() setDelayCallbacks:NO]; - startEndPointTimerIfNeeded(); -} - -void MediaPlayerPrivate::pause() -{ - if (!m_qtMovie) - return; - m_startedPlaying = false; -#if DRAW_FRAME_RATE - m_timeStoppedPlaying = [NSDate timeIntervalSinceReferenceDate]; -#endif - [m_objcObserver.get() setDelayCallbacks:YES]; - [m_qtMovie.get() stop]; - [m_objcObserver.get() setDelayCallbacks:NO]; - m_endPointTimer.stop(); -} - -float MediaPlayerPrivate::duration() const -{ - if (!m_qtMovie) - return 0; - QTTime time = [m_qtMovie.get() duration]; - if (time.flags == kQTTimeIsIndefinite) - return numeric_limits<float>::infinity(); - return static_cast<float>(time.timeValue) / time.timeScale; -} - -float MediaPlayerPrivate::currentTime() const -{ - if (!m_qtMovie) - return 0; - QTTime time = [m_qtMovie.get() currentTime]; - return min(static_cast<float>(time.timeValue) / time.timeScale, m_endTime); -} - -void MediaPlayerPrivate::seek(float time) -{ - cancelSeek(); - - if (!m_qtMovie) - return; - - if (time > duration()) - time = duration(); - - m_seekTo = time; - if (maxTimeLoaded() >= m_seekTo) - doSeek(); - else - m_seekTimer.start(0, 0.5f); -} - -void MediaPlayerPrivate::doSeek() -{ - QTTime qttime = createQTTime(m_seekTo); - // setCurrentTime generates several event callbacks, update afterwards - [m_objcObserver.get() setDelayCallbacks:YES]; - float oldRate = [m_qtMovie.get() rate]; - [m_qtMovie.get() setRate:0]; - [m_qtMovie.get() setCurrentTime:qttime]; - float timeAfterSeek = currentTime(); - // restore playback only if not at end, othewise QTMovie will loop - if (timeAfterSeek < duration() && timeAfterSeek < m_endTime) - [m_qtMovie.get() setRate:oldRate]; - cancelSeek(); - [m_objcObserver.get() setDelayCallbacks:NO]; -} - -void MediaPlayerPrivate::cancelSeek() -{ - m_seekTo = -1; - m_seekTimer.stop(); -} - -void MediaPlayerPrivate::seekTimerFired(Timer<MediaPlayerPrivate>*) -{ - if (!m_qtMovie || !seeking() || currentTime() == m_seekTo) { - cancelSeek(); - updateStates(); - m_player->timeChanged(); - return; - } - - if (maxTimeLoaded() >= m_seekTo) - doSeek(); - else { - MediaPlayer::NetworkState state = networkState(); - if (state == MediaPlayer::Empty || state == MediaPlayer::Loaded) { - cancelSeek(); - updateStates(); - m_player->timeChanged(); - } - } -} - -void MediaPlayerPrivate::setEndTime(float time) -{ - m_endTime = time; - startEndPointTimerIfNeeded(); -} - -void MediaPlayerPrivate::startEndPointTimerIfNeeded() -{ - if (m_endTime < duration() && m_startedPlaying && !m_endPointTimer.isActive()) - m_endPointTimer.startRepeating(endPointTimerInterval); -} - -void MediaPlayerPrivate::endPointTimerFired(Timer<MediaPlayerPrivate>*) -{ - float time = currentTime(); - - // just do end for now - if (time >= m_endTime) { - pause(); - didEnd(); - } -} - -bool MediaPlayerPrivate::paused() const -{ - if (!m_qtMovie) - return true; - return [m_qtMovie.get() rate] == 0; -} - -bool MediaPlayerPrivate::seeking() const -{ - if (!m_qtMovie) - return false; - return m_seekTo >= 0; -} - -IntSize MediaPlayerPrivate::naturalSize() const -{ - if (!m_qtMovie) - return IntSize(); - return IntSize([[m_qtMovie.get() attributeForKey:QTMovieNaturalSizeAttribute] sizeValue]); -} - -bool MediaPlayerPrivate::hasVideo() const -{ - if (!m_qtMovie) - return false; - return [[m_qtMovie.get() attributeForKey:QTMovieHasVideoAttribute] boolValue]; -} - -void MediaPlayerPrivate::setVolume(float volume) -{ - if (!m_qtMovie) - return; - [m_qtMovie.get() setVolume:volume]; -} - -void MediaPlayerPrivate::setRate(float rate) -{ - if (!m_qtMovie) - return; - if (!paused()) - [m_qtMovie.get() setRate:rate]; -} - -int MediaPlayerPrivate::dataRate() const -{ - if (!m_qtMovie) - return 0; - return wkQTMovieDataRate(m_qtMovie.get()); -} - - -float MediaPlayerPrivate::maxTimeBuffered() const -{ - // rtsp streams are not buffered - return m_isStreaming ? 0 : maxTimeLoaded(); -} - -float MediaPlayerPrivate::maxTimeSeekable() const -{ - // infinite duration means live stream - return isinf(duration()) ? 0 : maxTimeLoaded(); -} - -float MediaPlayerPrivate::maxTimeLoaded() const -{ - if (!m_qtMovie) - return 0; - return wkQTMovieMaxTimeLoaded(m_qtMovie.get()); -} - -unsigned MediaPlayerPrivate::bytesLoaded() const -{ - float dur = duration(); - if (!dur) - return 0; - return totalBytes() * maxTimeLoaded() / dur; -} - -bool MediaPlayerPrivate::totalBytesKnown() const -{ - return totalBytes() > 0; -} - -unsigned MediaPlayerPrivate::totalBytes() const -{ - if (!m_qtMovie) - return 0; - return [[m_qtMovie.get() attributeForKey:QTMovieDataSizeAttribute] intValue]; -} - -void MediaPlayerPrivate::cancelLoad() -{ - // FIXME: Is there a better way to check for this? - if (m_networkState < MediaPlayer::Loading || m_networkState == MediaPlayer::Loaded) - return; - - tearDownVideoRendering(); - m_qtMovie = nil; - - updateStates(); -} - -void MediaPlayerPrivate::updateStates() -{ - MediaPlayer::NetworkState oldNetworkState = m_networkState; - MediaPlayer::ReadyState oldReadyState = m_readyState; - - long loadState = m_qtMovie ? [[m_qtMovie.get() attributeForKey:QTMovieLoadStateAttribute] longValue] : static_cast<long>(QTMovieLoadStateError); - - if (loadState >= QTMovieLoadStateLoaded && m_networkState < MediaPlayer::LoadedMetaData && !m_player->inMediaDocument()) { - unsigned enabledTrackCount; - disableUnsupportedTracks(enabledTrackCount); - // FIXME: We should differentiate between load errors and decode errors <rdar://problem/5605692> - if (!enabledTrackCount) - loadState = QTMovieLoadStateError; - } - - // "Loaded" is reserved for fully buffered movies, never the case when streaming - if (loadState >= QTMovieLoadStateComplete && !m_isStreaming) { - if (m_networkState < MediaPlayer::Loaded) - m_networkState = MediaPlayer::Loaded; - m_readyState = MediaPlayer::CanPlayThrough; - } else if (loadState >= QTMovieLoadStatePlaythroughOK) { - if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking()) - m_networkState = MediaPlayer::LoadedFirstFrame; - m_readyState = MediaPlayer::CanPlayThrough; - } else if (loadState >= QTMovieLoadStatePlayable) { - if (m_networkState < MediaPlayer::LoadedFirstFrame && !seeking()) - m_networkState = MediaPlayer::LoadedFirstFrame; - // FIXME: This might not work correctly in streaming case, <rdar://problem/5693967> - m_readyState = currentTime() < maxTimeLoaded() ? MediaPlayer::CanPlay : MediaPlayer::DataUnavailable; - } else if (loadState >= QTMovieLoadStateLoaded) { - if (m_networkState < MediaPlayer::LoadedMetaData) - m_networkState = MediaPlayer::LoadedMetaData; - m_readyState = MediaPlayer::DataUnavailable; - } else if (loadState > QTMovieLoadStateError) { - if (m_networkState < MediaPlayer::Loading) - m_networkState = MediaPlayer::Loading; - m_readyState = MediaPlayer::DataUnavailable; - } else { - m_networkState = MediaPlayer::LoadFailed; - m_readyState = MediaPlayer::DataUnavailable; - } - - if (seeking()) - m_readyState = MediaPlayer::DataUnavailable; - - if (m_networkState != oldNetworkState) - m_player->networkStateChanged(); - if (m_readyState != oldReadyState) - m_player->readyStateChanged(); - - if (loadState >= QTMovieLoadStateLoaded && oldNetworkState < MediaPlayer::LoadedMetaData && m_player->visible()) - setUpVideoRendering(); -} - -void MediaPlayerPrivate::loadStateChanged() -{ - updateStates(); -} - -void MediaPlayerPrivate::rateChanged() -{ - updateStates(); -} - -void MediaPlayerPrivate::sizeChanged() -{ -} - -void MediaPlayerPrivate::timeChanged() -{ - updateStates(); - m_player->timeChanged(); -} - -void MediaPlayerPrivate::didEnd() -{ - m_endPointTimer.stop(); - m_startedPlaying = false; -#if DRAW_FRAME_RATE - m_timeStoppedPlaying = [NSDate timeIntervalSinceReferenceDate]; -#endif - updateStates(); - m_player->timeChanged(); -} - -void MediaPlayerPrivate::setRect(const IntRect& r) -{ - if (!m_qtMovieView) - return; - - if (m_player->inMediaDocument()) - // We need the QTMovieView to be placed in the proper location for document mode. - [m_qtMovieView.get() setFrame:r]; - 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(r); - farAwayButCorrectSize.move(-1000000, -1000000); - [m_qtMovieView.get() setFrame:farAwayButCorrectSize]; - } -} - -void MediaPlayerPrivate::setVisible(bool b) -{ - if (m_visible != b) { - m_visible = b; - if (b) { - if (m_networkState >= MediaPlayer::LoadedMetaData) - setUpVideoRendering(); - } else - tearDownVideoRendering(); - } -} - -void MediaPlayerPrivate::repaint() -{ -#if DRAW_FRAME_RATE - if (m_startedPlaying) { - m_frameCountWhilePlaying++; - // to eliminate preroll costs from our calculation, - // our frame rate calculation excludes the first frame drawn after playback starts - if (1==m_frameCountWhilePlaying) - m_timeStartedPlaying = [NSDate timeIntervalSinceReferenceDate]; - } -#endif - m_player->repaint(); -} - -void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& r) -{ - if (context->paintingDisabled()) - return; - NSView *view = m_qtMovieView.get(); - id qtVideoRenderer = m_qtVideoRenderer.get(); - if (!view && !qtVideoRenderer) - return; - - [m_objcObserver.get() setDelayCallbacks:YES]; - BEGIN_BLOCK_OBJC_EXCEPTIONS; - context->save(); - context->translate(r.x(), r.y() + r.height()); - context->scale(FloatSize(1.0f, -1.0f)); - context->setImageInterpolationQuality(InterpolationLow); - IntRect paintRect(IntPoint(0, 0), IntSize(r.width(), r.height())); - NSGraphicsContext* newContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context->platformContext() flipped:NO]; - - // draw the current video frame - if (qtVideoRenderer) { - [NSGraphicsContext saveGraphicsState]; - [NSGraphicsContext setCurrentContext:newContext]; - [(id<WebKitVideoRenderingDetails>)qtVideoRenderer drawInRect:paintRect]; - [NSGraphicsContext restoreGraphicsState]; - } else - [view displayRectIgnoringOpacity:paintRect inContext:newContext]; - -#if DRAW_FRAME_RATE - // Draw the frame rate only after having played more than 10 frames. - if (m_frameCountWhilePlaying > 10) { - Frame* frame = m_player->m_frameView ? m_player->m_frameView->frame() : NULL; - Document* document = frame ? frame->document() : NULL; - RenderObject* renderer = document ? document->renderer() : NULL; - RenderStyle* styleToUse = renderer ? renderer->style() : NULL; - if (styleToUse) { - double frameRate = (m_frameCountWhilePlaying - 1) / ( m_startedPlaying ? ([NSDate timeIntervalSinceReferenceDate] - m_timeStartedPlaying) : - (m_timeStoppedPlaying - m_timeStartedPlaying) ); - String text = String::format("%1.2f", frameRate); - TextRun textRun(text.characters(), text.length()); - const Color color(255, 0, 0); - context->scale(FloatSize(1.0f, -1.0f)); - context->setFont(styleToUse->font()); - context->setStrokeColor(color); - context->setStrokeStyle(SolidStroke); - context->setStrokeThickness(1.0f); - context->setFillColor(color); - context->drawText(textRun, IntPoint(2, -3)); - } - } -#endif - - context->restore(); - END_BLOCK_OBJC_EXCEPTIONS; - [m_objcObserver.get() setDelayCallbacks:NO]; -} - -void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types) -{ - 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; - types.add(mime.get()); - } -} - -bool MediaPlayerPrivate::isAvailable() -{ -#ifdef BUILDING_ON_TIGER - SInt32 version; - OSErr result; - result = Gestalt(gestaltQuickTime, &version); - if (result != noErr) { - LOG_ERROR("No QuickTime available. Disabling <video> and <audio> support."); - return false; - } - if (version < minimumQuickTimeVersion) { - LOG_ERROR("QuickTime version %x detected, at least %x required. Disabling <video> and <audio> support.", version, minimumQuickTimeVersion); - return false; - } - return true; -#else - // On 10.5 and higher, QuickTime will always be new enough for <video> and <audio> support, so we just check that the framework can be loaded. - return QTKitLibrary(); -#endif -} - -void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount) -{ - if (!m_qtMovie) { - enabledTrackCount = 0; - return; - } - - static HashSet<String>* allowedTrackTypes = 0; - if (!allowedTrackTypes) { - allowedTrackTypes = new HashSet<String>; - allowedTrackTypes->add(QTMediaTypeVideo); - allowedTrackTypes->add(QTMediaTypeSound); - allowedTrackTypes->add(QTMediaTypeText); - allowedTrackTypes->add(QTMediaTypeBase); - allowedTrackTypes->add("clcp"); - allowedTrackTypes->add("sbtl"); - } - - NSArray *tracks = [m_qtMovie.get() tracks]; - - unsigned trackCount = [tracks count]; - enabledTrackCount = trackCount; - for (unsigned trackIndex = 0; trackIndex < trackCount; 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]; - if (!track) - continue; - - // Check to see if the track is disabled already, we should move along. - // We don't need to re-disable it. - 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]; - 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]; - --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. - QTTrack *chapterTrack = [track performSelector:@selector(chapterlist)]; - if (!chapterTrack) - continue; - - // Try to grab the media for the track. - QTMedia *chapterMedia = [chapterTrack media]; - if (!chapterMedia) - continue; - - // Grab the media type for this track. - id chapterMediaType = [chapterMedia attributeForKey:QTMediaTypeAttribute]; - if (!chapterMediaType) - continue; - - // Check to see if the track is a video track. We don't care about - // other non-video tracks. - if (![chapterMediaType isEqual:QTMediaTypeVideo]) - continue; - - // Check to see if the track is already disabled. If it is, we - // should move along. - if (![chapterTrack isEnabled]) - continue; - - // Disable the evil, evil track. - [chapterTrack setEnabled:NO]; - --enabledTrackCount; - } -} - -} - -@implementation WebCoreMovieObserver - -- (id)initWithCallback:(MediaPlayerPrivate *)callback -{ - m_callback = callback; - return [super init]; -} - -- (void)disconnect -{ - [NSObject cancelPreviousPerformRequestsWithTarget:self]; - m_callback = 0; -} - --(NSMenu*)menuForEventDelegate:(NSEvent*)theEvent -{ - // Get the contextual menu from the QTMovieView's superview, the frame view - return [[m_view superview] menuForEvent:theEvent]; -} - --(void)setView:(NSView*)view -{ - m_view = view; -} - --(void)repaint -{ - if (m_delayCallbacks) - [self performSelector:_cmd withObject:nil afterDelay:0.]; - else if (m_callback) - m_callback->repaint(); -} - -- (void)loadStateChanged:(NSNotification *)notification -{ - if (m_delayCallbacks) - [self performSelector:_cmd withObject:nil afterDelay:0]; - else - m_callback->loadStateChanged(); -} - -- (void)rateChanged:(NSNotification *)notification -{ - if (m_delayCallbacks) - [self performSelector:_cmd withObject:nil afterDelay:0]; - else - m_callback->rateChanged(); -} - -- (void)sizeChanged:(NSNotification *)notification -{ - if (m_delayCallbacks) - [self performSelector:_cmd withObject:nil afterDelay:0]; - else - m_callback->sizeChanged(); -} - -- (void)timeChanged:(NSNotification *)notification -{ - if (m_delayCallbacks) - [self performSelector:_cmd withObject:nil afterDelay:0]; - else - m_callback->timeChanged(); -} - -- (void)didEnd:(NSNotification *)notification -{ - if (m_delayCallbacks) - [self performSelector:_cmd withObject:nil afterDelay:0]; - else - m_callback->didEnd(); -} - -- (void)newImageAvailable:(NSNotification *)notification -{ - [self repaint]; -} - -- (void)setDelayCallbacks:(BOOL)shouldDelay -{ - m_delayCallbacks = shouldDelay; -} - -@end - -#endif diff --git a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm b/WebCore/platform/graphics/mac/SimpleFontDataMac.mm deleted file mode 100644 index 4ee5933..0000000 --- a/WebCore/platform/graphics/mac/SimpleFontDataMac.mm +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2006 Alexey Proskuryakov - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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. - */ - -#import "config.h" -#import "SimpleFontData.h" - -#import "BlockExceptions.h" -#import "Color.h" -#import "FloatRect.h" -#import "Font.h" -#import "FontCache.h" -#import "FontDescription.h" -#import "SharedBuffer.h" -#import "WebCoreSystemInterface.h" -#import <ApplicationServices/ApplicationServices.h> -#import <float.h> -#import <unicode/uchar.h> -#import <wtf/Assertions.h> -#import <wtf/RetainPtr.h> - -@interface NSFont (WebAppKitSecretAPI) -- (BOOL)_isFakeFixedPitch; -@end - -namespace WebCore { - -const float smallCapsFontSizeMultiplier = 0.7f; -const float contextDPI = 72.0f; -static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x * (contextDPI / (contextDPI * unitsPerEm)); } - -bool initFontData(SimpleFontData* fontData) -{ - if (!fontData->m_font.cgFont()) - return false; - -#ifdef BUILDING_ON_TIGER - ATSUStyle fontStyle; - if (ATSUCreateStyle(&fontStyle) != noErr) - return false; - - ATSUFontID fontId = fontData->m_font.m_atsuFontID; - if (!fontId) { - ATSUDisposeStyle(fontStyle); - return false; - } - - ATSUAttributeTag tag = kATSUFontTag; - ByteCount size = sizeof(ATSUFontID); - ATSUFontID *valueArray[1] = {&fontId}; - OSStatus status = ATSUSetAttributes(fontStyle, 1, &tag, &size, (void* const*)valueArray); - if (status != noErr) { - ATSUDisposeStyle(fontStyle); - return false; - } - - if (wkGetATSStyleGroup(fontStyle, &fontData->m_styleGroup) != noErr) { - ATSUDisposeStyle(fontStyle); - return false; - } - - ATSUDisposeStyle(fontStyle); -#endif - - return true; -} - -static NSString *webFallbackFontFamily(void) -{ - static RetainPtr<NSString> webFallbackFontFamily = nil; - if (!webFallbackFontFamily) - webFallbackFontFamily = [[NSFont systemFontOfSize:16.0f] familyName]; - return webFallbackFontFamily.get(); -} - -#if !ERROR_DISABLED -#ifdef __LP64__ -static NSString* pathFromFont(NSFont*) -{ - // FMGetATSFontRefFromFont is not available in 64-bit. As pathFromFont is only used for debugging - // purposes, returning nil is acceptable. - return nil; -} -#else -static NSString* pathFromFont(NSFont *font) -{ -#ifndef BUILDING_ON_TIGER - ATSFontRef atsFont = FMGetATSFontRefFromFont(CTFontGetPlatformFont(toCTFontRef(font), 0)); -#else - ATSFontRef atsFont = FMGetATSFontRefFromFont(wkGetNSFontATSUFontId(font)); -#endif - FSRef fileRef; - -#ifndef BUILDING_ON_TIGER - OSStatus status = ATSFontGetFileReference(atsFont, &fileRef); - if (status != noErr) - return nil; -#else - FSSpec oFile; - OSStatus status = ATSFontGetFileSpecification(atsFont, &oFile); - if (status != noErr) - return nil; - - status = FSpMakeFSRef(&oFile, &fileRef); - if (status != noErr) - return nil; -#endif - - UInt8 filePathBuffer[PATH_MAX]; - status = FSRefMakePath(&fileRef, filePathBuffer, PATH_MAX); - if (status == noErr) - return [NSString stringWithUTF8String:(const char*)filePathBuffer]; - - return nil; -} -#endif // __LP64__ -#endif // !ERROR_DISABLED - -void SimpleFontData::platformInit() -{ -#ifdef BUILDING_ON_TIGER - m_styleGroup = 0; -#endif -#if USE(ATSUI) - m_ATSUStyleInitialized = false; - m_ATSUMirrors = false; - m_checkedShapesArabic = false; - m_shapesArabic = false; -#endif - - m_syntheticBoldOffset = m_font.m_syntheticBold ? 1.0f : 0.f; - - bool failedSetup = false; - if (!initFontData(this)) { - // Ack! Something very bad happened, like a corrupt font. - // Try looking for an alternate 'base' font for this renderer. - - // Special case hack to use "Times New Roman" in place of "Times". - // "Times RO" is a common font whose family name is "Times". - // 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"]) - fallbackFontFamily = @"Times New Roman"; - else - fallbackFontFamily = webFallbackFontFamily(); - - // 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(); -#endif - if (m_font.font()) - m_font.setFont([[NSFontManager sharedFontManager] convertFont:m_font.font() toFamily:fallbackFontFamily]); - else - m_font.setFont([NSFont fontWithName:fallbackFontFamily size:m_font.size()]); -#if !ERROR_DISABLED - NSString *filePath = pathFromFont(initialFont.get()); - if (!filePath) - filePath = @"not known"; -#endif - if (!initFontData(this)) { - 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()]); - 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); - failedSetup = true; - } - } else { - // We tried the requested font and the system font. No joy. We have to give up. - LOG_ERROR("unable to initialize with font %@ at %@", initialFont.get(), filePath); - failedSetup = true; - } - } - - // Report the problem. - LOG_ERROR("Corrupt font detected, using %@ in place of %@ located at \"%@\".", - [m_font.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()); - initFontData(this); - } - - int iAscent; - int iDescent; - int iLineGap; -#ifdef BUILDING_ON_TIGER - wkGetFontMetrics(m_font.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()); -#endif - - float pointSize = m_font.m_size; - float fAscent = scaleEmToUnits(iAscent, m_unitsPerEm) * pointSize; - float fDescent = -scaleEmToUnits(iDescent, m_unitsPerEm) * pointSize; - float fLineGap = scaleEmToUnits(iLineGap, m_unitsPerEm) * pointSize; - - // We need to adjust Times, Helvetica, and Courier to closely match the - // vertical metrics of their Microsoft counterparts that are the de facto - // 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]; - if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"]) - fAscent += floorf(((fAscent + fDescent) * 0.15f) + 0.5f); - else if ([familyName isEqualToString:@"Geeza Pro"]) { - // Geeza Pro has glyphs that draw slightly above the ascent or far below the descent. Adjust - // those vertical metrics to better match reality, so that diacritics at the bottom of one line - // do not overlap diacritics at the top of the next line. - fAscent *= 1.08f; - fDescent *= 2.f; - } - - m_ascent = lroundf(fAscent); - m_descent = lroundf(fDescent); - m_lineGap = lroundf(fLineGap); - m_lineSpacing = m_ascent + m_descent + m_lineGap; - - // Hack Hiragino line metrics to allow room for marked text underlines. - // <rdar://problem/5386183> - if (m_descent < 3 && m_lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) { - m_lineGap -= 3 - m_descent; - m_descent = 3; - } - - // 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) { - NSRect xBox = [m_font.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]; -} - -void SimpleFontData::platformDestroy() -{ -#ifdef BUILDING_ON_TIGER - if (m_styleGroup) - wkReleaseStyleGroup(m_styleGroup); -#endif -#if USE(ATSUI) - if (m_ATSUStyleInitialized) - ATSUDisposeStyle(m_ATSUStyle); -#endif -} - -SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const -{ - if (!m_smallCapsFontData) { - if (isCustomFont()) { - FontPlatformData smallCapsFontData(m_font); - 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]); - - // AppKit resets the type information (screen/printer) when you convert a font to a different size. - // We have to fix up the font that we're handed back. - smallCapsFont.setFont(fontDescription.usePrinterFont() ? [smallCapsFont.font() printerFont] : [smallCapsFont.font() screenFont]); - - if (smallCapsFont.font()) { - NSFontManager *fontManager = [NSFontManager sharedFontManager]; - NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_font.font()]; - - if (m_font.m_syntheticBold) - fontTraits |= NSBoldFontMask; - if (m_font.m_syntheticOblique) - fontTraits |= NSItalicFontMask; - - NSFontTraitMask smallCapsFontTraits = [fontManager traitsOfFont:smallCapsFont.font()]; - smallCapsFont.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(smallCapsFontTraits & NSBoldFontMask); - smallCapsFont.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(smallCapsFontTraits & NSItalicFontMask); - - m_smallCapsFontData = FontCache::getCachedFontData(&smallCapsFont); - } - END_BLOCK_OBJC_EXCEPTIONS; - } - } - return m_smallCapsFontData; -} - -bool SimpleFontData::containsCharacters(const UChar* characters, int length) const -{ - NSString *string = [[NSString alloc] initWithCharactersNoCopy:(UniChar*)characters length:length freeWhenDone:NO]; - NSCharacterSet *set = [[m_font.font() coveredCharacterSet] invertedSet]; - bool result = set && [string rangeOfCharacterFromSet:set].location == NSNotFound; - [string release]; - return result; -} - -void SimpleFontData::determinePitch() -{ - NSFont* f = m_font.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. - - // Special case MS-PGothic. - // According to <rdar://problem/4032938>, we should not treat MS-PGothic as fixed pitch. - // Note that AppKit does report MS-PGothic as fixed pitch. - - // Special case MonotypeCorsiva - // According to <rdar://problem/5454704>, we should not treat MonotypeCorsiva as fixed pitch. - // Note that AppKit does report MonotypeCorsiva as fixed pitch. - - NSString *name = [f fontName]; - m_treatAsFixedPitch = ([f isFixedPitch] || [f _isFakeFixedPitch] || - [name caseInsensitiveCompare:@"Osaka-Mono"] == NSOrderedSame) && - [name caseInsensitiveCompare:@"MS-PGothic"] != NSOrderedSame && - [name caseInsensitiveCompare:@"MonotypeCorsiva"] != NSOrderedSame; -} - -float SimpleFontData::platformWidthForGlyph(Glyph glyph) const -{ - NSFont* font = m_font.font(); - float pointSize = m_font.m_size; - CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize); - CGSize advance; - if (!wkGetGlyphTransformedAdvances(m_font.cgFont(), font, &m, &glyph, &advance)) { - LOG_ERROR("Unable to cache glyph widths for %@ %f", [font displayName], pointSize); - advance.width = 0; - } - return advance.width + m_syntheticBoldOffset; -} - -#if USE(ATSUI) -void SimpleFontData::checkShapesArabic() const -{ - ASSERT(!m_checkedShapesArabic); - - m_checkedShapesArabic = true; - - ATSUFontID fontID = m_font.m_atsuFontID; - if (!fontID) { - LOG_ERROR("unable to get ATSUFontID for %@", m_font.font()); - return; - } - - // This function is called only on fonts that contain Arabic glyphs. Our - // heuristic is that if such a font has a glyph metamorphosis table, then - // it includes shaping information for Arabic. - FourCharCode tables[] = { 'morx', 'mort' }; - for (unsigned i = 0; i < sizeof(tables) / sizeof(tables[0]); ++i) { - ByteCount tableSize; - OSStatus status = ATSFontGetTable(fontID, tables[i], 0, 0, 0, &tableSize); - if (status == noErr) { - m_shapesArabic = true; - return; - } - - if (status != kATSInvalidFontTableAccess) - LOG_ERROR("ATSFontGetTable failed (%d)", status); - } -} -#endif - -#if USE(CORE_TEXT) -CTFontRef SimpleFontData::getCTFont() const -{ - if (getNSFont()) - return toCTFontRef(getNSFont()); - if (!m_CTFont) - m_CTFont.adoptCF(CTFontCreateWithGraphicsFont(m_font.cgFont(), m_font.size(), NULL, NULL)); - return m_CTFont.get(); -} - -CFDictionaryRef SimpleFontData::getCFStringAttributes() const -{ - if (m_CFStringAttributes) - return m_CFStringAttributes.get(); - - static const float kerningAdjustmentValue = 0; - static CFNumberRef kerningAdjustment = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &kerningAdjustmentValue); - - static const int ligaturesNotAllowedValue = 0; - static CFNumberRef ligaturesNotAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesNotAllowedValue); - - static const int ligaturesAllowedValue = 1; - static CFNumberRef ligaturesAllowed = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &ligaturesAllowedValue); - - static const void* attributeKeys[] = { kCTFontAttributeName, kCTKernAttributeName, kCTLigatureAttributeName }; - const void* attributeValues[] = { getCTFont(), kerningAdjustment, platformData().allowsLigatures() ? ligaturesAllowed : ligaturesNotAllowed }; - - m_CFStringAttributes.adoptCF(CFDictionaryCreate(NULL, attributeKeys, attributeValues, sizeof(attributeKeys) / sizeof(*attributeKeys), &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); - - return m_CFStringAttributes.get(); -} - -#endif - -} // namespace WebCore |