|
Lines 81-92
Font::Font(const FontPlatformData& platformData, bool isCustomFont, bool isLoadi
a/Source/WebCore/platform/graphics/Font.cpp_sec1
|
| 81 |
// Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font. |
81 |
// Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font. |
| 82 |
void Font::initCharWidths() |
82 |
void Font::initCharWidths() |
| 83 |
{ |
83 |
{ |
| 84 |
auto* glyphPageZero = glyphPage(0); |
84 |
auto* glyphPageZero = glyphPage(GlyphPage::pageNumberForCodePoint('0')); |
| 85 |
|
85 |
|
| 86 |
// Treat the width of a '0' as the avgCharWidth. |
86 |
// Treat the width of a '0' as the avgCharWidth. |
| 87 |
if (m_avgCharWidth <= 0.f && glyphPageZero) { |
87 |
if (m_avgCharWidth <= 0.f && glyphPageZero) { |
| 88 |
static const UChar32 digitZeroChar = '0'; |
88 |
Glyph digitZeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph; |
| 89 |
Glyph digitZeroGlyph = glyphPageZero->glyphDataForCharacter(digitZeroChar).glyph; |
|
|
| 90 |
if (digitZeroGlyph) |
89 |
if (digitZeroGlyph) |
| 91 |
m_avgCharWidth = widthForGlyph(digitZeroGlyph); |
90 |
m_avgCharWidth = widthForGlyph(digitZeroGlyph); |
| 92 |
} |
91 |
} |
|
Lines 102-123
void Font::initCharWidths()
a/Source/WebCore/platform/graphics/Font.cpp_sec2
|
| 102 |
void Font::platformGlyphInit() |
101 |
void Font::platformGlyphInit() |
| 103 |
{ |
102 |
{ |
| 104 |
auto* glyphPageZero = glyphPage(0); |
103 |
auto* glyphPageZero = glyphPage(0); |
| 105 |
if (!glyphPageZero) { |
104 |
auto* glyphPageCharacterZero = glyphPage(GlyphPage::pageNumberForCodePoint('0')); |
| 106 |
determinePitch(); |
105 |
auto* glyphPageSpace = glyphPage(GlyphPage::pageNumberForCodePoint(space)); |
| 107 |
return; |
|
|
| 108 |
} |
| 109 |
|
106 |
|
| 110 |
// Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0, |
107 |
// Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0, |
| 111 |
// are mapped to the ZERO WIDTH SPACE glyph. |
108 |
// are mapped to the ZERO WIDTH SPACE glyph. |
| 112 |
m_zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph; |
109 |
if (glyphPageZero) |
|
|
110 |
m_zeroWidthSpaceGlyph = glyphPageZero->glyphDataForCharacter(0).glyph; |
| 113 |
|
111 |
|
| 114 |
// Nasty hack to determine if we should round or ceil space widths. |
112 |
// Nasty hack to determine if we should round or ceil space widths. |
| 115 |
// If the font is monospace or fake monospace we ceil to ensure that |
113 |
// If the font is monospace or fake monospace we ceil to ensure that |
| 116 |
// every character and the space are the same width. Otherwise we round. |
114 |
// every character and the space are the same width. Otherwise we round. |
| 117 |
m_spaceGlyph = glyphPageZero->glyphDataForCharacter(' ').glyph; |
115 |
if (glyphPageSpace) |
|
|
116 |
m_spaceGlyph = glyphPageSpace->glyphDataForCharacter(space).glyph; |
| 118 |
float width = widthForGlyph(m_spaceGlyph); |
117 |
float width = widthForGlyph(m_spaceGlyph); |
| 119 |
m_spaceWidth = width; |
118 |
m_spaceWidth = width; |
| 120 |
m_zeroGlyph = glyphPageZero->glyphDataForCharacter('0').glyph; |
119 |
if (glyphPageCharacterZero) |
|
|
120 |
m_zeroGlyph = glyphPageCharacterZero->glyphDataForCharacter('0').glyph; |
| 121 |
m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph)); |
121 |
m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph)); |
| 122 |
determinePitch(); |
122 |
determinePitch(); |
| 123 |
m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width); |
123 |
m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width); |
|
Lines 152-207
static RefPtr<GlyphPage> createAndFillGlyphPage(unsigned pageNumber, const Font&
a/Source/WebCore/platform/graphics/Font.cpp_sec3
|
| 152 |
// FIXME: Times New Roman contains Arabic glyphs, but Core Text doesn't know how to shape them. See <rdar://problem/9823975>. |
152 |
// FIXME: Times New Roman contains Arabic glyphs, but Core Text doesn't know how to shape them. See <rdar://problem/9823975>. |
| 153 |
// Once we have the fix for <rdar://problem/9823975> then remove this code together with Font::shouldNotBeUsedForArabic() |
153 |
// Once we have the fix for <rdar://problem/9823975> then remove this code together with Font::shouldNotBeUsedForArabic() |
| 154 |
// in <rdar://problem/12096835>. |
154 |
// in <rdar://problem/12096835>. |
| 155 |
if (pageNumber == 6 && font.shouldNotBeUsedForArabic()) |
155 |
if (GlyphPage::pageNumberIsUsedForArabic(pageNumber) && font.shouldNotBeUsedForArabic()) |
| 156 |
return nullptr; |
156 |
return nullptr; |
| 157 |
#endif |
157 |
#endif |
| 158 |
|
158 |
|
| 159 |
unsigned start = pageNumber * GlyphPage::size; |
159 |
unsigned glyphPageSize = GlyphPage::sizeForPageNumber(pageNumber); |
| 160 |
UChar buffer[GlyphPage::size * 2 + 2]; |
160 |
|
|
|
161 |
unsigned start = GlyphPage::startingCodePointInPageNumber(pageNumber); |
| 162 |
unsigned end = start + glyphPageSize; |
| 163 |
Vector<UChar> buffer(glyphPageSize * 2 + 2); |
| 161 |
unsigned bufferLength; |
164 |
unsigned bufferLength; |
| 162 |
// Fill in a buffer with the entire "page" of characters that we want to look up glyphs for. |
165 |
// Fill in a buffer with the entire "page" of characters that we want to look up glyphs for. |
| 163 |
if (U_IS_BMP(start)) { |
166 |
if (U_IS_BMP(start)) { |
| 164 |
bufferLength = GlyphPage::size; |
167 |
bufferLength = glyphPageSize; |
| 165 |
for (unsigned i = 0; i < GlyphPage::size; i++) |
168 |
for (unsigned i = 0; i < bufferLength; i++) |
| 166 |
buffer[i] = start + i; |
169 |
buffer[i] = start + i; |
| 167 |
|
170 |
|
| 168 |
if (!start) { |
171 |
// Code points 0x0 - 0x20 and 0x7F - 0xA0 are control character and shouldn't render. Map them to ZERO WIDTH SPACE. |
| 169 |
// Control characters must not render at all. |
172 |
auto overwriteCodePoints = [&](unsigned minimum, unsigned maximum, UChar newCodePoint) { |
| 170 |
for (unsigned i = 0; i < 0x20; ++i) |
173 |
unsigned begin = std::max(start, minimum); |
| 171 |
buffer[i] = zeroWidthSpace; |
174 |
unsigned complete = std::min(end, maximum); |
| 172 |
for (unsigned i = 0x7F; i < 0xA0; i++) |
175 |
for (unsigned i = begin; i < complete; ++i) |
| 173 |
buffer[i] = zeroWidthSpace; |
176 |
buffer[i - start] = newCodePoint; |
| 174 |
buffer[softHyphen] = zeroWidthSpace; |
177 |
}; |
| 175 |
|
178 |
|
| 176 |
// \n, \t, and nonbreaking space must render as a space. |
179 |
auto overwriteCodePoint = [&](UChar codePoint, UChar newCodePoint) { |
| 177 |
buffer[(int)'\n'] = ' '; |
180 |
if (codePoint >= start && codePoint < end) |
| 178 |
buffer[(int)'\t'] = ' '; |
181 |
buffer[codePoint - start] = newCodePoint; |
| 179 |
buffer[noBreakSpace] = ' '; |
182 |
}; |
| 180 |
} else if (start == (leftToRightMark & ~(GlyphPage::size - 1))) { |
183 |
|
| 181 |
// LRM, RLM, LRE, RLE, ZWNJ, ZWJ, and PDF must not render at all. |
184 |
overwriteCodePoints(0x0, 0x20, zeroWidthSpace); |
| 182 |
buffer[leftToRightMark - start] = zeroWidthSpace; |
185 |
overwriteCodePoints(0x7F, 0xA0, zeroWidthSpace); |
| 183 |
buffer[rightToLeftMark - start] = zeroWidthSpace; |
186 |
overwriteCodePoint(softHyphen, zeroWidthSpace); |
| 184 |
buffer[leftToRightEmbed - start] = zeroWidthSpace; |
187 |
overwriteCodePoint('\n', space); |
| 185 |
buffer[rightToLeftEmbed - start] = zeroWidthSpace; |
188 |
overwriteCodePoint('\t', space); |
| 186 |
buffer[leftToRightOverride - start] = zeroWidthSpace; |
189 |
overwriteCodePoint(noBreakSpace, space); |
| 187 |
buffer[rightToLeftOverride - start] = zeroWidthSpace; |
190 |
overwriteCodePoint(leftToRightMark, zeroWidthSpace); |
| 188 |
buffer[leftToRightIsolate - start] = zeroWidthSpace; |
191 |
overwriteCodePoint(rightToLeftMark, zeroWidthSpace); |
| 189 |
buffer[rightToLeftIsolate - start] = zeroWidthSpace; |
192 |
overwriteCodePoint(leftToRightEmbed, zeroWidthSpace); |
| 190 |
buffer[zeroWidthNonJoiner - start] = zeroWidthSpace; |
193 |
overwriteCodePoint(rightToLeftEmbed, zeroWidthSpace); |
| 191 |
buffer[zeroWidthJoiner - start] = zeroWidthSpace; |
194 |
overwriteCodePoint(leftToRightOverride, zeroWidthSpace); |
| 192 |
buffer[popDirectionalFormatting - start] = zeroWidthSpace; |
195 |
overwriteCodePoint(rightToLeftOverride, zeroWidthSpace); |
| 193 |
buffer[popDirectionalIsolate - start] = zeroWidthSpace; |
196 |
overwriteCodePoint(leftToRightIsolate, zeroWidthSpace); |
| 194 |
buffer[firstStrongIsolate - start] = zeroWidthSpace; |
197 |
overwriteCodePoint(rightToLeftIsolate, zeroWidthSpace); |
| 195 |
} else if (start == (objectReplacementCharacter & ~(GlyphPage::size - 1))) { |
198 |
overwriteCodePoint(zeroWidthNonJoiner, zeroWidthSpace); |
| 196 |
// Object replacement character must not render at all. |
199 |
overwriteCodePoint(zeroWidthJoiner, zeroWidthSpace); |
| 197 |
buffer[objectReplacementCharacter - start] = zeroWidthSpace; |
200 |
overwriteCodePoint(popDirectionalFormatting, zeroWidthSpace); |
| 198 |
} else if (start == (zeroWidthNoBreakSpace & ~(GlyphPage::size - 1))) { |
201 |
overwriteCodePoint(popDirectionalIsolate, zeroWidthSpace); |
| 199 |
// ZWNBS/BOM must not render at all. |
202 |
overwriteCodePoint(firstStrongIsolate, zeroWidthSpace); |
| 200 |
buffer[zeroWidthNoBreakSpace - start] = zeroWidthSpace; |
203 |
overwriteCodePoint(objectReplacementCharacter, zeroWidthSpace); |
| 201 |
} |
204 |
overwriteCodePoint(zeroWidthNoBreakSpace, zeroWidthSpace); |
| 202 |
} else { |
205 |
} else { |
| 203 |
bufferLength = GlyphPage::size * 2; |
206 |
bufferLength = glyphPageSize * 2; |
| 204 |
for (unsigned i = 0; i < GlyphPage::size; i++) { |
207 |
for (unsigned i = 0; i < glyphPageSize; i++) { |
| 205 |
int c = i + start; |
208 |
int c = i + start; |
| 206 |
buffer[i * 2] = U16_LEAD(c); |
209 |
buffer[i * 2] = U16_LEAD(c); |
| 207 |
buffer[i * 2 + 1] = U16_TRAIL(c); |
210 |
buffer[i * 2 + 1] = U16_TRAIL(c); |
|
Lines 238-244
const GlyphPage* Font::glyphPage(unsigned pageNumber) const
a/Source/WebCore/platform/graphics/Font.cpp_sec4
|
| 238 |
|
241 |
|
| 239 |
Glyph Font::glyphForCharacter(UChar32 character) const |
242 |
Glyph Font::glyphForCharacter(UChar32 character) const |
| 240 |
{ |
243 |
{ |
| 241 |
auto* page = glyphPage(character / GlyphPage::size); |
244 |
auto* page = glyphPage(GlyphPage::pageNumberForCodePoint(character)); |
| 242 |
if (!page) |
245 |
if (!page) |
| 243 |
return 0; |
246 |
return 0; |
| 244 |
return page->glyphForCharacter(character); |
247 |
return page->glyphForCharacter(character); |
|
Lines 246-252
Glyph Font::glyphForCharacter(UChar32 character) const
a/Source/WebCore/platform/graphics/Font.cpp_sec5
|
| 246 |
|
249 |
|
| 247 |
GlyphData Font::glyphDataForCharacter(UChar32 character) const |
250 |
GlyphData Font::glyphDataForCharacter(UChar32 character) const |
| 248 |
{ |
251 |
{ |
| 249 |
auto* page = glyphPage(character / GlyphPage::size); |
252 |
auto* page = glyphPage(GlyphPage::pageNumberForCodePoint(character)); |
| 250 |
if (!page) |
253 |
if (!page) |
| 251 |
return GlyphData(); |
254 |
return GlyphData(); |
| 252 |
return page->glyphDataForCharacter(character); |
255 |
return page->glyphDataForCharacter(character); |