summaryrefslogtreecommitdiffstats
path: root/gfx/ots/src/math.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/ots/src/math.cc')
-rw-r--r--gfx/ots/src/math.cc209
1 files changed, 87 insertions, 122 deletions
diff --git a/gfx/ots/src/math.cc b/gfx/ots/src/math.cc
index 36417dc29..c94e3bee3 100644
--- a/gfx/ots/src/math.cc
+++ b/gfx/ots/src/math.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Copyright (c) 2014-2017 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.
@@ -12,12 +12,7 @@
#include "maxp.h"
// MATH - The MATH Table
-// The specification is not yet public but has been submitted to the MPEG group
-// in response to the 'Call for Proposals for ISO/IEC 14496-22 "Open Font
-// Format" Color Font Technology and MATH layout support'. Meanwhile, you can
-// contact Microsoft's engineer Murray Sargent to obtain a copy.
-
-#define TABLE_NAME "MATH"
+// http://www.microsoft.com/typography/otspec/math.htm
namespace {
@@ -48,11 +43,15 @@ const unsigned kMathValueRecordSize = 2 * 2;
// PartFlags
const unsigned kGlyphPartRecordSize = 5 * 2;
+} // namespace
+
+namespace ots {
+
// Shared Table: MathValueRecord
-bool ParseMathValueRecord(const ots::Font *font,
- ots::Buffer* subtable, const uint8_t *data,
- const size_t length) {
+bool OpenTypeMATH::ParseMathValueRecord(ots::Buffer* subtable,
+ const uint8_t *data,
+ const size_t length) {
// Check the Value field.
if (!subtable->Skip(2)) {
return OTS_FAILURE();
@@ -67,7 +66,7 @@ bool ParseMathValueRecord(const ots::Font *font,
if (offset >= length) {
return OTS_FAILURE();
}
- if (!ots::ParseDeviceTable(font, data + offset, length - offset)) {
+ if (!ots::ParseDeviceTable(GetFont(), data + offset, length - offset)) {
return OTS_FAILURE();
}
}
@@ -75,8 +74,8 @@ bool ParseMathValueRecord(const ots::Font *font,
return true;
}
-bool ParseMathConstantsTable(const ots::Font *font,
- const uint8_t *data, size_t length) {
+bool OpenTypeMATH::ParseMathConstantsTable(const uint8_t *data,
+ size_t length) {
ots::Buffer subtable(data, length);
// Part 1: int16 or uint16 constants.
@@ -146,7 +145,7 @@ bool ParseMathConstantsTable(const ots::Font *font,
//
// RadicalKernAfterDegree
for (unsigned i = 0; i < static_cast<unsigned>(51); ++i) {
- if (!ParseMathValueRecord(font, &subtable, data, length)) {
+ if (!ParseMathValueRecord(&subtable, data, length)) {
return OTS_FAILURE();
}
}
@@ -160,11 +159,10 @@ bool ParseMathConstantsTable(const ots::Font *font,
return true;
}
-bool ParseMathValueRecordSequenceForGlyphs(const ots::Font *font,
- ots::Buffer* subtable,
- const uint8_t *data,
- const size_t length,
- const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseMathValueRecordSequenceForGlyphs(ots::Buffer* subtable,
+ const uint8_t *data,
+ const size_t length,
+ const uint16_t num_glyphs) {
// Check the header.
uint16_t offset_coverage = 0;
uint16_t sequence_count = 0;
@@ -183,7 +181,7 @@ bool ParseMathValueRecordSequenceForGlyphs(const ots::Font *font,
if (offset_coverage < sequence_end || offset_coverage >= length) {
return OTS_FAILURE();
}
- if (!ots::ParseCoverageTable(font, data + offset_coverage,
+ if (!ots::ParseCoverageTable(GetFont(), data + offset_coverage,
length - offset_coverage,
num_glyphs, sequence_count)) {
return OTS_FAILURE();
@@ -191,7 +189,7 @@ bool ParseMathValueRecordSequenceForGlyphs(const ots::Font *font,
// Check sequence.
for (unsigned i = 0; i < sequence_count; ++i) {
- if (!ParseMathValueRecord(font, subtable, data, length)) {
+ if (!ParseMathValueRecord(subtable, data, length)) {
return OTS_FAILURE();
}
}
@@ -199,26 +197,23 @@ bool ParseMathValueRecordSequenceForGlyphs(const ots::Font *font,
return true;
}
-bool ParseMathItalicsCorrectionInfoTable(const ots::Font *font,
- const uint8_t *data,
- size_t length,
- const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseMathItalicsCorrectionInfoTable(const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs) {
ots::Buffer subtable(data, length);
- return ParseMathValueRecordSequenceForGlyphs(font, &subtable, data, length,
+ return ParseMathValueRecordSequenceForGlyphs(&subtable, data, length,
num_glyphs);
}
-bool ParseMathTopAccentAttachmentTable(const ots::Font *font,
- const uint8_t *data,
- size_t length,
- const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseMathTopAccentAttachmentTable(const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs) {
ots::Buffer subtable(data, length);
- return ParseMathValueRecordSequenceForGlyphs(font, &subtable, data, length,
+ return ParseMathValueRecordSequenceForGlyphs(&subtable, data, length,
num_glyphs);
}
-bool ParseMathKernTable(const ots::Font *font,
- const uint8_t *data, size_t length) {
+bool OpenTypeMATH::ParseMathKernTable(const uint8_t *data, size_t length) {
ots::Buffer subtable(data, length);
// Check the Height count.
@@ -229,14 +224,14 @@ bool ParseMathKernTable(const ots::Font *font,
// Check the Correction Heights.
for (unsigned i = 0; i < height_count; ++i) {
- if (!ParseMathValueRecord(font, &subtable, data, length)) {
+ if (!ParseMathValueRecord(&subtable, data, length)) {
return OTS_FAILURE();
}
}
// Check the Kern Values.
for (unsigned i = 0; i <= height_count; ++i) {
- if (!ParseMathValueRecord(font, &subtable, data, length)) {
+ if (!ParseMathValueRecord(&subtable, data, length)) {
return OTS_FAILURE();
}
}
@@ -244,9 +239,9 @@ bool ParseMathKernTable(const ots::Font *font,
return true;
}
-bool ParseMathKernInfoTable(const ots::Font *font,
- const uint8_t *data, size_t length,
- const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseMathKernInfoTable(const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs) {
ots::Buffer subtable(data, length);
// Check the header.
@@ -267,7 +262,7 @@ bool ParseMathKernInfoTable(const ots::Font *font,
if (offset_coverage < sequence_end || offset_coverage >= length) {
return OTS_FAILURE();
}
- if (!ots::ParseCoverageTable(font, data + offset_coverage, length - offset_coverage,
+ if (!ots::ParseCoverageTable(GetFont(), data + offset_coverage, length - offset_coverage,
num_glyphs, sequence_count)) {
return OTS_FAILURE();
}
@@ -282,7 +277,7 @@ bool ParseMathKernInfoTable(const ots::Font *font,
}
if (offset_math_kern) {
if (offset_math_kern < sequence_end || offset_math_kern >= length ||
- !ParseMathKernTable(font, data + offset_math_kern,
+ !ParseMathKernTable(data + offset_math_kern,
length - offset_math_kern)) {
return OTS_FAILURE();
}
@@ -293,9 +288,9 @@ bool ParseMathKernInfoTable(const ots::Font *font,
return true;
}
-bool ParseMathGlyphInfoTable(const ots::Font *font,
- const uint8_t *data, size_t length,
- const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseMathGlyphInfoTable(const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs) {
ots::Buffer subtable(data, length);
// Check Header.
@@ -318,7 +313,7 @@ bool ParseMathGlyphInfoTable(const ots::Font *font,
if (offset_math_italics_correction_info >= length ||
offset_math_italics_correction_info < kMathGlyphInfoHeaderSize ||
!ParseMathItalicsCorrectionInfoTable(
- font, data + offset_math_italics_correction_info,
+ data + offset_math_italics_correction_info,
length - offset_math_italics_correction_info,
num_glyphs)) {
return OTS_FAILURE();
@@ -327,7 +322,7 @@ bool ParseMathGlyphInfoTable(const ots::Font *font,
if (offset_math_top_accent_attachment) {
if (offset_math_top_accent_attachment >= length ||
offset_math_top_accent_attachment < kMathGlyphInfoHeaderSize ||
- !ParseMathTopAccentAttachmentTable(font, data +
+ !ParseMathTopAccentAttachmentTable(data +
offset_math_top_accent_attachment,
length -
offset_math_top_accent_attachment,
@@ -338,7 +333,7 @@ bool ParseMathGlyphInfoTable(const ots::Font *font,
if (offset_extended_shaped_coverage) {
if (offset_extended_shaped_coverage >= length ||
offset_extended_shaped_coverage < kMathGlyphInfoHeaderSize ||
- !ots::ParseCoverageTable(font, data + offset_extended_shaped_coverage,
+ !ots::ParseCoverageTable(GetFont(), data + offset_extended_shaped_coverage,
length - offset_extended_shaped_coverage,
num_glyphs)) {
return OTS_FAILURE();
@@ -347,7 +342,7 @@ bool ParseMathGlyphInfoTable(const ots::Font *font,
if (offset_math_kern_info) {
if (offset_math_kern_info >= length ||
offset_math_kern_info < kMathGlyphInfoHeaderSize ||
- !ParseMathKernInfoTable(font, data + offset_math_kern_info,
+ !ParseMathKernInfoTable(data + offset_math_kern_info,
length - offset_math_kern_info, num_glyphs)) {
return OTS_FAILURE();
}
@@ -356,14 +351,14 @@ bool ParseMathGlyphInfoTable(const ots::Font *font,
return true;
}
-bool ParseGlyphAssemblyTable(const ots::Font *font,
- const uint8_t *data,
- size_t length, const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseGlyphAssemblyTable(const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs) {
ots::Buffer subtable(data, length);
// Check the header.
uint16_t part_count = 0;
- if (!ParseMathValueRecord(font, &subtable, data, length) ||
+ if (!ParseMathValueRecord(&subtable, data, length) ||
!subtable.ReadU16(&part_count)) {
return OTS_FAILURE();
}
@@ -384,19 +379,19 @@ bool ParseGlyphAssemblyTable(const ots::Font *font,
return OTS_FAILURE();
}
if (glyph >= num_glyphs) {
- return OTS_FAILURE_MSG("bad glyph ID: %u", glyph);
+ return Error("bad glyph ID: %u", glyph);
}
if (part_flags & ~0x00000001) {
- return OTS_FAILURE_MSG("unknown part flag: %u", part_flags);
+ return Error("unknown part flag: %u", part_flags);
}
}
return true;
}
-bool ParseMathGlyphConstructionTable(const ots::Font *font,
- const uint8_t *data,
- size_t length, const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseMathGlyphConstructionTable(const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs) {
ots::Buffer subtable(data, length);
// Check the header.
@@ -419,7 +414,7 @@ bool ParseMathGlyphConstructionTable(const ots::Font *font,
offset_glyph_assembly < sequence_end) {
return OTS_FAILURE();
}
- if (!ParseGlyphAssemblyTable(font, data + offset_glyph_assembly,
+ if (!ParseGlyphAssemblyTable(data + offset_glyph_assembly,
length - offset_glyph_assembly, num_glyphs)) {
return OTS_FAILURE();
}
@@ -433,21 +428,20 @@ bool ParseMathGlyphConstructionTable(const ots::Font *font,
return OTS_FAILURE();
}
if (glyph >= num_glyphs) {
- return OTS_FAILURE_MSG("bad glyph ID: %u", glyph);
+ return Error("bad glyph ID: %u", glyph);
}
}
return true;
}
-bool ParseMathGlyphConstructionSequence(const ots::Font *font,
- ots::Buffer* subtable,
- const uint8_t *data,
- size_t length,
- const uint16_t num_glyphs,
- uint16_t offset_coverage,
- uint16_t glyph_count,
- const unsigned sequence_end) {
+bool OpenTypeMATH::ParseMathGlyphConstructionSequence(ots::Buffer* subtable,
+ const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs,
+ uint16_t offset_coverage,
+ uint16_t glyph_count,
+ const unsigned sequence_end) {
// Zero glyph count, nothing to parse.
if (!glyph_count) {
return true;
@@ -457,7 +451,7 @@ bool ParseMathGlyphConstructionSequence(const ots::Font *font,
if (offset_coverage < sequence_end || offset_coverage >= length) {
return OTS_FAILURE();
}
- if (!ots::ParseCoverageTable(font, data + offset_coverage,
+ if (!ots::ParseCoverageTable(GetFont(), data + offset_coverage,
length - offset_coverage,
num_glyphs, glyph_count)) {
return OTS_FAILURE();
@@ -471,7 +465,7 @@ bool ParseMathGlyphConstructionSequence(const ots::Font *font,
}
if (offset_glyph_construction < sequence_end ||
offset_glyph_construction >= length ||
- !ParseMathGlyphConstructionTable(font, data + offset_glyph_construction,
+ !ParseMathGlyphConstructionTable(data + offset_glyph_construction,
length - offset_glyph_construction,
num_glyphs)) {
return OTS_FAILURE();
@@ -481,9 +475,9 @@ bool ParseMathGlyphConstructionSequence(const ots::Font *font,
return true;
}
-bool ParseMathVariantsTable(const ots::Font *font,
- const uint8_t *data,
- size_t length, const uint16_t num_glyphs) {
+bool OpenTypeMATH::ParseMathVariantsTable(const uint8_t *data,
+ size_t length,
+ const uint16_t num_glyphs) {
ots::Buffer subtable(data, length);
// Check the header.
@@ -505,11 +499,11 @@ bool ParseMathVariantsTable(const ots::Font *font,
return OTS_FAILURE();
}
- if (!ParseMathGlyphConstructionSequence(font, &subtable, data, length, num_glyphs,
+ if (!ParseMathGlyphConstructionSequence(&subtable, data, length, num_glyphs,
offset_vert_glyph_coverage,
vert_glyph_count,
sequence_end) ||
- !ParseMathGlyphConstructionSequence(font, &subtable, data, length, num_glyphs,
+ !ParseMathGlyphConstructionSequence(&subtable, data, length, num_glyphs,
offset_horiz_glyph_coverage,
horiz_glyph_count,
sequence_end)) {
@@ -519,37 +513,24 @@ bool ParseMathVariantsTable(const ots::Font *font,
return true;
}
-} // namespace
-
-#define DROP_THIS_TABLE(msg_) \
- do { \
- OTS_FAILURE_MSG(msg_ ", table discarded"); \
- font->math->data = 0; \
- font->math->length = 0; \
- } while (0)
-
-namespace ots {
-
-bool ots_math_parse(Font *font, const uint8_t *data, size_t length) {
+bool OpenTypeMATH::Parse(const uint8_t *data, size_t length) {
// Grab the number of glyphs in the font from the maxp table to check
// GlyphIDs in MATH table.
- if (!font->maxp) {
- return OTS_FAILURE();
+ OpenTypeMAXP *maxp = static_cast<OpenTypeMAXP*>(
+ GetFont()->GetTypedTable(OTS_TAG_MAXP));
+ if (!maxp) {
+ return Error("Required maxp table missing");
}
- const uint16_t num_glyphs = font->maxp->num_glyphs;
+ const uint16_t num_glyphs = maxp->num_glyphs;
Buffer table(data, length);
- OpenTypeMATH* math = new OpenTypeMATH;
- font->math = math;
-
uint32_t version = 0;
if (!table.ReadU32(&version)) {
return OTS_FAILURE();
}
if (version != 0x00010000) {
- DROP_THIS_TABLE("bad MATH version");
- return true;
+ return Drop("bad MATH version");
}
uint16_t offset_math_constants = 0;
@@ -567,53 +548,37 @@ bool ots_math_parse(Font *font, const uint8_t *data, size_t length) {
offset_math_glyph_info < kMathHeaderSize ||
offset_math_variants >= length ||
offset_math_variants < kMathHeaderSize) {
- DROP_THIS_TABLE("bad offset in MATH header");
- return true;
+ return Drop("bad offset in MATH header");
}
- if (!ParseMathConstantsTable(font, data + offset_math_constants,
+ if (!ParseMathConstantsTable(data + offset_math_constants,
length - offset_math_constants)) {
- DROP_THIS_TABLE("failed to parse MathConstants table");
- return true;
+ return Drop("failed to parse MathConstants table");
}
- if (!ParseMathGlyphInfoTable(font, data + offset_math_glyph_info,
+ if (!ParseMathGlyphInfoTable(data + offset_math_glyph_info,
length - offset_math_glyph_info, num_glyphs)) {
- DROP_THIS_TABLE("failed to parse MathGlyphInfo table");
- return true;
+ return Drop("failed to parse MathGlyphInfo table");
}
- if (!ParseMathVariantsTable(font, data + offset_math_variants,
+ if (!ParseMathVariantsTable(data + offset_math_variants,
length - offset_math_variants, num_glyphs)) {
- DROP_THIS_TABLE("failed to parse MathVariants table");
- return true;
+ return Drop("failed to parse MathVariants table");
}
- math->data = data;
- math->length = length;
+ this->m_data = data;
+ this->m_length = length;
return true;
}
-bool ots_math_should_serialise(Font *font) {
- return font->math != NULL && font->math->data != NULL;
-}
-
-bool ots_math_serialise(OTSStream *out, Font *font) {
- if (!out->Write(font->math->data, font->math->length)) {
+bool OpenTypeMATH::Serialize(OTSStream *out) {
+ if (!out->Write(this->m_data, this->m_length)) {
return OTS_FAILURE();
}
return true;
}
-void ots_math_reuse(Font *font, Font *other) {
- font->math = other->math;
- font->math_reused = true;
-}
-
-void ots_math_free(Font *font) {
- delete font->math;
+bool OpenTypeMATH::ShouldSerialize() {
+ return Table::ShouldSerialize() && this->m_data != NULL;
}
} // namespace ots
-
-#undef TABLE_NAME
-#undef DROP_THIS_TABLE