Home | History | Annotate | Download | only in carbon
      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 
     32 #include <ApplicationServices/ApplicationServices.h>
     33 
     34 #include <wx/defs.h>
     35 #include <wx/gdicmn.h>
     36 #include <wx/graphics.h>
     37 
     38 #ifdef BUILDING_ON_TIGER
     39 void (*wkGetFontMetrics)(CGFontRef, int* ascent, int* descent, int* lineGap, unsigned* unitsPerEm);
     40 #endif
     41 
     42 const float smallCapsFontSizeMultiplier = 0.7f;
     43 const float contextDPI = 72.0f;
     44 static inline float scaleEmToUnits(float x, unsigned unitsPerEm) { return x * (contextDPI / (contextDPI * unitsPerEm)); }
     45 
     46 wxFontProperties::wxFontProperties(wxFont* font):
     47 m_ascent(0), m_descent(0), m_lineGap(0), m_lineSpacing(0), m_xHeight(0)
     48 {
     49     CGFontRef cgFont;
     50 
     51 #ifdef wxOSX_USE_CORE_TEXT && wxOSX_USE_CORE_TEXT
     52     cgFont = CTFontCopyGraphicsFont((CTFontRef)font->OSXGetCTFont(), NULL);
     53 #else
     54     ATSFontRef fontRef;
     55 
     56     fontRef = FMGetATSFontRefFromFont(font->MacGetATSUFontID());
     57 
     58     if (fontRef)
     59         cgFont = CGFontCreateWithPlatformFont((void*)&fontRef);
     60 #endif
     61 
     62     if (cgFont) {
     63         int iAscent;
     64         int iDescent;
     65         int iLineGap;
     66         unsigned unitsPerEm;
     67 #ifdef BUILDING_ON_TIGER
     68         wkGetFontMetrics(cgFont, &iAscent, &iDescent, &iLineGap, &unitsPerEm);
     69 #else
     70         iAscent = CGFontGetAscent(cgFont);
     71         iDescent = CGFontGetDescent(cgFont);
     72         iLineGap = CGFontGetLeading(cgFont);
     73         unitsPerEm = CGFontGetUnitsPerEm(cgFont);
     74 #endif
     75         float pointSize = font->GetPointSize();
     76         float fAscent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
     77         float fDescent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
     78         float fLineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
     79 
     80         m_ascent = lroundf(fAscent);
     81         m_descent = lroundf(fDescent);
     82         m_lineGap = lroundf(fLineGap);
     83         wxCoord xHeight = 0;
     84         GetTextExtent(*font, wxT("x"), NULL, &xHeight, NULL, NULL);
     85         m_xHeight = lroundf(xHeight);
     86         m_lineSpacing = m_ascent + m_descent + m_lineGap;
     87 
     88     }
     89 
     90     if (cgFont)
     91         CGFontRelease(cgFont);
     92 
     93 }
     94 
     95 bool wxFontContainsCharacters(const wxFont& font, const UChar* characters, int length)
     96 {
     97 #if wxOSX_USE_COCOA
     98     NSString* string = [[NSString alloc] initWithCharactersNoCopy:const_cast<unichar*>(characters) length:length freeWhenDone:NO];
     99     NSCharacterSet* set = [[font.GetNSFont() coveredCharacterSet] invertedSet];
    100     bool result = set && [string rangeOfCharacterFromSet:set].location == NSNotFound;
    101     [string release];
    102     return result;
    103 #else
    104     return true;
    105 #endif
    106 }
    107 
    108 void GetTextExtent( const wxFont& font, const wxString& str, wxCoord *width, wxCoord *height,
    109                             wxCoord *descent, wxCoord *externalLeading )
    110 {
    111     wxGraphicsContext * const gc = wxGraphicsContext::Create();
    112     gc->SetFont(font, *wxBLACK); // colour doesn't matter but must be specified
    113     struct GCTextExtent
    114     {
    115         wxDouble width, height, descent, externalLeading;
    116     } e;
    117     gc->GetTextExtent(str, &e.width, &e.height, &e.descent, &e.externalLeading);
    118     if ( width )
    119         *width = wxCoord(e.width + .5);
    120     if ( height )
    121         *height = wxCoord(e.height + .5);
    122     if ( descent )
    123         *descent = wxCoord(e.descent + .5);
    124     if ( externalLeading )
    125         *externalLeading = wxCoord(e.externalLeading + .5);
    126 
    127     delete gc;
    128 }
    129