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