diff --git a/gfx/src/xlib/nsFontMetricsXlib.cpp b/gfx/src/xlib/nsFontMetricsXlib.cpp index d708bb5f37fa..a21b8bf0a971 100644 --- a/gfx/src/xlib/nsFontMetricsXlib.cpp +++ b/gfx/src/xlib/nsFontMetricsXlib.cpp @@ -1200,7 +1200,6 @@ void nsFontMetricsXlib::RealizeFont() mDeviceContext->GetDevUnitsToAppUnits(f); nscoord lineSpacing = nscoord((mFontHandle->ascent + mFontHandle->descent) * f); - // XXXldb Shouldn't we get mEmHeight from the metrics? mEmHeight = PR_MAX(1, nscoord(mWesternFont->mSize * f)); if (lineSpacing > mEmHeight) mLeading = lineSpacing - mEmHeight; @@ -1932,6 +1931,9 @@ nsFontXlib::LoadFont(void) ::XDisplayString(aDisplay), mName, (long)xlibFont)); if (xlibFont) { + mMaxAscent = xlibFont->ascent; + mMaxDescent = xlibFont->descent; + if (mCharSetInfo == &ISO106461) { mCCMap = GetMapFor10646Font(xlibFont); if (!mCCMap) { diff --git a/gfx/src/xlib/nsFontMetricsXlib.h b/gfx/src/xlib/nsFontMetricsXlib.h index 200102c23280..865687447359 100644 --- a/gfx/src/xlib/nsFontMetricsXlib.h +++ b/gfx/src/xlib/nsFontMetricsXlib.h @@ -120,6 +120,11 @@ public: PRUint16 mSize; PRInt16 mBaselineAdjust; PRBool mAlreadyCalledLoadFont; + + // these values are not in app units, they need to be scaled with + // nsIDeviceContext::GetDevUnitsToAppUnits() + PRInt16 mMaxAscent; + PRInt16 mMaxDescent; }; class nsFontMetricsXlib : public nsIFontMetrics diff --git a/gfx/src/xlib/nsRenderingContextXlib.cpp b/gfx/src/xlib/nsRenderingContextXlib.cpp index ae6753c4c813..730218e7b2d0 100644 --- a/gfx/src/xlib/nsRenderingContextXlib.cpp +++ b/gfx/src/xlib/nsRenderingContextXlib.cpp @@ -1349,10 +1349,102 @@ FoundFont: return NS_OK; } +NS_IMETHODIMP +nsRenderingContextXlib::GetTextDimensions(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions) +{ + mFontMetrics->GetMaxAscent(aDimensions.ascent); + mFontMetrics->GetMaxDescent(aDimensions.descent); + return GetWidth(aString, aLength, aDimensions.width); +} + +NS_IMETHODIMP +nsRenderingContextXlib::GetTextDimensions(const PRUnichar* aString, PRUint32 aLength, + nsTextDimensions& aDimensions, PRInt32 *aFontID) +{ + PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("nsRenderingContextXlib::GetTextDimensions()\n")); + aDimensions.Clear(); + if (0 < aLength) { + nsFontMetricsXlib* metrics = (nsFontMetricsXlib*) mFontMetrics; + nsFontXlib *prevFont = nsnull; + int rawWidth = 0, rawAscent = 0, rawDescent = 0; + PRUint32 start = 0; + PRUint32 i; + for (i = 0; i < aLength; i++) { + PRUnichar c = aString[i]; + nsFontXlib* currFont = nsnull; + nsFontXlib** font = metrics->mLoadedFonts; + nsFontXlib** end = &metrics->mLoadedFonts[metrics->mLoadedFontsCount]; + while (font < end) { + if (IS_REPRESENTABLE((*font)->mMap, c)) { + currFont = *font; + goto FoundFont; // for speed -- avoid "if" statement + } + font++; + } + currFont = metrics->FindFont(c); +FoundFont: + // XXX avoid this test by duplicating code -- erik + if (prevFont) { + if (currFont != prevFont) { + rawWidth += prevFont->GetWidth(&aString[start], i - start); + if (rawAscent < prevFont->mMaxAscent) + rawAscent = prevFont->mMaxAscent; + if (rawDescent < prevFont->mMaxDescent) + rawDescent = prevFont->mMaxDescent; + prevFont = currFont; + start = i; + } + } + else { + prevFont = currFont; + start = i; + } + } + + if (prevFont) { + rawWidth += prevFont->GetWidth(&aString[start], i - start); + if (rawAscent < prevFont->mMaxAscent) + rawAscent = prevFont->mMaxAscent; + if (rawDescent < prevFont->mMaxDescent) + rawDescent = prevFont->mMaxDescent; + } + + aDimensions.width = NSToCoordRound(rawWidth * mP2T); + aDimensions.ascent = NSToCoordRound(rawAscent * mP2T); + aDimensions.descent = NSToCoordRound(rawDescent * mP2T); + } + if (nsnull != aFontID) + *aFontID = 0; + + return NS_OK; +} + NS_IMETHODIMP nsRenderingContextXlib::DrawString(const char *aString, PRUint32 aLength, nscoord aX, nscoord aY, const nscoord* aSpacing) +{ + nscoord y; + mFontMetrics->GetMaxAscent(y); + return DrawString2(aString, aLength, aX, aY + y, aSpacing); +} + +NS_IMETHODIMP +nsRenderingContextXlib::DrawString(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing) +{ + nscoord y; + mFontMetrics->GetMaxAscent(y); + return DrawString2(aString, aLength, aX, aY + y, aFontID, aSpacing); +} + +NS_IMETHODIMP +nsRenderingContextXlib::DrawString2(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing) { PR_LOG(RenderingContextXlibLM, PR_LOG_DEBUG, ("nsRenderingContextXlib::DrawString()\n")); if (0 != aLength) { @@ -1361,12 +1453,6 @@ nsRenderingContextXlib::DrawString(const char *aString, PRUint32 aLength, nscoord x = aX; nscoord y = aY; - - // Substract xFontStruct ascent since drawing specifies baseline - if (mFontMetrics) { - mFontMetrics->GetMaxAscent(y); - y += aY; - } UpdateGC(); @@ -1454,7 +1540,7 @@ nsRenderingContextXlib::DrawString(const char *aString, PRUint32 aLength, } NS_IMETHODIMP -nsRenderingContextXlib::DrawString(const PRUnichar *aString, PRUint32 aLength, +nsRenderingContextXlib::DrawString2(const PRUnichar *aString, PRUint32 aLength, nscoord aX, nscoord aY, PRInt32 aFontID, const nscoord* aSpacing) @@ -1465,12 +1551,7 @@ nsRenderingContextXlib::DrawString(const PRUnichar *aString, PRUint32 aLength, return NS_ERROR_FAILURE; nscoord x = aX; - nscoord y; - - // Substract xFontStruct ascent since drawing specifies baseline - mFontMetrics->GetMaxAscent(y); - y += aY; - aY = y; + nscoord y = aY; mTranMatrix->TransformCoord(&x, &y); diff --git a/gfx/src/xlib/nsRenderingContextXlib.h b/gfx/src/xlib/nsRenderingContextXlib.h index 690059178bfb..0570e2e92985 100644 --- a/gfx/src/xlib/nsRenderingContextXlib.h +++ b/gfx/src/xlib/nsRenderingContextXlib.h @@ -189,6 +189,18 @@ class nsRenderingContextXlib : public nsRenderingContextImpl PRInt32 aFontID, const nscoord* aSpacing); + NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions); + NS_IMETHOD GetTextDimensions(const PRUnichar *aString, PRUint32 aLength, + nsTextDimensions& aDimensions, PRInt32 *aFontID); + NS_IMETHOD DrawString2(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing); + NS_IMETHOD DrawString2(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing); + NS_IMETHOD DrawImage(nsIImage *aImage, nscoord aX, nscoord aY); NS_IMETHOD DrawImage(nsIImage *aImage, nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);