mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 468387 - (reland) disable synthetic faces for downloadable fonts on Windows already specified as bold/italic. r=vlad
This commit is contained in:
parent
586c538ed3
commit
ba340eb217
@ -290,6 +290,8 @@ public:
|
|||||||
nsTArray< nsAutoPtr<Block> > mBlocks;
|
nsTArray< nsAutoPtr<Block> > mBlocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define TRUETYPE_TAG(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
|
||||||
|
|
||||||
class THEBES_API gfxFontUtils {
|
class THEBES_API gfxFontUtils {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -328,7 +330,7 @@ public:
|
|||||||
static nsresult
|
static nsresult
|
||||||
ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap,
|
ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap,
|
||||||
PRPackedBool& aUnicodeFont, PRPackedBool& aSymbolFont);
|
PRPackedBool& aUnicodeFont, PRPackedBool& aSymbolFont);
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
// given a TrueType/OpenType data file, produce a EOT-format header
|
// given a TrueType/OpenType data file, produce a EOT-format header
|
||||||
// for use with Windows T2Embed API AddFontResource type API's
|
// for use with Windows T2Embed API AddFontResource type API's
|
||||||
@ -352,6 +354,36 @@ public:
|
|||||||
RenameFont(const nsAString& aName, const PRUint8 *aFontData,
|
RenameFont(const nsAString& aName, const PRUint8 *aFontData,
|
||||||
PRUint32 aFontDataLength, nsTArray<PRUint8> *aNewFont);
|
PRUint32 aFontDataLength, nsTArray<PRUint8> *aNewFont);
|
||||||
|
|
||||||
|
// constansts used with name table read methods
|
||||||
|
enum {
|
||||||
|
PLATFORM_ALL = -1,
|
||||||
|
PLATFORM_UNICODE = 0,
|
||||||
|
PLATFORM_MACINTOSH = 1,
|
||||||
|
PLATFORM_MICROSOFT = 3,
|
||||||
|
|
||||||
|
NAME_LANG_ALL = -1,
|
||||||
|
|
||||||
|
// name record id's
|
||||||
|
NAME_ID_FAMILY = 1,
|
||||||
|
NAME_ID_STYLE = 2,
|
||||||
|
NAME_ID_UNIQUE = 3,
|
||||||
|
NAME_ID_FULL = 4, // used as key to GDI CreateFontIndirect
|
||||||
|
NAME_ID_VERSION = 5,
|
||||||
|
NAME_ID_POSTSCRIPT = 6,
|
||||||
|
NAME_ID_PREFERRED_FAMILY = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
// read all names matching aNameID, returning in aNames array
|
||||||
|
static nsresult
|
||||||
|
ReadNames(nsTArray<PRUint8>& aNameTable, PRUint32 aNameID,
|
||||||
|
PRInt32 aPlatformID, nsTArray<nsString>& aNames);
|
||||||
|
|
||||||
|
// reads English or first name matching aNameID, returning in aName
|
||||||
|
// platform based on OS
|
||||||
|
static nsresult
|
||||||
|
ReadCanonicalName(nsTArray<PRUint8>& aNameTable, PRUint32 aNameID,
|
||||||
|
nsString& aName);
|
||||||
|
|
||||||
static inline bool IsJoiner(PRUint32 ch) {
|
static inline bool IsJoiner(PRUint32 ch) {
|
||||||
return (ch == 0x200C ||
|
return (ch == 0x200C ||
|
||||||
ch == 0x200D ||
|
ch == 0x200D ||
|
||||||
@ -371,6 +403,11 @@ public:
|
|||||||
// generate a unique font name
|
// generate a unique font name
|
||||||
static nsresult MakeUniqueUserFontName(nsAString& aName);
|
static nsresult MakeUniqueUserFontName(nsAString& aName);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static nsresult
|
||||||
|
ReadNames(nsTArray<PRUint8>& aNameTable, PRUint32 aNameID,
|
||||||
|
PRInt32 aLangID, PRInt32 aPlatformID, nsTArray<nsString>& aNames);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper class for loading in font info spaced out at regular intervals
|
// helper class for loading in font info spaced out at regular intervals
|
||||||
|
@ -110,13 +110,18 @@ private:
|
|||||||
class FontEntry : public gfxFontEntry
|
class FontEntry : public gfxFontEntry
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FontEntry(const nsAString& aFaceName) :
|
FontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType,
|
||||||
gfxFontEntry(aFaceName), mFontType(GFX_FONT_TYPE_UNKNOWN),
|
PRBool aItalic, PRUint16 aWeight, gfxUserFontData *aUserFontData) :
|
||||||
|
gfxFontEntry(aFaceName), mFontType(aFontType),
|
||||||
mForceGDI(PR_FALSE), mUnknownCMAP(PR_FALSE),
|
mForceGDI(PR_FALSE), mUnknownCMAP(PR_FALSE),
|
||||||
mUnicodeFont(PR_FALSE), mSymbolFont(PR_FALSE),
|
mUnicodeFont(PR_FALSE), mSymbolFont(PR_FALSE), mUserFont(PR_FALSE),
|
||||||
mCharset(0), mUnicodeRanges(0)
|
mCharset(0), mUnicodeRanges(0)
|
||||||
{
|
{
|
||||||
|
mUserFontData = aUserFontData;
|
||||||
|
mItalic = aItalic;
|
||||||
|
mWeight = aWeight;
|
||||||
|
if (IsType1())
|
||||||
|
mForceGDI = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FontEntry(const FontEntry& aFontEntry) :
|
FontEntry(const FontEntry& aFontEntry) :
|
||||||
@ -128,6 +133,7 @@ public:
|
|||||||
mUnknownCMAP(aFontEntry.mUnknownCMAP),
|
mUnknownCMAP(aFontEntry.mUnknownCMAP),
|
||||||
mUnicodeFont(aFontEntry.mUnicodeFont),
|
mUnicodeFont(aFontEntry.mUnicodeFont),
|
||||||
mSymbolFont(aFontEntry.mSymbolFont),
|
mSymbolFont(aFontEntry.mSymbolFont),
|
||||||
|
mUserFont(aFontEntry.mUserFont),
|
||||||
mCharset(aFontEntry.mCharset),
|
mCharset(aFontEntry.mCharset),
|
||||||
mUnicodeRanges(aFontEntry.mUnicodeRanges)
|
mUnicodeRanges(aFontEntry.mUnicodeRanges)
|
||||||
{
|
{
|
||||||
@ -135,16 +141,29 @@ public:
|
|||||||
}
|
}
|
||||||
static void InitializeFontEmbeddingProcs();
|
static void InitializeFontEmbeddingProcs();
|
||||||
|
|
||||||
static FontEntry* CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
|
// create a font entry from downloaded font data
|
||||||
nsISupports *aLoader,
|
static FontEntry* LoadFont(const gfxProxyFontEntry &aProxyEntry,
|
||||||
const PRUint8 *aFontData,
|
nsISupports *aLoader,
|
||||||
PRUint32 aLength);
|
const PRUint8 *aFontData,
|
||||||
|
PRUint32 aLength);
|
||||||
static FontEntry* CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, PRBool aItalic, PRUint16 aWeight, gfxUserFontData* aUserFontData, HDC hdc = 0, LOGFONTW *aLogFont = nsnull);
|
|
||||||
|
|
||||||
static void FillLogFont(LOGFONTW *aLogFont, FontEntry *aFontEntry, gfxFloat aSize, PRBool aItalic);
|
// create a font entry for a font with a given name
|
||||||
|
static FontEntry* CreateFontEntry(const nsAString& aName,
|
||||||
|
gfxWindowsFontType aFontType,
|
||||||
|
PRBool aItalic, PRUint16 aWeight,
|
||||||
|
gfxUserFontData* aUserFontData,
|
||||||
|
HDC hdc = 0, LOGFONTW *aLogFont = nsnull);
|
||||||
|
|
||||||
static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics, DWORD fontType)
|
// create a font entry for a font referenced by its fullname
|
||||||
|
static FontEntry* LoadLocalFont(const gfxProxyFontEntry &aProxyEntry,
|
||||||
|
const nsAString& aFullname);
|
||||||
|
|
||||||
|
static void FillLogFont(LOGFONTW *aLogFont, const nsAString& aName,
|
||||||
|
gfxWindowsFontType aFontType, PRBool aItalic,
|
||||||
|
PRUint16 aWeight, gfxFloat aSize);
|
||||||
|
|
||||||
|
static gfxWindowsFontType DetermineFontType(const NEWTEXTMETRICW& metrics,
|
||||||
|
DWORD fontType)
|
||||||
{
|
{
|
||||||
gfxWindowsFontType feType;
|
gfxWindowsFontType feType;
|
||||||
if (metrics.ntmFlags & NTM_TYPE1)
|
if (metrics.ntmFlags & NTM_TYPE1)
|
||||||
@ -274,6 +293,7 @@ public:
|
|||||||
PRPackedBool mUnknownCMAP : 1;
|
PRPackedBool mUnknownCMAP : 1;
|
||||||
PRPackedBool mUnicodeFont : 1;
|
PRPackedBool mUnicodeFont : 1;
|
||||||
PRPackedBool mSymbolFont : 1;
|
PRPackedBool mSymbolFont : 1;
|
||||||
|
PRPackedBool mUserFont : 1;
|
||||||
|
|
||||||
std::bitset<256> mCharset;
|
std::bitset<256> mCharset;
|
||||||
std::bitset<128> mUnicodeRanges;
|
std::bitset<128> mUnicodeRanges;
|
||||||
|
@ -491,7 +491,7 @@ gfxAtsuiFont::HasMirroringInfo()
|
|||||||
ByteCount size;
|
ByteCount size;
|
||||||
|
|
||||||
// 361695 - if the font has a 'prop' table, assume that ATSUI will handle glyph mirroring
|
// 361695 - if the font has a 'prop' table, assume that ATSUI will handle glyph mirroring
|
||||||
status = ATSFontGetTable(GetATSFontRef(), 'prop', 0, 0, 0, &size);
|
status = ATSFontGetTable(GetATSFontRef(), TRUETYPE_TAG('p','r','o','p'), 0, 0, 0, &size);
|
||||||
mHasMirroring = (status == noErr);
|
mHasMirroring = (status == noErr);
|
||||||
mHasMirroringLookedUp = PR_TRUE;
|
mHasMirroringLookedUp = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,9 @@
|
|||||||
|
|
||||||
#include "plbase64.h"
|
#include "plbase64.h"
|
||||||
|
|
||||||
|
#ifdef XP_MACOSX
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define NO_RANGE_FOUND 126 // bit 126 in the font unicode ranges is required to be 0
|
#define NO_RANGE_FOUND 126 // bit 126 in the font unicode ranges is required to be 0
|
||||||
|
|
||||||
@ -331,19 +334,19 @@ gfxFontUtils::ReadCMAPTableFormat4(PRUint8 *aBuf, PRUint32 aLength, gfxSparseBit
|
|||||||
// For fonts with two format-4 tables, the first one (Unicode platform) is preferred on the Mac.
|
// For fonts with two format-4 tables, the first one (Unicode platform) is preferred on the Mac.
|
||||||
|
|
||||||
#if defined(XP_MACOSX)
|
#if defined(XP_MACOSX)
|
||||||
#define acceptablePlatform(p) ((p) == PlatformIDUnicode || (p) == PlatformIDMicrosoft)
|
#define acceptablePlatform(p) ((p) == PLATFORM_UNICODE || (p) == PLATFORM_MICROSOFT)
|
||||||
#define acceptableFormat4(p,e,k) ( ((p) == PlatformIDMicrosoft && (e) == EncodingIDMicrosoft && (k) != 4) || \
|
#define acceptableFormat4(p,e,k) ( ((p) == PLATFORM_MICROSOFT && (e) == EncodingIDMicrosoft && (k) != 4) || \
|
||||||
((p) == PlatformIDUnicode) )
|
((p) == PLATFORM_UNICODE) )
|
||||||
#define isSymbol(p,e) ((p) == PlatformIDMicrosoft && (e) == EncodingIDSymbol)
|
#define isSymbol(p,e) ((p) == PLATFORM_MICROSOFT && (e) == EncodingIDSymbol)
|
||||||
#else
|
#else
|
||||||
#define acceptablePlatform(p) ((p) == PlatformIDMicrosoft)
|
#define acceptablePlatform(p) ((p) == PLATFORM_MICROSOFT)
|
||||||
#define acceptableFormat4(p,e,k) ((e) == EncodingIDMicrosoft)
|
#define acceptableFormat4(p,e,k) ((e) == EncodingIDMicrosoft)
|
||||||
#define isSymbol(p,e) ((e) == EncodingIDSymbol)
|
#define isSymbol(p,e) ((e) == EncodingIDSymbol)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define acceptableUCS4Encoding(p, e) \
|
#define acceptableUCS4Encoding(p, e) \
|
||||||
((platformID == PlatformIDMicrosoft && encodingID == EncodingIDUCS4ForMicrosoftPlatform) || \
|
((platformID == PLATFORM_MICROSOFT && encodingID == EncodingIDUCS4ForMicrosoftPlatform) || \
|
||||||
(platformID == PlatformIDUnicode && encodingID == EncodingIDUCS4ForUnicodePlatform))
|
(platformID == PLATFORM_UNICODE && encodingID == EncodingIDUCS4ForUnicodePlatform))
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap,
|
gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCharacterMap,
|
||||||
@ -361,10 +364,6 @@ gfxFontUtils::ReadCMAP(PRUint8 *aBuf, PRUint32 aBufLength, gfxSparseBitSet& aCha
|
|||||||
|
|
||||||
SubtableOffsetFormat = 0
|
SubtableOffsetFormat = 0
|
||||||
};
|
};
|
||||||
enum {
|
|
||||||
PlatformIDUnicode = 0,
|
|
||||||
PlatformIDMicrosoft = 3
|
|
||||||
};
|
|
||||||
enum {
|
enum {
|
||||||
EncodingIDSymbol = 0,
|
EncodingIDSymbol = 0,
|
||||||
EncodingIDMicrosoft = 1,
|
EncodingIDMicrosoft = 1,
|
||||||
@ -600,16 +599,9 @@ struct NameRecord {
|
|||||||
AutoSwap_PRUint16 offset; // String offset from start of storage area (in bytes).
|
AutoSwap_PRUint16 offset; // String offset from start of storage area (in bytes).
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NAME_ID_FAMILY = 1,
|
|
||||||
NAME_ID_STYLE = 2,
|
|
||||||
NAME_ID_UNIQUE = 3,
|
|
||||||
NAME_ID_FULL = 4,
|
|
||||||
NAME_ID_VERSION = 5,
|
|
||||||
NAME_ID_POSTSCRIPT = 6,
|
|
||||||
PLATFORM_ID_UNICODE = 0, // Mac OS uses this typically
|
|
||||||
PLATFORM_ID_MICROSOFT = 3,
|
|
||||||
ENCODING_ID_MICROSOFT_UNICODEBMP = 1, // with Microsoft platformID, BMP-only Unicode encoding
|
ENCODING_ID_MICROSOFT_UNICODEBMP = 1, // with Microsoft platformID, BMP-only Unicode encoding
|
||||||
LANG_ID_MICROSOFT_EN_US = 0x0409 // with Microsoft platformID, EN US lang code
|
LANG_ID_MICROSOFT_EN_US = 0x0409, // with Microsoft platformID, EN US lang code
|
||||||
|
LANG_ID_MACINTOSH_EN = 0
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -667,7 +659,7 @@ IsValidSFNTVersion(PRUint32 version)
|
|||||||
{
|
{
|
||||||
// normally 0x00010000, CFF-style OT fonts == 'OTTO' and Apple TT fonts = 'true'
|
// normally 0x00010000, CFF-style OT fonts == 'OTTO' and Apple TT fonts = 'true'
|
||||||
// 'typ1' is also possible for old Type 1 fonts in a SFNT container but not supported
|
// 'typ1' is also possible for old Type 1 fonts in a SFNT container but not supported
|
||||||
return version == 0x10000 || version == 'OTTO' || version == 'true';
|
return version == 0x10000 || version == TRUETYPE_TAG('O','T','T','O') || version == TRUETYPE_TAG('t','r','u','e');
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy and swap UTF-16 values, assume no surrogate pairs, can be in place
|
// copy and swap UTF-16 values, assume no surrogate pairs, can be in place
|
||||||
@ -706,7 +698,7 @@ gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (aIsCFF)
|
if (aIsCFF)
|
||||||
*aIsCFF = (sfntVersion == 'OTTO');
|
*aIsCFF = (sfntVersion == TRUETYPE_TAG('O','T','T','O'));
|
||||||
|
|
||||||
// iterate through the table headers to find the head, name and OS/2 tables
|
// iterate through the table headers to find the head, name and OS/2 tables
|
||||||
PRBool foundHead = PR_FALSE, foundOS2 = PR_FALSE, foundName = PR_FALSE;
|
PRBool foundHead = PR_FALSE, foundOS2 = PR_FALSE, foundName = PR_FALSE;
|
||||||
@ -747,7 +739,7 @@ gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
|||||||
|
|
||||||
switch (dirEntry->tag) {
|
switch (dirEntry->tag) {
|
||||||
|
|
||||||
case 'head':
|
case TRUETYPE_TAG('h','e','a','d'):
|
||||||
foundHead = PR_TRUE;
|
foundHead = PR_TRUE;
|
||||||
headOffset = dirEntry->offset;
|
headOffset = dirEntry->offset;
|
||||||
headLen = dirEntry->length;
|
headLen = dirEntry->length;
|
||||||
@ -757,21 +749,21 @@ gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'name':
|
case TRUETYPE_TAG('n','a','m','e'):
|
||||||
foundName = PR_TRUE;
|
foundName = PR_TRUE;
|
||||||
nameOffset = dirEntry->offset;
|
nameOffset = dirEntry->offset;
|
||||||
nameLen = dirEntry->length;
|
nameLen = dirEntry->length;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'OS/2':
|
case TRUETYPE_TAG('O','S','/','2'):
|
||||||
foundOS2 = PR_TRUE;
|
foundOS2 = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'glyf': // TrueType-style quadratic glyph table
|
case TRUETYPE_TAG('g','l','y','f'): // TrueType-style quadratic glyph table
|
||||||
foundGlyphs = PR_TRUE;
|
foundGlyphs = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'CFF ': // PS-style cubic glyph table
|
case TRUETYPE_TAG('C','F','F',' '): // PS-style cubic glyph table
|
||||||
foundCFF = PR_TRUE;
|
foundCFF = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -811,7 +803,7 @@ gfxFontUtils::ValidateSFNTHeaders(const PRUint8 *aFontData,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// need glyf or CFF table based on sfnt version
|
// need glyf or CFF table based on sfnt version
|
||||||
if (sfntVersion == 'OTTO') {
|
if (sfntVersion == TRUETYPE_TAG('O','T','T','O')) {
|
||||||
if (!foundCFF) {
|
if (!foundCFF) {
|
||||||
NS_WARNING("invalid font (missing CFF table)");
|
NS_WARNING("invalid font (missing CFF table)");
|
||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
@ -861,11 +853,11 @@ gfxFontUtils::RenameFont(const nsAString& aName, const PRUint8 *aFontData,
|
|||||||
PRUint64 dataLength(aFontDataLength);
|
PRUint64 dataLength(aFontDataLength);
|
||||||
|
|
||||||
// new name table
|
// new name table
|
||||||
static const PRUint32 neededNameIDs[] = {NameRecord::NAME_ID_FAMILY,
|
static const PRUint32 neededNameIDs[] = {gfxFontUtils::NAME_ID_FAMILY,
|
||||||
NameRecord::NAME_ID_STYLE,
|
gfxFontUtils::NAME_ID_STYLE,
|
||||||
NameRecord::NAME_ID_UNIQUE,
|
gfxFontUtils::NAME_ID_UNIQUE,
|
||||||
NameRecord::NAME_ID_FULL,
|
gfxFontUtils::NAME_ID_FULL,
|
||||||
NameRecord::NAME_ID_POSTSCRIPT};
|
gfxFontUtils::NAME_ID_POSTSCRIPT};
|
||||||
|
|
||||||
// calculate new name table size
|
// calculate new name table size
|
||||||
PRUint16 nameCount = NS_ARRAY_LENGTH(neededNameIDs);
|
PRUint16 nameCount = NS_ARRAY_LENGTH(neededNameIDs);
|
||||||
@ -909,7 +901,7 @@ gfxFontUtils::RenameFont(const nsAString& aName, const PRUint8 *aFontData,
|
|||||||
NameRecord *nameRecord = reinterpret_cast<NameRecord*>(nameHeader + 1);
|
NameRecord *nameRecord = reinterpret_cast<NameRecord*>(nameHeader + 1);
|
||||||
|
|
||||||
for (i = 0; i < nameCount; i++, nameRecord++) {
|
for (i = 0; i < nameCount; i++, nameRecord++) {
|
||||||
nameRecord->platformID = NameRecord::PLATFORM_ID_MICROSOFT;
|
nameRecord->platformID = gfxFontUtils::PLATFORM_MICROSOFT;
|
||||||
nameRecord->encodingID = NameRecord::ENCODING_ID_MICROSOFT_UNICODEBMP;
|
nameRecord->encodingID = NameRecord::ENCODING_ID_MICROSOFT_UNICODEBMP;
|
||||||
nameRecord->languageID = NameRecord::LANG_ID_MICROSOFT_EN_US;
|
nameRecord->languageID = NameRecord::LANG_ID_MICROSOFT_EN_US;
|
||||||
nameRecord->nameID = neededNameIDs[i];
|
nameRecord->nameID = neededNameIDs[i];
|
||||||
@ -939,7 +931,7 @@ gfxFontUtils::RenameFont(const nsAString& aName, const PRUint8 *aFontData,
|
|||||||
PRBool foundName = PR_FALSE;
|
PRBool foundName = PR_FALSE;
|
||||||
|
|
||||||
for (i = 0; i < numTables; i++, dirEntry++) {
|
for (i = 0; i < numTables; i++, dirEntry++) {
|
||||||
if (dirEntry->tag == 'name') {
|
if (dirEntry->tag == TRUETYPE_TAG('n','a','m','e')) {
|
||||||
foundName = PR_TRUE;
|
foundName = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -980,7 +972,7 @@ gfxFontUtils::RenameFont(const nsAString& aName, const PRUint8 *aFontData,
|
|||||||
dirEntry = reinterpret_cast<TableDirEntry*>(newFontData + sizeof(SFNTHeader));
|
dirEntry = reinterpret_cast<TableDirEntry*>(newFontData + sizeof(SFNTHeader));
|
||||||
|
|
||||||
for (i = 0; i < numTables; i++, dirEntry++) {
|
for (i = 0; i < numTables; i++, dirEntry++) {
|
||||||
if (dirEntry->tag == 'head') {
|
if (dirEntry->tag == TRUETYPE_TAG('h','e','a','d')) {
|
||||||
headOffset = dirEntry->offset;
|
headOffset = dirEntry->offset;
|
||||||
}
|
}
|
||||||
checksum += dirEntry->checkSum;
|
checksum += dirEntry->checkSum;
|
||||||
@ -995,6 +987,216 @@ gfxFontUtils::RenameFont(const nsAString& aName, const PRUint8 *aFontData,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
CANONICAL_LANG_ID = NameRecord::LANG_ID_MACINTOSH_EN,
|
||||||
|
PLATFORM_ID = gfxFontUtils::PLATFORM_MACINTOSH
|
||||||
|
#else
|
||||||
|
CANONICAL_LANG_ID = NameRecord::LANG_ID_MICROSOFT_EN_US,
|
||||||
|
PLATFORM_ID = gfxFontUtils::PLATFORM_MICROSOFT
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
gfxFontUtils::ReadNames(nsTArray<PRUint8>& aNameTable, PRUint32 aNameID,
|
||||||
|
PRInt32 aPlatformID, nsTArray<nsString>& aNames)
|
||||||
|
{
|
||||||
|
return ReadNames(aNameTable, aNameID, NAME_LANG_ALL, aPlatformID, aNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
gfxFontUtils::ReadCanonicalName(nsTArray<PRUint8>& aNameTable, PRUint32 aNameID,
|
||||||
|
nsString& aName)
|
||||||
|
{
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
nsTArray<nsString> names;
|
||||||
|
|
||||||
|
// first, look for the English name (this will succeed 99% of the time)
|
||||||
|
rv = ReadNames(aNameTable, aNameID, CANONICAL_LANG_ID, PLATFORM_ID, names);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// otherwise, grab names for all languages
|
||||||
|
if (names.Length() == 0) {
|
||||||
|
rv = ReadNames(aNameTable, aNameID, NAME_LANG_ALL, PLATFORM_ID, names);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
// may be dealing with font that only has Microsoft name entries
|
||||||
|
if (names.Length() == 0) {
|
||||||
|
rv = ReadNames(aNameTable, aNameID, NameRecord::LANG_ID_MICROSOFT_EN_US,
|
||||||
|
gfxFontUtils::PLATFORM_MICROSOFT, names);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
// getting really desperate now, take anything!
|
||||||
|
if (names.Length() == 0) {
|
||||||
|
rv = ReadNames(aNameTable, aNameID, NAME_LANG_ALL,
|
||||||
|
gfxFontUtils::PLATFORM_MICROSOFT, names);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// return the first name (99.9% of the time names will
|
||||||
|
// contain a single English name)
|
||||||
|
if (names.Length()) {
|
||||||
|
aName.Assign(names[0]);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
DecodeName(PRUint8 *aNameData, PRUint32 aByteLen, PRInt32 aPlatform,
|
||||||
|
PRUint32 aEncoding, nsAString& aName)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aPlatform != gfxFontUtils::PLATFORM_ALL, "need a defined platform to decode string");
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
|
||||||
|
CFStringRef name = NULL;
|
||||||
|
|
||||||
|
if (aPlatform == gfxFontUtils::PLATFORM_MACINTOSH) {
|
||||||
|
name = CFStringCreateWithBytes(kCFAllocatorDefault, aNameData, aByteLen,
|
||||||
|
(CFStringEncoding) aEncoding, false);
|
||||||
|
} else if (aPlatform == gfxFontUtils::PLATFORM_UNICODE
|
||||||
|
|| aPlatform == gfxFontUtils::PLATFORM_MICROSOFT)
|
||||||
|
{
|
||||||
|
name = CFStringCreateWithBytes(kCFAllocatorDefault, aNameData, aByteLen,
|
||||||
|
kCFStringEncodingUTF16BE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
CFIndex len = CFStringGetLength(name);
|
||||||
|
aName.SetLength(len);
|
||||||
|
CFStringGetCharacters(name, CFRangeMake(0, len), aName.BeginWriting());
|
||||||
|
CFRelease(name);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// skip non-MS platforms and non-Unicode encodings
|
||||||
|
if (aPlatform != gfxFontUtils::PLATFORM_MICROSOFT
|
||||||
|
|| aEncoding != NameRecord::ENCODING_ID_MICROSOFT_UNICODEBMP)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRUint32 strLen = aByteLen/2;
|
||||||
|
PRUnichar *str;
|
||||||
|
|
||||||
|
#ifdef IS_LITTLE_ENDIAN
|
||||||
|
nsAutoTArray<PRUnichar,256> swapBuf;
|
||||||
|
if (!swapBuf.AppendElements(strLen))
|
||||||
|
NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
str = (PRUnichar*) (swapBuf.Elements());
|
||||||
|
PRUnichar *ch, *end = (PRUnichar*)(aNameData + aByteLen);
|
||||||
|
for (ch = (PRUnichar*) aNameData; ch < end; ch++) {
|
||||||
|
*str++ = NS_SWAP16(*ch);
|
||||||
|
}
|
||||||
|
str = (PRUnichar*) (swapBuf.Elements());
|
||||||
|
#else
|
||||||
|
str = (PRUnichar*) aNameData;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
aName.Assign(str, strLen);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
gfxFontUtils::ReadNames(nsTArray<PRUint8>& aNameTable, PRUint32 aNameID,
|
||||||
|
PRInt32 aLangID, PRInt32 aPlatformID,
|
||||||
|
nsTArray<nsString>& aNames)
|
||||||
|
{
|
||||||
|
PRUint32 nameTableLen = aNameTable.Length();
|
||||||
|
NS_ASSERTION(nameTableLen != 0, "null name table");
|
||||||
|
|
||||||
|
if (nameTableLen == 0)
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
PRUint8 *nameTable = aNameTable.Elements();
|
||||||
|
|
||||||
|
// -- name table data
|
||||||
|
const NameHeader *nameHeader = reinterpret_cast<const NameHeader*>(nameTable);
|
||||||
|
|
||||||
|
PRUint32 nameCount = nameHeader->count;
|
||||||
|
|
||||||
|
// -- sanity check the number of name records
|
||||||
|
if (PRUint64(nameCount) * sizeof(NameRecord) > nameTableLen) {
|
||||||
|
NS_WARNING("invalid font (name table data)");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- iterate through name records
|
||||||
|
const NameRecord *nameRecord
|
||||||
|
= reinterpret_cast<const NameRecord*>(nameTable + sizeof(NameHeader));
|
||||||
|
PRUint64 nameStringsBase = PRUint64(nameHeader->stringOffset);
|
||||||
|
|
||||||
|
PRUint32 i;
|
||||||
|
for (i = 0; i < nameCount; i++, nameRecord++) {
|
||||||
|
PRUint32 platformID;
|
||||||
|
|
||||||
|
// skip over unwanted nameID's
|
||||||
|
if (PRUint32(nameRecord->nameID) != aNameID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// skip over unwanted platform data
|
||||||
|
platformID = nameRecord->platformID;
|
||||||
|
if (aPlatformID != PLATFORM_ALL
|
||||||
|
&& PRUint32(nameRecord->platformID) != PLATFORM_ID)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// skip over unwanted languages
|
||||||
|
if (aLangID != NAME_LANG_ALL
|
||||||
|
&& PRUint32(nameRecord->languageID) != PRUint32(aLangID))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// add name to names array
|
||||||
|
|
||||||
|
// -- calculate string location
|
||||||
|
PRUint32 namelen = nameRecord->length;
|
||||||
|
PRUint32 nameoff = nameRecord->offset; // offset from base of string storage
|
||||||
|
|
||||||
|
if (nameStringsBase + PRUint64(nameoff) + PRUint64(namelen)
|
||||||
|
> nameTableLen) {
|
||||||
|
NS_WARNING("invalid font (name table strings)");
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- decode if necessary and make nsString
|
||||||
|
nsAutoString name;
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
rv = DecodeName(nameTable + nameStringsBase + nameoff, namelen,
|
||||||
|
platformID, PRUint32(nameRecord->encodingID), name);
|
||||||
|
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PRUint32 k, numNames;
|
||||||
|
PRBool foundName = PR_FALSE;
|
||||||
|
|
||||||
|
numNames = aNames.Length();
|
||||||
|
for (k = 0; k < numNames; k++) {
|
||||||
|
if (name.Equals(aNames[k])) {
|
||||||
|
foundName = PR_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundName)
|
||||||
|
aNames.AppendElement(name);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Embedded OpenType (EOT) handling
|
// Embedded OpenType (EOT) handling
|
||||||
// needed for dealing with downloadable fonts on Windows
|
// needed for dealing with downloadable fonts on Windows
|
||||||
//
|
//
|
||||||
@ -1142,7 +1344,7 @@ gfxFontUtils::MakeEOTHeader(const PRUint8 *aFontData, PRUint32 aFontDataLength,
|
|||||||
|
|
||||||
switch (dirEntry->tag) {
|
switch (dirEntry->tag) {
|
||||||
|
|
||||||
case 'head':
|
case TRUETYPE_TAG('h','e','a','d'):
|
||||||
foundHead = PR_TRUE;
|
foundHead = PR_TRUE;
|
||||||
headOffset = dirEntry->offset;
|
headOffset = dirEntry->offset;
|
||||||
headLen = dirEntry->length;
|
headLen = dirEntry->length;
|
||||||
@ -1150,23 +1352,23 @@ gfxFontUtils::MakeEOTHeader(const PRUint8 *aFontData, PRUint32 aFontDataLength,
|
|||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'name':
|
case TRUETYPE_TAG('n','a','m','e'):
|
||||||
foundName = PR_TRUE;
|
foundName = PR_TRUE;
|
||||||
nameOffset = dirEntry->offset;
|
nameOffset = dirEntry->offset;
|
||||||
nameLen = dirEntry->length;
|
nameLen = dirEntry->length;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'OS/2':
|
case TRUETYPE_TAG('O','S','/','2'):
|
||||||
foundOS2 = PR_TRUE;
|
foundOS2 = PR_TRUE;
|
||||||
os2Offset = dirEntry->offset;
|
os2Offset = dirEntry->offset;
|
||||||
os2Len = dirEntry->length;
|
os2Len = dirEntry->length;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'glyf': // TrueType-style quadratic glyph table
|
case TRUETYPE_TAG('g','l','y','f'): // TrueType-style quadratic glyph table
|
||||||
foundGlyphs = PR_TRUE;
|
foundGlyphs = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'CFF ': // PS-style cubic glyph table
|
case TRUETYPE_TAG('C','F','F',' '): // PS-style cubic glyph table
|
||||||
foundGlyphs = PR_TRUE;
|
foundGlyphs = PR_TRUE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1217,32 +1419,32 @@ gfxFontUtils::MakeEOTHeader(const PRUint8 *aFontData, PRUint32 aFontDataLength,
|
|||||||
for (i = 0; i < nameCount; i++, nameRecord++) {
|
for (i = 0; i < nameCount; i++, nameRecord++) {
|
||||||
|
|
||||||
// looking for Microsoft English US name strings, skip others
|
// looking for Microsoft English US name strings, skip others
|
||||||
if (PRUint32(nameRecord->platformID) != NameRecord::PLATFORM_ID_MICROSOFT ||
|
if (PRUint32(nameRecord->platformID) != gfxFontUtils::PLATFORM_MICROSOFT ||
|
||||||
PRUint32(nameRecord->encodingID) != NameRecord::ENCODING_ID_MICROSOFT_UNICODEBMP ||
|
PRUint32(nameRecord->encodingID) != NameRecord::ENCODING_ID_MICROSOFT_UNICODEBMP ||
|
||||||
PRUint32(nameRecord->languageID) != NameRecord::LANG_ID_MICROSOFT_EN_US)
|
PRUint32(nameRecord->languageID) != NameRecord::LANG_ID_MICROSOFT_EN_US)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch ((PRUint32)nameRecord->nameID) {
|
switch ((PRUint32)nameRecord->nameID) {
|
||||||
|
|
||||||
case NameRecord::NAME_ID_FAMILY:
|
case gfxFontUtils::NAME_ID_FAMILY:
|
||||||
names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].offset = nameRecord->offset;
|
names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].offset = nameRecord->offset;
|
||||||
names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].length = nameRecord->length;
|
names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].length = nameRecord->length;
|
||||||
needNames &= ~(1 << EOTFixedHeader::EOT_FAMILY_NAME_INDEX);
|
needNames &= ~(1 << EOTFixedHeader::EOT_FAMILY_NAME_INDEX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NameRecord::NAME_ID_STYLE:
|
case gfxFontUtils::NAME_ID_STYLE:
|
||||||
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].offset = nameRecord->offset;
|
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].offset = nameRecord->offset;
|
||||||
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].length = nameRecord->length;
|
names[EOTFixedHeader::EOT_STYLE_NAME_INDEX].length = nameRecord->length;
|
||||||
needNames &= ~(1 << EOTFixedHeader::EOT_STYLE_NAME_INDEX);
|
needNames &= ~(1 << EOTFixedHeader::EOT_STYLE_NAME_INDEX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NameRecord::NAME_ID_FULL:
|
case gfxFontUtils::NAME_ID_FULL:
|
||||||
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].offset = nameRecord->offset;
|
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].offset = nameRecord->offset;
|
||||||
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].length = nameRecord->length;
|
names[EOTFixedHeader::EOT_FULL_NAME_INDEX].length = nameRecord->length;
|
||||||
needNames &= ~(1 << EOTFixedHeader::EOT_FULL_NAME_INDEX);
|
needNames &= ~(1 << EOTFixedHeader::EOT_FULL_NAME_INDEX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NameRecord::NAME_ID_VERSION:
|
case gfxFontUtils::NAME_ID_VERSION:
|
||||||
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].offset = nameRecord->offset;
|
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].offset = nameRecord->offset;
|
||||||
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].length = nameRecord->length;
|
names[EOTFixedHeader::EOT_VERSION_NAME_INDEX].length = nameRecord->length;
|
||||||
needNames &= ~(1 << EOTFixedHeader::EOT_VERSION_NAME_INDEX);
|
needNames &= ~(1 << EOTFixedHeader::EOT_VERSION_NAME_INDEX);
|
||||||
|
@ -195,7 +195,9 @@ MacOSFontEntry::ReadCMAP()
|
|||||||
// attempt this once, if errors occur leave a blank cmap
|
// attempt this once, if errors occur leave a blank cmap
|
||||||
mCmapInitialized = PR_TRUE;
|
mCmapInitialized = PR_TRUE;
|
||||||
|
|
||||||
status = ATSFontGetTable(fontRef, 'cmap', 0, 0, 0, &size);
|
PRUint32 kCMAP = TRUETYPE_TAG('c','m','a','p');
|
||||||
|
|
||||||
|
status = ATSFontGetTable(fontRef, kCMAP, 0, 0, 0, &size);
|
||||||
cmapSize = size;
|
cmapSize = size;
|
||||||
//printf( "cmap size: %s %d", NS_ConvertUTF16toUTF8(mName).get(), size );
|
//printf( "cmap size: %s %d", NS_ConvertUTF16toUTF8(mName).get(), size );
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@ -212,7 +214,7 @@ MacOSFontEntry::ReadCMAP()
|
|||||||
return NS_ERROR_OUT_OF_MEMORY;
|
return NS_ERROR_OUT_OF_MEMORY;
|
||||||
PRUint8 *cmap = buffer.Elements();
|
PRUint8 *cmap = buffer.Elements();
|
||||||
|
|
||||||
status = ATSFontGetTable(fontRef, 'cmap', 0, size, cmap, &size);
|
status = ATSFontGetTable(fontRef, kCMAP, 0, size, cmap, &size);
|
||||||
NS_ENSURE_TRUE(status == noErr, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(status == noErr, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsresult rv = NS_ERROR_FAILURE;
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
@ -232,13 +234,13 @@ MacOSFontEntry::ReadCMAP()
|
|||||||
|
|
||||||
// check for mort/morx table, if haven't already
|
// check for mort/morx table, if haven't already
|
||||||
if (!checkedForMorphTable) {
|
if (!checkedForMorphTable) {
|
||||||
status = ATSFontGetTable(fontRef, 'morx', 0, 0, 0, &size);
|
status = ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','x'), 0, 0, 0, &size);
|
||||||
if (status == noErr) {
|
if (status == noErr) {
|
||||||
checkedForMorphTable = PR_TRUE;
|
checkedForMorphTable = PR_TRUE;
|
||||||
hasMorphTable = PR_TRUE;
|
hasMorphTable = PR_TRUE;
|
||||||
} else {
|
} else {
|
||||||
// check for a mort table
|
// check for a mort table
|
||||||
status = ATSFontGetTable(fontRef, 'mort', 0, 0, 0, &size);
|
status = ATSFontGetTable(fontRef, TRUETYPE_TAG('m','o','r','t'), 0, 0, 0, &size);
|
||||||
checkedForMorphTable = PR_TRUE;
|
checkedForMorphTable = PR_TRUE;
|
||||||
if (status == noErr) {
|
if (status == noErr) {
|
||||||
hasMorphTable = PR_TRUE;
|
hasMorphTable = PR_TRUE;
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
#include "nsIPrefService.h"
|
#include "nsIPrefService.h"
|
||||||
#include "nsIPrefLocalizedString.h"
|
#include "nsIPrefLocalizedString.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
#include "nsIStreamBufferAccess.h"
|
||||||
|
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
|
|
||||||
@ -147,7 +148,7 @@ struct DCFromContext {
|
|||||||
static nsresult
|
static nsresult
|
||||||
ReadCMAP(HDC hdc, FontEntry *aFontEntry)
|
ReadCMAP(HDC hdc, FontEntry *aFontEntry)
|
||||||
{
|
{
|
||||||
const PRUint32 kCMAP = (('c') | ('m' << 8) | ('a' << 16) | ('p' << 24));
|
const PRUint32 kCMAP = NS_SWAP32(TRUETYPE_TAG('c','m','a','p'));
|
||||||
|
|
||||||
DWORD len = GetFontData(hdc, kCMAP, 0, nsnull, 0);
|
DWORD len = GetFontData(hdc, kCMAP, 0, nsnull, 0);
|
||||||
if (len == GDI_ERROR || len == 0) // not a truetype font --
|
if (len == GDI_ERROR || len == 0) // not a truetype font --
|
||||||
@ -494,9 +495,9 @@ public:
|
|||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
FontEntry*
|
FontEntry*
|
||||||
FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
|
FontEntry::LoadFont(const gfxProxyFontEntry &aProxyEntry,
|
||||||
nsISupports *aLoader,const PRUint8 *aFontData,
|
nsISupports *aLoader,const PRUint8 *aFontData,
|
||||||
PRUint32 aLength) {
|
PRUint32 aLength) {
|
||||||
// if calls aren't available, bail
|
// if calls aren't available, bail
|
||||||
if (!TTLoadEmbeddedFontPtr || !TTDeleteEmbeddedFontPtr)
|
if (!TTLoadEmbeddedFontPtr || !TTDeleteEmbeddedFontPtr)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
@ -579,13 +580,45 @@ FontEntry::CreateFontEntry(const gfxProxyFontEntry &aProxyEntry,
|
|||||||
PRUint32(aProxyEntry.mItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL),
|
PRUint32(aProxyEntry.mItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL),
|
||||||
w, winUserFontData);
|
w, winUserFontData);
|
||||||
|
|
||||||
if (fe && isCFF)
|
if (!fe)
|
||||||
|
return fe;
|
||||||
|
|
||||||
|
fe->mUserFont = PR_TRUE;
|
||||||
|
if (isCFF)
|
||||||
fe->mForceGDI = PR_TRUE;
|
fe->mForceGDI = PR_TRUE;
|
||||||
|
|
||||||
return fe;
|
return fe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AutoReleaseDC {
|
||||||
|
public:
|
||||||
|
AutoReleaseDC(HDC hdc) : mDC(hdc) {
|
||||||
|
SetGraphicsMode(hdc, GM_ADVANCED);
|
||||||
|
}
|
||||||
|
~AutoReleaseDC() { ReleaseDC(nsnull, mDC); }
|
||||||
|
HDC mDC;
|
||||||
|
};
|
||||||
|
|
||||||
|
class AutoPushPopFont {
|
||||||
|
public:
|
||||||
|
AutoPushPopFont(HDC hdc, HFONT aFont) : mDC(hdc), mFont(aFont) {
|
||||||
|
mOldFont = (HFONT)SelectObject(mDC, mFont);
|
||||||
|
}
|
||||||
|
~AutoPushPopFont() {
|
||||||
|
SelectObject(mDC, mOldFont);
|
||||||
|
DeleteObject(mFont);
|
||||||
|
}
|
||||||
|
HDC mDC;
|
||||||
|
HFONT mFont;
|
||||||
|
HFONT mOldFont;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* static */
|
||||||
FontEntry*
|
FontEntry*
|
||||||
FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType, PRBool aItalic, PRUint16 aWeight, gfxUserFontData* aUserFontData, HDC hdc, LOGFONTW *aLogFont)
|
FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType,
|
||||||
|
PRBool aItalic, PRUint16 aWeight,
|
||||||
|
gfxUserFontData* aUserFontData,
|
||||||
|
HDC hdc, LOGFONTW *aLogFont)
|
||||||
{
|
{
|
||||||
LOGFONTW logFont;
|
LOGFONTW logFont;
|
||||||
PRBool needRelease = PR_FALSE;
|
PRBool needRelease = PR_FALSE;
|
||||||
@ -594,19 +627,11 @@ FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType,
|
|||||||
|
|
||||||
FontEntry *fe;
|
FontEntry *fe;
|
||||||
|
|
||||||
fe = new FontEntry(aName);
|
fe = new FontEntry(aName, aFontType, aItalic, aWeight, aUserFontData);
|
||||||
fe->mFontType = aFontType;
|
|
||||||
fe->mUserFontData = aUserFontData;
|
|
||||||
|
|
||||||
fe->mItalic = aItalic;
|
|
||||||
fe->mWeight = aWeight;
|
|
||||||
|
|
||||||
if (fe->IsType1())
|
|
||||||
fe->mForceGDI = PR_TRUE;
|
|
||||||
|
|
||||||
if (!aLogFont) {
|
if (!aLogFont) {
|
||||||
aLogFont = &logFont;
|
aLogFont = &logFont;
|
||||||
FontEntry::FillLogFont(aLogFont, fe, 0, aItalic);
|
FontEntry::FillLogFont(aLogFont, aName, aFontType, aItalic, aWeight, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hdc) {
|
if (!hdc) {
|
||||||
@ -614,11 +639,11 @@ FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType,
|
|||||||
SetGraphicsMode(hdc, GM_ADVANCED);
|
SetGraphicsMode(hdc, GM_ADVANCED);
|
||||||
needRelease = PR_TRUE;
|
needRelease = PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HFONT font = CreateFontIndirectW(aLogFont);
|
HFONT font = CreateFontIndirectW(aLogFont);
|
||||||
|
|
||||||
if (font) {
|
if (font) {
|
||||||
HFONT oldFont = (HFONT)SelectObject(hdc, font);
|
AutoPushPopFont fontCleanup(hdc, font);
|
||||||
|
|
||||||
// ReadCMAP may change the values of mUnicodeFont and mSymbolFont
|
// ReadCMAP may change the values of mUnicodeFont and mSymbolFont
|
||||||
if (NS_FAILED(::ReadCMAP(hdc, fe))) {
|
if (NS_FAILED(::ReadCMAP(hdc, fe))) {
|
||||||
@ -634,9 +659,6 @@ FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType,
|
|||||||
fe->mUnknownCMAP = PR_TRUE;
|
fe->mUnknownCMAP = PR_TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectObject(hdc, oldFont);
|
|
||||||
DeleteObject(font);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needRelease)
|
if (needRelease)
|
||||||
@ -645,9 +667,82 @@ FontEntry::CreateFontEntry(const nsAString& aName, gfxWindowsFontType aFontType,
|
|||||||
return fe;
|
return fe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */
|
||||||
|
FontEntry*
|
||||||
|
FontEntry::LoadLocalFont(const gfxProxyFontEntry &aProxyEntry,
|
||||||
|
const nsAString& aFullname)
|
||||||
|
{
|
||||||
|
// lookup name with CreateFontIndirect
|
||||||
|
HDC hdc = GetDC(nsnull);
|
||||||
|
AutoReleaseDC dcCleanup(hdc);
|
||||||
|
SetGraphicsMode(hdc, GM_ADVANCED);
|
||||||
|
|
||||||
|
LOGFONTW logFont;
|
||||||
|
memset(&logFont, 0, sizeof(LOGFONTW));
|
||||||
|
logFont.lfCharSet = DEFAULT_CHARSET;
|
||||||
|
PRUint32 namelen = PR_MIN(aFullname.Length(), LF_FACESIZE - 1);
|
||||||
|
memcpy(logFont.lfFaceName,
|
||||||
|
nsPromiseFlatString(aFullname).get(),
|
||||||
|
namelen * sizeof(PRUnichar));
|
||||||
|
logFont.lfFaceName[namelen] = 0;
|
||||||
|
|
||||||
|
HFONT font = CreateFontIndirectW(&logFont);
|
||||||
|
if (!font)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
// fetch fullname from name table (Windows takes swapped tag order)
|
||||||
|
const PRUint32 kNameTag = NS_SWAP32(TRUETYPE_TAG('n','a','m','e'));
|
||||||
|
nsAutoString fullName;
|
||||||
|
|
||||||
|
{
|
||||||
|
AutoPushPopFont fontCleanup(hdc, font);
|
||||||
|
|
||||||
|
DWORD len = GetFontData(hdc, kNameTag, 0, nsnull, 0);
|
||||||
|
if (len == GDI_ERROR || len == 0) // not a truetype font --
|
||||||
|
return nsnull; // so just ignore
|
||||||
|
|
||||||
|
nsAutoTArray<PRUint8,1024> nameData;
|
||||||
|
if (!nameData.AppendElements(len))
|
||||||
|
return nsnull;
|
||||||
|
PRUint8 *nameTable = nameData.Elements();
|
||||||
|
|
||||||
|
DWORD newLen = GetFontData(hdc, kNameTag, 0, nameTable, len);
|
||||||
|
if (newLen != len)
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
|
||||||
|
rv = gfxFontUtils::ReadCanonicalName(nameData,
|
||||||
|
gfxFontUtils::NAME_ID_FULL,
|
||||||
|
fullName);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reject if different from canonical fullname
|
||||||
|
if (!aFullname.Equals(fullName))
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
// create a new font entry
|
||||||
|
PRUint16 w = (aProxyEntry.mWeight == 0 ? 400 : aProxyEntry.mWeight);
|
||||||
|
PRBool isCFF = PR_FALSE; // jtdfix -- need to determine this
|
||||||
|
|
||||||
|
FontEntry *fe = FontEntry::CreateFontEntry(aFullname,
|
||||||
|
gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/,
|
||||||
|
PRUint32(aProxyEntry.mItalic ? FONT_STYLE_ITALIC : FONT_STYLE_NORMAL),
|
||||||
|
w, nsnull);
|
||||||
|
|
||||||
|
if (!fe)
|
||||||
|
return fe;
|
||||||
|
|
||||||
|
fe->mUserFont = PR_TRUE;
|
||||||
|
return fe;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
FontEntry::FillLogFont(LOGFONTW *aLogFont, FontEntry *aFontEntry, gfxFloat aSize, PRBool aItalic)
|
FontEntry::FillLogFont(LOGFONTW *aLogFont, const nsAString& aName,
|
||||||
|
gfxWindowsFontType aFontType, PRBool aItalic,
|
||||||
|
PRUint16 aWeight, gfxFloat aSize)
|
||||||
{
|
{
|
||||||
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
|
#define CLIP_TURNOFF_FONTASSOCIATION 0x40
|
||||||
|
|
||||||
@ -663,7 +758,7 @@ FontEntry::FillLogFont(LOGFONTW *aLogFont, FontEntry *aFontEntry, gfxFloat aSize
|
|||||||
aLogFont->lfUnderline = FALSE;
|
aLogFont->lfUnderline = FALSE;
|
||||||
aLogFont->lfStrikeOut = FALSE;
|
aLogFont->lfStrikeOut = FALSE;
|
||||||
aLogFont->lfCharSet = DEFAULT_CHARSET;
|
aLogFont->lfCharSet = DEFAULT_CHARSET;
|
||||||
aLogFont->lfOutPrecision = FontTypeToOutPrecision(aFontEntry->mFontType);
|
aLogFont->lfOutPrecision = FontTypeToOutPrecision(aFontType);
|
||||||
aLogFont->lfClipPrecision = CLIP_TURNOFF_FONTASSOCIATION;
|
aLogFont->lfClipPrecision = CLIP_TURNOFF_FONTASSOCIATION;
|
||||||
aLogFont->lfQuality = DEFAULT_QUALITY;
|
aLogFont->lfQuality = DEFAULT_QUALITY;
|
||||||
aLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
aLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
|
||||||
@ -672,10 +767,10 @@ FontEntry::FillLogFont(LOGFONTW *aLogFont, FontEntry *aFontEntry, gfxFloat aSize
|
|||||||
// it may give us a regular one based on weight. Windows should
|
// it may give us a regular one based on weight. Windows should
|
||||||
// do fake italic for us in that case.
|
// do fake italic for us in that case.
|
||||||
aLogFont->lfItalic = aItalic;
|
aLogFont->lfItalic = aItalic;
|
||||||
aLogFont->lfWeight = aFontEntry->mWeight;
|
aLogFont->lfWeight = aWeight;
|
||||||
|
|
||||||
int len = PR_MIN(aFontEntry->Name().Length(), LF_FACESIZE - 1);
|
int len = PR_MIN(aName.Length(), LF_FACESIZE - 1);
|
||||||
memcpy(aLogFont->lfFaceName, nsPromiseFlatString(aFontEntry->Name()).get(), len * 2);
|
memcpy(aLogFont->lfFaceName, nsPromiseFlatString(aName).get(), len * 2);
|
||||||
aLogFont->lfFaceName[len] = '\0';
|
aLogFont->lfFaceName[len] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,7 +1056,23 @@ gfxWindowsFont::ComputeMetrics()
|
|||||||
void
|
void
|
||||||
gfxWindowsFont::FillLogFont(gfxFloat aSize)
|
gfxWindowsFont::FillLogFont(gfxFloat aSize)
|
||||||
{
|
{
|
||||||
FontEntry::FillLogFont(&mLogFont, GetFontEntry(), aSize, (GetStyle()->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)));
|
FontEntry *fe = GetFontEntry();
|
||||||
|
PRBool isItalic;
|
||||||
|
|
||||||
|
isItalic = (GetStyle()->style & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE));
|
||||||
|
PRUint16 weight = fe->Weight();
|
||||||
|
|
||||||
|
// if user font, disable italics/bold if defined to be italics/bold face
|
||||||
|
// this avoids unwanted synthetic italics/bold
|
||||||
|
if (fe->mUserFont) {
|
||||||
|
if (fe->IsItalic())
|
||||||
|
isItalic = PR_FALSE; // avoid synthetic italic
|
||||||
|
if (fe->IsBold())
|
||||||
|
weight = 400; // avoid synthetic bold
|
||||||
|
}
|
||||||
|
|
||||||
|
FontEntry::FillLogFont(&mLogFont, fe->Name(), fe->mFontType, isItalic,
|
||||||
|
weight, aSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -754,6 +754,7 @@ gfxFontEntry*
|
|||||||
gfxWindowsPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
gfxWindowsPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
||||||
const nsAString& aFontName)
|
const nsAString& aFontName)
|
||||||
{
|
{
|
||||||
|
#ifdef MOZ_FT2_FONTS
|
||||||
// walk over list of names
|
// walk over list of names
|
||||||
FullFontNameSearch data(aFontName);
|
FullFontNameSearch data(aFontName);
|
||||||
|
|
||||||
@ -764,6 +765,9 @@ gfxWindowsPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
|||||||
ReleaseDC(nsnull, data.mDC);
|
ReleaseDC(nsnull, data.mDC);
|
||||||
|
|
||||||
return data.mFontEntry;
|
return data.mFontEntry;
|
||||||
|
#else
|
||||||
|
return FontEntry::LoadLocalFont(*aProxyEntry, aFontName);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxFontEntry*
|
gfxFontEntry*
|
||||||
@ -771,8 +775,7 @@ gfxWindowsPlatform::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
|
|||||||
nsISupports *aLoader,
|
nsISupports *aLoader,
|
||||||
const PRUint8 *aFontData, PRUint32 aLength)
|
const PRUint8 *aFontData, PRUint32 aLength)
|
||||||
{
|
{
|
||||||
return FontEntry::CreateFontEntry(*aProxyEntry, aLoader,
|
return FontEntry::LoadFont(*aProxyEntry, aLoader, aFontData, aLength);
|
||||||
aFontData, aLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
@ -25,15 +25,18 @@ HTTP(..) == src-list-format-4.html src-list-format-1-ref.html
|
|||||||
HTTP(..) == src-list-format-5.html src-list-format-2-ref.html
|
HTTP(..) == src-list-format-5.html src-list-format-2-ref.html
|
||||||
HTTP(..) == src-list-format-6.html src-list-format-3-ref.html
|
HTTP(..) == src-list-format-6.html src-list-format-3-ref.html
|
||||||
# assumes AAT fonts are only supported on MacOS
|
# assumes AAT fonts are only supported on MacOS
|
||||||
skip-if(MOZ_WIDGET_TOOLKIT=="cocoa") HTTP(..) == src-list-format-7.html src-list-format-2-ref.html
|
random-if(MOZ_WIDGET_TOOLKIT=="cocoa") HTTP(..) == src-list-format-7.html src-list-format-2-ref.html
|
||||||
skip-if(MOZ_WIDGET_TOOLKIT!="cocoa") HTTP(..) == src-list-format-7.html src-list-format-3-ref.html
|
random-if(MOZ_WIDGET_TOOLKIT!="cocoa") HTTP(..) == src-list-format-7.html src-list-format-3-ref.html
|
||||||
skip-if(MOZ_WIDGET_TOOLKIT=="windows") == src-list-local-full.html src-list-local-full-ref.html # bug 468387 (windows)
|
== src-list-local-full.html src-list-local-full-ref.html
|
||||||
skip-if(MOZ_WIDGET_TOOLKIT=="windows") == src-list-local-full-quotes.html src-list-local-full-ref.html # bug 468387 (windows)
|
== src-list-local-full-quotes.html src-list-local-full-ref.html
|
||||||
HTTP(..) == src-list-local-fallback.html src-list-local-fallback-ref.html
|
HTTP(..) == src-list-local-fallback.html src-list-local-fallback-ref.html
|
||||||
|
|
||||||
|
# localized full fontnames should *not* match, only English ones (need locale-invariant key)
|
||||||
|
random-if(MOZ_WIDGET_TOOLKIT=="gtk2") HTTP(..) == src-list-local-localized.html src-list-local-localized-ref.html
|
||||||
|
|
||||||
# Postscript name lookup only supported on MacOS currently
|
# Postscript name lookup only supported on MacOS currently
|
||||||
skip-if(MOZ_WIDGET_TOOLKIT!="cocoa") == src-list-local-ps.html src-list-local-full-ref.html
|
random-if(MOZ_WIDGET_TOOLKIT!="cocoa") == src-list-local-ps.html src-list-local-full-ref.html
|
||||||
skip-if(MOZ_WIDGET_TOOLKIT!="cocoa") == helveticaneue-ultra.html helveticaneue-ultra-ref.html
|
random-if(MOZ_WIDGET_TOOLKIT!="cocoa") == helveticaneue-ultra.html helveticaneue-ultra-ref.html
|
||||||
|
|
||||||
# Arabic support requires AAT fonts under Mac OS, OpenType otherwise
|
# Arabic support requires AAT fonts under Mac OS, OpenType otherwise
|
||||||
random-if(MOZ_WIDGET_TOOLKIT!="cocoa") HTTP(..) == src-format-arabic.html src-format-arabic-aat-ref.html
|
random-if(MOZ_WIDGET_TOOLKIT!="cocoa") HTTP(..) == src-format-arabic.html src-format-arabic-aat-ref.html
|
||||||
@ -80,5 +83,5 @@ HTTP(..) == ahem-metrics-1.html ahem-metrics-1-ref.html
|
|||||||
HTTP(..) == ex-unit-1.html ex-unit-1-ref.html
|
HTTP(..) == ex-unit-1.html ex-unit-1-ref.html
|
||||||
HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
|
HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
|
||||||
|
|
||||||
fails-if(MOZ_WIDGET_TOOLKIT=="windows") == local-1.html local-1-ref.html # bug 468387
|
== local-1.html local-1-ref.html
|
||||||
fails-if(MOZ_WIDGET_TOOLKIT=="windows") HTTP(..) == synthetic-weight-style.html synthetic-weight-style-ref.html # bug 468387
|
HTTP(..) == synthetic-weight-style.html synthetic-weight-style-ref.html
|
||||||
|
Loading…
Reference in New Issue
Block a user