author | Frédéric Wang <fred.wang@free.fr> |
Mon, 20 Aug 2012 20:14:20 -0400 | |
changeset 102862 | f9094ef74bf369e3112887164afc9e8a6fdfb799 |
parent 102861 | 17ddc4d169e1f9d54cfc005e5e67a4ea8e97146a |
child 102863 | 313eb51d2b577436f8ca590b6890085b0d87b6da |
push id | 23312 |
push user | emorley@mozilla.com |
push date | Tue, 21 Aug 2012 13:23:13 +0000 |
treeherder | mozilla-central@f9a8fdb08193 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | karlt |
bugs | 781494 |
milestone | 17.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/layout/mathml/MathJaxFonts.html +++ b/layout/mathml/MathJaxFonts.html @@ -48,30 +48,17 @@ hexacode = "0" + hexacode; } return "\\u" + hexacode + f; } function codePoint2(aList) { if (aList) { - if (Array.isArray(aList[0])) { - // Generate a string representation for a composite character. - // (the syntax may not match the parser in nsMathMLChar, but - // support for composite character is broken anyway). - var str = "("; - str += codePoint(aList[0][0], aList[1]); - for (var i = 1; i < aList[0].length; i++) { - str += "," + codePoint(aList[0][i], aList[1]); - } - str += ")"; - return str; - } else { - return codePoint(aList[0], aList[1]); - } + return codePoint(aList[0], aList[1]); } else { return noChar; } } function isSupported(aStretch) { for (var x in aStretch) { @@ -124,18 +111,19 @@ v = delimiters[v.alias]; } else { // It is an alias to a non-stretchy char. Ignore it. continue; } } if (v.stretch && !isSupported(v.stretch)) { - // This construction is not supported. Comment the line. - t.value += "# "; + // This construction is not supported. + t.value += "# " + codePoint(u) + " = [not supported]\n"; + continue; } t.value += codePoint(u); t.value += " = "; if (v.stretch) { if (v.dir == "V") { t.value += codePoint2(v.stretch.top); t.value += codePoint2(v.stretch.mid);
--- a/layout/mathml/mathfont.properties +++ b/layout/mathml/mathfont.properties @@ -1217,16 +1217,8 @@ operator.\uFE38.postfix = lspace:0 rspac # the "Symbol" font and the "MT Extra" font are in "mathfontSymbol.properties" # and "mathfontMTExtra.properties", respectively. The font property file is a # set of all the stretchy MathML characters that can be rendered with that font # using larger and/or partial glyphs. Each stretchy character is associated to # a list in the font property file which gives, in that order, the 4 partial # glyphs: top (or left), middle, bottom (or right), glue; and the variants of # bigger sizes (if any). A position that is not relevant to a particular character # is indicated there with the UNICODE REPLACEMENT CHARACTER 0xFFFD. -# -# Characters that need to be built from other characters are said to be composite. -# For example, characters like over/underbrace in CMEX10 have to be built from two -# half stretchy chars and joined in the middle (TeXbook, p.225). Several (i.e., 2 -# or more) child characters can be composed in order to render another chararacter. -# To specify such characters, their list of glyphs in the property file should be -# given as space-separated segments of glyphs. Each segment gives the 4 partial glyphs -# with which to build the child character that will be joined with its other siblings.
--- a/layout/mathml/mathfontMathJax_Main.properties +++ b/layout/mathml/mathfontMathJax_Main.properties @@ -4,17 +4,17 @@ # Content below is generated from MathJaxFonts.html. Do not edit. external.1 = MathJax_Size1 external.2 = MathJax_Size2 external.3 = MathJax_Size3 external.4 = MathJax_Size4 external.5 = MathJax_AMS -# external.6 = MathJax_Main-Bold +# external.6 = MathJax_Main-bold \u0028 = \u239B@4\uFFFD\u239D@4\u239C@4\u0028\u0028@1\u0028@2\u0028@3\u0028@4 \u0029 = \u239E@4\uFFFD\u23A0@4\u239F@4\u0029\u0029@1\u0029@2\u0029@3\u0029@4 \u002F = \uFFFD\uFFFD\uFFFD\uFFFD\u002F\u002F@1\u002F@2\u002F@3\u002F@4 \u005B = \u23A1@4\uFFFD\u23A3@4\u23A2@4\u005B\u005B@1\u005B@2\u005B@3\u005B@4 \u005C = \uFFFD\uFFFD\uFFFD\uFFFD\u005C\u005C@1\u005C@2\u005C@3\u005C@4 \u005D = \u23A4@4\uFFFD\u23A6@4\u23A5@4\u005D\u005D@1\u005D@2\u005D@3\u005D@4 \u007B = \u23A7@4\u23A8@4\u23A9@4\u23AA@4\u007B\u007B@1\u007B@2\u007B@3\u007B@4 @@ -43,18 +43,18 @@ external.5 = MathJax_AMS \u2308 = \u23A1@4\uFFFD\uFFFD\u23A2@4\u2308\u2308@1\u2308@2\u2308@3\u2308@4 \u2309 = \u23A4@4\uFFFD\uFFFD\u23A5@4\u2309\u2309@1\u2309@2\u2309@3\u2309@4 \u230A = \uFFFD\uFFFD\u23A3@4\u23A2@4\u230A\u230A@1\u230A@2\u230A@3\u230A@4 \u230B = \uFFFD\uFFFD\u23A6@4\u23A5@4\u230B\u230B@1\u230B@2\u230B@3\u230B@4 \u23AA = \u23AA@4\uFFFD\u23AA@4\u23AA@4\u23AA@4 \u23B0 = \u23A7@4\uFFFD\u23AD@4\u23AA@4\u23B0 \u23B1 = \u23AB@4\uFFFD\u23A9@4\u23AA@4\u23B1 \u23D0 = \uFFFD\uFFFD\uFFFD\u2223\u23D0@1\u23D0 -# \u23DE = \uE150@4(\uE153@4,\uE152@4)\uE151@4\uE154@4 -# \u23DF = \uE152@4(\uE151@4,\uE150@4)\uE153@4\uE154@4 +# \u23DE = [not supported] +# \u23DF = [not supported] \u27E8 = \uFFFD\uFFFD\uFFFD\uFFFD\u27E8\u27E8@1\u27E8@2\u27E8@3\u27E8@4 \u27E9 = \uFFFD\uFFFD\uFFFD\uFFFD\u27E9\u27E9@1\u27E9@2\u27E9@3\u27E9@4 \u27EE = \u23A7@4\uFFFD\u23A9@4\u23AA@4\u27EE \u27EF = \u23AB@4\uFFFD\u23AD@4\u23AA@4\u27EF \u002D = \uFFFD\uFFFD\uFFFD\u2212\u002D \u005E = \uFFFD\uFFFD\uFFFD\uFFFD\u005E\u005E@1\u005E@2\u005E@3\u005E@4 \u005F = \uFFFD\uFFFD\uFFFD\u2212\u005F \u007E = \uFFFD\uFFFD\uFFFD\uFFFD\u007E\u007E@1\u007E@2\u007E@3\u007E@4 @@ -68,67 +68,67 @@ external.5 = MathJax_AMS \u2215 = \uFFFD\uFFFD\uFFFD\uFFFD\u2215\u2215@1\u2215@2\u2215@3\u2215@4 \u2329 = \uFFFD\uFFFD\uFFFD\uFFFD\u2329\u2329@1\u2329@2\u2329@3\u2329@4 \u232A = \uFFFD\uFFFD\uFFFD\uFFFD\u232A\u232A@1\u232A@2\u232A@3\u232A@4 \u23AF = \uFFFD\uFFFD\uFFFD\u2212\u23AF \u2500 = \uFFFD\uFFFD\uFFFD\u2212\u2500 \u2758 = \uFFFD\uFFFD\uFFFD\u2223\u2758 \u3008 = \uFFFD\uFFFD\uFFFD\uFFFD\u3008\u3008@1\u3008@2\u3008@3\u3008@4 \u3009 = \uFFFD\uFFFD\uFFFD\uFFFD\u3009\u3009@1\u3009@2\u3009@3\u3009@4 -# \uFE37 = \uE150@4(\uE153@4,\uE152@4)\uE151@4\uE154@4 -# \uFE38 = \uE152@4(\uE151@4,\uE150@4)\uE153@4\uE154@4 +# \uFE37 = [not supported] +# \uFE38 = [not supported] \u003D = \uFFFD\uFFFD\uFFFD\u003D\u003D \u219E = \u219E@5\uFFFD\uFFFD\u2212\u219E@5 \u21A0 = \uFFFD\uFFFD\u21A0@5\u2212\u21A0@5 -# \u21A4 = \u2190\uFFFD\u2223@1\u2212 -# \u21A5 = \u2191@1\uFFFD\u22A5@6\u23D0@1 -# \u21A6 = \u2223@1\uFFFD\u2192\u2212\u21A6 -# \u21A7 = \u22A4@6\uFFFD\u2193@1\u23D0@1 -# \u21B0 = \u21B0@5\uFFFD\uFFFD\u23D0@1\u21B0@5 -# \u21B1 = \u21B1@5\uFFFD\uFFFD\u23D0@1\u21B1@5 +# \u21A4 = [not supported] +# \u21A5 = [not supported] +# \u21A6 = [not supported] +# \u21A7 = [not supported] +# \u21B0 = [not supported] +# \u21B1 = [not supported] \u21BC = \u21BC\uFFFD\uFFFD\u2212\u21BC \u21BD = \u21BD\uFFFD\uFFFD\u2212\u21BD -# \u21BE = \u21BE@5\uFFFD\uFFFD\u23D0@1\u21BE@5 -# \u21BF = \u21BF@5\uFFFD\uFFFD\u23D0@1\u21BF@5 +# \u21BE = [not supported] +# \u21BF = [not supported] \u21C0 = \uFFFD\uFFFD\u21C0\u2212\u21C0 \u21C1 = \uFFFD\uFFFD\u21C1\u2212\u21C1 -# \u21C2 = \uFFFD\uFFFD\u21C2@5\u23D0@1\u21C2@5 -# \u21C3 = \uFFFD\uFFFD\u21C3@5\u23D0@1\u21C3@5 +# \u21C2 = [not supported] +# \u21C3 = [not supported] \u21DA = \u21DA@5\uFFFD\uFFFD\u2261\u21DA@5 \u21DB = \uFFFD\uFFFD\u21DB@5\u2261\u21DB@5 -# \u23B4 = \u250C@5\uFFFD\u2510@5\u2212 -# \u23B5 = \u2514@5\uFFFD\u2518@5\u2212 +# \u23B4 = [not supported] +# \u23B5 = [not supported] \u23DC = \uE150@4\uFFFD\uE151@4\uE154@4\u23DC@5\u23DC \u23DD = \uE152@4\uFFFD\uE153@4\uE154@4\u23DD@5\u23DD -# \u23E0 = \u02CA\uFFFD\u02CB\u02C9 -# \u23E1 = \u02CB\uFFFD\u02CA\u02C9 -# \u2906 = \u21D0\uFFFD\u2223@1\u003D -# \u2907 = \u22A8@5\uFFFD\u21D2\u003D +# \u23E0 = [not supported] +# \u23E1 = [not supported] +# \u2906 = [not supported] +# \u2907 = [not supported] \u294E = \u21BC\uFFFD\u21C0\u2212 -# \u294F = \u21BE@5\uFFFD\u21C2@5\u23D0@1 +# \u294F = [not supported] \u2950 = \u21BD\uFFFD\u21C1\u2212 -# \u2951 = \u21BF@5\uFFFD\u21C3@5\u23D0@1 -# \u295A = \u21BC\uFFFD\u2223@1\u2212 -# \u295B = \u2223@1\uFFFD\u21C0\u2212 -# \u295C = \u21BE@5\uFFFD\u22A5@6\u23D0@1 -# \u295D = \u22A4@6\uFFFD\u21C2@5\u23D0@1 -# \u295E = \u21BD\uFFFD\u2223@1\u2212 -# \u295F = \u2223@1\uFFFD\u21C1\u2212 -# \u2960 = \u21BF@5\uFFFD\u22A5@6\u23D0@1 -# \u2961 = \u22A4@6\uFFFD\u21C3@5\u23D0@1 +# \u2951 = [not supported] +# \u295A = [not supported] +# \u295B = [not supported] +# \u295C = [not supported] +# \u295D = [not supported] +# \u295E = [not supported] +# \u295F = [not supported] +# \u2960 = [not supported] +# \u2961 = [not supported] \u27F5 = \u2190\uFFFD\uFFFD\u2212\u27F5 \u27F6 = \uFFFD\uFFFD\u2192\u2212\u27F6 \u27F7 = \u2190\uFFFD\u2192\u2212\u27F7 \u27F8 = \u21D0\uFFFD\uFFFD\u003D\u27F8 \u27F9 = \uFFFD\uFFFD\u21D2\u003D\u27F9 \u27FA = \u21D0\uFFFD\u21D2\u003D\u27FA -# \u27FB = \u2190\uFFFD\u2223@1\u2212 -# \u27FC = \u2223@1\uFFFD\u2192\u2212\u27FC -# \u27FD = \u21D0\uFFFD\u2223@1\u003D -# \u27FE = \u22A8@5\uFFFD\u21D2\u003D +# \u27FB = [not supported] +# \u27FC = [not supported] +# \u27FD = [not supported] +# \u27FE = [not supported] \u0020 = \uFFFD\uFFFD\uFFFD\uFFFD\u0020@1\u0020@2 \u00A0 = \uFFFD\uFFFD\uFFFD\uFFFD\u00A0@1\u00A0@2 \u220F = \uFFFD\uFFFD\uFFFD\uFFFD\u220F@1\u220F@2 \u2210 = \uFFFD\uFFFD\uFFFD\uFFFD\u2210@1\u2210@2 \u2211 = \uFFFD\uFFFD\uFFFD\uFFFD\u2211@1\u2211@2 \u222B = \uFFFD\uFFFD\uFFFD\uFFFD\u222B@1\u222B@2 \u222C = \uFFFD\uFFFD\uFFFD\uFFFD\u222C@1\u222C@2 \u222D = \uFFFD\uFFFD\uFFFD\uFFFD\u222D@1\u222D@2
--- a/layout/mathml/nsMathMLChar.cpp +++ b/layout/mathml/nsMathMLChar.cpp @@ -66,32 +66,16 @@ typedef enum {eExtension_base, eExtensio // and "mathfontMTExtra.properties", respectively. The mathfont property file // is a set of all the stretchy MathML characters that can be rendered with that // font using larger and/or partial glyphs. The entry of each stretchy character // in the mathfont property file gives, in that order, the 4 partial glyphs: // Top (or Left), Middle, Bottom (or Right), Glue; and the variants of bigger // sizes (if any). // A position that is not relevant to a particular character is indicated there // with the UNICODE REPLACEMENT CHARACTER 0xFFFD. -// Characters that need to be built recursively from other characters are said -// to be composite. For example, chars like over/underbrace in CMEX10 have to -// be built from two half stretchy chars and joined in the middle -// (TeXbook, p.225). -// Such chars are handled in a special manner by the nsMathMLChar class, which -// allows several (2 or more) child chars to be composed in order to render -// another char. -// To specify such chars, their list of glyphs in the property file should be -// given as space-separated segments of glyphs. Each segment gives the 4 partial -// glyphs with which to build the child char that will be joined with its other -// siblings. In this code, when this situation happens (see the detailed -// description of Stretch() below), the original char (referred to as "parent") -// creates a singly-linked list of child chars, asking them to stretch in an -// equally divided space. The nsGlyphTable embeds the necessary logic to -// guarantee correctness in a recursive stretch (and in the use of TopOf(), -// GlueOf(), etc) on these child chars. // ----------------------------------------------------------------------------- #define NS_TABLE_TYPE_UNICODE 0 #define NS_TABLE_TYPE_GLYPH_INDEX 1 #define NS_TABLE_STATE_ERROR -1 #define NS_TABLE_STATE_EMPTY 0 #define NS_TABLE_STATE_READY 1 @@ -152,25 +136,19 @@ public: // True if this table contains some glyphs (variants and/or parts) // or contains child chars that can be used to render this char bool Has(nsPresContext* aPresContext, nsMathMLChar* aChar); // True if this table contains variants of larger sizes to render this char bool HasVariantsOf(nsPresContext* aPresContext, nsMathMLChar* aChar); - // True if this table contains parts (or composite parts) to render this char + // True if this table contains parts to render this char bool HasPartsOf(nsPresContext* aPresContext, nsMathMLChar* aChar); - // True if aChar is to be assembled from other child chars in this table - bool IsComposite(nsPresContext* aPresContext, nsMathMLChar* aChar); - - // The number of child chars to assemble in order to render aChar - PRInt32 ChildCountOf(nsPresContext* aPresContext, nsMathMLChar* aChar); - // Getters for the parts nsGlyphCode TopOf(nsPresContext* aPresContext, nsMathMLChar* aChar) { return ElementAt(aPresContext, aChar, 0); } nsGlyphCode MiddleOf(nsPresContext* aPresContext, nsMathMLChar* aChar) { return ElementAt(aPresContext, aChar, 1); } nsGlyphCode BottomOf(nsPresContext* aPresContext, nsMathMLChar* aChar) { @@ -264,20 +242,16 @@ nsGlyphTable::ElementAt(nsPresContext* a key.AppendInt(i, 10); rv = mGlyphProperties->GetStringProperty(key, value); if (NS_FAILED(rv)) break; Clean(value); mFontName.AppendElement(value); // i.e., mFontName[i] holds this font name } } - // If aChar is a child char to be used by a parent composite char, make - // sure that it is really attached to this table - if (aChar->mParent && (aChar->mGlyphTable != this)) return kNullGlyph; - // Update our cache if it is not associated to this character PRUnichar uchar = aChar->mData[0]; if (mCharCache != uchar) { // The key in the property file is interpreted as ASCII and kept // as such ... char key[10]; PR_snprintf(key, sizeof(key), "\\u%04X", uchar); nsAutoString value; nsresult rv = mGlyphProperties->GetStringProperty(nsDependentCString(key), @@ -291,26 +265,20 @@ nsGlyphTable::ElementAt(nsPresContext* a // codes as combined pairs of 'code@font', excluding the '@' separator. This // means that mGlyphCache[3*k],mGlyphCache[3*k+1] will later be rendered // with mFontName[mGlyphCache[3*k+2]] // Note: font identifier is internally an ASCII digit to avoid the null // char issue nsAutoString buffer; PRInt32 length = value.Length(); PRInt32 i = 0; // index in value - PRInt32 j = 0; // part/variant index while (i < length) { PRUnichar code = value[i]; ++i; buffer.Append(code); - // see if we are at the beginning of a child char - if (code == kSpaceCh) { - // reset the annotation indicator to be 0 for the next code point - j = -1; - } // Read the next word if we have a non-BMP character. if (i < length && NS_IS_HIGH_SURROGATE(code)) { code = value[i]; ++i; } else { code = PRUnichar('\0'); } buffer.Append(code); @@ -328,79 +296,33 @@ nsGlyphTable::ElementAt(nsPresContext* a return kNullGlyph; } // The char cannot be handled if this font is not installed if (!mFontName[font].Length()) { return kNullGlyph; } } buffer.Append(font); - ++j; } // update our cache with the new settings mGlyphCache.Assign(buffer); mCharCache = uchar; } - // If aChar is a composite char, only its children are allowed - // to use its glyphs in this table, i.e., the parent char itself - // is disabled and cannot be stretched directly with these glyphs. - // This guarantees a coherent behavior in Stretch(). - if (!aChar->mParent && (kNotFound != mGlyphCache.FindChar(kSpaceCh))) { - return kNullGlyph; - } - - // If aChar is a child char, the index of the glyph is relative to - // the offset of the list of glyphs corresponding to the child char. - PRUint32 offset = 0; - PRUint32 length = mGlyphCache.Length(); - if (aChar->mParent) { - nsMathMLChar* child = aChar->mParent->mSibling; - // XXXkt composite chars can't have size variants - while (child && (child != aChar)) { - offset += 5; // skip the 4 partial glyphs + the whitespace separator - child = child->mSibling; - } - // stay confined in the 4 partial glyphs of this child - length = 3*(offset + 4); - } // 3* is to account for the code@font pairs - PRUint32 index = 3*(offset + aPosition); - if (index+2 >= length) return kNullGlyph; + PRUint32 index = 3*aPosition; + if (index+2 >= mGlyphCache.Length()) return kNullGlyph; nsGlyphCode ch; ch.code[0] = mGlyphCache.CharAt(index); ch.code[1] = mGlyphCache.CharAt(index + 1); ch.font = mGlyphCache.CharAt(index + 2); return ch.code[0] == PRUnichar(0xFFFD) ? kNullGlyph : ch; } bool -nsGlyphTable::IsComposite(nsPresContext* aPresContext, nsMathMLChar* aChar) -{ - // there is only one level of recursion in our model. a child - // cannot be composite because it cannot have its own children - if (aChar->mParent) return false; - // shortcut to sync the cache with this char... - mCharCache = 0; mGlyphCache.Truncate(); ElementAt(aPresContext, aChar, 0); - // the cache remained empty if the char wasn't found in this table - if (4*3 >= mGlyphCache.Length()) return false; - // the lists of glyphs of a composite char are space-separated - return (kSpaceCh == mGlyphCache.CharAt(4*3)); -} - -PRInt32 -nsGlyphTable::ChildCountOf(nsPresContext* aPresContext, nsMathMLChar* aChar) -{ - // this will sync the cache as well ... - if (!IsComposite(aPresContext, aChar)) return 0; - // the lists of glyphs of a composite char are space-separated - return 1 + mGlyphCache.CountChar(kSpaceCh); -} - -bool nsGlyphTable::Has(nsPresContext* aPresContext, nsMathMLChar* aChar) { return HasVariantsOf(aPresContext, aChar) || HasPartsOf(aPresContext, aChar); } bool nsGlyphTable::HasVariantsOf(nsPresContext* aPresContext, nsMathMLChar* aChar) { @@ -409,18 +331,17 @@ nsGlyphTable::HasVariantsOf(nsPresContex } bool nsGlyphTable::HasPartsOf(nsPresContext* aPresContext, nsMathMLChar* aChar) { return GlueOf(aPresContext, aChar).Exists() || TopOf(aPresContext, aChar).Exists() || BottomOf(aPresContext, aChar).Exists() || - MiddleOf(aPresContext, aChar).Exists() || - IsComposite(aPresContext, aChar); + MiddleOf(aPresContext, aChar).Exists(); } // ----------------------------------------------------------------------------- // This is the list of all the applicable glyph tables. // We will maintain a single global instance that will only reveal those // glyph tables that are associated to fonts currently installed on the // user' system. The class is an XPCOM shutdown observer to allow us to // free its allocated data at shutdown @@ -692,48 +613,38 @@ InitGlobals(nsPresContext* aPresContext) } // ----------------------------------------------------------------------------- // And now the implementation of nsMathMLChar nsStyleContext* nsMathMLChar::GetStyleContext() const { - NS_ASSERTION(!mParent, "invalid call - not allowed for child chars"); NS_ASSERTION(mStyleContext, "chars should always have style context"); return mStyleContext; } void nsMathMLChar::SetStyleContext(nsStyleContext* aStyleContext) { - NS_ASSERTION(!mParent, "invalid call - not allowed for child chars"); NS_PRECONDITION(aStyleContext, "null ptr"); if (aStyleContext != mStyleContext) { if (mStyleContext) mStyleContext->Release(); if (aStyleContext) { mStyleContext = aStyleContext; aStyleContext->AddRef(); - - // Sync the pointers of child chars. - nsMathMLChar* child = mSibling; - while (child) { - child->mStyleContext = mStyleContext; - child = child->mSibling; - } } } } void nsMathMLChar::SetData(nsPresContext* aPresContext, nsString& aData) { - NS_ASSERTION(!mParent, "invalid call - not allowed for child chars"); if (!gInitialized) { InitGlobals(aPresContext); } mData = aData; // some assumptions until proven otherwise // note that mGlyph is not initialized mDirection = NS_STRETCH_DIRECTION_UNSUPPORTED; mBoundingMetrics = nsBoundingMetrics(); @@ -798,26 +709,18 @@ nsMathMLChar::SetData(nsPresContext* aPr smaller variants already fit the container' size. b) if it is a largeopOnly request (i.e., a displaystyle operator with largeop=true and stretchy=false), we break after finding the first starting variant, regardless of whether that variant fits the container's size. 3) If a variant of appropriate size wasn't found, we see if the char can be built by parts using the same glyph table. - Issues: - a) Certain chars like over/underbrace in CMEX10 have to be built - from two half stretchy chars and joined in the middle. Such - chars are handled in a special manner. When this situation is - detected, the initial char (referred to as "parent") creates a - singly-linked list of child chars, asking them to stretch in - a divided space. A convention is used in the setup of - nsGlyphTable to express that a composite parent char can be built - from child chars. - b) There are some chars that have no middle and glue glyphs. For + Issue: + There are chars that have no middle and glue glyphs. For such chars, the parts need to be joined using the rule. By convention (TeXbook p.225), the descent of the parts is zero while their ascent gives the thickness of the rule that should be used to join them. 4) If a match was not found in that glyph table, repeat from 2 to search the ordered list of stretchy fonts for the first font with a glyph table that provides a fit to the container size. If no fit is found, the closest fit @@ -1188,40 +1091,16 @@ nsMathMLChar::StretchEnumContext::TryVar // Always updates the char if a better match is found. bool nsMathMLChar::StretchEnumContext::TryParts(nsGlyphTable* aGlyphTable, const nsAString& aFamily) { if (!aGlyphTable->HasPartsOf(mPresContext, mChar)) return false; // to next table - // See if this is a composite character ///////////////////////////////////// - if (aGlyphTable->IsComposite(mPresContext, mChar)) { - // let the child chars do the job - nsBoundingMetrics compositeSize; - nsresult rv = - mChar->ComposeChildren(mPresContext, mRenderingContext, aGlyphTable, - mTargetSize, compositeSize, mStretchHint); -#ifdef NOISY_SEARCH - printf(" Composing %d chars in font %s %s!\n", - aGlyphTable->ChildCountOf(mPresContext, mChar), - NS_LossyConvertUTF16toASCII(fontName).get(), - NS_SUCCEEDED(rv)? "OK" : "Rejected"); -#endif - if (NS_FAILED(rv)) - return false; // to next table - - // all went well, painting will be delegated from now on to children - mChar->mGlyph = kNullGlyph; // this will tell paint to build by parts - mGlyphFound = true; - mChar->mGlyphTable = aGlyphTable; - mBoundingMetrics = compositeSize; - return true; // no more searching - } - // See if the parts of this table fit in the desired space ////////////////// // Use our stretchy style context now that stretching is in progress nsFont font = mChar->mStyleContext->GetStyleFont()->mFont; // Ensure mRenderingContext.SetFont will be called: font.name.Truncate(); // Compute the bounding metrics of all partial glyphs @@ -1712,99 +1591,16 @@ nsMathMLChar::GetMaxWidth(nsPresContext* const nsBoundingMetrics container; // zero target size StretchInternal(aPresContext, aRenderingContext, direction, container, bm, aStretchHint | NS_STRETCH_MAXWIDTH); return NS_MAX(bm.width, bm.rightBearing) - NS_MIN(0, bm.leftBearing); } -nsresult -nsMathMLChar::ComposeChildren(nsPresContext* aPresContext, - nsRenderingContext& aRenderingContext, - nsGlyphTable* aGlyphTable, - nscoord aTargetSize, - nsBoundingMetrics& aCompositeSize, - PRUint32 aStretchHint) -{ - PRInt32 i = 0; - nsMathMLChar* child; - PRInt32 count = aGlyphTable->ChildCountOf(aPresContext, this); - NS_ASSERTION(count, "something is wrong somewhere"); - if (!count) return NS_ERROR_FAILURE; - // if we haven't been here before, create the linked list of children now - // otherwise, use what we have, adding more children as needed or deleting - // the extra - nsMathMLChar* last = this; - while ((i < count) && last->mSibling) { - i++; - last = last->mSibling; - } - while (i < count) { - child = new nsMathMLChar(this); - last->mSibling = child; - last = child; - i++; - } - if (last->mSibling) { - delete last->mSibling; - last->mSibling = nullptr; - } - // let children stretch in an equal space - nsBoundingMetrics splitSize; - if (NS_STRETCH_DIRECTION_HORIZONTAL == mDirection) - splitSize.width = aTargetSize / count; - else { - splitSize.ascent = aTargetSize / (count * 2); - splitSize.descent = splitSize.ascent; - } - nscoord dx = 0, dy = 0; - for (i = 0, child = mSibling; child; child = child->mSibling, i++) { - // child chars should just inherit our values - which may change between - // calls... - child->mData = mData; - child->mDirection = mDirection; - child->mStyleContext = mStyleContext; - child->mGlyphTable = aGlyphTable; // the child is associated to this table - child->mMirrored = mMirrored; - // there goes the Stretch() ... - nsBoundingMetrics childSize; - nsresult rv = child->Stretch(aPresContext, aRenderingContext, mDirection, - splitSize, childSize, aStretchHint, mMirrored); - // check if something went wrong or the child couldn't fit in the alloted - // space - if (NS_FAILED(rv) || - (NS_STRETCH_DIRECTION_UNSUPPORTED == child->mDirection)) { - delete mSibling; // don't leave a dangling list behind ... - mSibling = nullptr; - return NS_ERROR_FAILURE; - } - child->SetRect(nsRect(dx, dy, childSize.width, - childSize.ascent+childSize.descent)); - if (0 == i) - aCompositeSize = childSize; - else { - if (NS_STRETCH_DIRECTION_HORIZONTAL == mDirection) - aCompositeSize += childSize; - else { - aCompositeSize.descent += childSize.ascent + childSize.descent; - if (aCompositeSize.leftBearing > childSize.leftBearing) - aCompositeSize.leftBearing = childSize.leftBearing; - if (aCompositeSize.rightBearing < childSize.rightBearing) - aCompositeSize.rightBearing = childSize.rightBearing; - } - } - if (NS_STRETCH_DIRECTION_HORIZONTAL == mDirection) - dx += childSize.width; - else - dy += childSize.ascent + childSize.descent; - } - return NS_OK; -} - class nsDisplayMathMLSelectionRect : public nsDisplayItem { public: nsDisplayMathMLSelectionRect(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, const nsRect& aRect) : nsDisplayItem(aBuilder, aFrame), mRect(aRect) { MOZ_COUNT_CTOR(nsDisplayMathMLSelectionRect); } #ifdef NS_BUILD_REFCNT_LOGGING
--- a/layout/mathml/nsMathMLChar.h +++ b/layout/mathml/nsMathMLChar.h @@ -52,51 +52,33 @@ struct nsGlyphCode { bool operator!=(const nsGlyphCode& other) const { return ! operator==(other); } }; // Class used to handle stretchy symbols (accent, delimiter and boundary // symbols). -// There are composite characters that need to be built recursively from other -// characters. Since these are rare we use a light-weight mechanism to handle -// them. Specifically, as need arises we append a singly-linked list of child -// chars with their mParent pointing to the first element in the list, except in -// the originating first element itself where it points to null. mSibling points -// to the next element in the list. Since the originating first element is the -// parent of the others, we call it the "root" char of the list. Testing -// !mParent tells whether you are that "root" during the recursion. The parent -// delegates most of the tasks to the children. class nsMathMLChar { public: // constructor and destructor - nsMathMLChar(nsMathMLChar* aParent = nullptr) { + nsMathMLChar() { MOZ_COUNT_CTOR(nsMathMLChar); mStyleContext = nullptr; - mSibling = nullptr; - mParent = aParent; mUnscaledAscent = 0; mScaleX = mScaleY = 1.0; mDrawNormal = true; mMirrored = false; } // not a virtual destructor: this class is not intended to be subclassed ~nsMathMLChar() { MOZ_COUNT_DTOR(nsMathMLChar); - // there is only one style context owned by the "root" char - // and it may be used by child chars as well - if (!mParent && mStyleContext) { // only the "root" need to release it - mStyleContext->Release(); - } - if (mSibling) { - delete mSibling; - } + mStyleContext->Release(); } nsresult Display(nsDisplayListBuilder* aBuilder, nsIFrame* aForFrame, const nsDisplayListSet& aLists, PRUint32 aIndex, const nsRect* aSelectedRect = nullptr); @@ -147,26 +129,16 @@ public: void GetRect(nsRect& aRect) { aRect = mRect; } void SetRect(const nsRect& aRect) { mRect = aRect; - // shift the orgins of child chars if any - if (!mParent && mSibling) { // only a "root" having child chars can - // enter here - for (nsMathMLChar* child = mSibling; child; child = child->mSibling) { - nsRect rect; - child->GetRect(rect); - rect.MoveBy(mRect.x, mRect.y); - child->SetRect(rect); - } - } } // Get the maximum width that the character might have after a vertical // Stretch(). // // @param aStretchHint can be the value that will be passed to Stretch(). // It is used to determine whether the operator is stretchy or a largeop. // @param aMaxSize is the value of the "maxsize" attribute. @@ -204,20 +176,16 @@ public: nsStyleContext* GetStyleContext() const; void SetStyleContext(nsStyleContext* aStyleContext); protected: friend class nsGlyphTable; nsString mData; - // support for handling composite stretchy chars like TeX over/under braces - nsMathMLChar* mSibling; - nsMathMLChar* mParent; - private: nsRect mRect; nsStretchDirection mDirection; nsBoundingMetrics mBoundingMetrics; nsStyleContext* mStyleContext; nsGlyphTable* mGlyphTable; nsGlyphCode mGlyph; // mFamily is non-empty when the family for the current size is different @@ -242,24 +210,16 @@ private: nsStretchDirection& aStretchDirection, const nsBoundingMetrics& aContainerSize, nsBoundingMetrics& aDesiredStretchSize, PRUint32 aStretchHint, float aMaxSize = NS_MATHML_OPERATOR_SIZE_INFINITY, bool aMaxSizeIsAbsolute = false); nsresult - ComposeChildren(nsPresContext* aPresContext, - nsRenderingContext& aRenderingContext, - nsGlyphTable* aGlyphTable, - nscoord aTargetSize, - nsBoundingMetrics& aCompositeSize, - PRUint32 aStretchHint); - - nsresult PaintVertically(nsPresContext* aPresContext, nsRenderingContext& aRenderingContext, nsFont& aFont, nsStyleContext* aStyleContext, nsGlyphTable* aGlyphTable, nsRect& aRect); nsresult