bug 634762 - Don't call cairo_win32_scaled_font_select_font from SetupCairoFont, but from DCFromContext, and SaveDC/RestoreDC around it; fix usage of DC and font in Uniscribe/GDI shapers. r=roc a=blocking
authorJonathan Kew <jfkthame@gmail.com>
Sat, 19 Feb 2011 20:48:33 +0000
changeset 62868 36b58f89446d9c5a8fecd9ee8bc30aa6aabd2ffd
parent 62867 61c6c43d9630a4496d65e03d0f83f24c231b70c5
child 62869 77e1fe783407e3af600bd794ed520ac35db0bccb
push idunknown
push userunknown
push dateunknown
reviewersroc, blocking
bugs634762
milestone2.0b12pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 634762 - Don't call cairo_win32_scaled_font_select_font from SetupCairoFont, but from DCFromContext, and SaveDC/RestoreDC around it; fix usage of DC and font in Uniscribe/GDI shapers. r=roc a=blocking
gfx/thebes/gfxGDIFont.cpp
gfx/thebes/gfxGDIShaper.cpp
gfx/thebes/gfxUniscribeShaper.cpp
gfx/thebes/gfxWindowsPlatform.h
--- a/gfx/thebes/gfxGDIFont.cpp
+++ b/gfx/thebes/gfxGDIFont.cpp
@@ -260,17 +260,16 @@ gfxGDIFont::SetupCairoFont(gfxContext *a
     }
     if (!mScaledFont ||
         cairo_scaled_font_status(mScaledFont) != CAIRO_STATUS_SUCCESS) {
         // Don't cairo_set_scaled_font as that would propagate the error to
         // the cairo_t, precluding any further drawing.
         return PR_FALSE;
     }
     cairo_set_scaled_font(aContext->GetCairo(), mScaledFont);
-    cairo_win32_scaled_font_select_font(mScaledFont, DCFromContext(aContext));
     return PR_TRUE;
 }
 
 void
 gfxGDIFont::Initialize()
 {
     NS_ASSERTION(!mMetrics, "re-creating metrics? this will leak");
 
@@ -479,21 +478,18 @@ gfxGDIFont::GetGlyphWidth(gfxContext *aC
         mGlyphWidths.Init(200);
     }
 
     PRInt32 width;
     if (mGlyphWidths.Get(aGID, &width)) {
         return width;
     }
 
-    DCFromContext dc(aCtx);
-    AutoSelectFont fs(dc, GetHFONT());
-
     int devWidth;
-    if (GetCharWidthI(dc, aGID, 1, NULL, &devWidth)) {
+    if (GetCharWidthI(DCFromContext(aCtx), aGID, 1, NULL, &devWidth)) {
         // ensure width is positive, 16.16 fixed-point value
         width = (devWidth & 0x7fff) << 16;
         mGlyphWidths.Put(aGID, width);
         return width;
     }
 
     return -1;
 }
--- a/gfx/thebes/gfxGDIShaper.cpp
+++ b/gfx/thebes/gfxGDIShaper.cpp
@@ -52,19 +52,18 @@
 PRBool
 gfxGDIShaper::InitTextRun(gfxContext *aContext,
                           gfxTextRun *aTextRun,
                           const PRUnichar *aString,
                           PRUint32 aRunStart,
                           PRUint32 aRunLength,
                           PRInt32 aRunScript)
 {
-    gfxGDIFont *f = static_cast<gfxGDIFont*>(mFont);
+    mFont->SetupCairoFont(aContext);
     DCFromContext dc(aContext);
-    AutoSelectFont fs(dc, f->GetHFONT());
 
     nsAutoTArray<WORD,500> glyphArray;
     if (!glyphArray.SetLength(aRunLength)) {
         return PR_FALSE;
     }
     WORD *glyphs = glyphArray.Elements();
 
     DWORD ret = ::GetGlyphIndicesW(dc, aString + aRunStart, aRunLength,
--- a/gfx/thebes/gfxUniscribeShaper.cpp
+++ b/gfx/thebes/gfxUniscribeShaper.cpp
@@ -461,24 +461,22 @@ private:
 PRBool
 gfxUniscribeShaper::InitTextRun(gfxContext *aContext,
                                 gfxTextRun *aTextRun,
                                 const PRUnichar *aString,
                                 PRUint32 aRunStart,
                                 PRUint32 aRunLength,
                                 PRInt32 aRunScript)
 {
+    mFont->SetupCairoFont(aContext);
     DCFromContext aDC(aContext);
  
     PRBool result = PR_TRUE;
     HRESULT rv;
 
-    gfxGDIFont *font = static_cast<gfxGDIFont*>(mFont);
-    AutoSelectFont fs(aDC, font->GetHFONT());
-
     Uniscribe us(aString + aRunStart, aRunLength, aTextRun);
 
     /* itemize the string */
     int numItems = us.Itemize();
 
     SaveDC(aDC);
     PRUint32 ivs = 0;
     for (int i = 0; i < numItems; ++i) {
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -81,27 +81,34 @@ struct DCFromContext {
         nsRefPtr<gfxASurface> aSurface = aContext->CurrentSurface();
         NS_ASSERTION(aSurface, "DCFromContext: null surface");
         if (aSurface &&
             (aSurface->GetType() == gfxASurface::SurfaceTypeWin32 ||
              aSurface->GetType() == gfxASurface::SurfaceTypeWin32Printing))
         {
             dc = static_cast<gfxWindowsSurface*>(aSurface.get())->GetDC();
             needsRelease = PR_FALSE;
+            SaveDC(dc);
+            cairo_scaled_font_t* scaled =
+                cairo_get_scaled_font(aContext->GetCairo());
+            cairo_win32_scaled_font_select_font(scaled, dc);
         }
         if (!dc) {
             dc = GetDC(NULL);
             SetGraphicsMode(dc, GM_ADVANCED);
             needsRelease = PR_TRUE;
         }
     }
 
     ~DCFromContext() {
-        if (needsRelease)
+        if (needsRelease) {
             ReleaseDC(NULL, dc);
+        } else {
+            RestoreDC(dc, -1);
+        }
     }
 
     operator HDC () {
         return dc;
     }
 
     HDC dc;
     PRBool needsRelease;