mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Backout bug 467669 and bug 660088
This commit is contained in:
parent
66c70413dc
commit
f92823ac1a
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -122,7 +122,3 @@ interface nsIDOMRange;
|
||||
interface nsIDOMCRMFObject;
|
||||
interface nsIDOMCrypto;
|
||||
interface nsIDOMPkcs11;
|
||||
|
||||
// Used font face (for inspector)
|
||||
interface nsIDOMFontFace;
|
||||
interface nsIDOMFontFaceList;
|
||||
|
@ -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
|
||||
|
@ -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_
|
@ -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;
|
||||
|
@ -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 *
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -54,8 +54,6 @@ XPIDLSRCS = inIDOMView.idl \
|
||||
inISearchObserver.idl \
|
||||
inICSSValueSearch.idl \
|
||||
inIDOMUtils.idl \
|
||||
nsIDOMFontFace.idl \
|
||||
nsIDOMFontFaceList.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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)
|
||||
};
|
@ -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;
|
||||
};
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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;
|
||||
}
|
@ -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__
|
@ -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;
|
||||
}
|
@ -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__
|
Binary file not shown.
@ -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)
|
@ -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;
|
||||
}
|
@ -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 ­ 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, 你好</div>
|
||||
<div id="test4" class="gentium">Hello Gentium Plus!</div>
|
||||
<div id="test5" class="gentium">supercalifragilistic你ex­pi­a­li­do­cious好!</div>
|
||||
<div id="test6" style="font-family:serif">regular and <em>italic</em> text</div>
|
||||
</body>
|
||||
|
||||
</window>
|
@ -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;
|
||||
}
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user