OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #define PANGO_ENABLE_BACKEND | |
6 | |
7 #include "config.h" | 5 #include "config.h" |
8 #include "SimpleFontData.h" | 6 #include "SimpleFontData.h" |
9 | 7 |
10 #include <pango/pango.h> | |
11 #include <pango/pangoft2.h> | |
12 #include <pango/pangofc-font.h> | |
13 | |
14 #include "Font.h" | 8 #include "Font.h" |
15 #include "FontCache.h" | 9 #include "FontCache.h" |
16 #include "FloatRect.h" | 10 #include "FloatRect.h" |
17 #include "FontDescription.h" | 11 #include "FontDescription.h" |
18 #include "Logging.h" | 12 #include "Logging.h" |
19 #include "NotImplemented.h" | 13 #include "NotImplemented.h" |
20 | 14 |
| 15 #include "SkPaint.h" |
| 16 #include "SkTypeface.h" |
| 17 #include "SkTime.h" |
| 18 |
21 namespace WebCore { | 19 namespace WebCore { |
22 | 20 |
23 // TODO(agl): only stubs | 21 // Smallcaps versions of fonts are 70% the size of the normal font. |
| 22 static const float kSmallCapsFraction = 0.7f; |
24 | 23 |
25 void SimpleFontData::platformInit() | 24 void SimpleFontData::platformInit() |
26 { | 25 { |
27 PangoFont *const font = platformData().m_font; | 26 SkPaint paint; |
| 27 SkPaint::FontMetrics metrics; |
28 | 28 |
29 PangoFontMetrics *const metrics = pango_font_get_metrics(font, NULL); | 29 m_font.setupPaint(&paint); |
30 m_ascent = pango_font_metrics_get_ascent(metrics) / PANGO_SCALE; | 30 paint.getFontMetrics(&metrics); |
31 m_descent = pango_font_metrics_get_descent(metrics) / PANGO_SCALE; | |
32 m_lineSpacing = m_ascent + m_descent; | |
33 m_avgCharWidth = pango_font_metrics_get_approximate_char_width(metrics) / PA
NGO_SCALE; | |
34 pango_font_metrics_unref(metrics); | |
35 | 31 |
36 const guint xglyph = pango_fc_font_get_glyph(PANGO_FC_FONT(font), 'x'); | 32 // use ceil instead of round to favor descent, given a lot of accidental |
37 const guint spaceglyph = pango_fc_font_get_glyph(PANGO_FC_FONT(font), ' '); | 33 // clipping of descenders (e.g. 14pt 'g') in textedit fields |
38 PangoRectangle rect; | 34 const int descent = SkScalarCeil(metrics.fDescent); |
| 35 const int span = SkScalarRound(metrics.fDescent - metrics.fAscent); |
| 36 const int ascent = span - descent; |
39 | 37 |
40 pango_font_get_glyph_extents(font, xglyph, &rect, NULL); | 38 m_ascent = ascent; |
41 m_xHeight = rect.height / PANGO_SCALE; | 39 m_descent = descent; |
42 pango_font_get_glyph_extents(font, spaceglyph, NULL, &rect); | 40 m_xHeight = SkScalarToFloat(-metrics.fAscent) * 0.56f; // hack I stole fro
m the Windows port |
43 m_spaceWidth = rect.width / PANGO_SCALE; | 41 m_lineSpacing = ascent + descent; |
44 m_lineGap = m_lineSpacing - m_ascent - m_descent; | 42 m_lineGap = SkScalarRound(metrics.fLeading); |
45 | 43 |
46 FT_Face face = pango_ft2_font_get_face(font); | 44 // In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is |
47 m_unitsPerEm = face->units_per_EM / PANGO_SCALE; | 45 // calculated for us, but we need to calculate m_maxCharWidth and |
| 46 // m_avgCharWidth in order for text entry widgets to be sized correctly. |
| 47 // Skia doesn't expose either of these so we calculate them ourselves |
48 | 48 |
49 // TODO(agl): I'm not sure we have good data for this so it's 0 for now | 49 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page(); |
50 m_maxCharWidth = 0; | 50 if (!glyphPageZero) |
| 51 return; |
| 52 |
| 53 static const UChar32 e_char = 'e'; |
| 54 static const UChar32 M_char = 'M'; |
| 55 m_avgCharWidth = widthForGlyph(glyphPageZero->glyphDataForCharacter(e_char).
glyph); |
| 56 m_maxCharWidth = widthForGlyph(glyphPageZero->glyphDataForCharacter(M_char).
glyph); |
51 } | 57 } |
52 | 58 |
53 void SimpleFontData::platformDestroy() { } | 59 void SimpleFontData::platformDestroy() |
| 60 { |
| 61 delete m_smallCapsFontData; |
| 62 } |
54 | 63 |
55 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
cription) const | 64 SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDes
cription) const |
56 { | 65 { |
57 notImplemented(); | 66 if (!m_smallCapsFontData) { |
58 return NULL; | 67 m_smallCapsFontData = |
| 68 new SimpleFontData(FontPlatformData(m_font, fontDescription.computed
Size() * kSmallCapsFraction)); |
| 69 } |
| 70 return m_smallCapsFontData; |
59 } | 71 } |
60 | 72 |
61 bool SimpleFontData::containsCharacters(const UChar* characters, | 73 bool SimpleFontData::containsCharacters(const UChar* characters, int length) con
st |
62 int length) const | |
63 { | 74 { |
64 bool result = true; | 75 SkPaint paint; |
| 76 static const unsigned kMaxBufferCount = 64; |
| 77 uint16_t glyphs[kMaxBufferCount]; |
65 | 78 |
66 PangoCoverage* requested = pango_coverage_from_bytes((guchar*)characters, le
ngth); | 79 m_font.setupPaint(&paint); |
67 PangoCoverage* available = pango_font_get_coverage(m_font.m_font, pango_lang
uage_get_default()); | 80 paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); |
68 pango_coverage_max(requested, available); | |
69 | 81 |
70 for (int i = 0; i < length; i++) { | 82 while (length > 0) { |
71 if (PANGO_COVERAGE_NONE == pango_coverage_get(requested, i)) { | 83 int n = SkMin32(length, SK_ARRAY_COUNT(glyphs)); |
72 result = false; | 84 |
73 break; | 85 // textToGlyphs takes a byte count so we double the character count. |
| 86 int count = paint.textToGlyphs(characters, n * 2, glyphs); |
| 87 for (int i = 0; i < count; i++) { |
| 88 if (0 == glyphs[i]) { |
| 89 return false; // missing glyph |
| 90 } |
74 } | 91 } |
| 92 |
| 93 characters += n; |
| 94 length -= n; |
75 } | 95 } |
76 | 96 return true; |
77 pango_coverage_unref(requested); | |
78 pango_coverage_unref(available); | |
79 | |
80 return result; | |
81 } | 97 } |
82 | 98 |
83 void SimpleFontData::determinePitch() | 99 void SimpleFontData::determinePitch() |
84 { | 100 { |
85 m_treatAsFixedPitch = platformData().isFixedPitch(); | 101 m_treatAsFixedPitch = platformData().isFixedPitch(); |
86 } | 102 } |
87 | 103 |
88 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const | 104 float SimpleFontData::platformWidthForGlyph(Glyph glyph) const |
89 { | 105 { |
90 PangoFont *const font = platformData().m_font; | 106 SkASSERT(sizeof(glyph) == 2); // compile-time assert |
91 PangoRectangle rect; | |
92 | 107 |
93 pango_font_get_glyph_extents(font, glyph, NULL, &rect); | 108 SkPaint paint; |
94 | 109 |
95 return static_cast<float>(rect.width) / PANGO_SCALE; | 110 m_font.setupPaint(&paint); |
| 111 |
| 112 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); |
| 113 SkScalar width = paint.measureText(&glyph, 2); |
| 114 |
| 115 return SkScalarToFloat(width); |
96 } | 116 } |
97 | 117 |
98 } // namespace WebCore | 118 } // namespace WebCore |
OLD | NEW |