868280607e75662a960de4f621ffec5275f679bf
[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     , m_svgFontData(svgFontData)
46     , m_isCustomFont(customFont)
47     , m_isLoading(loading)
48     , m_smallCapsFontData(0)
49 {
50 #if ENABLE(SVG_FONTS) && !PLATFORM(QT)
51     if (SVGFontFaceElement* svgFontFaceElement = svgFontData ? svgFontData->svgFontFaceElement() : 0) {
52        m_unitsPerEm = svgFontFaceElement->unitsPerEm();
53
54        float scale = f.size();
55        if (m_unitsPerEm)
56            scale /= m_unitsPerEm;
57
58         m_ascent = svgFontFaceElement->ascent() * scale;
59         m_descent = svgFontFaceElement->descent() * scale;
60         m_xHeight = svgFontFaceElement->xHeight() * scale;
61
62         m_spaceGlyph = 0;
63         m_spaceWidth = 0;
64         m_adjustedSpaceWidth = 0;
65         determinePitch();
66         m_missingGlyphData.fontData = this;
67         m_missingGlyphData.glyph = 0;
68         return;
69     }
70 #endif
71
72     platformInit();
73
74     GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
75     if (!glyphPageZero) {
76         LOG_ERROR("Failed to get glyph page zero.");
77         m_spaceGlyph = 0;
78         m_spaceWidth = 0;
79         m_adjustedSpaceWidth = 0;
80         determinePitch();
81         m_missingGlyphData.fontData = this;
82         m_missingGlyphData.glyph = 0;
83         return;
84     }
85
86     // Nasty hack to determine if we should round or ceil space widths.
87     // If the font is monospace or fake monospace we ceil to ensure that 
88     // every character and the space are the same width.  Otherwise we round.
89     m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph;
90     float width = widthForGlyph(m_spaceGlyph);
91     m_spaceWidth = width;
92     determinePitch();
93     m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
94
95     // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
96     // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
97     // See <http://bugs.webkit.org/show_bug.cgi?id=13178>
98     // Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
99     // are mapped to the ZERO WIDTH SPACE glyph.
100     Glyph zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph;
101     if (zeroWidthSpaceGlyph) {
102         if (zeroWidthSpaceGlyph != m_spaceGlyph)
103             m_glyphToWidthMap.setWidthForGlyph(zeroWidthSpaceGlyph, 0);
104         else
105             LOG_ERROR("Font maps SPACE and ZERO WIDTH SPACE to the same glyph. Glyph width not overridden.");
106     }
107
108     m_missingGlyphData.fontData = this;
109     m_missingGlyphData.glyph = 0;
110 }
111
112 SimpleFontData::~SimpleFontData()
113 {
114     platformDestroy();
115
116     // We only get deleted when the cache gets cleared.  Since the smallCapsRenderer is also in that cache,
117     // it will be deleted then, so we don't need to do anything here.
118 }
119
120 float SimpleFontData::widthForGlyph(Glyph glyph) const
121 {
122     float width = m_glyphToWidthMap.widthForGlyph(glyph);
123     if (width != cGlyphWidthUnknown)
124         return width;
125     
126     width = platformWidthForGlyph(glyph);
127     m_glyphToWidthMap.setWidthForGlyph(glyph, width);
128     
129     return width;
130 }
131
132 const SimpleFontData* SimpleFontData::fontDataForCharacter(UChar32) const
133 {
134     return this;
135 }
136
137 bool SimpleFontData::isSegmented() const
138 {
139     return false;
140 }
141
142 } // namespace WebCore