/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef NSFONTMETRICS__H__ #define NSFONTMETRICS__H__ #include <stdint.h> // for uint32_t #include <sys/types.h> // for int32_t #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2 #include "mozilla/RefPtr.h" // for RefPtr #include "nsCOMPtr.h" // for nsCOMPtr #include "nsCoord.h" // for nscoord #include "nsError.h" // for nsresult #include "nsFont.h" // for nsFont #include "nsISupports.h" // for NS_INLINE_DECL_REFCOUNTING #include "nsStyleConsts.h" #include "nscore.h" // for char16_t class gfxContext; class gfxFontGroup; class gfxUserFontSet; class gfxTextPerfMetrics; class nsDeviceContext; class nsAtom; struct nsBoundingMetrics; struct FontMatchingStats; namespace mozilla { namespace gfx { class DrawTarget; } // namespace gfx } // namespace mozilla /** * Font metrics * * This class may be somewhat misnamed. A better name might be * nsFontList. The style system uses the nsFont struct for various * font properties, one of which is font-family, which can contain a * *list* of font names. The nsFont struct is "realized" by asking the * device context to cough up an nsFontMetrics object, which contains * a list of real font handles, one for each font mentioned in * font-family (and for each fallback when we fall off the end of that * list). * * The style system needs to have access to certain metrics, such as * the em height (for the CSS "em" unit), and we use the first Western * font's metrics for that purpose. The platform-specific * implementations are expected to select non-Western fonts that "fit" * reasonably well with the Western font that is loaded at Init time. */ class nsFontMetrics final { public: typedef mozilla::gfx::DrawTarget DrawTarget; enum FontOrientation { eHorizontal, eVertical }; struct MOZ_STACK_CLASS Params { nsAtom* language = nullptr; bool explicitLanguage = false; FontOrientation orientation = eHorizontal; gfxUserFontSet* userFontSet = nullptr; gfxTextPerfMetrics* textPerf = nullptr; FontMatchingStats* fontStats = nullptr; gfxFontFeatureValueSet* featureValueLookup = nullptr; }; nsFontMetrics(const nsFont& aFont, const Params& aParams, nsDeviceContext* aContext); // Used by stylo NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsFontMetrics) /** * Destroy this font metrics. This breaks the association between * the font metrics and the device context. */ void Destroy(); /** * Return the font's x-height. */ nscoord XHeight(); /** * Return the font's cap-height. */ nscoord CapHeight(); /** * Return the font's superscript offset (the distance from the * baseline to where a superscript's baseline should be placed). * The value returned will be positive. */ nscoord SuperscriptOffset(); /** * Return the font's subscript offset (the distance from the * baseline to where a subscript's baseline should be placed). * The value returned will be positive. */ nscoord SubscriptOffset(); /** * Return the font's strikeout offset (the distance from the * baseline to where a strikeout should be placed) and size. * Positive values are above the baseline, negative below. */ void GetStrikeout(nscoord& aOffset, nscoord& aSize); /** * Return the font's underline offset (the distance from the * baseline to where a underline should be placed) and size. * Positive values are above the baseline, negative below. */ void GetUnderline(nscoord& aOffset, nscoord& aSize); /** * Returns the amount of internal leading for the font. * This is normally the difference between the max ascent * and the em ascent. */ nscoord InternalLeading(); /** * Returns the amount of external leading for the font. * em ascent(?) plus external leading is the font designer's * recommended line-height for this font. */ nscoord ExternalLeading(); /** * Returns the height of the em square. * This is em ascent plus em descent. */ nscoord EmHeight(); /** * Returns the ascent part of the em square. */ nscoord EmAscent(); /** * Returns the descent part of the em square. */ nscoord EmDescent(); /** * Returns the height of the bounding box. * This is max ascent plus max descent. */ nscoord MaxHeight(); /** * Returns the maximum distance characters in this font extend * above the base line. */ nscoord MaxAscent(); /** * Returns the maximum distance characters in this font extend * below the base line. */ nscoord MaxDescent(); /** * Returns the maximum character advance for the font. */ nscoord MaxAdvance(); /** * Returns the average character width */ nscoord AveCharWidth(); /** * Returns the often needed width of the space character */ nscoord SpaceWidth(); /** * Returns the font associated with these metrics. The return value * is only defined after Init() has been called. */ const nsFont& Font() const { return mFont; } /** * Returns the language associated with these metrics */ nsAtom* Language() const { return mLanguage; } /** * Returns the orientation (horizontal/vertical) of these metrics. */ FontOrientation Orientation() const { return mOrientation; } int32_t GetMaxStringLength(); // Get the width for this string. aWidth will be updated with the // width in points, not twips. Callers must convert it if they // want it in another format. nscoord GetWidth(const char* aString, uint32_t aLength, DrawTarget* aDrawTarget); nscoord GetWidth(const char16_t* aString, uint32_t aLength, DrawTarget* aDrawTarget); // Draw a string using this font handle on the surface passed in. void DrawString(const char* aString, uint32_t aLength, nscoord aX, nscoord aY, gfxContext* aContext); void DrawString(const char16_t* aString, uint32_t aLength, nscoord aX, nscoord aY, gfxContext* aContext, DrawTarget* aTextRunConstructionDrawTarget); nsBoundingMetrics GetBoundingMetrics(const char16_t* aString, uint32_t aLength, DrawTarget* aDrawTarget); // Returns the LOOSE_INK_EXTENTS bounds of the text for determing the // overflow area of the string. nsBoundingMetrics GetInkBoundsForInkOverflow(const char16_t* aString, uint32_t aLength, DrawTarget* aDrawTarget); void SetTextRunRTL(bool aIsRTL) { mTextRunRTL = aIsRTL; } bool GetTextRunRTL() const { return mTextRunRTL; } void SetVertical(bool aVertical) { mVertical = aVertical; } bool GetVertical() const { return mVertical; } void SetTextOrientation(mozilla::StyleTextOrientation aTextOrientation) { mTextOrientation = aTextOrientation; } mozilla::StyleTextOrientation GetTextOrientation() const { return mTextOrientation; } bool ExplicitLanguage() const { return mExplicitLanguage; } gfxFontGroup* GetThebesFontGroup() const { return mFontGroup; } gfxUserFontSet* GetUserFontSet() const; int32_t AppUnitsPerDevPixel() const { return mP2A; } private: // Private destructor, to discourage deletion outside of Release(): ~nsFontMetrics(); nsFont mFont; RefPtr<gfxFontGroup> mFontGroup; RefPtr<nsAtom> mLanguage; // Pointer to the device context for which this fontMetrics object was // created. nsDeviceContext* MOZ_NON_OWNING_REF mDeviceContext; int32_t mP2A; // The font orientation (horizontal or vertical) for which these metrics // have been initialized. This determines which line metrics (ascent and // descent) they will return. FontOrientation mOrientation; // Whether mLanguage comes from explicit markup (in which case it should be // used to tailor effects like case-conversion) or is an inferred/default // value. bool mExplicitLanguage; // These fields may be set by clients to control the behavior of methods // like GetWidth and DrawString according to the writing mode, direction // and text-orientation desired. bool mTextRunRTL; bool mVertical; mozilla::StyleTextOrientation mTextOrientation; }; #endif /* NSFONTMETRICS__H__ */