зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1791017, bug 1740526) for causing reftest failures on colrv1-01.html. CLOSED TREE
Backed out changeset 3ca91d34f126 (bug 1740526) Backed out changeset df138324dd6b (bug 1791017)
This commit is contained in:
Родитель
c71dcf9398
Коммит
3addcb6dd7
|
@ -2,7 +2,7 @@ This is the Sanitiser for OpenType project, from http://code.google.com/p/ots/.
|
|||
|
||||
Our reference repository is https://github.com/khaledhosny/ots/.
|
||||
|
||||
Current revision: 35643038c4904538aa74c2c691f8d792efdbd6c0 (9.0.0)
|
||||
Current revision: dd99d9a451d070048b73b7c385c19c8dfb28c24d (8.2.2)
|
||||
|
||||
Upstream files included: LICENSE, src/, include/, tests/*.cc
|
||||
|
||||
|
|
1092
gfx/ots/src/colr.cc
1092
gfx/ots/src/colr.cc
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,31 +0,0 @@
|
|||
// Copyright (c) 2022 The OTS Authors. 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_COLR_H_
|
||||
#define OTS_COLR_H_
|
||||
|
||||
#include "ots.h"
|
||||
|
||||
namespace ots {
|
||||
|
||||
class OpenTypeCOLR : public Table {
|
||||
public:
|
||||
explicit OpenTypeCOLR(Font *font, uint32_t tag)
|
||||
: Table(font, tag, tag),
|
||||
m_data(NULL),
|
||||
m_length(0) {
|
||||
}
|
||||
|
||||
bool Parse(const uint8_t *data, size_t length);
|
||||
bool Serialize(OTSStream *out);
|
||||
|
||||
private:
|
||||
const uint8_t *m_data;
|
||||
size_t m_length;
|
||||
};
|
||||
|
||||
} // namespace ots
|
||||
|
||||
#endif // OTS_COLR_H_
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
// Copyright (c) 2022 The OTS 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 "cpal.h"
|
||||
#include "name.h"
|
||||
|
||||
// CPAL - Color Palette Table
|
||||
// http://www.microsoft.com/typography/otspec/cpal.htm
|
||||
|
||||
#define TABLE_NAME "CPAL"
|
||||
|
||||
namespace {
|
||||
|
||||
// Caller has sized the colorRecords array, so we know how much to try and read.
|
||||
bool ParseColorRecordsArray(const ots::Font* font,
|
||||
const uint8_t* data, size_t length,
|
||||
std::vector<uint32_t>* colorRecords)
|
||||
{
|
||||
ots::Buffer subtable(data, length);
|
||||
|
||||
for (auto& color : *colorRecords) {
|
||||
if (!subtable.ReadU32(&color)) {
|
||||
return OTS_FAILURE_MSG("Failed to read color record");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Caller has sized the paletteTypes array, so we know how much to try and read.
|
||||
bool ParsePaletteTypesArray(const ots::Font* font,
|
||||
const uint8_t* data, size_t length,
|
||||
std::vector<uint32_t>* paletteTypes)
|
||||
{
|
||||
ots::Buffer subtable(data, length);
|
||||
|
||||
constexpr uint32_t USABLE_WITH_LIGHT_BACKGROUND = 0x0001;
|
||||
constexpr uint32_t USABLE_WITH_DARK_BACKGROUND = 0x0002;
|
||||
constexpr uint32_t RESERVED = ~(USABLE_WITH_LIGHT_BACKGROUND | USABLE_WITH_DARK_BACKGROUND);
|
||||
|
||||
for (auto& type : *paletteTypes) {
|
||||
if (!subtable.ReadU32(&type)) {
|
||||
return OTS_FAILURE_MSG("Failed to read palette type");
|
||||
}
|
||||
if (type & RESERVED) {
|
||||
// Should we treat this as failure? For now, just a warning; seems unlikely
|
||||
// to be dangerous.
|
||||
OTS_WARNING("Invalid (reserved) palette type flags %08x", type);
|
||||
type &= ~RESERVED;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Caller has sized the labels array, so we know how much to try and read.
|
||||
bool ParseLabelsArray(const ots::Font* font,
|
||||
const uint8_t* data, size_t length,
|
||||
std::vector<uint16_t>* labels,
|
||||
const char* labelType)
|
||||
{
|
||||
ots::Buffer subtable(data, length);
|
||||
|
||||
auto* name = static_cast<ots::OpenTypeNAME*>(font->GetTypedTable(OTS_TAG_NAME));
|
||||
if (!name) {
|
||||
return OTS_FAILURE_MSG("Required name table missing");
|
||||
}
|
||||
|
||||
for (auto& nameID : *labels) {
|
||||
if (!subtable.ReadU16(&nameID)) {
|
||||
return OTS_FAILURE_MSG("Failed to read %s label ID", labelType);
|
||||
}
|
||||
if (nameID != 0xffff) {
|
||||
if (!name->IsValidNameId(nameID)) {
|
||||
OTS_WARNING("Label ID %u for %s missing from name table", nameID, labelType);
|
||||
nameID = 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace ots {
|
||||
|
||||
bool OpenTypeCPAL::Parse(const uint8_t *data, size_t length) {
|
||||
Font *font = GetFont();
|
||||
Buffer table(data, length);
|
||||
|
||||
// Header fields common to versions 0 and 1. These are recomputed
|
||||
// from the array sizes during serialization.
|
||||
uint16_t numPalettes;
|
||||
uint16_t numColorRecords;
|
||||
uint32_t colorRecordsArrayOffset;
|
||||
|
||||
if (!table.ReadU16(&this->version) ||
|
||||
!table.ReadU16(&this->num_palette_entries) ||
|
||||
!table.ReadU16(&numPalettes) ||
|
||||
!table.ReadU16(&numColorRecords) ||
|
||||
!table.ReadU32(&colorRecordsArrayOffset)) {
|
||||
return Error("Failed to read CPAL table header");
|
||||
}
|
||||
|
||||
if (this->version > 1) {
|
||||
return Error("Unknown CPAL table version %u", this->version);
|
||||
}
|
||||
|
||||
if (!this->num_palette_entries || !numPalettes || !numColorRecords) {
|
||||
return Error("Empty CPAL is not valid");
|
||||
}
|
||||
|
||||
if (this->num_palette_entries > numColorRecords) {
|
||||
return Error("Not enough color records for a complete palette");
|
||||
}
|
||||
|
||||
uint32_t headerSize = 4 * sizeof(uint16_t) + sizeof(uint32_t) +
|
||||
numPalettes * sizeof(uint16_t);
|
||||
|
||||
// uint16_t colorRecordIndices[numPalettes]
|
||||
this->colorRecordIndices.resize(numPalettes);
|
||||
for (auto& colorRecordIndex : this->colorRecordIndices) {
|
||||
if (!table.ReadU16(&colorRecordIndex)) {
|
||||
return Error("Failed to read color record index");
|
||||
}
|
||||
if (colorRecordIndex > numColorRecords - this->num_palette_entries) {
|
||||
return Error("Palette overflows color records array");
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t paletteTypesArrayOffset = 0;
|
||||
uint32_t paletteLabelsArrayOffset = 0;
|
||||
uint32_t paletteEntryLabelsArrayOffset = 0;
|
||||
if (this->version == 1) {
|
||||
if (!table.ReadU32(&paletteTypesArrayOffset) ||
|
||||
!table.ReadU32(&paletteLabelsArrayOffset) ||
|
||||
!table.ReadU32(&paletteEntryLabelsArrayOffset)) {
|
||||
return Error("Failed to read CPAL v.1 table header");
|
||||
}
|
||||
headerSize += 3 * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
// The following arrays may occur in any order, as they're independently referenced
|
||||
// by offsets in the header.
|
||||
|
||||
if (colorRecordsArrayOffset < headerSize || colorRecordsArrayOffset >= length) {
|
||||
return Error("Bad color records array offset in table header");
|
||||
}
|
||||
this->colorRecords.resize(numColorRecords);
|
||||
if (!ParseColorRecordsArray(font, data + colorRecordsArrayOffset, length - colorRecordsArrayOffset,
|
||||
&this->colorRecords)) {
|
||||
return Error("Failed to parse color records array");
|
||||
}
|
||||
|
||||
if (paletteTypesArrayOffset) {
|
||||
if (paletteTypesArrayOffset < headerSize || paletteTypesArrayOffset >= length) {
|
||||
return Error("Bad palette types array offset in table header");
|
||||
}
|
||||
this->paletteTypes.resize(numPalettes);
|
||||
if (!ParsePaletteTypesArray(font, data + paletteTypesArrayOffset, length - paletteTypesArrayOffset,
|
||||
&this->paletteTypes)) {
|
||||
return Error("Failed to parse palette types array");
|
||||
}
|
||||
}
|
||||
|
||||
if (paletteLabelsArrayOffset) {
|
||||
if (paletteLabelsArrayOffset < headerSize || paletteLabelsArrayOffset >= length) {
|
||||
return Error("Bad palette labels array offset in table header");
|
||||
}
|
||||
this->paletteLabels.resize(numPalettes);
|
||||
if (!ParseLabelsArray(font, data + paletteLabelsArrayOffset, length - paletteLabelsArrayOffset,
|
||||
&this->paletteLabels, "palette")) {
|
||||
return Error("Failed to parse palette labels array");
|
||||
}
|
||||
}
|
||||
|
||||
if (paletteEntryLabelsArrayOffset) {
|
||||
if (paletteEntryLabelsArrayOffset < headerSize || paletteEntryLabelsArrayOffset >= length) {
|
||||
return Error("Bad palette entry labels array offset in table header");
|
||||
}
|
||||
this->paletteEntryLabels.resize(this->num_palette_entries);
|
||||
if (!ParseLabelsArray(font, data + paletteEntryLabelsArrayOffset, length - paletteEntryLabelsArrayOffset,
|
||||
&this->paletteEntryLabels, "palette entry")) {
|
||||
return Error("Failed to parse palette entry labels array");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenTypeCPAL::Serialize(OTSStream *out) {
|
||||
uint16_t numPalettes = this->colorRecordIndices.size();
|
||||
uint16_t numColorRecords = this->colorRecords.size();
|
||||
|
||||
off_t start = out->Tell();
|
||||
|
||||
size_t colorRecordsArrayOffset = 4 * sizeof(uint16_t) + sizeof(uint32_t) +
|
||||
numPalettes * sizeof(uint16_t);
|
||||
if (this->version == 1) {
|
||||
colorRecordsArrayOffset += 3 * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
size_t totalLen = colorRecordsArrayOffset + numColorRecords * sizeof(uint32_t);
|
||||
|
||||
if (!out->WriteU16(this->version) ||
|
||||
!out->WriteU16(this->num_palette_entries) ||
|
||||
!out->WriteU16(numPalettes) ||
|
||||
!out->WriteU16(numColorRecords) ||
|
||||
!out->WriteU32(colorRecordsArrayOffset)) {
|
||||
return Error("Failed to write CPAL header");
|
||||
}
|
||||
|
||||
for (auto i : this->colorRecordIndices) {
|
||||
if (!out->WriteU16(i)) {
|
||||
return Error("Failed to write color record indices");
|
||||
}
|
||||
}
|
||||
|
||||
if (this->version == 1) {
|
||||
size_t paletteTypesArrayOffset = 0;
|
||||
if (!this->paletteTypes.empty()) {
|
||||
assert(paletteTypes.size() == numPalettes);
|
||||
paletteTypesArrayOffset = totalLen;
|
||||
totalLen += numPalettes * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
size_t paletteLabelsArrayOffset = 0;
|
||||
if (!this->paletteLabels.empty()) {
|
||||
assert(paletteLabels.size() == numPalettes);
|
||||
paletteLabelsArrayOffset = totalLen;
|
||||
totalLen += numPalettes * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
size_t paletteEntryLabelsArrayOffset = 0;
|
||||
if (!this->paletteEntryLabels.empty()) {
|
||||
assert(paletteEntryLabels.size() == this->num_palette_entries);
|
||||
paletteEntryLabelsArrayOffset = totalLen;
|
||||
totalLen += this->num_palette_entries * sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if (!out->WriteU32(paletteTypesArrayOffset) ||
|
||||
!out->WriteU32(paletteLabelsArrayOffset) ||
|
||||
!out->WriteU32(paletteEntryLabelsArrayOffset)) {
|
||||
return Error("Failed to write CPAL v.1 header");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i : this->colorRecords) {
|
||||
if (!out->WriteU32(i)) {
|
||||
return Error("Failed to write color records");
|
||||
}
|
||||
}
|
||||
|
||||
if (this->version == 1) {
|
||||
for (auto i : this->paletteTypes) {
|
||||
if (!out->WriteU32(i)) {
|
||||
return Error("Failed to write palette types");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i : this->paletteLabels) {
|
||||
if (!out->WriteU16(i)) {
|
||||
return Error("Failed to write palette labels");
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i : this->paletteEntryLabels) {
|
||||
if (!out->WriteU16(i)) {
|
||||
return Error("Failed to write palette entry labels");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(size_t(out->Tell() - start) == totalLen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace ots
|
||||
|
||||
#undef TABLE_NAME
|
|
@ -1,40 +0,0 @@
|
|||
// Copyright (c) 2022 The OTS Authors. 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_CPAL_H_
|
||||
#define OTS_CPAL_H_
|
||||
|
||||
#include "ots.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace ots {
|
||||
|
||||
class OpenTypeCPAL : public Table {
|
||||
public:
|
||||
explicit OpenTypeCPAL(Font *font, uint32_t tag)
|
||||
: Table(font, tag, tag) {
|
||||
}
|
||||
|
||||
bool Parse(const uint8_t *data, size_t length);
|
||||
bool Serialize(OTSStream *out);
|
||||
|
||||
// This is public so that COLR can access it.
|
||||
uint16_t num_palette_entries;
|
||||
|
||||
private:
|
||||
uint16_t version;
|
||||
|
||||
std::vector<uint16_t> colorRecordIndices;
|
||||
std::vector<uint32_t> colorRecords;
|
||||
|
||||
// Arrays present only if version == 1.
|
||||
std::vector<uint32_t> paletteTypes;
|
||||
std::vector<uint16_t> paletteLabels;
|
||||
std::vector<uint16_t> paletteEntryLabels;
|
||||
};
|
||||
|
||||
} // namespace ots
|
||||
|
||||
#endif // OTS_CPAL_H_
|
|
@ -19,8 +19,6 @@ UNIFIED_SOURCES += [
|
|||
'cff.cc',
|
||||
'cff_charstring.cc',
|
||||
'cmap.cc',
|
||||
'colr.cc',
|
||||
'cpal.cc',
|
||||
'cvar.cc',
|
||||
'cvt.cc',
|
||||
'feat.cc',
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#include "avar.h"
|
||||
#include "cff.h"
|
||||
#include "cmap.h"
|
||||
#include "colr.h"
|
||||
#include "cpal.h"
|
||||
#include "cvar.h"
|
||||
#include "cvt.h"
|
||||
#include "fpgm.h"
|
||||
|
@ -146,11 +144,6 @@ const struct {
|
|||
{ OTS_TAG_STAT, false },
|
||||
{ OTS_TAG_VVAR, false },
|
||||
{ OTS_TAG_CFF2, false },
|
||||
// Color font tables.
|
||||
// We need to parse CPAL before COLR so that the number of palette entries
|
||||
// is known; and these tables follow fvar because COLR may use variations.
|
||||
{ OTS_TAG_CPAL, false },
|
||||
{ OTS_TAG_COLR, false },
|
||||
// We need to parse GDEF table in advance of parsing GSUB/GPOS tables
|
||||
// because they could refer GDEF table.
|
||||
{ OTS_TAG_GDEF, false },
|
||||
|
@ -891,8 +884,6 @@ bool Font::ParseTable(const TableEntry& table_entry, const uint8_t* data,
|
|||
case OTS_TAG_CFF: table = new OpenTypeCFF(this, tag); break;
|
||||
case OTS_TAG_CFF2: table = new OpenTypeCFF2(this, tag); break;
|
||||
case OTS_TAG_CMAP: table = new OpenTypeCMAP(this, tag); break;
|
||||
case OTS_TAG_COLR: table = new OpenTypeCOLR(this, tag); break;
|
||||
case OTS_TAG_CPAL: table = new OpenTypeCPAL(this, tag); break;
|
||||
case OTS_TAG_CVAR: table = new OpenTypeCVAR(this, tag); break;
|
||||
case OTS_TAG_CVT: table = new OpenTypeCVT(this, tag); break;
|
||||
case OTS_TAG_FPGM: table = new OpenTypeFPGM(this, tag); break;
|
||||
|
|
|
@ -190,8 +190,6 @@ bool CheckTag(uint32_t tag_value);
|
|||
#define OTS_TAG_CFF OTS_TAG('C','F','F',' ')
|
||||
#define OTS_TAG_CFF2 OTS_TAG('C','F','F','2')
|
||||
#define OTS_TAG_CMAP OTS_TAG('c','m','a','p')
|
||||
#define OTS_TAG_COLR OTS_TAG('C','O','L','R')
|
||||
#define OTS_TAG_CPAL OTS_TAG('C','P','A','L')
|
||||
#define OTS_TAG_CVT OTS_TAG('c','v','t',' ')
|
||||
#define OTS_TAG_FEAT OTS_TAG('F','e','a','t')
|
||||
#define OTS_TAG_FPGM OTS_TAG('f','p','g','m')
|
||||
|
|
|
@ -67,24 +67,14 @@ ParseVariationDataSubtable(const ots::Font* font, const uint8_t* data, const siz
|
|||
ots::Buffer subtable(data, length);
|
||||
|
||||
uint16_t itemCount;
|
||||
uint16_t wordDeltaCount;
|
||||
|
||||
const uint16_t LONG_WORDS = 0x8000u;
|
||||
const uint16_t WORD_DELTA_COUNT_MASK = 0x7FFF;
|
||||
uint16_t shortDeltaCount;
|
||||
|
||||
if (!subtable.ReadU16(&itemCount) ||
|
||||
!subtable.ReadU16(&wordDeltaCount) ||
|
||||
!subtable.ReadU16(&shortDeltaCount) ||
|
||||
!subtable.ReadU16(regionIndexCount)) {
|
||||
return OTS_FAILURE_MSG("Failed to read variation data subtable header");
|
||||
}
|
||||
|
||||
size_t valueSize = (wordDeltaCount & LONG_WORDS) ? 2 : 1;
|
||||
wordDeltaCount &= WORD_DELTA_COUNT_MASK;
|
||||
|
||||
if (wordDeltaCount > *regionIndexCount) {
|
||||
return OTS_FAILURE_MSG("Bad word delta count");
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < *regionIndexCount; i++) {
|
||||
uint16_t regionIndex;
|
||||
if (!subtable.ReadU16(®ionIndex) || regionIndex >= regionCount) {
|
||||
|
@ -92,7 +82,7 @@ ParseVariationDataSubtable(const ots::Font* font, const uint8_t* data, const siz
|
|||
}
|
||||
}
|
||||
|
||||
if (!subtable.Skip(valueSize * size_t(itemCount) * (size_t(wordDeltaCount) + size_t(*regionIndexCount)))) {
|
||||
if (!subtable.Skip(size_t(itemCount) * (size_t(shortDeltaCount) + size_t(*regionIndexCount)))) {
|
||||
return OTS_FAILURE_MSG("Failed to read delta data");
|
||||
}
|
||||
|
||||
|
|
|
@ -105,14 +105,16 @@ class MOZ_STACK_CLASS gfxOTSContext : public ots::OTSContext {
|
|||
}
|
||||
|
||||
virtual ots::TableAction GetTableAction(uint32_t aTag) override {
|
||||
// Preserve Graphite and SVG tables,
|
||||
// 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')))) {
|
||||
return ots::TABLE_ACTION_PASSTHRU;
|
||||
}
|
||||
if (aTag == TRUETYPE_TAG('S', 'V', 'G', ' ')) {
|
||||
if (aTag == TRUETYPE_TAG('S', 'V', 'G', ' ') ||
|
||||
aTag == TRUETYPE_TAG('C', 'O', 'L', 'R') ||
|
||||
aTag == TRUETYPE_TAG('C', 'P', 'A', 'L')) {
|
||||
return ots::TABLE_ACTION_PASSTHRU;
|
||||
}
|
||||
if (mKeepColorBitmaps && (aTag == TRUETYPE_TAG('C', 'B', 'D', 'T') ||
|
||||
|
|
Двоичные данные
layout/reftests/font-face/CAhem.ttf
Двоичные данные
layout/reftests/font-face/CAhem.ttf
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче