oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 1 | /* |
mitz@apple.com | 26b747a | 2008-04-01 05:49:35 +0000 | [diff] [blame] | 2 | * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions |
| 6 | * are met: |
| 7 | * 1. Redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer. |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer in the |
| 11 | * documentation and/or other materials provided with the distribution. |
| 12 | * |
| 13 | * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| 14 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 15 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 18 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 20 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 21 | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 | */ |
| 25 | |
| 26 | #include "config.h" |
| 27 | #include "CachedFont.h" |
| 28 | |
| 29 | #include "Cache.h" |
| 30 | #include "CachedResourceClient.h" |
| 31 | #include "CachedResourceClientWalker.h" |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 32 | #include "DOMImplementation.h" |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 33 | #include "FontPlatformData.h" |
alp@webkit.org | c55e590 | 2008-01-11 21:58:11 +0000 | [diff] [blame] | 34 | #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 35 | #include "FontCustomPlatformData.h" |
| 36 | #endif |
| 37 | #include "TextResourceDecoder.h" |
| 38 | #include "loader.h" |
| 39 | #include <wtf/Vector.h> |
| 40 | |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 41 | #if ENABLE(SVG_FONTS) |
| 42 | #include "HTMLNames.h" |
| 43 | #include "NodeList.h" |
| 44 | #include "SVGElement.h" |
| 45 | #include "SVGFontElement.h" |
| 46 | #include "SVGGElement.h" |
| 47 | #endif |
| 48 | |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 49 | namespace WebCore { |
| 50 | |
antti@apple.com | b4122c5 | 2008-03-25 19:21:00 +0000 | [diff] [blame] | 51 | CachedFont::CachedFont(const String &url) |
mitz@apple.com | 0fec5b4 | 2008-01-30 04:32:50 +0000 | [diff] [blame] | 52 | : CachedResource(url, FontResource) |
| 53 | , m_fontData(0) |
antti@apple.com | b4122c5 | 2008-03-25 19:21:00 +0000 | [diff] [blame] | 54 | , m_loadInitiated(false) |
mitz@apple.com | 0fec5b4 | 2008-01-30 04:32:50 +0000 | [diff] [blame] | 55 | #if ENABLE(SVG_FONTS) |
mitz@apple.com | 2eb96ca | 2008-01-30 03:50:08 +0000 | [diff] [blame] | 56 | , m_isSVGFont(false) |
mitz@apple.com | 0fec5b4 | 2008-01-30 04:32:50 +0000 | [diff] [blame] | 57 | #endif |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 58 | { |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | CachedFont::~CachedFont() |
| 62 | { |
alp@webkit.org | c55e590 | 2008-01-11 21:58:11 +0000 | [diff] [blame] | 63 | #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 64 | delete m_fontData; |
alp@webkit.org | 5817666 | 2007-11-23 00:04:00 +0000 | [diff] [blame] | 65 | #endif |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 66 | } |
| 67 | |
antti@apple.com | b4122c5 | 2008-03-25 19:21:00 +0000 | [diff] [blame] | 68 | void CachedFont::load(DocLoader* docLoader) |
| 69 | { |
| 70 | // Don't load the file yet. Wait for an access before triggering the load. |
| 71 | m_loading = true; |
| 72 | } |
| 73 | |
hyatt@apple.com | 2c814c4 | 2008-04-12 04:09:22 +0000 | [diff] [blame] | 74 | void CachedFont::addClient(CachedResourceClient* c) |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 75 | { |
hyatt@apple.com | 2c814c4 | 2008-04-12 04:09:22 +0000 | [diff] [blame] | 76 | CachedResource::addClient(c); |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 77 | |
| 78 | if (!m_loading) |
| 79 | c->fontLoaded(this); |
| 80 | } |
| 81 | |
| 82 | void CachedFont::data(PassRefPtr<SharedBuffer> data, bool allDataReceived) |
| 83 | { |
| 84 | if (!allDataReceived) |
| 85 | return; |
| 86 | |
| 87 | m_data = data; |
| 88 | setEncodedSize(m_data.get() ? m_data->size() : 0); |
| 89 | m_loading = false; |
| 90 | checkNotify(); |
| 91 | } |
| 92 | |
| 93 | void CachedFont::beginLoadIfNeeded(DocLoader* dl) |
| 94 | { |
| 95 | if (!m_loadInitiated) { |
| 96 | m_loadInitiated = true; |
| 97 | cache()->loader()->load(dl, this, false); |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | bool CachedFont::ensureCustomFontData() |
| 102 | { |
alp@webkit.org | c55e590 | 2008-01-11 21:58:11 +0000 | [diff] [blame] | 103 | #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) |
mitz@apple.com | 2eb96ca | 2008-01-30 03:50:08 +0000 | [diff] [blame] | 104 | #if ENABLE(SVG_FONTS) |
| 105 | ASSERT(!m_isSVGFont); |
| 106 | #endif |
aroben@apple.com | fef84c14 | 2008-01-24 23:50:34 +0000 | [diff] [blame] | 107 | if (!m_fontData && !m_errorOccurred && !m_loading && m_data) { |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 108 | m_fontData = createFontCustomPlatformData(m_data.get()); |
| 109 | if (!m_fontData) |
| 110 | m_errorOccurred = true; |
| 111 | } |
| 112 | #endif |
| 113 | return m_fontData; |
| 114 | } |
| 115 | |
mitz@apple.com | 26b747a | 2008-04-01 05:49:35 +0000 | [diff] [blame] | 116 | FontPlatformData CachedFont::platformDataFromCustomData(float size, bool bold, bool italic, FontRenderingMode renderingMode) |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 117 | { |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 118 | #if ENABLE(SVG_FONTS) |
| 119 | if (m_externalSVGDocument) |
| 120 | return FontPlatformData(size, bold, italic); |
| 121 | #endif |
alp@webkit.org | c55e590 | 2008-01-11 21:58:11 +0000 | [diff] [blame] | 122 | #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 123 | ASSERT(m_fontData); |
mitz@apple.com | 26b747a | 2008-04-01 05:49:35 +0000 | [diff] [blame] | 124 | return m_fontData->fontPlatformData(static_cast<int>(size), bold, italic, renderingMode); |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 125 | #else |
| 126 | return FontPlatformData(); |
| 127 | #endif |
| 128 | } |
| 129 | |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 130 | #if ENABLE(SVG_FONTS) |
| 131 | bool CachedFont::ensureSVGFontData() |
| 132 | { |
mitz@apple.com | 2eb96ca | 2008-01-30 03:50:08 +0000 | [diff] [blame] | 133 | ASSERT(m_isSVGFont); |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 134 | if (!m_externalSVGDocument && !m_errorOccurred && !m_loading && m_data) { |
weinig@apple.com | 3feb4c3 | 2008-06-15 21:53:29 +0000 | [diff] [blame] | 135 | m_externalSVGDocument = SVGDocument::create(0); |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 136 | m_externalSVGDocument->open(); |
| 137 | |
darin@apple.com | 642f500 | 2008-06-07 22:51:37 +0000 | [diff] [blame] | 138 | RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml"); |
| 139 | m_externalSVGDocument->write(decoder->decode(m_data->data(), m_data->size())); |
| 140 | if (decoder->sawError()) { |
eric@webkit.org | 4f9b2dd | 2008-03-26 17:19:07 +0000 | [diff] [blame] | 141 | m_externalSVGDocument.clear(); |
| 142 | return 0; |
| 143 | } |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 144 | |
| 145 | m_externalSVGDocument->finishParsing(); |
| 146 | m_externalSVGDocument->close(); |
| 147 | } |
| 148 | |
| 149 | return m_externalSVGDocument; |
| 150 | } |
| 151 | |
| 152 | SVGFontElement* CachedFont::getSVGFontById(const String& fontName) const |
| 153 | { |
mitz@apple.com | 2eb96ca | 2008-01-30 03:50:08 +0000 | [diff] [blame] | 154 | ASSERT(m_isSVGFont); |
zimmermann@webkit.org | 8161594 | 2008-01-28 23:37:04 +0000 | [diff] [blame] | 155 | RefPtr<NodeList> list = m_externalSVGDocument->getElementsByTagName(SVGNames::fontTag.localName()); |
| 156 | if (!list) |
| 157 | return 0; |
| 158 | |
| 159 | unsigned fonts = list->length(); |
| 160 | for (unsigned i = 0; i < fonts; ++i) { |
| 161 | Node* node = list->item(i); |
| 162 | ASSERT(node); |
| 163 | |
| 164 | if (static_cast<Element*>(node)->getAttribute(HTMLNames::idAttr) != fontName) |
| 165 | continue; |
| 166 | |
| 167 | ASSERT(node->hasTagName(SVGNames::fontTag)); |
| 168 | return static_cast<SVGFontElement*>(node); |
| 169 | } |
| 170 | |
| 171 | return 0; |
| 172 | } |
| 173 | #endif |
| 174 | |
mitz@apple.com | 9d7e426 | 2008-09-04 18:15:25 +0000 | [diff] [blame^] | 175 | void CachedFont::allClientsRemoved() |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 176 | { |
alp@webkit.org | c55e590 | 2008-01-11 21:58:11 +0000 | [diff] [blame] | 177 | #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 178 | if (m_fontData) { |
| 179 | delete m_fontData; |
| 180 | m_fontData = 0; |
| 181 | } |
alp@webkit.org | 5817666 | 2007-11-23 00:04:00 +0000 | [diff] [blame] | 182 | #endif |
oliver | d6ae496 | 2007-10-12 14:55:24 +0000 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | void CachedFont::checkNotify() |
| 186 | { |
| 187 | if (m_loading) |
| 188 | return; |
| 189 | |
| 190 | CachedResourceClientWalker w(m_clients); |
| 191 | while (CachedResourceClient *c = w.next()) |
| 192 | c->fontLoaded(this); |
| 193 | } |
| 194 | |
| 195 | |
| 196 | void CachedFont::error() |
| 197 | { |
| 198 | m_loading = false; |
| 199 | m_errorOccurred = true; |
| 200 | checkNotify(); |
| 201 | } |
| 202 | |
| 203 | } |