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
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/
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
15
* The Original Code is mozilla.org code.
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.
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.
37
* ***** END LICENSE BLOCK ***** */
39
#include "nsCarbonHelpers.h"
41
#include "nsFontMetricsMac.h"
42
#include "nsDeviceContextMac.h"
43
#include "nsUnicodeFontMappingMac.h"
44
#include "nsUnicodeMappingUtil.h"
45
#include "nsGfxUtils.h"
46
#include "nsFontUtils.h"
48
#define BAD_FONT_NUM -1
51
nsFontMetricsMac :: nsFontMetricsMac()
54
mFontNum = BAD_FONT_NUM;
55
mFontMapping = nsnull;
58
nsFontMetricsMac :: ~nsFontMetricsMac()
66
// Notify our device context that owns us so that it can update its font cache
67
mContext->FontMetricsDeleted(this);
75
//------------------------------------------------------------------------
77
NS_IMPL_ISUPPORTS1(nsFontMetricsMac, nsIFontMetrics)
80
NS_IMETHODIMP nsFontMetricsMac::Init(const nsFont& aFont, nsIAtom* aLangGroup, nsIDeviceContext* aCX)
82
NS_ASSERTION(!(nsnull == aCX), "attempt to init fontmetrics with null device context");
84
mFont = new nsFont(aFont);
85
mLangGroup = aLangGroup;
90
nsFontUtils::GetNativeTextStyle(*this, *mContext, theStyle);
92
StTextStyleSetter styleSetter(theStyle);
98
dev2app = mContext->DevUnitsToAppUnits();
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;
105
mMaxHeight = mEmHeight + mLeading;
106
mMaxAscent = mEmAscent;
107
mMaxDescent = mEmDescent;
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);
115
unsigned char x = 'x';
117
if (noErr == ::OutlineMetrics(1, &x, frac, frac, &ascent, 0, 0, 0, 0))
118
mXHeight = NSToCoordRound(float(ascent) * dev2app);
120
mXHeight = NSToCoordRound(float(mMaxAscent) * 0.71f); // 0.71 = 5 / 7
125
nsUnicodeFontMappingMac* nsFontMetricsMac::GetUnicodeFontMapping()
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;
134
mLangGroup->ToString(langGroup);
136
langGroup.Assign(NS_LITERAL_STRING("ja"));
139
mFontMapping = new nsUnicodeFontMappingMac(mFont, mContext, langGroup, lang);
146
static void MapGenericFamilyToFont(const nsString& aGenericFamily, nsString& aFontFace, ScriptCode aScriptCode)
148
// the CSS generic names (conversions from the old Mac Mozilla code for now)
149
nsUnicodeMappingUtil* unicodeMappingUtil = nsUnicodeMappingUtil::GetSingleton();
150
if (unicodeMappingUtil)
152
nsString* foundFont = unicodeMappingUtil->GenericFontNameForScript(
154
unicodeMappingUtil->MapGenericFontNameType(aGenericFamily));
157
aFontFace = *foundFont;
162
NS_ASSERTION(0, "Failed to find a font");
163
aFontFace.Assign(NS_LITERAL_STRING("Times"));
166
// fall back onto hard-coded font names
167
if (aGenericFamily.EqualsIgnoreCase("serif"))
169
aFontFace.Assign(NS_LITERAL_STRING("Times"));
171
else if (aGenericFamily.EqualsIgnoreCase("sans-serif"))
173
aFontFace.Assign(NS_LITERAL_STRING("Helvetica"));
175
else if (aGenericFamily.EqualsIgnoreCase("cursive"))
177
aFontFace.Assign(NS_LITERAL_STRING("Apple Chancery"));
179
else if (aGenericFamily.EqualsIgnoreCase("fantasy"))
181
aFontFace.Assign(NS_LITERAL_STRING("Gadget"));
183
else if (aGenericFamily.EqualsIgnoreCase("monospace"))
185
aFontFace.Assign(NS_LITERAL_STRING("Courier"));
187
else if (aGenericFamily.EqualsIgnoreCase("-moz-fixed"))
189
aFontFace.Assign(NS_LITERAL_STRING("Courier"));
194
struct FontEnumData {
195
FontEnumData(nsIDeviceContext* aDC, nsString& aFaceName, ScriptCode aScriptCode)
196
: mContext(aDC), mFaceName(aFaceName), mScriptCode(aScriptCode)
198
nsIDeviceContext* mContext;
200
ScriptCode mScriptCode;
203
static PRBool FontEnumCallback(const nsString& aFamily, PRBool aGeneric, void *aData)
205
FontEnumData* data = (FontEnumData*)aData;
208
nsAutoString realFace;
209
MapGenericFamilyToFont(aFamily, realFace, data->mScriptCode);
210
data->mFaceName = realFace;
211
return PR_FALSE; // stop
215
nsAutoString realFace;
217
data->mContext->GetLocalFontName(aFamily, realFace, aliased);
218
if (aliased || (NS_OK == data->mContext->CheckFontExistence(realFace)))
220
data->mFaceName = realFace;
221
return PR_FALSE; // stop
227
void nsFontMetricsMac::RealizeFont()
229
nsAutoString fontName;
230
nsUnicodeMappingUtil *unicodeMappingUtil;
231
ScriptCode theScriptCode;
233
unicodeMappingUtil = nsUnicodeMappingUtil::GetSingleton ();
234
if (unicodeMappingUtil)
236
nsAutoString theLangGroupString;
239
mLangGroup->ToString(theLangGroupString);
241
theLangGroupString.Assign(NS_LITERAL_STRING("ja"));
243
theScriptCode = unicodeMappingUtil->MapLangGroupToScriptCode(
244
NS_ConvertUCS2toUTF8(theLangGroupString).get());
248
theScriptCode = GetScriptManagerVariable (smSysScript);
250
FontEnumData fontData(mContext, fontName, theScriptCode);
251
mFont->EnumerateFamilies(FontEnumCallback, &fontData);
253
nsDeviceContextMac::GetMacFontNumber(fontName, mFontNum);
258
nsFontMetricsMac::Destroy()
264
//------------------------------------------------------------------------
267
nsFontMetricsMac :: GetXHeight(nscoord& aResult)
274
nsFontMetricsMac :: GetSuperscriptOffset(nscoord& aResult)
277
dev2app = mContext->DevUnitsToAppUnits();
278
aResult = NSToCoordRound(float(mMaxAscent / 2) - dev2app);
283
nsFontMetricsMac :: GetSubscriptOffset(nscoord& aResult)
286
dev2app = mContext->DevUnitsToAppUnits();
287
aResult = NSToCoordRound(float(mMaxAscent / 2) - dev2app);
292
nsFontMetricsMac :: GetStrikeout(nscoord& aOffset, nscoord& aSize)
295
dev2app = mContext->DevUnitsToAppUnits();
296
aOffset = NSToCoordRound(float(mMaxAscent / 2) - dev2app);
297
aSize = NSToCoordRound(dev2app);
302
nsFontMetricsMac :: GetUnderline(nscoord& aOffset, nscoord& aSize)
305
dev2app = mContext->DevUnitsToAppUnits();
306
aOffset = -NSToCoordRound( dev2app );
307
aSize = NSToCoordRound( dev2app );
311
NS_IMETHODIMP nsFontMetricsMac :: GetHeight(nscoord &aHeight)
313
aHeight = mMaxHeight;
317
NS_IMETHODIMP nsFontMetricsMac :: GetNormalLineHeight(nscoord &aHeight)
319
aHeight = mMaxHeight; // on Windows, it's mEmHeight + mLeading (= mMaxHeight on the Mac)
323
NS_IMETHODIMP nsFontMetricsMac :: GetLeading(nscoord &aLeading)
330
nsFontMetricsMac :: GetEmHeight(nscoord &aHeight)
337
nsFontMetricsMac :: GetEmAscent(nscoord &aAscent)
344
nsFontMetricsMac :: GetEmDescent(nscoord &aDescent)
346
aDescent = mEmDescent;
351
nsFontMetricsMac :: GetMaxHeight(nscoord &aHeight)
353
aHeight = mMaxHeight;
357
NS_IMETHODIMP nsFontMetricsMac :: GetMaxAscent(nscoord &aAscent)
359
aAscent = mMaxAscent;
363
NS_IMETHODIMP nsFontMetricsMac :: GetMaxDescent(nscoord &aDescent)
365
aDescent = mMaxDescent;
369
NS_IMETHODIMP nsFontMetricsMac :: GetMaxAdvance(nscoord &aAdvance)
371
aAdvance = mMaxAdvance;
375
NS_IMETHODIMP nsFontMetricsMac :: GetAveCharWidth(nscoord &aAveCharWidth)
377
aAveCharWidth = mAveCharWidth;
381
nsresult nsFontMetricsMac :: GetSpaceWidth(nscoord &aSpaceWidth)
383
aSpaceWidth = mSpaceWidth;
387
NS_IMETHODIMP nsFontMetricsMac :: GetFont(const nsFont *&aFont)
392
NS_IMETHODIMP nsFontMetricsMac::GetLangGroup(nsIAtom** aLangGroup)
395
return NS_ERROR_NULL_POINTER;
398
*aLangGroup = mLangGroup;
399
NS_IF_ADDREF(*aLangGroup);
405
NS_IMETHODIMP nsFontMetricsMac :: GetWidths(const nscoord *&aWidths)
407
return NS_ERROR_NOT_IMPLEMENTED; //XXX
410
NS_IMETHODIMP nsFontMetricsMac :: GetFontHandle(nsFontHandle &aHandle)
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
417
NS_PRECONDITION(mFontNum != BAD_FONT_NUM, "Font metrics have not been initialized");
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;