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