Bug 781494 - Change line length in nsMathMLChar to be 80 characters or less. r=karlt

This commit is contained in:
Frédéric Wang 2012-08-10 11:29:59 -04:00
Родитель c0bf9cb126
Коммит f54d4562ae
2 изменённых файлов: 125 добавлений и 85 удалений

Просмотреть файл

@ -35,13 +35,13 @@ using namespace mozilla;
//#define NOISY_SEARCH 1
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
static const PRUnichar kSpaceCh = PRUnichar(' ');
static const nsGlyphCode kNullGlyph = {{0, 0}, 0};
typedef enum {eExtension_base, eExtension_variants, eExtension_parts}
nsMathfontPrefExtension;
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// nsGlyphTable is a class that provides an interface for accessing glyphs
// of stretchy chars. It acts like a table that stores the variants of bigger
// sizes (if any) and the partial glyphs needed to build extensible symbols.
@ -58,31 +58,36 @@ typedef enum {eExtension_base, eExtension_variants, eExtension_parts}
// points or as direct glyph indices, depending on the type of the table.
// XXX The latter is not yet supported.
// General format of MathFont Property Files from which glyph data are retrieved:
// -----------------------------------------------------------------------------------
// General format of MathFont Property Files from which glyph data are
// retrieved:
// -----------------------------------------------------------------------------
// Each font should have its set of glyph data. For example, the glyph data for
// the "Symbol" font and the "MT Extra" font are in "mathfontSymbol.properties"
// 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).
// 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
// 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.
// -----------------------------------------------------------------------------------
// 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
@ -115,7 +120,7 @@ LoadProperties(const nsString& aName,
NS_ConvertUTF16toUTF8(uriStr));
}
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
class nsGlyphTable {
public:
@ -129,7 +134,8 @@ public:
mFontName.AppendElement(aPrimaryFontName);
}
~nsGlyphTable() // not a virtual destructor: this class is not intended to be subclassed
// not a virtual destructor: this class is not intended to be subclassed
~nsGlyphTable()
{
MOZ_COUNT_DTOR(nsGlyphTable);
}
@ -173,7 +179,8 @@ public:
nsGlyphCode GlueOf(nsPresContext* aPresContext, nsMathMLChar* aChar) {
return ElementAt(aPresContext, aChar, 3);
}
nsGlyphCode BigOf(nsPresContext* aPresContext, nsMathMLChar* aChar, PRInt32 aSize) {
nsGlyphCode BigOf(nsPresContext* aPresContext, nsMathMLChar* aChar,
PRInt32 aSize) {
return ElementAt(aPresContext, aChar, 4 + aSize);
}
nsGlyphCode LeftOf(nsPresContext* aPresContext, nsMathMLChar* aChar) {
@ -184,7 +191,8 @@ public:
}
private:
nsGlyphCode ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint32 aPosition);
nsGlyphCode ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar,
PRUint32 aPosition);
// The type is either NS_TABLE_TYPE_UNICODE or NS_TABLE_TYPE_GLYPH_INDEX
PRInt32 mType;
@ -197,31 +205,36 @@ private:
// Tri-state variable for error/empty/ready
PRInt32 mState;
// The set of glyph data in this table, as provided by the MathFont Property File
// The set of glyph data in this table, as provided by the MathFont Property
// File
nsCOMPtr<nsIPersistentProperties> mGlyphProperties;
// For speedy re-use, we always cache the last data used in the table.
// mCharCache is the Unicode point of the last char that was queried in this
// table. mGlyphCache is a buffer containing the glyph data associated to
// that char. For a property line 'key = value' in the MathFont Property File,
// mCharCache will retain the 'key' -- which is a Unicode point, while mGlyphCache
// will retain the 'value', which is a consecutive list of nsGlyphCodes, i.e.,
// the pairs of 'code@font' needed by the char -- in which 'code@0' can be specified
// without the optional '@0'. However, to ease subsequent processing, mGlyphCache
// excludes the '@' symbol and explicitly inserts all optional '0' that indicates
// the primary font identifier. Specifically therefore, the k-th glyph is
// characterized by :
// 1) mGlyphCache[3*k],mGlyphCache[3*k+1] : its Unicode point (or glyph index -- depending on mType),
// 2) mGlyphCache[3*k+2] : the numeric identifier of the font where it comes from.
// mCharCache will retain the 'key' -- which is a Unicode point, while
// mGlyphCache will retain the 'value', which is a consecutive list of
// nsGlyphCodes, i.e., the pairs of 'code@font' needed by the char -- in
// which 'code@0' can be specified
// without the optional '@0'. However, to ease subsequent processing,
// mGlyphCache excludes the '@' symbol and explicitly inserts all optional '0'
// that indicates the primary font identifier. Specifically therefore, the
// k-th glyph is characterized by :
// 1) mGlyphCache[3*k],mGlyphCache[3*k+1] : its Unicode point (or glyph index
// -- depending on mType),
// 2) mGlyphCache[3*k+2] : the numeric identifier of the font where it comes
// from.
// A font identifier of '0' means the default primary font associated to this
// table. Other digits map to the "external" fonts that may have been specified
// in the MathFont Property File.
// table. Other digits map to the "external" fonts that may have been
// specified in the MathFont Property File.
nsString mGlyphCache;
PRUnichar mCharCache;
};
nsGlyphCode
nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint32 aPosition)
nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar,
PRUint32 aPosition)
{
if (mState == NS_TABLE_STATE_ERROR) return kNullGlyph;
// Load glyph properties if this is the first time we have been here
@ -267,15 +280,19 @@ nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint
// as such ...
char key[10]; PR_snprintf(key, sizeof(key), "\\u%04X", uchar);
nsAutoString value;
nsresult rv = mGlyphProperties->GetStringProperty(nsDependentCString(key), value);
nsresult rv = mGlyphProperties->GetStringProperty(nsDependentCString(key),
value);
if (NS_FAILED(rv)) return kNullGlyph;
Clean(value);
// See if this char uses external fonts; e.g., if the 2nd glyph is taken from the
// external font '1', the property line looks like \uNNNN = \uNNNN\uNNNN@1\uNNNN.
// This is where mGlyphCache is pre-processed to explicitly store all glyph 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
// See if this char uses external fonts; e.g., if the 2nd glyph is taken
// from the external font '1', the property line looks like
// \uNNNN = \uNNNN\uNNNN@1\uNNNN.
// This is where mGlyphCache is pre-processed to explicitly store all glyph
// 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
@ -362,9 +379,11 @@ nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint
offset += 5; // skip the 4 partial glyphs + the whitespace separator
child = child->mSibling;
}
length = 3*(offset + 4); // stay confined in the 4 partial glyphs of this child
// stay confined in the 4 partial glyphs of this child
length = 3*(offset + 4);
}
PRUint32 index = 3*(offset + aPosition); // 3* is to account for the code@font pairs
// 3* is to account for the code@font pairs
PRUint32 index = 3*(offset + aPosition);
if (index+2 >= length) return kNullGlyph;
nsGlyphCode ch;
ch.code[0] = mGlyphCache.CharAt(index);
@ -419,7 +438,7 @@ nsGlyphTable::HasPartsOf(nsPresContext* aPresContext, nsMathMLChar* aChar)
IsComposite(aPresContext, aChar);
}
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// 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
@ -475,7 +494,7 @@ private:
NS_IMPL_ISUPPORTS1(nsGlyphTableList, nsIObserver)
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Here is the global list of applicable glyph tables that we will be using
static nsGlyphTableList* gGlyphTableList = nullptr;
@ -567,7 +586,7 @@ nsGlyphTableList::GetGlyphTableFor(const nsAString& aFamily)
return &mUnicodeTable;
}
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Lookup the preferences:
// "font.mathfont-family.\uNNNN.base" -- fonts for the base size
@ -586,7 +605,8 @@ GetFontExtensionPref(PRUnichar aChar,
// user_pref("font.mathfont-family.\uNNNN.base", "...") rather than
// user_pref("font.mathfont-family.\\uNNNN.base", "...").
// The \uNNNN in the former is interpreted as an UTF16 escape sequence by
// JavaScript and is converted to the internal UTF8 string that JavaScript uses.
// JavaScript and is converted to the internal UTF8 string that JavaScript
// uses.
// But clueless users who are not savvy of JavaScript have no idea as to what
// is going on and are baffled as to why their pref setting is not working.
// So to save countless explanations, we are going to support both keys.
@ -691,7 +711,7 @@ InitGlobals(nsPresContext* aPresContext)
return rv;
}
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// And now the implementation of nsMathMLChar
nsStyleContext*
@ -747,7 +767,7 @@ nsMathMLChar::SetData(nsPresContext* aPresContext,
}
}
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
/*
The Stretch:
@param aContainerSize - suggested size for the stretched char
@ -830,7 +850,7 @@ nsMathMLChar::SetData(nsPresContext* aPresContext,
account for the spacing when setting aContainerSize, and to leave
any extra margin when placing the stretched char.
*/
// -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// plain TeX settings (TeXbook p.152)
@ -854,7 +874,8 @@ IsSizeOK(nsPresContext* aPresContext, nscoord a, nscoord b, PRUint32 aHint)
bool isNearer = false;
if (aHint & (NS_STRETCH_NEARER | NS_STRETCH_LARGEOP)) {
float c = NS_MAX(float(b) * NS_MATHML_DELIMITER_FACTOR,
float(b) - nsPresContext::CSSPointsToAppUnits(NS_MATHML_DELIMITER_SHORTFALL_POINTS));
float(b) - nsPresContext::
CSSPointsToAppUnits(NS_MATHML_DELIMITER_SHORTFALL_POINTS));
isNearer = bool(float(NS_ABS(b - a)) <= (float(b) - c));
}
// Smaller: Mainly for transitory use, to compare two candidate
@ -1178,7 +1199,8 @@ nsMathMLChar::StretchEnumContext::TryVariants(nsGlyphTable* aGlyphTable,
}
return haveBetter &&
(largeopOnly || IsSizeOK(mPresContext, bestSize, mTargetSize, mStretchHint));
(largeopOnly ||
IsSizeOK(mPresContext, bestSize, mTargetSize, mStretchHint));
}
// 3. Build by parts.
@ -1315,7 +1337,8 @@ nsMathMLChar::StretchEnumContext::TryParts(nsGlyphTable* aGlyphTable,
// When maxWidth, updating ascent and descent indicates that no characters
// larger than this character's minimum size need to be checked as they
// will not be used.
mBoundingMetrics.ascent = bmdata[0].ascent; // not used except with descent for height
mBoundingMetrics.ascent = bmdata[0].ascent; // not used except with descent
// for height
mBoundingMetrics.descent = computedSize - mBoundingMetrics.ascent;
mBoundingMetrics.leftBearing = lbearing;
mBoundingMetrics.rightBearing = rbearing;
@ -1356,7 +1379,8 @@ nsMathMLChar::StretchEnumContext::EnumCallback(const nsString& aFamily,
// See if there is a special table for the family, but always use the
// Unicode table for generic fonts.
nsGlyphTable* glyphTable = aGeneric ?
&gGlyphTableList->mUnicodeTable : gGlyphTableList->GetGlyphTableFor(aFamily);
&gGlyphTableList->mUnicodeTable :
gGlyphTableList->GetGlyphTableFor(aFamily);
if (context->mTablesTried.Contains(glyphTable))
return true; // already tried this one
@ -1437,9 +1461,9 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
mUnscaledAscent = aDesiredStretchSize.ascent;
}
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// 1. Check the common situations where stretching is not actually needed
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// quick return if there is nothing special about this char
if ((aStretchDirection != direction &&
@ -1519,9 +1543,9 @@ nsMathMLChar::StretchInternal(nsPresContext* aPresContext,
done = true;
}
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// 2/3. Search for a glyph or set of part glyphs of appropriate size
////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
bool glyphFound = false;
nsAutoString cssFamilies;
@ -1727,7 +1751,8 @@ nsMathMLChar::ComposeChildren(nsPresContext* aPresContext,
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
// otherwise, use what we have, adding more children as needed or deleting
// the extra
nsMathMLChar* last = this;
while ((i < count) && last->mSibling) {
i++;
@ -1753,7 +1778,8 @@ nsMathMLChar::ComposeChildren(nsPresContext* aPresContext,
}
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 chars should just inherit our values - which may change between
// calls...
child->mData = mData;
child->mDirection = mDirection;
child->mStyleContext = mStyleContext;
@ -1763,13 +1789,16 @@ nsMathMLChar::ComposeChildren(nsPresContext* aPresContext,
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)) {
// 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));
child->SetRect(nsRect(dx, dy, childSize.width,
childSize.ascent+childSize.descent));
if (0 == i)
aCompositeSize = childSize;
else {
@ -1827,7 +1856,8 @@ public:
nsDisplayMathMLCharBackground(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, const nsRect& aRect,
nsStyleContext* aStyleContext)
: nsDisplayItem(aBuilder, aFrame), mStyleContext(aStyleContext), mRect(aRect) {
: nsDisplayItem(aBuilder, aFrame), mStyleContext(aStyleContext),
mRect(aRect) {
MOZ_COUNT_CTOR(nsDisplayMathMLCharBackground);
}
#ifdef NS_BUILD_REFCNT_LOGGING
@ -1896,7 +1926,10 @@ public:
return GetBounds(aBuilder, &snap);
}
virtual PRUint32 GetPerFrameKey() { return (mIndex << nsDisplayItem::TYPE_BITS) | nsDisplayItem::GetPerFrameKey(); }
virtual PRUint32 GetPerFrameKey() {
return (mIndex << nsDisplayItem::TYPE_BITS)
| nsDisplayItem::GetPerFrameKey();
}
private:
nsMathMLChar* mChar;
@ -1976,7 +2009,8 @@ nsMathMLChar::Display(nsDisplayListBuilder* aBuilder,
if (styleContext != parentContext &&
NS_GET_A(backg->mBackgroundColor) > 0) {
rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
nsDisplayMathMLCharBackground(aBuilder, aForFrame, mRect, styleContext));
nsDisplayMathMLCharBackground(aBuilder, aForFrame, mRect,
styleContext));
NS_ENSURE_SUCCESS(rv, rv);
}
//else
@ -1992,7 +2026,8 @@ nsMathMLChar::Display(nsDisplayListBuilder* aBuilder,
return aLists.Content()->AppendNewToTop(new (aBuilder)
nsDisplayMathMLCharForeground(aBuilder, aForFrame, this,
aIndex,
aSelectedRect && !aSelectedRect->IsEmpty()));
aSelectedRect &&
!aSelectedRect->IsEmpty()));
}
void
@ -2070,16 +2105,16 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext,
PaintVertically(aPresContext, aRenderingContext, theFont, styleContext,
mGlyphTable, r);
else if (NS_STRETCH_DIRECTION_HORIZONTAL == mDirection)
PaintHorizontally(aPresContext, aRenderingContext, theFont, styleContext,
mGlyphTable, r);
PaintHorizontally(aPresContext, aRenderingContext, theFont,
styleContext, mGlyphTable, r);
}
}
aRenderingContext.PopState();
}
/* =================================================================================
And now the helper routines that actually do the job of painting the char by parts
/* =============================================================================
Helper routines that actually do the job of painting the char by parts
*/
class AutoPushClipRect {
@ -2241,7 +2276,8 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
// fill the gap between top and middle, and between middle and bottom.
if (!chGlue.Exists()) { // null glue : draw a rule
// figure out the dimensions of the rule to be drawn :
// set lbearing to rightmost lbearing among the two current successive parts.
// set lbearing to rightmost lbearing among the two current successive
// parts.
// set rbearing to leftmost rbearing among the two current successive parts.
// this not only satisfies the convention used for over/underbraces
// in TeX, but also takes care of broken fonts like the stretchy integral

Просмотреть файл

@ -30,10 +30,11 @@ enum {
NS_STRETCH_MAXWIDTH = 0x40
};
// A single glyph in our internal representation is characterized by a 'code@font'
// pair. The 'code' is interpreted as a Unicode point or as the direct glyph index
// (depending on the type of nsGlyphTable where this comes from). The 'font' is a
// numeric identifier given to the font to which the glyph belongs.
// A single glyph in our internal representation is characterized by a
// 'code@font' pair. The 'code' is interpreted as a Unicode point or as the
// direct glyph index (depending on the type of nsGlyphTable where this comes
// from). The 'font' is a numeric identifier given to the font to which the
// glyph belongs.
struct nsGlyphCode {
PRUnichar code[2];
PRInt32 font;
@ -54,16 +55,17 @@ struct nsGlyphCode {
}
};
// Class used to handle stretchy symbols (accent, delimiter and boundary symbols).
// 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.
// 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:
@ -79,7 +81,8 @@ public:
mMirrored = false;
}
~nsMathMLChar() { // not a virtual destructor: this class is not intended to be subclassed
// 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
@ -150,7 +153,8 @@ public:
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
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);