1 /*
2 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #include "core/rendering/svg/SVGTextLayoutEngineSpacing.h"
23
24 #include "core/svg/SVGLengthContext.h"
25 #include "platform/fonts/Character.h"
26 #include "platform/fonts/Font.h"
27
28 #if ENABLE(SVG_FONTS)
29 #include "core/svg/SVGFontData.h"
30 #include "core/svg/SVGFontElement.h"
31 #include "core/svg/SVGFontFaceElement.h"
32 #endif
33
34 namespace WebCore {
35
SVGTextLayoutEngineSpacing(const Font & font,float effectiveZoom)36 SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const Font& font, float effectiveZoom)
37 : m_font(font)
38 , m_lastCharacter(0)
39 , m_effectiveZoom(effectiveZoom)
40 #if ENABLE(SVG_FONTS)
41 , m_lastGlyph(0)
42 #endif
43 {
44 ASSERT(m_effectiveZoom);
45 }
46
calculateSVGKerning(bool isVerticalText,Glyph currentGlyph)47 float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, Glyph currentGlyph)
48 {
49 #if ENABLE(SVG_FONTS)
50 const SimpleFontData* fontData = m_font.primaryFont();
51 if (!fontData->isSVGFont()) {
52 m_lastGlyph = 0;
53 return 0;
54 }
55
56 ASSERT(fontData->isCustomFont());
57 ASSERT(fontData->isSVGFont());
58
59 RefPtr<CustomFontData> customFontData = fontData->customFontData();
60 const SVGFontData* svgFontData = static_cast<const SVGFontData*>(customFontData.get());
61 SVGFontFaceElement* svgFontFace = svgFontData->svgFontFaceElement();
62 ASSERT(svgFontFace);
63
64 SVGFontElement* svgFont = svgFontFace->associatedFontElement();
65 if (!svgFont) {
66 m_lastGlyph = 0;
67 return 0;
68 }
69
70 float kerning = 0;
71 if (m_lastGlyph) {
72 if (isVerticalText)
73 kerning = svgFont->verticalKerningForPairOfGlyphs(m_lastGlyph, currentGlyph);
74 else
75 kerning = svgFont->horizontalKerningForPairOfGlyphs(m_lastGlyph, currentGlyph);
76
77 kerning *= m_font.fontDescription().computedSize() / m_font.fontMetrics().unitsPerEm();
78 }
79
80 m_lastGlyph = currentGlyph;
81 return kerning;
82 #else
83 return 0;
84 #endif
85 }
86
calculateCSSSpacing(UChar currentCharacter)87 float SVGTextLayoutEngineSpacing::calculateCSSSpacing(UChar currentCharacter)
88 {
89 UChar lastCharacter = m_lastCharacter;
90 m_lastCharacter = currentCharacter;
91
92 if (!m_font.fontDescription().letterSpacing() && !m_font.fontDescription().wordSpacing())
93 return 0;
94
95 float spacing = m_font.fontDescription().letterSpacing();
96 if (currentCharacter && lastCharacter && m_font.fontDescription().wordSpacing()) {
97 if (Character::treatAsSpace(currentCharacter) && !Character::treatAsSpace(lastCharacter))
98 spacing += m_font.fontDescription().wordSpacing();
99 }
100
101 if (m_effectiveZoom != 1)
102 spacing = spacing / m_effectiveZoom;
103
104 return spacing;
105 }
106
107 }
108