bug 571767 - @font-face is not working on Android r=jdagget b=fennec2.0

This commit is contained in:
Brad Lassey 2010-07-16 02:03:45 -04:00
parent f3b2471ebf
commit 3495a1c15f
9 changed files with 130 additions and 28 deletions

View File

@ -277,6 +277,7 @@ CPPSRCS += \
gfxFT2Fonts.cpp \
gfxFT2FontBase.cpp \
gfxFT2Utils.cpp \
gfxFT2FontList.cpp \
nsUnicodeRange.cpp \
$(NULL)
endif

View File

@ -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<nsRefPtr<gfxFontEntry> > *aFontEntryList)
{

View File

@ -62,6 +62,11 @@ public:
already_AddRefed<gfxASurface> 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<nsString>& aListOfFonts);

View File

@ -55,9 +55,9 @@
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsISimpleEnumerator.h"
#include "nsIWindowsRegKey.h"
#ifdef XP_WIN
#include "nsIWindowsRegKey.h"
#include <windows.h>
#endif
@ -67,14 +67,23 @@
static PRLogModuleInfo *gFontInfoLog = PR_NewLogModule("fontInfoLog");
#endif /* PR_LOGGING */
#ifdef ANDROID
#include "gfxAndroidPlatform.h"
#include <dirent.h>
#include <android/log.h>
#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<nsString> searchPaths(3);
nsTArray<nsString> 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;

View File

@ -41,10 +41,12 @@
#ifndef GFX_FT2FONTLIST_H
#define GFX_FT2FONTLIST_H
#ifdef XP_WIN
#include "gfxWindowsPlatform.h"
#include <windows.h>
#endif
#include "gfxPlatformFontList.h"
#include <windows.h>
#include <bitset>
class gfxFT2FontList : public gfxPlatformFontList
@ -66,6 +68,7 @@ protected:
virtual void InitFontList();
void AppendFacesFromFontFile(const PRUnichar *aFileName);
void AppendFacesFromFontFile(const char *aFileName);
void FindFonts();
};

View File

@ -108,6 +108,12 @@ FontEntry::~FontEntry()
#endif
}
gfxFont*
FontEntry::CreateFontInstance(const gfxFontStyle *aFontStyle, PRBool aNeedsBold) {
already_AddRefed<gfxFT2Font> 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<gfxFont> selectedFont;
nsRefPtr<gfxFT2Font> refFont = GetFontAt(0);
nsRefPtr<gfxFont> refFont = GetFontAt(0);
gfxToolkitPlatform *platform = gfxToolkitPlatform::GetPlatform();
selectedFont = platform->FindFontForChar(aCh, refFont);
if (selectedFont)

View File

@ -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 <gfxFT2Font *>(static_cast <gfxFont *>(mFonts[i]));
}
protected: // from gfxFontGroup
virtual gfxTextRun *MakeTextRun(const PRUnichar *aString,
PRUint32 aLength,

View File

@ -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) {

View File

@ -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");