зеркало из https://github.com/mozilla/pjs.git
fixing CSS letter-spacing on windows. bug 327184. r=vlad
This commit is contained in:
Родитель
0f782f6059
Коммит
fa798d27b2
|
@ -732,5 +732,4 @@ nsThebesDeviceContext::FindScreen(nsIScreen** outScreen)
|
|||
#endif
|
||||
|
||||
mScreenManager->GetPrimaryScreen(outScreen);
|
||||
|
||||
}
|
||||
|
|
|
@ -286,7 +286,7 @@ nsThebesFontMetrics::GetWidth(const char* aString, PRUint32 aLength, nscoord& aW
|
|||
|
||||
textrun->SetRightToLeft(mIsRTL);
|
||||
|
||||
aWidth = ROUND_TO_TWIPS(textrun->MeasureString(aContext->Thebes()));
|
||||
aWidth = ROUND_TO_TWIPS(textrun->Measure(aContext->Thebes()));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ nsThebesFontMetrics::GetWidth(const PRUnichar* aString, PRUint32 aLength,
|
|||
|
||||
textrun->SetRightToLeft(mIsRTL);
|
||||
|
||||
aWidth = ROUND_TO_TWIPS(textrun->MeasureString(aContext->Thebes()));
|
||||
aWidth = ROUND_TO_TWIPS(textrun->Measure(aContext->Thebes()));
|
||||
|
||||
return NS_OK;
|
||||
|
||||
|
@ -366,7 +366,14 @@ nsThebesFontMetrics::DrawString(const char *aString, PRUint32 aLength,
|
|||
|
||||
textrun->SetRightToLeft(mIsRTL);
|
||||
|
||||
textrun->DrawString(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev)));
|
||||
if (aSpacing) {
|
||||
nsTArray<gfxFloat> spacing(aLength);
|
||||
for (PRUint32 i = 0; i < aLength; ++i)
|
||||
spacing.AppendElement(aSpacing[i] * app2dev);
|
||||
textrun->SetSpacing(spacing);
|
||||
}
|
||||
|
||||
textrun->Draw(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -389,7 +396,14 @@ nsThebesFontMetrics::DrawString(const PRUnichar* aString, PRUint32 aLength,
|
|||
|
||||
textrun->SetRightToLeft(mIsRTL);
|
||||
|
||||
textrun->DrawString(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev)));
|
||||
if (aSpacing) {
|
||||
nsTArray<gfxFloat> spacing(aLength);
|
||||
for (PRUint32 i = 0; i < aLength; ++i)
|
||||
spacing.AppendElement(aSpacing[i] * app2dev);
|
||||
textrun->SetSpacing(spacing);
|
||||
}
|
||||
|
||||
textrun->Draw(aContext->Thebes(), gfxPoint(NSToIntRound(aX * app2dev), NSToIntRound(aY * app2dev)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -103,8 +103,11 @@ public:
|
|||
gfxAtsuiTextRun(const nsAString& aString, gfxAtsuiFontGroup *aFontGroup);
|
||||
~gfxAtsuiTextRun();
|
||||
|
||||
virtual void DrawString(gfxContext *aContext, gfxPoint pt);
|
||||
virtual gfxFloat MeasureString(gfxContext *aContext);
|
||||
virtual void Draw(gfxContext *aContext, gfxPoint pt);
|
||||
virtual gfxFloat Measure(gfxContext *aContext);
|
||||
|
||||
virtual void SetSpacing(const nsTArray<gfxFloat>& spacingArray);
|
||||
virtual const nsTArray<gfxFloat> *const GetSpacing() const;
|
||||
|
||||
private:
|
||||
nsString mString;
|
||||
|
|
|
@ -202,12 +202,14 @@ class NS_EXPORT gfxTextRun {
|
|||
THEBES_DECL_REFCOUNTING_ABSTRACT
|
||||
|
||||
public:
|
||||
virtual void DrawString(gfxContext *aContext,
|
||||
gfxPoint pt) = 0;
|
||||
|
||||
virtual void Draw(gfxContext *aContext, gfxPoint pt) = 0;
|
||||
// returns length in pixels
|
||||
virtual gfxFloat MeasureString(gfxContext *aContext) = 0;
|
||||
virtual gfxFloat Measure(gfxContext *aContext) = 0;
|
||||
|
||||
virtual void SetSpacing(const nsTArray<gfxFloat> &spacing) = 0;
|
||||
virtual const nsTArray<gfxFloat> *const GetSpacing() const = 0;
|
||||
|
||||
// defaults to FALSE
|
||||
virtual void SetRightToLeft(PRBool aIsRTL) { mIsRTL = aIsRTL; }
|
||||
virtual PRBool IsRightToLeft() const { return mIsRTL; }
|
||||
|
||||
|
|
|
@ -95,8 +95,11 @@ public:
|
|||
gfxPangoTextRun(const nsAString& aString, gfxPangoFontGroup *aFontGroup);
|
||||
~gfxPangoTextRun();
|
||||
|
||||
virtual void DrawString(gfxContext *aContext, gfxPoint pt);
|
||||
virtual gfxFloat MeasureString(gfxContext *aContext);
|
||||
virtual void Draw(gfxContext *aContext, gfxPoint pt);
|
||||
virtual gfxFloat Measure(gfxContext *aContext);
|
||||
|
||||
virtual void SetSpacing(const nsTArray<gfxFloat>& spacingArray);
|
||||
virtual const nsTArray<gfxFloat> *const GetSpacing() const;
|
||||
|
||||
private:
|
||||
nsString mString;
|
||||
|
|
|
@ -136,23 +136,22 @@ public:
|
|||
gfxWindowsTextRun(const nsACString& aString, gfxWindowsFontGroup *aFontGroup);
|
||||
~gfxWindowsTextRun();
|
||||
|
||||
virtual void DrawString(gfxContext *aContext, gfxPoint pt);
|
||||
virtual gfxFloat MeasureString(gfxContext *aContext);
|
||||
virtual void Draw(gfxContext *aContext, gfxPoint pt);
|
||||
virtual gfxFloat Measure(gfxContext *aContext);
|
||||
|
||||
virtual void SetSpacing(const nsTArray<gfxFloat>& spacingArray);
|
||||
virtual const nsTArray<gfxFloat> *const GetSpacing() const;
|
||||
|
||||
private:
|
||||
gfxWindowsFont *FindFallbackFont(HDC aDC,
|
||||
const PRUnichar *aString, PRUint32 aLength,
|
||||
gfxWindowsFont *aFont);
|
||||
|
||||
PRInt32 MeasureOrDrawFast(gfxContext *aContext,
|
||||
PRBool aDraw,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
const PRInt32 *aSpacing);
|
||||
PRInt32 MeasureOrDrawUniscribe(gfxContext *aContext, PRBool aDraw,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
const PRInt32 *aSpacing);
|
||||
PRInt32 MeasureOrDrawFast(gfxContext *aContext, PRBool aDraw, gfxPoint pt);
|
||||
PRInt32 MeasureOrDrawUniscribe(gfxContext *aContext, PRBool aDraw, gfxPoint pt);
|
||||
|
||||
gfxWindowsFontGroup *mGroup;
|
||||
nsTArray<gfxFloat> mSpacing;
|
||||
|
||||
// These should probably be in a union
|
||||
const nsAString& mString;
|
||||
|
|
|
@ -366,7 +366,7 @@ gfxAtsuiTextRun::~gfxAtsuiTextRun()
|
|||
}
|
||||
|
||||
void
|
||||
gfxAtsuiTextRun::DrawString(gfxContext *aContext, gfxPoint pt)
|
||||
gfxAtsuiTextRun::Draw(gfxContext *aContext, gfxPoint pt)
|
||||
{
|
||||
cairo_t *cr = aContext->GetCairo();
|
||||
nsRefPtr<gfxAtsuiFont> atsuiFont = mGroup->GetFontAt(0);
|
||||
|
@ -415,7 +415,7 @@ gfxAtsuiTextRun::DrawString(gfxContext *aContext, gfxPoint pt)
|
|||
}
|
||||
|
||||
gfxFloat
|
||||
gfxAtsuiTextRun::MeasureString(gfxContext *aContext)
|
||||
gfxAtsuiTextRun::Measure(gfxContext *aContext)
|
||||
{
|
||||
OSStatus status;
|
||||
ATSTrapezoid trap;
|
||||
|
@ -438,3 +438,16 @@ gfxAtsuiTextRun::MeasureString(gfxContext *aContext)
|
|||
//fprintf (stderr, "measured: %f\n", f);
|
||||
return f;
|
||||
}
|
||||
|
||||
void
|
||||
gfxAtsuiTextRun::SetSpacing(const nsTArray<gfxFloat> &spacingArray)
|
||||
{
|
||||
// XXX implement me!
|
||||
}
|
||||
|
||||
const nsTArray<gfxFloat> *const
|
||||
gfxAtsuiTextRun::GetSpacing() const
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
|
|
@ -654,7 +654,7 @@ gfxPangoTextRun::EnsurePangoLayout(gfxContext *aContext)
|
|||
}
|
||||
|
||||
void
|
||||
gfxPangoTextRun::DrawString (gfxContext *aContext, gfxPoint pt)
|
||||
gfxPangoTextRun::Draw(gfxContext *aContext, gfxPoint pt)
|
||||
{
|
||||
gfxMatrix mat = aContext->CurrentMatrix();
|
||||
|
||||
|
@ -677,7 +677,7 @@ gfxPangoTextRun::DrawString (gfxContext *aContext, gfxPoint pt)
|
|||
EnsurePangoLayout(aContext);
|
||||
|
||||
#if 0
|
||||
MeasureString(aContext);
|
||||
Measure(aContext);
|
||||
if (mWidth != -1) {
|
||||
aContext->Save();
|
||||
aContext->SetColor(gfxRGBA(1.0, 0.0, 0.0, 0.5));
|
||||
|
@ -710,7 +710,7 @@ gfxPangoTextRun::DrawString (gfxContext *aContext, gfxPoint pt)
|
|||
}
|
||||
|
||||
gfxFloat
|
||||
gfxPangoTextRun::MeasureString (gfxContext *aContext)
|
||||
gfxPangoTextRun::Measure(gfxContext *aContext)
|
||||
{
|
||||
if (mWidth == -1) {
|
||||
EnsurePangoLayout(aContext);
|
||||
|
@ -720,6 +720,17 @@ gfxPangoTextRun::MeasureString (gfxContext *aContext)
|
|||
return mWidth/FLOAT_PANGO_SCALE;
|
||||
}
|
||||
|
||||
void
|
||||
gfxPangoTextRun::SetSpacing(const nsTArray<gfxFloat> &spacingArray)
|
||||
{
|
||||
// XXX implement me!
|
||||
}
|
||||
|
||||
const nsTArray<gfxFloat> *const
|
||||
gfxPangoTextRun::GetSpacing() const
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
** language group helpers
|
||||
|
|
|
@ -413,19 +413,19 @@ gfxWindowsTextRun::~gfxWindowsTextRun()
|
|||
}
|
||||
|
||||
void
|
||||
gfxWindowsTextRun::DrawString(gfxContext *aContext, gfxPoint pt)
|
||||
gfxWindowsTextRun::Draw(gfxContext *aContext, gfxPoint pt)
|
||||
{
|
||||
PRInt32 ret = MeasureOrDrawFast(aContext, PR_TRUE, pt.x, pt.y, nsnull);
|
||||
PRInt32 ret = MeasureOrDrawFast(aContext, PR_TRUE, pt);
|
||||
if (ret != -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
MeasureOrDrawUniscribe(aContext, PR_TRUE, pt.x, pt.y, nsnull);
|
||||
MeasureOrDrawUniscribe(aContext, PR_TRUE, pt);
|
||||
}
|
||||
|
||||
//#define TIME_MEASURE 1
|
||||
gfxFloat
|
||||
gfxWindowsTextRun::MeasureString(gfxContext *aContext)
|
||||
gfxWindowsTextRun::Measure(gfxContext *aContext)
|
||||
{
|
||||
#ifdef TIME_MEASURE
|
||||
if (mIsASCII) {
|
||||
|
@ -436,24 +436,36 @@ gfxWindowsTextRun::MeasureString(gfxContext *aContext)
|
|||
printf("%s\n", foo.get());
|
||||
|
||||
QueryPerformanceCounter(&start);
|
||||
ret = MeasureOrDrawAscii(aContext, PR_FALSE, 0, 0, nsnull);
|
||||
ret = MeasureOrDrawAscii(aContext, PR_FALSE, gfxPoint(0,0));
|
||||
QueryPerformanceCounter(&end);
|
||||
printf("ascii: %d\n", end.QuadPart - start.QuadPart);
|
||||
|
||||
QueryPerformanceCounter(&start);
|
||||
ret = MeasureOrDrawUniscribe(aContext, PR_FALSE, 0, 0, nsnull);
|
||||
ret = MeasureOrDrawUniscribe(aContext, PR_FALSE, gfxPoint(0,0));
|
||||
QueryPerformanceCounter(&end);
|
||||
printf("utf16: %d\n\n", end.QuadPart - start.QuadPart);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
PRInt32 ret = MeasureOrDrawFast(aContext, PR_FALSE, 0, 0, nsnull);
|
||||
PRInt32 ret = MeasureOrDrawFast(aContext, PR_FALSE, gfxPoint(0,0));
|
||||
if (ret != -1) {
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
return MeasureOrDrawUniscribe(aContext, PR_FALSE, 0, 0, nsnull);
|
||||
return MeasureOrDrawUniscribe(aContext, PR_FALSE, gfxPoint(0,0));
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsTextRun::SetSpacing(const nsTArray<gfxFloat>& spacingArray)
|
||||
{
|
||||
mSpacing = spacingArray;
|
||||
}
|
||||
|
||||
const nsTArray<gfxFloat> *const
|
||||
gfxWindowsTextRun::GetSpacing() const
|
||||
{
|
||||
return &mSpacing;
|
||||
}
|
||||
|
||||
gfxWindowsFont *
|
||||
|
@ -490,8 +502,7 @@ gfxWindowsTextRun::FindFallbackFont(HDC aDC, const PRUnichar *aString, PRUint32
|
|||
PRInt32
|
||||
gfxWindowsTextRun::MeasureOrDrawFast(gfxContext *aContext,
|
||||
PRBool aDraw,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
const PRInt32 *aSpacing)
|
||||
gfxPoint pt)
|
||||
{
|
||||
PRInt32 length = 0;
|
||||
|
||||
|
@ -597,9 +608,14 @@ gfxWindowsTextRun::MeasureOrDrawFast(gfxContext *aContext,
|
|||
double offset = 0;
|
||||
for (PRInt32 k = 0; k < numGlyphs; k++) {
|
||||
cglyphs[k].index = glyphs[k];
|
||||
cglyphs[k].x = aX + offset;
|
||||
cglyphs[k].y = aY;
|
||||
offset += NSToCoordRound(dxBuf[k] * cairoToPixels);
|
||||
cglyphs[k].x = pt.x + offset;
|
||||
cglyphs[k].y = pt.y;
|
||||
|
||||
if (!mSpacing.IsEmpty()) {
|
||||
offset += mSpacing[k];
|
||||
} else {
|
||||
offset += dxBuf[k] * cairoToPixels;
|
||||
}
|
||||
}
|
||||
|
||||
SetWorldTransform(aDC, &savedxform);
|
||||
|
@ -628,8 +644,7 @@ gfxWindowsTextRun::MeasureOrDrawFast(gfxContext *aContext,
|
|||
PRInt32
|
||||
gfxWindowsTextRun::MeasureOrDrawUniscribe(gfxContext *aContext,
|
||||
PRBool aDraw,
|
||||
PRInt32 aX, PRInt32 aY,
|
||||
const PRInt32 *aSpacing)
|
||||
gfxPoint pt)
|
||||
{
|
||||
nsRefPtr<gfxASurface> surf = aContext->CurrentSurface();
|
||||
HDC aDC = GetDCFromSurface(surf);
|
||||
|
@ -839,8 +854,9 @@ TRY_AGAIN_JUST_PLACE:
|
|||
if (!aDraw) {
|
||||
length += NSToCoordRound((abc.abcA + abc.abcB + abc.abcC) * cairoToPixels);
|
||||
} else {
|
||||
PRInt32 *spacing = 0;
|
||||
PRInt32 *spacing = nsnull;
|
||||
PRInt32 justTotal = 0;
|
||||
#if 0
|
||||
if (aSpacing) {
|
||||
PRUint32 j;
|
||||
/* need to correct for layout/gfx spacing mismatch */
|
||||
|
@ -885,18 +901,22 @@ TRY_AGAIN_JUST_PLACE:
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
cairo_glyph_t *cglyphs = (cairo_glyph_t*)malloc(numGlyphs*sizeof(cairo_glyph_t));
|
||||
PRInt32 offset = 0;
|
||||
gfxFloat offset = 0;
|
||||
PRInt32 m = items[i].iCharPos;
|
||||
for (PRInt32 k = 0; k < numGlyphs; k++) {
|
||||
cglyphs[k].index = glyphs[k];
|
||||
cglyphs[k].x = aX + offset + NSToCoordRound(offsets[k].du * cairoToPixels);
|
||||
cglyphs[k].y = aY + NSToCoordRound(offsets[k].dv * cairoToPixels);
|
||||
offset += NSToCoordRound(advance[k] * cairoToPixels);
|
||||
cglyphs[k].x = pt.x + offset + (offsets[k].du * cairoToPixels);
|
||||
cglyphs[k].y = pt.y + (offsets[k].dv * cairoToPixels);
|
||||
|
||||
/* XXX this needs some testing */
|
||||
if (aSpacing)
|
||||
offset += spacing[k] * cairoToPixels;
|
||||
if (!mSpacing.IsEmpty()) {
|
||||
// XXX We need to convert char index to cluster index.
|
||||
// But we cannot do it until nsTextFrame is refactored.
|
||||
offset += mSpacing[m++];
|
||||
} else {
|
||||
offset += advance[k] * cairoToPixels;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* Draw using ScriptTextOut() */
|
||||
|
@ -914,7 +934,7 @@ TRY_AGAIN_JUST_PLACE:
|
|||
xform.eDy = dm[5];
|
||||
SetWorldTransform (aDC, &xform);
|
||||
|
||||
ScriptTextOut(aDC, currentFont->ScriptCache(), aX, aY, 0, NULL, &items->a,
|
||||
ScriptTextOut(aDC, currentFont->ScriptCache(), pt.x, pt.y, 0, NULL, &items->a,
|
||||
NULL, 0, glyphs, numGlyphs,
|
||||
advance, NULL, offsets);
|
||||
|
||||
|
@ -944,8 +964,13 @@ TRY_AGAIN_JUST_PLACE:
|
|||
#endif
|
||||
free(cglyphs);
|
||||
|
||||
aX += NSToCoordRound((abc.abcA + abc.abcB + abc.abcC + justTotal) * cairoToPixels);
|
||||
free(spacing);
|
||||
pt.x += offset;
|
||||
//NSToCoordRound((abc.abcA + abc.abcB + abc.abcC + justTotal) * cairoToPixels);
|
||||
|
||||
#if 0
|
||||
if (spacing)
|
||||
free(spacing);
|
||||
#endif
|
||||
}
|
||||
free(offsets);
|
||||
free(advance);
|
||||
|
|
Загрузка…
Ссылка в новой задаче