Bug 613696. Always use the presshell's reference rendering context to create textruns when we draw text via nsIThebesFontMetrics::DrawString, to be consistent with the textruns we measure during reflow. r=dbaron,a=blocking

This commit is contained in:
Robert O'Callahan 2011-01-17 09:23:33 +13:00
Родитель 067b6d4ab4
Коммит fc3314bc13
8 изменённых файлов: 53 добавлений и 22 удалений

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

@ -52,7 +52,6 @@ public:
// want it in another format.
virtual nsresult GetWidth(const char* aString, PRUint32 aLength,
nscoord& aWidth, nsThebesRenderingContext *aContext) = 0;
// aCachedOffset will be updated with a new offset.
virtual nsresult GetWidth(const PRUnichar* aString, PRUint32 aLength,
nscoord& aWidth, PRInt32 *aFontID,
nsThebesRenderingContext *aContext) = 0;
@ -86,12 +85,15 @@ public:
nscoord aX, nscoord aY,
const nscoord* aSpacing,
nsThebesRenderingContext *aContext) = 0;
// aCachedOffset will be updated with a new offset.
virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing,
nsThebesRenderingContext *aContext) = 0;
virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
nscoord aX, nscoord aY,
nsIRenderingContext *aContext,
nsIRenderingContext *aTextRunConstructionContext) = 0;
#ifdef MOZ_MATHML
// These two functions get the bounding metrics for this handle,

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

@ -406,16 +406,14 @@ nsThebesFontMetrics::DrawString(const char *aString, PRUint32 aLength,
nsresult
nsThebesFontMetrics::DrawString(const PRUnichar* aString, PRUint32 aLength,
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing,
nsThebesRenderingContext *aContext)
nsIRenderingContext *aContext,
nsIRenderingContext *aTextRunConstructionContext)
{
if (aLength == 0)
return NS_OK;
NS_ASSERTION(!aSpacing, "Spacing not supported here");
StubPropertyProvider provider;
AutoTextRun textRun(this, aContext, aString, aLength);
AutoTextRun textRun(this, aTextRunConstructionContext, aString, aLength);
if (!textRun.get())
return NS_ERROR_FAILURE;
gfxPoint pt(aX, aY);

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

@ -121,7 +121,15 @@ public:
nscoord aX, nscoord aY,
PRInt32 aFontID,
const nscoord* aSpacing,
nsThebesRenderingContext *aContext);
nsThebesRenderingContext *aContext)
{
NS_ASSERTION(!aSpacing, "Spacing not supported here");
return DrawString(aString, aLength, aX, aY, aContext, aContext);
}
virtual nsresult DrawString(const PRUnichar* aString, PRUint32 aLength,
nscoord aX, nscoord aY,
nsIRenderingContext *aContext,
nsIRenderingContext *aTextRunConstructionContext);
#ifdef MOZ_MATHML
// These two functions get the bounding metrics for this handle,

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

@ -56,6 +56,7 @@
#include "nsContainerFrame.h"
#include "nsFirstLetterFrame.h"
#include "gfxUnicodeProperties.h"
#include "nsIThebesFontMetrics.h"
using namespace mozilla;
@ -1628,8 +1629,9 @@ nsresult nsBidiPresUtils::ProcessText(const PRUnichar* aText,
class NS_STACK_CLASS nsIRenderingContextBidiProcessor : public nsBidiPresUtils::BidiProcessor {
public:
nsIRenderingContextBidiProcessor(nsIRenderingContext* aCtx,
nsIRenderingContext* aTextRunConstructionContext,
const nsPoint& aPt)
: mCtx(aCtx), mPt(aPt) { }
: mCtx(aCtx), mTextRunConstructionContext(aTextRunConstructionContext), mPt(aPt) { }
~nsIRenderingContextBidiProcessor()
{
@ -1640,7 +1642,7 @@ public:
PRInt32 aLength,
nsBidiDirection aDirection)
{
mCtx->SetTextRunRTL(aDirection==NSBIDI_RTL);
mTextRunConstructionContext->SetTextRunRTL(aDirection==NSBIDI_RTL);
mText = aText;
mLength = aLength;
}
@ -1648,18 +1650,23 @@ public:
virtual nscoord GetWidth()
{
nscoord width;
mCtx->GetWidth(mText, mLength, width, nsnull);
mTextRunConstructionContext->GetWidth(mText, mLength, width, nsnull);
return width;
}
virtual void DrawText(nscoord aXOffset,
nscoord)
{
mCtx->DrawString(mText, mLength, mPt.x + aXOffset, mPt.y);
nsCOMPtr<nsIFontMetrics> metrics;
mCtx->GetFontMetrics(*getter_AddRefs(metrics));
nsIThebesFontMetrics* fm = static_cast<nsIThebesFontMetrics*>(metrics.get());
fm->DrawString(mText, mLength, mPt.x + aXOffset, mPt.y,
mCtx, mTextRunConstructionContext);
}
private:
nsIRenderingContext* mCtx;
nsIRenderingContext* mTextRunConstructionContext;
nsPoint mPt;
const PRUnichar* mText;
PRInt32 mLength;
@ -1671,6 +1678,7 @@ nsresult nsBidiPresUtils::ProcessTextForRenderingContext(const PRUnichar*
nsBidiDirection aBaseDirection,
nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIRenderingContext& aTextRunConstructionContext,
Mode aMode,
nscoord aX,
nscoord aY,
@ -1678,7 +1686,7 @@ nsresult nsBidiPresUtils::ProcessTextForRenderingContext(const PRUnichar*
PRInt32 aPosResolveCount,
nscoord* aWidth)
{
nsIRenderingContextBidiProcessor processor(&aRenderingContext, nsPoint(aX, aY));
nsIRenderingContextBidiProcessor processor(&aRenderingContext, &aTextRunConstructionContext, nsPoint(aX, aY));
return ProcessText(aText, aLength, aBaseDirection, aPresContext, processor,
aMode, aPosResolve, aPosResolveCount, aWidth);

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

@ -208,7 +208,8 @@ public:
* NSBIDI_LTR - left-to-right string
* NSBIDI_RTL - right-to-left string
* @param aPresContext the presentation context
* @param aRenderingContext the rendering context
* @param aRenderingContext the rendering context to render to
* @param aTextRunConstructionContext the rendering context to be used to construct the textrun (affects font hinting)
* @param aX the x-coordinate to render the string
* @param aY the y-coordinate to render the string
* @param[in,out] aPosResolve array of logical positions to resolve into visual positions; can be nsnull if this functionality is not required
@ -219,13 +220,14 @@ public:
nsBidiDirection aBaseDirection,
nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIRenderingContext& aTextRunConstructionContext,
nscoord aX,
nscoord aY,
nsBidiPositionResolve* aPosResolve = nsnull,
PRInt32 aPosResolveCount = 0)
{
return ProcessTextForRenderingContext(aText, aLength, aBaseDirection, aPresContext, aRenderingContext,
MODE_DRAW, aX, aY, aPosResolve, aPosResolveCount, nsnull);
aTextRunConstructionContext, MODE_DRAW, aX, aY, aPosResolve, aPosResolveCount, nsnull);
}
nscoord MeasureTextWidth(const PRUnichar* aText,
@ -235,7 +237,8 @@ public:
nsIRenderingContext& aRenderingContext)
{
nscoord length;
nsresult rv = ProcessTextForRenderingContext(aText, aLength, aBaseDirection, aPresContext, aRenderingContext,
nsresult rv = ProcessTextForRenderingContext(aText, aLength, aBaseDirection, aPresContext,
aRenderingContext, aRenderingContext,
MODE_MEASURE, 0, 0, nsnull, 0, &length);
return NS_SUCCEEDED(rv) ? length : 0;
}
@ -350,6 +353,7 @@ private:
nsBidiDirection aBaseDirection,
nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,
nsIRenderingContext& aTextRunConstructionContext,
Mode aMode,
nscoord aX, // DRAW only
nscoord aY, // DRAW only

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

@ -2720,7 +2720,7 @@ nsLayoutUtils::DrawString(const nsIFrame* aFrame,
(NS_STYLE_DIRECTION_RTL == aDirection) ?
NSBIDI_RTL : NSBIDI_LTR;
rv = bidiUtils->RenderText(aString, aLength, direction,
presContext, *aContext,
presContext, *aContext, *aContext,
aPoint.x, aPoint.y);
}
}

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

@ -993,10 +993,12 @@ nsImageFrame::DisplayAltText(nsPresContext* aPresContext,
if (vis->mDirection == NS_STYLE_DIRECTION_RTL)
rv = bidiUtils->RenderText(str, maxFit, NSBIDI_RTL,
aPresContext, aRenderingContext,
aRenderingContext,
aRect.XMost() - strWidth, y + maxAscent);
else
rv = bidiUtils->RenderText(str, maxFit, NSBIDI_LTR,
aPresContext, aRenderingContext,
aRenderingContext,
aRect.x, y + maxAscent);
}
}

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

@ -72,6 +72,7 @@
#include "nsCSSRendering.h"
#include "nsIReflowCallback.h"
#include "nsBoxFrame.h"
#include "nsIThebesFontMetrics.h"
#ifdef IBMBIDI
#include "nsBidiUtils.h"
@ -503,9 +504,13 @@ nsTextBoxFrame::DrawText(nsIRenderingContext& aRenderingContext,
}
}
aRenderingContext.SetFont(fontMet);
nsCOMPtr<nsIRenderingContext> refContext =
PresContext()->PresShell()->GetReferenceRenderingContext();
CalculateUnderline(aRenderingContext);
aRenderingContext.SetFont(fontMet);
refContext->SetFont(fontMet);
CalculateUnderline(*refContext);
aRenderingContext.SetColor(aOverrideColor ? *aOverrideColor : GetStyleColor()->mColor);
@ -526,6 +531,7 @@ nsTextBoxFrame::DrawText(nsIRenderingContext& aRenderingContext,
posResolve.logicalIndex = mAccessKeyInfo->mAccesskeyIndex;
rv = bidiUtils->RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
presContext, aRenderingContext,
*refContext,
aTextRect.x, baseline,
&posResolve,
1);
@ -536,6 +542,7 @@ nsTextBoxFrame::DrawText(nsIRenderingContext& aRenderingContext,
{
rv = bidiUtils->RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
presContext, aRenderingContext,
*refContext,
aTextRect.x, baseline);
}
}
@ -550,13 +557,15 @@ nsTextBoxFrame::DrawText(nsIRenderingContext& aRenderingContext,
// underline position by getting the text metric.
// XXX are attribute values always two byte?
if (mAccessKeyInfo->mAccesskeyIndex > 0)
aRenderingContext.GetWidth(mCroppedTitle.get(), mAccessKeyInfo->mAccesskeyIndex,
mAccessKeyInfo->mBeforeWidth);
refContext->GetWidth(mCroppedTitle.get(), mAccessKeyInfo->mAccesskeyIndex,
mAccessKeyInfo->mBeforeWidth);
else
mAccessKeyInfo->mBeforeWidth = 0;
}
aRenderingContext.DrawString(mCroppedTitle, aTextRect.x, baseline);
nsIThebesFontMetrics* fm = static_cast<nsIThebesFontMetrics*>(fontMet.get());
fm->DrawString(mCroppedTitle.get(), mCroppedTitle.Length(),
aTextRect.x, baseline, &aRenderingContext, refContext.get());
}
if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {