layout/mathml/nsMathMLChar.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/mathml/nsMathMLChar.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,270 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef nsMathMLChar_h___
    1.10 +#define nsMathMLChar_h___
    1.11 +
    1.12 +#include "nsAutoPtr.h"
    1.13 +#include "nsMathMLOperators.h"
    1.14 +#include "nsPoint.h"
    1.15 +#include "nsRect.h"
    1.16 +#include "nsString.h"
    1.17 +#include "nsBoundingMetrics.h"
    1.18 +#include "gfxFont.h"
    1.19 +
    1.20 +class nsGlyphTable;
    1.21 +class nsIFrame;
    1.22 +class nsDisplayListBuilder;
    1.23 +class nsDisplayListSet;
    1.24 +class nsPresContext;
    1.25 +class nsRenderingContext;
    1.26 +class nsBoundingMetrics;
    1.27 +class nsStyleContext;
    1.28 +class nsFont;
    1.29 +
    1.30 +// Hints for Stretch() to indicate criteria for stretching
    1.31 +enum {
    1.32 +  // Don't stretch
    1.33 +  NS_STRETCH_NONE     = 0x00,
    1.34 +  // Variable size stretches
    1.35 +  NS_STRETCH_VARIABLE_MASK = 0x0F,
    1.36 +  NS_STRETCH_NORMAL   = 0x01, // try to stretch to requested size
    1.37 +  NS_STRETCH_NEARER   = 0x02, // stretch very close to requested size
    1.38 +  NS_STRETCH_SMALLER  = 0x04, // don't stretch more than requested size
    1.39 +  NS_STRETCH_LARGER   = 0x08, // don't stretch less than requested size
    1.40 +  // A largeop in displaystyle
    1.41 +  NS_STRETCH_LARGEOP  = 0x10,
    1.42 +  NS_STRETCH_INTEGRAL  = 0x20,
    1.43 +
    1.44 +  // Intended for internal use:
    1.45 +  // Find the widest metrics that might be returned from a vertical stretch
    1.46 +  NS_STRETCH_MAXWIDTH = 0x40
    1.47 +};
    1.48 +
    1.49 +// A single glyph in our internal representation is either
    1.50 +// 1) a 'code@font' pair from the mathfontFONTFAMILY.properties table. The
    1.51 +// 'code' is interpreted as a Unicode point. The 'font' is a numeric
    1.52 +// identifier given to the font to which the glyph belongs, which is 0 for the
    1.53 +// FONTFAMILY and > 0 for 'external' fonts.
    1.54 +// 2) a glyph index from the Open Type MATH table. In that case, all the glyphs
    1.55 +// come from the font containing that table and 'font' is just set to -1.
    1.56 +struct nsGlyphCode {
    1.57 +  union {
    1.58 +    char16_t code[2];
    1.59 +    uint32_t glyphID;
    1.60 +  };
    1.61 +  int8_t   font;
    1.62 +
    1.63 +  bool IsGlyphID() const { return font == -1; }
    1.64 +
    1.65 +  int32_t Length() const {
    1.66 +    return (IsGlyphID() || code[1] == PRUnichar('\0') ? 1 : 2);
    1.67 +  }
    1.68 +  bool Exists() const
    1.69 +  {
    1.70 +    return IsGlyphID() ? glyphID != 0 : code[0] != 0;
    1.71 +  }
    1.72 +  bool operator==(const nsGlyphCode& other) const
    1.73 +  {
    1.74 +    return (other.font == font &&
    1.75 +            ((IsGlyphID() && other.glyphID == glyphID) ||
    1.76 +             (!IsGlyphID() && other.code[0] == code[0] &&
    1.77 +              other.code[1] == code[1])));
    1.78 +  }
    1.79 +  bool operator!=(const nsGlyphCode& other) const
    1.80 +  {
    1.81 +    return ! operator==(other);
    1.82 +  }
    1.83 +};
    1.84 +
    1.85 +// Class used to handle stretchy symbols (accent, delimiter and boundary
    1.86 +// symbols).
    1.87 +class nsMathMLChar
    1.88 +{
    1.89 +public:
    1.90 +  // constructor and destructor
    1.91 +  nsMathMLChar() {
    1.92 +    MOZ_COUNT_CTOR(nsMathMLChar);
    1.93 +    mStyleContext = nullptr;
    1.94 +    mUnscaledAscent = 0;
    1.95 +    mScaleX = mScaleY = 1.0;
    1.96 +    mDraw = DRAW_NORMAL;
    1.97 +    mMirrored = false;
    1.98 +  }
    1.99 +
   1.100 +  // not a virtual destructor: this class is not intended to be subclassed
   1.101 +  ~nsMathMLChar();
   1.102 +
   1.103 +  void Display(nsDisplayListBuilder*   aBuilder,
   1.104 +               nsIFrame*               aForFrame,
   1.105 +               const nsDisplayListSet& aLists,
   1.106 +               uint32_t                aIndex,
   1.107 +               const nsRect*           aSelectedRect = nullptr);
   1.108 +          
   1.109 +  void PaintForeground(nsPresContext* aPresContext,
   1.110 +                       nsRenderingContext& aRenderingContext,
   1.111 +                       nsPoint aPt,
   1.112 +                       bool aIsSelected);
   1.113 +
   1.114 +  // This is the method called to ask the char to stretch itself.
   1.115 +  // @param aContainerSize - IN - suggested size for the stretched char
   1.116 +  // @param aDesiredStretchSize - OUT - the size that the char wants
   1.117 +  nsresult
   1.118 +  Stretch(nsPresContext*           aPresContext,
   1.119 +          nsRenderingContext&     aRenderingContext,
   1.120 +          nsStretchDirection       aStretchDirection,
   1.121 +          const nsBoundingMetrics& aContainerSize,
   1.122 +          nsBoundingMetrics&       aDesiredStretchSize,
   1.123 +          uint32_t                 aStretchHint,
   1.124 +          bool                     aRTL);
   1.125 +
   1.126 +  void
   1.127 +  SetData(nsPresContext* aPresContext,
   1.128 +          nsString&       aData);
   1.129 +
   1.130 +  void
   1.131 +  GetData(nsString& aData) {
   1.132 +    aData = mData;
   1.133 +  }
   1.134 +
   1.135 +  int32_t
   1.136 +  Length() {
   1.137 +    return mData.Length();
   1.138 +  }
   1.139 +
   1.140 +  nsStretchDirection
   1.141 +  GetStretchDirection() {
   1.142 +    return mDirection;
   1.143 +  }
   1.144 +
   1.145 +  // Sometimes we only want to pass the data to another routine,
   1.146 +  // this function helps to avoid copying
   1.147 +  const char16_t*
   1.148 +  get() {
   1.149 +    return mData.get();
   1.150 +  }
   1.151 +
   1.152 +  void
   1.153 +  GetRect(nsRect& aRect) {
   1.154 +    aRect = mRect;
   1.155 +  }
   1.156 +
   1.157 +  void
   1.158 +  SetRect(const nsRect& aRect) {
   1.159 +    mRect = aRect;
   1.160 +  }
   1.161 +
   1.162 +  // Get the maximum width that the character might have after a vertical
   1.163 +  // Stretch().
   1.164 +  //
   1.165 +  // @param aStretchHint can be the value that will be passed to Stretch().
   1.166 +  // It is used to determine whether the operator is stretchy or a largeop.
   1.167 +  // @param aMaxSize is the value of the "maxsize" attribute.
   1.168 +  // @param aMaxSizeIsAbsolute indicates whether the aMaxSize is an absolute
   1.169 +  // value in app units (true) or a multiplier of the base size (false).
   1.170 +  nscoord
   1.171 +  GetMaxWidth(nsPresContext* aPresContext,
   1.172 +              nsRenderingContext& aRenderingContext,
   1.173 +              uint32_t aStretchHint = NS_STRETCH_NORMAL,
   1.174 +              float aMaxSize = NS_MATHML_OPERATOR_SIZE_INFINITY,
   1.175 +              // Perhaps just nsOperatorFlags aFlags.
   1.176 +              // But need DisplayStyle for largeOp,
   1.177 +              // or remove the largeop bit from flags.
   1.178 +              bool aMaxSizeIsAbsolute = false);
   1.179 +
   1.180 +  // Metrics that _exactly_ enclose the char. The char *must* have *already*
   1.181 +  // being stretched before you can call the GetBoundingMetrics() method.
   1.182 +  // IMPORTANT: since chars have their own style contexts, and may be rendered
   1.183 +  // with glyphs that are not in the parent font, just calling the default
   1.184 +  // aRenderingContext.GetBoundingMetrics(aChar) can give incorrect results.
   1.185 +  void
   1.186 +  GetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
   1.187 +    aBoundingMetrics = mBoundingMetrics;
   1.188 +  }
   1.189 +
   1.190 +  void
   1.191 +  SetBoundingMetrics(nsBoundingMetrics& aBoundingMetrics) {
   1.192 +    mBoundingMetrics = aBoundingMetrics;
   1.193 +  }
   1.194 +
   1.195 +  // Hooks to access the extra leaf style contexts given to the MathMLChars.
   1.196 +  // They provide an interface to make them accessible to the Style System via
   1.197 +  // the Get/Set AdditionalStyleContext() APIs. Owners of MathMLChars
   1.198 +  // should honor these APIs.
   1.199 +  nsStyleContext* GetStyleContext() const;
   1.200 +
   1.201 +  void SetStyleContext(nsStyleContext* aStyleContext);
   1.202 +
   1.203 +protected:
   1.204 +  friend class nsGlyphTable;
   1.205 +  friend class nsPropertiesTable;
   1.206 +  friend class nsOpenTypeTable;
   1.207 +  nsString           mData;
   1.208 +
   1.209 +private:
   1.210 +  nsRect             mRect;
   1.211 +  nsStretchDirection mDirection;
   1.212 +  nsBoundingMetrics  mBoundingMetrics;
   1.213 +  nsStyleContext*    mStyleContext;
   1.214 +  // mGlyphs/mBmData are arrays describing the glyphs used to draw the operator.
   1.215 +  // See the drawing methods below.
   1.216 +  nsAutoPtr<gfxTextRun> mGlyphs[4];
   1.217 +  nsBoundingMetrics     mBmData[4];
   1.218 +  // mUnscaledAscent is the actual ascent of the char.
   1.219 +  nscoord            mUnscaledAscent;
   1.220 +  // mScaleX, mScaleY are the factors by which we scale the char.
   1.221 +  float              mScaleX, mScaleY;
   1.222 +
   1.223 +  // mDraw indicates how we draw the stretchy operator:
   1.224 +  // - DRAW_NORMAL: we render the mData string normally.
   1.225 +  // - DRAW_VARIANT: we draw a larger size variant given by mGlyphs[0].
   1.226 +  // - DRAW_PARTS: we assemble several parts given by mGlyphs[0], ... mGlyphs[4]
   1.227 +  // XXXfredw: the MATH table can have any numbers of parts and extenders.
   1.228 +  enum DrawingMethod {
   1.229 +    DRAW_NORMAL, DRAW_VARIANT, DRAW_PARTS
   1.230 +  };
   1.231 +  DrawingMethod mDraw;
   1.232 +
   1.233 +  // mMirrored indicates whether the character is mirrored. 
   1.234 +  bool               mMirrored;
   1.235 +
   1.236 +  class StretchEnumContext;
   1.237 +  friend class StretchEnumContext;
   1.238 +
   1.239 +  // helper methods
   1.240 +  bool
   1.241 +  SetFontFamily(nsPresContext*          aPresContext,
   1.242 +                const nsGlyphTable*     aGlyphTable,
   1.243 +                const nsGlyphCode&      aGlyphCode,
   1.244 +                const nsAString&        aDefaultFamily,
   1.245 +                nsFont&                 aFont,
   1.246 +                nsRefPtr<gfxFontGroup>* aFontGroup);
   1.247 +
   1.248 +  nsresult
   1.249 +  StretchInternal(nsPresContext*           aPresContext,
   1.250 +                  gfxContext*              aThebesContext,
   1.251 +                  nsStretchDirection&      aStretchDirection,
   1.252 +                  const nsBoundingMetrics& aContainerSize,
   1.253 +                  nsBoundingMetrics&       aDesiredStretchSize,
   1.254 +                  uint32_t                 aStretchHint,
   1.255 +                  float           aMaxSize = NS_MATHML_OPERATOR_SIZE_INFINITY,
   1.256 +                  bool            aMaxSizeIsAbsolute = false);
   1.257 +
   1.258 +  nsresult
   1.259 +  PaintVertically(nsPresContext* aPresContext,
   1.260 +                  gfxContext*    aThebesContext,
   1.261 +                  nsRect&        aRect);
   1.262 +
   1.263 +  nsresult
   1.264 +  PaintHorizontally(nsPresContext* aPresContext,
   1.265 +                    gfxContext*    aThebesContext,
   1.266 +                    nsRect&        aRect);
   1.267 +
   1.268 +  void
   1.269 +  ApplyTransforms(gfxContext* aThebesContext, int32_t aAppUnitsPerGfxUnit,
   1.270 +                  nsRect &r);
   1.271 +};
   1.272 +
   1.273 +#endif /* nsMathMLChar_h___ */

mercurial