blob: c5080c97692b7569a021c1bce75b420f84704558 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "config.h"
#include "SimpleFontData.h"
#include "Font.h"
#include "FontCache.h"
#include "FloatRect.h"
#include "FontDescription.h"
#include "Logging.h"
#include "NotImplemented.h"
#include "SkPaint.h"
#include "SkTypeface.h"
#include "SkTime.h"
namespace WebCore {
// Smallcaps versions of fonts are 70% the size of the normal font.
static const float kSmallCapsFraction = 0.7f;
void SimpleFontData::platformInit()
{
SkPaint paint;
SkPaint::FontMetrics metrics;
m_font.setupPaint(&paint);
paint.getFontMetrics(&metrics);
// Beware those who step here: This code is designed to match Win32 font
// metrics *exactly*.
if (metrics.fVDMXMetricsValid) {
m_ascent = metrics.fVDMXAscent;
m_descent = metrics.fVDMXDescent;
} else {
m_ascent = SkScalarCeil(-metrics.fAscent);
m_descent = SkScalarCeil(metrics.fHeight) - m_ascent;
}
m_xHeight = SkScalarToFloat(-metrics.fAscent) * 0.56f; // hack I stole from the Windows port
m_lineGap = SkScalarRound(metrics.fLeading);
m_lineSpacing = m_ascent + m_descent + m_lineGap;
// In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is
// calculated for us, but we need to calculate m_maxCharWidth and
// m_avgCharWidth in order for text entry widgets to be sized correctly.
// Skia doesn't expose either of these so we calculate them ourselves
GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page();
if (!glyphPageZero)
return;
m_maxCharWidth = SkScalarRound(metrics.fXRange * SkScalarRound(m_font.size()));
if (metrics.fAvgCharWidth) {
m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth);
} else {
static const UChar32 x_char = 'x';
m_avgCharWidth = widthForGlyph(glyphPageZero->glyphDataForCharacter(x_char).glyph);
}
}
void SimpleFontData::platformDestroy()
{
delete m_smallCapsFontData;
}
SimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const
{
if (!m_smallCapsFontData) {
m_smallCapsFontData =
new SimpleFontData(FontPlatformData(m_font, fontDescription.computedSize() * kSmallCapsFraction));
}
return m_smallCapsFontData;
}
bool SimpleFontData::containsCharacters(const UChar* characters, int length) const
{
SkPaint paint;
static const unsigned kMaxBufferCount = 64;
uint16_t glyphs[kMaxBufferCount];
m_font.setupPaint(&paint);
paint.setTextEncoding(SkPaint::kUTF16_TextEncoding);
while (length > 0) {
int n = SkMin32(length, SK_ARRAY_COUNT(glyphs));
// textToGlyphs takes a byte count so we double the character count.
int count = paint.textToGlyphs(characters, n * 2, glyphs);
for (int i = 0; i < count; i++) {
if (0 == glyphs[i]) {
return false; // missing glyph
}
}
characters += n;
length -= n;
}
return true;
}
void SimpleFontData::determinePitch()
{
m_treatAsFixedPitch = platformData().isFixedPitch();
}
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
{
SkASSERT(sizeof(glyph) == 2); // compile-time assert
SkPaint paint;
m_font.setupPaint(&paint);
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
SkScalar width = paint.measureText(&glyph, 2);
return SkScalarToFloat(width);
}
} // namespace WebCore
|