d44d88a769917144ee78b74fff3d18414bc2348c
[WebKit-https.git] / WebCore / platform / mac / FontMac.mm
1 /**
2  * This file is part of the html renderer for KDE.
3  *
4  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
5  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
6  *           (C) 2000 Dirk Mueller (mueller@kde.org)
7  * Copyright (C) 2003, 2006 Apple Computer, Inc.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  *
24  */
25
26 #import "config.h"
27 #import "Font.h"
28
29 #import "Logging.h"
30 #import "BlockExceptions.h"
31 #import "FoundationExtras.h"
32
33 #import "FontFallbackList.h"
34 #import "GraphicsContext.h"
35 #import "KWQKHTMLSettings.h"
36
37 #import "FontData.h"
38 #import "WebTextRendererFactory.h"
39
40 #import "IntRect.h"
41
42 using namespace std;
43
44 namespace WebCore {
45
46 FontFallbackList::FontFallbackList()
47 :m_pitch(UnknownPitch), m_font(nil)
48 {
49     m_platformFont.font = nil;
50 }
51
52 FontFallbackList::~FontFallbackList()
53 {
54     KWQRelease(m_platformFont.font);
55 }
56
57 const FontPlatformData& FontFallbackList::platformFont(const FontDescription& fontDescription) const
58 {
59     if (!m_platformFont.font) {
60         CREATE_FAMILY_ARRAY(fontDescription, families);
61         BEGIN_BLOCK_OBJC_EXCEPTIONS;
62         int traits = 0;
63         if (fontDescription.italic())
64             traits |= NSItalicFontMask;
65         if (fontDescription.weight() >= WebCore::cBoldWeight)
66             traits |= NSBoldFontMask;
67         m_platformFont = [[WebTextRendererFactory sharedFactory] 
68                                      fontWithFamilies:families traits:traits size:fontDescription.computedPixelSize()];
69         KWQRetain(m_platformFont.font);
70         m_platformFont.forPrinter = fontDescription.usePrinterFont();
71         END_BLOCK_OBJC_EXCEPTIONS;
72     }
73     return m_platformFont;
74 }
75
76 FontData* FontFallbackList::primaryFont(const FontDescription& fontDescription) const
77 {
78     if (!m_font)
79         m_font = [[WebTextRendererFactory sharedFactory] rendererWithFont:platformFont(fontDescription)];
80     return m_font;
81 }
82
83 void FontFallbackList::determinePitch(const FontDescription& fontDescription) const
84 {
85     BEGIN_BLOCK_OBJC_EXCEPTIONS;
86     if ([[WebTextRendererFactory sharedFactory] isFontFixedPitch:platformFont(fontDescription)])
87         m_pitch = FixedPitch;
88     else
89         m_pitch = VariablePitch;
90     END_BLOCK_OBJC_EXCEPTIONS;
91 }
92
93 void FontFallbackList::invalidate()
94 {
95     m_font = 0;
96     KWQRelease(m_platformFont.font);
97     m_platformFont.font = nil;
98     m_pitch = UnknownPitch;
99 }
100
101 const FontPlatformData& Font::platformFont() const
102 {
103     return m_fontList->platformFont(fontDescription());
104 }
105
106 IntRect Font::selectionRectForText(const IntPoint& point, int h, int tabWidth, int xpos, 
107     const UChar* str, int slen, int pos, int l, int toAdd,
108     bool rtl, bool visuallyOrdered, int from, int to) const
109 {
110     assert(m_fontList);
111     int len = min(slen - pos, l);
112
113     CREATE_FAMILY_ARRAY(fontDescription(), families);
114
115     if (from < 0)
116         from = 0;
117     if (to < 0)
118         to = len;
119
120     WebCoreTextRun run;
121     WebCoreInitializeTextRun(&run, str + pos, len, from, to);
122     WebCoreTextStyle style;
123     WebCoreInitializeEmptyTextStyle(&style);
124     style.rtl = rtl;
125     style.directionalOverride = visuallyOrdered;
126     style.letterSpacing = letterSpacing();
127     style.wordSpacing = wordSpacing();
128     style.smallCaps = fontDescription().smallCaps();
129     style.families = families;    
130     style.padding = toAdd;
131     style.tabWidth = tabWidth;
132     style.xpos = xpos;
133     WebCoreTextGeometry geometry;
134     WebCoreInitializeEmptyTextGeometry(&geometry);
135     geometry.point = point;
136     geometry.selectionY = point.y();
137     geometry.selectionHeight = h;
138     geometry.useFontMetricsForSelectionYAndHeight = false;
139     return enclosingIntRect(m_fontList->primaryFont(fontDescription())->selectionRectForRun(&run, &style, &geometry));
140 }
141                      
142 void Font::drawText(GraphicsContext* context, const IntPoint& point, int tabWidth, int xpos, const UChar* str, int len, int from, int to,
143                     int toAdd, TextDirection d, bool visuallyOrdered) const
144 {
145     // Avoid allocations, use stack array to pass font families.  Normally these
146     // css fallback lists are small <= 3.
147     CREATE_FAMILY_ARRAY(*this, families);
148
149     if (from < 0)
150         from = 0;
151     if (to < 0)
152         to = len;
153         
154     WebCoreTextRun run;
155     WebCoreInitializeTextRun(&run, str, len, from, to);    
156     WebCoreTextStyle style;
157     WebCoreInitializeEmptyTextStyle(&style);
158     style.textColor = nsColor(context->pen().color());
159     style.backgroundColor = nil;
160     style.rtl = d == RTL;
161     style.directionalOverride = visuallyOrdered;
162     style.letterSpacing = letterSpacing();
163     style.wordSpacing = wordSpacing();
164     style.smallCaps = isSmallCaps();
165     style.families = families;
166     style.padding = toAdd;
167     style.tabWidth = tabWidth;
168     style.xpos = xpos;
169     WebCoreTextGeometry geometry;
170     WebCoreInitializeEmptyTextGeometry(&geometry);
171     geometry.point = point;
172     m_fontList->primaryFont(fontDescription())->drawRun(&run, &style, &geometry);
173 }
174
175 void Font::drawHighlightForText(GraphicsContext* context, const IntPoint& point, int h, int tabWidth, int xpos, const UChar* str,
176                                 int len, int from, int to, int toAdd,
177                                 TextDirection d, bool visuallyOrdered, const Color& backgroundColor) const
178 {
179     // Avoid allocations, use stack array to pass font families.  Normally these
180     // css fallback lists are small <= 3.
181     CREATE_FAMILY_ARRAY(*this, families);
182
183     if (from < 0)
184         from = 0;
185     if (to < 0)
186         to = len;
187         
188     WebCoreTextRun run;
189     WebCoreInitializeTextRun(&run, str, len, from, to);    
190     WebCoreTextStyle style;
191     WebCoreInitializeEmptyTextStyle(&style);
192     style.textColor = nsColor(context->pen().color());
193     style.backgroundColor = backgroundColor.isValid() ? nsColor(backgroundColor) : nil;
194     style.rtl = d == RTL;
195     style.directionalOverride = visuallyOrdered;
196     style.letterSpacing = letterSpacing();
197     style.wordSpacing = wordSpacing();
198     style.smallCaps = isSmallCaps();
199     style.families = families;    
200     style.padding = toAdd;
201     style.tabWidth = tabWidth;
202     style.xpos = xpos;
203     WebCoreTextGeometry geometry;
204     WebCoreInitializeEmptyTextGeometry(&geometry);
205     geometry.point = point;
206     geometry.selectionY = point.y();
207     geometry.selectionHeight = h;
208     geometry.useFontMetricsForSelectionYAndHeight = false;
209     m_fontList->primaryFont(fontDescription())->drawHighlightForRun(&run, &style, &geometry);
210 }
211
212 void Font::drawLineForText(GraphicsContext* context, const IntPoint& point, int yOffset, int width) const
213 {
214     m_fontList->primaryFont(fontDescription())->drawLineForCharacters(point, yOffset, width, context->pen().color(), context->pen().width());
215 }
216
217 void Font::drawLineForMisspelling(GraphicsContext* context, const IntPoint& point, int width) const
218 {
219     m_fontList->primaryFont(fontDescription())->drawLineForMisspelling(point, width);
220 }
221
222 int Font::misspellingLineThickness(GraphicsContext* context) const
223 {
224     return m_fontList->primaryFont(fontDescription())->misspellingLineThickness();
225 }
226
227 float Font::floatWidth(const UChar* uchars, int slen, int pos, int len, int tabWidth, int xpos, bool runRounding) const
228 {
229     assert(m_fontList);
230     CREATE_FAMILY_ARRAY(fontDescription(), families);
231
232     WebCoreTextRun run;
233     WebCoreInitializeTextRun(&run, uchars, slen, pos, pos + len);
234     
235     WebCoreTextStyle style;
236     WebCoreInitializeEmptyTextStyle(&style);
237     style.tabWidth = tabWidth;
238     style.xpos = xpos;
239     style.letterSpacing = letterSpacing();
240     style.wordSpacing = wordSpacing();
241     style.smallCaps = fontDescription().smallCaps();
242     style.families = families;
243     style.applyRunRounding = runRounding;
244
245     return m_fontList->primaryFont(fontDescription())->floatWidthForRun(&run, &style);
246 }
247
248 int Font::checkSelectionPoint(const UChar* s, int slen, int pos, int len, int toAdd, int tabWidth, int xpos, int x, TextDirection d, bool visuallyOrdered, bool includePartialGlyphs) const
249 {
250     assert(m_fontList);
251     CREATE_FAMILY_ARRAY(fontDescription(), families);
252     
253     WebCoreTextRun run;
254     WebCoreInitializeTextRun(&run, s + pos, min(slen - pos, len), 0, len);
255     
256     WebCoreTextStyle style;
257     WebCoreInitializeEmptyTextStyle(&style);
258     style.letterSpacing = letterSpacing();
259     style.wordSpacing = wordSpacing();
260     style.smallCaps = fontDescription().smallCaps();
261     style.families = families;
262     style.padding = toAdd;
263     style.tabWidth = tabWidth;
264     style.xpos = xpos;
265     style.rtl =  d == RTL;
266     style.directionalOverride = visuallyOrdered;
267
268     return m_fontList->primaryFont(fontDescription())->pointToOffset(&run, &style, x, includePartialGlyphs);
269 }
270
271 }