author Jan de Mooij <>
Sat, 12 Jan 2019 10:50:04 +0000
changeset 453631 cfa1c48c717048f00eb4811b5719cd716eb1e5b3
parent 449035 66eb1f485c1a3ea81372758bc92292c9428b17cd
child 459868 2d5c4e71e258e24f1a70ed850c619f97e56f2c60
permissions -rw-r--r--
Bug 1518753 part 5 - Stop using JSProtoKey for initial shapes. r=tcampbell I added this optimization in bug 1299107 to share more shapes across compartments. Unfortunately this doesn't play well with same-compartment realms (ICs can misbehave) because it relies on compartments being isolated from each other. I think we should remove this optimization: * Fixing the IC issue is impossible without deoptimizing everything. * I added it mainly for chrome globals. The shared-JSM-global work has eliminated the need for this there. * Same-compartment realms win memory back by eliminating CCWs etc. * It's quite a lot of complicated code. Differential Revision:

/* -*- 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 */


#include <stdint.h>              // for uint32_t
#include <sys/types.h>           // for int32_t
#include "gfxTextRun.h"          // for gfxFont, gfxFontGroup
#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 "nscore.h"              // for char16_t

class gfxContext;
class gfxUserFontSet;
class gfxTextPerfMetrics;
class nsDeviceContext;
class nsAtom;
struct nsBoundingMetrics;

 * 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 {
  typedef gfxTextRun::Range Range;
  typedef mozilla::gfx::DrawTarget DrawTarget;

  struct MOZ_STACK_CLASS Params {
    nsAtom* language = nullptr;
    bool explicitLanguage = false;
    gfxFont::Orientation orientation = gfxFont::eHorizontal;
    gfxUserFontSet* userFontSet = nullptr;
    gfxTextPerfMetrics* textPerf = nullptr;

  nsFontMetrics(const nsFont& aFont, const Params& aParams,
                nsDeviceContext* aContext);

  // Used by stylo

   * 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.
  gfxFont::Orientation 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 GetInkBoundsForVisualOverflow(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(uint8_t aTextOrientation) {
    mTextOrientation = aTextOrientation;
  uint8_t GetTextOrientation() const { return mTextOrientation; }

  gfxFontGroup* GetThebesFontGroup() const { return mFontGroup; }
  gfxUserFontSet* GetUserFontSet() const {
    return mFontGroup->GetUserFontSet();

  int32_t AppUnitsPerDevPixel() const { return mP2A; }

  // Private destructor, to discourage deletion outside of Release():

  const gfxFont::Metrics& GetMetrics() const {
    return GetMetrics(mOrientation);

  const gfxFont::Metrics& GetMetrics(
      const gfxFont::Orientation aFontOrientation) const;

  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.
  gfxFont::Orientation mOrientation;

  // 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;
  uint8_t mTextOrientation;

#endif /* NSFONTMETRICS__H__ */