зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1639563) for gfx related bustages CLOSED TREE
DONTBUILD Backed out changeset b2c8de065886 (bug 1639563) Backed out changeset 43abf0a9602a (bug 1639563)
This commit is contained in:
Родитель
2bf24e6359
Коммит
107fbafd77
|
@ -230,15 +230,12 @@ bool ShmSegmentsReader::Read(const layers::OffsetRange& aRange,
|
|||
size_t initialLength = aInto.Length();
|
||||
|
||||
size_t srcCursor = aRange.start();
|
||||
size_t remainingBytesToCopy = aRange.length();
|
||||
int remainingBytesToCopy = aRange.length();
|
||||
while (remainingBytesToCopy > 0) {
|
||||
const size_t shm_idx = srcCursor / mChunkSize;
|
||||
const size_t ptrOffset = srcCursor % mChunkSize;
|
||||
if (ptrOffset >= mChunkSize) {
|
||||
break;
|
||||
}
|
||||
const size_t copyRange =
|
||||
std::min(remainingBytesToCopy, mChunkSize - ptrOffset);
|
||||
std::min<int>(remainingBytesToCopy, mChunkSize - ptrOffset);
|
||||
uint8_t* srcPtr =
|
||||
RefCountedShm::GetBytes(mSmallAllocs[shm_idx]) + ptrOffset;
|
||||
|
||||
|
@ -251,53 +248,6 @@ bool ShmSegmentsReader::Read(const layers::OffsetRange& aRange,
|
|||
return aInto.Length() - initialLength == aRange.length();
|
||||
}
|
||||
|
||||
Maybe<Range<uint8_t>> ShmSegmentsReader::GetReadPointerLarge(
|
||||
const layers::OffsetRange& aRange) {
|
||||
// source = zero is for small allocs.
|
||||
MOZ_RELEASE_ASSERT(aRange.source() != 0);
|
||||
if (aRange.source() > mLargeAllocs.Length()) {
|
||||
return Nothing();
|
||||
}
|
||||
size_t id = aRange.source() - 1;
|
||||
const ipc::Shmem& shm = mLargeAllocs[id];
|
||||
if (shm.Size<uint8_t>() < aRange.length()) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
uint8_t* srcPtr = shm.get<uint8_t>();
|
||||
return Some(Range<uint8_t>(srcPtr, aRange.length()));
|
||||
}
|
||||
|
||||
Maybe<Range<uint8_t>> ShmSegmentsReader::GetReadPointer(
|
||||
const layers::OffsetRange& aRange) {
|
||||
if (aRange.length() == 0) {
|
||||
return Some(Range<uint8_t>());
|
||||
}
|
||||
|
||||
if (aRange.source() != 0) {
|
||||
return GetReadPointerLarge(aRange);
|
||||
}
|
||||
|
||||
if (mChunkSize == 0 ||
|
||||
aRange.start() + aRange.length() > mChunkSize * mSmallAllocs.Length()) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
size_t srcCursor = aRange.start();
|
||||
size_t remainingBytesToCopy = aRange.length();
|
||||
const size_t shm_idx = srcCursor / mChunkSize;
|
||||
const size_t ptrOffset = srcCursor % mChunkSize;
|
||||
// Return nothing if we can't return a pointer to the full range
|
||||
if (ptrOffset >= mChunkSize ||
|
||||
mChunkSize - ptrOffset < remainingBytesToCopy) {
|
||||
return Nothing();
|
||||
}
|
||||
const size_t copyRange =
|
||||
std::min(remainingBytesToCopy, mChunkSize - ptrOffset);
|
||||
uint8_t* srcPtr = RefCountedShm::GetBytes(mSmallAllocs[shm_idx]) + ptrOffset;
|
||||
return Some(Range<uint8_t>(srcPtr, copyRange));
|
||||
}
|
||||
|
||||
IpcResourceUpdateQueue::IpcResourceUpdateQueue(
|
||||
layers::WebRenderBridgeChild* aAllocator, size_t aChunkSize)
|
||||
: mWriter(aAllocator, aChunkSize) {}
|
||||
|
|
|
@ -71,34 +71,9 @@ class ShmSegmentsReader {
|
|||
|
||||
bool Read(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
|
||||
|
||||
// Get a read pointer, if possible, directly into the shm. If the range has
|
||||
// been broken up into multiple chunks that can't be represented by a single
|
||||
// range, nothing will be returned to indicate failure.
|
||||
Maybe<Range<uint8_t>> GetReadPointer(const layers::OffsetRange& aRange);
|
||||
|
||||
// Get a read pointer, if possible, directly into the shm. Otherwise, copy
|
||||
// it into the Vec and return a pointer to that contiguous memory instead.
|
||||
// If all fails, return nothing.
|
||||
Maybe<Range<uint8_t>> GetReadPointerOrCopy(const layers::OffsetRange& aRange,
|
||||
wr::Vec<uint8_t>& aInto) {
|
||||
if (Maybe<Range<uint8_t>> ptr = GetReadPointer(aRange)) {
|
||||
return ptr;
|
||||
} else {
|
||||
size_t initialLength = aInto.Length();
|
||||
if (Read(aRange, aInto)) {
|
||||
return Some(Range<uint8_t>(aInto.Data() + initialLength,
|
||||
aInto.Length() - initialLength));
|
||||
} else {
|
||||
return Nothing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
bool ReadLarge(const layers::OffsetRange& aRange, wr::Vec<uint8_t>& aInto);
|
||||
|
||||
Maybe<Range<uint8_t>> GetReadPointerLarge(const layers::OffsetRange& aRange);
|
||||
|
||||
const nsTArray<layers::RefCountedShmem>& mSmallAllocs;
|
||||
const nsTArray<mozilla::ipc::Shmem>& mLargeAllocs;
|
||||
size_t mChunkSize;
|
||||
|
@ -112,8 +87,9 @@ class IpcResourceUpdateQueue {
|
|||
// we use here. The RefCountedShmem type used to allocate the chunks keeps a
|
||||
// 16 bytes header in the buffer which we account for here as well. So we pick
|
||||
// 64k - 2 * 4k - 16 = 57328 bytes as the default alloc size.
|
||||
explicit IpcResourceUpdateQueue(layers::WebRenderBridgeChild* aAllocator,
|
||||
size_t aChunkSize = 57328);
|
||||
explicit IpcResourceUpdateQueue(
|
||||
layers::WebRenderBridgeChild* aAllocator,
|
||||
size_t aChunkSize = 57328);
|
||||
|
||||
IpcResourceUpdateQueue(IpcResourceUpdateQueue&& aOther) noexcept;
|
||||
IpcResourceUpdateQueue& operator=(IpcResourceUpdateQueue&& aOther) noexcept;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "CompositableHost.h"
|
||||
#include "gfxEnv.h"
|
||||
#include "gfxOTSUtils.h"
|
||||
#include "gfxEnv.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
|
@ -430,48 +430,6 @@ void WebRenderBridgeParent::Destroy() {
|
|||
ClearResources();
|
||||
}
|
||||
|
||||
struct WROTSAlloc {
|
||||
wr::Vec<uint8_t> mVec;
|
||||
|
||||
void* Grow(void* aPtr, size_t aLength) {
|
||||
if (aLength > mVec.Length()) {
|
||||
mVec.Reserve(aLength - mVec.Length());
|
||||
}
|
||||
return mVec.inner.data;
|
||||
}
|
||||
wr::Vec<uint8_t> ShrinkToFit(void* aPtr, size_t aLength) {
|
||||
wr::Vec<uint8_t> result(std::move(mVec));
|
||||
result.inner.length = aLength;
|
||||
return result;
|
||||
}
|
||||
void Free(void* aPtr) {}
|
||||
};
|
||||
|
||||
static bool ReadRawFont(const OpAddRawFont& aOp, wr::ShmSegmentsReader& aReader,
|
||||
wr::TransactionBuilder& aUpdates) {
|
||||
wr::Vec<uint8_t> sourceBytes;
|
||||
Maybe<Range<uint8_t>> ptr =
|
||||
aReader.GetReadPointerOrCopy(aOp.bytes(), sourceBytes);
|
||||
if (ptr.isNothing()) {
|
||||
return false;
|
||||
}
|
||||
Range<uint8_t>& source = ptr.ref();
|
||||
// Attempt to sanitize the font before passing it along for updating
|
||||
size_t lengthHint = gfxOTSContext::GuessSanitizedFontSize(
|
||||
source.begin().get(), source.length());
|
||||
if (!lengthHint) {
|
||||
return false;
|
||||
}
|
||||
gfxOTSExpandingMemoryStream<WROTSAlloc> output(lengthHint);
|
||||
gfxOTSContext otsContext;
|
||||
if (!otsContext.Process(&output, source.begin().get(), source.length())) {
|
||||
return false;
|
||||
}
|
||||
wr::Vec<uint8_t> bytes = output.forget();
|
||||
aUpdates.AddRawFont(aOp.key(), bytes, aOp.fontIndex());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WebRenderBridgeParent::UpdateResources(
|
||||
const nsTArray<OpUpdateResource>& aResourceUpdates,
|
||||
const nsTArray<RefCountedShmem>& aSmallShmems,
|
||||
|
@ -571,9 +529,12 @@ bool WebRenderBridgeParent::UpdateResources(
|
|||
break;
|
||||
}
|
||||
case OpUpdateResource::TOpAddRawFont: {
|
||||
if (!ReadRawFont(cmd.get_OpAddRawFont(), reader, aUpdates)) {
|
||||
const auto& op = cmd.get_OpAddRawFont();
|
||||
wr::Vec<uint8_t> bytes;
|
||||
if (!reader.Read(op.bytes(), bytes)) {
|
||||
return false;
|
||||
}
|
||||
aUpdates.AddRawFont(op.key(), bytes, op.fontIndex());
|
||||
break;
|
||||
}
|
||||
case OpUpdateResource::TOpAddFontDescriptor: {
|
||||
|
|
|
@ -1,157 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GFX_OTS_UTILS_H
|
||||
#define GFX_OTS_UTILS_H
|
||||
|
||||
#include "gfxFontUtils.h"
|
||||
|
||||
#include "opentype-sanitiser.h"
|
||||
|
||||
struct gfxOTSMozAlloc {
|
||||
void* Grow(void* aPtr, size_t aLength) { return moz_xrealloc(aPtr, aLength); }
|
||||
void* ShrinkToFit(void* aPtr, size_t aLength) {
|
||||
return moz_xrealloc(aPtr, aLength);
|
||||
}
|
||||
void Free(void* aPtr) { free(aPtr); }
|
||||
};
|
||||
|
||||
// Based on ots::ExpandingMemoryStream from ots-memory-stream.h,
|
||||
// adapted to use Mozilla allocators and to allow the final
|
||||
// memory buffer to be adopted by the client.
|
||||
template <typename AllocT = gfxOTSMozAlloc>
|
||||
class gfxOTSExpandingMemoryStream : public ots::OTSStream {
|
||||
public:
|
||||
// limit output/expansion to 256MB by default
|
||||
enum { DEFAULT_LIMIT = 256 * 1024 * 1024 };
|
||||
|
||||
explicit gfxOTSExpandingMemoryStream(size_t initial,
|
||||
size_t limit = DEFAULT_LIMIT)
|
||||
: mLength(initial), mLimit(limit), mOff(0) {
|
||||
mPtr = mAlloc.Grow(nullptr, mLength);
|
||||
}
|
||||
|
||||
~gfxOTSExpandingMemoryStream() { mAlloc.Free(mPtr); }
|
||||
|
||||
// Return the buffer, resized to fit its contents (as it may have been
|
||||
// over-allocated during growth), and give up ownership of it so the
|
||||
// caller becomes responsible to call free() when finished with it.
|
||||
auto forget() {
|
||||
auto p = mAlloc.ShrinkToFit(mPtr, mOff);
|
||||
mPtr = nullptr;
|
||||
return p;
|
||||
}
|
||||
|
||||
bool WriteRaw(const void* data, size_t length) override {
|
||||
if ((mOff + length > mLength) ||
|
||||
(mLength > std::numeric_limits<size_t>::max() - mOff)) {
|
||||
if (mLength == mLimit) {
|
||||
return false;
|
||||
}
|
||||
size_t newLength = (mLength + 1) * 2;
|
||||
if (newLength < mLength) {
|
||||
return false;
|
||||
}
|
||||
if (newLength > mLimit) {
|
||||
newLength = mLimit;
|
||||
}
|
||||
mPtr = mAlloc.Grow(mPtr, newLength);
|
||||
mLength = newLength;
|
||||
return WriteRaw(data, length);
|
||||
}
|
||||
std::memcpy(static_cast<char*>(mPtr) + mOff, data, length);
|
||||
mOff += length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seek(off_t position) override {
|
||||
if (position < 0) {
|
||||
return false;
|
||||
}
|
||||
if (static_cast<size_t>(position) > mLength) {
|
||||
return false;
|
||||
}
|
||||
mOff = position;
|
||||
return true;
|
||||
}
|
||||
|
||||
off_t Tell() const override { return mOff; }
|
||||
|
||||
private:
|
||||
AllocT mAlloc;
|
||||
void* mPtr;
|
||||
size_t mLength;
|
||||
const size_t mLimit;
|
||||
off_t mOff;
|
||||
};
|
||||
|
||||
class MOZ_STACK_CLASS gfxOTSContext : public ots::OTSContext {
|
||||
public:
|
||||
gfxOTSContext() {
|
||||
using namespace mozilla;
|
||||
|
||||
// Whether to apply OTS validation to OpenType Layout tables
|
||||
mCheckOTLTables = StaticPrefs::gfx_downloadable_fonts_otl_validation();
|
||||
// Whether to preserve Variation tables in downloaded fonts
|
||||
mCheckVariationTables =
|
||||
StaticPrefs::gfx_downloadable_fonts_validate_variation_tables();
|
||||
// Whether to preserve color bitmap glyphs
|
||||
mKeepColorBitmaps =
|
||||
StaticPrefs::gfx_downloadable_fonts_keep_color_bitmaps();
|
||||
}
|
||||
|
||||
virtual ots::TableAction GetTableAction(uint32_t aTag) override {
|
||||
// Preserve Graphite, color glyph and SVG tables,
|
||||
// and possibly OTL and Variation tables (depending on prefs)
|
||||
if ((!mCheckOTLTables && (aTag == TRUETYPE_TAG('G', 'D', 'E', 'F') ||
|
||||
aTag == TRUETYPE_TAG('G', 'P', 'O', 'S') ||
|
||||
aTag == TRUETYPE_TAG('G', 'S', 'U', 'B'))) ||
|
||||
(!mCheckVariationTables &&
|
||||
(aTag == TRUETYPE_TAG('a', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('c', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('f', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('g', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('H', 'V', 'A', 'R') ||
|
||||
aTag == TRUETYPE_TAG('M', 'V', 'A', 'R') ||
|
||||
aTag == TRUETYPE_TAG('S', 'T', 'A', 'T') ||
|
||||
aTag == TRUETYPE_TAG('V', 'V', 'A', 'R'))) ||
|
||||
aTag == TRUETYPE_TAG('S', 'V', 'G', ' ') ||
|
||||
aTag == TRUETYPE_TAG('C', 'O', 'L', 'R') ||
|
||||
aTag == TRUETYPE_TAG('C', 'P', 'A', 'L') ||
|
||||
(mKeepColorBitmaps && (aTag == TRUETYPE_TAG('C', 'B', 'D', 'T') ||
|
||||
aTag == TRUETYPE_TAG('C', 'B', 'L', 'C'))) ||
|
||||
false) {
|
||||
return ots::TABLE_ACTION_PASSTHRU;
|
||||
}
|
||||
return ots::TABLE_ACTION_DEFAULT;
|
||||
}
|
||||
|
||||
static size_t GuessSanitizedFontSize(size_t aLength,
|
||||
gfxUserFontType aFontType) {
|
||||
switch (aFontType) {
|
||||
case GFX_USERFONT_UNKNOWN:
|
||||
return 0;
|
||||
case GFX_USERFONT_WOFF:
|
||||
return aLength * 2;
|
||||
case GFX_USERFONT_WOFF2:
|
||||
return aLength * 3;
|
||||
default:
|
||||
return aLength;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t GuessSanitizedFontSize(const uint8_t* aData, size_t aLength) {
|
||||
gfxUserFontType fontType =
|
||||
gfxFontUtils::DetermineFontDataType(aData, aLength);
|
||||
return GuessSanitizedFontSize(aLength, fontType);
|
||||
}
|
||||
|
||||
private:
|
||||
bool mCheckOTLTables;
|
||||
bool mCheckVariationTables;
|
||||
bool mKeepColorBitmaps;
|
||||
};
|
||||
|
||||
#endif /* GFX_OTS_UTILS_H */
|
|
@ -17,7 +17,9 @@
|
|||
#include "gfxPlatformFontList.h"
|
||||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "mozilla/PostTraversalTask.h"
|
||||
#include "gfxOTSUtils.h"
|
||||
|
||||
#include "opentype-sanitiser.h"
|
||||
#include "ots-memory-stream.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
@ -33,6 +35,69 @@ mozilla::LogModule* gfxUserFontSet::GetUserFontsLog() {
|
|||
|
||||
static uint64_t sFontSetGeneration = 0;
|
||||
|
||||
// Based on ots::ExpandingMemoryStream from ots-memory-stream.h,
|
||||
// adapted to use Mozilla allocators and to allow the final
|
||||
// memory buffer to be adopted by the client.
|
||||
class ExpandingMemoryStream : public ots::OTSStream {
|
||||
public:
|
||||
ExpandingMemoryStream(size_t initial, size_t limit)
|
||||
: mLength(initial), mLimit(limit), mOff(0) {
|
||||
mPtr = moz_xmalloc(mLength);
|
||||
}
|
||||
|
||||
~ExpandingMemoryStream() { free(mPtr); }
|
||||
|
||||
// Return the buffer, resized to fit its contents (as it may have been
|
||||
// over-allocated during growth), and give up ownership of it so the
|
||||
// caller becomes responsible to call free() when finished with it.
|
||||
void* forget() {
|
||||
void* p = moz_xrealloc(mPtr, mOff);
|
||||
mPtr = nullptr;
|
||||
return p;
|
||||
}
|
||||
|
||||
bool WriteRaw(const void* data, size_t length) override {
|
||||
if ((mOff + length > mLength) ||
|
||||
(mLength > std::numeric_limits<size_t>::max() - mOff)) {
|
||||
if (mLength == mLimit) {
|
||||
return false;
|
||||
}
|
||||
size_t newLength = (mLength + 1) * 2;
|
||||
if (newLength < mLength) {
|
||||
return false;
|
||||
}
|
||||
if (newLength > mLimit) {
|
||||
newLength = mLimit;
|
||||
}
|
||||
mPtr = moz_xrealloc(mPtr, newLength);
|
||||
mLength = newLength;
|
||||
return WriteRaw(data, length);
|
||||
}
|
||||
std::memcpy(static_cast<char*>(mPtr) + mOff, data, length);
|
||||
mOff += length;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Seek(off_t position) override {
|
||||
if (position < 0) {
|
||||
return false;
|
||||
}
|
||||
if (static_cast<size_t>(position) > mLength) {
|
||||
return false;
|
||||
}
|
||||
mOff = position;
|
||||
return true;
|
||||
}
|
||||
|
||||
off_t Tell() const override { return mOff; }
|
||||
|
||||
private:
|
||||
void* mPtr;
|
||||
size_t mLength;
|
||||
const size_t mLimit;
|
||||
off_t mOff;
|
||||
};
|
||||
|
||||
gfxUserFontEntry::gfxUserFontEntry(
|
||||
gfxUserFontSet* aFontSet, const nsTArray<gfxFontFaceSrc>& aFontFaceSrcList,
|
||||
WeightRange aWeight, StretchRange aStretch, SlantStyleRange aStyle,
|
||||
|
@ -115,12 +180,49 @@ gfxFont* gfxUserFontEntry::CreateFontInstance(const gfxFontStyle* aFontStyle) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
class MOZ_STACK_CLASS gfxOTSMessageContext : public gfxOTSContext {
|
||||
class MOZ_STACK_CLASS gfxOTSContext : public ots::OTSContext {
|
||||
public:
|
||||
virtual ~gfxOTSMessageContext() {
|
||||
gfxOTSContext() {
|
||||
// Whether to apply OTS validation to OpenType Layout tables
|
||||
mCheckOTLTables = StaticPrefs::gfx_downloadable_fonts_otl_validation();
|
||||
// Whether to preserve Variation tables in downloaded fonts
|
||||
mCheckVariationTables =
|
||||
StaticPrefs::gfx_downloadable_fonts_validate_variation_tables();
|
||||
// Whether to preserve color bitmap glyphs
|
||||
mKeepColorBitmaps =
|
||||
StaticPrefs::gfx_downloadable_fonts_keep_color_bitmaps();
|
||||
}
|
||||
|
||||
virtual ~gfxOTSContext() {
|
||||
MOZ_ASSERT(mMessages.IsEmpty(), "should have called TakeMessages");
|
||||
}
|
||||
|
||||
virtual ots::TableAction GetTableAction(uint32_t aTag) override {
|
||||
// Preserve Graphite, color glyph and SVG tables,
|
||||
// and possibly OTL and Variation tables (depending on prefs)
|
||||
if ((!mCheckOTLTables && (aTag == TRUETYPE_TAG('G', 'D', 'E', 'F') ||
|
||||
aTag == TRUETYPE_TAG('G', 'P', 'O', 'S') ||
|
||||
aTag == TRUETYPE_TAG('G', 'S', 'U', 'B'))) ||
|
||||
(!mCheckVariationTables &&
|
||||
(aTag == TRUETYPE_TAG('a', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('c', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('f', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('g', 'v', 'a', 'r') ||
|
||||
aTag == TRUETYPE_TAG('H', 'V', 'A', 'R') ||
|
||||
aTag == TRUETYPE_TAG('M', 'V', 'A', 'R') ||
|
||||
aTag == TRUETYPE_TAG('S', 'T', 'A', 'T') ||
|
||||
aTag == TRUETYPE_TAG('V', 'V', 'A', 'R'))) ||
|
||||
aTag == TRUETYPE_TAG('S', 'V', 'G', ' ') ||
|
||||
aTag == TRUETYPE_TAG('C', 'O', 'L', 'R') ||
|
||||
aTag == TRUETYPE_TAG('C', 'P', 'A', 'L') ||
|
||||
(mKeepColorBitmaps && (aTag == TRUETYPE_TAG('C', 'B', 'D', 'T') ||
|
||||
aTag == TRUETYPE_TAG('C', 'B', 'L', 'C'))) ||
|
||||
false) {
|
||||
return ots::TABLE_ACTION_PASSTHRU;
|
||||
}
|
||||
return ots::TABLE_ACTION_DEFAULT;
|
||||
}
|
||||
|
||||
virtual void Message(int level, const char* format,
|
||||
...) MSGFUNC_FMT_ATTR override {
|
||||
va_list va;
|
||||
|
@ -157,6 +259,9 @@ class MOZ_STACK_CLASS gfxOTSMessageContext : public gfxOTSContext {
|
|||
private:
|
||||
nsTHashtable<nsCStringHashKey> mWarningsIssued;
|
||||
nsTArray<gfxUserFontEntry::OTSMessage> mMessages;
|
||||
bool mCheckOTLTables;
|
||||
bool mCheckVariationTables;
|
||||
bool mKeepColorBitmaps;
|
||||
};
|
||||
|
||||
// Call the OTS library to sanitize an sfnt before attempting to use it.
|
||||
|
@ -167,15 +272,22 @@ const uint8_t* gfxUserFontEntry::SanitizeOpenTypeData(
|
|||
aFontType = gfxFontUtils::DetermineFontDataType(aData, aLength);
|
||||
Telemetry::Accumulate(Telemetry::WEBFONT_FONTTYPE, uint32_t(aFontType));
|
||||
|
||||
size_t lengthHint = gfxOTSContext::GuessSanitizedFontSize(aLength, aFontType);
|
||||
if (!lengthHint) {
|
||||
if (aFontType == GFX_USERFONT_UNKNOWN) {
|
||||
aSaneLength = 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
gfxOTSExpandingMemoryStream output(lengthHint);
|
||||
uint32_t lengthHint = aLength;
|
||||
if (aFontType == GFX_USERFONT_WOFF) {
|
||||
lengthHint *= 2;
|
||||
} else if (aFontType == GFX_USERFONT_WOFF2) {
|
||||
lengthHint *= 3;
|
||||
}
|
||||
|
||||
gfxOTSMessageContext otsContext;
|
||||
// limit output/expansion to 256MB
|
||||
ExpandingMemoryStream output(lengthHint, 1024 * 1024 * 256);
|
||||
|
||||
gfxOTSContext otsContext;
|
||||
if (!otsContext.Process(&output, aData, aLength, aMessages)) {
|
||||
// Failed to decode/sanitize the font, so discard it.
|
||||
aSaneLength = 0;
|
||||
|
|
|
@ -181,11 +181,11 @@ class gfxUserFontFamily : public gfxFontFamily {
|
|||
};
|
||||
|
||||
class gfxUserFontEntry;
|
||||
class gfxOTSMessageContext;
|
||||
class gfxOTSContext;
|
||||
|
||||
class gfxUserFontSet {
|
||||
friend class gfxUserFontEntry;
|
||||
friend class gfxOTSMessageContext;
|
||||
friend class gfxOTSContext;
|
||||
|
||||
public:
|
||||
typedef mozilla::FontStretch FontStretch;
|
||||
|
@ -531,7 +531,7 @@ class gfxUserFontEntry : public gfxFontEntry {
|
|||
friend class gfxUserFontSet;
|
||||
friend class nsUserFontSet;
|
||||
friend class nsFontFaceLoader;
|
||||
friend class gfxOTSMessageContext;
|
||||
friend class gfxOTSContext;
|
||||
|
||||
public:
|
||||
enum UserFontLoadState {
|
||||
|
|
|
@ -44,7 +44,6 @@ EXPORTS += [
|
|||
'gfxLineSegment.h',
|
||||
'gfxMathTable.h',
|
||||
'gfxMatrix.h',
|
||||
'gfxOTSUtils.h',
|
||||
'gfxPattern.h',
|
||||
'gfxPlatform.h',
|
||||
'gfxPlatformFontList.h',
|
||||
|
|
|
@ -652,18 +652,12 @@ struct Vec<uint8_t> final {
|
|||
inner.length = 0;
|
||||
}
|
||||
|
||||
uint8_t* Data() { return inner.data; }
|
||||
|
||||
size_t Length() { return inner.length; }
|
||||
|
||||
Range<uint8_t> GetRange() { return Range<uint8_t>(Data(), Length()); }
|
||||
|
||||
void PushBytes(Range<uint8_t> aBytes) {
|
||||
wr_vec_u8_push_bytes(&inner, RangeToByteSlice(aBytes));
|
||||
}
|
||||
|
||||
void Reserve(size_t aLength) { wr_vec_u8_reserve(&inner, aLength); }
|
||||
|
||||
~Vec() {
|
||||
if (inner.data) {
|
||||
wr_vec_u8_free(inner);
|
||||
|
|
|
@ -269,18 +269,11 @@ impl WrVecU8 {
|
|||
w
|
||||
}
|
||||
|
||||
fn reserve(&mut self, len: usize) {
|
||||
let mut vec = self.flush_into_vec();
|
||||
vec.reserve(len);
|
||||
*self = Self::from_vec(vec);
|
||||
}
|
||||
|
||||
fn push_bytes(&mut self, bytes: &[u8]) {
|
||||
let mut vec = self.flush_into_vec();
|
||||
vec.extend_from_slice(bytes);
|
||||
*self = Self::from_vec(vec);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -288,11 +281,6 @@ pub extern "C" fn wr_vec_u8_push_bytes(v: &mut WrVecU8, bytes: ByteSlice) {
|
|||
v.push_bytes(bytes.as_slice());
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_vec_u8_reserve(v: &mut WrVecU8, len: usize) {
|
||||
v.reserve(len);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_vec_u8_free(v: WrVecU8) {
|
||||
v.to_vec();
|
||||
|
|
Загрузка…
Ссылка в новой задаче