tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsMathMLChar.h (8394B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef nsMathMLChar_h___
      8 #define nsMathMLChar_h___
      9 
     10 #include "gfxTextRun.h"
     11 #include "nsBoundingMetrics.h"
     12 #include "nsColor.h"
     13 #include "nsMathMLOperators.h"
     14 #include "nsPoint.h"
     15 #include "nsRect.h"
     16 #include "nsString.h"
     17 
     18 class gfxContext;
     19 class nsGlyphTable;
     20 class nsIFrame;
     21 class nsPresContext;
     22 struct nsBoundingMetrics;
     23 struct nsFont;
     24 
     25 namespace mozilla {
     26 class nsDisplayListBuilder;
     27 class nsDisplayListSet;
     28 class ComputedStyle;
     29 }  // namespace mozilla
     30 
     31 // Hints for Stretch() to indicate criteria for stretching
     32 enum {
     33  // Don't stretch
     34  NS_STRETCH_NONE = 0x00,
     35  // Variable size stretches
     36  NS_STRETCH_VARIABLE_MASK = 0x0F,
     37  NS_STRETCH_NORMAL = 0x01,   // try to stretch to requested size
     38  NS_STRETCH_NEARER = 0x02,   // stretch very close to requested size
     39  NS_STRETCH_SMALLER = 0x04,  // don't stretch more than requested size
     40  NS_STRETCH_LARGER = 0x08,   // don't stretch less than requested size
     41  // A largeop in displaystyle
     42  NS_STRETCH_LARGEOP = 0x10,
     43 
     44  // Intended for internal use:
     45  // Find the widest metrics that might be returned from a vertical stretch
     46  NS_STRETCH_MAXWIDTH = 0x20
     47 };
     48 
     49 // A single glyph in our internal representation is either
     50 // 1) a code pair from the mathfontFONTFAMILY.properties table, interpreted
     51 // as a Unicode point.
     52 // 2) a glyph index from the Open Type MATH table.
     53 struct nsGlyphCode {
     54  union {
     55    char16_t code;
     56    uint32_t glyphID;
     57  };
     58  bool isGlyphID = true;
     59 
     60  bool Exists() const { return isGlyphID ? glyphID != 0 : code != 0; }
     61  bool operator==(const nsGlyphCode& other) const {
     62    return (other.isGlyphID == isGlyphID &&
     63            (isGlyphID ? other.glyphID == glyphID : other.code == code));
     64  }
     65  bool operator!=(const nsGlyphCode&) const = default;
     66 };
     67 
     68 // Class used to handle stretchy symbols (accent, delimiter and boundary
     69 // symbols).
     70 class nsMathMLChar {
     71 public:
     72  typedef gfxTextRun::Range Range;
     73  typedef mozilla::gfx::DrawTarget DrawTarget;
     74 
     75  // constructor and destructor
     76  nsMathMLChar() : mDirection(NS_STRETCH_DIRECTION_DEFAULT) {
     77    MOZ_COUNT_CTOR(nsMathMLChar);
     78    mComputedStyle = nullptr;
     79    mUnscaledAscent = 0;
     80    mScaleX = mScaleY = 1.0;
     81    mDrawingMethod = DrawingMethod::Normal;
     82    mMirroringMethod = MirroringMethod::None;
     83  }
     84 
     85  // not a virtual destructor: this class is not intended to be subclassed
     86  ~nsMathMLChar();
     87 
     88  void Display(mozilla::nsDisplayListBuilder* aBuilder, nsIFrame* aForFrame,
     89               const mozilla::nsDisplayListSet& aLists, uint32_t aIndex,
     90               const nsRect* aSelectedRect = nullptr);
     91 
     92  void PaintForeground(nsIFrame* aForFrame, gfxContext& aRenderingContext,
     93                       nsPoint aPt, bool aIsSelected);
     94 
     95  // This is the method called to ask the char to stretch itself.
     96  // @param aContainerSize - IN - suggested size for the stretched char
     97  // @param aDesiredStretchSize - OUT - the size that the char wants
     98  nsresult Stretch(nsIFrame* aForFrame, DrawTarget* aDrawTarget,
     99                   float aFontSizeInflation,
    100                   nsStretchDirection aStretchDirection,
    101                   const nsBoundingMetrics& aContainerSize,
    102                   nsBoundingMetrics& aDesiredStretchSize,
    103                   uint32_t aStretchHint, bool aRTL);
    104 
    105  void SetData(nsString& aData);
    106 
    107  void GetData(nsString& aData) { aData = mData; }
    108 
    109  int32_t Length() { return mData.Length(); }
    110 
    111  nsStretchDirection GetStretchDirection() { return mDirection; }
    112 
    113  // Sometimes we only want to pass the data to another routine,
    114  // this function helps to avoid copying
    115  const char16_t* get() { return mData.get(); }
    116 
    117  void GetRect(nsRect& aRect) { aRect = mRect; }
    118 
    119  void SetRect(const nsRect& aRect) { mRect = aRect; }
    120 
    121  // Get the maximum width that the character might have after a vertical
    122  // Stretch().
    123  //
    124  // @param aStretchHint can be the value that will be passed to Stretch().
    125  // It is used to determine whether the operator is stretchy or a largeop.
    126  nscoord GetMaxWidth(nsIFrame* aForFrame, DrawTarget* aDrawTarget,
    127                      float aFontSizeInflation,
    128                      uint32_t aStretchHint = NS_STRETCH_NORMAL);
    129 
    130  // Metrics that _exactly_ enclose the char. The char *must* have *already*
    131  // being stretched before you can call the GetBoundingMetrics() method.
    132  // IMPORTANT: since chars have their own ComputedStyles, and may be rendered
    133  // with glyphs that are not in the parent font, just calling the default
    134  // aRenderingContext.GetBoundingMetrics(aChar) can give incorrect results.
    135  void GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
    136    aBoundingMetrics = mBoundingMetrics;
    137  }
    138 
    139  void SetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
    140    mBoundingMetrics = aBoundingMetrics;
    141  }
    142 
    143  // Hooks to access the extra leaf ComputedStyles given to the MathMLChars.
    144  // They provide an interface to make them accessible to the Style System via
    145  // the Get/Set AdditionalComputedStyle() APIs. Owners of MathMLChars
    146  // should honor these APIs.
    147  mozilla::ComputedStyle* GetComputedStyle() const;
    148 
    149  void SetComputedStyle(mozilla::ComputedStyle* aComputedStyle);
    150 
    151 protected:
    152  friend class nsGlyphTable;
    153  friend class nsPropertiesTable;
    154  friend class nsOpenTypeTable;
    155  nsString mData;
    156 
    157 private:
    158  nsRect mRect;
    159  nsStretchDirection mDirection;
    160  nsBoundingMetrics mBoundingMetrics;
    161  RefPtr<mozilla::ComputedStyle> mComputedStyle;
    162  // mGlyphs/mBmData are arrays describing the glyphs used to draw the operator.
    163  // See the drawing methods below.
    164  RefPtr<gfxTextRun> mGlyphs[4];
    165  nsBoundingMetrics mBmData[4];
    166  // mUnscaledAscent is the actual ascent of the char.
    167  nscoord mUnscaledAscent;
    168  // mScaleX, mScaleY are the factors by which we scale the char.
    169  float mScaleX, mScaleY;
    170 
    171  // mDrawingMethod indicates how we draw the stretchy operator:
    172  // - Normal: we render the mData string normally.
    173  // - Variant: we draw a larger size variant given by mGlyphs[0].
    174  // - Parts: we assemble several parts given by mGlyphs[0], ... mGlyphs[4]
    175  // XXXfredw: the MATH table can have any numbers of parts and extenders.
    176  enum class DrawingMethod { Normal, Variant, Parts };
    177  DrawingMethod mDrawingMethod;
    178 
    179  // mMirroringMethod indicates whether the character is mirrored.
    180  // - None: shouldn't be mirrored.
    181  // - Character: using unicode character mirroring.
    182  // - Glyph: using rtlm glyph mirroring.
    183  // - ScaleFallback: the font doesn't support this character, fall back
    184  //                  to applying a scale of -1 on the X axis and a scale
    185  //                  of 1 on the Y axis.
    186  enum class MirroringMethod : uint8_t {
    187    None,
    188    Character,
    189    Glyph,
    190    ScaleFallback,
    191  };
    192  MirroringMethod mMirroringMethod;
    193 
    194  class StretchEnumContext;
    195  friend class StretchEnumContext;
    196 
    197  // helper methods
    198  bool SetFontFamily(nsPresContext* aPresContext,
    199                     const nsGlyphTable* aGlyphTable,
    200                     const nsGlyphCode& aGlyphCode,
    201                     const mozilla::StyleFontFamilyList& aDefaultFamily,
    202                     nsFont& aFont, RefPtr<gfxFontGroup>* aFontGroup);
    203 
    204  nsresult StretchInternal(nsIFrame* aForFrame, DrawTarget* aDrawTarget,
    205                           float aFontSizeInflation,
    206                           nsStretchDirection& aStretchDirection,
    207                           const nsBoundingMetrics& aContainerSize,
    208                           nsBoundingMetrics& aDesiredStretchSize,
    209                           uint32_t aStretchHint,
    210                           float aMaxSize = NS_MATHML_OPERATOR_SIZE_INFINITY,
    211                           bool aMaxSizeIsAbsolute = false);
    212 
    213  nsresult PaintVertically(nsPresContext* aPresContext,
    214                           gfxContext* aThebesContext, nsRect& aRect,
    215                           nscolor aColor);
    216 
    217  nsresult PaintHorizontally(nsPresContext* aPresContext,
    218                             gfxContext* aThebesContext, nsRect& aRect,
    219                             nscolor aColor);
    220 
    221  void ApplyTransforms(gfxContext* aThebesContext, int32_t aAppUnitsPerGfxUnit,
    222                       nsRect& r);
    223 };
    224 
    225 #endif /* nsMathMLChar_h___ */