Backout bug 467669 and bug 660088

This commit is contained in:
Ehsan Akhgari 2011-06-15 16:52:48 -04:00
parent 66c70413dc
commit f92823ac1a
40 changed files with 167 additions and 1706 deletions

View File

@ -48,8 +48,6 @@
{ 0x09dec26b, 0x1ab7, 0x4ff0, \
{ 0xa1, 0x67, 0x7f, 0x22, 0x9c, 0xaa, 0xc3, 0x04 } }
class nsIDOMFontFaceList;
class nsIRange : public nsIDOMRange {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRANGE_IID)
@ -125,9 +123,6 @@ public:
NS_IMETHOD SetEnd(nsIDOMNode* aParent, PRInt32 aOffset) = 0;
NS_IMETHOD CloneRange(nsIDOMRange** aNewRange) = 0;
// To support the font inspector API
NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult) = 0;
protected:
nsCOMPtr<nsINode> mRoot;
nsCOMPtr<nsINode> mStartParent;

View File

@ -59,7 +59,6 @@
#include "nsClientRect.h"
#include "nsLayoutUtils.h"
#include "nsTextFrame.h"
#include "nsFontFaceList.h"
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
@ -2237,62 +2236,3 @@ nsRange::GetClientRects(nsIDOMClientRectList** aResult)
return NS_OK;
}
NS_IMETHODIMP
nsRange::GetUsedFontFaces(nsIDOMFontFaceList** aResult)
{
*aResult = nsnull;
NS_ENSURE_TRUE(mStartParent, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIDOMNode> startContainer = do_QueryInterface(mStartParent);
nsCOMPtr<nsIDOMNode> endContainer = do_QueryInterface(mEndParent);
// Flush out layout so our frames are up to date.
nsIDocument* doc = mStartParent->GetOwnerDoc();
NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
doc->FlushPendingNotifications(Flush_Frames);
// Recheck whether we're still in the document
NS_ENSURE_TRUE(mStartParent->IsInDoc(), NS_ERROR_UNEXPECTED);
nsRefPtr<nsFontFaceList> fontFaceList = new nsFontFaceList();
RangeSubtreeIterator iter;
nsresult rv = iter.Init(this);
NS_ENSURE_SUCCESS(rv, rv);
while (!iter.IsDone()) {
// only collect anything if the range is not collapsed
nsCOMPtr<nsIDOMNode> node(iter.GetCurrentNode());
iter.Next();
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
if (!content) {
continue;
}
nsIFrame* frame = content->GetPrimaryFrame();
if (!frame) {
continue;
}
if (content->IsNodeOfType(nsINode::eTEXT)) {
if (node == startContainer) {
PRInt32 offset = startContainer == endContainer ?
mEndOffset : content->GetText()->GetLength();
nsLayoutUtils::GetFontFacesForText(frame, mStartOffset, offset,
PR_TRUE, fontFaceList);
continue;
}
if (node == endContainer) {
nsLayoutUtils::GetFontFacesForText(frame, 0, mEndOffset,
PR_TRUE, fontFaceList);
continue;
}
}
nsLayoutUtils::GetFontFacesForFrames(frame, fontFaceList);
}
fontFaceList.forget(aResult);
return NS_OK;
}

View File

@ -98,8 +98,6 @@ public:
virtual nsresult SetEnd(nsINode* aParent, PRInt32 aOffset);
virtual nsresult CloneRange(nsIRange** aNewRange) const;
virtual nsresult GetUsedFontFaces(nsIDOMFontFaceList** aResult);
// nsIMutationObserver methods
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED

View File

@ -122,7 +122,3 @@ interface nsIDOMRange;
interface nsIDOMCRMFObject;
interface nsIDOMCrypto;
interface nsIDOMPkcs11;
// Used font face (for inspector)
interface nsIDOMFontFace;
interface nsIDOMFontFaceList;

View File

@ -1,323 +1,131 @@
// Copyright (c) 2011 Mozilla Foundation. All rights reserved.
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "name.h"
#include <algorithm>
#include <cstring>
#include "cff.h"
#include "ots.h"
// name - Naming Table
// http://www.microsoft.com/opentype/otspec/name.htm
namespace { // misc local helper functions
inline bool
valid_in_ps_name(char c) {
return (c > 0x20 && c < 0x7f && !std::strchr("[](){}<>/%", c));
}
inline bool
check_ps_name_ascii(std::string& name) {
for (unsigned int i = 0; i < name.size(); ++i) {
if (!valid_in_ps_name(name[i])) {
return false;
}
}
return true;
}
inline bool
check_ps_name_utf16_be(std::string& name) {
for (unsigned int i = 0; i < name.size(); i += 2) {
if (name[i] != 0) {
return false;
}
if (!valid_in_ps_name(name[i+1])) {
return false;
}
}
return true;
}
void
assign_to_utf16_be_from_ascii(std::string& target, const std::string& source) {
target.resize(source.size() * 2);
for (unsigned int i = 0, j = 0; i < source.size(); i++) {
target[j++] = '\0';
target[j++] = source[i];
}
}
} // end anonymous namespace
namespace ots {
bool ots_name_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
Buffer table(data, length);
bool ots_name_parse(OpenTypeFile *, const uint8_t *, size_t) {
return true;
}
OpenTypeNAME *name = new OpenTypeNAME;
file->name = name;
bool ots_name_should_serialise(OpenTypeFile *) {
return true;
}
uint16_t format;
if (!table.ReadU16(&format) || format > 1) {
return OTS_FAILURE();
}
bool ots_name_serialise(OTSStream *out, OpenTypeFile *file) {
// NAME is a required table, but we don't want anything to do with it. Thus,
// we don't bother parsing it and we just serialise an empty name table.
uint16_t count;
if (!table.ReadU16(&count)) {
return OTS_FAILURE();
}
uint16_t stringOffset;
if (!table.ReadU16(&stringOffset) || stringOffset > length) {
return OTS_FAILURE();
}
const char* stringBase = (const char*)data + stringOffset;
NameRecord prevRec;
bool sortRequired = false;
// Read all the names, discarding any with invalid IDs,
// and any where the offset/length would be outside the table.
// A stricter alternative would be to reject the font if there
// are invalid name records, but it's not clear that is necessary.
for (unsigned int i = 0; i < count; ++i) {
NameRecord rec;
uint16_t nameLength, nameOffset;
if (!table.ReadU16(&rec.platformID) ||
!table.ReadU16(&rec.encodingID) ||
!table.ReadU16(&rec.languageID) ||
!table.ReadU16(&rec.nameID) ||
!table.ReadU16(&nameLength) ||
!table.ReadU16(&nameOffset)) {
return OTS_FAILURE();
}
// check platform & encoding, discard names with unknown values
switch (rec.platformID) {
case 0: // Unicode
if (rec.encodingID > 6) {
continue;
}
break;
case 1: // Macintosh
if (rec.encodingID > 32) {
continue;
}
break;
case 2: // ISO
if (rec.encodingID > 2) {
continue;
}
break;
case 3: // Windows: IDs 7 to 9 are "reserved"
if (rec.encodingID > 6 && rec.encodingID != 10) {
continue;
}
break;
case 4: // Custom (OTF Windows NT compatibility)
if (rec.encodingID > 255) {
continue;
}
break;
default: // unknown platform
continue;
}
if (size_t(stringOffset) + nameOffset + nameLength > length) {
continue;
}
rec.text.resize(nameLength);
rec.text.assign(stringBase + nameOffset, nameLength);
if (rec.nameID == 6) {
// PostScript name: check that it is valid, if not then discard it
if (rec.platformID == 1) {
if (file->cff && !file->cff->name.empty()) {
rec.text = file->cff->name;
} else if (!check_ps_name_ascii(rec.text)) {
continue;
}
} else if (rec.platformID == 0 || rec.platformID == 3) {
if (file->cff && !file->cff->name.empty()) {
assign_to_utf16_be_from_ascii(rec.text, file->cff->name);
} else if (!check_ps_name_utf16_be(rec.text)) {
continue;
}
}
}
if (i > 0) {
if (!(prevRec < rec)) {
sortRequired = true;
}
}
name->names.push_back(rec);
prevRec = rec;
}
if (format == 1) {
// extended name table format with language tags
uint16_t langTagCount;
if (!table.ReadU16(&langTagCount)) {
return OTS_FAILURE();
}
for (unsigned int i = 0; i < langTagCount; ++i) {
uint16_t tagLength, tagOffset;
if (!table.ReadU16(&tagLength) || !table.ReadU16(&tagOffset)) {
return OTS_FAILURE();
}
if (size_t(stringOffset) + tagOffset + tagLength > length) {
return OTS_FAILURE();
}
std::string tag(stringBase + tagOffset, tagLength);
name->langTags.push_back(tag);
}
}
if (table.offset() > stringOffset) {
// the string storage apparently overlapped the name/tag records;
// consider this font to be badly broken
return OTS_FAILURE();
}
// check existence of required name strings (synthesize if necessary)
// [0 - copyright - skip]
// 1 - family
// 2 - subfamily
// [3 - unique ID - skip]
// 4 - full name
// 5 - version
// 6 - postscript name
const unsigned int kStdNameCount = 7;
const char* kStdNames[kStdNameCount] = {
NULL,
"OTS derived font",
"Unspecified",
NULL,
"OTS derived font",
"1.000",
"OTS-derived-font"
const char* kStrings[] = {
"Derived font data", // 0: copyright
"OTS derived font", // 1: the name the user sees
"Unspecified", // 2: face weight
"UniqueID", // 3: unique id
"OTS derivied font", // 4: human readable name
"1.000", // 5: version
"False", // 6: postscript name
NULL, // 7: trademark data
"OTS", // 8: foundary
"OTS", // 9: designer
};
static const size_t kStringsLen = sizeof(kStrings) / sizeof(kStrings[0]);
// The spec says that "In CFF OpenType fonts, these two name strings, when
// translated to ASCII, must also be identical to the font name as stored in
// the CFF's Name INDEX." And actually, Mac OS X's font parser requires that.
if (file->cff && !file->cff->name.empty()) {
kStdNames[6] = file->cff->name.c_str();
kStrings[6] = file->cff->name.c_str();
}
// scan the names to check whether the required "standard" ones are present;
// if not, we'll add our fixed versions here
bool macName[kStdNameCount] = { 0 };
bool winName[kStdNameCount] = { 0 };
for (std::vector<NameRecord>::iterator nameIter = name->names.begin();
nameIter != name->names.end(); nameIter++) {
uint16_t id = nameIter->nameID;
if (id >= kStdNameCount || kStdNames[id] == NULL) {
continue;
}
if (nameIter->platformID == 1) {
macName[id] = true;
continue;
}
if (nameIter->platformID == 3) {
winName[id] = true;
continue;
}
unsigned num_strings = 0;
for (unsigned i = 0; i < kStringsLen; ++i) {
if (kStrings[i]) num_strings++;
}
for (unsigned int i = 0; i < kStdNameCount; ++i) {
if (kStdNames[i] == NULL) {
continue;
}
if (!macName[i]) {
NameRecord rec(1, 0, 0, i);
rec.text.assign(kStdNames[i]);
name->names.push_back(rec);
sortRequired = true;
}
if (!winName[i]) {
NameRecord rec(3, 1, 1033, i);
assign_to_utf16_be_from_ascii(rec.text, std::string(kStdNames[i]));
name->names.push_back(rec);
sortRequired = true;
}
}
if (sortRequired) {
std::sort(name->names.begin(), name->names.end());
}
return true;
}
bool ots_name_should_serialise(OpenTypeFile *file) {
return file->name != NULL;
}
bool ots_name_serialise(OTSStream *out, OpenTypeFile *file) {
const OpenTypeNAME *name = file->name;
uint16_t nameCount = name->names.size();
uint16_t langTagCount = name->langTags.size();
uint16_t format = 0;
size_t stringOffset = 6 + nameCount * 12;
if (name->langTags.size() > 0) {
// lang tags require a format-1 name table
format = 1;
stringOffset = 8 + nameCount * 12 + langTagCount * 4;
}
if (stringOffset > 0xffff) {
return OTS_FAILURE();
}
if (!out->WriteU16(format) ||
!out->WriteU16(nameCount) ||
!out->WriteU16(stringOffset)) {
if (!out->WriteU16(0) || // version
// Magic numbers:
// 6: This entry (U16 * 3 = 6 bytes)
// 2: Mac Roman & Windows Roman = 2 types
// 12: Each string entry (U16 * 6 = 12 bytes)
!out->WriteU16(num_strings * 2) || // count
!out->WriteU16(6 + num_strings * 2 * 12)) { // string data offset
return OTS_FAILURE();
}
std::string stringData;
for (std::vector<NameRecord>::const_iterator nameIter = name->names.begin();
nameIter != name->names.end(); nameIter++) {
const NameRecord& rec = *nameIter;
if (!out->WriteU16(rec.platformID) ||
!out->WriteU16(rec.encodingID) ||
!out->WriteU16(rec.languageID) ||
!out->WriteU16(rec.nameID) ||
!out->WriteU16(rec.text.size()) ||
!out->WriteU16(stringData.size()) ) {
unsigned current_offset = 0;
for (unsigned i = 0; i < kStringsLen; ++i) {
if (!kStrings[i]) continue;
// string length in UTF-8 (ASCII).
size_t len = std::strlen(kStrings[i]);
if (!out->WriteU16(1) || // Mac
!out->WriteU16(0) || // Roman
!out->WriteU16(0) || // English
!out->WriteU16(i) ||
!out->WriteU16(len) ||
!out->WriteU16(current_offset)) {
return OTS_FAILURE();
}
stringData.append(rec.text);
current_offset += len;
}
if (format == 1) {
if (!out->WriteU16(langTagCount)) {
for (unsigned i = 0; i < kStringsLen; ++i) {
if (!kStrings[i]) continue;
// string length in UTF-16.
size_t len = std::strlen(kStrings[i]) * 2;
if (!out->WriteU16(3) || // Windows
!out->WriteU16(1) || // Unicode BMP (UCS-2)
!out->WriteU16(0x0409) || // US English
!out->WriteU16(i) ||
!out->WriteU16(len) ||
!out->WriteU16(current_offset)) {
return OTS_FAILURE();
}
for (std::vector<std::string>::const_iterator tagIter = name->langTags.begin();
tagIter != name->langTags.end(); tagIter++) {
if (!out->WriteU16(tagIter->size()) ||
!out->WriteU16(stringData.size())) {
current_offset += len;
}
// Write strings in Mac Roman compatible with ASCII.
// Because all the entries are ASCII, we can just copy.
for (unsigned i = 0; i < kStringsLen; ++i) {
if (!kStrings[i]) continue;
const size_t len = std::strlen(kStrings[i]);
if (!out->Write(kStrings[i], len)) {
return OTS_FAILURE();
}
}
// Write strings in UCS-2. Because all the entries are ASCII,
// we can just expand each byte to U16.
for (unsigned i = 0; i < kStringsLen; ++i) {
if (!kStrings[i]) continue;
const size_t len = std::strlen(kStrings[i]);
for (size_t j = 0; j < len; ++j) {
uint16_t v = kStrings[i][j];
if (!out->WriteU16(v)) {
return OTS_FAILURE();
}
stringData.append(*tagIter);
}
}
if (!out->Write(stringData.data(), stringData.size())) {
return OTS_FAILURE();
}
return true;
}
void ots_name_free(OpenTypeFile *file) {
delete file->name;
void ots_name_free(OpenTypeFile *) {
}
} // namespace

View File

@ -1,50 +0,0 @@
// Copyright (c) 2011 Mozilla Foundation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef OTS_NAME_H_
#define OTS_NAME_H_
#include <new>
#include <utility>
#include <vector>
#include <string>
#include "ots.h"
namespace ots {
struct NameRecord {
NameRecord()
{ }
NameRecord(uint16_t p, uint16_t e, uint16_t l, uint16_t n)
: platformID(p), encodingID(e), languageID(l), nameID(n)
{ }
uint16_t platformID;
uint16_t encodingID;
uint16_t languageID;
uint16_t nameID;
std::string text;
bool operator<(const NameRecord& rhs) const {
if (platformID < rhs.platformID) return true;
if (platformID > rhs.platformID) return false;
if (encodingID < rhs.encodingID) return true;
if (encodingID > rhs.encodingID) return false;
if (languageID < rhs.languageID) return true;
if (languageID > rhs.languageID) return false;
if (nameID < rhs.nameID) return true;
return false;
}
};
struct OpenTypeNAME {
std::vector<NameRecord> names;
std::vector<std::string> langTags;
};
} // namespace ots
#endif // OTS_NAME_H_

View File

@ -110,9 +110,10 @@ gfxDWriteShaper::InitTextRun(gfxContext *aContext,
}
}
PRUint32 rangeStart = aRunStart + rangeOffset;
gfxTextRange range(aRunStart + rangeOffset,
aRunStart + rangeOffset + rangeLen);
rangeOffset += rangeLen;
TextAnalysis analysis(aString + rangeStart, rangeLen,
TextAnalysis analysis(aString + range.start, range.Length(),
NULL,
readingDirection);
TextAnalysis::Run *runHead;
@ -129,18 +130,18 @@ gfxDWriteShaper::InitTextRun(gfxContext *aContext,
UINT32 maxGlyphs = 0;
trymoreglyphs:
if ((PR_UINT32_MAX - 3 * rangeLen / 2 + 16) < maxGlyphs) {
if ((PR_UINT32_MAX - 3 * range.Length() / 2 + 16) < maxGlyphs) {
// This isn't going to work, we're going to cross the UINT32 upper
// limit. Next range it is.
continue;
}
maxGlyphs += 3 * rangeLen / 2 + 16;
maxGlyphs += 3 * range.Length() / 2 + 16;
nsAutoTArray<UINT16, 400> clusters;
nsAutoTArray<UINT16, 400> indices;
nsAutoTArray<DWRITE_SHAPING_TEXT_PROPERTIES, 400> textProperties;
nsAutoTArray<DWRITE_SHAPING_GLYPH_PROPERTIES, 400> glyphProperties;
if (!clusters.SetLength(rangeLen) ||
if (!clusters.SetLength(range.Length()) ||
!indices.SetLength(maxGlyphs) ||
!textProperties.SetLength(maxGlyphs) ||
!glyphProperties.SetLength(maxGlyphs)) {
@ -149,7 +150,7 @@ trymoreglyphs:
UINT32 actualGlyphs;
hr = analyzer->GetGlyphs(aString + rangeStart, rangeLen,
hr = analyzer->GetGlyphs(aString + range.start, range.Length(),
font->GetFontFace(), FALSE,
readingDirection == DWRITE_READING_DIRECTION_RIGHT_TO_LEFT,
&runHead->mScript, NULL, NULL, NULL, NULL, 0,
@ -176,10 +177,10 @@ trymoreglyphs:
if (!static_cast<gfxDWriteFont*>(mFont)->mUseSubpixelPositions) {
hr = analyzer->GetGdiCompatibleGlyphPlacements(
aString + rangeStart,
aString + range.start,
clusters.Elements(),
textProperties.Elements(),
rangeLen,
range.Length(),
indices.Elements(),
glyphProperties.Elements(),
actualGlyphs,
@ -198,10 +199,10 @@ trymoreglyphs:
advances.Elements(),
glyphOffsets.Elements());
} else {
hr = analyzer->GetGlyphPlacements(aString + rangeStart,
hr = analyzer->GetGlyphPlacements(aString + range.start,
clusters.Elements(),
textProperties.Elements(),
rangeLen,
range.Length(),
indices.Elements(),
glyphProperties.Elements(),
actualGlyphs,
@ -225,9 +226,9 @@ trymoreglyphs:
nsAutoTArray<gfxTextRun::DetailedGlyph,1> detailedGlyphs;
for (unsigned int c = 0; c < rangeLen; c++) {
for (unsigned int c = 0; c < range.Length(); c++) {
PRUint32 k = clusters[c];
PRUint32 absC = rangeStart + c;
PRUint32 absC = range.start + c;
if (c > 0 && k == clusters[c - 1]) {
g.SetComplex(aTextRun->IsClusterStart(absC), PR_FALSE, 0);
@ -240,7 +241,7 @@ trymoreglyphs:
PRUint32 glyphCount = actualGlyphs - k;
PRUint32 nextClusterOffset;
for (nextClusterOffset = c + 1;
nextClusterOffset < rangeLen; ++nextClusterOffset) {
nextClusterOffset < range.Length(); ++nextClusterOffset) {
if (clusters[nextClusterOffset] > k) {
glyphCount = clusters[nextClusterOffset] - k;
break;

View File

@ -260,42 +260,31 @@ FontEntry::ReadCMAP()
// attempt this once, if errors occur leave a blank cmap
mCmapInitialized = PR_TRUE;
AutoFallibleTArray<PRUint8,16384> buffer;
nsresult rv = GetFontTable(TTAG_cmap, buffer);
if (NS_SUCCEEDED(rv)) {
PRPackedBool unicodeFont;
PRPackedBool symbolFont;
rv = gfxFontUtils::ReadCMAP(buffer.Elements(), buffer.Length(),
mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
}
mHasCmapTable = NS_SUCCEEDED(rv);
return rv;
}
nsresult
FontEntry::GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer)
{
// Ensure existence of mFTFace
CairoFontFace();
NS_ENSURE_TRUE(mFTFace, NS_ERROR_FAILURE);
FT_Error status;
FT_ULong len = 0;
status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, nsnull, &len);
status = FT_Load_Sfnt_Table(mFTFace, TTAG_cmap, 0, nsnull, &len);
NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(len != 0, NS_ERROR_FAILURE);
if (!aBuffer.SetLength(len)) {
return NS_ERROR_OUT_OF_MEMORY;
AutoFallibleTArray<PRUint8,16384> buffer;
if (!buffer.AppendElements(len)) {
return NS_ERROR_FAILURE;
}
PRUint8 *buf = aBuffer.Elements();
status = FT_Load_Sfnt_Table(mFTFace, aTableTag, 0, buf, &len);
PRUint8 *buf = buffer.Elements();
status = FT_Load_Sfnt_Table(mFTFace, TTAG_cmap, 0, buf, &len);
NS_ENSURE_TRUE(status == 0, NS_ERROR_FAILURE);
return NS_OK;
PRPackedBool unicodeFont;
PRPackedBool symbolFont;
nsresult rv = gfxFontUtils::ReadCMAP(buf, len, mCharacterMap, mUVSOffset,
unicodeFont, symbolFont);
mHasCmapTable = NS_SUCCEEDED(rv);
return rv;
}
FontEntry *

View File

@ -112,8 +112,6 @@ public:
cairo_font_face_t *CairoFontFace();
nsresult ReadCMAP();
nsresult GetFontTable(PRUint32 aTableTag, FallibleTArray<PRUint8>& aBuffer);
FT_Face mFTFace;
cairo_font_face_t *mFontFace;

View File

@ -165,29 +165,10 @@ nsresult gfxFontEntry::ReadCMAP()
return NS_OK;
}
nsString gfxFontEntry::FamilyName() const
const nsString& gfxFontEntry::FamilyName() const
{
NS_ASSERTION(mFamily, "orphaned font entry");
if (mFamily) {
return mFamily->Name();
} else {
return nsString();
}
}
nsString
gfxFontEntry::RealFaceName()
{
FallibleTArray<PRUint8> nameTable;
nsresult rv = GetFontTable(TRUETYPE_TAG('n','a','m','e'), nameTable);
if (NS_SUCCEEDED(rv)) {
nsAutoString name;
rv = gfxFontUtils::GetFullNameFromTable(nameTable, name);
if (NS_SUCCEEDED(rv)) {
return name;
}
}
return Name();
NS_ASSERTION(mFamily, "gfxFontEntry is not a member of a family");
return mFamily->Name();
}
already_AddRefed<gfxFont>
@ -2350,7 +2331,7 @@ gfxFontGroup::MakeSpaceTextRun(const Parameters *aParams, PRUint32 aFlags)
// Short-circuit for size-0 fonts, as Windows and ATSUI can't handle
// them, and always create at least size 1 fonts, i.e. they still
// render something for size 0 fonts.
textRun->AddGlyphRun(font, gfxTextRange::kFontGroup, 0, PR_FALSE);
textRun->AddGlyphRun(font, 0);
}
else {
textRun->SetSpaceGlyph(font, aParams->mContext, 0);
@ -2499,13 +2480,8 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
gfxFont *matchedFont = (range.font ? range.font.get() : nsnull);
// create the glyph run for this range
if (matchedFont) {
aTextRun->AddGlyphRun(matchedFont, range.matchType,
runStart, (matchedLength > 0));
} else {
aTextRun->AddGlyphRun(mainFont, gfxTextRange::kFontGroup,
runStart, (matchedLength > 0));
}
aTextRun->AddGlyphRun(matchedFont ? matchedFont : mainFont,
runStart, (matchedLength > 0));
if (matchedFont) {
// do glyph layout and record the resulting positioned glyphs
if (!matchedFont->SplitAndInitTextRun(aContext, aTextRun, aString,
@ -2566,8 +2542,7 @@ gfxFontGroup::InitScriptRun(gfxContext *aContext,
already_AddRefed<gfxFont>
gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
PRInt32 aRunScript, gfxFont *aPrevMatchedFont,
PRUint8 *aMatchType)
PRInt32 aRunScript, gfxFont *aPrevMatchedFont)
{
nsRefPtr<gfxFont> selectedFont;
@ -2595,10 +2570,8 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
// 1. check fonts in the font group
for (PRUint32 i = 0; i < FontListLength(); i++) {
nsRefPtr<gfxFont> font = GetFontAt(i);
if (font->HasCharacter(aCh)) {
*aMatchType = gfxTextRange::kFontGroup;
if (font->HasCharacter(aCh))
return font.forget();
}
}
// if character is in Private Use Area, don't do matching against pref or system fonts
@ -2607,14 +2580,12 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
// 2. search pref fonts
if ((selectedFont = WhichPrefFontSupportsChar(aCh))) {
*aMatchType = gfxTextRange::kPrefsFallback;
return selectedFont.forget();
}
// 3. use fallback fonts
// -- before searching for something else check the font used for the previous character
if (!selectedFont && aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) {
*aMatchType = gfxTextRange::kSystemFallback;
selectedFont = aPrevMatchedFont;
return selectedFont.forget();
}
@ -2630,7 +2601,6 @@ gfxFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
// -- otherwise look for other stuff
if (!selectedFont) {
*aMatchType = gfxTextRange::kSystemFallback;
selectedFont = WhichSystemFontSupportsChar(aCh);
return selectedFont.forget();
}
@ -2655,7 +2625,6 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
PRUint32 prevCh = 0;
gfxFont *prevFont = nsnull;
PRUint8 matchType = 0;
for (PRUint32 i = 0; i < len; i++) {
@ -2670,21 +2639,26 @@ void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
// find the font for this char
nsRefPtr<gfxFont> font =
FindFontForChar(ch, prevCh, aRunScript, prevFont, &matchType);
FindFontForChar(ch, prevCh, aRunScript, prevFont);
prevCh = ch;
if (aRanges.Length() == 0) {
// first char ==> make a new range
aRanges.AppendElement(gfxTextRange(0, 1, font, matchType));
gfxTextRange r(0,1);
r.font = font;
aRanges.AppendElement(r);
prevFont = font;
} else {
// if font has changed, make a new range
gfxTextRange& prevRange = aRanges[aRanges.Length() - 1];
if (prevRange.font != font || prevRange.matchType != matchType) {
if (prevRange.font != font) {
// close out the previous range
prevRange.end = origI;
aRanges.AppendElement(gfxTextRange(origI, i+1, font, matchType));
gfxTextRange r(origI, i+1);
r.font = font;
aRanges.AppendElement(r);
// update prevFont for the next match, *unless* we switched
// fonts on a ZWJ, in which case propagating the changed font
@ -3956,22 +3930,20 @@ gfxTextRun::FindFirstGlyphRunContaining(PRUint32 aOffset)
}
nsresult
gfxTextRun::AddGlyphRun(gfxFont *aFont, PRUint8 aMatchType,
PRUint32 aUTF16Offset, PRBool aForceNewRun)
gfxTextRun::AddGlyphRun(gfxFont *aFont, PRUint32 aUTF16Offset, PRBool aForceNewRun)
{
PRUint32 numGlyphRuns = mGlyphRuns.Length();
if (!aForceNewRun && numGlyphRuns > 0) {
if (!aForceNewRun &&
numGlyphRuns > 0)
{
GlyphRun *lastGlyphRun = &mGlyphRuns[numGlyphRuns - 1];
NS_ASSERTION(lastGlyphRun->mCharacterOffset <= aUTF16Offset,
"Glyph runs out of order (and run not forced)");
// Don't append a run if the font is already the one we want
if (lastGlyphRun->mFont == aFont &&
lastGlyphRun->mMatchType == aMatchType)
{
if (lastGlyphRun->mFont == aFont)
return NS_OK;
}
// If the offset has not changed, avoid leaving a zero-length run
// by overwriting the last entry instead of appending...
@ -3981,15 +3953,13 @@ gfxTextRun::AddGlyphRun(gfxFont *aFont, PRUint8 aMatchType,
// font as the new one wants, merge with it instead of creating
// adjacent runs with the same font
if (numGlyphRuns > 1 &&
mGlyphRuns[numGlyphRuns - 2].mFont == aFont &&
mGlyphRuns[numGlyphRuns - 2].mMatchType == aMatchType)
mGlyphRuns[numGlyphRuns - 2].mFont == aFont)
{
mGlyphRuns.TruncateLength(numGlyphRuns - 1);
return NS_OK;
}
lastGlyphRun->mFont = aFont;
lastGlyphRun->mMatchType = aMatchType;
return NS_OK;
}
}
@ -4002,7 +3972,6 @@ gfxTextRun::AddGlyphRun(gfxFont *aFont, PRUint8 aMatchType,
return NS_ERROR_OUT_OF_MEMORY;
glyphRun->mFont = aFont;
glyphRun->mCharacterOffset = aUTF16Offset;
glyphRun->mMatchType = aMatchType;
return NS_OK;
}
@ -4228,8 +4197,7 @@ gfxTextRun::CopyGlyphDataFrom(gfxTextRun *aSource, PRUint32 aStart,
NS_WARN_IF_FALSE(end == aSource->GetLength() || aSource->IsClusterStart(end),
"Ended font run in the middle of a cluster");
nsresult rv = AddGlyphRun(font, iter.GetGlyphRun()->mMatchType,
start - aStart + aDest, PR_FALSE);
nsresult rv = AddGlyphRun(font, start - aStart + aDest);
if (NS_FAILED(rv))
return;
}
@ -4257,7 +4225,8 @@ gfxTextRun::SetSpaceGlyph(gfxFont *aFont, gfxContext *aContext, PRUint32 aCharIn
CopyGlyphDataFrom(textRun, 0, 1, aCharIndex);
return;
}
AddGlyphRun(aFont, gfxTextRange::kFontGroup, aCharIndex, PR_FALSE);
AddGlyphRun(aFont, aCharIndex);
CompressedGlyph g;
g.SetSimpleGlyph(spaceWidthAppUnits, spaceGlyph);
SetSimpleGlyph(aCharIndex, g);

View File

@ -221,14 +221,9 @@ public:
virtual ~gfxFontEntry();
// unique name for the face, *not* the family; not necessarily the
// "real" or user-friendly name, may be an internal identifier
// unique name for the face, *not* the family
const nsString& Name() const { return mName; }
// the "real" name of the face, if available from the font resource
// (may be expensive); returns Name() if nothing better is available
virtual nsString RealFaceName();
gfxFontFamily* Family() const { return mFamily; }
PRUint16 Weight() const { return mWeight; }
@ -278,7 +273,7 @@ public:
mFamily = aFamily;
}
virtual nsString FamilyName() const;
const nsString& FamilyName() const;
already_AddRefed<gfxFont> FindOrMakeFont(const gfxFontStyle *aStyle,
PRBool aNeedsBold);
@ -610,23 +605,10 @@ protected:
};
struct gfxTextRange {
enum {
// flags for recording the kind of font-matching that was used
kFontGroup = 0x0001,
kPrefsFallback = 0x0002,
kSystemFallback = 0x0004
};
gfxTextRange(PRUint32 aStart, PRUint32 aEnd,
gfxFont* aFont, PRUint8 aMatchType)
: start(aStart),
end(aEnd),
font(aFont),
matchType(aMatchType)
{ }
gfxTextRange(PRUint32 aStart, PRUint32 aEnd) : start(aStart), end(aEnd) { }
PRUint32 Length() const { return end - start; }
PRUint32 start, end;
nsRefPtr<gfxFont> font;
PRUint8 matchType;
PRUint32 start, end;
};
@ -1889,7 +1871,6 @@ public:
struct GlyphRun {
nsRefPtr<gfxFont> mFont; // never null
PRUint32 mCharacterOffset; // into original UTF16 string
PRUint8 mMatchType;
};
class THEBES_API GlyphRunIterator {
@ -1945,8 +1926,7 @@ public:
* are added before any further operations are performed with this
* TextRun.
*/
nsresult AddGlyphRun(gfxFont *aFont, PRUint8 aMatchType,
PRUint32 aStartCharIndex, PRBool aForceNewRun);
nsresult AddGlyphRun(gfxFont *aFont, PRUint32 aStartCharIndex, PRBool aForceNewRun = PR_FALSE);
void ResetGlyphRuns() { mGlyphRuns.Clear(); }
void SortGlyphRuns();
void SanitizeGlyphRuns();
@ -2245,7 +2225,7 @@ private:
// XXX this should be changed to a GlyphRun plus a maybe-null GlyphRun*,
// for smaller size especially in the super-common one-glyphrun case
nsAutoTArray<GlyphRun,1> mGlyphRuns;
nsAutoTArray<GlyphRun,1> mGlyphRuns;
// When TEXT_IS_8BIT is set, we use mSingle, otherwise we use mDouble.
// When TEXT_IS_PERSISTENT is set, we don't own the text, otherwise we
// own the text. When we own the text, it's allocated fused with the
@ -2372,8 +2352,7 @@ public:
virtual already_AddRefed<gfxFont>
FindFontForChar(PRUint32 ch, PRUint32 prevCh, PRInt32 aRunScript,
gfxFont *aPrevMatchedFont,
PRUint8 *aMatchType);
gfxFont *aPrevMatchedFont);
// search through pref fonts for a character, return nsnull if no matching pref font
virtual already_AddRefed<gfxFont> WhichPrefFontSupportsChar(PRUint32 aCh);

View File

@ -1434,80 +1434,6 @@ gfxFontUtils::RenameFont(const nsAString& aName, const PRUint8 *aFontData,
return NS_OK;
}
// This is only called after the basic validity of the downloaded sfnt
// data has been checked, so it should never fail to find the name table
// (though it might fail to read it, if memory isn't available);
// other checks here are just for extra paranoia.
nsresult
gfxFontUtils::GetFullNameFromSFNT(const PRUint8* aFontData, PRUint32 aLength,
nsAString& aFullName)
{
aFullName.AssignLiteral("(MISSING NAME)"); // should always get replaced
NS_ENSURE_TRUE(aLength >= sizeof(SFNTHeader), NS_ERROR_UNEXPECTED);
const SFNTHeader *sfntHeader =
reinterpret_cast<const SFNTHeader*>(aFontData);
const TableDirEntry *dirEntry =
reinterpret_cast<const TableDirEntry*>(aFontData + sizeof(SFNTHeader));
PRUint32 numTables = sfntHeader->numTables;
NS_ENSURE_TRUE(aLength >=
sizeof(SFNTHeader) + numTables * sizeof(TableDirEntry),
NS_ERROR_UNEXPECTED);
PRBool foundName = PR_FALSE;
for (PRUint32 i = 0; i < numTables; i++, dirEntry++) {
if (dirEntry->tag == TRUETYPE_TAG('n','a','m','e')) {
foundName = PR_TRUE;
break;
}
}
// should never fail, as we're only called after font validation succeeded
NS_ENSURE_TRUE(foundName, NS_ERROR_NOT_AVAILABLE);
PRUint32 len = dirEntry->length;
NS_ENSURE_TRUE(aLength > len && aLength - len >= dirEntry->offset,
NS_ERROR_UNEXPECTED);
FallibleTArray<PRUint8> nameTable;
if (!nameTable.SetLength(len)) {
return NS_ERROR_OUT_OF_MEMORY;
}
memcpy(nameTable.Elements(), aFontData + dirEntry->offset, len);
return GetFullNameFromTable(nameTable, aFullName);
}
nsresult
gfxFontUtils::GetFullNameFromTable(FallibleTArray<PRUint8>& aNameTable,
nsAString& aFullName)
{
nsAutoString name;
nsresult rv =
gfxFontUtils::ReadCanonicalName(aNameTable,
gfxFontUtils::NAME_ID_FULL,
name);
if (NS_SUCCEEDED(rv) && !name.IsEmpty()) {
aFullName = name;
return NS_OK;
}
rv = gfxFontUtils::ReadCanonicalName(aNameTable,
gfxFontUtils::NAME_ID_FAMILY,
name);
if (NS_SUCCEEDED(rv) && !name.IsEmpty()) {
nsAutoString styleName;
rv = gfxFontUtils::ReadCanonicalName(aNameTable,
gfxFontUtils::NAME_ID_STYLE,
styleName);
if (NS_SUCCEEDED(rv) && !styleName.IsEmpty()) {
name.AppendLiteral(" ");
name.Append(styleName);
aFullName = name;
}
return NS_OK;
}
return NS_ERROR_NOT_AVAILABLE;
}
enum {
#if defined(XP_MACOSX)
CANONICAL_LANG_ID = gfxFontUtils::LANG_ID_MAC_ENGLISH,

View File

@ -706,26 +706,10 @@ public:
DetermineFontDataType(const PRUint8 *aFontData, PRUint32 aFontDataLength);
// checks for valid SFNT table structure, returns true if valid
// does *not* guarantee that all font data is valid, though it does
// check that key tables such as 'name' are present and readable.
// XXX to be removed if/when we eliminate the option to disable OTS,
// which does more thorough validation.
// does *not* guarantee that all font data is valid
static PRBool
ValidateSFNTHeaders(const PRUint8 *aFontData, PRUint32 aFontDataLength);
// Read the fullname from the sfnt data (used to save the original name
// prior to renaming the font for installation).
// This is called with sfnt data that has already been validated,
// so it should always succeed in finding the name table.
static nsresult
GetFullNameFromSFNT(const PRUint8* aFontData, PRUint32 aLength,
nsAString& aFullName);
// helper to get fullname from name table
static nsresult
GetFullNameFromTable(FallibleTArray<PRUint8>& aNameTable,
nsAString& aFullName);
// create a new name table and build a new font with that name table
// appended on the end, returns true on success
static nsresult

View File

@ -866,7 +866,6 @@ gfxMacPlatformFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
aProxyEntry->mItalic ?
FONT_STYLE_ITALIC : FONT_STYLE_NORMAL,
nsnull);
newFontEntry->mIsUserFont = newFontEntry->mIsLocalUserFont = PR_TRUE;
} else {
newFontEntry =
new MacOSFontEntry(aFontName, fontRef,

View File

@ -190,15 +190,6 @@ public:
(cairo_font_face_get_user_data(aFace, &sFontEntryKey));
}
// override the default impl in gfxFontEntry because we don't organize
// gfxFcFontEntries in families; just read the name from fontconfig
virtual nsString FamilyName() const;
// override the gfxFontEntry impl to read the name from fontconfig
// instead of trying to get the 'name' table, as we don't implement
// GetFontTable() here
virtual nsString RealFaceName();
protected:
gfxFcFontEntry(const nsAString& aName)
: gfxFontEntry(aName),
@ -217,46 +208,6 @@ protected:
cairo_user_data_key_t gfxFcFontEntry::sFontEntryKey;
nsString
gfxFcFontEntry::FamilyName() const
{
if (mIsUserFont) {
// for user fonts, we want the name of the family
// as specified in the user font set
return gfxFontEntry::FamilyName();
}
FcChar8 *familyname;
if (!mPatterns.IsEmpty() &&
FcPatternGetString(mPatterns[0],
FC_FAMILY, 0, &familyname) == FcResultMatch) {
return NS_ConvertUTF8toUTF16((const char*)familyname);
}
return gfxFontEntry::FamilyName();
}
nsString
gfxFcFontEntry::RealFaceName()
{
FcChar8 *name;
if (!mPatterns.IsEmpty()) {
if (FcPatternGetString(mPatterns[0],
FC_FULLNAME, 0, &name) == FcResultMatch) {
return NS_ConvertUTF8toUTF16((const char*)name);
}
if (FcPatternGetString(mPatterns[0],
FC_FAMILY, 0, &name) == FcResultMatch) {
NS_ConvertUTF8toUTF16 result((const char*)name);
if (FcPatternGetString(mPatterns[0],
FC_STYLE, 0, &name) == FcResultMatch) {
result.AppendLiteral(" ");
AppendUTF8toUTF16((const char*)name, result);
}
return result;
}
}
return gfxFontEntry::RealFaceName();
}
PRBool
gfxFcFontEntry::ShouldUseHarfBuzz(PRInt32 aRunScript) {
if (mSkipHarfBuzz ||
@ -2000,8 +1951,7 @@ gfxPangoFontGroup::GetFontSet(PangoLanguage *aLang)
already_AddRefed<gfxFont>
gfxPangoFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
PRInt32 aRunScript,
gfxFont *aPrevMatchedFont,
PRUint8 *aMatchType)
gfxFont *aPrevMatchedFont)
{
if (aPrevMatchedFont) {
PRUint8 category = gfxUnicodeProperties::GetGeneralCategory(aCh);
@ -2065,7 +2015,6 @@ gfxPangoFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
if (!mStyle.systemFont && mPangoLanguage) {
basePattern = fontSet->GetFontPatternAt(0);
if (HasChar(basePattern, aCh)) {
*aMatchType = gfxTextRange::kFontGroup;
return nsRefPtr<gfxFont>(GetBaseFont()).forget();
}
@ -2092,7 +2041,6 @@ gfxPangoFontGroup::FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh,
}
if (HasChar(pattern, aCh)) {
*aMatchType = gfxTextRange::kFontGroup;
return nsRefPtr<gfxFont>(fontSet->GetFontAt(i)).forget();
}
}

View File

@ -70,8 +70,7 @@ public:
virtual already_AddRefed<gfxFont>
FindFontForChar(PRUint32 aCh, PRUint32 aPrevCh, PRInt32 aRunScript,
gfxFont *aPrevMatchedFont,
PRUint8 *aMatchType);
gfxFont *aPrevMatchedFont);
static void Shutdown();

View File

@ -569,7 +569,7 @@ MakeBlankTextRun(const void* aText, PRUint32 aLength,
if (!textRun || !textRun->GetCharacterGlyphs())
return nsnull;
gfxFont *font = aFontGroup->GetFontAt(0);
textRun->AddGlyphRun(font, gfxTextRange::kFontGroup, 0, PR_FALSE);
textRun->AddGlyphRun(font, 0);
#ifdef DEBUG
textRun->mCachedWords = 0;
textRun->mCacheGeneration = gTextRunWordCache ? gTextRunWordCache->mGeneration : 0;
@ -603,8 +603,7 @@ TextRunWordCache::MakeTextRun(const PRUnichar *aText, PRUint32 aLength,
#endif
gfxFont *font = aFontGroup->GetFontAt(0);
nsresult rv =
textRun->AddGlyphRun(font, gfxTextRange::kFontGroup, 0, PR_FALSE);
nsresult rv = textRun->AddGlyphRun(font, 0);
NS_ENSURE_SUCCESS(rv, nsnull);
nsAutoTArray<PRUnichar,200> tempString;
@ -747,8 +746,7 @@ TextRunWordCache::MakeTextRun(const PRUint8 *aText, PRUint32 aLength,
#endif
gfxFont *font = aFontGroup->GetFontAt(0);
nsresult rv =
textRun->AddGlyphRun(font, gfxTextRange::kFontGroup, 0, PR_FALSE);
nsresult rv = textRun->AddGlyphRun(font, 0);
NS_ENSURE_SUCCESS(rv, nsnull);
nsAutoTArray<PRUint8,200> tempString;

View File

@ -372,74 +372,6 @@ SanitizeOpenTypeData(const PRUint8* aData, PRUint32 aLength,
}
}
static void
StoreUserFontData(gfxFontEntry* aFontEntry, gfxProxyFontEntry* aProxy,
const nsAString& aOriginalName,
nsTArray<PRUint8>* aMetadata, PRUint32 aMetaOrigLen)
{
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;
userFontData->mRealName = aOriginalName;
if (aMetadata) {
userFontData->mMetadata.SwapElements(*aMetadata);
userFontData->mMetaOrigLen = aMetaOrigLen;
}
}
static void
CopyWOFFMetadata(const PRUint8* aFontData, PRUint32 aLength,
nsTArray<PRUint8>* aMetadata, PRUint32* aMetaOrigLen)
{
// This function may be called with arbitrary, unvalidated "font" data
// from @font-face, so it needs to be careful to bounds-check, etc.,
// before trying to read anything.
// This just saves a copy of the compressed data block; it does NOT check
// that the block can be successfully decompressed, or that it contains
// well-formed/valid XML metadata.
struct WOFFHeader {
AutoSwap_PRUint32 signature;
AutoSwap_PRUint32 flavor;
AutoSwap_PRUint32 length;
AutoSwap_PRUint16 numTables;
AutoSwap_PRUint16 reserved;
AutoSwap_PRUint32 totalSfntSize;
AutoSwap_PRUint16 majorVersion;
AutoSwap_PRUint16 minorVersion;
AutoSwap_PRUint32 metaOffset;
AutoSwap_PRUint32 metaCompLen;
AutoSwap_PRUint32 metaOrigLen;
AutoSwap_PRUint32 privOffset;
AutoSwap_PRUint32 privLen;
};
if (aLength < sizeof(WOFFHeader)) {
return;
}
const WOFFHeader* woff = reinterpret_cast<const WOFFHeader*>(aFontData);
PRUint32 metaOffset = woff->metaOffset;
PRUint32 metaCompLen = woff->metaCompLen;
if (!metaOffset || !metaCompLen || !woff->metaOrigLen) {
return;
}
if (metaOffset >= aLength || metaCompLen > aLength - metaOffset) {
return;
}
if (!aMetadata->SetLength(woff->metaCompLen)) {
return;
}
memcpy(aMetadata->Elements(), aFontData + metaOffset, metaCompLen);
*aMetaOrigLen = woff->metaOrigLen;
}
// 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().
@ -452,31 +384,14 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
if (NS_SUCCEEDED(aDownloadStatus)) {
gfxFontEntry *fe = nsnull;
gfxUserFontType fontType =
gfxFontUtils::DetermineFontDataType(aFontData, aLength);
// Save a copy of the metadata block (if present) for nsIDOMFontFace
// to use if required. Ownership of the metadata block will be passed
// to the gfxUserFontData record below.
// NOTE: after the non-OTS codepath using PrepareOpenTypeData is
// removed, we should defer this until after we've created the new
// fontEntry.
nsTArray<PRUint8> metadata;
PRUint32 metaOrigLen = 0;
if (fontType == GFX_USERFONT_WOFF) {
CopyWOFFMetadata(aFontData, aLength, &metadata, &metaOrigLen);
}
// Unwrap/decompress/sanitize or otherwise munge the downloaded data
// to make a usable sfnt structure.
// Because platform font activation code may replace the name table
// in the font with a synthetic one, we save the original name so that
// it can be reported via the nsIDOMFontFace API.
nsAutoString originalFullName;
if (gfxPlatform::GetPlatform()->SanitizeDownloadedFonts()) {
// Call the OTS sanitizer; this will also decode WOFF to sfnt
gfxUserFontType fontType =
gfxFontUtils::DetermineFontDataType(aFontData, aLength);
// Call the OTS sanitizer; this will also decode WOFF to sfnt
// if necessary. The original data in aFontData is left unchanged.
PRUint32 saneLen;
const PRUint8* saneData =
@ -491,12 +406,6 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
}
#endif
if (saneData) {
// The sanitizer ensures that we have a valid sfnt and a usable
// name table, so this should never fail unless we're out of
// memory, and GetFullNameFromSFNT is not directly exposed to
// arbitrary/malicious data from the web.
gfxFontUtils::GetFullNameFromSFNT(saneData, saneLen,
originalFullName);
// Here ownership of saneData is passed to the platform,
// which will delete it when no longer required
fe = gfxPlatform::GetPlatform()->MakePlatformFont(aProxy,
@ -514,10 +423,6 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
if (aFontData) {
if (gfxFontUtils::ValidateSFNTHeaders(aFontData, aLength)) {
// ValidateSFNTHeaders has checked that we have a valid
// sfnt structure and a usable 'name' table
gfxFontUtils::GetFullNameFromSFNT(aFontData, aLength,
originalFullName);
// Here ownership of aFontData is passed to the platform,
// which will delete it when no longer required
fe = gfxPlatform::GetPlatform()->MakePlatformFont(aProxy,
@ -542,8 +447,7 @@ gfxUserFontSet::OnLoadComplete(gfxProxyFontEntry *aProxy,
// newly-created font entry
fe->mFeatureSettings.AppendElements(aProxy->mFeatureSettings);
fe->mLanguageOverride = aProxy->mLanguageOverride;
StoreUserFontData(fe, aProxy, originalFullName,
&metadata, metaOrigLen);
#ifdef PR_LOGGING
// must do this before ReplaceFontEntry() because that will
// clear the proxy's mFamily pointer!
@ -635,7 +539,6 @@ gfxUserFontSet::LoadNext(gfxProxyFontEntry *aProxyEntry)
PRUint32(mGeneration)));
fe->mFeatureSettings.AppendElements(aProxyEntry->mFeatureSettings);
fe->mLanguageOverride = aProxyEntry->mLanguageOverride;
StoreUserFontData(fe, aProxyEntry, nsString(), nsnull, 0);
ReplaceFontEntry(aProxyEntry, fe);
return STATUS_LOADED;
} else {

View File

@ -71,26 +71,12 @@ struct gfxFontFaceSrc {
};
// 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.
// subclassed to store platform-specific code cleaned out when font entry is deleted
// lifetime: from when platform font is created until it is deactivated
class gfxUserFontData {
public:
gfxUserFontData()
: mSrcIndex(0), mFormat(0), mMetaOrigLen(0)
{ }
gfxUserFontData() { }
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()
nsString mRealName; // original fullname from the font resource
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

View File

@ -63,7 +63,7 @@ endif
PARALLEL_DIRS += inspector/public inspector/src
ifdef ENABLE_TESTS
PARALLEL_DIRS += inspector/tests inspector/tests/chrome
PARALLEL_DIRS += inspector/tests
endif
DIRS += build

View File

@ -98,8 +98,6 @@
#include "gfxDrawable.h"
#include "gfxUtils.h"
#include "nsDataHashtable.h"
#include "nsTextFrame.h"
#include "nsFontFaceList.h"
#include "nsSVGUtils.h"
#include "nsSVGIntegrationUtils.h"
@ -4057,77 +4055,6 @@ nsLayoutUtils::AssertTreeOnlyEmptyNextInFlows(nsIFrame *aSubtreeRoot)
}
#endif
/* static */
nsresult
nsLayoutUtils::GetFontFacesForFrames(nsIFrame* aFrame,
nsFontFaceList* aFontFaceList)
{
NS_PRECONDITION(aFrame, "NULL frame pointer");
if (aFrame->GetType() == nsGkAtoms::textFrame) {
return GetFontFacesForText(aFrame, 0, PR_INT32_MAX, PR_FALSE,
aFontFaceList);
}
while (aFrame) {
nsIAtom* childLists[] = { nsnull, nsGkAtoms::popupList };
for (int i = 0; i < NS_ARRAY_LENGTH(childLists); ++i) {
nsFrameList children(aFrame->GetChildList(childLists[i]));
for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) {
nsIFrame* child = e.get();
if (child->GetPrevContinuation()) {
continue;
}
child = nsPlaceholderFrame::GetRealFrameFor(child);
nsresult rv = GetFontFacesForFrames(child, aFontFaceList);
NS_ENSURE_SUCCESS(rv, rv);
}
}
aFrame = GetNextContinuationOrSpecialSibling(aFrame);
}
return NS_OK;
}
/* static */
nsresult
nsLayoutUtils::GetFontFacesForText(nsIFrame* aFrame,
PRInt32 aStartOffset, PRInt32 aEndOffset,
PRBool aFollowContinuations,
nsFontFaceList* aFontFaceList)
{
NS_PRECONDITION(aFrame, "NULL frame pointer");
if (aFrame->GetType() != nsGkAtoms::textFrame) {
return NS_OK;
}
nsTextFrame* curr = static_cast<nsTextFrame*>(aFrame);
do {
PRInt32 offset = curr->GetContentOffset();
PRInt32 fstart = NS_MAX(offset, aStartOffset);
PRInt32 fend = NS_MIN(curr->GetContentEnd(), aEndOffset);
if (fstart >= fend) {
continue;
}
// overlapping with the offset we want
curr->EnsureTextRun();
gfxTextRun* textRun = curr->GetTextRun();
NS_ENSURE_TRUE(textRun, NS_ERROR_OUT_OF_MEMORY);
gfxSkipCharsIterator iter(textRun->GetSkipChars());
PRUint32 skipStart = iter.ConvertOriginalToSkipped(fstart - offset);
PRUint32 skipEnd = iter.ConvertOriginalToSkipped(fend - offset);
aFontFaceList->AddFontsFromTextRun(textRun,
skipStart, skipEnd - skipStart,
curr);
} while (aFollowContinuations &&
(curr = static_cast<nsTextFrame*>(curr->GetNextContinuation())));
return NS_OK;
}
/* static */
void
nsLayoutUtils::Shutdown()

View File

@ -52,7 +52,6 @@ class nsDisplayListBuilder;
class nsDisplayItem;
class nsFontMetrics;
class nsClientRectList;
class nsFontFaceList;
#include "prtypes.h"
#include "nsStyleContext.h"
@ -1345,25 +1344,6 @@ public:
aPresContext->Type() == nsPresContext::eContext_PageLayout);
}
/**
* Adds all font faces used in the frame tree starting from aFrame
* to the list aFontFaceList.
*/
static nsresult GetFontFacesForFrames(nsIFrame* aFrame,
nsFontFaceList* aFontFaceList);
/**
* Adds all font faces used within the specified range of text in aFrame,
* and optionally its continuations, to the list in aFontFaceList.
* Pass 0 and PR_INT32_MAX for aStartOffset and aEndOffset to specify the
* entire text is to be considered.
*/
static nsresult GetFontFacesForText(nsIFrame* aFrame,
PRInt32 aStartOffset,
PRInt32 aEndOffset,
PRBool aFollowContinuations,
nsFontFaceList* aFontFaceList);
static void Shutdown();
#ifdef DEBUG

View File

@ -153,8 +153,7 @@ MergeCharactersInTextRun(gfxTextRun* aDest, gfxTextRun* aSrc,
nsAutoTArray<gfxTextRun::DetailedGlyph,2> glyphs;
while (iter.NextRun()) {
gfxTextRun::GlyphRun* run = iter.GetGlyphRun();
nsresult rv = aDest->AddGlyphRun(run->mFont, run->mMatchType,
offset, PR_FALSE);
nsresult rv = aDest->AddGlyphRun(run->mFont, offset);
if (NS_FAILED(rv))
return;

View File

@ -54,8 +54,6 @@ XPIDLSRCS = inIDOMView.idl \
inISearchObserver.idl \
inICSSValueSearch.idl \
inIDOMUtils.idl \
nsIDOMFontFace.idl \
nsIDOMFontFaceList.idl \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -46,10 +46,8 @@ interface nsIDOMDocument;
interface nsIDOMCSSStyleRule;
interface nsIDOMNode;
interface nsIDOMNodeList;
interface nsIDOMFontFaceList;
interface nsIDOMRange;
[scriptable, uuid(70205D9E-EFD7-4658-8E9E-690400B57FD0)]
[scriptable, uuid(bb8f76f4-888e-11e0-9e35-5f8b6c85da46)]
interface inIDOMUtils : nsISupports
{
// CSS utilities
@ -72,6 +70,4 @@ interface inIDOMUtils : nsISupports
// content state utilities
unsigned long long getContentState(in nsIDOMElement aElement);
void setContentState(in nsIDOMElement aElement, in unsigned long long aState);
nsIDOMFontFaceList getUsedFontFaces(in nsIDOMRange aRange);
};

View File

@ -1,28 +0,0 @@
#include "nsISupports.idl"
interface nsIDOMCSSFontFaceRule;
interface nsIDOMCSSStyleDeclaration;
[scriptable, uuid(9a3b1272-6585-4f41-b08f-fdc5da444cd0)]
interface nsIDOMFontFace : nsISupports
{
// An indication of how we found this font during font-matching.
// Note that the same physical font may have been found in multiple ways within a range.
readonly attribute boolean fromFontGroup;
readonly attribute boolean fromLanguagePrefs;
readonly attribute boolean fromSystemFallback;
// available for all fonts
readonly attribute DOMString name; // full font name as obtained from the font resource
readonly attribute DOMString CSSFamilyName; // a family name that could be used in CSS font-family
// (not necessarily the actual name that was used,
// due to aliases, generics, localized names, etc)
// meaningful only when the font is a user font defined using @font-face
readonly attribute nsIDOMCSSFontFaceRule rule; // null if no associated @font-face rule
readonly attribute long srcIndex; // index in the rule's src list, -1 if no @font-face rule
readonly attribute DOMString URI; // null if not a downloaded font, i.e. local
readonly attribute DOMString localName; // null if not a src:local(...) rule
readonly attribute DOMString format; // as per http://www.w3.org/TR/css3-webfonts/#referencing
readonly attribute DOMString metadata; // XML metadata from WOFF file (if any)
};

View File

@ -1,10 +0,0 @@
#include "nsISupports.idl"
interface nsIDOMFontFace;
[scriptable, uuid(2538579c-9472-4fd9-8dc1-d44ce4c1b7ba)]
interface nsIDOMFontFaceList : nsISupports
{
nsIDOMFontFace item(in unsigned long index);
readonly attribute unsigned long length;
};

View File

@ -46,10 +46,7 @@ MODULE = inspector
LIBRARY_NAME = inspector_s
LIBXUL_LIBRARY = 1
EXPORTS = \
nsFontFace.h \
nsFontFaceList.h \
$(NULL)
CPPSRCS= \
inDeepTreeWalker.cpp \
@ -58,8 +55,6 @@ CPPSRCS= \
inCSSValueSearch.cpp \
inDOMUtils.cpp \
inLayoutUtils.cpp \
nsFontFace.cpp \
nsFontFaceList.cpp \
$(NULL)
ifdef MOZ_XUL

View File

@ -58,7 +58,6 @@
#include "nsComputedDOMStyle.h"
#include "nsEventStateManager.h"
#include "nsIAtom.h"
#include "nsIRange.h"
///////////////////////////////////////////////////////////////////////////////
@ -332,13 +331,3 @@ inDOMUtils::GetRuleNodeForContent(nsIContent* aContent,
}
return NS_OK;
}
NS_IMETHODIMP
inDOMUtils::GetUsedFontFaces(nsIDOMRange* aRange,
nsIDOMFontFaceList** aFontFaceList)
{
nsCOMPtr<nsIRange> range = do_QueryInterface(aRange);
NS_ENSURE_TRUE(range, NS_ERROR_UNEXPECTED);
return range->GetUsedFontFaces(aFontFaceList);
}

View File

@ -64,8 +64,8 @@ private:
nsRuleNode** aRuleNode);
};
// {0a499822-a287-4089-ad3f-9ffcd4f40263}
// {40B22006-5DD5-42f2-BFE7-7DBF0757AB8B}
#define IN_DOMUTILS_CID \
{0x0a499822, 0xa287, 0x4089, {0xad, 0x3f, 0x9f, 0xfc, 0xd4, 0xf4, 0x02, 0x63}}
{ 0x40b22006, 0x5dd5, 0x42f2, { 0xbf, 0xe7, 0x7d, 0xbf, 0x7, 0x57, 0xab, 0x8b } }
#endif // __inDOMUtils_h__

View File

@ -1,227 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonathan Kew <jfkthame@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define _IMPL_NS_LAYOUT
#include "nsFontFace.h"
#include "nsIDOMCSSFontFaceRule.h"
#include "nsCSSRules.h"
#include "gfxUserFontSet.h"
#include "zlib.h"
nsFontFace::nsFontFace(gfxFontEntry* aFontEntry,
PRUint8 aMatchType,
nsCSSFontFaceRule* aRule)
: mFontEntry(aFontEntry),
mMatchType(aMatchType),
mRule(aRule)
{
}
nsFontFace::~nsFontFace()
{
}
////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS1(nsFontFace, nsIDOMFontFace)
////////////////////////////////////////////////////////////////////////
// nsIDOMFontFace
/* readonly attribute boolean fromFontGroup; */
NS_IMETHODIMP
nsFontFace::GetFromFontGroup(PRBool * aFromFontGroup)
{
*aFromFontGroup =
(mMatchType & gfxTextRange::kFontGroup) != 0;
return NS_OK;
}
/* readonly attribute boolean fromLanguagePrefs; */
NS_IMETHODIMP
nsFontFace::GetFromLanguagePrefs(PRBool * aFromLanguagePrefs)
{
*aFromLanguagePrefs =
(mMatchType & gfxTextRange::kPrefsFallback) != 0;
return NS_OK;
}
/* readonly attribute boolean fromSystemFallback; */
NS_IMETHODIMP
nsFontFace::GetFromSystemFallback(PRBool * aFromSystemFallback)
{
*aFromSystemFallback =
(mMatchType & gfxTextRange::kSystemFallback) != 0;
return NS_OK;
}
/* readonly attribute DOMString name; */
NS_IMETHODIMP
nsFontFace::GetName(nsAString & aName)
{
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
aName = mFontEntry->mUserFontData->mRealName;
} else {
aName = mFontEntry->RealFaceName();
}
return NS_OK;
}
/* readonly attribute DOMString CSSFamilyName; */
NS_IMETHODIMP
nsFontFace::GetCSSFamilyName(nsAString & aCSSFamilyName)
{
aCSSFamilyName = mFontEntry->FamilyName();
return NS_OK;
}
/* readonly attribute nsIDOMCSSFontFaceRule rule; */
NS_IMETHODIMP
nsFontFace::GetRule(nsIDOMCSSFontFaceRule **aRule)
{
NS_IF_ADDREF(*aRule = mRule.get());
return NS_OK;
}
/* readonly attribute long srcIndex; */
NS_IMETHODIMP
nsFontFace::GetSrcIndex(PRInt32 * aSrcIndex)
{
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)
{
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)
{
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)
{
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)
{
aMetadata.Truncate();
if (mFontEntry->IsUserFont() && !mFontEntry->IsLocalUserFont()) {
NS_ASSERTION(mFontEntry->mUserFontData, "missing userFontData");
const gfxUserFontData* userFontData = mFontEntry->mUserFontData;
if (userFontData->mMetadata.Length() && userFontData->mMetaOrigLen) {
nsCAutoString str;
str.SetLength(userFontData->mMetaOrigLen);
if (str.Length() == userFontData->mMetaOrigLen) {
uLongf destLen = userFontData->mMetaOrigLen;
if (uncompress((Bytef *)(str.BeginWriting()), &destLen,
(const Bytef *)(userFontData->mMetadata.Elements()),
userFontData->mMetadata.Length()) == Z_OK &&
destLen == userFontData->mMetaOrigLen)
{
AppendUTF8toUTF16(str, aMetadata);
}
}
}
}
return NS_OK;
}

View File

@ -1,69 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonathan Kew <jfkthame@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __nsFontFace_h__
#define __nsFontFace_h__
#include "nsIDOMFontFace.h"
#include "gfxFont.h"
class nsCSSFontFaceRule;
class nsFontFace : public nsIDOMFontFace
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMFONTFACE
nsFontFace(gfxFontEntry* aFontEntry,
PRUint8 aMatchInfo,
nsCSSFontFaceRule* aRule);
virtual ~nsFontFace();
gfxFontEntry* GetFontEntry() const { return mFontEntry.get(); }
void AddMatchType(PRUint8 aMatchType) {
mMatchType |= aMatchType;
}
protected:
nsRefPtr<gfxFontEntry> mFontEntry;
nsRefPtr<nsCSSFontFaceRule> mRule;
PRUint8 mMatchType;
};
#endif // __nsFontFace_h__

View File

@ -1,138 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonathan Kew <jfkthame@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#define _IMPL_NS_LAYOUT
#include "nsFontFaceList.h"
#include "nsFontFace.h"
#include "nsFontFaceLoader.h"
#include "nsIFrame.h"
#include "gfxFont.h"
nsFontFaceList::nsFontFaceList()
{
mFontFaces.Init();
}
nsFontFaceList::~nsFontFaceList()
{
}
////////////////////////////////////////////////////////////////////////
// nsISupports
NS_IMPL_ISUPPORTS1(nsFontFaceList, nsIDOMFontFaceList)
////////////////////////////////////////////////////////////////////////
// nsIDOMFontFaceList
/* nsIDOMFontFace item (in unsigned long index); */
struct FindByIndexData {
PRUint32 mTarget;
PRUint32 mCurrent;
nsIDOMFontFace* mResult;
};
static PLDHashOperator
FindByIndex(gfxFontEntry* aKey, nsIDOMFontFace* aData, void* aUserData)
{
FindByIndexData* data = static_cast<FindByIndexData*>(aUserData);
if (data->mCurrent == data->mTarget) {
data->mResult = aData;
return PL_DHASH_STOP;
}
data->mCurrent++;
return PL_DHASH_NEXT;
}
NS_IMETHODIMP
nsFontFaceList::Item(PRUint32 index, nsIDOMFontFace **_retval NS_OUTPARAM)
{
NS_ENSURE_TRUE(index < mFontFaces.Count(), NS_ERROR_INVALID_ARG);
FindByIndexData userData;
userData.mTarget = index;
userData.mCurrent = 0;
userData.mResult = nsnull;
mFontFaces.EnumerateRead(FindByIndex, &userData);
NS_ASSERTION(userData.mResult != nsnull, "null entry in nsFontFaceList?");
NS_IF_ADDREF(*_retval = userData.mResult);
return NS_OK;
}
/* readonly attribute unsigned long length; */
NS_IMETHODIMP
nsFontFaceList::GetLength(PRUint32 *aLength)
{
*aLength = mFontFaces.Count();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////
// nsFontFaceList
nsresult
nsFontFaceList::AddFontsFromTextRun(gfxTextRun* aTextRun,
PRUint32 aOffset, PRUint32 aLength,
nsIFrame* aFrame)
{
gfxTextRun::GlyphRunIterator iter(aTextRun, aOffset, aLength);
while (iter.NextRun()) {
gfxFontEntry *fe = iter.GetGlyphRun()->mFont->GetFontEntry();
// if we have already listed this face, just make sure the match type is
// recorded
nsFontFace* existingFace =
static_cast<nsFontFace*>(mFontFaces.GetWeak(fe));
if (existingFace) {
existingFace->AddMatchType(iter.GetGlyphRun()->mMatchType);
} else {
// A new font entry we haven't seen before;
// check whether this font entry is associated with an @font-face rule
nsRefPtr<nsCSSFontFaceRule> rule;
nsUserFontSet* fontSet =
static_cast<nsUserFontSet*>(aFrame->PresContext()->GetUserFontSet());
if (fontSet) {
rule = fontSet->FindRuleForEntry(fe);
}
nsCOMPtr<nsFontFace> ff =
new nsFontFace(fe, iter.GetGlyphRun()->mMatchType, rule);
if (!mFontFaces.Put(fe, ff)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
}
return NS_OK;
}

View File

@ -1,67 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonathan Kew <jfkthame@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __nsFontFaceList_h__
#define __nsFontFaceList_h__
#include "nsIDOMFontFaceList.h"
#include "nsIDOMFontFace.h"
#include "nsCOMPtr.h"
#include "nsInterfaceHashtable.h"
#include "nsHashKeys.h"
#include "gfxFont.h"
class gfxTextRun;
class nsIFrame;
class nsFontFaceList : public nsIDOMFontFaceList
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMFONTFACELIST
nsFontFaceList();
virtual ~nsFontFaceList();
nsresult AddFontsFromTextRun(gfxTextRun* aTextRun,
PRUint32 aOffset, PRUint32 aLength,
nsIFrame* aFrame);
protected:
nsInterfaceHashtable<nsPtrHashKey<gfxFontEntry>,nsIDOMFontFace> mFontFaces;
};
#endif // __nsFontFaceList_h__

View File

@ -1,54 +0,0 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = layout/inspector/tests/chrome
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_CHROME_FILES =\
test_bug467669.xul \
test_bug467669.css \
GentiumPlus-R.woff \
$(NULL)
libs:: $(_CHROME_FILES)
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)

View File

@ -1,8 +0,0 @@
@font-face {
font-family: font-face-test-family;
src: url(bad/font/name.ttf), url(GentiumPlus-R.woff) format("woff");
}
.gentium {
font-family: font-face-test-family;
}

View File

@ -1,175 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin"?>
<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
<?xml-stylesheet type="text/css" href="test_bug467669.css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=467669
-->
<window title="Mozilla Bug 467669"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="RunTest();">
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"/>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
<!-- test code goes here -->
<script type="application/javascript">
<![CDATA[
/** Test for Bug 467669 **/
SimpleTest.waitForExplicitFinish();
function RunTest() {
const CI = Components.interfaces;
const CC = Components.classes;
const kIsLinux = navigator.platform.indexOf("Linux") == 0;
const kIsMac = navigator.platform.indexOf("Mac") == 0;
const kIsWin = navigator.platform.indexOf("Win") == 0;
var domUtils =
CC["@mozilla.org/inspector/dom-utils;1"].getService(CI.inIDOMUtils);
var rng = document.createRange();
var elem, fonts, f;
elem = document.getElementById("test1");
rng.selectNode(elem);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 1, "number of fonts for simple Latin text");
f = fonts.item(0);
is(f.rule, null, "rule");
is(f.srcIndex, -1, "srcIndex");
is(f.localName, "", "local name");
is(f.URI, "", "URI");
is(f.format, "", "format string");
is(f.metadata, "", "metadata");
// report(elem.id, fonts);
elem = document.getElementById("test2");
rng.selectNode(elem);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 3, "number of fonts for mixed serif, sans and monospaced text");
// report(elem.id, fonts);
elem = document.getElementById("test3");
rng.selectNode(elem);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 2, "number of fonts for mixed Latin & Chinese");
// report(elem.id, fonts);
// get properties of a @font-face font
elem = document.getElementById("test4");
rng.selectNode(elem);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 1, "number of fonts in @font-face test");
f = fonts.item(0);
isnot(f.rule, null, "missing rule");
is(f.srcIndex, 1, "srcIndex");
is(f.localName, "", "local name");
is(f.URI, "chrome://mochitests/content/chrome/layout/inspector/tests/chrome/GentiumPlus-R.woff", "bad URI");
is(f.format, "woff", "format");
is(/bukva:raz/.test(f.metadata), true, "metadata");
// report(elem.id, fonts);
elem = document.getElementById("test5").childNodes[0];
// check that string length is as expected, including soft hyphens
is(elem.length, 42, "string length with soft hyphens");
// initial latin substring...
rng.setStart(elem, 0);
rng.setEnd(elem, 20); // "supercalifragilistic"
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 1, "number of fonts (Latin-only)");
f = fonts.item(0);
is(f.name, "Gentium Plus", "font name");
is(f.CSSFamilyName, "font-face-test-family", "family name");
is(f.fromFontGroup, true, "font matched in font group");
// extend to include a chinese character
rng.setEnd(elem, 21);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 2, "number of fonts (incl Chinese)");
if (kIsMac || kIsWin) { // these are only implemented by the Mac & Win font backends
var i;
for (i = 0; i < fonts.length; ++i) {
f = fonts.item(i);
if (f.rule) {
is(f.fromFontGroup, true, "@font-face font matched in group");
is(f.fromLanguagePrefs, false, "not from language prefs");
is(f.fromSystemFallback, false, "not from system fallback");
} else {
is(f.fromFontGroup, false, "not matched in group");
is(f.fromLanguagePrefs, true, "from language prefs");
is(f.fromSystemFallback, false, "not from system fallback");
}
}
}
// second half of the string includes &shy; chars to check original/skipped mapping;
// select just the final character
rng.setStart(elem, elem.length - 1);
rng.setEnd(elem, elem.length);
is(rng.toString(), "!", "content of range");
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 1, "number of fonts for last char");
f = fonts.item(0);
is(f.name, "Gentium Plus", "font name");
// include the preceding character as well
rng.setStart(elem, elem.length - 2);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 2, "number of fonts for last two chars");
// then trim the final one
rng.setEnd(elem, elem.length - 1);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 1, "number of fonts for Chinese char");
f = fonts.item(0);
isnot(f.name, "Gentium Plus", "font name for Chinese char");
rng.selectNode(elem);
fonts = domUtils.getUsedFontFaces(rng);
// report("test5", fonts);
elem = document.getElementById("test6");
rng.selectNode(elem);
fonts = domUtils.getUsedFontFaces(rng);
is(fonts.length, 2, "number of font faces for regular & italic");
is(fonts.item(0).CSSFamilyName, fonts.item(1).CSSFamilyName, "same family for regular & italic");
isnot(fonts.item(0).name, fonts.item(1).name, "different faces for regular & italic");
// report(elem.id, fonts);
SimpleTest.finish();
}
// just for test-debugging purposes
function report(e, f) {
var fontNames = "";
var i;
for (i = 0; i < f.length; ++i) {
if (i == 0) {
fontNames += e + " fonts: "
} else {
fontNames += ", ";
}
fontNames += f.item(i).name;
}
dump(fontNames + "\n");
}
]]>
</script>
<!-- html:body contains elements the test will inspect -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=467669"
target="_blank">Mozilla Bug 467669</a>
<div id="test1">Hello world</div>
<div id="test2" style="font-family:sans-serif"><span style="font-family:serif">Hello</span> <tt>cruel</tt> world</div>
<div id="test3">Hello, &#x4F60;&#x597D;</div>
<div id="test4" class="gentium">Hello Gentium Plus!</div>
<div id="test5" class="gentium">supercalifragilistic&#x4F60;ex&#xAD;pi&#xAD;a&#xAD;li&#xAD;do&#xAD;cious&#x597D;!</div>
<div id="test6" style="font-family:serif">regular and <em>italic</em> text</div>
</body>
</window>

View File

@ -686,14 +686,3 @@ nsUserFontSet::ReplaceFontEntry(gfxProxyFontEntry *aProxy,
static_cast<gfxMixedFontFamily*>(aProxy->Family())->
ReplaceFontEntry(aProxy, aFontEntry);
}
nsCSSFontFaceRule*
nsUserFontSet::FindRuleForEntry(gfxFontEntry *aFontEntry)
{
for (PRUint32 i = 0; i < mRules.Length(); ++i) {
if (mRules[i].mFontEntry == aFontEntry) {
return mRules[i].mContainer.mRule;
}
}
return nsnull;
}

View File

@ -86,8 +86,6 @@ public:
virtual void ReplaceFontEntry(gfxProxyFontEntry *aProxy,
gfxFontEntry *aFontEntry);
nsCSSFontFaceRule *FindRuleForEntry(gfxFontEntry *aFontEntry);
protected:
// The font-set keeps track of the collection of rules, and their
// corresponding font entries (whether proxies or real entries),