1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "gfxMacFont.h"
8 #include "mozilla/MemoryReporting.h"
9 #include "mozilla/Sprintf.h"
10 #include "mozilla/StaticPrefs_gfx.h"
12 #include "gfxCoreTextShaper.h"
14 #include "gfxPlatformMac.h"
15 #include "gfxContext.h"
16 #include "gfxFontUtils.h"
17 #include "gfxMacPlatformFontList.h"
18 #include "gfxFontConstants.h"
19 #include "gfxTextRun.h"
20 #include "nsCocoaFeatures.h"
21 #include "cairo-quartz.h"
23 using namespace mozilla
;
24 using namespace mozilla::gfx
;
28 bool Equals(const T
& aIter
, uint32_t aTag
) const {
29 return aIter
.mTag
== aTag
;
33 gfxMacFont::gfxMacFont(const RefPtr
<UnscaledFontMac
>& aUnscaledFont
,
34 MacOSFontEntry
* aFontEntry
,
35 const gfxFontStyle
* aFontStyle
)
36 : gfxFont(aUnscaledFont
, aFontEntry
, aFontStyle
),
40 mFontSmoothingBackgroundColor(aFontStyle
->fontSmoothingBackgroundColor
),
41 mVariationFont(aFontEntry
->HasVariations()) {
42 mApplySyntheticBold
= aFontStyle
->NeedsSyntheticBold(aFontEntry
);
45 CGFontRef baseFont
= aUnscaledFont
->GetFont();
51 // Get the variation settings needed to instantiate the fontEntry
52 // for a particular fontStyle.
53 AutoTArray
<gfxFontVariation
, 4> vars
;
54 aFontEntry
->GetVariationsForStyle(vars
, *aFontStyle
);
56 // Because of a Core Text bug, we need to ensure that if the font has
57 // an 'opsz' axis, it is always explicitly set, and NOT to the font's
58 // default value. (See bug 1457417, bug 1478720.)
59 // We record the result of searching the font's axes in the font entry,
60 // so that this only has to be done by the first instance created for
61 // a given font resource.
62 const uint32_t kOpszTag
= HB_TAG('o', 'p', 's', 'z');
63 const float kOpszFudgeAmount
= 0.01f
;
65 if (!aFontEntry
->mCheckedForOpszAxis
) {
66 aFontEntry
->mCheckedForOpszAxis
= true;
67 AutoTArray
<gfxFontVariationAxis
, 4> axes
;
68 aFontEntry
->GetVariationAxes(axes
);
69 auto index
= axes
.IndexOf(kOpszTag
, 0, TagEquals
<gfxFontVariationAxis
>());
70 if (index
== axes
.NoIndex
) {
71 aFontEntry
->mHasOpszAxis
= false;
73 const auto& axis
= axes
[index
];
74 aFontEntry
->mHasOpszAxis
= true;
75 aFontEntry
->mOpszAxis
= axis
;
76 // Pick a slightly-adjusted version of the default that we'll
77 // use to work around Core Text's habit of ignoring any attempt
78 // to explicitly set the default value.
79 aFontEntry
->mAdjustedDefaultOpsz
=
80 axis
.mDefaultValue
== axis
.mMinValue
81 ? axis
.mDefaultValue
+ kOpszFudgeAmount
82 : axis
.mDefaultValue
- kOpszFudgeAmount
;
86 // Add 'opsz' if not present, or tweak its value if it looks too close
87 // to the default (after clamping to the font's available range).
88 if (aFontEntry
->mHasOpszAxis
) {
89 auto index
= vars
.IndexOf(kOpszTag
, 0, TagEquals
<gfxFontVariation
>());
90 if (index
== vars
.NoIndex
) {
91 gfxFontVariation opsz
{kOpszTag
, aFontEntry
->mAdjustedDefaultOpsz
};
92 vars
.AppendElement(opsz
);
94 // Figure out a "safe" value that Core Text won't ignore.
95 auto& value
= vars
[index
].mValue
;
96 auto& axis
= aFontEntry
->mOpszAxis
;
97 value
= fmin(fmax(value
, axis
.mMinValue
), axis
.mMaxValue
);
98 if (std::abs(value
- axis
.mDefaultValue
) < kOpszFudgeAmount
) {
99 value
= aFontEntry
->mAdjustedDefaultOpsz
;
104 mCGFont
= UnscaledFontMac::CreateCGFontWithVariations(
105 baseFont
, vars
.Length(), vars
.Elements());
107 ::CFRetain(baseFont
);
111 mCGFont
= aUnscaledFont
->GetFont();
119 // InitMetrics will handle the sizeAdjust factor and set mAdjustedSize
125 mFontFace
= cairo_quartz_font_face_create_for_cgfont(mCGFont
);
127 cairo_status_t cairoerr
= cairo_font_face_status(mFontFace
);
128 if (cairoerr
!= CAIRO_STATUS_SUCCESS
) {
132 SprintfLiteral(warnBuf
, "Failed to create Cairo font face: %s status: %d",
133 GetName().get(), cairoerr
);
139 cairo_matrix_t sizeMatrix
, ctm
;
140 cairo_matrix_init_identity(&ctm
);
141 cairo_matrix_init_scale(&sizeMatrix
, mAdjustedSize
, mAdjustedSize
);
143 cairo_font_options_t
* fontOptions
= cairo_font_options_create();
145 // turn off font anti-aliasing based on user pref setting
146 if ((mAdjustedSize
<=
147 (gfxFloat
)gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) ||
148 // Turn off AA for Ahem for testing purposes when requested.
149 MOZ_UNLIKELY(StaticPrefs::gfx_font_ahem_antialias_none() &&
150 mFontEntry
->FamilyName().EqualsLiteral("Ahem"))) {
151 cairo_font_options_set_antialias(fontOptions
, CAIRO_ANTIALIAS_NONE
);
152 mAntialiasOption
= kAntialiasNone
;
153 } else if (mStyle
.useGrayscaleAntialiasing
) {
154 cairo_font_options_set_antialias(fontOptions
, CAIRO_ANTIALIAS_GRAY
);
155 mAntialiasOption
= kAntialiasGrayscale
;
159 cairo_scaled_font_create(mFontFace
, &sizeMatrix
, &ctm
, fontOptions
);
160 cairo_font_options_destroy(fontOptions
);
162 cairoerr
= cairo_scaled_font_status(mScaledFont
);
163 if (cairoerr
!= CAIRO_STATUS_SUCCESS
) {
167 SprintfLiteral(warnBuf
, "Failed to create scaled font: %s status: %d",
168 GetName().get(), cairoerr
);
174 gfxMacFont::~gfxMacFont() {
176 ::CFRelease(mCGFont
);
179 ::CFRelease(mCTFont
);
182 cairo_scaled_font_destroy(mScaledFont
);
185 cairo_font_face_destroy(mFontFace
);
189 bool gfxMacFont::ShapeText(DrawTarget
* aDrawTarget
, const char16_t
* aText
,
190 uint32_t aOffset
, uint32_t aLength
, Script aScript
,
191 bool aVertical
, RoundingFlags aRounding
,
192 gfxShapedText
* aShapedText
) {
194 NS_WARNING("invalid font! expect incorrect text rendering");
198 // Currently, we don't support vertical shaping via CoreText,
199 // so we ignore RequiresAATLayout if vertical is requested.
200 auto macFontEntry
= static_cast<MacOSFontEntry
*>(GetFontEntry());
201 if (macFontEntry
->RequiresAATLayout() && !aVertical
&&
202 StaticPrefs::gfx_font_rendering_coretext_enabled()) {
203 if (!mCoreTextShaper
) {
204 mCoreTextShaper
= MakeUnique
<gfxCoreTextShaper
>(this);
206 if (mCoreTextShaper
->ShapeText(aDrawTarget
, aText
, aOffset
, aLength
,
207 aScript
, aVertical
, aRounding
,
209 PostShapingFixup(aDrawTarget
, aText
, aOffset
, aLength
, aVertical
,
211 if (GetFontEntry()->HasTrackingTable()) {
212 // Convert font size from device pixels back to CSS px
213 // to use in selecting tracking value
214 float trackSize
= GetAdjustedSize() *
215 aShapedText
->GetAppUnitsPerDevUnit() /
216 AppUnitsPerCSSPixel();
218 GetFontEntry()->TrackingForCSSPx(trackSize
) * mFUnitsConvFactor
;
219 // Applying tracking is a lot like the adjustment we do for
220 // synthetic bold: we want to apply between clusters, not to
221 // non-spacing glyphs within a cluster. So we can reuse that
223 aShapedText
->AdjustAdvancesForSyntheticBold(tracking
, aOffset
, aLength
);
229 return gfxFont::ShapeText(aDrawTarget
, aText
, aOffset
, aLength
, aScript
,
230 aVertical
, aRounding
, aShapedText
);
233 bool gfxMacFont::SetupCairoFont(DrawTarget
* aDrawTarget
) {
234 if (cairo_scaled_font_status(mScaledFont
) != CAIRO_STATUS_SUCCESS
) {
235 // Don't cairo_set_scaled_font as that would propagate the error to
236 // the cairo_t, precluding any further drawing.
239 cairo_set_scaled_font(gfxFont::RefCairo(aDrawTarget
), mScaledFont
);
243 gfxFont::RunMetrics
gfxMacFont::Measure(const gfxTextRun
* aTextRun
,
244 uint32_t aStart
, uint32_t aEnd
,
245 BoundingBoxType aBoundingBoxType
,
246 DrawTarget
* aRefDrawTarget
,
248 gfx::ShapedTextFlags aOrientation
) {
249 gfxFont::RunMetrics metrics
=
250 gfxFont::Measure(aTextRun
, aStart
, aEnd
, aBoundingBoxType
, aRefDrawTarget
,
251 aSpacing
, aOrientation
);
253 // if aBoundingBoxType is not TIGHT_HINTED_OUTLINE_EXTENTS then we need to add
254 // a pixel column each side of the bounding box in case of antialiasing
256 if (aBoundingBoxType
!= TIGHT_HINTED_OUTLINE_EXTENTS
&&
257 metrics
.mBoundingBox
.width
> 0) {
258 metrics
.mBoundingBox
.x
-= aTextRun
->GetAppUnitsPerDevUnit();
259 metrics
.mBoundingBox
.width
+= aTextRun
->GetAppUnitsPerDevUnit() * 2;
265 void gfxMacFont::InitMetrics() {
267 ::memset(&mMetrics
, 0, sizeof(mMetrics
));
271 // try to get unitsPerEm from sfnt head table, to avoid calling CGFont
272 // if possible (bug 574368) and because CGFontGetUnitsPerEm does not
273 // return the true value for OpenType/CFF fonts (it normalizes to 1000,
274 // which then leads to metrics errors when we read the 'hmtx' table to
275 // get glyph advances for HarfBuzz, see bug 580863)
277 ::CGFontCopyTableForTag(mCGFont
, TRUETYPE_TAG('h', 'e', 'a', 'd'));
279 if (size_t(::CFDataGetLength(headData
)) >= sizeof(HeadTable
)) {
280 const HeadTable
* head
=
281 reinterpret_cast<const HeadTable
*>(::CFDataGetBytePtr(headData
));
282 upem
= head
->unitsPerEm
;
284 ::CFRelease(headData
);
287 upem
= ::CGFontGetUnitsPerEm(mCGFont
);
290 if (upem
< 16 || upem
> 16384) {
291 // See http://www.microsoft.com/typography/otspec/head.htm
294 SprintfLiteral(warnBuf
,
295 "Bad font metrics for: %s (invalid unitsPerEm value)",
296 mFontEntry
->Name().get());
302 mAdjustedSize
= std::max(mStyle
.size
, 1.0);
303 mFUnitsConvFactor
= mAdjustedSize
/ upem
;
305 // For CFF fonts, when scaling values read from CGFont* APIs, we need to
306 // use CG's idea of unitsPerEm, which may differ from the "true" value in
307 // the head table of the font (see bug 580863)
308 gfxFloat cgConvFactor
;
309 if (static_cast<MacOSFontEntry
*>(mFontEntry
.get())->IsCFF()) {
310 cgConvFactor
= mAdjustedSize
/ ::CGFontGetUnitsPerEm(mCGFont
);
312 cgConvFactor
= mFUnitsConvFactor
;
315 // Try to read 'sfnt' metrics; for local, non-sfnt fonts ONLY, fall back to
316 // platform APIs. The InitMetrics...() functions will set mIsValid on success.
317 if (!InitMetricsFromSfntTables(mMetrics
) &&
318 (!mFontEntry
->IsUserFont() || mFontEntry
->IsLocalUserFont())) {
319 InitMetricsFromPlatform();
325 if (mMetrics
.xHeight
== 0.0) {
326 mMetrics
.xHeight
= ::CGFontGetXHeight(mCGFont
) * cgConvFactor
;
329 if (mMetrics
.capHeight
== 0.0) {
330 mMetrics
.capHeight
= ::CGFontGetCapHeight(mCGFont
) * cgConvFactor
;
333 if (mStyle
.sizeAdjust
> 0.0 && mStyle
.size
> 0.0 && mMetrics
.xHeight
> 0.0) {
334 // apply font-size-adjust, and recalculate metrics
335 gfxFloat aspect
= mMetrics
.xHeight
/ mStyle
.size
;
336 mAdjustedSize
= mStyle
.GetAdjustedSize(aspect
);
337 mFUnitsConvFactor
= mAdjustedSize
/ upem
;
338 if (static_cast<MacOSFontEntry
*>(mFontEntry
.get())->IsCFF()) {
339 cgConvFactor
= mAdjustedSize
/ ::CGFontGetUnitsPerEm(mCGFont
);
341 cgConvFactor
= mFUnitsConvFactor
;
343 mMetrics
.xHeight
= 0.0;
344 if (!InitMetricsFromSfntTables(mMetrics
) &&
345 (!mFontEntry
->IsUserFont() || mFontEntry
->IsLocalUserFont())) {
346 InitMetricsFromPlatform();
349 // this shouldn't happen, as we succeeded earlier before applying
350 // the size-adjust factor! But check anyway, for paranoia's sake.
353 if (mMetrics
.xHeight
== 0.0) {
354 mMetrics
.xHeight
= ::CGFontGetXHeight(mCGFont
) * cgConvFactor
;
358 // Once we reach here, we've got basic metrics and set mIsValid = TRUE;
359 // there should be no further points of actual failure in InitMetrics().
360 // (If one is introduced, be sure to reset mIsValid to FALSE!)
362 mMetrics
.emHeight
= mAdjustedSize
;
364 // Measure/calculate additional metrics, independent of whether we used
365 // the tables directly or ATS metrics APIs
368 ::CGFontCopyTableForTag(mCGFont
, TRUETYPE_TAG('c', 'm', 'a', 'p'));
371 if (mMetrics
.aveCharWidth
<= 0) {
372 mMetrics
.aveCharWidth
= GetCharWidth(cmap
, 'x', &glyphID
, cgConvFactor
);
374 // we didn't find 'x', so use maxAdvance rather than zero
375 mMetrics
.aveCharWidth
= mMetrics
.maxAdvance
;
378 if (IsSyntheticBold()) {
379 mMetrics
.aveCharWidth
+= GetSyntheticBoldOffset();
380 mMetrics
.maxAdvance
+= GetSyntheticBoldOffset();
383 mMetrics
.spaceWidth
= GetCharWidth(cmap
, ' ', &glyphID
, cgConvFactor
);
386 mMetrics
.spaceWidth
= mMetrics
.aveCharWidth
;
388 mSpaceGlyph
= glyphID
;
390 mMetrics
.zeroWidth
= GetCharWidth(cmap
, '0', &glyphID
, cgConvFactor
);
392 mMetrics
.zeroWidth
= -1.0; // indicates not found
399 CalculateDerivedMetrics(mMetrics
);
401 SanitizeMetrics(&mMetrics
, mFontEntry
->mIsBadUnderlineFont
);
404 fprintf (stderr
, "Font: %p (%s) size: %f\n", this,
405 NS_ConvertUTF16toUTF8(GetName()).get(), mStyle
.size
);
406 // fprintf (stderr, " fbounds.origin.x %f y %f size.width %f height %f\n", fbounds.origin.x, fbounds.origin.y, fbounds.size.width, fbounds.size.height);
407 fprintf (stderr
, " emHeight: %f emAscent: %f emDescent: %f\n", mMetrics
.emHeight
, mMetrics
.emAscent
, mMetrics
.emDescent
);
408 fprintf (stderr
, " maxAscent: %f maxDescent: %f maxAdvance: %f\n", mMetrics
.maxAscent
, mMetrics
.maxDescent
, mMetrics
.maxAdvance
);
409 fprintf (stderr
, " internalLeading: %f externalLeading: %f\n", mMetrics
.internalLeading
, mMetrics
.externalLeading
);
410 fprintf (stderr
, " spaceWidth: %f aveCharWidth: %f xHeight: %f capHeight: %f\n", mMetrics
.spaceWidth
, mMetrics
.aveCharWidth
, mMetrics
.xHeight
, mMetrics
.capHeight
);
411 fprintf (stderr
, " uOff: %f uSize: %f stOff: %f stSize: %f\n", mMetrics
.underlineOffset
, mMetrics
.underlineSize
, mMetrics
.strikeoutOffset
, mMetrics
.strikeoutSize
);
415 gfxFloat
gfxMacFont::GetCharWidth(CFDataRef aCmap
, char16_t aUniChar
,
416 uint32_t* aGlyphID
, gfxFloat aConvFactor
) {
420 glyph
= gfxFontUtils::MapCharToGlyph(::CFDataGetBytePtr(aCmap
),
421 ::CFDataGetLength(aCmap
), aUniChar
);
430 if (::CGFontGetGlyphAdvances(mCGFont
, &glyph
, 1, &advance
)) {
431 return advance
* aConvFactor
;
439 CTFontRef
gfxMacFont::CreateCTFontFromCGFontWithVariations(
440 CGFontRef aCGFont
, CGFloat aSize
, bool aInstalledFont
,
441 CTFontDescriptorRef aFontDesc
) {
442 // Avoid calling potentially buggy variation APIs on pre-Sierra macOS
443 // versions (see bug 1331683).
445 // And on HighSierra, CTFontCreateWithGraphicsFont properly carries over
446 // variation settings from the CGFont to CTFont, so we don't need to do
447 // the extra work here -- and this seems to avoid Core Text crashiness
448 // seen in bug 1454094.
450 // However, for installed fonts it seems we DO need to copy the variations
451 // explicitly even on 10.13, otherwise fonts fail to render (as in bug
452 // 1455494) when non-default values are used. Fortunately, the crash
453 // mentioned above occurs with data fonts, not (AFAICT) with system-
456 // So we only need to do this "the hard way" on Sierra, and on HighSierra
457 // for system-installed fonts; in other cases just let the standard CTFont
458 // function do its thing.
460 // NOTE in case this ever needs further adjustment: there is similar logic
461 // in four places in the tree (sadly):
462 // CreateCTFontFromCGFontWithVariations in gfxMacFont.cpp
463 // CreateCTFontFromCGFontWithVariations in ScaledFontMac.cpp
464 // CreateCTFontFromCGFontWithVariations in cairo-quartz-font.c
465 // ctfont_create_exact_copy in SkFontHost_mac.cpp
468 if (nsCocoaFeatures::OnSierraExactly() ||
469 (aInstalledFont
&& nsCocoaFeatures::OnHighSierraOrLater())) {
470 CFDictionaryRef variations
= ::CGFontCopyVariations(aCGFont
);
472 CFDictionaryRef varAttr
= ::CFDictionaryCreate(
473 nullptr, (const void**)&kCTFontVariationAttribute
,
474 (const void**)&variations
, 1, &kCFTypeDictionaryKeyCallBacks
,
475 &kCFTypeDictionaryValueCallBacks
);
476 ::CFRelease(variations
);
478 CTFontDescriptorRef varDesc
=
480 ? ::CTFontDescriptorCreateCopyWithAttributes(aFontDesc
, varAttr
)
481 : ::CTFontDescriptorCreateWithAttributes(varAttr
);
482 ::CFRelease(varAttr
);
484 ctFont
= ::CTFontCreateWithGraphicsFont(aCGFont
, aSize
, nullptr, varDesc
);
485 ::CFRelease(varDesc
);
488 ::CTFontCreateWithGraphicsFont(aCGFont
, aSize
, nullptr, aFontDesc
);
491 ctFont
= ::CTFontCreateWithGraphicsFont(aCGFont
, aSize
, nullptr, aFontDesc
);
497 int32_t gfxMacFont::GetGlyphWidth(uint16_t aGID
) {
498 if (mVariationFont
) {
499 // Avoid a potential Core Text crash (bug 1450209) by using
500 // CoreGraphics glyph advance API. This is inferior for 'sbix'
501 // fonts, but those won't have variations, so it's OK.
503 if (::CGFontGetGlyphAdvances(mCGFont
, &aGID
, 1, &cgAdvance
)) {
504 return cgAdvance
* mFUnitsConvFactor
* 0x10000;
509 bool isInstalledFont
=
510 !mFontEntry
->IsUserFont() || mFontEntry
->IsLocalUserFont();
511 mCTFont
= CreateCTFontFromCGFontWithVariations(mCGFont
, mAdjustedSize
,
513 if (!mCTFont
) { // shouldn't happen, but let's be safe
514 NS_WARNING("failed to create CTFontRef to measure glyph width");
520 ::CTFontGetAdvancesForGlyphs(mCTFont
, kCTFontDefaultOrientation
, &aGID
,
522 return advance
.width
* 0x10000;
525 // Try to initialize font metrics via platform APIs (CG/CT),
526 // and set mIsValid = TRUE on success.
527 // We ONLY call this for local (platform) fonts that are not sfnt format;
528 // for sfnts, including ALL downloadable fonts, we prefer to use
529 // InitMetricsFromSfntTables and avoid platform APIs.
530 void gfxMacFont::InitMetricsFromPlatform() {
532 ::CTFontCreateWithGraphicsFont(mCGFont
, mAdjustedSize
, nullptr, nullptr);
537 mMetrics
.underlineOffset
= ::CTFontGetUnderlinePosition(ctFont
);
538 mMetrics
.underlineSize
= ::CTFontGetUnderlineThickness(ctFont
);
540 mMetrics
.externalLeading
= ::CTFontGetLeading(ctFont
);
542 mMetrics
.maxAscent
= ::CTFontGetAscent(ctFont
);
543 mMetrics
.maxDescent
= ::CTFontGetDescent(ctFont
);
545 // this is not strictly correct, but neither CTFont nor CGFont seems to
546 // provide maxAdvance, unless we were to iterate over all the glyphs
547 // (which isn't worth the cost here)
548 CGRect r
= ::CTFontGetBoundingBox(ctFont
);
549 mMetrics
.maxAdvance
= r
.size
.width
;
551 // aveCharWidth is also not provided, so leave it at zero
552 // (fallback code in gfxMacFont::InitMetrics will then try measuring 'x');
553 // this could lead to less-than-"perfect" text field sizing when width is
554 // specified as a number of characters, and the font in use is a non-sfnt
555 // legacy font, but that's a sufficiently obscure edge case that we can
556 // ignore the potential discrepancy.
557 mMetrics
.aveCharWidth
= 0;
559 mMetrics
.xHeight
= ::CTFontGetXHeight(ctFont
);
560 mMetrics
.capHeight
= ::CTFontGetCapHeight(ctFont
);
567 already_AddRefed
<ScaledFont
> gfxMacFont::GetScaledFont(DrawTarget
* aTarget
) {
568 if (!mAzureScaledFont
) {
569 mAzureScaledFont
= Factory::CreateScaledFontForMacFont(
570 GetCGFontRef(), GetUnscaledFont(), GetAdjustedSize(),
571 Color::FromABGR(mFontSmoothingBackgroundColor
),
572 !mStyle
.useGrayscaleAntialiasing
, IsSyntheticBold());
573 if (!mAzureScaledFont
) {
576 InitializeScaledFont();
577 mAzureScaledFont
->SetCairoScaledFont(mScaledFont
);
580 RefPtr
<ScaledFont
> scaledFont(mAzureScaledFont
);
581 return scaledFont
.forget();
584 void gfxMacFont::AddSizeOfExcludingThis(MallocSizeOf aMallocSizeOf
,
585 FontCacheSizes
* aSizes
) const {
586 gfxFont::AddSizeOfExcludingThis(aMallocSizeOf
, aSizes
);
587 // mCGFont is shared with the font entry, so not counted here;
588 // and we don't have APIs to measure the cairo mFontFace object
591 void gfxMacFont::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf
,
592 FontCacheSizes
* aSizes
) const {
593 aSizes
->mFontInstances
+= aMallocSizeOf(this);
594 AddSizeOfExcludingThis(aMallocSizeOf
, aSizes
);