OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2005, 2006, 2010, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2010, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2006 Alexey Proskuryakov | 3 * Copyright (C) 2006 Alexey Proskuryakov |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 148 |
149 // Special case hack to use "Times New Roman" in place of "Times". | 149 // Special case hack to use "Times New Roman" in place of "Times". |
150 // "Times RO" is a common font whose family name is "Times". | 150 // "Times RO" is a common font whose family name is "Times". |
151 // It overrides the normal "Times" family font. | 151 // It overrides the normal "Times" family font. |
152 // It also appears to have a corrupt regular variant. | 152 // It also appears to have a corrupt regular variant. |
153 NSString *fallbackFontFamily; | 153 NSString *fallbackFontFamily; |
154 if ([[m_platformData.font() familyName] isEqual:@"Times"]) | 154 if ([[m_platformData.font() familyName] isEqual:@"Times"]) |
155 fallbackFontFamily = @"Times New Roman"; | 155 fallbackFontFamily = @"Times New Roman"; |
156 else | 156 else |
157 fallbackFontFamily = webFallbackFontFamily(); | 157 fallbackFontFamily = webFallbackFontFamily(); |
158 | 158 |
159 // Try setting up the alternate font. | 159 // Try setting up the alternate font. |
160 // This is a last ditch effort to use a substitute font when something h
as gone wrong. | 160 // This is a last ditch effort to use a substitute font when something h
as gone wrong. |
161 #if !ERROR_DISABLED | 161 #if !ERROR_DISABLED |
162 RetainPtr<NSFont> initialFont = m_platformData.font(); | 162 RetainPtr<NSFont> initialFont = m_platformData.font(); |
163 #endif | 163 #endif |
164 if (m_platformData.font()) | 164 if (m_platformData.font()) |
165 m_platformData.setFont([[NSFontManager sharedFontManager] convertFon
t:m_platformData.font() toFamily:fallbackFontFamily]); | 165 m_platformData.setFont([[NSFontManager sharedFontManager] convertFon
t:m_platformData.font() toFamily:fallbackFontFamily]); |
166 else | 166 else |
167 m_platformData.setFont([NSFont fontWithName:fallbackFontFamily size:
m_platformData.size()]); | 167 m_platformData.setFont([NSFont fontWithName:fallbackFontFamily size:
m_platformData.size()]); |
168 | 168 |
(...skipping 19 matching lines...) Expand all Loading... |
188 [m_platformData.font() familyName], [initialFont.get() familyName]); | 188 [m_platformData.font() familyName], [initialFont.get() familyName]); |
189 } | 189 } |
190 | 190 |
191 // If all else fails, try to set up using the system font. | 191 // If all else fails, try to set up using the system font. |
192 // This is probably because Times and Times New Roman are both unavailable. | 192 // This is probably because Times and Times New Roman are both unavailable. |
193 if (failedSetup) { | 193 if (failedSetup) { |
194 m_platformData.setFont([NSFont systemFontOfSize:[m_platformData.font() p
ointSize]]); | 194 m_platformData.setFont([NSFont systemFontOfSize:[m_platformData.font() p
ointSize]]); |
195 WTF_LOG_ERROR("failed to set up font, using system font %s", m_platformD
ata.font()); | 195 WTF_LOG_ERROR("failed to set up font, using system font %s", m_platformD
ata.font()); |
196 initFontData(this); | 196 initFontData(this); |
197 } | 197 } |
198 | 198 |
199 int iAscent; | 199 int iAscent; |
200 int iDescent; | 200 int iDescent; |
201 int iLineGap; | 201 int iLineGap; |
202 unsigned unitsPerEm; | 202 unsigned unitsPerEm; |
| 203 |
203 iAscent = CGFontGetAscent(m_platformData.cgFont()); | 204 iAscent = CGFontGetAscent(m_platformData.cgFont()); |
204 // Some fonts erroneously specify a positive descender value. We follow Core
Text in assuming that | 205 // Some fonts erroneously specify a positive descender value. We follow Core
Text in assuming that |
205 // such fonts meant the same distance, but in the reverse direction. | 206 // such fonts meant the same distance, but in the reverse direction. |
206 iDescent = -abs(CGFontGetDescent(m_platformData.cgFont())); | 207 iDescent = -abs(CGFontGetDescent(m_platformData.cgFont())); |
207 iLineGap = CGFontGetLeading(m_platformData.cgFont()); | 208 iLineGap = CGFontGetLeading(m_platformData.cgFont()); |
208 unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont()); | 209 unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont()); |
209 | 210 |
210 float pointSize = m_platformData.m_size; | 211 float pointSize = m_platformData.m_size; |
211 float ascent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize; | 212 float ascent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize; |
212 float descent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize; | 213 float descent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize; |
213 float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize; | 214 float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize; |
| 215 float underlineThickness = CTFontGetUnderlineThickness(m_platformData.ctFont
()); |
214 | 216 |
215 // We need to adjust Times, Helvetica, and Courier to closely match the | 217 // We need to adjust Times, Helvetica, and Courier to closely match the |
216 // vertical metrics of their Microsoft counterparts that are the de facto | 218 // vertical metrics of their Microsoft counterparts that are the de facto |
217 // web standard. The AppKit adjustment of 20% is too big and is | 219 // web standard. The AppKit adjustment of 20% is too big and is |
218 // incorrectly added to line spacing, so we use a 15% adjustment instead | 220 // incorrectly added to line spacing, so we use a 15% adjustment instead |
219 // and add it to the ascent. | 221 // and add it to the ascent. |
220 NSString *familyName = [m_platformData.font() familyName]; | 222 NSString *familyName = [m_platformData.font() familyName]; |
221 if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"H
elvetica"] || [familyName isEqualToString:@"Courier"]) | 223 if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"H
elvetica"] || [familyName isEqualToString:@"Courier"]) |
222 ascent += floorf(((ascent + descent) * 0.15f) + 0.5f); | 224 ascent += floorf(((ascent + descent) * 0.15f) + 0.5f); |
223 | 225 |
224 // Compute and store line spacing, before the line metrics hacks are applied
. | 226 // Compute and store line spacing, before the line metrics hacks are applied
. |
225 m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(li
neGap)); | 227 m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(li
neGap)); |
226 | 228 |
227 // Hack Hiragino line metrics to allow room for marked text underlines. | 229 // Hack Hiragino line metrics to allow room for marked text underlines. |
228 // <rdar://problem/5386183> | 230 // <rdar://problem/5386183> |
229 if (descent < 3 && lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) { | 231 if (descent < 3 && lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) { |
230 lineGap -= 3 - descent; | 232 lineGap -= 3 - descent; |
231 descent = 3; | 233 descent = 3; |
232 } | 234 } |
233 | 235 |
234 if (platformData().orientation() == Vertical && !isTextOrientationFallback()
) | 236 if (platformData().orientation() == Vertical && !isTextOrientationFallback()
) |
235 m_hasVerticalGlyphs = fontHasVerticalGlyphs(m_platformData.ctFont()); | 237 m_hasVerticalGlyphs = fontHasVerticalGlyphs(m_platformData.ctFont()); |
236 | 238 |
237 float xHeight; | 239 float xHeight; |
238 | 240 |
239 if (platformData().orientation() == Horizontal) { | 241 if (platformData().orientation() == Horizontal) { |
240 // Measure the actual character "x", since it's possible for it to exten
d below the baseline, and we need the | 242 // Measure the actual character "x", since it's possible for it to exten
d below the baseline, and we need the |
241 // reported x-height to only include the portion of the glyph that is ab
ove the baseline. | 243 // reported x-height to only include the portion of the glyph that is ab
ove the baseline. |
242 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->pag
e(); | 244 GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->pag
e(); |
243 NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphForCharacter('x') :
0; | 245 NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphForCharacter('x') :
0; |
244 if (xGlyph) | 246 if (xGlyph) |
245 xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph)); | 247 xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph)); |
246 else | 248 else |
247 xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()),
unitsPerEm) * pointSize; | 249 xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()),
unitsPerEm) * pointSize; |
248 } else | 250 } else |
249 xHeight = verticalRightOrientationFontData()->fontMetrics().xHeight(); | 251 xHeight = verticalRightOrientationFontData()->fontMetrics().xHeight(); |
250 | 252 |
251 m_fontMetrics.setUnitsPerEm(unitsPerEm); | 253 m_fontMetrics.setUnitsPerEm(unitsPerEm); |
252 m_fontMetrics.setAscent(ascent); | 254 m_fontMetrics.setAscent(ascent); |
253 m_fontMetrics.setDescent(descent); | 255 m_fontMetrics.setDescent(descent); |
254 m_fontMetrics.setLineGap(lineGap); | 256 m_fontMetrics.setLineGap(lineGap); |
255 m_fontMetrics.setXHeight(xHeight); | 257 m_fontMetrics.setXHeight(xHeight); |
| 258 m_fontMetrics.setUnderlineThickness(underlineThickness); |
256 } | 259 } |
257 | 260 |
258 static CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCod
e tableName) | 261 static CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCod
e tableName) |
259 { | 262 { |
260 return CGFontCopyTableForTag(platformData.cgFont(), tableName); | 263 return CGFontCopyTableForTag(platformData.cgFont(), tableName); |
261 } | 264 } |
262 | 265 |
263 void SimpleFontData::platformCharWidthInit() | 266 void SimpleFontData::platformCharWidthInit() |
264 { | 267 { |
265 m_avgCharWidth = 0; | 268 m_avgCharWidth = 0; |
266 m_maxCharWidth = 0; | 269 m_maxCharWidth = 0; |
267 | 270 |
268 RetainPtr<CFDataRef> os2Table(AdoptCF, copyFontTableForTag(m_platformData, '
OS/2')); | 271 RetainPtr<CFDataRef> os2Table(AdoptCF, copyFontTableForTag(m_platformData, '
OS/2')); |
269 if (os2Table && CFDataGetLength(os2Table.get()) >= 4) { | 272 if (os2Table && CFDataGetLength(os2Table.get()) >= 4) { |
270 const UInt8* os2 = CFDataGetBytePtr(os2Table.get()); | 273 const UInt8* os2 = CFDataGetBytePtr(os2Table.get()); |
271 SInt16 os2AvgCharWidth = os2[2] * 256 + os2[3]; | 274 SInt16 os2AvgCharWidth = os2[2] * 256 + os2[3]; |
272 m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_fontMetrics.unitsPerE
m()) * m_platformData.m_size; | 275 m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_fontMetrics.unitsPerE
m()) * m_platformData.m_size; |
273 } | 276 } |
274 | 277 |
275 RetainPtr<CFDataRef> headTable(AdoptCF, copyFontTableForTag(m_platformData,
'head')); | 278 RetainPtr<CFDataRef> headTable(AdoptCF, copyFontTableForTag(m_platformData,
'head')); |
276 if (headTable && CFDataGetLength(headTable.get()) >= 42) { | 279 if (headTable && CFDataGetLength(headTable.get()) >= 42) { |
277 const UInt8* head = CFDataGetBytePtr(headTable.get()); | 280 const UInt8* head = CFDataGetBytePtr(headTable.get()); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont,
0)); | 446 RetainPtr<CGFontRef> runCGFont(AdoptCF, CTFontCopyGraphicsFont(runFont,
0)); |
444 if (!CFEqual(runCGFont.get(), cgFont.get())) | 447 if (!CFEqual(runCGFont.get(), cgFont.get())) |
445 return false; | 448 return false; |
446 } | 449 } |
447 | 450 |
448 addResult.iterator->value = true; | 451 addResult.iterator->value = true; |
449 return true; | 452 return true; |
450 } | 453 } |
451 | 454 |
452 } // namespace WebCore | 455 } // namespace WebCore |
OLD | NEW |