1 /*
2  * Copyright (C) 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 "CSSFontFace.h"
28 
29 #include "CSSFontFaceSource.h"
30 #include "CSSFontSelector.h"
31 #include "CSSSegmentedFontFace.h"
32 #include "FontDescription.h"
33 #include "SimpleFontData.h"
34 
35 namespace WebCore {
36 
~CSSFontFace()37 CSSFontFace::~CSSFontFace()
38 {
39     deleteAllValues(m_sources);
40 }
41 
isLoaded() const42 bool CSSFontFace::isLoaded() const
43 {
44     unsigned size = m_sources.size();
45     for (unsigned i = 0; i < size; i++) {
46         if (!m_sources[i]->isLoaded())
47             return false;
48     }
49     return true;
50 }
51 
isValid() const52 bool CSSFontFace::isValid() const
53 {
54     unsigned size = m_sources.size();
55     if (!size)
56         return false;
57     for (unsigned i = 0; i < size; i++) {
58         if (m_sources[i]->isValid())
59             return true;
60     }
61     return false;
62 }
63 
addedToSegmentedFontFace(CSSSegmentedFontFace * segmentedFontFace)64 void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
65 {
66     m_segmentedFontFaces.add(segmentedFontFace);
67 }
68 
removedFromSegmentedFontFace(CSSSegmentedFontFace * segmentedFontFace)69 void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace* segmentedFontFace)
70 {
71     m_segmentedFontFaces.remove(segmentedFontFace);
72 }
73 
addSource(CSSFontFaceSource * source)74 void CSSFontFace::addSource(CSSFontFaceSource* source)
75 {
76     m_sources.append(source);
77     source->setFontFace(this);
78 }
79 
fontLoaded(CSSFontFaceSource * source)80 void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
81 {
82     if (source != m_activeSource)
83         return;
84 
85     // FIXME: Can we assert that m_segmentedFontFaces is not empty? That may
86     // require stopping in-progress font loading when the last
87     // CSSSegmentedFontFace is removed.
88     if (m_segmentedFontFaces.isEmpty())
89         return;
90 
91     HashSet<CSSSegmentedFontFace*>::iterator end = m_segmentedFontFaces.end();
92     for (HashSet<CSSSegmentedFontFace*>::iterator it = m_segmentedFontFaces.begin(); it != end; ++it)
93         (*it)->fontLoaded(this);
94 
95     // Use one of the CSSSegmentedFontFaces' font selector. They all have
96     // the same font selector, so it's wasteful to store it in the CSSFontFace.
97     CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
98     fontSelector->fontLoaded();
99 }
100 
getFontData(const FontDescription & fontDescription,bool syntheticBold,bool syntheticItalic)101 SimpleFontData* CSSFontFace::getFontData(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic)
102 {
103     m_activeSource = 0;
104     if (!isValid())
105         return 0;
106 
107     ASSERT(!m_segmentedFontFaces.isEmpty());
108     CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();
109 
110     size_t size = m_sources.size();
111     for (size_t i = 0; i < size; ++i) {
112         if (SimpleFontData* result = m_sources[i]->getFontData(fontDescription, syntheticBold, syntheticItalic, fontSelector)) {
113             m_activeSource = m_sources[i];
114             return result;
115         }
116     }
117 
118     return 0;
119 }
120 
121 #if ENABLE(SVG_FONTS)
hasSVGFontFaceSource() const122 bool CSSFontFace::hasSVGFontFaceSource() const
123 {
124     for (unsigned i = 0; i < m_sources.size(); i++) {
125         if (m_sources[i]->isSVGFontFaceSource())
126             return true;
127     }
128     return false;
129 }
130 #endif
131 
132 }
133 
134