1 /* 2 * Copyright (C) 2007 Kevin Ollivier <kevino (at) theolliviers.com> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 // this needs to be included before fontprops.h for UChar* to be defined. 28 #include <wtf/unicode/Unicode.h> 29 30 #include "fontprops.h" 31 #include "WebCoreSystemInterface.h" 32 33 #include <ApplicationServices/ApplicationServices.h> 34 35 #include <wx/defs.h> 36 #include <wx/gdicmn.h> 37 #include <wx/graphics.h> 38 39 const float smallCapsFontSizeMultiplier = 0.7f; 40 const float contextDPI = 72.0f; 41 static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x * (contextDPI / (contextDPI * unitsPerEm)); } 42 43 wxFontProperties::wxFontProperties(wxFont* font): 44 m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0) 45 { 46 CGFontRef cgFont; 47 48 #ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT 49 cgFont = CTFontCopyGraphicsFont((CTFontRef)font->OSXGetCTFont(), NULL); 50 #else 51 ATSFontRef fontRef; 52 53 fontRef = FMGetATSFontRefFromFont(font->MacGetATSUFontID()); 54 55 if (fontRef) 56 cgFont = CGFontCreateWithPlatformFont((void*)&fontRef); 57 #endif 58 59 if (cgFont) { 60 int iAscent; 61 int iDescent; 62 int iLineGap; 63 unsigned unitsPerEm; 64 #ifdef BUILDING_ON_TIGER 65 wkGetFontMetrics(cgFont, &iAscent, &iDescent, &iLineGap, &unitsPerEm); 66 #else 67 iAscent = CGFontGetAscent(cgFont); 68 iDescent = CGFontGetDescent(cgFont); 69 iLineGap = CGFontGetLeading(cgFont); 70 unitsPerEm = CGFontGetUnitsPerEm(cgFont); 71 #endif 72 float pointSize = font->GetPointSize(); 73 float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize; 74 float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize; 75 float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize; 76 77 m_ascent = lroundf(fAscent); 78 m_descent = lroundf(fDescent); 79 m_lineGap = lroundf(fLineGap); 80 wxCoord xHeight = 0; 81 GetTextExtent(*font, wxT("x"), NULL, &xHeight, NULL, NULL); 82 m_xHeight = lroundf(xHeight); 83 m_lineSpacing = m_ascent + m_descent + m_lineGap; 84 85 } 86 87 if (cgFont) 88 CGFontRelease(cgFont); 89 90 } 91 92 bool wxFontContainsCharacters(void* font, const UChar* characters, int length) 93 { 94 NSString* string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(characters) length:length freeWhenDone:NO]; 95 NSCharacterSet* set = [[(NSFont*)font coveredCharacterSet] invertedSet]; 96 bool result = set && [string rangeOfCharacterFromSet:set].location == NSNotFound; 97 [string release]; 98 return result; 99 } 100 101 void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height, 102 wxCoord *descent, wxCoord *externalLeading ) 103 { 104 wxGraphicsContext * const gc = wxGraphicsContext::Create(); 105 106 gc->SetFont(font, *wxBLACK); // colour doesn't matter but must be specified 107 struct GCTextExtent 108 { 109 wxDouble width, height, descent, externalLeading; 110 } e; 111 gc->GetTextExtent(str, &e.width, &e.height, &e.descent, &e.externalLeading); 112 if ( width ) 113 *width = wxCoord(e.width + .5); 114 if ( height ) 115 *height = wxCoord(e.height + .5); 116 if ( descent ) 117 *descent = wxCoord(e.descent + .5); 118 if ( externalLeading ) 119 *externalLeading = wxCoord(e.externalLeading + .5); 120 121 delete gc; 122 } 123