1/*
2 * Copyright (C) 2010 Kevin Ollivier, Stefan Csomor  All rights reserved.
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 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include "config.h"
30#include "FontPlatformData.h"
31
32#include <wx/defs.h>
33#include <wx/font.h>
34#include <wx/fontutil.h>
35
36#if !wxCHECK_VERSION(2,9,0)
37#include <wx/mac/private.h>
38#else
39#include <wx/osx/private.h>
40#endif
41
42#if !wxCHECK_VERSION(2,9,0) || !wxOSX_USE_COCOA
43
44static inline double DegToRad(double deg)
45{
46    return (deg * M_PI) / 180.0;
47}
48
49static const NSAffineTransformStruct kSlantNSTransformStruct = { 1, 0, tan(DegToRad(11)), 1, 0, 0  };
50
51NSFont* OSXCreateNSFont(const wxNativeFontInfo* info)
52{
53    NSFont* nsFont;
54    int weight = 5;
55    NSFontTraitMask traits = 0;
56    if (info->GetWeight() == wxFONTWEIGHT_BOLD)
57    {
58        traits |= NSBoldFontMask;
59        weight = 9;
60    }
61    else if (info->GetWeight() == wxFONTWEIGHT_LIGHT)
62        weight = 3;
63
64    if (info->GetStyle() == wxFONTSTYLE_ITALIC || info->GetStyle() == wxFONTSTYLE_SLANT)
65        traits |= NSItalicFontMask;
66
67    nsFont = [[NSFontManager sharedFontManager] fontWithFamily:(NSString*)(CFStringRef)wxMacCFStringHolder(info->GetFaceName())
68        traits:traits weight:weight size:info->GetPointSize()];
69
70    if ( nsFont == nil )
71    {
72        NSFontTraitMask remainingTraits = traits;
73        nsFont = [[NSFontManager sharedFontManager] fontWithFamily:(NSString*)(CFStringRef)wxMacCFStringHolder(info->GetFaceName())
74                                                            traits:0 weight:5 size:info->GetPointSize()];
75        if ( nsFont == nil )
76        {
77            if ( info->GetWeight() == wxFONTWEIGHT_BOLD )
78            {
79                nsFont = [NSFont boldSystemFontOfSize:info->GetPointSize()];
80                remainingTraits &= ~NSBoldFontMask;
81            }
82            else
83                nsFont = [NSFont systemFontOfSize:info->GetPointSize()];
84        }
85
86        // fallback - if in doubt, let go of the bold attribute
87        if ( nsFont && (remainingTraits & NSItalicFontMask) )
88        {
89            NSFont* nsFontWithTraits = nil;
90            if ( remainingTraits & NSBoldFontMask)
91            {
92                nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
93                if ( nsFontWithTraits == nil )
94                {
95                    nsFontWithTraits = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSItalicFontMask];
96                    if ( nsFontWithTraits != nil )
97                        remainingTraits &= ~NSItalicFontMask;
98                }
99                else
100                {
101                    remainingTraits &= ~NSBoldFontMask;
102                }
103            }
104            if ( remainingTraits & NSItalicFontMask)
105            {
106                if ( nsFontWithTraits == nil )
107                    nsFontWithTraits = nsFont;
108
109                NSAffineTransform* transform = [NSAffineTransform transform];
110                [transform setTransformStruct:kSlantNSTransformStruct];
111                [transform scaleBy:info->GetPointSize()];
112                NSFontDescriptor* italicDesc = [[nsFontWithTraits fontDescriptor] fontDescriptorWithMatrix:transform];
113                if ( italicDesc != nil )
114                {
115                    NSFont* f = [NSFont fontWithDescriptor:italicDesc size:(CGFloat)(info->GetPointSize())];
116                    if ( f != nil )
117                        nsFontWithTraits = f;
118                }
119            }
120            if ( nsFontWithTraits != nil )
121                nsFont = nsFontWithTraits;
122        }
123    }
124
125    wxASSERT_MSG(nsFont != nil,wxT("Couldn't create nsFont")) ;
126    wxMacCocoaRetain(nsFont);
127    return nsFont;
128}
129
130#endif
131
132namespace WebCore {
133
134void FontPlatformData::cacheNSFont()
135{
136    if (m_nsFont)
137        return;
138
139#if wxCHECK_VERSION(2,9,1) && wxOSX_USE_COCOA
140    if (m_font && m_font->font())
141        m_nsFont = (NSFont*)m_font->font()->OSXGetNSFont();
142#else
143    m_nsFont = OSXCreateNSFont(m_font->font()->GetNativeFontInfo());
144#endif
145}
146
147}
148