diff options
Diffstat (limited to 'gfx/ots/src/math.cc')
-rw-r--r-- | gfx/ots/src/math.cc | 209 |
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 |