[MATHML] Coded GetItalicSlope() and updated GetBoundingMetrics(). Added code to catch up with recent changes in gfx/src/windows that broke the MathML build on Win32

This commit is contained in:
rbs%maths.uq.edu.au 2000-01-07 14:22:07 +00:00
Родитель 5bf1ba7301
Коммит f8a30ef096
3 изменённых файлов: 269 добавлений и 24 удалений

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

@ -852,8 +852,9 @@ public:
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
const PRUnichar* aString, PRUint32 aLength);
#ifdef MOZ_MATHML
NS_IMETHOD
GetBoundingMetrics(HDC aDC,
virtual nsresult
GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics);
@ -870,8 +871,9 @@ public:
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
const PRUnichar* aString, PRUint32 aLength);
#ifdef MOZ_MATHML
NS_IMETHOD
GetBoundingMetrics(HDC aDC,
virtual nsresult
GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics);
@ -1720,6 +1722,11 @@ HDC dc1 = NULL;
mStrikeoutOffset = NSToCoordRound(oMetrics.otmsStrikeoutPosition * dev2app);
mUnderlineSize = PR_MAX(onePixel, NSToCoordRound(oMetrics.otmsUnderscoreSize * dev2app));
mUnderlineOffset = NSToCoordRound(oMetrics.otmsUnderscorePosition * dev2app);
#ifdef MOZ_MATHML
mItalicSlope = float(oMetrics.otmsCharSlopeRun)/float(oMetrics.otmsCharSlopeRise);
if (oMetrics.otmItalicAngle > 0) mItalicSlope = -mItalicSlope; // back-slanted font
#endif
}
else {
// Make a best-effort guess at extended metrics
@ -1733,6 +1740,15 @@ HDC dc1 = NULL;
mStrikeoutOffset = NSToCoordRound(mXHeight / 2.0f); // 50% of xHeight
mUnderlineSize = onePixel; // XXX this is a guess
mUnderlineOffset = -NSToCoordRound((float)metrics.tmDescent * dev2app * 0.30f); // 30% of descent
#ifdef MOZ_MATHML
mItalicSlope = 0.0f;
if (0 != metrics.tmItalic) { // Italic fonts are usually slanted between 10-20 degrees.
// e.g. for a slant of 10 degrees, the slope is 0.176f
mItalicSlope = float(metrics.tmMaxCharWidth )/float(metrics.tmHeight);
// XXX what about a back-slanted font
}
#endif
}
mHeight = NSToCoordRound(metrics.tmHeight * dev2app);
@ -1757,6 +1773,15 @@ HDC dc1 = NULL;
}
}
#ifdef MOZ_MATHML
NS_IMETHODIMP
nsFontMetricsWin :: GetItalicSlope(float& aResult)
{
aResult = mItalicSlope;
return NS_OK;
}
#endif
NS_IMETHODIMP
nsFontMetricsWin :: GetXHeight(nscoord& aResult)
{
@ -1903,14 +1928,15 @@ nsFontWinUnicode::DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
}
#ifdef MOZ_MATHML
NS_IMETHODIMP
nsresult
nsFontWinUnicode::GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics)
{
aBoundingMetrics.Clear();
if (0 < aLength) {
if (aString && 0 < aLength) {
HFONT oldFont = (HFONT) ::SelectObject(aDC, mFont);
// set glyph transform matrix to identity
@ -1922,16 +1948,18 @@ nsFontWinUnicode::GetBoundingMetrics(HDC aDC,
mat2.eM11 = mat2.eM22 = one;
// measure the string
nscoord descent;
GLYPHMETRICS gm;
DWORD len = GetGlyphOutline(aDC, aString[0], GGO_METRICS, &gm, 0, nsnull, &mat2);
if (GDI_ERROR == len) {
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
aBoundingMetrics.leftBearing = gm.gmptGlyphOrigin.x;
aBoundingMetrics.rightBearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
aBoundingMetrics.descent = gm.gmptGlyphOrigin.y - gm.gmBlackBoxY;
aBoundingMetrics.descent = descent;
aBoundingMetrics.width = gm.gmCellIncX;
}
if (1 < aLength) {
@ -1943,19 +1971,36 @@ nsFontWinUnicode::GetBoundingMetrics(HDC aDC,
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
if (aBoundingMetrics.ascent < gm.gmptGlyphOrigin.y)
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
if (aBoundingMetrics.descent > nscoord(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY))
aBoundingMetrics.descent = gm.gmptGlyphOrigin.y - gm.gmBlackBoxY;
if (aBoundingMetrics.descent > descent)
aBoundingMetrics.descent = descent;
}
}
// get the final rightBearing and width. Possible kerning is taken into account.
SIZE size;
::GetTextExtentPointW(aDC, aString, aLength, &size);
aBoundingMetrics.width = size.cx;
aBoundingMetrics.rightBearing = size.cx - gm.gmCellIncX + gm.gmBlackBoxX;
aBoundingMetrics.rightBearing = size.cx - gm.gmCellIncX + gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
}
// italic correction
if (aItalicSlope) {
ABC abc;
aBoundingMetrics.subItalicCorrection = nscoord(aItalicSlope * float(descent));
if (GetCharABCWidths(aDC, aString[aLength-1], aString[aLength-1], &abc)) {
if (abc.abcC < 0) {
aBoundingMetrics.supItalicCorrection = -abc.abcC;
}
}
if (GetCharABCWidths(aDC, aString[0], aString[0], &abc)) {
if (abc.abcA < 0) {
aBoundingMetrics.leftItalicCorrection = -abc.abcA;
}
}
}
::SelectObject(aDC, oldFont);
}
return NS_OK;
@ -2029,14 +2074,15 @@ nsFontWinNonUnicode::DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
}
#ifdef MOZ_MATHML
NS_IMETHODIMP
nsresult
nsFontWinNonUnicode::GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics)
{
aBoundingMetrics.Clear();
if (mConverter && 0 < aLength) {
if (mConverter && aString && 0 < aLength) {
HFONT oldFont = (HFONT) ::SelectObject(aDC, mFont);
// set glyph transform matrix to identity
@ -2048,16 +2094,18 @@ nsFontWinNonUnicode::GetBoundingMetrics(HDC aDC,
mat2.eM11 = mat2.eM22 = one;
// measure the string
nscoord descent;
GLYPHMETRICS gm;
DWORD len = GetGlyphOutline(aDC, mConverter[aString[0]], GGO_METRICS, &gm, 0, nsnull, &mat2);
if (GDI_ERROR == len) {
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
aBoundingMetrics.leftBearing = gm.gmptGlyphOrigin.x;
aBoundingMetrics.rightBearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
aBoundingMetrics.descent = gm.gmptGlyphOrigin.y - gm.gmBlackBoxY;
aBoundingMetrics.descent = descent;
aBoundingMetrics.width = gm.gmCellIncX;
}
if (1 < aLength) {
@ -2069,10 +2117,11 @@ nsFontWinNonUnicode::GetBoundingMetrics(HDC aDC,
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
if (aBoundingMetrics.ascent < gm.gmptGlyphOrigin.y)
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
if (aBoundingMetrics.descent > nscoord(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY))
aBoundingMetrics.descent = gm.gmptGlyphOrigin.y - gm.gmBlackBoxY;
if (aBoundingMetrics.descent > descent)
aBoundingMetrics.descent = descent;
}
}
// get the final rightBearing and width. Possible kerning is taken into account.
@ -2094,6 +2143,22 @@ nsFontWinNonUnicode::GetBoundingMetrics(HDC aDC,
}
}
// italic correction
if (aItalicSlope) {
aBoundingMetrics.subItalicCorrection = nscoord(aItalicSlope * float(descent));
ABC abc;
if (GetCharABCWidths(aDC, mConverter[aString[aLength-1]], mConverter[aString[aLength-1]], &abc)) {
if (abc.abcC < 0) {
aBoundingMetrics.supItalicCorrection = -abc.abcC;
}
}
if (GetCharABCWidths(aDC, mConverter[aString[0]], mConverter[aString[0]], &abc)) {
if (abc.abcA < 0) {
aBoundingMetrics.leftItalicCorrection = -abc.abcA;
}
}
}
::SelectObject(aDC, oldFont);
}
return NS_OK;
@ -2655,6 +2720,109 @@ nsFontSubset::DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
}
}
#ifdef MOZ_MATHML
nsresult
nsFontSubset::GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics)
{
aBoundingMetrics.Clear();
if (aString && 0 < aLength) {
char str[CHAR_BUFFER_SIZE];
char* pstr = str;
// Get number of bytes to needed for the conversion
int nb;
nb = WideCharToMultiByte(mCodePage, 0, aString, aLength,
pstr, 0, nsnull, nsnull);
if (!nb) return NS_ERROR_UNEXPECTED;
if (nb > CHAR_BUFFER_SIZE) {
pstr = new char[nb];
if (!pstr) return NS_ERROR_OUT_OF_MEMORY;
}
// Convert the string Unicode to ANSI
nb = WideCharToMultiByte(mCodePage, 0, aString, aLength,
pstr, nb, nsnull, nsnull);
if (!nb) return NS_ERROR_UNEXPECTED;
nb--; //ignore the null terminator
HFONT oldFont = (HFONT) ::SelectObject(aDC, mFont);
// set glyph transform matrix to identity
MAT2 mat2;
FIXED zero, one;
zero.fract = 0; one.fract = 0;
zero.value = 0; one.value = 1;
mat2.eM12 = mat2.eM21 = zero;
mat2.eM11 = mat2.eM22 = one;
// measure the string
nscoord descent;
GLYPHMETRICS gm;
DWORD len = GetGlyphOutline(aDC, pstr[0], GGO_METRICS, &gm, 0, nsnull, &mat2);
if (GDI_ERROR == len) {
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
aBoundingMetrics.leftBearing = gm.gmptGlyphOrigin.x;
aBoundingMetrics.rightBearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
aBoundingMetrics.descent = descent;
aBoundingMetrics.width = gm.gmCellIncX;
}
if (1 < nb) {
// loop over each glyph to get the ascent and descent
int i;
for (i = 1; i < nb; i++) {
len = GetGlyphOutline(aDC, pstr[i], GGO_METRICS, &gm, 0, nsnull, &mat2);
if (GDI_ERROR == len) {
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
if (aBoundingMetrics.ascent < gm.gmptGlyphOrigin.y)
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
if (aBoundingMetrics.descent > descent)
aBoundingMetrics.descent = descent;
}
}
// get the final rightBearing and width. Possible kerning is taken into account.
SIZE size;
::GetTextExtentPointA(aDC, pstr, aLength, &size);
aBoundingMetrics.width = size.cx;
aBoundingMetrics.rightBearing = size.cx - gm.gmCellIncX + gm.gmBlackBoxX;
}
// italic correction
if (aItalicSlope) {
aBoundingMetrics.subItalicCorrection = nscoord(aItalicSlope * float(descent));
ABC abc;
if (GetCharABCWidths(aDC, pstr[nb-1], pstr[nb-1], &abc)) {
if (abc.abcC < 0) {
aBoundingMetrics.supItalicCorrection = -abc.abcC;
}
}
if (GetCharABCWidths(aDC, pstr[0], pstr[0], &abc)) {
if (abc.abcA < 0) {
aBoundingMetrics.leftItalicCorrection = -abc.abcA;
}
}
}
if (pstr != str) {
delete[] pstr;
}
::SelectObject(aDC, oldFont);
}
return NS_OK;
}
#endif
nsFontWinA::nsFontWinA(LOGFONT* aLogFont, HFONT aFont, PRUint8* aMap)
: nsFontWin(aLogFont, aFont, aMap)
{
@ -2692,6 +2860,19 @@ nsFontWinA::DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
NS_ASSERTION(0, "must call nsFontSubset's DrawString");
}
#ifdef MOZ_MATHML
nsresult
nsFontWinA::GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics)
{
NS_ASSERTION(0, "must call nsFontSubset's GetBoundingMetrics");
return NS_ERROR_FAILURE;
}
#endif
nsFontWin*
nsFontMetricsWinA::LoadFont(HDC aDC, nsString* aName)
{

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

@ -55,8 +55,9 @@ public:
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
const PRUnichar* aString, PRUint32 aLength) = 0;
#ifdef MOZ_MATHML
NS_IMETHOD
virtual nsresult
GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics) = 0;
@ -90,6 +91,9 @@ public:
nsIDeviceContext* aContext);
NS_IMETHOD Destroy();
#ifdef MOZ_MATHML
NS_IMETHOD GetItalicSlope(float& aResult);
#endif
NS_IMETHOD GetXHeight(nscoord& aResult);
NS_IMETHOD GetSuperscriptOffset(nscoord& aResult);
NS_IMETHOD GetSubscriptOffset(nscoord& aResult);
@ -128,7 +132,7 @@ public:
int mTriedAllGenerics;
nsCOMPtr<nsIAtom> mLangGroup;
nscoord mSpaceWidth;
nscoord mSpaceWidth;
static nsGlobalFont* gGlobalFonts;
static int gGlobalFontsCount;
@ -174,6 +178,9 @@ protected:
nscoord mMaxAscent;
nscoord mMaxDescent;
nscoord mMaxAdvance;
#ifdef MOZ_MATHML
float mItalicSlope;
#endif
nscoord mXHeight;
nscoord mSuperscriptOffset;
nscoord mSubscriptOffset;
@ -213,6 +220,15 @@ public:
PRUint32 aLength);
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
const PRUnichar* aString, PRUint32 aLength);
#ifdef MOZ_MATHML
virtual nsresult
GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics);
#endif
int Load(nsFontWinA* aFont);
BYTE mCharSet;
@ -228,6 +244,15 @@ public:
PRUint32 aLength);
virtual void DrawString(HDC aDC, PRInt32 aX, PRInt32 aY,
const PRUnichar* aString, PRUint32 aLength);
#ifdef MOZ_MATHML
virtual nsresult
GetBoundingMetrics(HDC aDC,
float aItalicSlope,
const PRUnichar* aString,
PRUint32 aLength,
nsBoundingMetrics& aBoundingMetrics);
#endif
int GetSubsets(HDC aDC);
LOGFONT mLogFont;

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

@ -1950,7 +1950,7 @@ nsRenderingContextWin::GetBoundingMetrics(const char* aString,
aBoundingMetrics.Clear();
if (!mFontMetrics)
return NS_ERROR_FAILURE;
else if (0 < aLength) {
else if (aString && 0 < aLength) {
SetupFontAndColor();
// set glyph transform matrix to identity
@ -1962,12 +1962,14 @@ nsRenderingContextWin::GetBoundingMetrics(const char* aString,
mat2.eM11 = mat2.eM22 = one;
// measure the string
nscoord descent;
GLYPHMETRICS gm;
DWORD len = GetGlyphOutline(mDC, aString[0], GGO_METRICS, &gm, 0, nsnull, &mat2);
if (GDI_ERROR == len) {
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
aBoundingMetrics.leftBearing = gm.gmptGlyphOrigin.x;
aBoundingMetrics.rightBearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
@ -1983,10 +1985,11 @@ nsRenderingContextWin::GetBoundingMetrics(const char* aString,
return NS_ERROR_UNEXPECTED;
}
else {
descent = nscoord(gm.gmptGlyphOrigin.y) - nscoord(gm.gmBlackBoxY);
if (aBoundingMetrics.ascent < gm.gmptGlyphOrigin.y)
aBoundingMetrics.ascent = gm.gmptGlyphOrigin.y;
if (aBoundingMetrics.descent > nscoord(gm.gmptGlyphOrigin.y - gm.gmBlackBoxY))
aBoundingMetrics.descent = gm.gmptGlyphOrigin.y - gm.gmBlackBoxY;
if (aBoundingMetrics.descent > descent)
aBoundingMetrics.descent = descent;
}
}
// get the final rightBearing and width. Possible kerning is taken into account.
@ -1995,6 +1998,35 @@ nsRenderingContextWin::GetBoundingMetrics(const char* aString,
aBoundingMetrics.width = size.cx;
aBoundingMetrics.rightBearing = size.cx - gm.gmCellIncX + gm.gmBlackBoxX;
}
// italic correction
float aItalicSlope;
mFontMetrics->GetItalicSlope(aItalicSlope);
if (aItalicSlope) {
aBoundingMetrics.subItalicCorrection = nscoord(aItalicSlope * float(descent));
ABC abc;
if (GetCharABCWidths(mDC, aString[aLength-1], aString[aLength-1], &abc)) {
if (abc.abcC < 0) {
aBoundingMetrics.supItalicCorrection = -abc.abcC;
}
}
if (GetCharABCWidths(mDC, aString[0], aString[0], &abc)) {
if (abc.abcA < 0) {
aBoundingMetrics.leftItalicCorrection = -abc.abcA;
}
}
}
// convert to app units
aBoundingMetrics.leftBearing = NSToCoordRound(float(aBoundingMetrics.leftBearing) * mP2T);
aBoundingMetrics.rightBearing = NSToCoordRound(float(aBoundingMetrics.rightBearing) * mP2T);
aBoundingMetrics.width = NSToCoordRound(float(aBoundingMetrics.width) * mP2T);
aBoundingMetrics.ascent = NSToCoordRound(float(aBoundingMetrics.ascent) * mP2T);
aBoundingMetrics.descent = NSToCoordRound(float(aBoundingMetrics.descent) * mP2T);
aBoundingMetrics.subItalicCorrection = NSToCoordRound(float(aBoundingMetrics.subItalicCorrection) * mP2T);
aBoundingMetrics.supItalicCorrection = NSToCoordRound(float(aBoundingMetrics.supItalicCorrection) * mP2T);
aBoundingMetrics.leftItalicCorrection = NSToCoordRound(float(aBoundingMetrics.leftItalicCorrection) * mP2T);
}
return NS_OK;
}
@ -2010,12 +2042,15 @@ nsRenderingContextWin::GetBoundingMetrics(const PRUnichar* aString,
aBoundingMetrics.Clear();
if (!mFontMetrics)
return NS_ERROR_FAILURE;
else if (0 < aLength) {
else if (aString && 0 < aLength) {
nsFontMetricsWin* metrics = (nsFontMetricsWin*) mFontMetrics;
nsFontWin* prevFont = nsnull;
SetupFontAndColor();
float italicSlope;
mFontMetrics->GetItalicSlope(italicSlope);
nsBoundingMetrics rawbm;
PRBool firstTime = PR_TRUE;
PRUint32 start = 0;
@ -2036,7 +2071,7 @@ FoundFont:
// XXX avoid this test by duplicating code
if (prevFont) {
if (currFont != prevFont) {
rv = prevFont->GetBoundingMetrics(mDC, &aString[start], i - start, rawbm);
rv = prevFont->GetBoundingMetrics(mDC, italicSlope, &aString[start], i - start, rawbm);
if (NS_FAILED(rv)) return rv;
if (firstTime) {
firstTime = PR_FALSE;
@ -2056,7 +2091,7 @@ FoundFont:
}
if (prevFont) {
rv = prevFont->GetBoundingMetrics(mDC, &aString[start], i - start, rawbm);
rv = prevFont->GetBoundingMetrics(mDC, italicSlope, &aString[start], i - start, rawbm);
if (NS_FAILED(rv)) return rv;
if (firstTime)
aBoundingMetrics = rawbm;
@ -2070,6 +2105,10 @@ FoundFont:
aBoundingMetrics.width = NSToCoordRound(float(aBoundingMetrics.width) * mP2T);
aBoundingMetrics.ascent = NSToCoordRound(float(aBoundingMetrics.ascent) * mP2T);
aBoundingMetrics.descent = NSToCoordRound(float(aBoundingMetrics.descent) * mP2T);
aBoundingMetrics.subItalicCorrection = NSToCoordRound(float(aBoundingMetrics.subItalicCorrection) * mP2T);
aBoundingMetrics.supItalicCorrection = NSToCoordRound(float(aBoundingMetrics.supItalicCorrection) * mP2T);
aBoundingMetrics.leftItalicCorrection = NSToCoordRound(float(aBoundingMetrics.leftItalicCorrection) * mP2T);
}
if (nsnull != aFontID)
*aFontID = 0;