~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/gfx/src/mac/nsFontMetricsMac.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
#include "nsCarbonHelpers.h"
 
40
 
 
41
#include "nsFontMetricsMac.h"
 
42
#include "nsDeviceContextMac.h"
 
43
#include "nsUnicodeFontMappingMac.h"
 
44
#include "nsUnicodeMappingUtil.h"
 
45
#include "nsGfxUtils.h"
 
46
#include "nsFontUtils.h"
 
47
 
 
48
#define BAD_FONT_NUM    -1
 
49
 
 
50
 
 
51
nsFontMetricsMac :: nsFontMetricsMac()
 
52
{
 
53
  mFont = nsnull;
 
54
  mFontNum = BAD_FONT_NUM;
 
55
  mFontMapping = nsnull;
 
56
}
 
57
  
 
58
nsFontMetricsMac :: ~nsFontMetricsMac()
 
59
{
 
60
  if (nsnull != mFont)
 
61
  {
 
62
    delete mFont;
 
63
    mFont = nsnull;
 
64
  }
 
65
  if (mContext) {
 
66
    // Notify our device context that owns us so that it can update its font cache
 
67
    mContext->FontMetricsDeleted(this);
 
68
    mContext = nsnull;
 
69
  }
 
70
  if (mFontMapping) {
 
71
    delete mFontMapping;
 
72
  }
 
73
}
 
74
 
 
75
//------------------------------------------------------------------------
 
76
 
 
77
NS_IMPL_ISUPPORTS1(nsFontMetricsMac, nsIFontMetrics)
 
78
 
 
79
 
 
80
NS_IMETHODIMP nsFontMetricsMac::Init(const nsFont& aFont, nsIAtom* aLangGroup, nsIDeviceContext* aCX)
 
81
{
 
82
  NS_ASSERTION(!(nsnull == aCX), "attempt to init fontmetrics with null device context");
 
83
 
 
84
  mFont = new nsFont(aFont);
 
85
  mLangGroup = aLangGroup;
 
86
  mContext = aCX;
 
87
  RealizeFont();
 
88
        
 
89
        TextStyle               theStyle;
 
90
        nsFontUtils::GetNativeTextStyle(*this, *mContext, theStyle);
 
91
        
 
92
  StTextStyleSetter styleSetter(theStyle);
 
93
  
 
94
  FontInfo fInfo;
 
95
  GetFontInfo(&fInfo);
 
96
  
 
97
  float  dev2app;
 
98
  dev2app = mContext->DevUnitsToAppUnits();
 
99
 
 
100
  mLeading    = NSToCoordRound(float(fInfo.leading) * dev2app);
 
101
  mEmAscent   = NSToCoordRound(float(fInfo.ascent) * dev2app);
 
102
  mEmDescent  = NSToCoordRound(float(fInfo.descent) * dev2app);
 
103
  mEmHeight   = mEmAscent + mEmDescent;
 
104
 
 
105
        mMaxHeight  = mEmHeight + mLeading;
 
106
  mMaxAscent  = mEmAscent;
 
107
  mMaxDescent = mEmDescent;
 
108
 
 
109
  mMaxAdvance = NSToCoordRound(float(::CharWidth('M')) * dev2app);      // don't use fInfo.widMax here
 
110
  mAveCharWidth = NSToCoordRound(float(::CharWidth('x')) * dev2app);    
 
111
  mSpaceWidth = NSToCoordRound(float(::CharWidth(' ')) * dev2app);
 
112
 
 
113
  Point frac;
 
114
  frac.h = frac.v = 1;
 
115
  unsigned char x = 'x';
 
116
  short ascent;
 
117
  if (noErr == ::OutlineMetrics(1, &x, frac, frac, &ascent, 0, 0, 0, 0))
 
118
    mXHeight = NSToCoordRound(float(ascent) * dev2app);
 
119
  else
 
120
    mXHeight = NSToCoordRound(float(mMaxAscent) * 0.71f); // 0.71 = 5 / 7
 
121
 
 
122
  return NS_OK;
 
123
}
 
124
 
 
125
nsUnicodeFontMappingMac* nsFontMetricsMac::GetUnicodeFontMapping()
 
126
{
 
127
  if (!mFontMapping)
 
128
  {
 
129
        // we should pass the documentCharset from the nsIDocument level and
 
130
        // the lang attribute from the tag level to here.
 
131
        // XXX hard code to some value till peterl pass them down.
 
132
        nsAutoString langGroup;
 
133
        if (mLangGroup)
 
134
                mLangGroup->ToString(langGroup);
 
135
    else
 
136
      langGroup.Assign(NS_LITERAL_STRING("ja"));
 
137
      
 
138
        nsString lang;
 
139
    mFontMapping = new nsUnicodeFontMappingMac(mFont, mContext, langGroup, lang);
 
140
  }
 
141
  
 
142
        return mFontMapping;
 
143
}
 
144
 
 
145
 
 
146
static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsString& aFontFace, ScriptCode aScriptCode)
 
147
{
 
148
  // the CSS generic names (conversions from the old Mac Mozilla code for now)
 
149
  nsUnicodeMappingUtil* unicodeMappingUtil = nsUnicodeMappingUtil::GetSingleton();
 
150
  if (unicodeMappingUtil)
 
151
  {
 
152
    nsString*   foundFont = unicodeMappingUtil->GenericFontNameForScript(
 
153
          aScriptCode,
 
154
          unicodeMappingUtil->MapGenericFontNameType(aGenericFamily));
 
155
    if (foundFont)
 
156
    {
 
157
      aFontFace = *foundFont;
 
158
      return;
 
159
    }
 
160
  }
 
161
  
 
162
  NS_ASSERTION(0, "Failed to find a font");
 
163
  aFontFace.Assign(NS_LITERAL_STRING("Times"));
 
164
        
 
165
  /*
 
166
  // fall back onto hard-coded font names
 
167
  if (aGenericFamily.EqualsIgnoreCase("serif"))
 
168
  {
 
169
    aFontFace.Assign(NS_LITERAL_STRING("Times"));
 
170
  }
 
171
  else if (aGenericFamily.EqualsIgnoreCase("sans-serif"))
 
172
  {
 
173
    aFontFace.Assign(NS_LITERAL_STRING("Helvetica"));
 
174
  }
 
175
  else if (aGenericFamily.EqualsIgnoreCase("cursive"))
 
176
  {
 
177
     aFontFace.Assign(NS_LITERAL_STRING("Apple Chancery"));
 
178
  }
 
179
  else if (aGenericFamily.EqualsIgnoreCase("fantasy"))
 
180
  {
 
181
    aFontFace.Assign(NS_LITERAL_STRING("Gadget"));
 
182
  }
 
183
  else if (aGenericFamily.EqualsIgnoreCase("monospace"))
 
184
  {
 
185
    aFontFace.Assign(NS_LITERAL_STRING("Courier"));
 
186
  }
 
187
  else if (aGenericFamily.EqualsIgnoreCase("-moz-fixed"))
 
188
  {
 
189
    aFontFace.Assign(NS_LITERAL_STRING("Courier"));
 
190
  }
 
191
  */
 
192
}
 
193
 
 
194
struct FontEnumData {
 
195
  FontEnumData(nsIDeviceContext* aDC, nsString& aFaceName, ScriptCode aScriptCode)
 
196
    : mContext(aDC), mFaceName(aFaceName), mScriptCode(aScriptCode)
 
197
  {}
 
198
  nsIDeviceContext* mContext;
 
199
  nsString&         mFaceName;
 
200
  ScriptCode            mScriptCode;
 
201
};
 
202
 
 
203
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
 
204
{
 
205
  FontEnumData* data = (FontEnumData*)aData;
 
206
  if (aGeneric)
 
207
  {
 
208
    nsAutoString realFace;
 
209
    MapGenericFamilyToFont(aFamily, realFace, data->mScriptCode);
 
210
    data->mFaceName = realFace;
 
211
    return PR_FALSE;  // stop
 
212
  }
 
213
  else
 
214
  {
 
215
    nsAutoString realFace;
 
216
    PRBool  aliased;
 
217
    data->mContext->GetLocalFontName(aFamily, realFace, aliased);
 
218
    if (aliased || (NS_OK == data->mContext->CheckFontExistence(realFace)))
 
219
    {
 
220
        data->mFaceName = realFace;
 
221
      return PR_FALSE;  // stop
 
222
    }
 
223
  }
 
224
  return PR_TRUE;
 
225
}
 
226
 
 
227
void nsFontMetricsMac::RealizeFont()
 
228
{
 
229
        nsAutoString    fontName;
 
230
        nsUnicodeMappingUtil    *unicodeMappingUtil;
 
231
        ScriptCode                              theScriptCode;
 
232
 
 
233
        unicodeMappingUtil = nsUnicodeMappingUtil::GetSingleton ();
 
234
        if (unicodeMappingUtil)
 
235
        {
 
236
                nsAutoString    theLangGroupString;
 
237
 
 
238
                if (mLangGroup)
 
239
                        mLangGroup->ToString(theLangGroupString);
 
240
                else
 
241
                        theLangGroupString.Assign(NS_LITERAL_STRING("ja"));
 
242
 
 
243
                theScriptCode = unicodeMappingUtil->MapLangGroupToScriptCode(
 
244
                    NS_ConvertUCS2toUTF8(theLangGroupString).get());
 
245
 
 
246
        }
 
247
        else
 
248
                theScriptCode = GetScriptManagerVariable (smSysScript);
 
249
 
 
250
        FontEnumData  fontData(mContext, fontName, theScriptCode);
 
251
        mFont->EnumerateFamilies(FontEnumCallback, &fontData);
 
252
  
 
253
        nsDeviceContextMac::GetMacFontNumber(fontName, mFontNum);
 
254
}
 
255
 
 
256
 
 
257
NS_IMETHODIMP
 
258
nsFontMetricsMac::Destroy()
 
259
{
 
260
  mContext = nsnull;
 
261
  return NS_OK;
 
262
}
 
263
 
 
264
//------------------------------------------------------------------------
 
265
 
 
266
NS_IMETHODIMP
 
267
nsFontMetricsMac :: GetXHeight(nscoord& aResult)
 
268
{
 
269
  aResult = mXHeight;
 
270
  return NS_OK;
 
271
}
 
272
 
 
273
NS_IMETHODIMP
 
274
nsFontMetricsMac :: GetSuperscriptOffset(nscoord& aResult)
 
275
{
 
276
  float  dev2app;
 
277
  dev2app = mContext->DevUnitsToAppUnits();
 
278
  aResult = NSToCoordRound(float(mMaxAscent / 2) - dev2app);
 
279
  return NS_OK;
 
280
}
 
281
 
 
282
NS_IMETHODIMP
 
283
nsFontMetricsMac :: GetSubscriptOffset(nscoord& aResult)
 
284
{
 
285
  float  dev2app;
 
286
  dev2app = mContext->DevUnitsToAppUnits();
 
287
  aResult = NSToCoordRound(float(mMaxAscent / 2) - dev2app);
 
288
  return NS_OK;
 
289
}
 
290
 
 
291
NS_IMETHODIMP
 
292
nsFontMetricsMac :: GetStrikeout(nscoord& aOffset, nscoord& aSize)
 
293
{
 
294
  float  dev2app;
 
295
  dev2app = mContext->DevUnitsToAppUnits();
 
296
  aOffset = NSToCoordRound(float(mMaxAscent / 2) - dev2app);
 
297
  aSize = NSToCoordRound(dev2app);
 
298
  return NS_OK;
 
299
}
 
300
 
 
301
NS_IMETHODIMP
 
302
nsFontMetricsMac :: GetUnderline(nscoord& aOffset, nscoord& aSize)
 
303
{
 
304
  float  dev2app;
 
305
  dev2app = mContext->DevUnitsToAppUnits();
 
306
  aOffset = -NSToCoordRound( dev2app );
 
307
  aSize   = NSToCoordRound( dev2app );
 
308
  return NS_OK;
 
309
}
 
310
 
 
311
NS_IMETHODIMP nsFontMetricsMac :: GetHeight(nscoord &aHeight)
 
312
{
 
313
  aHeight = mMaxHeight;
 
314
  return NS_OK;
 
315
}
 
316
 
 
317
NS_IMETHODIMP nsFontMetricsMac :: GetNormalLineHeight(nscoord &aHeight)
 
318
{
 
319
  aHeight = mMaxHeight; // on Windows, it's mEmHeight + mLeading (= mMaxHeight on the Mac)
 
320
  return NS_OK;
 
321
}
 
322
 
 
323
NS_IMETHODIMP nsFontMetricsMac :: GetLeading(nscoord &aLeading)
 
324
{
 
325
  aLeading = mLeading;
 
326
  return NS_OK;
 
327
}
 
328
 
 
329
NS_IMETHODIMP
 
330
nsFontMetricsMac :: GetEmHeight(nscoord &aHeight)
 
331
{
 
332
  aHeight = mEmHeight;
 
333
  return NS_OK;
 
334
}
 
335
 
 
336
NS_IMETHODIMP
 
337
nsFontMetricsMac :: GetEmAscent(nscoord &aAscent)
 
338
{
 
339
  aAscent = mEmAscent;
 
340
  return NS_OK;
 
341
}
 
342
 
 
343
NS_IMETHODIMP
 
344
nsFontMetricsMac :: GetEmDescent(nscoord &aDescent)
 
345
{
 
346
  aDescent = mEmDescent;
 
347
  return NS_OK;
 
348
}
 
349
 
 
350
NS_IMETHODIMP
 
351
nsFontMetricsMac :: GetMaxHeight(nscoord &aHeight)
 
352
{
 
353
  aHeight = mMaxHeight;
 
354
  return NS_OK;
 
355
}
 
356
 
 
357
NS_IMETHODIMP nsFontMetricsMac :: GetMaxAscent(nscoord &aAscent)
 
358
{
 
359
  aAscent = mMaxAscent;
 
360
  return NS_OK;
 
361
}
 
362
 
 
363
NS_IMETHODIMP nsFontMetricsMac :: GetMaxDescent(nscoord &aDescent)
 
364
{
 
365
  aDescent = mMaxDescent;
 
366
  return NS_OK;
 
367
}
 
368
 
 
369
NS_IMETHODIMP nsFontMetricsMac :: GetMaxAdvance(nscoord &aAdvance)
 
370
{
 
371
  aAdvance = mMaxAdvance;
 
372
  return NS_OK;
 
373
}
 
374
 
 
375
NS_IMETHODIMP nsFontMetricsMac :: GetAveCharWidth(nscoord &aAveCharWidth)
 
376
{
 
377
  aAveCharWidth = mAveCharWidth;
 
378
  return NS_OK;
 
379
}
 
380
 
 
381
nsresult nsFontMetricsMac :: GetSpaceWidth(nscoord &aSpaceWidth)
 
382
{
 
383
  aSpaceWidth = mSpaceWidth;
 
384
  return NS_OK;
 
385
}
 
386
 
 
387
NS_IMETHODIMP nsFontMetricsMac :: GetFont(const nsFont *&aFont)
 
388
{
 
389
  aFont = mFont;
 
390
  return NS_OK;
 
391
}
 
392
NS_IMETHODIMP nsFontMetricsMac::GetLangGroup(nsIAtom** aLangGroup)
 
393
{
 
394
  if (!aLangGroup) {
 
395
    return NS_ERROR_NULL_POINTER;
 
396
  }
 
397
 
 
398
  *aLangGroup = mLangGroup;
 
399
  NS_IF_ADDREF(*aLangGroup);
 
400
 
 
401
  return NS_OK;
 
402
}
 
403
 
 
404
 
 
405
NS_IMETHODIMP nsFontMetricsMac :: GetWidths(const nscoord *&aWidths)
 
406
{
 
407
  return NS_ERROR_NOT_IMPLEMENTED;      //XXX
 
408
}
 
409
 
 
410
NS_IMETHODIMP nsFontMetricsMac :: GetFontHandle(nsFontHandle &aHandle)
 
411
{
 
412
        // NOTE: the name in the mFont may be a comma-separated list of
 
413
        // font names, like "Verdana, Arial, sans-serif"
 
414
        // If you want to do the conversion again to a Mac font, you'll
 
415
        // have to EnumerateFamilies() to resolve it to an installed
 
416
        // font again.
 
417
        NS_PRECONDITION(mFontNum != BAD_FONT_NUM, "Font metrics have not been initialized");
 
418
        
 
419
        // We have no 'font handles' on Mac like they have on Windows
 
420
        // so let's use it for the fontNum.
 
421
        aHandle = (nsFontHandle)mFontNum;
 
422
        return NS_OK;
 
423
}
 
424