bug 467669 - pt 4 - expose additional attributes for downloaded fonts. r=roc
authorJonathan Kew <jfkthame@gmail.com>
Wed, 15 Jun 2011 20:17:52 +0100
changeset 71669 52b41635185ed290547087c2eec872f8e2a61676
parent 71668 05c732013acb529e62dd555248aeaf4094b032c8
child 71670 66fd359aa53c080b72ccedd667cc463036a6349f
push id159
push usereakhgari@mozilla.com
push dateTue, 16 Aug 2011 17:53:11 +0000
treeherdermozilla-beta@8786e3e49240 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs467669
milestone7.0a1
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 467669 - pt 4 - expose additional attributes for downloaded fonts. r=roc
gfx/thebes/gfxUserFontSet.cpp
gfx/thebes/gfxUserFontSet.h
layout/inspector/src/nsFontFace.cpp
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -367,16 +367,33 @@ SanitizeOpenTypeData(const PRUint8* aDat
         aSaneLength = output.Tell();
         return static_cast<PRUint8*>(output.forget());
     } else {
         aSaneLength = 0;
         return nsnull;
     }
 }
 
+static void
+StoreUserFontData(gfxFontEntry* aFontEntry, gfxProxyFontEntry* aProxy)
+{
+    if (!aFontEntry->mUserFontData) {
+        aFontEntry->mUserFontData = new gfxUserFontData;
+    }
+    gfxUserFontData* userFontData = aFontEntry->mUserFontData;
+    userFontData->mSrcIndex = aProxy->mSrcIndex;
+    const gfxFontFaceSrc& src = aProxy->mSrcList[aProxy->mSrcIndex];
+    if (src.mIsLocal) {
+        userFontData->mLocalName = src.mLocalName;
+    } else {
+        userFontData->mURI = src.mURI;
+    }
+    userFontData->mFormat = src.mFormatFlags;
+}
+
 // This is called when a font download finishes.
 // Ownership of aFontData passes in here, and the font set must
 // ensure that it is eventually deleted via NS_Free().
 PRBool 
 gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
                                const PRUint8 *aFontData, PRUint32 aLength, 
                                nsresult aDownloadStatus)
 {
@@ -442,17 +459,17 @@ gfxUserFontSet::OnLoadComplete(gfxProxyF
             aFontData = nsnull;
         }
 
         if (fe) {
             // copy OpenType feature/language settings from the proxy to the
             // newly-created font entry
             fe->mFeatureSettings.AppendElements(aProxy->mFeatureSettings);
             fe->mLanguageOverride = aProxy->mLanguageOverride;
-
+            StoreUserFontData(fe, aProxy);
 #ifdef PR_LOGGING
             // must do this before ReplaceFontEntry() because that will
             // clear the proxy's mFamily pointer!
             if (LOG_ENABLED()) {
                 nsCAutoString fontURI;
                 aProxy->mSrcList[aProxy->mSrcIndex].mURI->GetSpec(fontURI);
                 LOG(("userfonts (%p) [src %d] loaded uri: (%s) for (%s) gen: %8.8x\n",
                      this, aProxy->mSrcIndex, fontURI.get(),
@@ -534,16 +551,17 @@ gfxUserFontSet::LoadNext(gfxProxyFontEnt
             if (fe) {
                 LOG(("userfonts (%p) [src %d] loaded local: (%s) for (%s) gen: %8.8x\n", 
                      this, aProxyEntry->mSrcIndex, 
                      NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(), 
                      NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get(), 
                      PRUint32(mGeneration)));
                 fe->mFeatureSettings.AppendElements(aProxyEntry->mFeatureSettings);
                 fe->mLanguageOverride = aProxyEntry->mLanguageOverride;
+                StoreUserFontData(fe, aProxyEntry);
                 ReplaceFontEntry(aProxyEntry, fe);
                 return STATUS_LOADED;
             } else {
                 LOG(("userfonts (%p) [src %d] failed local: (%s) for (%s)\n", 
                      this, aProxyEntry->mSrcIndex, 
                      NS_ConvertUTF16toUTF8(currSrc.mLocalName).get(), 
                      NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));            
             }
--- a/gfx/thebes/gfxUserFontSet.h
+++ b/gfx/thebes/gfxUserFontSet.h
@@ -66,22 +66,35 @@ struct gfxFontFaceSrc {
 
     nsString               mLocalName;     // full font name if local
     nsCOMPtr<nsIURI>       mURI;           // uri if url 
     nsCOMPtr<nsIURI>       mReferrer;      // referrer url if url
     nsCOMPtr<nsISupports>  mOriginPrincipal; // principal if url 
     
 };
 
-// subclassed to store platform-specific code cleaned out when font entry is deleted
-// lifetime: from when platform font is created until it is deactivated 
+// Subclassed to store platform-specific code cleaned out when font entry is
+// deleted.
+// Lifetime: from when platform font is created until it is deactivated.
+// If the platform does not need to add any platform-specific code/data here,
+// then the gfxUserFontSet will allocate a base gfxUserFontData and attach
+// to the entry to track the basic user font info fields here.
 class gfxUserFontData {
 public:
-    gfxUserFontData() { }
+    gfxUserFontData()
+        : mSrcIndex(0), mFormat(0), mMetaOrigLen(0)
+    { }
     virtual ~gfxUserFontData() { }
+
+    nsTArray<PRUint8> mMetadata;  // woff metadata block (compressed), if any
+    nsCOMPtr<nsIURI>  mURI;       // URI of the source, if it was url()
+    nsString          mLocalName; // font name used for the source, if local()
+    PRUint32          mSrcIndex;  // index in the rule's source list
+    PRUint32          mFormat;    // format hint for the source used, if any
+    PRUint32          mMetaOrigLen; // length needed to decompress metadata
 };
 
 // initially contains a set of proxy font entry objects, replaced with
 // platform/user fonts as downloaded
 
 class gfxMixedFontFamily : public gfxFontFamily {
 public:
     friend class gfxUserFontSet;
--- a/layout/inspector/src/nsFontFace.cpp
+++ b/layout/inspector/src/nsFontFace.cpp
@@ -34,16 +34,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #define _IMPL_NS_LAYOUT
 
 #include "nsFontFace.h"
 #include "nsIDOMCSSFontFaceRule.h"
 #include "nsCSSRules.h"
+#include "gfxUserFontSet.h"
 
 nsFontFace::nsFontFace(gfxFontEntry*      aFontEntry,
                        PRUint8            aMatchType,
                        nsCSSFontFaceRule* aRule)
   : mFontEntry(aFontEntry),
     mMatchType(aMatchType),
     mRule(aRule)
 {
@@ -111,38 +112,91 @@ nsFontFace::GetRule(nsIDOMCSSFontFaceRul
   NS_IF_ADDREF(*aRule = mRule.get());
   return NS_OK;
 }
 
 /* readonly attribute long srcIndex; */
 NS_IMETHODIMP
 nsFontFace::GetSrcIndex(PRInt32 * aSrcIndex)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (mFontEntry->IsUserFont()) {
+    NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
+    *aSrcIndex = mFontEntry->mUserFontData->mSrcIndex;
+  } else {
+    *aSrcIndex = -1;
+  }
+  return NS_OK;
 }
 
 /* readonly attribute DOMString URI; */
 NS_IMETHODIMP
 nsFontFace::GetURI(nsAString & aURI)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  aURI.Truncate();
+  if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
+    NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
+    if (mFontEntry->mUserFontData->mURI) {
+      nsCAutoString spec;
+      mFontEntry->mUserFontData->mURI->GetSpec(spec);
+      AppendUTF8toUTF16(spec, aURI);
+    }
+  }
+  return NS_OK;
 }
 
 /* readonly attribute DOMString localName; */
 NS_IMETHODIMP
 nsFontFace::GetLocalName(nsAString & aLocalName)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  if (mFontEntry->IsLocalUserFont()) {
+    NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
+    aLocalName = mFontEntry->mUserFontData->mLocalName;
+  } else {
+    aLocalName.Truncate();
+  }
+  return NS_OK;
 }
 
 /* readonly attribute DOMString format; */
+static void
+AppendToFormat(nsAString & aResult, const char* aFormat)
+{
+  if (!aResult.IsEmpty()) {
+    aResult.AppendASCII(",");
+  }
+  aResult.AppendASCII(aFormat);
+}
+
 NS_IMETHODIMP
 nsFontFace::GetFormat(nsAString & aFormat)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  aFormat.Truncate();
+  if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
+    NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
+    PRUint32 formatFlags = mFontEntry->mUserFontData->mFormat;
+    if (formatFlags & gfxUserFontSet::FLAG_FORMAT_OPENTYPE) {
+      AppendToFormat(aFormat, "opentype");
+    }
+    if (formatFlags & gfxUserFontSet::FLAG_FORMAT_TRUETYPE) {
+      AppendToFormat(aFormat, "truetype");
+    }
+    if (formatFlags & gfxUserFontSet::FLAG_FORMAT_TRUETYPE_AAT) {
+      AppendToFormat(aFormat, "truetype-aat");
+    }
+    if (formatFlags & gfxUserFontSet::FLAG_FORMAT_EOT) {
+      AppendToFormat(aFormat, "embedded-opentype");
+    }
+    if (formatFlags & gfxUserFontSet::FLAG_FORMAT_SVG) {
+      AppendToFormat(aFormat, "svg");
+    }
+    if (formatFlags & gfxUserFontSet::FLAG_FORMAT_WOFF) {
+      AppendToFormat(aFormat, "woff");
+    }
+  }
+  return NS_OK;
 }
 
 /* readonly attribute DOMString metadata; */
 NS_IMETHODIMP
 nsFontFace::GetMetadata(nsAString & aMetadata)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }