зеркало из https://github.com/mozilla/pjs.git
support drawing non-BMP characters for stretchy operators (bug 407439). r=karlt
--HG-- extra : rebase_source : 8a0351a8a0b45de4e783050608e513582b8a345c
This commit is contained in:
Родитель
bdf202b283
Коммит
8beebf2153
|
@ -74,7 +74,7 @@ using namespace mozilla;
|
|||
|
||||
// -----------------------------------------------------------------------------------
|
||||
static const PRUnichar kSpaceCh = PRUnichar(' ');
|
||||
static const nsGlyphCode kNullGlyph = {0, 0};
|
||||
static const nsGlyphCode kNullGlyph = {{0, 0}, 0};
|
||||
typedef enum {eExtension_base, eExtension_variants, eExtension_parts}
|
||||
nsMathfontPrefExtension;
|
||||
|
||||
|
@ -248,8 +248,8 @@ private:
|
|||
// 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[2*k] : its Unicode point (or glyph index -- depending on mType),
|
||||
// 2) mGlyphCache[2*k+1] : the numeric identifier of the font where it comes from.
|
||||
// 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.
|
||||
|
@ -311,7 +311,7 @@ nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint
|
|||
// 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[2*k] will later be rendered with mFontName[mGlyphCache[2*k+1]]
|
||||
// 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();
|
||||
|
@ -320,7 +320,7 @@ nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint
|
|||
while (i < length) {
|
||||
PRUnichar code = value[i];
|
||||
++i;
|
||||
PRUnichar font = 0;
|
||||
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
|
||||
|
@ -346,8 +346,18 @@ nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint
|
|||
++i;
|
||||
}
|
||||
#endif
|
||||
// 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);
|
||||
|
||||
// See if an external font is needed for the code point.
|
||||
// Limit of 9 external fonts
|
||||
PRUnichar font = 0;
|
||||
if (i+1 < length && value[i] == PRUnichar('@') &&
|
||||
value[i+1] >= PRUnichar('0') && value[i+1] <= PRUnichar('9')) {
|
||||
++i;
|
||||
|
@ -362,7 +372,6 @@ nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint
|
|||
return kNullGlyph;
|
||||
}
|
||||
}
|
||||
buffer.Append(code);
|
||||
buffer.Append(font);
|
||||
++j;
|
||||
}
|
||||
|
@ -390,14 +399,15 @@ nsGlyphTable::ElementAt(nsPresContext* aPresContext, nsMathMLChar* aChar, PRUint
|
|||
offset += 5; // skip the 4 partial glyphs + the whitespace separator
|
||||
child = child->mSibling;
|
||||
}
|
||||
length = 2*(offset + 4); // stay confined in the 4 partial glyphs of this child
|
||||
length = 3*(offset + 4); // stay confined in the 4 partial glyphs of this child
|
||||
}
|
||||
PRUint32 index = 2*(offset + aPosition); // 2* is to account for the code@font pairs
|
||||
if (index+1 >= length) return kNullGlyph;
|
||||
PRUint32 index = 3*(offset + aPosition); // 3* is to account for the code@font pairs
|
||||
if (index+2 >= length) return kNullGlyph;
|
||||
nsGlyphCode ch;
|
||||
ch.code = mGlyphCache.CharAt(index);
|
||||
ch.font = mGlyphCache.CharAt(index + 1);
|
||||
return (ch.code == PRUnichar(0xFFFD)) ? kNullGlyph : 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;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -409,9 +419,9 @@ nsGlyphTable::IsComposite(nsPresContext* aPresContext, nsMathMLChar* aChar)
|
|||
// 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 (8 >= mGlyphCache.Length()) return PR_FALSE;
|
||||
if (4*3 >= mGlyphCache.Length()) return PR_FALSE;
|
||||
// the lists of glyphs of a composite char are space-separated
|
||||
return (kSpaceCh == mGlyphCache.CharAt(8));
|
||||
return (kSpaceCh == mGlyphCache.CharAt(4*3));
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -1137,11 +1147,13 @@ nsMathMLChar::StretchEnumContext::TryVariants(nsGlyphTable* aGlyphTable,
|
|||
SetFontFamily(mChar->mStyleContext->PresContext(), mRenderingContext,
|
||||
font, aGlyphTable, ch, aFamily);
|
||||
|
||||
NS_ASSERTION(maxWidth || ch.code != mChar->mGlyph.code ||
|
||||
NS_ASSERTION(maxWidth || ch.code[0] != mChar->mGlyph.code[0] ||
|
||||
ch.code[1] != mChar->mGlyph.code[1] ||
|
||||
!font.name.Equals(mChar->mFamily),
|
||||
"glyph table incorrectly set -- duplicate found");
|
||||
|
||||
nsBoundingMetrics bm = mRenderingContext.GetBoundingMetrics(&ch.code, 1);
|
||||
nsBoundingMetrics bm = mRenderingContext.GetBoundingMetrics(ch.code,
|
||||
ch.Length());
|
||||
nscoord charSize =
|
||||
isVertical ? bm.ascent + bm.descent
|
||||
: bm.rightBearing - bm.leftBearing;
|
||||
|
@ -1259,7 +1271,8 @@ nsMathMLChar::StretchEnumContext::TryParts(nsGlyphTable* aGlyphTable,
|
|||
else {
|
||||
SetFontFamily(mChar->mStyleContext->PresContext(), mRenderingContext,
|
||||
font, aGlyphTable, ch, aFamily);
|
||||
nsBoundingMetrics bm = mRenderingContext.GetBoundingMetrics(&ch.code, 1);
|
||||
nsBoundingMetrics bm = mRenderingContext.GetBoundingMetrics(ch.code,
|
||||
ch.Length());
|
||||
|
||||
// TODO: For the generic Unicode table, ideally we should check that the
|
||||
// glyphs are actually found and that they each come from the same
|
||||
|
@ -2063,7 +2076,8 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext,
|
|||
if (mGlyph.Exists()) {
|
||||
//printf("Painting %04X with a glyph of appropriate size\n", mData[0]);
|
||||
//aRenderingContext.SetColor(NS_RGB(0,0,255));
|
||||
aRenderingContext.DrawString(&mGlyph.code, 1, 0, mUnscaledAscent);
|
||||
aRenderingContext.DrawString(mGlyph.code, mGlyph.Length(),
|
||||
0, mUnscaledAscent);
|
||||
}
|
||||
else { // paint by parts
|
||||
//aRenderingContext.SetColor(NS_RGB(0,255,0));
|
||||
|
@ -2153,7 +2167,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
|
|||
if (ch.Exists()) {
|
||||
SetFontFamily(aPresContext, aRenderingContext,
|
||||
aFont, aGlyphTable, ch, mFamily);
|
||||
bmdata[i] = aRenderingContext.GetBoundingMetrics(&ch.code, 1);
|
||||
bmdata[i] = aRenderingContext.GetBoundingMetrics(ch.code, ch.Length());
|
||||
}
|
||||
chdata[i] = ch;
|
||||
++i;
|
||||
|
@ -2238,7 +2252,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
|
|||
AutoPushClipRect clip(aRenderingContext, clipRect);
|
||||
SetFontFamily(aPresContext, aRenderingContext,
|
||||
aFont, aGlyphTable, ch, mFamily);
|
||||
aRenderingContext.DrawString(&ch.code, 1, dx, dy);
|
||||
aRenderingContext.DrawString(ch.code, ch.Length(), dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2314,7 +2328,7 @@ nsMathMLChar::PaintVertically(nsPresContext* aPresContext,
|
|||
clipRect.height = NS_MIN(bm.ascent + bm.descent, fillEnd - dy);
|
||||
AutoPushClipRect clip(aRenderingContext, clipRect);
|
||||
dy += bm.ascent;
|
||||
aRenderingContext.DrawString(&chGlue.code, 1, dx, dy);
|
||||
aRenderingContext.DrawString(chGlue.code, chGlue.Length(), dx, dy);
|
||||
dy += bm.descent;
|
||||
}
|
||||
#ifdef SHOW_BORDERS
|
||||
|
@ -2381,7 +2395,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
|
|||
if (ch.Exists()) {
|
||||
SetFontFamily(aPresContext, aRenderingContext,
|
||||
aFont, aGlyphTable, ch, mFamily);
|
||||
bmdata[i] = aRenderingContext.GetBoundingMetrics(&ch.code, 1);
|
||||
bmdata[i] = aRenderingContext.GetBoundingMetrics(ch.code, ch.Length());
|
||||
}
|
||||
chdata[i] = ch;
|
||||
++i;
|
||||
|
@ -2461,7 +2475,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
|
|||
AutoPushClipRect clip(aRenderingContext, clipRect);
|
||||
SetFontFamily(aPresContext, aRenderingContext,
|
||||
aFont, aGlyphTable, ch, mFamily);
|
||||
aRenderingContext.DrawString(&ch.code, 1, dx, dy);
|
||||
aRenderingContext.DrawString(ch.code, ch.Length(), dx, dy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2536,7 +2550,7 @@ nsMathMLChar::PaintHorizontally(nsPresContext* aPresContext,
|
|||
clipRect.width = NS_MIN(bm.rightBearing - bm.leftBearing, fillEnd - dx);
|
||||
AutoPushClipRect clip(aRenderingContext, clipRect);
|
||||
dx -= bm.leftBearing;
|
||||
aRenderingContext.DrawString(&chGlue.code, 1, dx, dy);
|
||||
aRenderingContext.DrawString(chGlue.code, chGlue.Length(), dx, dy);
|
||||
dx += bm.rightBearing;
|
||||
}
|
||||
#ifdef SHOW_BORDERS
|
||||
|
|
|
@ -71,16 +71,18 @@ enum {
|
|||
// (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;
|
||||
PRUnichar code[2];
|
||||
PRInt32 font;
|
||||
|
||||
PRInt32 Length() { return (code[1] == PRUnichar('\0') ? 1 : 2); }
|
||||
PRBool Exists() const
|
||||
{
|
||||
return (code != 0);
|
||||
return (code[0] != 0);
|
||||
}
|
||||
PRBool operator==(const nsGlyphCode& other) const
|
||||
{
|
||||
return other.code == code && other.font == font;
|
||||
return (other.code[0] == code[0] && other.code[1] == code[1] &&
|
||||
other.font == font);
|
||||
}
|
||||
PRBool operator!=(const nsGlyphCode& other) const
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче