diff --git a/gfx/thebes/Makefile.in b/gfx/thebes/Makefile.in index 74caddfe4175..57849e86d0a3 100644 --- a/gfx/thebes/Makefile.in +++ b/gfx/thebes/Makefile.in @@ -277,6 +277,7 @@ CPPSRCS += \ gfxFT2Fonts.cpp \ gfxFT2FontBase.cpp \ gfxFT2Utils.cpp \ + gfxFT2FontList.cpp \ nsUnicodeRange.cpp \ $(NULL) endif diff --git a/gfx/thebes/gfxAndroidPlatform.cpp b/gfx/thebes/gfxAndroidPlatform.cpp index f66f5a284ee9..fac55b3de0ba 100644 --- a/gfx/thebes/gfxAndroidPlatform.cpp +++ b/gfx/thebes/gfxAndroidPlatform.cpp @@ -58,6 +58,8 @@ #include "ft2build.h" #include FT_FREETYPE_H #include "gfxFT2Fonts.h" +#include "gfxPlatformFontList.h" +#include "gfxFT2FontList.h" static FT_Library gPlatformFTLibrary = NULL; @@ -225,6 +227,15 @@ gfxAndroidPlatform::ResolveFontName(const nsAString& aFontName, if (aFontName.IsEmpty()) return NS_ERROR_FAILURE; + nsAutoString resolvedName; + gfxPlatformFontList* platformFontList = gfxPlatformFontList::PlatformFontList(); + if (platformFontList) { + if (!platformFontList->ResolveFontName(aFontName, resolvedName)) { + aAborted = PR_FALSE; + return NS_OK; + } + } + nsAutoString keyName(aFontName); ToLowerCase(keyName); @@ -256,12 +267,40 @@ gfxAndroidPlatform::GetStandardFamilyName(const nsAString& aFontName, nsAString& return ResolveFontName(aFontName, SimpleResolverCallback, &aFamilyName, aborted); } +gfxPlatformFontList* +gfxAndroidPlatform::CreatePlatformFontList() +{ + return new gfxFT2FontList(); +} + +PRBool +gfxAndroidPlatform::IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags) +{ + // check for strange format flags + NS_ASSERTION(!(aFormatFlags & gfxUserFontSet::FLAG_FORMAT_NOT_USED), + "strange font format hint set"); + + // accept supported formats + if (aFormatFlags & (gfxUserFontSet::FLAG_FORMAT_OPENTYPE | + gfxUserFontSet::FLAG_FORMAT_TRUETYPE)) { + return PR_TRUE; + } + + // reject all other formats, known and unknown + if (aFormatFlags != 0) { + return PR_FALSE; + } + + // no format hint set, need to look at data + return PR_TRUE; +} + gfxFontGroup * gfxAndroidPlatform::CreateFontGroup(const nsAString &aFamilies, const gfxFontStyle *aStyle, gfxUserFontSet* aUserFontSet) { - return new gfxFT2FontGroup(aFamilies, aStyle); + return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet); } FT_Library @@ -332,6 +371,15 @@ gfxAndroidPlatform::FindFontForChar(PRUint32 aCh, gfxFont *aFont) return nsnull; } +gfxFontEntry* +gfxAndroidPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, + const PRUint8 *aFontData, PRUint32 aLength) +{ + return gfxPlatformFontList::PlatformFontList()->MakePlatformFont(aProxyEntry, + aFontData, + aLength); +} + PRBool gfxAndroidPlatform::GetPrefFontEntries(const nsCString& aKey, nsTArray > *aFontEntryList) { diff --git a/gfx/thebes/gfxAndroidPlatform.h b/gfx/thebes/gfxAndroidPlatform.h index a097b7064ca9..5edc2667cee7 100644 --- a/gfx/thebes/gfxAndroidPlatform.h +++ b/gfx/thebes/gfxAndroidPlatform.h @@ -62,6 +62,11 @@ public: already_AddRefed CreateOffscreenSurface(const gfxIntSize& size, gfxASurface::gfxImageFormat imageFormat); + virtual PRBool IsFontFormatSupported(nsIURI *aFontURI, PRUint32 aFormatFlags); + virtual gfxPlatformFontList* CreatePlatformFontList(); + virtual gfxFontEntry* MakePlatformFont(const gfxProxyFontEntry *aProxyEntry, + const PRUint8 *aFontData, PRUint32 aLength); + nsresult GetFontList(nsIAtom *aLangGroup, const nsACString& aGenericFamily, nsTArray& aListOfFonts); diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index a0d0ca1f7a33..eaa7d93687db 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -55,9 +55,9 @@ #include "nsDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h" #include "nsISimpleEnumerator.h" -#include "nsIWindowsRegKey.h" #ifdef XP_WIN +#include "nsIWindowsRegKey.h" #include #endif @@ -67,14 +67,23 @@ static PRLogModuleInfo *gFontInfoLog = PR_NewLogModule("fontInfoLog"); #endif /* PR_LOGGING */ +#ifdef ANDROID +#include "gfxAndroidPlatform.h" +#include +#include +#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gecko" , ## args) + +#endif #define LOG(args) PR_LOG(gFontInfoLog, PR_LOG_DEBUG, args) #define LOG_ENABLED() PR_LOG_TEST(gFontInfoLog, PR_LOG_DEBUG) static __inline void BuildKeyNameFromFontName(nsAString &aName) { +#ifdef XP_WIN if (aName.Length() >= LF_FACESIZE) aName.Truncate(LF_FACESIZE - 1); +#endif ToLowerCase(aName); } @@ -102,14 +111,22 @@ gfxFT2FontList::gfxFT2FontList() void gfxFT2FontList::AppendFacesFromFontFile(const PRUnichar *aFileName) { - char fileName[MAX_PATH]; - WideCharToMultiByte(CP_ACP, 0, aFileName, -1, fileName, MAX_PATH, NULL, NULL); + AppendFacesFromFontFile(NS_ConvertUTF16toUTF8(aFileName).get()); +} + +void +gfxFT2FontList::AppendFacesFromFontFile(const char *aFileName) +{ +#ifdef XP_WIN FT_Library ftLibrary = gfxWindowsPlatform::GetPlatform()->GetFTLibrary(); +#elif defined(ANDROID) + FT_Library ftLibrary = gfxAndroidPlatform::GetPlatform()->GetFTLibrary(); +#endif FT_Face dummy; - if (FT_Err_Ok == FT_New_Face(ftLibrary, fileName, -1, &dummy)) { + if (FT_Err_Ok == FT_New_Face(ftLibrary, aFileName, -1, &dummy)) { for (FT_Long i = 0; i < dummy->num_faces; i++) { FT_Face face; - if (FT_Err_Ok != FT_New_Face(ftLibrary, fileName, i, &face)) + if (FT_Err_Ok != FT_New_Face(ftLibrary, aFileName, i, &face)) continue; FontEntry* fe = FontEntry::CreateFontEntryFromFace(face); @@ -147,6 +164,7 @@ gfxFT2FontList::AppendFacesFromFontFile(const PRUnichar *aFileName) void gfxFT2FontList::FindFonts() { +#ifdef XP_WIN nsTArray searchPaths(3); nsTArray fontPatterns(3); fontPatterns.AppendElement(NS_LITERAL_STRING("\\*.ttf")); @@ -189,6 +207,32 @@ gfxFT2FontList::FindFonts() FindClose(handle); } } +#elif defined(ANDROID) + gfxFontCache *fc = gfxFontCache::GetCache(); + if (fc) + fc->AgeAllGenerations(); + mPrefFonts.Clear(); + mCodepointsWithNoFonts.reset(); + + DIR *d = opendir("/system/fonts"); + struct dirent *ent = NULL; + while(d && (ent = readdir(d)) != NULL) { + int namelen = strlen(ent->d_name); + if (namelen > 4 && + strcasecmp(ent->d_name + namelen - 4, ".ttf") == 0) + { + nsCString s("/system/fonts"); + s.Append("/"); + s.Append(nsDependentCString(ent->d_name)); + + AppendFacesFromFontFile(nsPromiseFlatCString(s).get()); + } + } + + mCodepointsWithNoFonts.SetRange(0,0x1f); // C0 controls + mCodepointsWithNoFonts.SetRange(0x7f,0x9f); // C1 controls + +#endif // XP_WIN && ANDROID } void @@ -263,6 +307,11 @@ gfxFT2FontList::GetDefaultFont(const gfxFontStyle* aStyle, PRBool& aNeedsBold) return FindFontForFamily(resolvedName, aStyle, aNeedsBold); } } +#elif defined(ANDROID) + nsAutoString resolvedName; + if (ResolveFontName(nsDependentString(NS_LITERAL_STRING("Droid Sans")), + resolvedName)) + return FindFontForFamily(resolvedName, aStyle, aNeedsBold); #endif /* TODO: what about Qt or other platforms that may use this? */ return nsnull; diff --git a/gfx/thebes/gfxFT2FontList.h b/gfx/thebes/gfxFT2FontList.h index ae50a336e96f..d6c894f9bb80 100644 --- a/gfx/thebes/gfxFT2FontList.h +++ b/gfx/thebes/gfxFT2FontList.h @@ -41,10 +41,12 @@ #ifndef GFX_FT2FONTLIST_H #define GFX_FT2FONTLIST_H +#ifdef XP_WIN #include "gfxWindowsPlatform.h" +#include +#endif #include "gfxPlatformFontList.h" -#include #include class gfxFT2FontList : public gfxPlatformFontList @@ -66,6 +68,7 @@ protected: virtual void InitFontList(); void AppendFacesFromFontFile(const PRUnichar *aFileName); + void AppendFacesFromFontFile(const char *aFileName); void FindFonts(); }; diff --git a/gfx/thebes/gfxFT2Fonts.cpp b/gfx/thebes/gfxFT2Fonts.cpp index 3a49cdd35fc7..54f9194b9a8b 100644 --- a/gfx/thebes/gfxFT2Fonts.cpp +++ b/gfx/thebes/gfxFT2Fonts.cpp @@ -108,6 +108,12 @@ FontEntry::~FontEntry() #endif } +gfxFont* +FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold) { + already_AddRefed font = gfxFT2Font::GetOrMakeFont(this, aFontStyle); + return font.get(); +} + /* static */ FontEntry* FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry, @@ -325,8 +331,9 @@ gfxFT2FontGroup::FontCallback(const nsAString& fontName, } gfxFT2FontGroup::gfxFT2FontGroup(const nsAString& families, - const gfxFontStyle *aStyle) - : gfxFontGroup(families, aStyle) + const gfxFontStyle *aStyle, + gfxUserFontSet *aUserFontSet) + : gfxFontGroup(families, aStyle, aUserFontSet) { #ifdef DEBUG_pavlov printf("Looking for %s\n", NS_ConvertUTF16toUTF8(families).get()); @@ -385,7 +392,7 @@ gfxFT2FontGroup::~gfxFT2FontGroup() gfxFontGroup * gfxFT2FontGroup::Copy(const gfxFontStyle *aStyle) { - return new gfxFT2FontGroup(mFamilies, aStyle); + return new gfxFT2FontGroup(mFamilies, aStyle, nsnull); } /** @@ -699,7 +706,7 @@ gfxFT2FontGroup::WhichSystemFontSupportsChar(PRUint32 aCh) } #else nsRefPtr selectedFont; - nsRefPtr refFont = GetFontAt(0); + nsRefPtr refFont = GetFontAt(0); gfxToolkitPlatform *platform = gfxToolkitPlatform::GetPlatform(); selectedFont = platform->FindFontForChar(aCh, refFont); if (selectedFont) diff --git a/gfx/thebes/gfxFT2Fonts.h b/gfx/thebes/gfxFT2Fonts.h index 688c4daa84ce..a8d44a1be7cd 100644 --- a/gfx/thebes/gfxFT2Fonts.h +++ b/gfx/thebes/gfxFT2Fonts.h @@ -94,6 +94,8 @@ public: // aFontData is NS_Malloc'ed data that aFace depends on, to be freed // after the face is destroyed; null if there is no such buffer + virtual gfxFont *CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold); + cairo_font_face_t *CairoFontFace(); nsresult ReadCMAP(); @@ -159,23 +161,10 @@ protected: class THEBES_API gfxFT2FontGroup : public gfxFontGroup { public: // new functions gfxFT2FontGroup (const nsAString& families, - const gfxFontStyle *aStyle); + const gfxFontStyle *aStyle, + gfxUserFontSet *aUserFontSet); virtual ~gfxFT2FontGroup (); - inline gfxFT2Font *GetFontAt (PRInt32 i) { - // If it turns out to be hard for all clients that cache font - // groups to call UpdateFontList at appropriate times, we could - // instead consider just calling UpdateFontList from someplace - // more central (such as here). - NS_ASSERTION(!mUserFontSet || mCurrGeneration == GetGeneration(), - "Whoever was caching this font group should have " - "called UpdateFontList on it"); - NS_ASSERTION(mFonts.Length() > PRUint32(i), - "Requesting a font index that doesn't exist"); - - return static_cast (static_cast (mFonts[i])); - } - protected: // from gfxFontGroup virtual gfxTextRun *MakeTextRun(const PRUnichar *aString, PRUint32 aLength, diff --git a/gfx/thebes/gfxFont.cpp b/gfx/thebes/gfxFont.cpp index 7c8ffeabe313..bfc1177130af 100644 --- a/gfx/thebes/gfxFont.cpp +++ b/gfx/thebes/gfxFont.cpp @@ -1764,7 +1764,7 @@ gfxFontGroup::BuildFontList() { // "#if" to be removed once all platforms are moved to gfxPlatformFontList interface // and subclasses of gfxFontGroup eliminated -#if defined(XP_MACOSX) || (defined(XP_WIN) && !defined(WINCE)) +#if defined(XP_MACOSX) || (defined(XP_WIN) && !defined(WINCE)) || defined(ANDROID) ForEachFont(FindPlatformFont, this); if (mFonts.Length() == 0) { diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index d46488a592ac..cd0bba73d5cf 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -242,7 +242,7 @@ gfxPlatform::Init() nsresult rv; -#if defined(XP_MACOSX) || defined(XP_WIN) // temporary, until this is implemented on others +#if defined(XP_MACOSX) || defined(XP_WIN) || defined(ANDROID) // temporary, until this is implemented on others rv = gfxPlatformFontList::Init(); if (NS_FAILED(rv)) { NS_ERROR("Could not initialize gfxPlatformFontList");