diff --git a/mozilla/gfx/public/nsIRenderingContext.h b/mozilla/gfx/public/nsIRenderingContext.h index 991d04ebc6d..ac803e79fb8 100644 --- a/mozilla/gfx/public/nsIRenderingContext.h +++ b/mozilla/gfx/public/nsIRenderingContext.h @@ -823,8 +823,6 @@ public: * right-to-left base direction */ NS_IMETHOD SetRightToLeftText(PRBool aIsRTL) = 0; - - NS_IMETHOD GetRightToLeftText(PRBool* aIsRTL) = 0; /** * Draw a portion of an image, scaling it to fit within a specified rect. diff --git a/mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp b/mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp index 86df6480e0d..5947c83d948 100644 --- a/mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp +++ b/mozilla/gfx/src/gtk/nsFontMetricsGTK.cpp @@ -1736,6 +1736,10 @@ void nsFontMetricsGTK::RealizeFont() mMaxDescent = nscoord(ft->max_descent() * f); mMaxAdvance = nscoord(ft->max_width() * f); + // X may screw up if we try to measure/draw more than 32767 pixels in + // one operation + mMaxStringLength = (PRInt32)floor(32767.0/ft->max_width()); + mMaxStringLength = PR_MAX(1, mMaxStringLength); // 56% of ascent, best guess for non-true type mXHeight = NSToCoordRound((float) ft->ascent()* f * 0.56f); @@ -1818,6 +1822,10 @@ void nsFontMetricsGTK::RealizeFont() mEmDescent = mEmHeight - mEmAscent; mMaxAdvance = nscoord(fontInfo->max_bounds.width * f); + // X may screw up if we try to measure/draw more than 32767 pixels in + // one operation. + mMaxStringLength = (PRInt32)floor(32767.0/fontInfo->max_bounds.width); + mMaxStringLength = PR_MAX(1, mMaxStringLength); gint rawWidth, rawAverage; if ((fontInfo->min_byte1 == 0) && (fontInfo->max_byte1 == 0)) { @@ -2010,6 +2018,11 @@ NS_IMETHODIMP nsFontMetricsGTK::GetAveCharWidth(nscoord &aAveCharWidth) return NS_OK; } +PRInt32 nsFontMetricsGTK::GetMaxStringLength() +{ + return mMaxStringLength; +} + NS_IMETHODIMP nsFontMetricsGTK::GetLangGroup(nsIAtom** aLangGroup) { if (!aLangGroup) { diff --git a/mozilla/gfx/src/gtk/nsFontMetricsGTK.h b/mozilla/gfx/src/gtk/nsFontMetricsGTK.h index 8f3d45c6cf5..ab522cba033 100644 --- a/mozilla/gfx/src/gtk/nsFontMetricsGTK.h +++ b/mozilla/gfx/src/gtk/nsFontMetricsGTK.h @@ -255,6 +255,7 @@ public: NS_IMETHOD GetMaxDescent(nscoord &aDescent); NS_IMETHOD GetMaxAdvance(nscoord &aAdvance); NS_IMETHOD GetAveCharWidth(nscoord &aAveCharWidth); + virtual PRInt32 GetMaxStringLength(); NS_IMETHOD GetLangGroup(nsIAtom** aLangGroup); NS_IMETHOD GetFontHandle(nsFontHandle &aHandle); @@ -417,6 +418,7 @@ protected: nscoord mUnderlineOffset; nscoord mSpaceWidth; nscoord mAveCharWidth; + PRInt32 mMaxStringLength; PRUint16 mPixelSize; PRUint8 mStretchIndex; diff --git a/mozilla/gfx/src/gtk/nsFontMetricsPango.cpp b/mozilla/gfx/src/gtk/nsFontMetricsPango.cpp index 2c81c064dc8..457680c0c21 100644 --- a/mozilla/gfx/src/gtk/nsFontMetricsPango.cpp +++ b/mozilla/gfx/src/gtk/nsFontMetricsPango.cpp @@ -322,6 +322,10 @@ nsFontMetricsPango::CacheFontMetrics(void) // mMaxAdvance val = MOZ_FT_TRUNC(face->size->metrics.max_advance); mMaxAdvance = NSToIntRound(val * f); + // X may screw up if we try to measure/draw more than 32767 pixels in + // one operation. + mMaxStringLength = (PRInt32)floor(32767.0/val); + mMaxStringLength = PR_MAX(1, mMaxStringLength); // mPangoSpaceWidth PangoLayout *layout = pango_layout_new(mPangoContext); diff --git a/mozilla/gfx/src/gtk/nsFontMetricsPango.h b/mozilla/gfx/src/gtk/nsFontMetricsPango.h index 0cca56d2890..743899109f6 100644 --- a/mozilla/gfx/src/gtk/nsFontMetricsPango.h +++ b/mozilla/gfx/src/gtk/nsFontMetricsPango.h @@ -134,6 +134,8 @@ public: { aAveCharWidth = mAveCharWidth; return NS_OK; }; + PRInt32 GetMaxStringLength() { return mMaxStringLength; } + // nsIFontMetricsGTK (calls from the font rendering layer) virtual nsresult GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth, @@ -263,6 +265,7 @@ private: nscoord mSpaceWidth; nscoord mPangoSpaceWidth; nscoord mAveCharWidth; + PRInt32 mMaxStringLength; // Private methods nsresult RealizeFont(void); diff --git a/mozilla/gfx/src/gtk/nsFontMetricsXft.cpp b/mozilla/gfx/src/gtk/nsFontMetricsXft.cpp index f1f0c2eeb11..4c4a4b5f46f 100644 --- a/mozilla/gfx/src/gtk/nsFontMetricsXft.cpp +++ b/mozilla/gfx/src/gtk/nsFontMetricsXft.cpp @@ -852,6 +852,10 @@ nsFontMetricsXft::CacheFontMetrics(void) // mMaxAdvance mMaxAdvance = nscoord(xftFont->max_advance_width * f); + // X may screw up if we try to measure/draw more than 32767 pixels in + // one operation. + mMaxStringLength = (PRInt32)floor(32767.0/xftFont->max_advance_width); + mMaxStringLength = PR_MAX(1, mMaxStringLength); // mSpaceWidth (width of a space) gint rawWidth; diff --git a/mozilla/gfx/src/gtk/nsFontMetricsXft.h b/mozilla/gfx/src/gtk/nsFontMetricsXft.h index b74f14d5b4c..a9c5a5f28c9 100644 --- a/mozilla/gfx/src/gtk/nsFontMetricsXft.h +++ b/mozilla/gfx/src/gtk/nsFontMetricsXft.h @@ -143,6 +143,8 @@ public: { aAveCharWidth = mAveCharWidth; return NS_OK; }; + PRInt32 GetMaxStringLength() { return mMaxStringLength; } + // nsIFontMetricsGTK (calls from the font rendering layer) virtual nsresult GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth, @@ -336,6 +338,7 @@ private: nscoord mMaxAdvance; nscoord mSpaceWidth; nscoord mAveCharWidth; + PRInt32 mMaxStringLength; }; class nsFontEnumeratorXft : public nsIFontEnumerator diff --git a/mozilla/gfx/src/gtk/nsIFontMetricsGTK.h b/mozilla/gfx/src/gtk/nsIFontMetricsGTK.h index acce63822d9..3499c2e5a94 100644 --- a/mozilla/gfx/src/gtk/nsIFontMetricsGTK.h +++ b/mozilla/gfx/src/gtk/nsIFontMetricsGTK.h @@ -144,7 +144,7 @@ public: PRUint32 aStart, PRUint32 aEnd, PRUint32 &aWidth) = 0; - + virtual PRInt32 GetMaxStringLength() = 0; }; #endif /* __nsIFontMetricsGTK_h */ diff --git a/mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp b/mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp index ab693bcdd90..75cf5a01b81 100644 --- a/mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp +++ b/mozilla/gfx/src/gtk/nsRenderingContextGTK.cpp @@ -1219,21 +1219,8 @@ nsRenderingContextGTK::GetWidth(PRUnichar aC, nscoord& aWidth, } NS_IMETHODIMP -nsRenderingContextGTK::GetWidth(const nsString& aString, - nscoord& aWidth, PRInt32* aFontID) -{ - return GetWidth(aString.get(), aString.Length(), aWidth, aFontID); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetWidth(const char* aString, nscoord& aWidth) -{ - return GetWidth(aString, strlen(aString), aWidth); -} - -NS_IMETHODIMP -nsRenderingContextGTK::GetWidth(const char* aString, PRUint32 aLength, - nscoord& aWidth) +nsRenderingContextGTK::GetWidthInternal(const char* aString, PRUint32 aLength, + nscoord& aWidth) { if (0 == aLength) { aWidth = 0; @@ -1246,8 +1233,8 @@ nsRenderingContextGTK::GetWidth(const char* aString, PRUint32 aLength, } NS_IMETHODIMP -nsRenderingContextGTK::GetWidth(const PRUnichar* aString, PRUint32 aLength, - nscoord& aWidth, PRInt32* aFontID) +nsRenderingContextGTK::GetWidthInternal(const PRUnichar* aString, PRUint32 aLength, + nscoord& aWidth, PRInt32* aFontID) { if (0 == aLength) { aWidth = 0; @@ -1260,8 +1247,8 @@ nsRenderingContextGTK::GetWidth(const PRUnichar* aString, PRUint32 aLength, } NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensions(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions) +nsRenderingContextGTK::GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions) { mFontMetrics->GetMaxAscent(aDimensions.ascent); mFontMetrics->GetMaxDescent(aDimensions.descent); @@ -1269,25 +1256,25 @@ nsRenderingContextGTK::GetTextDimensions(const char* aString, PRUint32 aLength, } NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID) +nsRenderingContextGTK::GetTextDimensionsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsTextDimensions& aDimensions, + PRInt32* aFontID) { return mFontMetrics->GetTextDimensions(aString, aLength, aDimensions, aFontID, this); } NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) +nsRenderingContextGTK::GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) { return mFontMetrics->GetTextDimensions(aString, aLength, aAvailWidth, aBreaks, aNumBreaks, aDimensions, @@ -1296,15 +1283,15 @@ nsRenderingContextGTK::GetTextDimensions(const char* aString, this); } NS_IMETHODIMP -nsRenderingContextGTK::GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) +nsRenderingContextGTK::GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) { return mFontMetrics->GetTextDimensions(aString, aLength, aAvailWidth, aBreaks, aNumBreaks, aDimensions, @@ -1314,34 +1301,24 @@ nsRenderingContextGTK::GetTextDimensions(const PRUnichar* aString, } NS_IMETHODIMP -nsRenderingContextGTK::DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing) +nsRenderingContextGTK::DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing) { return mFontMetrics->DrawString(aString, aLength, aX, aY, aSpacing, this, mSurface); } NS_IMETHODIMP -nsRenderingContextGTK::DrawString(const PRUnichar* aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) +nsRenderingContextGTK::DrawStringInternal(const PRUnichar* aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing) { return mFontMetrics->DrawString(aString, aLength, aX, aY, aFontID, aSpacing, this, mSurface); } -NS_IMETHODIMP -nsRenderingContextGTK::DrawString(const nsString& aString, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) -{ - return DrawString(aString.get(), aString.Length(), - aX, aY, aFontID, aSpacing); -} - NS_IMETHODIMP nsRenderingContextGTK::CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, @@ -1424,19 +1401,19 @@ nsRenderingContextGTK::CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, #ifdef MOZ_MATHML NS_IMETHODIMP -nsRenderingContextGTK::GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) +nsRenderingContextGTK::GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics) { return mFontMetrics->GetBoundingMetrics(aString, aLength, aBoundingMetrics, this); } NS_IMETHODIMP -nsRenderingContextGTK::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID) +nsRenderingContextGTK::GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID) { return mFontMetrics->GetBoundingMetrics(aString, aLength, aBoundingMetrics, aFontID, this); @@ -1455,6 +1432,13 @@ NS_IMETHODIMP nsRenderingContextGTK::GetRightToLeftText(PRBool* aIsRTL) return NS_OK; } +PRInt32 nsRenderingContextGTK::GetMaxStringLength() +{ + if (!mFontMetrics) + return 1; + return mFontMetrics->GetMaxStringLength(); +} + NS_IMETHODIMP nsRenderingContextGTK::GetClusterInfo(const PRUnichar *aText, PRUint32 aLength, PRUint8 *aClusterStarts) diff --git a/mozilla/gfx/src/gtk/nsRenderingContextGTK.h b/mozilla/gfx/src/gtk/nsRenderingContextGTK.h index b0ce0c5d115..f2fb4e3f7a8 100644 --- a/mozilla/gfx/src/gtk/nsRenderingContextGTK.h +++ b/mozilla/gfx/src/gtk/nsRenderingContextGTK.h @@ -145,49 +145,80 @@ public: NS_IMETHOD FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, float aStartAngle, float aEndAngle); + NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, + PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aWidth, aFontID); } + NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aWidth); } + NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, + nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth); } + NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth, aFontID); } + NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, + PRInt32 aFontID = -1, + const nscoord* aSpacing = nsnull) + { return nsRenderingContextImpl::DrawString(aString, aX, aY, aFontID, aSpacing); } + NS_IMETHOD GetWidth(char aC, nscoord &aWidth); NS_IMETHOD GetWidth(PRUnichar aC, nscoord &aWidth, PRInt32 *aFontID); - NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, - PRInt32 *aFontID); - NS_IMETHOD GetWidth(const char *aString, nscoord &aWidth); - NS_IMETHOD GetWidth(const char *aString, PRUint32 aLength, nscoord &aWidth); - NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, - PRInt32 *aFontID); + + NS_IMETHOD GetWidthInternal(const char *aString, PRUint32 aLength, nscoord &aWidth); + NS_IMETHOD GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, + PRInt32 *aFontID); - NS_IMETHOD DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing); - NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); - NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); + NS_IMETHOD DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing); + NS_IMETHOD DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + 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 GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID); - NS_IMETHOD GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID); + NS_IMETHOD GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar *aString, PRUint32 aLength, + nsTextDimensions& aDimensions,PRInt32 *aFontID); + NS_IMETHOD GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + +#ifdef MOZ_MATHML + /** + * Returns metrics (in app units) of an 8-bit character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics); + + /** + * Returns metrics (in app units) of a Unicode character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID = nsnull); + +#endif /* MOZ_MATHML */ + + virtual PRInt32 GetMaxStringLength(); NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, const nsRect &aDestBounds, PRUint32 aCopyFlags); @@ -215,24 +246,6 @@ public: PRBool aForBlending, nsIDrawingSurface* &aBackbuffer); NS_IMETHOD ReleaseBackbuffer(void); -#ifdef MOZ_MATHML - /** - * Returns metrics (in app units) of an 8-bit character string - */ - NS_IMETHOD GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); - - /** - * Returns metrics (in app units) of a Unicode character string - */ - NS_IMETHOD GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID = nsnull); - -#endif /* MOZ_MATHML */ - //locals NS_IMETHOD CommonInit(); diff --git a/mozilla/gfx/src/mac/nsFontMetricsMac.h b/mozilla/gfx/src/mac/nsFontMetricsMac.h index 5b9bdacc1b7..9f949f11f9b 100644 --- a/mozilla/gfx/src/mac/nsFontMetricsMac.h +++ b/mozilla/gfx/src/mac/nsFontMetricsMac.h @@ -83,6 +83,8 @@ public: NS_IMETHOD GetLangGroup(nsIAtom** aLangGroup); NS_IMETHOD GetFontHandle(nsFontHandle& aHandle); NS_IMETHOD GetSpaceWidth(nscoord& aSpaceCharWidth); + // No known string length limits on Mac + virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; } nsUnicodeFontMappingMac* GetUnicodeFontMapping(); diff --git a/mozilla/gfx/src/mac/nsRenderingContextMac.cpp b/mozilla/gfx/src/mac/nsRenderingContextMac.cpp index 7910eede6c4..8da4c55735b 100644 --- a/mozilla/gfx/src/mac/nsRenderingContextMac.cpp +++ b/mozilla/gfx/src/mac/nsRenderingContextMac.cpp @@ -1225,6 +1225,13 @@ NS_IMETHODIMP nsRenderingContextMac::FillArc(nscoord aX, nscoord aY, nscoord aWi return NS_OK; } +PRInt32 nsRenderingContextMac::GetMaxStringLength() +{ + if (!mGS->mFontMetrics) + return 1; + return NS_STATIC_CAST(nsFontMetricsMac*, mGS->mFontMetrics)->GetMaxStringLength(); +} + #pragma mark - //------------------------------------------------------------------------ @@ -1254,22 +1261,8 @@ NS_IMETHODIMP nsRenderingContextMac::GetWidth(PRUnichar ch, nscoord &aWidth, PRI //------------------------------------------------------------------------ -NS_IMETHODIMP nsRenderingContextMac::GetWidth(const nsString& aString, nscoord &aWidth, PRInt32 *aFontID) -{ - return GetWidth(aString.get(), aString.Length(), aWidth, aFontID); -} - -//------------------------------------------------------------------------ - -NS_IMETHODIMP nsRenderingContextMac::GetWidth(const char *aString, nscoord &aWidth) -{ - return GetWidth(aString, strlen(aString), aWidth); -} - -//------------------------------------------------------------------------ - NS_IMETHODIMP -nsRenderingContextMac::GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth) +nsRenderingContextMac::GetWidthInternal(const char* aString, PRUint32 aLength, nscoord& aWidth) { SetupPortState(); @@ -1288,7 +1281,7 @@ nsRenderingContextMac::GetWidth(const char* aString, PRUint32 aLength, nscoord& //------------------------------------------------------------------------ -NS_IMETHODIMP nsRenderingContextMac::GetWidth(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, PRInt32 *aFontID) +NS_IMETHODIMP nsRenderingContextMac::GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, PRInt32 *aFontID) { SetupPortState(); @@ -1308,8 +1301,8 @@ NS_IMETHODIMP nsRenderingContextMac::GetWidth(const PRUnichar *aString, PRUint32 //------------------------------------------------------------------------ NS_IMETHODIMP -nsRenderingContextMac::GetTextDimensions(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions) +nsRenderingContextMac::GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions) { nsresult rv= GetWidth(aString, aLength, aDimensions.width); if (NS_SUCCEEDED(rv) && (mGS->mFontMetrics)) @@ -1321,8 +1314,8 @@ nsRenderingContextMac::GetTextDimensions(const char* aString, PRUint32 aLength, } NS_IMETHODIMP -nsRenderingContextMac::GetTextDimensions(const PRUnichar* aString, PRUint32 aLength, - nsTextDimensions& aDimensions, PRInt32* aFontID) +nsRenderingContextMac::GetTextDimensionsInternal(const PRUnichar* aString, PRUint32 aLength, + nsTextDimensions& aDimensions, PRInt32* aFontID) { SetupPortState(); @@ -1342,9 +1335,9 @@ nsRenderingContextMac::GetTextDimensions(const PRUnichar* aString, PRUint32 aLen #pragma mark - //------------------------------------------------------------------------ -NS_IMETHODIMP nsRenderingContextMac::DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing) +NS_IMETHODIMP nsRenderingContextMac::DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing) { SetupPortState(); @@ -1389,9 +1382,9 @@ NS_IMETHODIMP nsRenderingContextMac::DrawString(const char *aString, PRUint32 aL //------------------------------------------------------------------------ -NS_IMETHODIMP nsRenderingContextMac::DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, PRInt32 aFontID, - const nscoord* aSpacing) +NS_IMETHODIMP nsRenderingContextMac::DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, PRInt32 aFontID, + const nscoord* aSpacing) { SetupPortState(); @@ -1413,15 +1406,6 @@ NS_IMETHODIMP nsRenderingContextMac::DrawString(const PRUnichar *aString, PRUint return rv; } -//------------------------------------------------------------------------ - -NS_IMETHODIMP nsRenderingContextMac::DrawString(const nsString& aString, - nscoord aX, nscoord aY, PRInt32 aFontID, - const nscoord* aSpacing) -{ - return DrawString(aString.get(), aString.Length(), aX, aY, aFontID, aSpacing); -} - #pragma mark - //------------------------------------------------------------------------ @@ -1465,18 +1449,18 @@ nsRenderingContextMac::FlushRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord #ifdef MOZ_MATHML NS_IMETHODIMP -nsRenderingContextMac::GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) +nsRenderingContextMac::GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -nsRenderingContextMac::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID) +nsRenderingContextMac::GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID) { SetupPortState(); diff --git a/mozilla/gfx/src/mac/nsRenderingContextMac.h b/mozilla/gfx/src/mac/nsRenderingContextMac.h index c8ff8dc2f06..7e8359dcea9 100644 --- a/mozilla/gfx/src/mac/nsRenderingContextMac.h +++ b/mozilla/gfx/src/mac/nsRenderingContextMac.h @@ -121,27 +121,81 @@ public: NS_IMETHOD DrawArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,float aStartAngle, float aEndAngle); NS_IMETHOD FillArc(const nsRect& aRect,float aStartAngle, float aEndAngle); NS_IMETHOD FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,float aStartAngle, float aEndAngle); + + NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, + PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aWidth, aFontID); } + NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aWidth); } + NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, + nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth); } + NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth, aFontID); } + NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, + PRInt32 aFontID = -1, + const nscoord* aSpacing = nsnull) + { return nsRenderingContextImpl::DrawString(aString, aX, aY, aFontID, aSpacing); } + NS_IMETHOD GetWidth(char aC, nscoord &aWidth); NS_IMETHOD GetWidth(PRUnichar aC, nscoord &aWidth, PRInt32 *aFontID); - NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, - PRInt32 *aFontID); - NS_IMETHOD GetWidth(const char *aString, nscoord &aWidth); - NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth); - NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, - PRInt32 *aFontID); - NS_IMETHOD DrawString(const char *aString, PRUint32 aLength,nscoord aX, nscoord aY,const nscoord* aSpacing); - NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); - NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); + + NS_IMETHOD GetWidthInternal(const char *aString, PRUint32 aLength, nscoord &aWidth); + NS_IMETHOD GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, + PRInt32 *aFontID); - NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions); - NS_IMETHOD GetTextDimensions(const PRUnichar *aString, PRUint32 aLength, - nsTextDimensions& aDimensions, PRInt32 *aFontID); + NS_IMETHOD DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing); + NS_IMETHOD DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing); + + NS_IMETHOD GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar *aString, PRUint32 aLength, + nsTextDimensions& aDimensions,PRInt32 *aFontID); + NS_IMETHOD GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + +#ifdef MOZ_MATHML + /** + * Returns metrics (in app units) of an 8-bit character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics); + + /** + * Returns metrics (in app units) of a Unicode character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID = nsnull); + +#endif /* MOZ_MATHML */ + + virtual PRInt32 GetMaxStringLength(); NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, const nsRect &aDestBounds, PRUint32 aCopyFlags); @@ -152,22 +206,6 @@ public: virtual void* GetNativeGraphicData(GraphicDataType aType); -#ifdef MOZ_MATHML - /** - * Returns metrics (in app units) of an 8-bit character string - */ - NS_IMETHOD GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); - - /** - * Returns metrics (in app units) of a Unicode character string - */ - NS_IMETHOD GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID); -#endif /* MOZ_MATHML */ /** * Let the device context know whether we want text reordered with * right-to-left base direction diff --git a/mozilla/gfx/src/nsRenderingContextImpl.h b/mozilla/gfx/src/nsRenderingContextImpl.h index 4b6b2183fa5..4a2129399d7 100644 --- a/mozilla/gfx/src/nsRenderingContextImpl.h +++ b/mozilla/gfx/src/nsRenderingContextImpl.h @@ -102,6 +102,14 @@ public: NS_IMETHOD PopTranslation(PushedTranslation* aState); NS_IMETHOD SetTranslation(nscoord aX, nscoord aY); + /** + * Return the maximum length of a string that can be handled by the platform + * using the current font metrics. + * The implementation here is just a stub; classes that don't override + * the safe string methods need to implement this. + */ + virtual PRInt32 GetMaxStringLength() { return 1; } + /** * Let the device context know whether we want text reordered with * right-to-left base direction @@ -118,6 +126,7 @@ public: virtual PRInt32 GetPosition(const PRUnichar *aText, PRUint32 aLength, nsPoint aPt); + NS_IMETHOD GetRangeWidth(const PRUnichar *aText, PRUint32 aLength, PRUint32 aStart, @@ -129,6 +138,132 @@ public: PRUint32 aEnd, PRUint32 &aWidth); + // Silence C++ hiding warnings + NS_IMETHOD GetWidth(char aC, nscoord &aWidth) = 0; + NS_IMETHOD GetWidth(PRUnichar aC, nscoord &aWidth, + PRInt32 *aFontID = nsnull) = 0; + + // Safe string method variants: by default, these defer to the more + // elaborate methods below + NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, + PRInt32 *aFontID = nsnull); + NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth); + NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, + PRInt32 aFontID = -1, + const nscoord* aSpacing = nsnull); + + // Safe string methods + NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, + nscoord& aWidth); + NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID = nsnull); + + NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions); + NS_IMETHOD GetTextDimensions(const PRUnichar* aString, PRUint32 aLength, + nsTextDimensions& aDimensions, PRInt32* aFontID = nsnull); + +#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) + NS_IMETHOD GetTextDimensions(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID = nsnull); + + NS_IMETHOD GetTextDimensions(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID = nsnull); +#endif +#ifdef MOZ_MATHML + NS_IMETHOD + GetBoundingMetrics(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics); + NS_IMETHOD + GetBoundingMetrics(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID = nsnull); +#endif + NS_IMETHOD DrawString(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing = nsnull); + NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID = -1, + const nscoord* aSpacing = nsnull); + + // Unsafe platform-specific implementations + NS_IMETHOD GetWidthInternal(const char* aString, PRUint32 aLength, + nscoord& aWidth) + { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID = nsnull) + { return NS_ERROR_NOT_IMPLEMENTED; } + + NS_IMETHOD GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions) + { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar* aString, PRUint32 aLength, + nsTextDimensions& aDimensions, PRInt32* aFontID = nsnull) + { return NS_ERROR_NOT_IMPLEMENTED; } + +#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) + NS_IMETHOD GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID = nsnull) + { return NS_ERROR_NOT_IMPLEMENTED; } + + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID = nsnull) + { return NS_ERROR_NOT_IMPLEMENTED; } +#endif +#ifdef MOZ_MATHML + NS_IMETHOD + GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics) + { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD + GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID = nsnull) + { return NS_ERROR_NOT_IMPLEMENTED; } +#endif + NS_IMETHOD DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing = nsnull) + { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID = -1, + const nscoord* aSpacing = nsnull) + { return NS_ERROR_NOT_IMPLEMENTED; } + NS_IMETHOD RenderEPS(const nsRect& aRect, FILE *aDataFile); #ifdef MOZ_CAIRO_GFX diff --git a/mozilla/gfx/src/os2/nsFontMetricsOS2.h b/mozilla/gfx/src/os2/nsFontMetricsOS2.h index f8adee41d95..61484b5ce90 100644 --- a/mozilla/gfx/src/os2/nsFontMetricsOS2.h +++ b/mozilla/gfx/src/os2/nsFontMetricsOS2.h @@ -250,6 +250,8 @@ public: NS_IMETHOD GetFontHandle(nsFontHandle &aHandle); NS_IMETHOD GetAveCharWidth(nscoord &aAveCharWidth); NS_IMETHOD GetSpaceWidth(nscoord &aSpaceWidth); + // No known string length limits on OS/2 + virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; } virtual nsresult ResolveForwards(HPS aPS, diff --git a/mozilla/gfx/src/photon/nsFontMetricsPh.h b/mozilla/gfx/src/photon/nsFontMetricsPh.h index 0b2f11b34a2..8e9e6cdea4d 100644 --- a/mozilla/gfx/src/photon/nsFontMetricsPh.h +++ b/mozilla/gfx/src/photon/nsFontMetricsPh.h @@ -171,6 +171,8 @@ public: aSpaceWidth = mSpaceWidth; return NS_OK; } + // No known string length limits on Photon + virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; } protected: void RealizeFont(); @@ -197,7 +199,9 @@ protected: nscoord mUnderlineOffset; nscoord mSpaceWidth; nscoord mAveCharWidth; - + // No known string length limits on Photon + virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; } + nsCOMPtr mLangGroup; }; diff --git a/mozilla/gfx/src/ps/nsFontMetricsPS.h b/mozilla/gfx/src/ps/nsFontMetricsPS.h index f075e238eba..c4b36a3b3d1 100644 --- a/mozilla/gfx/src/ps/nsFontMetricsPS.h +++ b/mozilla/gfx/src/ps/nsFontMetricsPS.h @@ -127,6 +127,8 @@ public: inline void SetMaxAdvance(nscoord aMaxAdvance) { mMaxAdvance = aMaxAdvance; }; inline void SetAveCharWidth(nscoord aAveCharWidth) { mAveCharWidth = aAveCharWidth; }; inline void SetSpaceWidth(nscoord aSpaceWidth) { mSpaceWidth = aSpaceWidth; }; + // No known string length limits in Postscript + virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; } inline nsDeviceContextPS* GetDeviceContext() { return mDeviceContext; } inline nsVoidArray* GetFontsPS() { diff --git a/mozilla/gfx/src/qt/nsFontMetricsQt.h b/mozilla/gfx/src/qt/nsFontMetricsQt.h index f37affb8dd8..ff3a1467eb9 100644 --- a/mozilla/gfx/src/qt/nsFontMetricsQt.h +++ b/mozilla/gfx/src/qt/nsFontMetricsQt.h @@ -143,6 +143,8 @@ public: NS_IMETHOD GetFontHandle(nsFontHandle &aHandle); NS_IMETHOD GetSpaceWidth(nscoord &aSpaceWidth); + // No known string length limits on Qt + virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; } nsFontQt *qFont; diff --git a/mozilla/gfx/src/shared/nsRenderingContextImpl.cpp b/mozilla/gfx/src/shared/nsRenderingContextImpl.cpp index 8f3f80aa12a..2bbe44a37d3 100644 --- a/mozilla/gfx/src/shared/nsRenderingContextImpl.cpp +++ b/mozilla/gfx/src/shared/nsRenderingContextImpl.cpp @@ -41,6 +41,7 @@ #include "nsIImage.h" #include "nsTransform2D.h" #include "nsIRegion.h" +#include "nsIFontMetrics.h" #include @@ -494,10 +495,444 @@ nsRenderingContextImpl::GetRangeWidth(const char *aText, return NS_ERROR_NOT_IMPLEMENTED; } +// Hard limit substring lengths to 8000 characters ... this lets us statically +// size the cluster buffer array in FindSafeLength +#define MAX_GFX_TEXT_BUF_SIZE 8000 +static PRInt32 GetMaxChunkLength(nsRenderingContextImpl* aContext) +{ + PRInt32 len = aContext->GetMaxStringLength(); + return PR_MIN(len, MAX_GFX_TEXT_BUF_SIZE); +} + +static PRInt32 FindSafeLength(nsRenderingContextImpl* aContext, + const PRUnichar *aString, PRUint32 aLength, + PRUint32 aMaxChunkLength) +{ + if (aLength <= aMaxChunkLength) + return aLength; + + PRUint8 buffer[MAX_GFX_TEXT_BUF_SIZE + 1]; + // Fill in the cluster hint information, if it's available. + PRUint32 clusterHint; + aContext->GetHints(clusterHint); + clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS; + + PRInt32 len = aMaxChunkLength; + + if (clusterHint) { + nsresult rv = + aContext->GetClusterInfo(aString, aMaxChunkLength + 1, buffer); + if (NS_FAILED(rv)) + return len; + } + + // Ensure that we don't break inside a cluster or inside a surrogate pair + while (len > 0 && + (IS_LOW_SURROGATE(aString[len]) || (clusterHint && !buffer[len]))) { + len--; + } + if (len == 0) { + // We don't want our caller to go into an infinite loop, so don't return + // zero. It's hard to imagine how we could actually get here unless there + // are languages that allow clusters of arbitrary size. If there are and + // someone feeds us a 500+ character cluster, too bad. + return aMaxChunkLength; + } + return len; +} + +static PRInt32 FindSafeLength(nsRenderingContextImpl* aContext, + const char *aString, PRUint32 aLength, + PRUint32 aMaxChunkLength) +{ + // Since it's ASCII, we don't need to worry about clusters or RTL + return PR_MIN(aLength, aMaxChunkLength); +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetWidth(const nsString& aString, nscoord &aWidth, + PRInt32 *aFontID) +{ + return GetWidth(aString.get(), aString.Length(), aWidth, aFontID); +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetWidth(const char* aString, nscoord& aWidth) +{ + return GetWidth(aString, strlen(aString), aWidth); +} + +NS_IMETHODIMP +nsRenderingContextImpl::DrawString(const nsString& aString, nscoord aX, nscoord aY, + PRInt32 aFontID, const nscoord* aSpacing) +{ + return DrawString(aString.get(), aString.Length(), aX, aY, aFontID, aSpacing); +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetWidth(const char* aString, PRUint32 aLength, + nscoord& aWidth) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + aWidth = 0; + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nscoord width; + nsresult rv = GetWidthInternal(aString, len, width); + if (NS_FAILED(rv)) + return rv; + aWidth += width; + aLength -= len; + aString += len; + } + return NS_OK; +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetWidth(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + aWidth = 0; + + if (aFontID) { + *aFontID = 0; + } + + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nscoord width; + nsresult rv = GetWidthInternal(aString, len, width); + if (NS_FAILED(rv)) + return rv; + aWidth += width; + aLength -= len; + aString += len; + } + return NS_OK; +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetTextDimensions(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + if (aLength <= maxChunkLength) + return GetTextDimensionsInternal(aString, aLength, aDimensions); + + PRBool firstIteration = PR_TRUE; + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nsTextDimensions dimensions; + nsresult rv = GetTextDimensionsInternal(aString, len, dimensions); + if (NS_FAILED(rv)) + return rv; + if (firstIteration) { + // Instead of combining with a Clear()ed nsTextDimensions, we assign + // directly in the first iteration. This ensures that negative ascent/ + // descent can be returned. + aDimensions = dimensions; + } else { + aDimensions.Combine(dimensions); + } + aLength -= len; + aString += len; + firstIteration = PR_FALSE; + } + return NS_OK; +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetTextDimensions(const PRUnichar* aString, PRUint32 aLength, + nsTextDimensions& aDimensions, PRInt32* aFontID) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + if (aLength <= maxChunkLength) + return GetTextDimensionsInternal(aString, aLength, aDimensions); + + if (*aFontID) { + *aFontID = nsnull; + } + + PRBool firstIteration = PR_TRUE; + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nsTextDimensions dimensions; + nsresult rv = GetTextDimensionsInternal(aString, len, dimensions); + if (NS_FAILED(rv)) + return rv; + if (firstIteration) { + // Instead of combining with a Clear()ed nsTextDimensions, we assign + // directly in the first iteration. This ensures that negative ascent/ + // descent can be returned. + aDimensions = dimensions; + } else { + aDimensions.Combine(dimensions); + } + aLength -= len; + aString += len; + firstIteration = PR_FALSE; + } + return NS_OK; +} + +#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) +NS_IMETHODIMP +nsRenderingContextImpl::GetTextDimensions(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + if (aLength <= PRInt32(maxChunkLength)) + return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks, aNumBreaks, + aDimensions, aNumCharsFit, aLastWordDimensions, aFontID); + + if (aFontID) { + *aFontID = 0; + } + + // Do a naive implementation based on 3-arg GetTextDimensions + PRInt32 x = 0; + PRInt32 wordCount; + for (wordCount = 0; wordCount < aNumBreaks; ++wordCount) { + PRInt32 lastBreak = wordCount > 0 ? aBreaks[wordCount - 1] : 0; + nsTextDimensions dimensions; + // Call safe method + nsresult rv = GetTextDimensions(aString + lastBreak, aBreaks[wordCount], + dimensions); + if (NS_FAILED(rv)) + return rv; + x += dimensions.width; + // The first word always "fits" + if (x > aAvailWidth && wordCount > 0) + break; + // aDimensions ascent/descent should exclude the last word (unless there + // is only one word) so we let it run one word behind + if (wordCount == 0) { + aDimensions = dimensions; + } else { + aDimensions.Combine(aLastWordDimensions); + } + aNumCharsFit = aBreaks[wordCount]; + aLastWordDimensions = dimensions; + } + // aDimensions width should include all the text + aDimensions.width = x; + return NS_OK; +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetTextDimensions(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + if (aLength <= PRInt32(maxChunkLength)) + return GetTextDimensionsInternal(aString, aLength, aAvailWidth, aBreaks, aNumBreaks, + aDimensions, aNumCharsFit, aLastWordDimensions, aFontID); + + if (aFontID) { + *aFontID = 0; + } + + // Do a naive implementation based on 3-arg GetTextDimensions + PRInt32 x = 0; + PRInt32 wordCount; + for (wordCount = 0; wordCount < aNumBreaks; ++wordCount) { + PRInt32 lastBreak = wordCount > 0 ? aBreaks[wordCount - 1] : 0; + nsTextDimensions dimensions; + // Call safe method + nsresult rv = GetTextDimensions(aString + lastBreak, aBreaks[wordCount], + dimensions); + if (NS_FAILED(rv)) + return rv; + x += dimensions.width; + // The first word always "fits" + if (x > aAvailWidth && wordCount > 0) + break; + // aDimensions ascent/descent should exclude the last word (unless there + // is only one word) so we let it run one word behind + if (wordCount == 0) { + aDimensions = dimensions; + } else { + aDimensions.Combine(aLastWordDimensions); + } + aNumCharsFit = aBreaks[wordCount]; + aLastWordDimensions = dimensions; + } + // aDimensions width should include all the text + aDimensions.width = x; + return NS_OK; +} +#endif + +#ifdef MOZ_MATHML +NS_IMETHODIMP +nsRenderingContextImpl::GetBoundingMetrics(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + if (aLength <= maxChunkLength) + return GetBoundingMetricsInternal(aString, aLength, aBoundingMetrics); + + PRBool firstIteration = PR_TRUE; + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nsBoundingMetrics metrics; + nsresult rv = GetBoundingMetricsInternal(aString, len, metrics); + if (NS_FAILED(rv)) + return rv; + if (firstIteration) { + // Instead of combining with a Clear()ed nsBoundingMetrics, we assign + // directly in the first iteration. This ensures that negative ascent/ + // descent can be returned and the left bearing is properly initialized. + aBoundingMetrics = metrics; + } else { + aBoundingMetrics += metrics; + } + aLength -= len; + aString += len; + firstIteration = PR_FALSE; + } + return NS_OK; +} + +NS_IMETHODIMP +nsRenderingContextImpl::GetBoundingMetrics(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + if (aLength <= maxChunkLength) + return GetBoundingMetricsInternal(aString, aLength, aBoundingMetrics, aFontID); + + if (aFontID) { + *aFontID = 0; + } + + PRBool firstIteration = PR_TRUE; + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nsBoundingMetrics metrics; + nsresult rv = GetBoundingMetricsInternal(aString, len, metrics); + if (NS_FAILED(rv)) + return rv; + if (firstIteration) { + // Instead of combining with a Clear()ed nsBoundingMetrics, we assign + // directly in the first iteration. This ensures that negative ascent/ + // descent can be returned and the left bearing is properly initialized. + aBoundingMetrics = metrics; + } else { + aBoundingMetrics += metrics; + } + aLength -= len; + aString += len; + firstIteration = PR_FALSE; + } + return NS_OK; +} +#endif + +NS_IMETHODIMP +nsRenderingContextImpl::DrawString(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nsresult rv = DrawStringInternal(aString, len, aX, aY); + if (NS_FAILED(rv)) + return rv; + aLength -= len; + + if (aLength > 0) { + nscoord width; + rv = GetWidthInternal(aString, len, width); + if (NS_FAILED(rv)) + return rv; + aX += width; + aString += len; + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsRenderingContextImpl::DrawString(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing) +{ + PRUint32 maxChunkLength = GetMaxChunkLength(this); + if (aLength <= maxChunkLength) { + return DrawStringInternal(aString, aLength, aX, aY, aFontID, aSpacing); + } + + PRBool isRTL = PR_FALSE; + GetRightToLeftText(&isRTL); + + if (isRTL) { + nscoord totalWidth = 0; + if (aSpacing) { + for (PRUint32 i = 0; i < aLength; ++i) { + totalWidth += aSpacing[i]; + } + } else { + nsresult rv = GetWidth(aString, aLength, totalWidth); + if (NS_FAILED(rv)) + return rv; + } + aX += totalWidth; + } + + while (aLength > 0) { + PRInt32 len = FindSafeLength(this, aString, aLength, maxChunkLength); + nscoord width = 0; + if (aSpacing) { + for (PRInt32 i = 0; i < len; ++i) { + width += aSpacing[i]; + } + } else { + nsresult rv = GetWidthInternal(aString, len, width); + if (NS_FAILED(rv)) + return rv; + } + + if (isRTL) { + aX -= width; + } + nsresult rv = DrawStringInternal(aString, len, aX, aY, aFontID, aSpacing); + if (NS_FAILED(rv)) + return rv; + aLength -= len; + if (!isRTL) { + aX += width; + } + aString += len; + if (aSpacing) { + aSpacing += len; + } + } + return NS_OK; +} + NS_IMETHODIMP nsRenderingContextImpl::RenderEPS(const nsRect& aRect, FILE *aDataFile) { return NS_ERROR_NOT_IMPLEMENTED; } - - diff --git a/mozilla/gfx/src/thebes/nsIThebesFontMetrics.h b/mozilla/gfx/src/thebes/nsIThebesFontMetrics.h index a09085d7515..92254bceb6c 100644 --- a/mozilla/gfx/src/thebes/nsIThebesFontMetrics.h +++ b/mozilla/gfx/src/thebes/nsIThebesFontMetrics.h @@ -109,6 +109,7 @@ public: virtual nsresult SetRightToLeftText(PRBool aIsRTL) = 0; virtual PRBool GetRightToLeftText() = 0; + virtual PRInt32 GetMaxStringLength() = 0; }; #endif /* __nsIThebesFontMetrics_h */ diff --git a/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp b/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp index 2f07e088b41..1ba065d74a8 100644 --- a/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp +++ b/mozilla/gfx/src/thebes/nsThebesFontMetrics.cpp @@ -272,6 +272,13 @@ nsThebesFontMetrics::GetNormalLineHeight(nscoord& aLineHeight) return NS_OK; } +PRInt32 +nsThebesFontMetrics::GetMaxStringLength() +{ + PRInt32 len = (PRInt32)floor(32767.0/GetMetrics().maxAdvance); + return PR_MAX(1, len); +} + nsresult nsThebesFontMetrics::GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth, nsThebesRenderingContext *aContext) diff --git a/mozilla/gfx/src/thebes/nsThebesFontMetrics.h b/mozilla/gfx/src/thebes/nsThebesFontMetrics.h index b5c25657bee..2d057ee30aa 100644 --- a/mozilla/gfx/src/thebes/nsThebesFontMetrics.h +++ b/mozilla/gfx/src/thebes/nsThebesFontMetrics.h @@ -79,8 +79,7 @@ public: NS_IMETHOD GetSpaceWidth(nscoord& aSpaceCharWidth); NS_IMETHOD GetLeading(nscoord& aLeading); NS_IMETHOD GetNormalLineHeight(nscoord& aLineHeight); - - + virtual PRInt32 GetMaxStringLength(); virtual nsresult GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth, diff --git a/mozilla/gfx/src/thebes/nsThebesRenderingContext.cpp b/mozilla/gfx/src/thebes/nsThebesRenderingContext.cpp index 2492b8a2a2d..718d9541307 100644 --- a/mozilla/gfx/src/thebes/nsThebesRenderingContext.cpp +++ b/mozilla/gfx/src/thebes/nsThebesRenderingContext.cpp @@ -1157,6 +1157,14 @@ nsThebesRenderingContext::GetFontMetrics(nsIFontMetrics *&aFontMetrics) return NS_OK; } +PRInt32 +nsThebesRenderingContext::GetMaxStringLength() +{ + if (!mFontMetrics) + return 1; + return mFontMetrics->GetMaxStringLength(); +} + NS_IMETHODIMP nsThebesRenderingContext::GetWidth(char aC, nscoord &aWidth) { @@ -1173,19 +1181,7 @@ nsThebesRenderingContext::GetWidth(PRUnichar aC, nscoord &aWidth, PRInt32 *aFont } NS_IMETHODIMP -nsThebesRenderingContext::GetWidth(const nsString& aString, nscoord &aWidth, PRInt32 *aFontID) -{ - return GetWidth(aString.get(), aString.Length(), aWidth, aFontID); -} - -NS_IMETHODIMP -nsThebesRenderingContext::GetWidth(const char* aString, nscoord& aWidth) -{ - return GetWidth(aString, strlen(aString), aWidth); -} - -NS_IMETHODIMP -nsThebesRenderingContext::GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth) +nsThebesRenderingContext::GetWidthInternal(const char* aString, PRUint32 aLength, nscoord& aWidth) { if (aLength == 0) { aWidth = 0; @@ -1196,8 +1192,8 @@ nsThebesRenderingContext::GetWidth(const char* aString, PRUint32 aLength, nscoor } NS_IMETHODIMP -nsThebesRenderingContext::GetWidth(const PRUnichar *aString, PRUint32 aLength, - nscoord &aWidth, PRInt32 *aFontID) +nsThebesRenderingContext::GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID) { if (aLength == 0) { aWidth = 0; @@ -1208,8 +1204,8 @@ nsThebesRenderingContext::GetWidth(const PRUnichar *aString, PRUint32 aLength, } NS_IMETHODIMP -nsThebesRenderingContext::GetTextDimensions(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions) +nsThebesRenderingContext::GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions) { mFontMetrics->GetMaxAscent(aDimensions.ascent); mFontMetrics->GetMaxDescent(aDimensions.descent); @@ -1217,10 +1213,10 @@ nsThebesRenderingContext::GetTextDimensions(const char* aString, PRUint32 aLengt } NS_IMETHODIMP -nsThebesRenderingContext::GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID) +nsThebesRenderingContext::GetTextDimensionsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsTextDimensions& aDimensions, + PRInt32* aFontID) { mFontMetrics->GetMaxAscent(aDimensions.ascent); mFontMetrics->GetMaxDescent(aDimensions.descent); @@ -1229,29 +1225,29 @@ nsThebesRenderingContext::GetTextDimensions(const PRUnichar* aString, #if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) NS_IMETHODIMP -nsThebesRenderingContext::GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) +nsThebesRenderingContext::GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -nsThebesRenderingContext::GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) +nsThebesRenderingContext::GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) { return NS_ERROR_NOT_IMPLEMENTED; } @@ -1259,52 +1255,42 @@ nsThebesRenderingContext::GetTextDimensions(const PRUnichar* aString, #ifdef MOZ_MATHML NS_IMETHODIMP -nsThebesRenderingContext::GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) +nsThebesRenderingContext::GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics) { - return NS_OK; + return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP -nsThebesRenderingContext::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID) +nsThebesRenderingContext::GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID) { - return NS_OK; + return NS_ERROR_NOT_IMPLEMENTED; } #endif // MOZ_MATHML NS_IMETHODIMP -nsThebesRenderingContext::DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing) +nsThebesRenderingContext::DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing) { return mFontMetrics->DrawString(aString, aLength, aX, aY, aSpacing, this); } NS_IMETHODIMP -nsThebesRenderingContext::DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) +nsThebesRenderingContext::DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing) { return mFontMetrics->DrawString(aString, aLength, aX, aY, aFontID, aSpacing, this); } -NS_IMETHODIMP -nsThebesRenderingContext::DrawString(const nsString& aString, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) -{ - return DrawString(aString.get(), aString.Length(), - aX, aY, aFontID, aSpacing); -} - NS_IMETHODIMP nsThebesRenderingContext::GetClusterInfo(const PRUnichar *aText, PRUint32 aLength, diff --git a/mozilla/gfx/src/thebes/nsThebesRenderingContext.h b/mozilla/gfx/src/thebes/nsThebesRenderingContext.h index 8e05032a588..131ab3ad7c0 100644 --- a/mozilla/gfx/src/thebes/nsThebesRenderingContext.h +++ b/mozilla/gfx/src/thebes/nsThebesRenderingContext.h @@ -139,56 +139,85 @@ public: float aStartAngle, float aEndAngle); NS_IMETHOD FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, float aStartAngle, float aEndAngle); + + NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, + PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aWidth, aFontID); } + NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aWidth); } + NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, + nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth); } + NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth, aFontID); } + NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, + PRInt32 aFontID = -1, + const nscoord* aSpacing = nsnull) + { return nsRenderingContextImpl::DrawString(aString, aX, aY, aFontID, aSpacing); } + NS_IMETHOD GetWidth(char aC, nscoord &aWidth); NS_IMETHOD GetWidth(PRUnichar aC, nscoord &aWidth, - PRInt32 *aFontID = nsnull); - NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, - PRInt32 *aFontID = nsnull); - NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth); - NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, - nscoord& aWidth); - NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, - nscoord &aWidth, PRInt32 *aFontID = nsnull); - NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions); - NS_IMETHOD GetTextDimensions(const PRUnichar* aString, PRUint32 aLength, - nsTextDimensions& aDimensions, PRInt32* aFontID = nsnull); + PRInt32 *aFontID); + + NS_IMETHOD GetWidthInternal(const char *aString, PRUint32 aLength, nscoord &aWidth); + NS_IMETHOD GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, + PRInt32 *aFontID); + + NS_IMETHOD DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing); + NS_IMETHOD DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing); + + NS_IMETHOD GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar *aString, PRUint32 aLength, + nsTextDimensions& aDimensions,PRInt32 *aFontID); + NS_IMETHOD GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + +#ifdef MOZ_MATHML + /** + * Returns metrics (in app units) of an 8-bit character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics); + + /** + * Returns metrics (in app units) of a Unicode character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID = nsnull); + +#endif /* MOZ_MATHML */ + + virtual PRInt32 GetMaxStringLength(); NS_IMETHOD PushFilter(const nsRect& aRect, PRBool aAreaIsOpaque, float aOpacity); NS_IMETHOD PopFilter(); -#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) - NS_IMETHOD GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID = nsnull); - - NS_IMETHOD GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID = nsnull); -#endif - - NS_IMETHOD DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing = nsnull); - NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID = -1, - const nscoord* aSpacing = nsnull); - NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, - PRInt32 aFontID = -1, - const nscoord* aSpacing = nsnull); NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface *aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, const nsRect &aDestBounds, @@ -206,15 +235,6 @@ public: NS_IMETHOD PopTranslation(PushedTranslation* aState); NS_IMETHOD SetTranslation(nscoord aX, nscoord aY); -#ifdef MOZ_MATHML - NS_IMETHOD GetBoundingMetrics(const char* aString, PRUint32 aLength, nsBoundingMetrics& aBoundingMetrics); - NS_IMETHOD GetBoundingMetrics(const PRUnichar* aString, PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID); - -#endif // MOZ_MATHML - - NS_IMETHOD DrawImage(imgIContainer *aImage, const nsRect &aSrcRect, const nsRect &aDestRect); diff --git a/mozilla/gfx/src/windows/nsFontMetricsWin.cpp b/mozilla/gfx/src/windows/nsFontMetricsWin.cpp index 84a9f0a092e..075b1949b12 100644 --- a/mozilla/gfx/src/windows/nsFontMetricsWin.cpp +++ b/mozilla/gfx/src/windows/nsFontMetricsWin.cpp @@ -3823,6 +3823,11 @@ nsFontMetricsWin::RealizeFont() mMaxAscent = NSToCoordRound(metrics.tmAscent * dev2app); mMaxDescent = NSToCoordRound(metrics.tmDescent * dev2app); mMaxAdvance = NSToCoordRound(metrics.tmMaxCharWidth * dev2app); + // Windows may screw up if we try to measure/draw more than 32767 pixels in + // one operation. + mMaxStringLength = (PRInt32)floor(32767.0/metrics.tmMaxCharWidth); + mMaxStringLength = PR_MAX(1, mMaxStringLength); + mAveCharWidth = PR_MAX(1, NSToCoordRound(metrics.tmAveCharWidth * dev2app)); if (gDoingLineheightFixup) { @@ -3994,6 +3999,12 @@ nsFontMetricsWin::GetAveCharWidth(nscoord &aAveCharWidth) return NS_OK; } +PRInt32 +nsFontMetricsWin::GetMaxStringLength() +{ + return mMaxStringLength; +} + NS_IMETHODIMP nsFontMetricsWin::GetLangGroup(nsIAtom** aLangGroup) { diff --git a/mozilla/gfx/src/windows/nsFontMetricsWin.h b/mozilla/gfx/src/windows/nsFontMetricsWin.h index f6e712f0876..59c06278912 100644 --- a/mozilla/gfx/src/windows/nsFontMetricsWin.h +++ b/mozilla/gfx/src/windows/nsFontMetricsWin.h @@ -243,6 +243,7 @@ public: NS_IMETHOD GetFontHandle(nsFontHandle &aHandle); NS_IMETHOD GetAveCharWidth(nscoord &aAveCharWidth); NS_IMETHOD GetSpaceWidth(nscoord &aSpaceWidth); + virtual PRInt32 GetMaxStringLength(); virtual nsresult ResolveForwards(HDC aDC, @@ -362,6 +363,7 @@ protected: nscoord mUnderlineSize; nscoord mUnderlineOffset; nscoord mSpaceWidth; + PRInt32 mMaxStringLength; }; diff --git a/mozilla/gfx/src/windows/nsRenderingContextWin.cpp b/mozilla/gfx/src/windows/nsRenderingContextWin.cpp index 1ae9bc12def..820699ec630 100644 --- a/mozilla/gfx/src/windows/nsRenderingContextWin.cpp +++ b/mozilla/gfx/src/windows/nsRenderingContextWin.cpp @@ -1446,14 +1446,9 @@ NS_IMETHODIMP nsRenderingContextWin :: GetWidth(PRUnichar ch, nscoord &aWidth, P return GetWidth(buf, 1, aWidth, aFontID); } -NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const char* aString, nscoord& aWidth) -{ - return GetWidth(aString, strlen(aString), aWidth); -} - -NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const char* aString, - PRUint32 aLength, - nscoord& aWidth) +NS_IMETHODIMP nsRenderingContextWin :: GetWidthInternal(const char* aString, + PRUint32 aLength, + nscoord& aWidth) { if (nsnull != mFontMetrics) @@ -1476,11 +1471,6 @@ NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const char* aString, return NS_ERROR_FAILURE; } -NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const nsString& aString, nscoord& aWidth, PRInt32 *aFontID) -{ - return GetWidth(aString.get(), aString.Length(), aWidth, aFontID); -} - struct GetWidthData { HDC mDC; // IN HFONT mFont; // IN/OUT (running) @@ -1505,10 +1495,10 @@ do_GetWidth(const nsFontSwitch* aFontSwitch, return PR_TRUE; // don't stop till the end } -NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const PRUnichar *aString, - PRUint32 aLength, - nscoord &aWidth, - PRInt32 *aFontID) +NS_IMETHODIMP nsRenderingContextWin :: GetWidthInternal(const PRUnichar *aString, + PRUint32 aLength, + nscoord &aWidth, + PRInt32 *aFontID) { if (!mFontMetrics) return NS_ERROR_FAILURE; @@ -1532,15 +1522,15 @@ NS_IMETHODIMP nsRenderingContextWin :: GetWidth(const PRUnichar *aString, } NS_IMETHODIMP -nsRenderingContextWin::GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) +nsRenderingContextWin::GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) { NS_PRECONDITION(aBreaks[aNumBreaks - 1] == aLength, "invalid break array"); @@ -1966,15 +1956,15 @@ do_BreakGetTextDimensions(const nsFontSwitch* aFontSwitch, } NS_IMETHODIMP -nsRenderingContextWin::GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID) +nsRenderingContextWin::GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID) { if (!mFontMetrics) return NS_ERROR_FAILURE; @@ -2129,9 +2119,9 @@ nsRenderingContextWin::GetTextDimensions(const PRUnichar* aString, } NS_IMETHODIMP -nsRenderingContextWin::GetTextDimensions(const char* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions) +nsRenderingContextWin::GetTextDimensionsInternal(const char* aString, + PRUint32 aLength, + nsTextDimensions& aDimensions) { if (!mFontMetrics) { aDimensions.Clear(); @@ -2175,10 +2165,10 @@ do_GetTextDimensions(const nsFontSwitch* aFontSwitch, } NS_IMETHODIMP -nsRenderingContextWin::GetTextDimensions(const PRUnichar* aString, - PRUint32 aLength, - nsTextDimensions& aDimensions, - PRInt32* aFontID) +nsRenderingContextWin::GetTextDimensionsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsTextDimensions& aDimensions, + PRInt32* aFontID) { aDimensions.Clear(); if (!mFontMetrics) return NS_ERROR_FAILURE; @@ -2204,9 +2194,9 @@ nsRenderingContextWin::GetTextDimensions(const PRUnichar* aString, return NS_OK; } -NS_IMETHODIMP nsRenderingContextWin :: DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing) +NS_IMETHODIMP nsRenderingContextWin :: DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing) { NS_PRECONDITION(mFontMetrics,"Something is wrong somewhere"); @@ -2303,10 +2293,10 @@ do_DrawString(const nsFontSwitch* aFontSwitch, return PR_TRUE; // don't stop till the end } -NS_IMETHODIMP nsRenderingContextWin :: DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) +NS_IMETHODIMP nsRenderingContextWin :: DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing) { if (!mFontMetrics) return NS_ERROR_FAILURE; @@ -2337,19 +2327,11 @@ NS_IMETHODIMP nsRenderingContextWin :: DrawString(const PRUnichar *aString, PRUi return NS_OK; } -NS_IMETHODIMP nsRenderingContextWin :: DrawString(const nsString& aString, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) -{ - return DrawString(aString.get(), aString.Length(), aX, aY, aFontID, aSpacing); -} - #ifdef MOZ_MATHML NS_IMETHODIMP -nsRenderingContextWin::GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) +nsRenderingContextWin::GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics) { NS_PRECONDITION(mFontMetrics,"Something is wrong somewhere"); @@ -2410,10 +2392,10 @@ do_GetBoundingMetrics(const nsFontSwitch* aFontSwitch, } NS_IMETHODIMP -nsRenderingContextWin::GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID) +nsRenderingContextWin::GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID) { aBoundingMetrics.Clear(); if (!mFontMetrics) return NS_ERROR_FAILURE; @@ -2447,6 +2429,13 @@ nsRenderingContextWin::GetBoundingMetrics(const PRUnichar* aString, } #endif // MOZ_MATHML +PRInt32 nsRenderingContextWin::GetMaxStringLength() +{ + if (!mFontMetrics) + return 1; + return NS_STATIC_CAST(nsFontMetricsWin*, mFontMetrics)->GetMaxStringLength(); +} + NS_IMETHODIMP nsRenderingContextWin :: CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, const nsRect &aDestBounds, diff --git a/mozilla/gfx/src/windows/nsRenderingContextWin.h b/mozilla/gfx/src/windows/nsRenderingContextWin.h index d605aa76e61..441301dc402 100644 --- a/mozilla/gfx/src/windows/nsRenderingContextWin.h +++ b/mozilla/gfx/src/windows/nsRenderingContextWin.h @@ -149,49 +149,79 @@ public: NS_IMETHOD FillArc(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight, float aStartAngle, float aEndAngle); - NS_IMETHOD GetWidth(char aC, nscoord& aWidth); - NS_IMETHOD GetWidth(PRUnichar aC, nscoord& aWidth, - PRInt32 *aFontID); - NS_IMETHOD GetWidth(const nsString& aString, nscoord& aWidth, - PRInt32 *aFontID); - NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth); - NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, nscoord& aWidth); - NS_IMETHOD GetWidth(const PRUnichar* aString, PRUint32 aLength, - nscoord& aWidth, PRInt32 *aFontID); - - NS_IMETHOD GetTextDimensions(const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions); - NS_IMETHOD GetTextDimensions(const PRUnichar *aString, PRUint32 aLength, - nsTextDimensions& aDimensions, PRInt32 *aFontID); - NS_IMETHOD GetTextDimensions(const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID = nsnull); - NS_IMETHOD GetTextDimensions(const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions, - PRInt32* aFontID = nsnull); - - NS_IMETHOD DrawString(const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - const nscoord* aSpacing); - NS_IMETHOD DrawString(const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); + NS_IMETHOD GetWidth(const nsString& aString, nscoord &aWidth, + PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aWidth, aFontID); } + NS_IMETHOD GetWidth(const char* aString, nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aWidth); } + NS_IMETHOD GetWidth(const char* aString, PRUint32 aLength, + nscoord& aWidth) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth); } + NS_IMETHOD GetWidth(const PRUnichar *aString, PRUint32 aLength, + nscoord &aWidth, PRInt32 *aFontID = nsnull) + { return nsRenderingContextImpl::GetWidth(aString, aLength, aWidth, aFontID); } NS_IMETHOD DrawString(const nsString& aString, nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing); + PRInt32 aFontID = -1, + const nscoord* aSpacing = nsnull) + { return nsRenderingContextImpl::DrawString(aString, aX, aY, aFontID, aSpacing); } + + NS_IMETHOD GetWidth(char aC, nscoord &aWidth); + NS_IMETHOD GetWidth(PRUnichar aC, nscoord &aWidth, + PRInt32 *aFontID); + + NS_IMETHOD GetWidthInternal(const char *aString, PRUint32 aLength, nscoord &aWidth); + NS_IMETHOD GetWidthInternal(const PRUnichar *aString, PRUint32 aLength, nscoord &aWidth, + PRInt32 *aFontID); + + NS_IMETHOD DrawStringInternal(const char *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + const nscoord* aSpacing); + NS_IMETHOD DrawStringInternal(const PRUnichar *aString, PRUint32 aLength, + nscoord aX, nscoord aY, + PRInt32 aFontID, + const nscoord* aSpacing); + + NS_IMETHOD GetTextDimensionsInternal(const char* aString, PRUint32 aLength, + nsTextDimensions& aDimensions); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar *aString, PRUint32 aLength, + nsTextDimensions& aDimensions,PRInt32 *aFontID); + NS_IMETHOD GetTextDimensionsInternal(const char* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + NS_IMETHOD GetTextDimensionsInternal(const PRUnichar* aString, + PRInt32 aLength, + PRInt32 aAvailWidth, + PRInt32* aBreaks, + PRInt32 aNumBreaks, + nsTextDimensions& aDimensions, + PRInt32& aNumCharsFit, + nsTextDimensions& aLastWordDimensions, + PRInt32* aFontID); + +#ifdef MOZ_MATHML + /** + * Returns metrics (in app units) of an 8-bit character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const char* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics); + + /** + * Returns metrics (in app units) of a Unicode character string + */ + NS_IMETHOD GetBoundingMetricsInternal(const PRUnichar* aString, + PRUint32 aLength, + nsBoundingMetrics& aBoundingMetrics, + PRInt32* aFontID = nsnull); + +#endif /* MOZ_MATHML */ + virtual PRInt32 GetMaxStringLength(); NS_IMETHOD CopyOffScreenBits(nsIDrawingSurface* aSrcSurf, PRInt32 aSrcX, PRInt32 aSrcY, const nsRect &aDestBounds, PRUint32 aCopyFlags); @@ -202,19 +232,6 @@ public: NS_IMETHOD ReleaseBackbuffer(void); -#ifdef MOZ_MATHML - NS_IMETHOD - GetBoundingMetrics(const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); - - NS_IMETHOD - GetBoundingMetrics(const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics, - PRInt32* aFontID); -#endif - NS_IMETHOD SetRightToLeftText(PRBool aIsRTL); NS_IMETHOD GetRightToLeftText(PRBool* aIsRTL); diff --git a/mozilla/gfx/src/xlib/nsFontMetricsXlib.h b/mozilla/gfx/src/xlib/nsFontMetricsXlib.h index 15f6d3f4312..40c92a0dc95 100644 --- a/mozilla/gfx/src/xlib/nsFontMetricsXlib.h +++ b/mozilla/gfx/src/xlib/nsFontMetricsXlib.h @@ -373,6 +373,8 @@ public: NS_IMETHOD GetAveCharWidth(nscoord &aAveCharWidth); NS_IMETHOD GetLangGroup(nsIAtom** aLangGroup); NS_IMETHOD GetFontHandle(nsFontHandle &aHandle); + // Xlib probably has string length limits, but I can't be bothered + virtual PRInt32 GetMaxStringLength() { return PR_INT32_MAX; } NS_IMETHOD GetSpaceWidth(nscoord &aSpaceWidth); NS_IMETHOD ResolveForwards(const PRUnichar* aString, PRUint32 aLength, diff --git a/mozilla/layout/base/nsBidiPresUtils.cpp b/mozilla/layout/base/nsBidiPresUtils.cpp index 53ad158f939..48253ee94ab 100644 --- a/mozilla/layout/base/nsBidiPresUtils.cpp +++ b/mozilla/layout/base/nsBidiPresUtils.cpp @@ -51,7 +51,6 @@ #include "nsBidiUtils.h" #include "nsCSSFrameConstructor.h" #include "nsHTMLContainerFrame.h" -#include "nsLayoutUtils.h" #include "nsInlineFrame.h" static NS_DEFINE_IID(kInlineFrameCID, NS_INLINE_FRAME_CID); @@ -1391,7 +1390,7 @@ nsresult nsBidiPresUtils::RenderText(const PRUnichar* aText, * x-coordinate of the end of the run for the start of the next run. */ if (level & 1) { - nsLayoutUtils::SafeGetWidth(&aRenderingContext, aText + start, subRunLength, width); + aRenderingContext.GetWidth(aText + start, subRunLength, width, nsnull); aX += width; xEndRun = aX; } @@ -1418,11 +1417,11 @@ nsresult nsBidiPresUtils::RenderText(const PRUnichar* aText, (nsCharType)charType, level & 1, isBidiSystem); - nsLayoutUtils::SafeGetWidth(&aRenderingContext, runVisualText.get(), subRunLength, width); + aRenderingContext.GetWidth(runVisualText.get(), subRunLength, width, nsnull); if (level & 1) { aX -= width; } - nsLayoutUtils::SafeDrawString(&aRenderingContext, runVisualText.get(), subRunLength, aX, aY, width); + aRenderingContext.DrawString(runVisualText.get(), subRunLength, aX, aY, width); /* * The caller may request to calculate the visual position of one @@ -1477,9 +1476,9 @@ nsresult nsBidiPresUtils::RenderText(const PRUnichar* aText, } // The delta between the start of the run and the left part's end. PRInt32 visualLeftLength = posResolve->visualIndex - visualStart; - nsLayoutUtils::SafeGetWidth(&aRenderingContext, visualLeftPart, - visualLeftLength, - subWidth); + aRenderingContext.GetWidth(visualLeftPart, + visualLeftLength, + subWidth, nsnull); posResolve->visualLeftTwips = aX + subWidth - xStartText; } } diff --git a/mozilla/layout/base/nsLayoutUtils.cpp b/mozilla/layout/base/nsLayoutUtils.cpp index 389cff2431a..0ae03e4eafd 100644 --- a/mozilla/layout/base/nsLayoutUtils.cpp +++ b/mozilla/layout/base/nsLayoutUtils.cpp @@ -959,366 +959,6 @@ nsLayoutUtils::ScrollIntoView(nsIFormControlFrame* aFormFrame) } } -static PRInt32 FindSafeLength(nsIRenderingContext* aContext, - const PRUnichar *aString, PRUint32 aLength) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) - return aLength; - - PRUint8 buffer[MAX_GFX_TEXT_BUF_SIZE + 1]; - // Fill in the cluster hint information, if it's available. - PRUint32 clusterHint; - aContext->GetHints(clusterHint); - clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS; - - PRInt32 len = MAX_GFX_TEXT_BUF_SIZE; - - if (clusterHint) { - nsresult rv = - aContext->GetClusterInfo(aString, MAX_GFX_TEXT_BUF_SIZE + 1, buffer); - if (NS_FAILED(rv)) - return len; - } - - // Ensure that we don't break inside a cluster or inside a surrogate pair - while (len > 0 && - (IS_LOW_SURROGATE(aString[len]) || (clusterHint && !buffer[len]))) { - len--; - } - if (len == 0) { - // We don't want our caller to go into an infinite loop, so don't return - // zero. It's hard to imagine how we could actually get here unless there - // are languages that allow clusters of arbitrary size. If there are and - // someone feeds us a 500+ character cluster, too bad. - return MAX_GFX_TEXT_BUF_SIZE; - } - return len; -} - -nsresult -nsLayoutUtils::SafeGetWidth(nsIRenderingContext* aContext, - const char *aString, PRUint32 aLength, nscoord& aWidth) -{ - // Since it's ASCII, we don't need to worry about clusters or RTL - aWidth = 0; - while (aLength > 0) { - PRInt32 len = PR_MIN(aLength, MAX_GFX_TEXT_BUF_SIZE); - nscoord width; - nsresult rv = aContext->GetWidth(aString, len, width); - if (NS_FAILED(rv)) - return rv; - aWidth += width; - aLength -= len; - aString += len; - } - return NS_OK; -} - -nsresult -nsLayoutUtils::SafeGetWidth(nsIRenderingContext* aContext, - const PRUnichar *aString, PRUint32 aLength, nscoord& aWidth) -{ - aWidth = 0; - while (aLength > 0) { - PRInt32 len = FindSafeLength(aContext, aString, aLength); - nscoord width; - nsresult rv = aContext->GetWidth(aString, len, width); - if (NS_FAILED(rv)) - return rv; - aWidth += width; - aLength -= len; - aString += len; - } - return NS_OK; -} - -void -nsLayoutUtils::SafeDrawString(nsIRenderingContext* aContext, - const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY) -{ - // Since it's ASCII, we don't need to worry about clusters or RTL - while (aLength > 0) { - PRInt32 len = PR_MIN(aLength, MAX_GFX_TEXT_BUF_SIZE); - aContext->DrawString(aString, len, aX, aY); - aLength -= len; - - if (aLength > 0) { - nscoord width; - aContext->GetWidth(aString, len, width); - aX += width; - aString += len; - } - } -} - -void -nsLayoutUtils::SafeDrawString(nsIRenderingContext* aContext, - const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID, - const nscoord* aSpacing) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) { - aContext->DrawString(aString, aLength, aX, aY, aFontID, aSpacing); - return; - } - - PRBool isRTL = PR_FALSE; - aContext->GetRightToLeftText(&isRTL); - - if (isRTL) { - nscoord totalWidth = 0; - if (aSpacing) { - for (PRUint32 i = 0; i < aLength; ++i) { - totalWidth += aSpacing[i]; - } - } else { - SafeGetWidth(aContext, aString, aLength, totalWidth); - } - aX += totalWidth; - } - - while (aLength > 0) { - PRInt32 len = FindSafeLength(aContext, aString, aLength); - nscoord width = 0; - if (aSpacing) { - for (PRInt32 i = 0; i < len; ++i) { - width += aSpacing[i]; - } - } else { - aContext->GetWidth(aString, len, width); - } - - if (isRTL) { - aX -= width; - } - aContext->DrawString(aString, len, aX, aY, aFontID, aSpacing); - aLength -= len; - if (!isRTL) { - aX += width; - } - aString += len; - if (aSpacing) { - aSpacing += len; - } - } -} - -void -nsLayoutUtils::SafeGetTextDimensions(nsIRenderingContext* aContext, - const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) { - aContext->GetTextDimensions(aString, aLength, aDimensions); - return; - } - - PRBool firstIteration = PR_TRUE; - while (aLength > 0) { - PRInt32 len = PR_MIN(aLength, MAX_GFX_TEXT_BUF_SIZE); - nsTextDimensions dimensions; - nsresult rv = aContext->GetTextDimensions(aString, len, dimensions); - if (NS_FAILED(rv)) - return; - if (firstIteration) { - // Instead of combining with a Clear()ed nsTextDimensions, we assign - // directly in the first iteration. This ensures that negative ascent/ - // descent can be returned. - aDimensions = dimensions; - } else { - aDimensions.Combine(dimensions); - } - aLength -= len; - aString += len; - firstIteration = PR_FALSE; - } -} - -void -nsLayoutUtils::SafeGetTextDimensions(nsIRenderingContext* aContext, - const PRUnichar* aString, PRUint32 aLength, - nsTextDimensions& aDimensions) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) { - aContext->GetTextDimensions(aString, aLength, aDimensions); - return; - } - - PRBool firstIteration = PR_TRUE; - while (aLength > 0) { - PRInt32 len = FindSafeLength(aContext, aString, aLength); - nsTextDimensions dimensions; - nsresult rv = aContext->GetTextDimensions(aString, len, dimensions); - if (NS_FAILED(rv)) - return; - if (firstIteration) { - // Instead of combining with a Clear()ed nsTextDimensions, we assign - // directly in the first iteration. This ensures that negative ascent/ - // descent can be returned. - aDimensions = dimensions; - } else { - aDimensions.Combine(dimensions); - } - aLength -= len; - aString += len; - firstIteration = PR_FALSE; - } -} - -#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) -void -nsLayoutUtils::SafeGetTextDimensions(nsIRenderingContext* aContext, - const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) { - aContext->GetTextDimensions(aString, aLength, aAvailWidth, aBreaks, aNumBreaks, - aDimensions, aNumCharsFit, aLastWordDimensions); - return; - } - - // Do a naive implementation based on 3-arg GetTextDimensions - PRInt32 x = 0; - PRInt32 wordCount; - for (wordCount = 0; wordCount < aNumBreaks; ++wordCount) { - PRInt32 lastBreak = wordCount > 0 ? aBreaks[wordCount - 1] : 0; - nsTextDimensions dimensions; - SafeGetTextDimensions(aContext, aString + lastBreak, aBreaks[wordCount], - dimensions); - x += dimensions.width; - // The first word always "fits" - if (x > aAvailWidth && wordCount > 0) - break; - // aDimensions ascent/descent should exclude the last word (unless there - // is only one word) so we let it run one word behind - if (wordCount == 0) { - aDimensions = dimensions; - } else { - aDimensions.Combine(aLastWordDimensions); - } - aNumCharsFit = aBreaks[wordCount]; - aLastWordDimensions = dimensions; - } - // aDimensions width should include all the text - aDimensions.width = x; -} - -void -nsLayoutUtils::SafeGetTextDimensions(nsIRenderingContext* aContext, - const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) { - aContext->GetTextDimensions(aString, aLength, aAvailWidth, aBreaks, aNumBreaks, - aDimensions, aNumCharsFit, aLastWordDimensions); - return; - } - - // Do a naive implementation based on 3-arg GetTextDimensions - PRInt32 x = 0; - PRInt32 wordCount; - for (wordCount = 0; wordCount < aNumBreaks; ++wordCount) { - PRInt32 lastBreak = wordCount > 0 ? aBreaks[wordCount - 1] : 0; - nsTextDimensions dimensions; - SafeGetTextDimensions(aContext, aString + lastBreak, aBreaks[wordCount], - dimensions); - x += dimensions.width; - // The first word always "fits" - if (x > aAvailWidth && wordCount > 0) - break; - // aDimensions ascent/descent should exclude the last word (unless there - // is only one word) so we let it run one word behind - if (wordCount == 0) { - aDimensions = dimensions; - } else { - aDimensions.Combine(aLastWordDimensions); - } - aNumCharsFit = aBreaks[wordCount]; - aLastWordDimensions = dimensions; - } - // aDimensions width should include all the text - aDimensions.width = x; -} -#endif - -#ifdef MOZ_MATHML -nsresult -nsLayoutUtils::SafeGetBoundingMetrics(nsIRenderingContext* aContext, - const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) - return aContext->GetBoundingMetrics(aString, aLength, aBoundingMetrics); - - PRBool firstIteration = PR_TRUE; - while (aLength > 0) { - PRInt32 len = PR_MIN(MAX_GFX_TEXT_BUF_SIZE, aLength); - nsBoundingMetrics metrics; - nsresult rv = aContext->GetBoundingMetrics(aString, len, metrics); - if (NS_FAILED(rv)) - return rv; - if (firstIteration) { - // Instead of combining with a Clear()ed nsBoundingMetrics, we assign - // directly in the first iteration. This ensures that negative ascent/ - // descent can be returned and the left bearing is properly initialized. - aBoundingMetrics = metrics; - } else { - aBoundingMetrics += metrics; - } - aLength -= len; - aString += len; - firstIteration = PR_FALSE; - } - return NS_OK; -} - -nsresult -nsLayoutUtils::SafeGetBoundingMetrics(nsIRenderingContext* aContext, - const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics) -{ - if (aLength <= MAX_GFX_TEXT_BUF_SIZE) - return aContext->GetBoundingMetrics(aString, aLength, aBoundingMetrics); - - PRBool firstIteration = PR_TRUE; - while (aLength > 0) { - PRInt32 len = FindSafeLength(aContext, aString, aLength); - nsBoundingMetrics metrics; - nsresult rv = aContext->GetBoundingMetrics(aString, len, metrics); - if (NS_FAILED(rv)) - return rv; - if (firstIteration) { - // Instead of combining with a Clear()ed nsBoundingMetrics, we assign - // directly in the first iteration. This ensures that negative ascent/ - // descent can be returned and the left bearing is properly initialized. - aBoundingMetrics = metrics; - } else { - aBoundingMetrics += metrics; - } - aLength -= len; - aString += len; - firstIteration = PR_FALSE; - } - return NS_OK; -} -#endif - nsRect nsLayoutUtils::GetAllInFlowBoundingRect(nsIFrame* aFrame) { diff --git a/mozilla/layout/base/nsLayoutUtils.h b/mozilla/layout/base/nsLayoutUtils.h index 93dccb32d9b..fc4b4e115be 100644 --- a/mozilla/layout/base/nsLayoutUtils.h +++ b/mozilla/layout/base/nsLayoutUtils.h @@ -414,86 +414,6 @@ public: */ static void ScrollIntoView(nsIFormControlFrame* aFormFrame); - // Safe wrappers around Gfx nsIRenderingContext functions to avoid passing - // long strings to unreliable platform APIs, by breaking strings up into pieces. - // - // We avoid breaking strings at bad places (e.g. inside Unicode surrogate - // pairs, or inside a cluster). However we still slightly alter output because - // we will be disabling kerning at the boundaries where we break strings. At - // least (hopefully) we disable kerning consistently when we measure and draw - // strings. - -#define MAX_GFX_TEXT_BUF_SIZE 8000 - - static nsresult SafeGetWidth(nsIRenderingContext* aContext, - const char *aString, PRUint32 aLength, - nscoord& aWidth); - static nsresult SafeGetWidth(nsIRenderingContext* aContext, - const PRUnichar *aString, PRUint32 aLength, - nscoord& aWidth); - static nsresult SafeGetWidth(nsIRenderingContext* aContext, - const char* aString, - nscoord& aWidth) { - return SafeGetWidth(aContext, aString, strlen(aString), aWidth); - } - static nsresult SafeGetWidth(nsIRenderingContext* aContext, - const nsString& aString, - nscoord& aWidth) { - return SafeGetWidth(aContext, aString.get(), aString.Length(), aWidth); - } - static void SafeDrawString(nsIRenderingContext* aContext, - const char *aString, PRUint32 aLength, - nscoord aX, nscoord aY); - static void SafeDrawString(nsIRenderingContext* aContext, - const PRUnichar *aString, PRUint32 aLength, - nscoord aX, nscoord aY, - PRInt32 aFontID = -1, - const nscoord* aSpacing = nsnull); - static void SafeDrawString(nsIRenderingContext* aContext, - const nsString& aString, - nscoord aX, nscoord aY, - PRInt32 aFontID = -1, - const nscoord* aSpacing = nsnull) { - SafeDrawString(aContext, aString.get(), aString.Length(), aX, aY, - aFontID, aSpacing); - } - static void SafeGetTextDimensions(nsIRenderingContext* aContext, - const char* aString, PRUint32 aLength, - nsTextDimensions& aDimensions); - static void SafeGetTextDimensions(nsIRenderingContext* aContext, - const PRUnichar* aString, PRUint32 aLength, - nsTextDimensions& aDimensions); -#if defined(_WIN32) || defined(XP_OS2) || defined(MOZ_X11) || defined(XP_BEOS) - static void SafeGetTextDimensions(nsIRenderingContext* aContext, - const char* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions); - static void SafeGetTextDimensions(nsIRenderingContext* aContext, - const PRUnichar* aString, - PRInt32 aLength, - PRInt32 aAvailWidth, - PRInt32* aBreaks, - PRInt32 aNumBreaks, - nsTextDimensions& aDimensions, - PRInt32& aNumCharsFit, - nsTextDimensions& aLastWordDimensions); -#endif -#ifdef MOZ_MATHML - static nsresult SafeGetBoundingMetrics(nsIRenderingContext* aContext, - const char* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); - static nsresult SafeGetBoundingMetrics(nsIRenderingContext* aContext, - const PRUnichar* aString, - PRUint32 aLength, - nsBoundingMetrics& aBoundingMetrics); -#endif - /** * Get the union of all rects in aFrame and its continuations, relative * to aFrame's origin. Scrolling is taken into account, but this shouldn't diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index e11c8f80b5a..cea16e3a995 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -2744,14 +2744,13 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState, // a placeholder and then reflow its associated float we don't // end up resetting the line's right edge and have it think the // width is unconstrained... - nsSpaceManager::SavedState spaceManagerState; - aState.mSpaceManager->PushState(&spaceManagerState); + aState.mSpaceManager->PushState(); aState.SetFlag(BRS_UNCONSTRAINEDWIDTH, PR_TRUE); ReflowInlineFrames(aState, aLine, aKeepReflowGoing, aDamageDirtyArea, PR_TRUE); aState.mY = oldY; aState.mPrevBottomMargin = oldPrevBottomMargin; aState.SetFlag(BRS_UNCONSTRAINEDWIDTH, oldUnconstrainedWidth); - aState.mSpaceManager->PopState(&spaceManagerState); + aState.mSpaceManager->PopState(); // Update the line's maximum width aLine->mMaximumWidth = aLine->mBounds.XMost(); @@ -3508,10 +3507,9 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, aState.mReflowState.reason, PR_TRUE); blockHtmlRS.mFlags.mHasClearance = aLine->HasClearance(); - nsSpaceManager::SavedState spaceManagerState; if (mayNeedRetry) { blockHtmlRS.mDiscoveredClearance = &clearanceFrame; - aState.mSpaceManager->PushState(&spaceManagerState); + aState.mSpaceManager->PushState(); } else if (!applyTopMargin) { blockHtmlRS.mDiscoveredClearance = aState.mReflowState.mDiscoveredClearance; } @@ -3528,12 +3526,19 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, return rv; } - if (mayNeedRetry && clearanceFrame) { - UndoSplitPlaceholders(aState, lastPlaceholder); - aState.mSpaceManager->PopState(&spaceManagerState); - aState.mY = startingY; - aState.mPrevBottomMargin = incomingMargin; - continue; + if (mayNeedRetry) { + if (clearanceFrame) { + UndoSplitPlaceholders(aState, lastPlaceholder); + aState.mSpaceManager->PopState(); + aState.mY = startingY; + aState.mPrevBottomMargin = incomingMargin; + continue; + } else { + // pop the saved state off the stack and discard it, because we + // want to keep the current state, since our speculation + // succeeded + aState.mSpaceManager->DiscardState(); + } } aState.mPrevChild = frame; @@ -3760,6 +3765,12 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, return rv; } +#define LINE_REFLOW_OK 0 +#define LINE_REFLOW_STOP 1 +#define LINE_REFLOW_REDO 2 +// a frame was complete, but truncated and not at the top of a page +#define LINE_REFLOW_TRUNCATED 3 + nsresult nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState, line_iterator aLine, @@ -3773,61 +3784,45 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState, #ifdef DEBUG PRInt32 spins = 0; #endif - LineReflowStatus lineReflowStatus = LINE_REFLOW_REDO_NEXT_BAND; - PRBool movedPastFloat = PR_FALSE; + PRUint8 lineReflowStatus = LINE_REFLOW_REDO; + PRBool didRedo = PR_FALSE; do { - PRBool allowPullUp = PR_TRUE; - do { - nsSpaceManager::SavedState spaceManagerState; - aState.mReflowState.mSpaceManager->PushState(&spaceManagerState); + // Once upon a time we allocated the first 30 nsLineLayout objects + // on the stack, and then we switched to the heap. At that time + // these objects were large (1100 bytes on a 32 bit system). + // Then the nsLineLayout object was shrunk to 156 bytes by + // removing some internal buffers. Given that it is so much + // smaller, the complexity of 2 different ways of allocating + // no longer makes sense. Now we always allocate on the stack + + nsLineLayout lineLayout(aState.mPresContext, + aState.mReflowState.mSpaceManager, + &aState.mReflowState, + aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)); + lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber); + rv = DoReflowInlineFrames(aState, lineLayout, aLine, + aKeepReflowGoing, &lineReflowStatus, + aUpdateMaximumWidth, aDamageDirtyArea); + lineLayout.EndLineReflow(); + + if (LINE_REFLOW_REDO == lineReflowStatus) { + didRedo = PR_TRUE; + } - // Once upon a time we allocated the first 30 nsLineLayout objects - // on the stack, and then we switched to the heap. At that time - // these objects were large (1100 bytes on a 32 bit system). - // Then the nsLineLayout object was shrunk to 156 bytes by - // removing some internal buffers. Given that it is so much - // smaller, the complexity of 2 different ways of allocating - // no longer makes sense. Now we always allocate on the stack - nsLineLayout lineLayout(aState.mPresContext, - aState.mReflowState.mSpaceManager, - &aState.mReflowState, - aState.GetFlag(BRS_COMPUTEMAXELEMENTWIDTH)); - lineLayout.Init(&aState, aState.mMinLineHeight, aState.mLineNumber); - rv = DoReflowInlineFrames(aState, lineLayout, aLine, - aKeepReflowGoing, &lineReflowStatus, - aUpdateMaximumWidth, aDamageDirtyArea, - allowPullUp); - lineLayout.EndLineReflow(); - - if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus || - LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) { - // restore the space manager state - aState.mReflowState.mSpaceManager->PopState(&spaceManagerState); - // Clear out below-current-line-floats - aState.mBelowCurrentLineFloats.DeleteAll(); - } - #ifdef DEBUG - spins++; - if (1000 == spins) { - ListTag(stdout); - printf(": yikes! spinning on a line over 1000 times!\n"); - NS_ABORT(); - } + spins++; + if (1000 == spins) { + ListTag(stdout); + printf(": yikes! spinning on a line over 1000 times!\n"); + NS_ABORT(); + } #endif - // Don't allow pullup on a subsequent LINE_REFLOW_REDO_NO_PULL pass - allowPullUp = PR_FALSE; - } while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO_NO_PULL == lineReflowStatus); + } while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO == lineReflowStatus); - if (LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) { - movedPastFloat = PR_TRUE; - } - } while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus); - - // If we did at least one REDO_FOR_FLOAT, then the line did not fit next to some float. + // If we did at least one REDO, then the line did not fit next to some float. // Mark it as impacted by a float, even if it no longer is next to a float. - if (movedPastFloat) { + if (didRedo) { aLine->SetLineIsImpactedByFloat(PR_TRUE); } @@ -3858,10 +3853,9 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, nsLineLayout& aLineLayout, line_iterator aLine, PRBool* aKeepReflowGoing, - LineReflowStatus* aLineReflowStatus, + PRUint8* aLineReflowStatus, PRBool aUpdateMaximumWidth, - PRBool aDamageDirtyArea, - PRBool aAllowPullUp) + PRBool aDamageDirtyArea) { // Forget all of the floats on the line aLine->FreeFloats(aState.mFloatCacheFreeList); @@ -3911,7 +3905,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, // Reflow the frames that are already on the line first nsresult rv = NS_OK; - LineReflowStatus lineReflowStatus = LINE_REFLOW_OK; + PRUint8 lineReflowStatus = LINE_REFLOW_OK; PRInt32 i; nsIFrame* frame = aLine->mFirstChild; aLine->SetHasPercentageChild(PR_FALSE); // To be set by ReflowInlineFrame below @@ -3958,7 +3952,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, } // Don't pull up new frames into lines with continuation placeholders - if (!isContinuingPlaceholders && aAllowPullUp) { + if (!isContinuingPlaceholders) { // Pull frames and reflow them until we can't while (LINE_REFLOW_OK == lineReflowStatus) { rv = PullFrame(aState, aLine, aDamageDirtyArea, frame); @@ -3990,7 +3984,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, } } - if (LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) { + if (LINE_REFLOW_REDO == lineReflowStatus) { // This happens only when we have a line that is impacted by // floats and the first element in the line doesn't fit with // the floats. @@ -4002,6 +3996,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aState.mAvailSpaceRect.height, "unconstrained height on totally empty line"); + if (aState.mAvailSpaceRect.height > 0) { aState.mY += aState.mAvailSpaceRect.height; } else { @@ -4034,13 +4029,6 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState, // push the line and return now instead of later on after we are // past the float. } - else if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus) { - // We don't want to advance by the bottom margin anymore (we did it - // once at the beginning of this function, which will just be called - // again), and we certainly don't want to go back if it's negative - // (infinite loop, bug 153429). - aState.mPrevBottomMargin.Zero(); - } else if (LINE_REFLOW_TRUNCATED != lineReflowStatus) { // If we are propagating out a break-before status then there is // no point in placing the line. @@ -4068,9 +4056,9 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, nsLineLayout& aLineLayout, line_iterator aLine, nsIFrame* aFrame, - LineReflowStatus* aLineReflowStatus) + PRUint8* aLineReflowStatus) { - NS_ENSURE_ARG_POINTER(aFrame); + NS_ENSURE_ARG_POINTER(aFrame); *aLineReflowStatus = LINE_REFLOW_OK; @@ -4163,12 +4151,12 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // be trying to place content where there's no room (e.g. on a // line with wide floats). Inform the caller to reflow the // line after skipping past a float. - *aLineReflowStatus = LINE_REFLOW_REDO_NEXT_BAND; + *aLineReflowStatus = LINE_REFLOW_REDO; } else { // It's not the first child on this line so go ahead and split // the line. We will see the frame again on the next-line. - rv = SplitLine(aState, aLineLayout, aLine, aFrame, aLineReflowStatus); + rv = SplitLine(aState, aLineLayout, aLine, aFrame); if (NS_FAILED(rv)) { return rv; } @@ -4211,7 +4199,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } // Split line, but after the frame just reflowed - rv = SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling(), aLineReflowStatus); + rv = SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling()); if (NS_FAILED(rv)) { return rv; } @@ -4261,7 +4249,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, if (splitLine) { // Split line after the current frame *aLineReflowStatus = LINE_REFLOW_STOP; - rv = SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling(), aLineReflowStatus); + rv = SplitLine(aState, aLineLayout, aLine, aFrame->GetNextSibling()); if (NS_FAILED(rv)) { return rv; } @@ -4343,35 +4331,11 @@ nsBlockFrame::SplitPlaceholder(nsBlockReflowState& aState, return NS_OK; } -static nsFloatCache* -GetLastFloat(nsLineBox* aLine) -{ - nsFloatCache* fc = aLine->GetFirstFloat(); - while (fc && fc->Next()) { - fc = fc->Next(); - } - return fc; -} - -static PRBool -CheckPlaceholderInLine(nsIFrame* aBlock, nsLineBox* aLine, nsFloatCache* aFC) -{ - if (!aFC) - return PR_TRUE; - for (nsIFrame* f = aFC->mPlaceholder; f; f = f->GetParent()) { - if (f->GetParent() == aBlock) - return aLine->Contains(f); - } - NS_ASSERTION(PR_FALSE, "aBlock is not an ancestor of aFrame!"); - return PR_TRUE; -} - nsresult nsBlockFrame::SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, line_iterator aLine, - nsIFrame* aFrame, - LineReflowStatus* aLineReflowStatus) + nsIFrame* aFrame) { NS_ABORT_IF_FALSE(aLine->IsInline(), "illegal SplitLine on block line"); @@ -4418,17 +4382,6 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, // Let line layout know that some frames are no longer part of its // state. aLineLayout.SplitLineTo(aLine->GetChildCount()); - - // If floats have been placed whose placeholders have been pushed to the new - // line, we need to reflow the old line again. We don't want to look at the - // frames in the new line, because as a large paragraph is laid out the - // we'd get O(N^2) performance. So instead we just check that the last - // float and the last below-current-line float are still in aLine. - if (!CheckPlaceholderInLine(this, aLine, GetLastFloat(aLine)) || - !CheckPlaceholderInLine(this, aLine, aState.mBelowCurrentLineFloats.Tail())) { - *aLineReflowStatus = LINE_REFLOW_REDO_NO_PULL; - } - #ifdef DEBUG VerifyLines(PR_TRUE); #endif diff --git a/mozilla/layout/generic/nsBlockFrame.h b/mozilla/layout/generic/nsBlockFrame.h index 915256ebdc1..bb8b72b6478 100644 --- a/mozilla/layout/generic/nsBlockFrame.h +++ b/mozilla/layout/generic/nsBlockFrame.h @@ -52,24 +52,6 @@ #include "nsCSSPseudoElements.h" #include "nsStyleSet.h" -enum LineReflowStatus { - // The line was completely reflowed and fit in available width, and we should - // try to pull up content from the next line if possible. - LINE_REFLOW_OK, - // The line was completely reflowed and fit in available width, but we should - // not try to pull up content from the next line. - LINE_REFLOW_STOP, - // We need to reflow the line again at its current vertical position. The - // new reflow should not try to pull up any frames from the next line. - LINE_REFLOW_REDO_NO_PULL, - // We need to reflow the line again at a lower vertical postion where there - // may be more horizontal space due to different float configuration. - LINE_REFLOW_REDO_NEXT_BAND, - // The line did not fit in the available vertical space. Try pushing it to - // the next page or column if it's not the first line on the current page/column. - LINE_REFLOW_TRUNCATED -}; - class nsBlockReflowState; class nsBulletFrame; class nsLineBox; @@ -484,16 +466,15 @@ protected: nsLineLayout& aLineLayout, line_iterator aLine, PRBool* aKeepReflowGoing, - LineReflowStatus* aLineReflowStatus, + PRUint8* aLineReflowStatus, PRBool aUpdateMaximumWidth, - PRBool aDamageDirtyArea, - PRBool aAllowPullUp); + PRBool aDamageDirtyArea); nsresult ReflowInlineFrame(nsBlockReflowState& aState, nsLineLayout& aLineLayout, line_iterator aLine, nsIFrame* aFrame, - LineReflowStatus* aLineReflowStatus); + PRUint8* aLineReflowStatus); // An incomplete aReflowStatus indicates the float should be split // but only if the available height is constrained. @@ -520,8 +501,7 @@ protected: nsresult SplitLine(nsBlockReflowState& aState, nsLineLayout& aLineLayout, line_iterator aLine, - nsIFrame* aFrame, - LineReflowStatus* aLineReflowStatus); + nsIFrame* aFrame); nsresult PullFrame(nsBlockReflowState& aState, line_iterator aLine, diff --git a/mozilla/layout/generic/nsBlockReflowContext.cpp b/mozilla/layout/generic/nsBlockReflowContext.cpp index 4af7fb826ae..0a384c303a9 100644 --- a/mozilla/layout/generic/nsBlockReflowContext.cpp +++ b/mozilla/layout/generic/nsBlockReflowContext.cpp @@ -618,8 +618,7 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace, // See if this is the child's initial reflow and we are supposed to // compute our maximum width if (mComputeMaximumWidth && (eReflowReason_Initial == aFrameRS.reason)) { - nsSpaceManager::SavedState spaceManagerState; - mOuterReflowState.mSpaceManager->PushState(&spaceManagerState); + mOuterReflowState.mSpaceManager->PushState(); nscoord oldAvailableWidth = aFrameRS.availableWidth; nscoord oldComputedWidth = aFrameRS.mComputedWidth; @@ -643,7 +642,7 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace, aFrameRS.mComputedWidth = oldComputedWidth; aFrameRS.reason = eReflowReason_Resize; - mOuterReflowState.mSpaceManager->PopState(&spaceManagerState); + mOuterReflowState.mSpaceManager->PopState(); } rv = mFrame->Reflow(mPresContext, mMetrics, aFrameRS, aFrameReflowStatus); diff --git a/mozilla/layout/generic/nsBlockReflowState.cpp b/mozilla/layout/generic/nsBlockReflowState.cpp index c490a85f987..fdfbabecf78 100644 --- a/mozilla/layout/generic/nsBlockReflowState.cpp +++ b/mozilla/layout/generic/nsBlockReflowState.cpp @@ -1102,7 +1102,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache, * Place below-current-line floats. */ PRBool -nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aList, PRBool aForceFit) +nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheList& aList, PRBool aForceFit) { nsFloatCache* fc = aList.Head(); while (fc) { diff --git a/mozilla/layout/generic/nsBlockReflowState.h b/mozilla/layout/generic/nsBlockReflowState.h index 0f0e4158a65..771a9504de1 100644 --- a/mozilla/layout/generic/nsBlockReflowState.h +++ b/mozilla/layout/generic/nsBlockReflowState.h @@ -99,7 +99,7 @@ public: PRBool* aIsLeftFloat, nsReflowStatus& aReflowStatus, PRBool aForceFit); - PRBool PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aFloats, PRBool aForceFit); + PRBool PlaceBelowCurrentLineFloats(nsFloatCacheList& aFloats, PRBool aForceFit); // Returns the first coordinate >= aY that clears the // indicated floats. diff --git a/mozilla/layout/generic/nsBulletFrame.cpp b/mozilla/layout/generic/nsBulletFrame.cpp index d6c85982e5d..50d63edc142 100644 --- a/mozilla/layout/generic/nsBulletFrame.cpp +++ b/mozilla/layout/generic/nsBulletFrame.cpp @@ -372,8 +372,8 @@ nsBulletFrame::PaintBullet(nsIRenderingContext& aRenderingContext, nsPoint aPt) aRenderingContext.SetFont(fm); nscoord ascent; fm->GetMaxAscent(ascent); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, mPadding.left + aPt.x, - mPadding.top + aPt.y + ascent); + aRenderingContext.DrawString(text, mPadding.left + aPt.x, + mPadding.top + aPt.y + ascent); break; } #ifdef IBMBIDI @@ -400,8 +400,8 @@ nsBulletFrame::PaintBullet(nsIRenderingContext& aRenderingContext, nsPoint aPt) charType, level, isBidiSystem);//Mohamed } } - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, mPadding.left + aPt.x, - mPadding.top + aPt.y + ascent); + aRenderingContext.DrawString(text, mPadding.left + aPt.x, + mPadding.top + aPt.y + ascent); } #endif // IBMBIDI } @@ -1615,7 +1615,7 @@ nsBulletFrame::GetDesiredSize(nsPresContext* aCX, GetListItemText(*myList, text); fm->GetHeight(aMetrics.height); aReflowState.rendContext->SetFont(fm); - nsLayoutUtils::SafeGetWidth(aReflowState.rendContext, text, aMetrics.width); + aReflowState.rendContext->GetWidth(text, aMetrics.width); aMetrics.width += mPadding.right; fm->GetMaxAscent(aMetrics.ascent); fm->GetMaxDescent(aMetrics.descent); diff --git a/mozilla/layout/generic/nsImageFrame.cpp b/mozilla/layout/generic/nsImageFrame.cpp index 2bbdedcff0a..b8fea41d4bd 100644 --- a/mozilla/layout/generic/nsImageFrame.cpp +++ b/mozilla/layout/generic/nsImageFrame.cpp @@ -1033,7 +1033,7 @@ nsImageFrame::MeasureString(const PRUnichar* aString, // Measure this chunk of text, and see if it fits nscoord width; - nsLayoutUtils::SafeGetWidth(&aContext, aString, len, width); + aContext.GetWidth(aString, len, width); PRBool fits = (totalWidth + width) <= aMaxWidth; // If it fits on the line, or it's the first word we've processed then @@ -1101,7 +1101,7 @@ nsImageFrame::DisplayAltText(nsPresContext* aPresContext, MeasureString(str, strLen, aRect.width, maxFit, aRenderingContext); // Display the text - nsLayoutUtils::SafeDrawString(&aRenderingContext, str, maxFit, aRect.x, y + maxAscent); + aRenderingContext.DrawString(str, maxFit, aRect.x, y + maxAscent); // Move to the next line str += maxFit; diff --git a/mozilla/layout/generic/nsLineBox.cpp b/mozilla/layout/generic/nsLineBox.cpp index a4c28005c23..38b3283d9fa 100644 --- a/mozilla/layout/generic/nsLineBox.cpp +++ b/mozilla/layout/generic/nsLineBox.cpp @@ -875,20 +875,14 @@ nsFloatCacheList::nsFloatCacheList() : nsFloatCacheList::~nsFloatCacheList() { - DeleteAll(); - MOZ_COUNT_DTOR(nsFloatCacheList); -} - -void -nsFloatCacheList::DeleteAll() -{ - nsFloatCache* c = mHead; - while (c) { - nsFloatCache* next = c->Next(); - delete c; - c = next; + nsFloatCache* fc = mHead; + while (fc) { + nsFloatCache* next = fc->mNext; + delete fc; + fc = next; } mHead = nsnull; + MOZ_COUNT_DTOR(nsFloatCacheList); } nsFloatCache* @@ -935,24 +929,17 @@ nsFloatCacheList::Find(nsIFrame* aOutOfFlowFrame) return fc; } -nsFloatCache* -nsFloatCacheList::RemoveAndReturnPrev(nsFloatCache* aElement) +void +nsFloatCacheList::Remove(nsFloatCache* aElement) { - NS_ASSERTION(!aElement->mNext, "Can only remove a singleton element"); - - nsFloatCache* fc = mHead; - nsFloatCache* prev = nsnull; - while (fc) { + nsFloatCache** fcp = &mHead; + nsFloatCache* fc; + while (nsnull != (fc = *fcp)) { if (fc == aElement) { - if (prev) { - prev->mNext = fc->mNext; - } else { - mHead = fc->mNext; - } - return prev; + *fcp = fc->mNext; + break; } - prev = fc; - fc = fc->mNext; + fcp = &fc->mNext; } } @@ -988,22 +975,6 @@ nsFloatCacheFreeList::Append(nsFloatCacheList& aList) aList.mHead = nsnull; } -void -nsFloatCacheFreeList::Remove(nsFloatCache* aElement) -{ - nsFloatCache* prev = nsFloatCacheList::RemoveAndReturnPrev(aElement); - if (mTail == aElement) { - mTail = prev; - } -} - -void -nsFloatCacheFreeList::DeleteAll() -{ - nsFloatCacheList::DeleteAll(); - mTail = nsnull; -} - nsFloatCache* nsFloatCacheFreeList::Alloc() { diff --git a/mozilla/layout/generic/nsLineBox.h b/mozilla/layout/generic/nsLineBox.h index f495736b222..a59123923d1 100644 --- a/mozilla/layout/generic/nsLineBox.h +++ b/mozilla/layout/generic/nsLineBox.h @@ -120,14 +120,12 @@ public: nsFloatCache* Tail() const; - void DeleteAll(); - nsFloatCache* Find(nsIFrame* aOutOfFlowFrame); // Remove a nsFloatCache from this list. Deleting this nsFloatCache // becomes the caller's responsibility. - void Remove(nsFloatCache* aElement) { RemoveAndReturnPrev(aElement); } - + void Remove(nsFloatCache* aElement); + // Steal away aList's nsFloatCache objects and put them in this // list. aList must not be empty. void Append(nsFloatCacheFreeList& aList); @@ -135,18 +133,12 @@ public: protected: nsFloatCache* mHead; - // Remove a nsFloatCache from this list. Deleting this nsFloatCache - // becomes the caller's responsibility. Returns the nsFloatCache that was - // before aElement, or nsnull if aElement was the first. - nsFloatCache* RemoveAndReturnPrev(nsFloatCache* aElement); - friend class nsFloatCacheFreeList; }; //--------------------------------------- -// Like nsFloatCacheList, but with fast access to the tail -class nsFloatCacheFreeList : private nsFloatCacheList { +class nsFloatCacheFreeList : public nsFloatCacheList { public: #ifdef NS_BUILD_REFCNT_LOGGING nsFloatCacheFreeList(); @@ -156,37 +148,15 @@ public: ~nsFloatCacheFreeList() { } #endif - // Reimplement trivial functions - PRBool IsEmpty() const { - return nsnull == mHead; - } - - nsFloatCache* Head() const { - return mHead; - } - - nsFloatCache* Tail() const { - return mTail; - } - - PRBool NotEmpty() const { - return nsnull != mHead; - } - - void DeleteAll(); - // Steal away aList's nsFloatCache objects and put them on this // free-list. aList must not be empty. void Append(nsFloatCacheList& aList); void Append(nsFloatCache* aFloatCache); - void Remove(nsFloatCache* aElement); - - // Remove an nsFloatCache object from this list and return it, or create - // a new one if this one is empty; + // Allocate a new nsFloatCache object nsFloatCache* Alloc(); - + protected: nsFloatCache* mTail; diff --git a/mozilla/layout/generic/nsPageFrame.cpp b/mozilla/layout/generic/nsPageFrame.cpp index e715e15468d..a8ff17db618 100644 --- a/mozilla/layout/generic/nsPageFrame.cpp +++ b/mozilla/layout/generic/nsPageFrame.cpp @@ -304,7 +304,7 @@ nscoord nsPageFrame::GetXPosition(nsIRenderingContext& aRenderingContext, const nsString& aStr) { PRInt32 width; - nsLayoutUtils::SafeGetWidth(&aRenderingContext, aStr.get(), aStr.Length(), width); + aRenderingContext.GetWidth(aStr, width); nscoord x = aRect.x; switch (aJust) { @@ -459,8 +459,7 @@ nsPageFrame::DrawHeaderFooter(nsPresContext* aPresContext, } if (NS_FAILED(rv)) #endif // IBMBIDI - nsLayoutUtils::SafeDrawString(&aRenderingContext, str.get(), str.Length(), - x, y + aAscent); + aRenderingContext.DrawString(str, x, y + aAscent); aRenderingContext.PopState(); #ifdef DEBUG_PRINTING diff --git a/mozilla/layout/generic/nsSpaceManager.cpp b/mozilla/layout/generic/nsSpaceManager.cpp index 1be30d02bad..b128e28abd9 100644 --- a/mozilla/layout/generic/nsSpaceManager.cpp +++ b/mozilla/layout/generic/nsSpaceManager.cpp @@ -116,6 +116,7 @@ nsSpaceManager::nsSpaceManager(nsIPresShell* aPresShell, nsIFrame* aFrame) MOZ_COUNT_CTOR(nsSpaceManager); mX = mY = 0; mFrameInfoMap = nsnull; + mSavedStates = nsnull; } void @@ -133,6 +134,14 @@ nsSpaceManager::~nsSpaceManager() MOZ_COUNT_DTOR(nsSpaceManager); mBandList.Clear(); ClearFrameInfo(); + + NS_ASSERTION(!mSavedStates, "states remaining on state stack"); + + while (mSavedStates && mSavedStates != &mAutoState){ + SpaceManagerState *state = mSavedStates; + mSavedStates = state->mNext; + delete state; + } } // static @@ -976,16 +985,17 @@ nsSpaceManager::ClearRegions() } void -nsSpaceManager::PushState(SavedState* aState) +nsSpaceManager::PushState() { - NS_PRECONDITION(aState, "Need a place to save state"); - - // This is a cheap push implementation, which + // This is a quick and dirty push implementation, which // only saves the (x,y) and last frame in the mFrameInfoMap // which is enough info to get us back to where we should be // when pop is called. // - // This push/pop mechanism is used to undo any + // The alternative would be to make full copies of the contents + // of mBandList and mFrameInfoMap and restore them when pop is + // called, but I'm not sure it's worth the effort/bloat at this + // point, since this push/pop mechanism is only used to undo any // floats that were added during the unconstrained reflow // in nsBlockReflowContext::DoReflowBlock(). (See bug 96736) // @@ -997,30 +1007,55 @@ nsSpaceManager::PushState(SavedState* aState) // reflow. In the typical case A and C will be the same, but not always. // Allowing mFloatDamage to accumulate the damage incurred during both // reflows ensures that nothing gets missed. - aState->mX = mX; - aState->mY = mY; - aState->mLowestTop = mLowestTop; + + SpaceManagerState *state; + + if(mSavedStates) { + state = new SpaceManagerState; + } else { + state = &mAutoState; + } + + NS_ASSERTION(state, "PushState() failed!"); + + if (!state) { + return; + } + + state->mX = mX; + state->mY = mY; + state->mLowestTop = mLowestTop; if (mFrameInfoMap) { - aState->mLastFrame = mFrameInfoMap->mFrame; + state->mLastFrame = mFrameInfoMap->mFrame; } else { - aState->mLastFrame = nsnull; + state->mLastFrame = nsnull; } + + // Now that we've saved our state, add it to mSavedStates. + + state->mNext = mSavedStates; + mSavedStates = state; } void -nsSpaceManager::PopState(SavedState* aState) +nsSpaceManager::PopState() { - NS_PRECONDITION(aState, "No state to restore?"); - // This is a quick and dirty pop implementation, to // match the current implementation of PushState(). The // idea here is to remove any frames that have been added // to the mFrameInfoMap since the last call to PushState(). + NS_ASSERTION(mSavedStates, "Invalid call to PopState()!"); + + if (!mSavedStates) { + return; + } + // mFrameInfoMap is LIFO so keep removing what it points // to until we hit mLastFrame. - while (mFrameInfoMap && mFrameInfoMap->mFrame != aState->mLastFrame) { + + while (mFrameInfoMap && mFrameInfoMap->mFrame != mSavedStates->mLastFrame) { RemoveRegion(mFrameInfoMap->mFrame); } @@ -1029,13 +1064,39 @@ nsSpaceManager::PopState(SavedState* aState) // removed mLastFrame from mFrameInfoMap, which means our // state is now out of sync with what we thought it should be. - NS_ASSERTION(((aState->mLastFrame && mFrameInfoMap) || - (!aState->mLastFrame && !mFrameInfoMap)), + NS_ASSERTION(((mSavedStates->mLastFrame && mFrameInfoMap) || + (!mSavedStates->mLastFrame && !mFrameInfoMap)), "Unexpected outcome!"); - mX = aState->mX; - mY = aState->mY; - mLowestTop = aState->mLowestTop; + mX = mSavedStates->mX; + mY = mSavedStates->mY; + mLowestTop = mSavedStates->mLowestTop; + + // Now that we've restored our state, pop the topmost + // state and delete it. Make sure not to delete the mAutoState element + // as it is embedded in this class + + SpaceManagerState *state = mSavedStates; + mSavedStates = mSavedStates->mNext; + if(state != &mAutoState) { + delete state; + } +} + +void +nsSpaceManager::DiscardState() +{ + NS_ASSERTION(mSavedStates, "Invalid call to DiscardState()!"); + + if (!mSavedStates) { + return; + } + + SpaceManagerState *state = mSavedStates; + mSavedStates = mSavedStates->mNext; + if(state != &mAutoState) { + delete state; + } } nscoord diff --git a/mozilla/layout/generic/nsSpaceManager.h b/mozilla/layout/generic/nsSpaceManager.h index a84df4e99a0..d77d6af2262 100644 --- a/mozilla/layout/generic/nsSpaceManager.h +++ b/mozilla/layout/generic/nsSpaceManager.h @@ -282,17 +282,6 @@ protected: nsresult RemoveRegion(nsIFrame* aFrame); public: - // Structure that stores the current state of a frame manager for - // Save/Restore purposes. - struct SavedState { - private: - nsIFrame *mLastFrame; - nscoord mX, mY; - nscoord mLowestTop; - - friend class nsSpaceManager; - }; - /** * Clears the list of regions representing the unavailable space. */ @@ -320,19 +309,21 @@ public: } /** - * Saves the current state of the space manager into aState. + * Pushes the current state of the space manager onto a state stack. */ - void PushState(SavedState* aState); + void PushState(); /** - * Restores the space manager to the saved state. - * - * These states must be managed using stack discipline. PopState can only - * be used after PushState has been used to save the state, and it can only - * be used once --- although it can be omitted; saved states can be ignored. - * States must be popped in the reverse order they were pushed. + * Restores the space manager to the state at the top of the state stack, + * then pops this state off the stack. */ - void PopState(SavedState* aState); + void PopState(); + + /** + * Pops the state off the stack without restoring it. Useful for speculative + * reflow where we're not sure if we're going to keep the result. + */ + void DiscardState(); /** * Get the top of the last region placed into the space manager, to @@ -368,6 +359,15 @@ protected: #endif }; + // Structure that stores the current state of a frame manager for + // Save/Restore purposes. + struct SpaceManagerState { + nscoord mX, mY; + nsIFrame *mLastFrame; + nscoord mLowestTop; + SpaceManagerState *mNext; + }; + public: // Doubly linked list of band rects struct BandRect : PRCListStr { @@ -440,6 +440,9 @@ protected: FrameInfo* mFrameInfoMap; nsIntervalSet mFloatDamage; + SpaceManagerState *mSavedStates; + SpaceManagerState mAutoState; + protected: FrameInfo* GetFrameInfoFor(nsIFrame* aFrame); FrameInfo* CreateFrameInfo(nsIFrame* aFrame, const nsRect& aRect); diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index b8f476c17e1..f06b49132e0 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -133,7 +133,6 @@ static NS_DEFINE_CID(kLECID, NS_ULE_CID); //---------------------------------------------------------------------- #define TEXT_BUF_SIZE 100 -#define TEXT_MAX_NUM_SEGMENTS 65 //---------------------------------------- @@ -703,7 +702,7 @@ struct nsAutoPRUint8Buffer { nsAutoPRUint8Buffer::nsAutoPRUint8Buffer() : mBuffer(mAutoBuffer), - mBufferLen(sizeof(mAutoBuffer)) + mBufferLen(TEXT_BUF_SIZE) { #ifdef DEBUG memset(mAutoBuffer, 0xdd, sizeof(mAutoBuffer)); @@ -2564,7 +2563,7 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext, } } else - nsLayoutUtils::SafeGetWidth(&aRenderingContext, aText, start, startOffset); + aRenderingContext.GetWidth(aText, start, startOffset); } if (sp){ for (i = start; i < end;i ++){ @@ -2572,8 +2571,8 @@ nsTextFrame::PaintTextDecorations(nsIRenderingContext& aRenderingContext, } } else - nsLayoutUtils::SafeGetWidth(&aRenderingContext, aText + start, - PRUint32(end - start), textWidth); + aRenderingContext.GetWidth(aText + start, + PRUint32(end - start), textWidth); } nscolor lineColor; @@ -2951,7 +2950,7 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, // simplest rendering approach aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); PaintTextDecorations(aRenderingContext, aStyleContext, aPresContext, aTextStyle, dx, dy, width); } @@ -3038,7 +3037,7 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, #ifdef IBMBIDI // Simon - display substrings RTL in RTL frame nscoord FrameWidth = 0; if (isRightToLeftOnBidiPlatform) - if (NS_SUCCEEDED(nsLayoutUtils::SafeGetWidth(&aRenderingContext, text, textLength, FrameWidth))) + if (NS_SUCCEEDED(aRenderingContext.GetWidth(text, textLength, FrameWidth))) currentX = dx + FrameWidth; #endif while (!iter.IsDone()) @@ -3062,7 +3061,7 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, newWidth = nscoord(tmpWidth); } else { - rv = nsLayoutUtils::SafeGetWidth(&aRenderingContext, currenttext, currentlength,newWidth); //ADJUST FOR CHAR SPACING + rv = aRenderingContext.GetWidth(currenttext, currentlength,newWidth); //ADJUST FOR CHAR SPACING } if (NS_SUCCEEDED(rv)) { if (isRightToLeftOnBidiPlatform) @@ -3090,10 +3089,10 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, if (isPaginated && !iter.IsBeforeOrAfter()) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); } else if (!isPaginated) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(currentFGColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); } aRenderingContext.PopState(); @@ -3109,7 +3108,7 @@ nsTextFrame::PaintUnicodeText(nsPresContext* aPresContext, else if (!isPaginated || (aPresContext->Type() == nsPresContext::eContext_PageLayout)) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); } } PaintTextDecorations(aRenderingContext, aStyleContext, aPresContext, @@ -3318,7 +3317,7 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext, // Render the text with the color specified first. aRenderingContext.SetColor(textColor); // Measure previous run of characters using the previous font - nsLayoutUtils::SafeDrawString(&aRenderingContext, runStart, pendingCount, + aRenderingContext.DrawString(runStart, pendingCount, aX, aY + mAscent, -1, spacing ? sp0 : nsnull); @@ -3399,7 +3398,7 @@ nsTextFrame::RenderString(nsIRenderingContext& aRenderingContext, // Render the text with the color specified first. aRenderingContext.SetColor(textColor); // Measure previous run of characters using the previous font - nsLayoutUtils::SafeDrawString(&aRenderingContext, runStart, pendingCount, aX, aY + mAscent, -1, + aRenderingContext.DrawString(runStart, pendingCount, aX, aY + mAscent, -1, spacing ? sp0 : nsnull); // Note: use aY not small-y so that decorations are drawn with @@ -3921,7 +3920,7 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, // When there is no selection showing, use the fastest and // simplest rendering approach aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); PaintTextDecorations(aRenderingContext, aStyleContext, aPresContext, aTextStyle, dx, dy, width); } @@ -3962,7 +3961,7 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, clusterHint &= NS_RENDERING_HINT_TEXT_CLUSTERS; nscoord foo; - nsLayoutUtils::SafeGetWidth(&aRenderingContext, text, textLength, foo); + aRenderingContext.GetWidth(text, textLength, foo); if (!iter.IsDone() && iter.First()) { @@ -3983,7 +3982,7 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, newWidth = nscoord(tmpWidth); } else { - rv = nsLayoutUtils::SafeGetWidth(&aRenderingContext, currenttext, currentlength,newWidth); //ADJUST FOR CHAR SPACING + rv = aRenderingContext.GetWidth(currenttext, currentlength,newWidth); //ADJUST FOR CHAR SPACING } PRBool isSelection = iter.GetSelectionColors(¤tFGColor, @@ -4010,10 +4009,10 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, if (!isDynamic && !iter.IsBeforeOrAfter()) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); } else if (isDynamic) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(currentFGColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); } aRenderingContext.PopState(); @@ -4026,7 +4025,7 @@ nsTextFrame::PaintAsciiText(nsPresContext* aPresContext, else if (isDynamic) { aRenderingContext.SetColor(nsCSSRendering::TransformColor(aTextStyle.mColor->mColor,canDarkenColor)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, PRUint32(textLength), dx, dy + mAscent); + aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy + mAscent); } } @@ -4423,7 +4422,7 @@ nsTextFrame::GetPointFromOffset(nsPresContext* aPresContext, // no need to re-measure when at the end of the last-in-flow } else - nsLayoutUtils::SafeGetWidth(inRendContext, paintBuffer.mBuffer, hitLength, width); + inRendContext->GetWidth(paintBuffer.mBuffer, hitLength, width); } if ((hitLength == textLength) && (TEXT_TRIMMED_WS & mState)) { // @@ -5043,6 +5042,8 @@ nsTextFrame::GetOffsets(PRInt32 &start, PRInt32 &end) const return NS_OK; } +#define TEXT_MAX_NUM_SEGMENTS 65 + struct SegmentData { PRUint32 mIsWhitespace : 1; PRUint32 mContentLen : 31; // content length @@ -5424,9 +5425,9 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, else { // Measure just the one word if (aTx.TransformedTextIsAscii()) { - nsLayoutUtils::SafeGetTextDimensions(aReflowState.rendContext, bp1, wordLen, dimensions); + aReflowState.rendContext->GetTextDimensions(bp1, wordLen, dimensions); } else { - nsLayoutUtils::SafeGetTextDimensions(aReflowState.rendContext, bp2, wordLen, dimensions); + aReflowState.rendContext->GetTextDimensions(bp2, wordLen, dimensions); } #ifdef MOZ_MATHML // If GetBoundingMetrics is available, use the exact glyph metrics @@ -5436,9 +5437,9 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, nsresult res; nsBoundingMetrics bm; if (aTx.TransformedTextIsAscii()) { - res = nsLayoutUtils::SafeGetBoundingMetrics(aReflowState.rendContext, bp1, wordLen, bm); + res = aReflowState.rendContext->GetBoundingMetrics(bp1, wordLen, bm); } else { - res = nsLayoutUtils::SafeGetBoundingMetrics(aReflowState.rendContext, bp2, wordLen, bm); + res = aReflowState.rendContext->GetBoundingMetrics(bp2, wordLen, bm); } if (NS_SUCCEEDED(res)) { aTextData.mAscent = dimensions.ascent = bm.ascent; @@ -5519,15 +5520,15 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, PRInt32 numCharsFit; // These calls can return numCharsFit not positioned at a break in the textRun. Beware. if (aTx.TransformedTextIsAscii()) { - nsLayoutUtils::SafeGetTextDimensions(aReflowState.rendContext, (char*)aTx.GetWordBuffer(), textRun.mTotalNumChars, - maxWidth - aTextData.mX, - textRun.mBreaks, textRun.mNumSegments, - dimensions, numCharsFit, lastWordDimensions); + aReflowState.rendContext->GetTextDimensions((char*)aTx.GetWordBuffer(), textRun.mTotalNumChars, + maxWidth - aTextData.mX, + textRun.mBreaks, textRun.mNumSegments, + dimensions, numCharsFit, lastWordDimensions); } else { - nsLayoutUtils::SafeGetTextDimensions(aReflowState.rendContext, aTx.GetWordBuffer(), textRun.mTotalNumChars, - maxWidth - aTextData.mX, - textRun.mBreaks, textRun.mNumSegments, - dimensions, numCharsFit, lastWordDimensions); + aReflowState.rendContext->GetTextDimensions(aTx.GetWordBuffer(), textRun.mTotalNumChars, + maxWidth - aTextData.mX, + textRun.mBreaks, textRun.mNumSegments, + dimensions, numCharsFit, lastWordDimensions); } // See how much of the text fit if ((0 != aTextData.mX) && aTextData.mWrapping && (aTextData.mX + dimensions.width > maxWidth)) { @@ -5717,7 +5718,7 @@ nsTextFrame::MeasureText(nsPresContext* aPresContext, lastWordLen, PR_FALSE, &lastWordDimensions); } else { - nsLayoutUtils::SafeGetTextDimensions(aReflowState.rendContext, pWordBuf, lastWordLen, lastWordDimensions); + aReflowState.rendContext->GetTextDimensions(pWordBuf, lastWordLen, lastWordDimensions); if (aTs.mLetterSpacing) { lastWordDimensions.width += aTs.mLetterSpacing * lastWordLen; } @@ -6090,7 +6091,7 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, if (calcMathMLMetrics) { SetFontFromStyle(aReflowState.rendContext, mStyleContext); nsBoundingMetrics bm; - rv = nsLayoutUtils::SafeGetBoundingMetrics(aReflowState.rendContext, textBuffer.mBuffer, textLength, bm); + rv = aReflowState.rendContext->GetBoundingMetrics(textBuffer.mBuffer, textLength, bm); if (NS_SUCCEEDED(rv)) aMetrics.mBoundingMetrics = bm; else { @@ -6460,7 +6461,7 @@ nsTextFrame::ComputeWordFragmentDimensions(nsPresContext* aPresContext, MeasureSmallCapsText(aReflowState, ts, bp, wordLen, PR_FALSE, &dimensions); } else { - nsLayoutUtils::SafeGetTextDimensions(&rc, bp, wordLen, dimensions); + rc.GetTextDimensions(bp, wordLen, dimensions); // NOTE: Don't forget to add letter spacing for the word fragment! dimensions.width += wordLen*ts.mLetterSpacing; if (ts.mWordSpacing) { diff --git a/mozilla/layout/mathml/base/src/nsMathMLChar.cpp b/mozilla/layout/mathml/base/src/nsMathMLChar.cpp index 4fc659cb2c5..e7a144ef244 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLChar.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLChar.cpp @@ -1541,9 +1541,9 @@ nsMathMLChar::Stretch(nsPresContext* aPresContext, PRUnichar uchar = mData[0]; SetBaseFamily(uchar, theFont); aRenderingContext.SetFont(theFont, nsnull); - rv = nsLayoutUtils::SafeGetBoundingMetrics(&aRenderingContext, mData.get(), - PRUint32(mData.Length()), - mBoundingMetrics); + rv = aRenderingContext.GetBoundingMetrics(mData.get(), + PRUint32(mData.Length()), + mBoundingMetrics); if (NS_FAILED(rv)) { NS_WARNING("GetBoundingMetrics failed"); // ensure that the char later behaves like a normal char @@ -2140,8 +2140,8 @@ nsMathMLChar::PaintForeground(nsPresContext* aPresContext, aRenderingContext.SetFont(theFont, nsnull); //printf("Painting %04X like a normal char\n", mData[0]); //aRenderingContext.SetColor(NS_RGB(255,0,0)); - nsLayoutUtils::SafeDrawString(&aRenderingContext, mData.get(), len, mRect.x + aPt.x, - mRect.y + aPt.y + mBoundingMetrics.ascent); + aRenderingContext.DrawString(mData.get(), len, mRect.x + aPt.x, + mRect.y + aPt.y + mBoundingMetrics.ascent); } else { // Set the stretchy font and grab some metrics to adjust the placements ... diff --git a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp index 3a5051087db..baa5c1cfa89 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmfencedFrame.cpp @@ -46,7 +46,6 @@ #include "nsStyleConsts.h" #include "nsIRenderingContext.h" #include "nsIFontMetrics.h" -#include "nsLayoutUtils.h" #include "nsMathMLmfencedFrame.h" @@ -514,7 +513,7 @@ nsMathMLmfencedFrame::ReflowChar(nsPresContext* aPresContext, leading = 0; if (NS_FAILED(res)) { nsTextDimensions dimensions; - nsLayoutUtils::SafeGetTextDimensions(&aRenderingContext, data.get(), data.Length(), dimensions); + aRenderingContext.GetTextDimensions(data.get(), data.Length(), dimensions); charSize.ascent = dimensions.ascent; charSize.descent = dimensions.descent; charSize.width = dimensions.width; diff --git a/mozilla/layout/xul/base/src/nsTextBoxFrame.cpp b/mozilla/layout/xul/base/src/nsTextBoxFrame.cpp index d7cfcad46cc..a2ad1229f1f 100644 --- a/mozilla/layout/xul/base/src/nsTextBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsTextBoxFrame.cpp @@ -468,15 +468,13 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext, // underline position by getting the text metric. // XXX are attribute values always two byte? if (mAccessKeyInfo->mAccesskeyIndex > 0) - nsLayoutUtils::SafeGetWidth(&aRenderingContext, mCroppedTitle.get(), - mAccessKeyInfo->mAccesskeyIndex, - mAccessKeyInfo->mBeforeWidth); + aRenderingContext.GetWidth(mCroppedTitle.get(), mAccessKeyInfo->mAccesskeyIndex, + mAccessKeyInfo->mBeforeWidth); else mAccessKeyInfo->mBeforeWidth = 0; } - nsLayoutUtils::SafeDrawString(&aRenderingContext, mCroppedTitle, - textRect.x, textRect.y + baseline); + aRenderingContext.DrawString(mCroppedTitle, textRect.x, textRect.y + baseline); } if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { @@ -513,7 +511,6 @@ nsTextBoxFrame::CalculateUnderline(nsIRenderingContext& aRenderingContext) // Calculate all fields of mAccessKeyInfo which // are the same for both BiDi and non-BiDi rames. const PRUnichar *titleString = mCroppedTitle.get(); - // XXX this doesn't handle clusters... or UTF16 surrogate pairs aRenderingContext.GetWidth(titleString[mAccessKeyInfo->mAccesskeyIndex], mAccessKeyInfo->mAccessWidth); @@ -541,7 +538,7 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, aRenderingContext.SetFont(fontMet); // see if the text will completely fit in the width given - nsLayoutUtils::SafeGetWidth(&aRenderingContext, mTitle, mTitleWidth); + aRenderingContext.GetWidth(mTitle, mTitleWidth); if (mTitleWidth <= aWidth) { mCroppedTitle = mTitle; @@ -651,7 +648,7 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, case CropCenter: { nscoord stringWidth = 0; - nsLayoutUtils::SafeGetWidth(&aRenderingContext, mTitle, stringWidth); + aRenderingContext.GetWidth(mTitle, stringWidth); if (stringWidth <= aWidth) { // the entire string will fit in the maximum width mCroppedTitle.Insert(mTitle, 0); @@ -712,7 +709,7 @@ nsTextBoxFrame::CalculateTitleForWidth(nsPresContext* aPresContext, break; } - nsLayoutUtils::SafeGetWidth(&aRenderingContext, mCroppedTitle, mTitleWidth); + aRenderingContext.GetWidth(mCroppedTitle, mTitleWidth); } // the following block is to append the accesskey to mTitle if there is an accesskey @@ -838,7 +835,7 @@ nsTextBoxFrame::GetTextSize(nsPresContext* aPresContext, nsIRenderingContext& aR *getter_AddRefs(fontMet)); fontMet->GetHeight(aSize.height); aRenderingContext.SetFont(fontMet); - nsLayoutUtils::SafeGetWidth(&aRenderingContext, aString, aSize.width); + aRenderingContext.GetWidth(aString, aSize.width); fontMet->GetMaxAscent(aAscent); } diff --git a/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp index 2141b770c3b..d6a76124fcb 100644 --- a/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp +++ b/mozilla/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp @@ -1222,7 +1222,7 @@ nsTreeBodyFrame::GetCoordsForCellItem(PRInt32 aRow, nsITreeColumn* aCol, const n rc->SetFont(fm); nscoord width; - nsLayoutUtils::SafeGetWidth(rc, cellText, width); + rc->GetWidth(cellText, width); nscoord totalTextWidth = width + bp.left + bp.right; if (totalTextWidth < remainWidth) { @@ -1265,7 +1265,7 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, nsRect& aTextRect) { nscoord width; - nsLayoutUtils::SafeGetWidth(&aRenderingContext, aText, width); + aRenderingContext.GetWidth(aText, width); nscoord maxWidth = aTextRect.width; @@ -1391,7 +1391,7 @@ nsTreeBodyFrame::AdjustForCellText(nsAutoString& aText, } } - nsLayoutUtils::SafeGetWidth(&aRenderingContext, aText, width); + aRenderingContext.GetWidth(aText, width); aTextRect.width = width; } @@ -1638,7 +1638,7 @@ nsTreeBodyFrame::GetCellWidth(PRInt32 aRow, nsTreeColumn* aCol, // Get the width of the text itself nscoord width; - nsLayoutUtils::SafeGetWidth(aRenderingContext, cellText, width); + aRenderingContext->GetWidth(cellText, width); nscoord totalTextWidth = width + bp.left + bp.right; aDesiredSize += totalTextWidth; } @@ -3402,7 +3402,7 @@ nsTreeBodyFrame::PaintText(PRInt32 aRowIndex, } if (NS_FAILED(rv)) #endif // IBMBIDI - nsLayoutUtils::SafeDrawString(&aRenderingContext, text, textRect.x, textRect.y + baseline); + aRenderingContext.DrawString(text, textRect.x, textRect.y + baseline); #ifdef MOZ_TIMELINE NS_TIMELINE_STOP_TIMER("Render Outline Text"); NS_TIMELINE_MARK_TIMER("Render Outline Text");