18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006 Alexey Proskuryakov 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * its contributors may be used to endorse or promote products derived 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * from this software without specific prior written permission. 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "config.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "SimpleFontData.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "BlockExceptions.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "Color.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "FloatRect.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "Font.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "FontCache.h" 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "FontDescription.h" 398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "SharedBuffer.h" 408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import "WebCoreSystemInterface.h" 418f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#import <AppKit/AppKit.h> 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <ApplicationServices/ApplicationServices.h> 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <float.h> 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <unicode/uchar.h> 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <wtf/Assertions.h> 46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#import <wtf/StdLibExtras.h> 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#import <wtf/RetainPtr.h> 4821939df44de1705786c545cd1bf519d47250322dBen Murdoch#import <wtf/UnusedParam.h> 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@interface NSFont (WebAppKitSecretAPI) 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project- (BOOL)_isFakeFixedPitch; 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockusing namespace std; 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst float smallCapsFontSizeMultiplier = 0.7f; 59d0825bca7fe65beaee391d30da42e937db621564Steve Blockstatic inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x / unitsPerEm; } 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 61635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic bool initFontData(SimpleFontData* fontData) 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 635f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (!fontData->platformData().cgFont()) 648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef BUILDING_ON_TIGER 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSUStyle fontStyle; 688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (ATSUCreateStyle(&fontStyle) != noErr) 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 715f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian ATSUFontID fontId = fontData->platformData().m_atsuFontID; 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!fontId) { 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSUDisposeStyle(fontStyle); 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSUAttributeTag tag = kATSUFontTag; 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ByteCount size = sizeof(ATSUFontID); 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSUFontID *valueArray[1] = {&fontId}; 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OSStatus status = ATSUSetAttributes(fontStyle, 1, &tag, &size, (void* const*)valueArray); 818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (status != noErr) { 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSUDisposeStyle(fontStyle); 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (wkGetATSStyleGroup(fontStyle, &fontData->m_styleGroup) != noErr) { 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSUDisposeStyle(fontStyle); 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSUDisposeStyle(fontStyle); 928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic NSString *webFallbackFontFamily(void) 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 99635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(RetainPtr<NSString>, webFallbackFontFamily, ([[NSFont systemFontOfSize:16.0f] familyName])); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return webFallbackFontFamily.get(); 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if !ERROR_DISABLED 1045ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#if defined(__LP64__) || (!defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)) 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic NSString* pathFromFont(NSFont*) 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1075ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // FMGetATSFontRefFromFont is not available. As pathFromFont is only used for debugging purposes, 1085ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen // returning nil is acceptable. 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic NSString* pathFromFont(NSFont *font) 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef BUILDING_ON_TIGER 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSFontRef atsFont = FMGetATSFontRefFromFont(CTFontGetPlatformFont(toCTFontRef(font), 0)); 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ATSFontRef atsFont = FMGetATSFontRefFromFont(wkGetNSFontATSUFontId(font)); 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FSRef fileRef; 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifndef BUILDING_ON_TIGER 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OSStatus status = ATSFontGetFileReference(atsFont, &fileRef); 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (status != noErr) 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FSSpec oFile; 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project OSStatus status = ATSFontGetFileSpecification(atsFont, &oFile); 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (status != noErr) 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project status = FSpMakeFSRef(&oFile, &fileRef); 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (status != noErr) 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project UInt8 filePathBuffer[PATH_MAX]; 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project status = FSRefMakePath(&fileRef, filePathBuffer, PATH_MAX); 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (status == noErr) 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return [NSString stringWithUTF8String:(const char*)filePathBuffer]; 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return nil; 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // __LP64__ 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif // !ERROR_DISABLED 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SimpleFontData::platformInit() 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef BUILDING_ON_TIGER 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_styleGroup = 0; 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if USE(ATSUI) 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_ATSUMirrors = false; 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_checkedShapesArabic = false; 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_shapesArabic = false; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1575f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_syntheticBoldOffset = m_platformData.m_syntheticBold ? 1.0f : 0.f; 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool failedSetup = false; 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!initFontData(this)) { 1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Ack! Something very bad happened, like a corrupt font. 1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Try looking for an alternate 'base' font for this renderer. 1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Special case hack to use "Times New Roman" in place of "Times". 1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // "Times RO" is a common font whose family name is "Times". 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // It overrides the normal "Times" family font. 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // It also appears to have a corrupt regular variant. 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *fallbackFontFamily; 1695f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if ([[m_platformData.font() familyName] isEqual:@"Times"]) 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fallbackFontFamily = @"Times New Roman"; 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fallbackFontFamily = webFallbackFontFamily(); 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Try setting up the alternate font. 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This is a last ditch effort to use a substitute font when something has gone wrong. 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if !ERROR_DISABLED 1775f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian RetainPtr<NSFont> initialFont = m_platformData.font(); 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1795f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian if (m_platformData.font()) 1805f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_platformData.setFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toFamily:fallbackFontFamily]); 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else 1825f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_platformData.setFont([NSFont fontWithName:fallbackFontFamily size:m_platformData.size()]); 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if !ERROR_DISABLED 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *filePath = pathFromFont(initialFont.get()); 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!filePath) 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project filePath = @"not known"; 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!initFontData(this)) { 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ([fallbackFontFamily isEqual:@"Times New Roman"]) { 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // OK, couldn't setup Times New Roman as an alternate to Times, fallback 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // on the system font. If this fails we have no alternative left. 1925f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_platformData.setFont([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toFamily:webFallbackFontFamily()]); 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!initFontData(this)) { 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We tried, Times, Times New Roman, and the system font. No joy. We have to give up. 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("unable to initialize with font %@ at %@", initialFont.get(), filePath); 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project failedSetup = true; 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We tried the requested font and the system font. No joy. We have to give up. 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("unable to initialize with font %@ at %@", initialFont.get(), filePath); 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project failedSetup = true; 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Report the problem. 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("Corrupt font detected, using %@ in place of %@ located at \"%@\".", 2075f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian [m_platformData.font() familyName], [initialFont.get() familyName], filePath); 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If all else fails, try to set up using the system font. 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This is probably because Times and Times New Roman are both unavailable. 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (failedSetup) { 2135f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian m_platformData.setFont([NSFont systemFontOfSize:[m_platformData.font() pointSize]]); 2145f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian LOG_ERROR("failed to set up font, using system font %s", m_platformData.font()); 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project initFontData(this); 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int iAscent; 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int iDescent; 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int iLineGap; 2212fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned unitsPerEm; 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef BUILDING_ON_TIGER 2232fc2651226baac27029e38c9d6ef883fa32084dbSteve Block wkGetFontMetrics(m_platformData.cgFont(), &iAscent, &iDescent, &iLineGap, &unitsPerEm); 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#else 2255f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian iAscent = CGFontGetAscent(m_platformData.cgFont()); 2265f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian iDescent = CGFontGetDescent(m_platformData.cgFont()); 2275f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian iLineGap = CGFontGetLeading(m_platformData.cgFont()); 2282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont()); 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian float pointSize = m_platformData.m_size; 2322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block float ascent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize; 2332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block float descent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize; 2342fc2651226baac27029e38c9d6ef883fa32084dbSteve Block float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize; 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We need to adjust Times, Helvetica, and Courier to closely match the 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // vertical metrics of their Microsoft counterparts that are the de facto 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // web standard. The AppKit adjustment of 20% is too big and is 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // incorrectly added to line spacing, so we use a 15% adjustment instead 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // and add it to the ascent. 2415f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NSString *familyName = [m_platformData.font() familyName]; 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if ([familyName isEqualToString:@"Times"] || [familyName isEqualToString:@"Helvetica"] || [familyName isEqualToString:@"Courier"]) 2432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ascent += floorf(((ascent + descent) * 0.15f) + 0.5f); 2442daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#if defined(BUILDING_ON_LEOPARD) 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project else if ([familyName isEqualToString:@"Geeza Pro"]) { 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Geeza Pro has glyphs that draw slightly above the ascent or far below the descent. Adjust 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // those vertical metrics to better match reality, so that diacritics at the bottom of one line 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // do not overlap diacritics at the top of the next line. 2492fc2651226baac27029e38c9d6ef883fa32084dbSteve Block ascent *= 1.08f; 2502fc2651226baac27029e38c9d6ef883fa32084dbSteve Block descent *= 2.f; 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2522daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#endif 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2542fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Compute and store line spacing, before the line metrics hacks are applied. 2552fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap)); 2562fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Hack Hiragino line metrics to allow room for marked text underlines. 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // <rdar://problem/5386183> 2592fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (descent < 3 && lineGap >= 3 && [familyName hasPrefix:@"Hiragino"]) { 2602fc2651226baac27029e38c9d6ef883fa32084dbSteve Block lineGap -= 3 - descent; 2612fc2651226baac27029e38c9d6ef883fa32084dbSteve Block descent = 3; 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2642bde8e466a4451c7319e3a072d118917957d6554Steve Block if (platformData().orientation() == Vertical && !isTextOrientationFallback()) { 2656b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner // The check doesn't look neat but this is what AppKit does for vertical writing... 2666b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner RetainPtr<CFArrayRef> tableTags(AdoptCF, CTFontCopyAvailableTables(m_platformData.ctFont(), kCTFontTableOptionExcludeSynthetic)); 2676b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CFIndex numTables = CFArrayGetCount(tableTags.get()); 2686b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner for (CFIndex index = 0; index < numTables; ++index) { 2696b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index); 2706b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner if (tag == kCTFontTableVhea || tag == kCTFontTableVORG) { 2712bde8e466a4451c7319e3a072d118917957d6554Steve Block m_hasVerticalGlyphs = true; 2726b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner break; 2736b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2746b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2756b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 2766b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 2772fc2651226baac27029e38c9d6ef883fa32084dbSteve Block float xHeight; 2782fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2792bde8e466a4451c7319e3a072d118917957d6554Steve Block if (platformData().orientation() == Horizontal) { 2802bde8e466a4451c7319e3a072d118917957d6554Steve Block // Measure the actual character "x", since it's possible for it to extend below the baseline, and we need the 2812bde8e466a4451c7319e3a072d118917957d6554Steve Block // reported x-height to only include the portion of the glyph that is above the baseline. 2822bde8e466a4451c7319e3a072d118917957d6554Steve Block GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page(); 2832bde8e466a4451c7319e3a072d118917957d6554Steve Block NSGlyph xGlyph = glyphPageZero ? glyphPageZero->glyphDataForCharacter('x').glyph : 0; 2842bde8e466a4451c7319e3a072d118917957d6554Steve Block if (xGlyph) 2852bde8e466a4451c7319e3a072d118917957d6554Steve Block xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph)); 2862bde8e466a4451c7319e3a072d118917957d6554Steve Block else 2872bde8e466a4451c7319e3a072d118917957d6554Steve Block xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()), unitsPerEm) * pointSize; 2882bde8e466a4451c7319e3a072d118917957d6554Steve Block } else 2892bde8e466a4451c7319e3a072d118917957d6554Steve Block xHeight = verticalRightOrientationFontData()->fontMetrics().xHeight(); 2902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 2912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setUnitsPerEm(unitsPerEm); 2922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setAscent(ascent); 2932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setDescent(descent); 2942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setLineGap(lineGap); 2952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_fontMetrics.setXHeight(xHeight); 2965f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian} 2972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 298ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockstatic CFDataRef copyFontTableForTag(FontPlatformData& platformData, FourCharCode tableName) 299692e5dbf12901edacf14812a6fae25462920af42Steve Block{ 300692e5dbf12901edacf14812a6fae25462920af42Steve Block#ifdef BUILDING_ON_TIGER 301692e5dbf12901edacf14812a6fae25462920af42Steve Block ATSFontRef atsFont = FMGetATSFontRefFromFont(platformData.m_atsuFontID); 302692e5dbf12901edacf14812a6fae25462920af42Steve Block 303692e5dbf12901edacf14812a6fae25462920af42Steve Block ByteCount tableSize; 304692e5dbf12901edacf14812a6fae25462920af42Steve Block if (ATSFontGetTable(atsFont, tableName, 0, 0, NULL, &tableSize) != noErr) 305692e5dbf12901edacf14812a6fae25462920af42Steve Block return 0; 306692e5dbf12901edacf14812a6fae25462920af42Steve Block 307692e5dbf12901edacf14812a6fae25462920af42Steve Block CFMutableDataRef data = CFDataCreateMutable(kCFAllocatorDefault, tableSize); 308692e5dbf12901edacf14812a6fae25462920af42Steve Block if (!data) 309692e5dbf12901edacf14812a6fae25462920af42Steve Block return 0; 310692e5dbf12901edacf14812a6fae25462920af42Steve Block 311692e5dbf12901edacf14812a6fae25462920af42Steve Block CFDataIncreaseLength(data, tableSize); 312692e5dbf12901edacf14812a6fae25462920af42Steve Block if (ATSFontGetTable(atsFont, tableName, 0, tableSize, CFDataGetMutableBytePtr(data), &tableSize) != noErr) { 313692e5dbf12901edacf14812a6fae25462920af42Steve Block CFRelease(data); 314692e5dbf12901edacf14812a6fae25462920af42Steve Block return 0; 315692e5dbf12901edacf14812a6fae25462920af42Steve Block } 316692e5dbf12901edacf14812a6fae25462920af42Steve Block 317692e5dbf12901edacf14812a6fae25462920af42Steve Block return data; 318692e5dbf12901edacf14812a6fae25462920af42Steve Block#else 319692e5dbf12901edacf14812a6fae25462920af42Steve Block return CGFontCopyTableForTag(platformData.cgFont(), tableName); 320692e5dbf12901edacf14812a6fae25462920af42Steve Block#endif 321692e5dbf12901edacf14812a6fae25462920af42Steve Block} 3225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3235f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid SimpleFontData::platformCharWidthInit() 3245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian{ 325692e5dbf12901edacf14812a6fae25462920af42Steve Block m_avgCharWidth = 0; 326692e5dbf12901edacf14812a6fae25462920af42Steve Block m_maxCharWidth = 0; 327692e5dbf12901edacf14812a6fae25462920af42Steve Block 328692e5dbf12901edacf14812a6fae25462920af42Steve Block RetainPtr<CFDataRef> os2Table(AdoptCF, copyFontTableForTag(m_platformData, 'OS/2')); 329692e5dbf12901edacf14812a6fae25462920af42Steve Block if (os2Table && CFDataGetLength(os2Table.get()) >= 4) { 330692e5dbf12901edacf14812a6fae25462920af42Steve Block const UInt8* os2 = CFDataGetBytePtr(os2Table.get()); 331692e5dbf12901edacf14812a6fae25462920af42Steve Block SInt16 os2AvgCharWidth = os2[2] * 256 + os2[3]; 3322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_fontMetrics.unitsPerEm()) * m_platformData.m_size; 3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian } 3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 335692e5dbf12901edacf14812a6fae25462920af42Steve Block RetainPtr<CFDataRef> headTable(AdoptCF, copyFontTableForTag(m_platformData, 'head')); 336692e5dbf12901edacf14812a6fae25462920af42Steve Block if (headTable && CFDataGetLength(headTable.get()) >= 42) { 337692e5dbf12901edacf14812a6fae25462920af42Steve Block const UInt8* head = CFDataGetBytePtr(headTable.get()); 338692e5dbf12901edacf14812a6fae25462920af42Steve Block ushort uxMin = head[36] * 256 + head[37]; 339692e5dbf12901edacf14812a6fae25462920af42Steve Block ushort uxMax = head[40] * 256 + head[41]; 340692e5dbf12901edacf14812a6fae25462920af42Steve Block SInt16 xMin = static_cast<SInt16>(uxMin); 341692e5dbf12901edacf14812a6fae25462920af42Steve Block SInt16 xMax = static_cast<SInt16>(uxMax); 342692e5dbf12901edacf14812a6fae25462920af42Steve Block float diff = static_cast<float>(xMax - xMin); 3432fc2651226baac27029e38c9d6ef883fa32084dbSteve Block m_maxCharWidth = scaleEmToUnits(diff, m_fontMetrics.unitsPerEm()) * m_platformData.m_size; 344692e5dbf12901edacf14812a6fae25462920af42Steve Block } 3455f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3465f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian // Fallback to a cross-platform estimate, which will populate these values if they are non-positive. 3475f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian initCharWidths(); 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SimpleFontData::platformDestroy() 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 352f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!isCustomFont() && m_derivedFontData) { 353f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // These come from the cache. 354f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_derivedFontData->smallCaps) 355f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch fontCache()->releaseFontData(m_derivedFontData->smallCaps.leakPtr()); 356f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 357f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_derivedFontData->emphasisMark) 358f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch fontCache()->releaseFontData(m_derivedFontData->emphasisMark.leakPtr()); 3596b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner } 3606b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#ifdef BUILDING_ON_TIGER 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_styleGroup) 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project wkReleaseStyleGroup(m_styleGroup); 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if USE(ATSUI) 366d0825bca7fe65beaee391d30da42e937db621564Steve Block HashMap<unsigned, ATSUStyle>::iterator end = m_ATSUStyleMap.end(); 367d0825bca7fe65beaee391d30da42e937db621564Steve Block for (HashMap<unsigned, ATSUStyle>::iterator it = m_ATSUStyleMap.begin(); it != end; ++it) 368d0825bca7fe65beaee391d30da42e937db621564Steve Block ATSUDisposeStyle(it->second); 3698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 372f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::scaledFontData(const FontDescription& fontDescription, float scaleFactor) const 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 374f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (isCustomFont()) { 375f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch FontPlatformData scaledFontData(m_platformData); 376f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch scaledFontData.m_size = scaledFontData.m_size * scaleFactor; 377f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return new SimpleFontData(scaledFontData, true, false); 378f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 379f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 380f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch BEGIN_BLOCK_OBJC_EXCEPTIONS; 381f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch float size = m_platformData.size() * scaleFactor; 3822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.font() toSize:size], size, false, false, m_platformData.orientation()); 383f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 384f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // AppKit resets the type information (screen/printer) when you convert a font to a different size. 385f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // We have to fix up the font that we're handed back. 386f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch scaledFontData.setFont(fontDescription.usePrinterFont() ? [scaledFontData.font() printerFont] : [scaledFontData.font() screenFont]); 387f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 388f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (scaledFontData.font()) { 389f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch NSFontManager *fontManager = [NSFontManager sharedFontManager]; 390f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.font()]; 391f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 392f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_platformData.m_syntheticBold) 393f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch fontTraits |= NSBoldFontMask; 394f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (m_platformData.m_syntheticOblique) 395f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch fontTraits |= NSItalicFontMask; 396f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 397f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontData.font()]; 398f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch scaledFontData.m_syntheticBold = (fontTraits & NSBoldFontMask) && !(scaledFontTraits & NSBoldFontMask); 399f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch scaledFontData.m_syntheticOblique = (fontTraits & NSItalicFontMask) && !(scaledFontTraits & NSItalicFontMask); 400f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 401f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return fontCache()->getCachedFontData(&scaledFontData); 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 403f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch END_BLOCK_OBJC_EXCEPTIONS; 404f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 405f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return 0; 406f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 407f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 408f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::smallCapsFontData(const FontDescription& fontDescription) const 409f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 410f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData) 411f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData = DerivedFontData::create(isCustomFont()); 412f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData->smallCaps) 413f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData->smallCaps = scaledFontData(fontDescription, smallCapsFontSizeMultiplier); 414f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 415f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return m_derivedFontData->smallCaps.get(); 416f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 417f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 418f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochSimpleFontData* SimpleFontData::emphasisMarkFontData(const FontDescription& fontDescription) const 419f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 420f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData) 421f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData = DerivedFontData::create(isCustomFont()); 422f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!m_derivedFontData->emphasisMark) 423f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch m_derivedFontData->emphasisMark = scaledFontData(fontDescription, .5f); 424f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 425f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return m_derivedFontData->emphasisMark.get(); 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool SimpleFontData::containsCharacters(const UChar* characters, int length) const 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 430635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project NSString *string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(characters) length:length freeWhenDone:NO]; 4315f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NSCharacterSet *set = [[m_platformData.font() coveredCharacterSet] invertedSet]; 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool result = set && [string rangeOfCharacterFromSet:set].location == NSNotFound; 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [string release]; 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid SimpleFontData::determinePitch() 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4395f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian NSFont* f = m_platformData.font(); 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Special case Osaka-Mono. 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // According to <rdar://problem/3999467>, we should treat Osaka-Mono as fixed pitch. 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Note that the AppKit does not report Osaka-Mono as fixed pitch. 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Special case MS-PGothic. 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // According to <rdar://problem/4032938>, we should not treat MS-PGothic as fixed pitch. 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Note that AppKit does report MS-PGothic as fixed pitch. 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Special case MonotypeCorsiva 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // According to <rdar://problem/5454704>, we should not treat MonotypeCorsiva as fixed pitch. 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Note that AppKit does report MonotypeCorsiva as fixed pitch. 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project NSString *name = [f fontName]; 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_treatAsFixedPitch = ([f isFixedPitch] || [f _isFakeFixedPitch] || 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [name caseInsensitiveCompare:@"Osaka-Mono"] == NSOrderedSame) && 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [name caseInsensitiveCompare:@"MS-PGothic"] != NSOrderedSame && 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project [name caseInsensitiveCompare:@"MonotypeCorsiva"] != NSOrderedSame; 4578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 45921939df44de1705786c545cd1bf519d47250322dBen MurdochFloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const 46021939df44de1705786c545cd1bf519d47250322dBen Murdoch{ 46121939df44de1705786c545cd1bf519d47250322dBen Murdoch FloatRect boundingBox; 4622bde8e466a4451c7319e3a072d118917957d6554Steve Block boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(), platformData().orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &glyph, 0, 1); 4632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block boundingBox.setY(-boundingBox.maxY()); 4645af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (m_syntheticBoldOffset) 4655af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset); 4665af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke 46721939df44de1705786c545cd1bf519d47250322dBen Murdoch return boundingBox; 46821939df44de1705786c545cd1bf519d47250322dBen Murdoch} 46921939df44de1705786c545cd1bf519d47250322dBen Murdoch 47021939df44de1705786c545cd1bf519d47250322dBen Murdochfloat SimpleFontData::platformWidthForGlyph(Glyph glyph) const 4718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CGSize advance; 4732bde8e466a4451c7319e3a072d118917957d6554Steve Block if (platformData().orientation() == Horizontal || m_isBrokenIdeographFallback) { 474e14391e94c850b8bd03680c23b38978db68687a8John Reck NSFont* font = platformData().font(); 475e14391e94c850b8bd03680c23b38978db68687a8John Reck float pointSize = platformData().m_size; 476e14391e94c850b8bd03680c23b38978db68687a8John Reck CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize); 477e14391e94c850b8bd03680c23b38978db68687a8John Reck if (!wkGetGlyphTransformedAdvances(platformData().cgFont(), font, &m, &glyph, &advance)) { 478e14391e94c850b8bd03680c23b38978db68687a8John Reck LOG_ERROR("Unable to cache glyph widths for %@ %f", [font displayName], pointSize); 479e14391e94c850b8bd03680c23b38978db68687a8John Reck advance.width = 0; 480e14391e94c850b8bd03680c23b38978db68687a8John Reck } 481e14391e94c850b8bd03680c23b38978db68687a8John Reck } else 482e14391e94c850b8bd03680c23b38978db68687a8John Reck CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), kCTFontVerticalOrientation, &glyph, &advance, 1); 483e14391e94c850b8bd03680c23b38978db68687a8John Reck 48421939df44de1705786c545cd1bf519d47250322dBen Murdoch return advance.width + m_syntheticBoldOffset; 4858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 488