Added Screen Manager
authorOleg Romashin <romaxa@gmail.com>
Sat, 19 Apr 2008 18:14:15 +0300
changeset 16780 a01e74e075ea46bca9f3d9232235762945c38bcf
parent 16779 58cf4b52f7f67b2aced38d6ccd69779a44357006
child 16781 bec5e1269d11b9e3166a31e18e0f8a7a2b91ae5d
push id1298
push userpavlov@mozilla.com
push dateSun, 17 Aug 2008 05:03:09 +0000
treeherderautoland@4a506fa751d8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0a1pre
Added Screen Manager Some fixes and addditional stuff for fonts
gfx/thebes/public/gfxQtFonts.h
gfx/thebes/src/gfxQtFonts.cpp
widget/src/qt/Makefile.in
widget/src/qt/nsWidgetFactory.cpp
--- a/gfx/thebes/public/gfxQtFonts.h
+++ b/gfx/thebes/public/gfxQtFonts.h
@@ -41,18 +41,19 @@
 
 #include "cairo.h"
 #include "gfxTypes.h"
 #include "gfxFont.h"
 #include "gfxContext.h"
 
 #include "nsDataHashtable.h"
 #include "nsClassHashtable.h"
-//#include <QFont>
 
+#define ENABLE_FAST_PATH_8BIT 1
+#define ENABLE_FAST_PATH_ALWAYS 1
 
 class gfxQtFont : public gfxFont {
 public:
      gfxQtFont (const nsAString& aName,
                 const gfxFontStyle *aFontStyle);
      virtual ~gfxQtFont ();
 
      virtual nsString GetUniqueName ();
@@ -64,27 +65,29 @@ public:
         GetMetrics ();
        return mSpaceGlyph;
      }
 
     static void Shutdown();
 
     virtual const gfxFont::Metrics& GetMetrics();
 
+    void* GetQFont() { if (!mQFont) RealizeQFont(); return mQFont; }
+
 protected:
     void *mQFont;
     cairo_scaled_font_t *mCairoFont;
 
     PRBool mHasMetrics;
     PRUint32 mSpaceGlyph;
     Metrics mMetrics;
     gfxFloat mAdjustedSize;
 
     virtual PRBool SetupCairoFont(gfxContext *aContext);
-
+    void RealizeQFont();
 };
 
 class THEBES_API gfxQtFontGroup : public gfxFontGroup {
 public:
     gfxQtFontGroup (const nsAString& families,
                     const gfxFontStyle *aStyle);
     virtual ~gfxQtFontGroup ();
 
@@ -96,19 +99,30 @@ public:
     virtual gfxTextRun *MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
                                     const Parameters *aParams, PRUint32 aFlags);
 
     gfxQtFont * GetFontAt (PRInt32 i) {
         return static_cast < gfxQtFont * >(static_cast < gfxFont * >(mFonts[i]));
     }
 
 protected:
-   void InitTextRun (gfxTextRun * aTextRun, const char * aUTF8Text,
-                     PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
-                     PRBool aTake8BitPath);
+    void InitTextRun (gfxTextRun * aTextRun, const char * aUTF8Text,
+                      PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
+                      PRBool aTake8BitPath);
+
+/*
+    void CreateGlyphRunsItemizing (gfxTextRun * aTextRun,
+                                   const char * aUTF8, PRUint32 aUTF8Length,
+                                   PRUint32 aUTF8HeaderLength);
+*/
+#if defined(ENABLE_FAST_PATH_8BIT) || defined(ENABLE_FAST_PATH_ALWAYS)
+    PRBool CanTakeFastPath (PRUint32 aFlags);
+    nsresult CreateGlyphRunsFast (gfxTextRun * aTextRun,
+                                  const char * aUTF8, PRUint32 aUTF8Length);
+#endif
 
 
     static PRBool FontCallback (const nsAString & fontName, const nsACString & genericName, void *closure);
 
 };
 
 #endif /* GFX_QTFONTS_H */
 
--- a/gfx/thebes/src/gfxQtFonts.cpp
+++ b/gfx/thebes/src/gfxQtFonts.cpp
@@ -41,16 +41,20 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "gfxPlatformQt.h"
 #include "gfxTypes.h"
 #include "gfxQtFonts.h"
 #include "qdebug.h"
+#include "qrect.h"
+#include <locale.h>
+
+#include <cairo.h>
 
 /**
  * gfxQtFontGroup
  */
 
 static int
 FFRECountHyphens (const nsAString &aFFREName)
 {
@@ -63,17 +67,16 @@ FFRECountHyphens (const nsAString &aFFRE
     return h;
 }
 
 PRBool
 gfxQtFontGroup::FontCallback (const nsAString& fontName,
                                  const nsACString& genericName,
                                  void *closure)
 {
-    qDebug(">>>>>>Func:%s::%d, fontname:%s, genName:%s\n", __PRETTY_FUNCTION__, __LINE__, NS_ConvertUTF16toUTF8(fontName).get(), nsCString(genericName).get());
     nsStringArray *sa = static_cast<nsStringArray*>(closure);
 
     // We ignore prefs that have three hypens since they are X style prefs.
     if (genericName.Length() && FFRECountHyphens(fontName) >= 3)
         return PR_TRUE;
 
     if (sa->IndexOf(fontName) < 0) {
         sa->AppendString(fontName);
@@ -85,46 +88,93 @@ gfxQtFontGroup::FontCallback (const nsAS
 /**
  * Look up the font in the gfxFont cache. If we don't find it, create one.
  * In either case, add a ref, append it to the aFonts array, and return it ---
  * except for OOM in which case we do nothing and return null.
  */
 static already_AddRefed<gfxQtFont>
 GetOrMakeFont(const nsAString& aName, const gfxFontStyle *aStyle)
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
     nsRefPtr<gfxFont> font = gfxFontCache::GetCache()->Lookup(aName, aStyle);
     if (!font) {
         font = new gfxQtFont(aName, aStyle);
         if (!font)
             return nsnull;
         gfxFontCache::GetCache()->AddNew(font);
     }
     gfxFont *f = nsnull;
     font.swap(f);
     return static_cast<gfxQtFont *>(f);
 }
 
+void
+gfxQtFont::RealizeQFont()
+{
+    // already realized?
+    if (mQFont)
+        return;
+    qDebug("QTFONT NOT_IMPLEMENTED!!!! Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+
+/*
+    PangoFontDescription *pangoFontDesc =
+        NewPangoFontDescription(mName, GetStyle());
+
+    PangoContext *pangoCtx = gdk_pango_context_get();
+
+    if (!GetStyle()->langGroup.IsEmpty()) {
+        PangoLanguage *lang = GetPangoLanguage(GetStyle()->langGroup);
+        if (lang)
+            pango_context_set_language(pangoCtx, lang);
+    }
+
+    mQFont = LoadPangoFont(pangoCtx, pangoFontDesc);
+
+    gfxFloat size = GetStyle()->size;
+    // Checking mQFont to avoid infinite recursion through GetCharSize
+    if (size != 0.0 && GetStyle()->sizeAdjust != 0.0 && mQFont) {
+        // Could try xHeight from TrueType/OpenType fonts.
+        gfxSize isz, lsz;
+        GetCharSize('x', isz, lsz);
+        if (isz.height != 0.0) {
+            gfxFloat aspect = isz.height / size;
+            size = GetStyle()->GetAdjustedSize(aspect);
+
+            pango_font_description_set_absolute_size(pangoFontDesc,
+                                                     size * PANGO_SCALE);
+            g_object_unref(mQFont);
+            mQFont = LoadPangoFont(pangoCtx, pangoFontDesc);
+        }
+    }
+
+    NS_ASSERTION(mHasMetrics == PR_FALSE, "metrics will be invalid...");
+    mAdjustedSize = size;
+    if (!g_object_get_qdata(G_OBJECT(mQFont), GetFontQuark()))
+        g_object_set_qdata(G_OBJECT(mQFont), GetFontQuark(), this);
+
+    if (pangoFontDesc)
+        pango_font_description_free(pangoFontDesc);
+    if (pangoCtx)
+        g_object_unref(pangoCtx);
+*/
+}
 
 gfxQtFontGroup::gfxQtFontGroup (const nsAString& families,
                                 const gfxFontStyle *aStyle)
     : gfxFontGroup(families, aStyle)
 {
-    qDebug("Func:%s::%d, fam:%s\n\tNeed to create font metrics, otherwise - CRASH\n\n", __PRETTY_FUNCTION__, __LINE__, NS_ConvertUTF16toUTF8(families).get());
     nsStringArray familyArray;
 
     // Leave non-existing fonts in the list so that fontconfig can get the
     // best match.
     ForEachFontInternal(families, aStyle->langGroup, PR_TRUE, PR_FALSE,
                         FontCallback, &familyArray);
 
     // Construct a string suitable for fontconfig
     nsAutoString fcFamilies;
     if (familyArray.Count()) {
-        qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
         int i = 0;
         while (1) {
             fcFamilies.Append(*familyArray[i]);
             ++i;
             if (i >= familyArray.Count())
                 break;
             fcFamilies.Append(NS_LITERAL_STRING(","));
         }
@@ -141,23 +191,21 @@ gfxQtFontGroup::gfxQtFontGroup (const ns
     nsRefPtr<gfxQtFont> font = GetOrMakeFont(fcFamilies, &mStyle);
     if (font) {
         mFonts.AppendElement(font);
     }
 }
 
 gfxQtFontGroup::~gfxQtFontGroup()
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
 }
 
 gfxFontGroup *
 gfxQtFontGroup::Copy(const gfxFontStyle *aStyle)
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
      return new gfxQtFontGroup(mFamilies, aStyle);
 }
 
 #if defined(ENABLE_FAST_PATH_8BIT)
 PRBool
 gfxQtFontGroup::CanTakeFastPath(PRUint32 aFlags)
 {
     // Can take fast path only if OPTIMIZE_SPEED is set and IS_RTL isn't.
@@ -166,33 +214,178 @@ gfxQtFontGroup::CanTakeFastPath(PRUint32
     PRBool speed = aFlags & gfxTextRunFactory::TEXT_OPTIMIZE_SPEED;
     PRBool isRTL = aFlags & gfxTextRunFactory::TEXT_IS_RTL;
     return speed && !isRTL
            //&& PANGO_IS_FC_FONT(GetFontAt(0)->GetPangoFont())
            ;
 }
 #endif
 
+#if defined(ENABLE_FAST_PATH_8BIT) || defined(ENABLE_FAST_PATH_ALWAYS)
+#define UTF8_COMPUTE(Char, Mask, Len)					      \
+  if (Char < 128)							      \
+    {									      \
+      Len = 1;								      \
+      Mask = 0x7f;							      \
+    }									      \
+  else if ((Char & 0xe0) == 0xc0)					      \
+    {									      \
+      Len = 2;								      \
+      Mask = 0x1f;							      \
+    }									      \
+  else if ((Char & 0xf0) == 0xe0)					      \
+    {									      \
+      Len = 3;								      \
+      Mask = 0x0f;							      \
+    }									      \
+  else if ((Char & 0xf8) == 0xf0)					      \
+    {									      \
+      Len = 4;								      \
+      Mask = 0x07;							      \
+    }									      \
+  else if ((Char & 0xfc) == 0xf8)					      \
+    {									      \
+      Len = 5;								      \
+      Mask = 0x03;							      \
+    }									      \
+  else if ((Char & 0xfe) == 0xfc)					      \
+    {									      \
+      Len = 6;								      \
+      Mask = 0x01;							      \
+    }									      \
+  else									      \
+    Len = -1;
+
+#define UTF8_GET(Result, Chars, Count, Mask, Len)			      \
+  (Result) = (Chars)[0] & (Mask);					      \
+  for ((Count) = 1; (Count) < (Len); ++(Count))				      \
+    {									      \
+      if (((Chars)[(Count)] & 0xc0) != 0x80)				      \
+	{								      \
+	  (Result) = -1;						      \
+	  break;							      \
+	}								      \
+      (Result) <<= 6;							      \
+      (Result) |= ((Chars)[(Count)] & 0x3f);				      \
+    }
+
+static const char utf8_skip_data[256] = {
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
+};
+
+const char * const g_utf8_skip = utf8_skip_data;
+#define g_utf8_next_char(p) (char *)((p) + g_utf8_skip[*(const unsigned char *)(p)])
+
+int
+g_utf8_get_char (const char *p)
+{
+  int i, mask = 0, len;
+  int result;
+  unsigned char c = (unsigned char) *p;
+
+  UTF8_COMPUTE (c, mask, len);
+  if (len == -1)
+    return (int)-1;
+  UTF8_GET (result, p, i, mask, len);
+  return result;
+}
+
+nsresult
+gfxQtFontGroup::CreateGlyphRunsFast(gfxTextRun *aTextRun,
+                                    const char *aUTF8, PRUint32 aUTF8Length)
+{
+    const char *p = aUTF8;
+    gfxQtFont *font = GetFontAt(0);
+//    PangoFont *pangofont = font->GetPangoFont();
+//    PangoFcFont *fcfont = PANGO_FC_FONT (pangofont);
+    PRUint32 utf16Offset = 0;
+    gfxTextRun::CompressedGlyph g;
+    const PRUint32 appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
+
+    aTextRun->AddGlyphRun(font, 0);
+
+    while (p < aUTF8 + aUTF8Length) {
+        // glib-2.12.9: "If p does not point to a valid UTF-8 encoded
+        // character, results are undefined." so it is not easy to assert that
+        // aUTF8 in fact points to UTF8 data but asserting
+        // g_unichar_validate(ch) may be mildly useful.
+        int ch = g_utf8_get_char(p);
+        p = g_utf8_next_char(p);
+
+        if (ch == 0) {
+            // treat this null byte as a missing glyph. Pango
+            // doesn't create glyphs for these, not even missing-glyphs.
+            aTextRun->SetMissingGlyph(utf16Offset, 0);
+        } else {
+            NS_ASSERTION(!IsInvalidChar(ch), "Invalid char detected");
+            int glyph = 124;
+            //FT_UInt glyph = pango_fc_font_get_glyph (fcfont, ch);
+            if (!glyph)                  // character not in font,
+                return NS_ERROR_FAILURE; // fallback to CreateGlyphRunsItemizing
+
+//            PangoRectangle rect;
+            QRect rect;
+//            pango_font_get_glyph_extents (pangofont, glyph, NULL, &rect);
+            PRInt32 advance = 0;
+            //advance = PANGO_PIXELS (rect.width * appUnitsPerDevUnit);
+            if (advance >= 0 &&
+                gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
+                gfxTextRun::CompressedGlyph::IsSimpleGlyphID(glyph)) {
+                aTextRun->SetSimpleGlyph(utf16Offset,
+                                         g.SetSimpleGlyph(advance, glyph));
+            } else {
+                gfxTextRun::DetailedGlyph details;
+                details.mGlyphID = glyph;
+                NS_ASSERTION(details.mGlyphID == glyph,
+                             "Seriously weird glyph ID detected!");
+                details.mAdvance = advance;
+                details.mXOffset = 0;
+                details.mYOffset = 0;
+                g.SetComplex(aTextRun->IsClusterStart(utf16Offset), PR_TRUE, 1);
+                aTextRun->SetGlyphs(utf16Offset, g, &details);
+            }
+
+            NS_ASSERTION(!IS_SURROGATE(ch), "Surrogates shouldn't appear in UTF8");
+            if (ch >= 0x10000) {
+                // This character is a surrogate pair in UTF16
+                ++utf16Offset;
+            }
+        }
+
+        ++utf16Offset;
+    }
+    return NS_OK;
+}
+#endif
+
+
 void
 gfxQtFontGroup::InitTextRun(gfxTextRun *aTextRun, const char *aUTF8Text,
                              PRUint32 aUTF8Length, PRUint32 aUTF8HeaderLength,
                              PRBool aTake8BitPath)
 {
-    qDebug(">>>>>>Func:%s::%d, Text:'%s'\n", __PRETTY_FUNCTION__, __LINE__, aUTF8Text);
 #if defined(ENABLE_FAST_PATH_ALWAYS)
-//    CreateGlyphRunsFast(aTextRun, aUTF8Text + aUTF8HeaderLength, aUTF8Length - aUTF8HeaderLength);
+    CreateGlyphRunsFast(aTextRun, aUTF8Text + aUTF8HeaderLength, aUTF8Length - aUTF8HeaderLength);
 #else
 #if defined(ENABLE_FAST_PATH_8BIT)
     if (aTake8BitPath && CanTakeFastPath(aTextRun->GetFlags())) {
+        qDebug("QTFONT NOT_IMPLEMENTED!!!! Func:%s::%d, Text:'%s'\n", __PRETTY_FUNCTION__, __LINE__, aUTF8Text);
 //        nsresult rv = CreateGlyphRunsFast(aTextRun, aUTF8Text + aUTF8HeaderLength, aUTF8Length - aUTF8HeaderLength);
         if (NS_SUCCEEDED(rv))
             return;
     }
 #endif
-
+      qDebug("QTFONT NOT_IMPLEMENTED!!!! Func:%s::%d, Text:'%s'\n", __PRETTY_FUNCTION__, __LINE__, aUTF8Text);
 //    CreateGlyphRunsItemizing(aTextRun, aUTF8Text, aUTF8Length, aUTF8HeaderLength);
 #endif
 }
 
 /**
  * We use this to append an LTR or RTL Override character to the start of the
  * string. This forces Pango to honour our direction even if there are neutral characters
  * in the string.
@@ -204,17 +397,16 @@ static PRInt32 AppendDirectionalIndicato
     AppendUTF16toUTF8(overrides[aIsRTL], aString);
     return 3; // both overrides map to 3 bytes in UTF8
 }
 
 gfxTextRun *
 gfxQtFontGroup::MakeTextRun(const PRUint8 *aString, PRUint32 aLength,
                                const Parameters *aParams, PRUint32 aFlags)
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
     NS_ASSERTION(aFlags & TEXT_IS_8BIT, "8bit should have been set");
     gfxTextRun *run = gfxTextRun::Create(aParams, aString, aLength, this, aFlags);
     if (!run)
         return nsnull;
 
     PRBool isRTL = run->IsRightToLeft();
     if ((aFlags & TEXT_IS_ASCII) && !isRTL) {
         // We don't need to send an override character here, the characters must be all LTR
@@ -232,17 +424,16 @@ gfxQtFontGroup::MakeTextRun(const PRUint
     run->FetchGlyphExtents(aParams->mContext);
     return run;
 }
 
 gfxTextRun *
 gfxQtFontGroup::MakeTextRun(const PRUnichar *aString, PRUint32 aLength,
                                const Parameters *aParams, PRUint32 aFlags)
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
     gfxTextRun *run = gfxTextRun::Create(aParams, aString, aLength, this, aFlags);
     if (!run)
         return nsnull;
 
     run->RecordSurrogates(aString);
 
     nsCAutoString utf8;
     PRInt32 headerLen = AppendDirectionalIndicatorUTF8(run->IsRightToLeft(), utf8);
@@ -269,31 +460,30 @@ gfxQtFontGroup::MakeTextRun(const PRUnic
  */
 
 gfxQtFont::gfxQtFont(const nsAString &aName,
                      const gfxFontStyle *aFontStyle)
     : gfxFont(aName, aFontStyle),
       mQFont(nsnull), mCairoFont(nsnull),
       mHasMetrics(PR_FALSE), mAdjustedSize(0)
 {
-    qDebug(">>>>>>Func:%s::%d, name:%s\n", __PRETTY_FUNCTION__, __LINE__, NS_ConvertUTF16toUTF8(aName).get());
 }
 
 gfxQtFont::~gfxQtFont()
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
 }
 
 const gfxFont::Metrics&
 gfxQtFont::GetMetrics()
 {
     if (mHasMetrics)
         return mMetrics;
 
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+    qDebug("QTFONT NOT_IMPLEMENTED!!!! Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+
 #if 0
     //    printf("font name: %s %f %f\n", NS_ConvertUTF16toUTF8(mName).get(), GetStyle()->size, mAdjustedSize);
     //    printf ("pango font %s\n", pango_font_description_to_string (pango_font_describe (font)));
 
     fprintf (stderr, "Font: %s\n", NS_ConvertUTF16toUTF8(mName).get());
     fprintf (stderr, "    emHeight: %f emAscent: %f emDescent: %f\n", mMetrics.emHeight, mMetrics.emAscent, mMetrics.emDescent);
     fprintf (stderr, "    maxAscent: %f maxDescent: %f\n", mMetrics.maxAscent, mMetrics.maxDescent);
     fprintf (stderr, "    internalLeading: %f externalLeading: %f\n", mMetrics.externalLeading, mMetrics.internalLeading);
@@ -304,57 +494,91 @@ gfxQtFont::GetMetrics()
     mHasMetrics = PR_TRUE;
     return mMetrics;
 }
 
 
 nsString
 gfxQtFont::GetUniqueName()
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+    qDebug("QTFONT NOT_IMPLEMENTED!!!! Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
     nsString result;
 /*
     PangoFont *font = GetPangoFont();
     PangoFontDescription *desc = pango_font_describe(font);
     pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
     char *str = pango_font_description_to_string(desc);
     pango_font_description_free (desc);
 
     CopyUTF8toUTF16(str, result);
     g_free(str);*/
     return result;
 }
 
 /* static */ void
 gfxQtFont::Shutdown()
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+    qDebug("QTFONT NOT_IMPLEMENTED!!!! Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+}
+
+static cairo_scaled_font_t*
+CreateScaledFont(cairo_t *aCR, cairo_matrix_t *aCTM, void *aQFont)
+{
+    // XXX is this safe really? We should probably check the font type or something.
+    // XXX does this really create the same font that Pango used for measurement?
+    // We probably need to work harder here. We should pay particular attention
+    // to the font options.
+/*
+    PangoFcFont *fcfont = PANGO_FC_FONT(aPangoFont);
+    cairo_font_face_t *face = cairo_ft_font_face_create_for_pattern(fcfont->font_pattern);
+    double size;
+    if (FcPatternGetDouble(fcfont->font_pattern, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
+        size = 12.0;
+    cairo_matrix_t fontMatrix;
+    FcMatrix *fcMatrix;
+    if (FcPatternGetMatrix(fcfont->font_pattern, FC_MATRIX, 0, &fcMatrix) == FcResultMatch)
+        cairo_matrix_init(&fontMatrix, fcMatrix->xx, -fcMatrix->yx, -fcMatrix->xy, fcMatrix->yy, 0, 0);
+    else
+        cairo_matrix_init_identity(&fontMatrix);
+    cairo_matrix_scale(&fontMatrix, size, size);
+    cairo_font_options_t *fontOptions = cairo_font_options_create();
+    cairo_get_font_options(aCR, fontOptions);
+    cairo_scaled_font_t *scaledFont =
+        cairo_scaled_font_create(face, &fontMatrix, aCTM, fontOptions);
+    cairo_font_options_destroy(fontOptions);
+    cairo_font_face_destroy(face);
+    NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
+                 "Failed to create scaled font");
+    return scaledFont;
+*/
+    return nsnull;
 }
 
 PRBool
 gfxQtFont::SetupCairoFont(gfxContext *aContext)
 {
-    qDebug(">>>>>>Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
     cairo_t *cr = aContext->GetCairo();
     cairo_matrix_t currentCTM;
     cairo_get_matrix(cr, &currentCTM);
 
     if (mCairoFont) {
         // Need to validate that its CTM is OK
         cairo_matrix_t fontCTM;
         cairo_scaled_font_get_ctm(mCairoFont, &fontCTM);
         if (fontCTM.xx != currentCTM.xx || fontCTM.yy != currentCTM.yy ||
             fontCTM.xy != currentCTM.xy || fontCTM.yx != currentCTM.yx) {
             // Just recreate it from scratch, simplest way
             cairo_scaled_font_destroy(mCairoFont);
             mCairoFont = nsnull;
         }
     }
     if (!mCairoFont) {
-        //mCairoFont = CreateScaledFont(cr, &currentCTM, GetPangoFont());
+        qDebug("QTFONT NOT_IMPLEMENTED!!!! Func:%s::%d\n", __PRETTY_FUNCTION__, __LINE__);
+        mCairoFont = CreateScaledFont(cr, &currentCTM, GetQFont());
+        return PR_FALSE;
     }
     if (cairo_scaled_font_status(mCairoFont) != 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(cr, mCairoFont);
     return PR_TRUE;
--- a/widget/src/qt/Makefile.in
+++ b/widget/src/qt/Makefile.in
@@ -78,16 +78,18 @@ CPPSRCS	= \
 		moc_mozqwidget.cpp \
 		moc_nsAppShell.cpp \
 		nsAppShell.cpp \
 		nsWidgetFactory.cpp \
 		nsCommonWidget.cpp \
 		nsWindow.cpp \
 		nsLookAndFeel.cpp \
 		nsToolkit.cpp \
+		nsScreenQt.cpp \
+		nsScreenManagerQt.cpp \
 		mozqwidget.cpp \
 		$(NULL)
 
 SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
 
 EXTRA_DSO_LDOPTS = \
 		$(MOZ_COMPONENT_LIBS) \
 		-lgkgfx \
--- a/widget/src/qt/nsWidgetFactory.cpp
+++ b/widget/src/qt/nsWidgetFactory.cpp
@@ -46,16 +46,17 @@
 #include "nsWidgetsCID.h"
 #include "nsAppShell.h"
 #include "nsWindow.h"
 #include "nsToolkit.h"
 #include "nsHTMLFormatConverter.h"
 #include "nsTransferable.h"
 #include "nsLookAndFeel.h"
 #include "nsAppShellSingleton.h"
+#include "nsScreenManagerQt.h"
 
 // #include "nsIComponentRegistrar.h"
 // #include "nsComponentManagerUtils.h"
 // #include "nsAutoPtr.h"
 // 
 
 
 // #include "nsClipboard.h"
@@ -78,16 +79,17 @@
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(ChildWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(PopupWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsToolkit)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsLookAndFeel)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsScreenManagerQt)
 
 /*
 static NS_DEFINE_CID(kNativeScrollCID, NS_NATIVESCROLLBAR_CID);
 
 
 
 
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboard)
@@ -128,17 +130,21 @@ static const nsModuleComponentInfo compo
       nsHTMLFormatConverterConstructor },
     { "Qt Toolkit",
       NS_TOOLKIT_CID,
       "@mozilla.org/widget/toolkit/qt;1",
       nsToolkitConstructor },
     { "Transferrable",
       NS_TRANSFERABLE_CID,
       "@mozilla.org/widget/transferable;1",
-      nsTransferableConstructor }
+      nsTransferableConstructor },
+    { "Qt Screen Manager",
+      NS_SCREENMANAGER_CID,
+      "@mozilla.org/gfx/screenmanager;1",
+      nsScreenManagerQtConstructor }
 /*
     { "Qt Native Scrollbar",
       NS_NATIVESCROLLBAR_CID,
       "@mozilla.org/widget/nativescrollbar/qt;1",
       nsNativeScrollbarConstructor},
     { "Qt Clipboard",
       NS_CLIPBOARD_CID,
       "@mozilla.org/widget/clipboard;1",