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