bug 631479 (part 3) - allow graphite tables to be passed through OTS for downloadable fonts. r=jdaggett

This commit is contained in:
Jonathan Kew 2011-12-09 22:32:29 +00:00
Родитель 1acaf9ad30
Коммит 5861e88308
7 изменённых файлов: 255 добавлений и 4 удалений

Просмотреть файл

@ -181,8 +181,10 @@ class OTSStream {
// partial output may have been written.
// input: the OpenType file
// length: the size, in bytes, of |input|
// preserve_graphite_tables: whether to preserve Graphite Layout tables
// -----------------------------------------------------------------------------
bool Process(OTSStream *output, const uint8_t *input, size_t length);
bool Process(OTSStream *output, const uint8_t *input, size_t length,
bool preserve_graphite_tables = false);
// Force to disable debug output even when the library is compiled with
// -DOTS_DEBUG.

Просмотреть файл

@ -69,6 +69,7 @@ CPPSRCS = \
gdef.cc \
gpos.cc \
gsub.cc \
graphite.cc \
$(NULL)
EXPORTS = \

181
gfx/ots/src/graphite.cc Normal file
Просмотреть файл

@ -0,0 +1,181 @@
// Copyright (c) 2010 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.
#include "graphite.h"
// Support for preserving (NOT sanitizing) the Graphite tables
namespace ots {
// 'Silf'
bool ots_silf_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
Buffer table(data, length);
OpenTypeSILF *silf = new OpenTypeSILF;
file->silf = silf;
if (!table.Skip(length)) {
return OTS_FAILURE();
}
silf->data = data;
silf->length = length;
return true;
}
bool ots_silf_should_serialise(OpenTypeFile *file) {
return file->preserve_graphite && file->silf;
}
bool ots_silf_serialise(OTSStream *out, OpenTypeFile *file) {
const OpenTypeSILF *silf = file->silf;
if (!out->Write(silf->data, silf->length)) {
return OTS_FAILURE();
}
return true;
}
void ots_silf_free(OpenTypeFile *file) {
delete file->silf;
}
// 'Sill'
bool ots_sill_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
Buffer table(data, length);
OpenTypeSILL *sill = new OpenTypeSILL;
file->sill = sill;
if (!table.Skip(length)) {
return OTS_FAILURE();
}
sill->data = data;
sill->length = length;
return true;
}
bool ots_sill_should_serialise(OpenTypeFile *file) {
return file->preserve_graphite && file->sill;
}
bool ots_sill_serialise(OTSStream *out, OpenTypeFile *file) {
const OpenTypeSILL *sill = file->sill;
if (!out->Write(sill->data, sill->length)) {
return OTS_FAILURE();
}
return true;
}
void ots_sill_free(OpenTypeFile *file) {
delete file->sill;
}
// 'Gloc'
bool ots_gloc_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
Buffer table(data, length);
OpenTypeGLOC *gloc = new OpenTypeGLOC;
file->gloc = gloc;
if (!table.Skip(length)) {
return OTS_FAILURE();
}
gloc->data = data;
gloc->length = length;
return true;
}
bool ots_gloc_should_serialise(OpenTypeFile *file) {
return file->preserve_graphite && file->gloc;
}
bool ots_gloc_serialise(OTSStream *out, OpenTypeFile *file) {
const OpenTypeGLOC *gloc = file->gloc;
if (!out->Write(gloc->data, gloc->length)) {
return OTS_FAILURE();
}
return true;
}
void ots_gloc_free(OpenTypeFile *file) {
delete file->gloc;
}
// 'Glat'
bool ots_glat_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
Buffer table(data, length);
OpenTypeGLAT *glat = new OpenTypeGLAT;
file->glat = glat;
if (!table.Skip(length)) {
return OTS_FAILURE();
}
glat->data = data;
glat->length = length;
return true;
}
bool ots_glat_should_serialise(OpenTypeFile *file) {
return file->preserve_graphite && file->glat;
}
bool ots_glat_serialise(OTSStream *out, OpenTypeFile *file) {
const OpenTypeGLAT *glat = file->glat;
if (!out->Write(glat->data, glat->length)) {
return OTS_FAILURE();
}
return true;
}
void ots_glat_free(OpenTypeFile *file) {
delete file->glat;
}
// 'Feat'
bool ots_feat_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
Buffer table(data, length);
OpenTypeFEAT *feat = new OpenTypeFEAT;
file->feat = feat;
if (!table.Skip(length)) {
return OTS_FAILURE();
}
feat->data = data;
feat->length = length;
return true;
}
bool ots_feat_should_serialise(OpenTypeFile *file) {
return file->preserve_graphite && file->feat;
}
bool ots_feat_serialise(OTSStream *out, OpenTypeFile *file) {
const OpenTypeFEAT *feat = file->feat;
if (!out->Write(feat->data, feat->length)) {
return OTS_FAILURE();
}
return true;
}
void ots_feat_free(OpenTypeFile *file) {
delete file->feat;
}
} // namespace ots

39
gfx/ots/src/graphite.h Normal file
Просмотреть файл

@ -0,0 +1,39 @@
// Copyright (c) 2010 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_GRAPHITE_H_
#define OTS_GRAPHITE_H_
#include "ots.h"
namespace ots {
struct OpenTypeSILF {
const uint8_t *data;
uint32_t length;
};
struct OpenTypeSILL {
const uint8_t *data;
uint32_t length;
};
struct OpenTypeGLOC {
const uint8_t *data;
uint32_t length;
};
struct OpenTypeGLAT {
const uint8_t *data;
uint32_t length;
};
struct OpenTypeFEAT {
const uint8_t *data;
uint32_t length;
};
} // namespace ots
#endif // OTS_GRAPHITE_H_

Просмотреть файл

@ -143,6 +143,17 @@ const struct {
ots::ots_vhea_should_serialise, ots::ots_vhea_free, false },
{ Tag("vmtx"), ots::ots_vmtx_parse, ots::ots_vmtx_serialise,
ots::ots_vmtx_should_serialise, ots::ots_vmtx_free, false },
// SILGraphite layout tables - not actually parsed, just copied
{ Tag("Silf"), ots::ots_silf_parse, ots::ots_silf_serialise,
ots::ots_silf_should_serialise, ots::ots_silf_free, false },
{ Tag("Sill"), ots::ots_sill_parse, ots::ots_sill_serialise,
ots::ots_sill_should_serialise, ots::ots_sill_free, false },
{ Tag("Gloc"), ots::ots_gloc_parse, ots::ots_gloc_serialise,
ots::ots_gloc_should_serialise, ots::ots_gloc_free, false },
{ Tag("Glat"), ots::ots_glat_parse, ots::ots_glat_serialise,
ots::ots_glat_should_serialise, ots::ots_glat_free, false },
{ Tag("Feat"), ots::ots_feat_parse, ots::ots_feat_serialise,
ots::ots_feat_should_serialise, ots::ots_feat_free, false },
// TODO(bashi): Support mort, base, and jstf tables.
{ 0, NULL, NULL, NULL, NULL, false },
};
@ -586,12 +597,15 @@ void DisableDebugOutput() {
g_debug_output = false;
}
bool Process(OTSStream *output, const uint8_t *data, size_t length) {
bool Process(OTSStream *output, const uint8_t *data, size_t length,
bool preserveGraphite) {
OpenTypeFile header;
if (length < 4) {
return OTS_FAILURE();
}
header.preserve_graphite = preserveGraphite;
bool result;
if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F') {
result = ProcessWOFF(&header, output, data, length);

Просмотреть файл

@ -183,7 +183,12 @@ class Buffer {
F(vdmx, VDMX) \
F(vorg, VORG) \
F(vhea, VHEA) \
F(vmtx, VMTX)
F(vmtx, VMTX) \
F(silf, SILF) \
F(sill, SILL) \
F(glat, GLAT) \
F(gloc, GLOC) \
F(feat, FEAT)
#define F(name, capname) struct OpenType##capname;
FOR_EACH_TABLE_TYPE
@ -202,6 +207,10 @@ struct OpenTypeFile {
uint16_t entry_selector;
uint16_t range_shift;
// This is used to tell the relevant parsers whether to preserve the
// Graphite layout tables (currently _without_ any checking)
bool preserve_graphite;
#define F(name, capname) OpenType##capname *name;
FOR_EACH_TABLE_TYPE
#undef F

Просмотреть файл

@ -363,7 +363,12 @@ SanitizeOpenTypeData(const PRUint8* aData, PRUint32 aLength,
// limit output/expansion to 256MB
ExpandingMemoryStream output(aIsCompressed ? aLength * 2 : aLength,
1024 * 1024 * 256);
if (ots::Process(&output, aData, aLength)) {
#ifdef MOZ_GRAPHITE
#define PRESERVE_GRAPHITE true
#else
#define PRESERVE_GRAPHITE false
#endif
if (ots::Process(&output, aData, aLength, PRESERVE_GRAPHITE)) {
aSaneLength = output.Tell();
return static_cast<PRUint8*>(output.forget());
} else {