• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
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"
32 #include "DOMImplementation.h"
33 #include "FontPlatformData.h"
34 #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && (PLATFORM(WIN_OS) || PLATFORM(LINUX)))
35 #include "FontCustomPlatformData.h"
36 #endif
37 #include "TextResourceDecoder.h"
38 #include "loader.h"
39 #include <wtf/Vector.h>
40 
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 
49 namespace WebCore {
50 
CachedFont(const String & url)51 CachedFont::CachedFont(const String &url)
52     : CachedResource(url, FontResource)
53     , m_fontData(0)
54     , m_loadInitiated(false)
55 #if ENABLE(SVG_FONTS)
56     , m_isSVGFont(false)
57 #endif
58 {
59 }
60 
~CachedFont()61 CachedFont::~CachedFont()
62 {
63 #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && (PLATFORM(WIN_OS) || PLATFORM(LINUX)))
64     delete m_fontData;
65 #endif
66 }
67 
load(DocLoader *)68 void CachedFont::load(DocLoader*)
69 {
70     // Don't load the file yet.  Wait for an access before triggering the load.
71     m_loading = true;
72 }
73 
didAddClient(CachedResourceClient * c)74 void CachedFont::didAddClient(CachedResourceClient* c)
75 {
76     if (!m_loading)
77         c->fontLoaded(this);
78 }
79 
data(PassRefPtr<SharedBuffer> data,bool allDataReceived)80 void CachedFont::data(PassRefPtr<SharedBuffer> data, bool allDataReceived)
81 {
82     if (!allDataReceived)
83         return;
84 
85     m_data = data;
86     setEncodedSize(m_data.get() ? m_data->size() : 0);
87     m_loading = false;
88     checkNotify();
89 }
90 
beginLoadIfNeeded(DocLoader * dl)91 void CachedFont::beginLoadIfNeeded(DocLoader* dl)
92 {
93     if (!m_loadInitiated) {
94         m_loadInitiated = true;
95         cache()->loader()->load(dl, this, false);
96     }
97 }
98 
ensureCustomFontData()99 bool CachedFont::ensureCustomFontData()
100 {
101 #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && (PLATFORM(WIN_OS) || PLATFORM(LINUX)))
102 #if ENABLE(SVG_FONTS)
103     ASSERT(!m_isSVGFont);
104 #endif
105     if (!m_fontData && !m_errorOccurred && !m_loading && m_data) {
106         m_fontData = createFontCustomPlatformData(m_data.get());
107         if (!m_fontData)
108             m_errorOccurred = true;
109     }
110 #endif
111     return m_fontData;
112 }
113 
platformDataFromCustomData(float size,bool bold,bool italic,FontRenderingMode renderingMode)114 FontPlatformData CachedFont::platformDataFromCustomData(float size, bool bold, bool italic, FontRenderingMode renderingMode)
115 {
116 #if ENABLE(SVG_FONTS)
117     if (m_externalSVGDocument)
118         return FontPlatformData(size, bold, italic);
119 #endif
120 #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && (PLATFORM(WIN_OS) || PLATFORM(LINUX)))
121     ASSERT(m_fontData);
122     return m_fontData->fontPlatformData(static_cast<int>(size), bold, italic, renderingMode);
123 #else
124     return FontPlatformData();
125 #endif
126 }
127 
128 #if ENABLE(SVG_FONTS)
ensureSVGFontData()129 bool CachedFont::ensureSVGFontData()
130 {
131     ASSERT(m_isSVGFont);
132     if (!m_externalSVGDocument && !m_errorOccurred && !m_loading && m_data) {
133         m_externalSVGDocument = SVGDocument::create(0);
134         m_externalSVGDocument->open();
135 
136         RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
137         m_externalSVGDocument->write(decoder->decode(m_data->data(), m_data->size()));
138         m_externalSVGDocument->write(decoder->flush());
139         if (decoder->sawError()) {
140             m_externalSVGDocument.clear();
141             return 0;
142         }
143 
144         m_externalSVGDocument->finishParsing();
145         m_externalSVGDocument->close();
146     }
147 
148     return m_externalSVGDocument;
149 }
150 
getSVGFontById(const String & fontName) const151 SVGFontElement* CachedFont::getSVGFontById(const String& fontName) const
152 {
153     ASSERT(m_isSVGFont);
154     RefPtr<NodeList> list = m_externalSVGDocument->getElementsByTagName(SVGNames::fontTag.localName());
155     if (!list)
156         return 0;
157 
158     unsigned fonts = list->length();
159     for (unsigned i = 0; i < fonts; ++i) {
160         Node* node = list->item(i);
161         ASSERT(node);
162 
163         if (static_cast<Element*>(node)->getAttribute(HTMLNames::idAttr) != fontName)
164             continue;
165 
166         ASSERT(node->hasTagName(SVGNames::fontTag));
167         return static_cast<SVGFontElement*>(node);
168     }
169 
170     return 0;
171 }
172 #endif
173 
allClientsRemoved()174 void CachedFont::allClientsRemoved()
175 {
176 #if PLATFORM(CG) || PLATFORM(QT) || PLATFORM(GTK) || (PLATFORM(CHROMIUM) && (PLATFORM(WIN_OS) || PLATFORM(LINUX)))
177     if (m_fontData) {
178         delete m_fontData;
179         m_fontData = 0;
180     }
181 #endif
182 }
183 
checkNotify()184 void CachedFont::checkNotify()
185 {
186     if (m_loading)
187         return;
188 
189     CachedResourceClientWalker w(m_clients);
190     while (CachedResourceClient *c = w.next())
191          c->fontLoaded(this);
192 }
193 
194 
error()195 void CachedFont::error()
196 {
197     m_loading = false;
198     m_errorOccurred = true;
199     checkNotify();
200 }
201 
202 }
203