diff --git a/gfx/src/thebes/nsThebesDeviceContext.cpp b/gfx/src/thebes/nsThebesDeviceContext.cpp index f96873b50e1..d28ae001b66 100644 --- a/gfx/src/thebes/nsThebesDeviceContext.cpp +++ b/gfx/src/thebes/nsThebesDeviceContext.cpp @@ -732,5 +732,4 @@ nsThebesDeviceContext::FindScreen(nsIScreen** outScreen) #endif mScreenManager->GetPrimaryScreen(outScreen); - } diff --git a/gfx/src/thebes/nsThebesFontMetrics.cpp b/gfx/src/thebes/nsThebesFontMetrics.cpp index d2484a2ac9d..1586c5b3085 100644 --- a/gfx/src/thebes/nsThebesFontMetrics.cpp +++ b/gfx/src/thebes/nsThebesFontMetrics.cpp @@ -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 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 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; } diff --git a/gfx/thebes/public/gfxAtsuiFonts.h b/gfx/thebes/public/gfxAtsuiFonts.h index 97dba624c0a..e1ebdf35bd5 100644 --- a/gfx/thebes/public/gfxAtsuiFonts.h +++ b/gfx/thebes/public/gfxAtsuiFonts.h @@ -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& spacingArray); + virtual const nsTArray *const GetSpacing() const; private: nsString mString; diff --git a/gfx/thebes/public/gfxFont.h b/gfx/thebes/public/gfxFont.h index 1ae0163e3c2..2cec3599bbc 100644 --- a/gfx/thebes/public/gfxFont.h +++ b/gfx/thebes/public/gfxFont.h @@ -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 &spacing) = 0; + virtual const nsTArray *const GetSpacing() const = 0; + + // defaults to FALSE virtual void SetRightToLeft(PRBool aIsRTL) { mIsRTL = aIsRTL; } virtual PRBool IsRightToLeft() const { return mIsRTL; } diff --git a/gfx/thebes/public/gfxPangoFonts.h b/gfx/thebes/public/gfxPangoFonts.h index fe5c447ca17..b504d410e4d 100644 --- a/gfx/thebes/public/gfxPangoFonts.h +++ b/gfx/thebes/public/gfxPangoFonts.h @@ -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& spacingArray); + virtual const nsTArray *const GetSpacing() const; private: nsString mString; diff --git a/gfx/thebes/public/gfxWindowsFonts.h b/gfx/thebes/public/gfxWindowsFonts.h index 5bfe90653c6..9f6139e5b1f 100644 --- a/gfx/thebes/public/gfxWindowsFonts.h +++ b/gfx/thebes/public/gfxWindowsFonts.h @@ -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& spacingArray); + virtual const nsTArray *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 mSpacing; // These should probably be in a union const nsAString& mString; diff --git a/gfx/thebes/src/gfxAtsuiFonts.cpp b/gfx/thebes/src/gfxAtsuiFonts.cpp index 724f4363caa..0348c617749 100644 --- a/gfx/thebes/src/gfxAtsuiFonts.cpp +++ b/gfx/thebes/src/gfxAtsuiFonts.cpp @@ -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 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 &spacingArray) +{ + // XXX implement me! +} + +const nsTArray *const +gfxAtsuiTextRun::GetSpacing() const +{ + return nsnull; +} + diff --git a/gfx/thebes/src/gfxPangoFonts.cpp b/gfx/thebes/src/gfxPangoFonts.cpp index 3eec8a1fe9f..84a66f8bab3 100644 --- a/gfx/thebes/src/gfxPangoFonts.cpp +++ b/gfx/thebes/src/gfxPangoFonts.cpp @@ -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 &spacingArray) +{ + // XXX implement me! +} + +const nsTArray *const +gfxPangoTextRun::GetSpacing() const +{ + return nsnull; +} /** ** language group helpers diff --git a/gfx/thebes/src/gfxWindowsFonts.cpp b/gfx/thebes/src/gfxWindowsFonts.cpp index 6adb70460ad..c43acfe6033 100644 --- a/gfx/thebes/src/gfxWindowsFonts.cpp +++ b/gfx/thebes/src/gfxWindowsFonts.cpp @@ -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& spacingArray) +{ + mSpacing = spacingArray; +} + +const nsTArray *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 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);