ffe25692fe6390c75ca63119a49ed2f9270ae281
[WebKit-https.git] / WebCore / platform / graphics / SimpleFontData.cpp
1 /*
2  * Copyright (C) 2005, 2008 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2006 Alexey Proskuryakov
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  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer. 
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution. 
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission. 
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "SimpleFontData.h"
32
33 #if ENABLE(SVG_FONTS)
34 #include "SVGFontData.h"
35 #include "SVGFontFaceElement.h"
36 #endif
37
38 #include <wtf/MathExtras.h>
39
40 namespace WebCore {
41
42 SimpleFontData::SimpleFontData(const FontPlatformData& f, bool customFont, bool loading, SVGFontData* svgFontData)
43     : m_font(f)
44     , m_treatAsFixedPitch(false)
45 #if ENABLE(SVG_FONTS)
46     , m_svgFontData(svgFontData)
47 #endif
48     , m_isCustomFont(customFont)
49     , m_isLoading(loading)
50     , m_smallCapsFontData(0)
51 {
52 #if ENABLE(SVG_FONTS) && !PLATFORM(QT)
53     if (SVGFontFaceElement* svgFontFaceElement = svgFontData ? svgFontData->svgFontFaceElement() : 0) {
54        m_unitsPerEm = svgFontFaceElement->unitsPerEm();
55
56        float scale = f.size();
57        if (m_unitsPerEm)
58            scale /= m_unitsPerEm;
59
60         m_ascent = svgFontFaceElement->ascent() * scale;
61         m_descent = svgFontFaceElement->descent() * scale;
62         m_xHeight = svgFontFaceElement->xHeight() * scale;
63
64         m_spaceGlyph = 0;
65         m_spaceWidth = 0;
66         m_adjustedSpaceWidth = 0;
67         determinePitch();
68         m_missingGlyphData.fontData = this;
69         m_missingGlyphData.glyph = 0;
70         return;
71     }
72 #endif
73
74     platformInit();
75
76     GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
77     if (!glyphPageZero) {
78         LOG_ERROR("Failed to get glyph page zero.");
79         m_spaceGlyph = 0;
80         m_spaceWidth = 0;
81         m_adjustedSpaceWidth = 0;
82         determinePitch();
83         m_missingGlyphData.fontData = this;
84         m_missingGlyphData.glyph = 0;
85         return;
86     }
87
88     // Nasty hack to determine if we should round or ceil space widths.
89     // If the font is monospace or fake monospace we ceil to ensure that 
90     // every character and the space are the same width.  Otherwise we round.
91     m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph;
92     float width = widthForGlyph(m_spaceGlyph);
93     m_spaceWidth = width;
94     determinePitch();
95     m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
96
97     // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
98     // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
99     // See <http://bugs.webkit.org/show_bug.cgi?id=13178>
100     // Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
101     // are mapped to the ZERO WIDTH SPACE glyph.
102     Glyph zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
103     if (zeroWidthSpaceGlyph) {
104         if (zeroWidthSpaceGlyph != m_spaceGlyph)
105             m_glyphToWidthMap.setWidthForGlyph(zeroWidthSpaceGlyph, 0);
106         else
107             LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width not overridden.");
108     }
109
110     m_missingGlyphData.fontData = this;
111     m_missingGlyphData.glyph = 0;
112 }
113
114 SimpleFontData::~SimpleFontData()
115 {
116     platformDestroy();
117
118     // We only get deleted when the cache gets cleared.  Since the smallCapsRenderer is also in that cache,
119     // it will be deleted then, so we don't need to do anything here.
120 }
121
122 float SimpleFontData::widthForGlyph(Glyph glyph) const
123 {
124     float width = m_glyphToWidthMap.widthForGlyph(glyph);
125     if (width != cGlyphWidthUnknown)
126         return width;
127     
128     width = platformWidthForGlyph(glyph);
129     m_glyphToWidthMap.setWidthForGlyph(glyph, width);
130     
131     return width;
132 }
133
134 const SimpleFontData* SimpleFontData::fontDataForCharacter(UChar32) const
135 {
136     return this;
137 }
138
139 bool SimpleFontData::isSegmented() const
140 {
141     return false;
142 }
143
144 } // namespace WebCore