// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// We use an underscore to avoid confusion with the standard math.h library.
#include "math_.h"

#include <limits>
#include <vector>

#include "layout.h"
#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.

namespace {

// The size of MATH header.
// Version
// MathConstants
// MathGlyphInfo
// MathVariants
const unsigned kMathHeaderSize = 4 + 3 * 2;

// The size of the MathGlyphInfo header.
// MathItalicsCorrectionInfo
// MathTopAccentAttachment
// ExtendedShapeCoverage
// MathKernInfo
const unsigned kMathGlyphInfoHeaderSize = 4 * 2;

// The size of the MathValueRecord.
// Value
// DeviceTable
const unsigned kMathValueRecordSize = 2 * 2;

// The size of the GlyphPartRecord.
// glyph
// StartConnectorLength
// EndConnectorLength
// FullAdvance
// PartFlags
const unsigned kGlyphPartRecordSize = 5 * 2;

// Shared Table: MathValueRecord

bool ParseMathValueRecord(ots::Buffer* subtable, const uint8_t *data,
                          const size_t length) {
  // Check the Value field.
  if (!subtable->Skip(2)) {
    return OTS_FAILURE();
  }

  // Check the offset to device table.
  uint16_t offset = 0;
  if (!subtable->ReadU16(&offset)) {
    return OTS_FAILURE();
  }
  if (offset) {
    if (offset >= length) {
      return OTS_FAILURE();
    }
    if (!ots::ParseDeviceTable(data + offset, length - offset)) {
      return OTS_FAILURE();
    }
  }

  return true;
}

bool ParseMathConstantsTable(const uint8_t *data, size_t length) {
  ots::Buffer subtable(data, length);

  // Part 1: int16 or uint16 constants.
  //  ScriptPercentScaleDown
  //  ScriptScriptPercentScaleDown
  //  DelimitedSubFormulaMinHeight
  //  DisplayOperatorMinHeight
  if (!subtable.Skip(4 * 2)) {
    return OTS_FAILURE();
  }

  // Part 2: MathValueRecord constants.
  // MathLeading
  // AxisHeight
  // AccentBaseHeight
  // FlattenedAccentBaseHeight
  // SubscriptShiftDown
  // SubscriptTopMax
  // SubscriptBaselineDropMin
  // SuperscriptShiftUp
  // SuperscriptShiftUpCramped
  // SuperscriptBottomMin
  //
  // SuperscriptBaselineDropMax
  // SubSuperscriptGapMin
  // SuperscriptBottomMaxWithSubscript
  // SpaceAfterScript
  // UpperLimitGapMin
  // UpperLimitBaselineRiseMin
  // LowerLimitGapMin
  // LowerLimitBaselineDropMin
  // StackTopShiftUp
  // StackTopDisplayStyleShiftUp
  //
  // StackBottomShiftDown
  // StackBottomDisplayStyleShiftDown
  // StackGapMin
  // StackDisplayStyleGapMin
  // StretchStackTopShiftUp
  // StretchStackBottomShiftDown
  // StretchStackGapAboveMin
  // StretchStackGapBelowMin
  // FractionNumeratorShiftUp
  // FractionNumeratorDisplayStyleShiftUp
  //
  // FractionDenominatorShiftDown
  // FractionDenominatorDisplayStyleShiftDown
  // FractionNumeratorGapMin
  // FractionNumDisplayStyleGapMin
  // FractionRuleThickness
  // FractionDenominatorGapMin
  // FractionDenomDisplayStyleGapMin
  // SkewedFractionHorizontalGap
  // SkewedFractionVerticalGap
  // OverbarVerticalGap
  //
  // OverbarRuleThickness
  // OverbarExtraAscender
  // UnderbarVerticalGap
  // UnderbarRuleThickness
  // UnderbarExtraDescender
  // RadicalVerticalGap
  // RadicalDisplayStyleVerticalGap
  // RadicalRuleThickness
  // RadicalExtraAscender
  // RadicalKernBeforeDegree
  //
  // RadicalKernAfterDegree
  for (unsigned i = 0; i < static_cast<unsigned>(51); ++i) {
    if (!ParseMathValueRecord(&subtable, data, length)) {
      return OTS_FAILURE();
    }
  }

  // Part 3: uint16 constant
  // RadicalDegreeBottomRaisePercent
  if (!subtable.Skip(2)) {
    return OTS_FAILURE();
  }

  return true;
}

bool 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;
  if (!subtable->ReadU16(&offset_coverage) ||
      !subtable->ReadU16(&sequence_count)) {
    return OTS_FAILURE();
  }

  const unsigned sequence_end = static_cast<unsigned>(2 * 2) +
      sequence_count * kMathValueRecordSize;
  if (sequence_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }

  // Check coverage table.
  if (offset_coverage < sequence_end || offset_coverage >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseCoverageTable(data + offset_coverage,
                               length - offset_coverage,
                               num_glyphs, sequence_count)) {
    return OTS_FAILURE();
  }

  // Check sequence.
  for (unsigned i = 0; i < sequence_count; ++i) {
    if (!ParseMathValueRecord(subtable, data, length)) {
      return OTS_FAILURE();
    }
  }

  return true;
}

bool ParseMathItalicsCorrectionInfoTable(const uint8_t *data,
                                         size_t length,
                                         const uint16_t num_glyphs) {
  ots::Buffer subtable(data, length);
  return ParseMathValueRecordSequenceForGlyphs(&subtable, data, length,
                                               num_glyphs);
}

bool ParseMathTopAccentAttachmentTable(const uint8_t *data,
                                       size_t length,
                                       const uint16_t num_glyphs) {
  ots::Buffer subtable(data, length);
  return ParseMathValueRecordSequenceForGlyphs(&subtable, data, length,
                                               num_glyphs);
}

bool ParseMathKernTable(const uint8_t *data, size_t length) {
  ots::Buffer subtable(data, length);

  // Check the Height count.
  uint16_t height_count = 0;
  if (!subtable.ReadU16(&height_count)) {
    return OTS_FAILURE();
  }

  // Check the Correction Heights.
  for (unsigned i = 0; i < height_count; ++i) {
    if (!ParseMathValueRecord(&subtable, data, length)) {
      return OTS_FAILURE();
    }
  }

  // Check the Kern Values.
  for (unsigned i = 0; i <= height_count; ++i) {
    if (!ParseMathValueRecord(&subtable, data, length)) {
      return OTS_FAILURE();
    }
  }

  return true;
}

bool ParseMathKernInfoTable(const uint8_t *data, size_t length,
                            const uint16_t num_glyphs) {
  ots::Buffer subtable(data, length);

  // Check the header.
  uint16_t offset_coverage = 0;
  uint16_t sequence_count = 0;
  if (!subtable.ReadU16(&offset_coverage) ||
      !subtable.ReadU16(&sequence_count)) {
    return OTS_FAILURE();
  }

  const unsigned sequence_end = static_cast<unsigned>(2 * 2) +
    sequence_count * 4 * 2;
  if (sequence_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }

  // Check coverage table.
  if (offset_coverage < sequence_end || offset_coverage >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseCoverageTable(data + offset_coverage, length - offset_coverage,
                               num_glyphs, sequence_count)) {
    return OTS_FAILURE();
  }

  // Check sequence of MathKernInfoRecord
  for (unsigned i = 0; i < sequence_count; ++i) {
    // Check TopRight, TopLeft, BottomRight and BottomLeft Math Kern.
    for (unsigned j = 0; j < 4; ++j) {
      uint16_t offset_math_kern = 0;
      if (!subtable.ReadU16(&offset_math_kern)) {
        return OTS_FAILURE();
      }
      if (offset_math_kern) {
        if (offset_math_kern < sequence_end || offset_math_kern >= length ||
            !ParseMathKernTable(data + offset_math_kern,
                                length - offset_math_kern)) {
          return OTS_FAILURE();
        }
      }
    }
  }

  return true;
}

bool ParseMathGlyphInfoTable(const uint8_t *data, size_t length,
                             const uint16_t num_glyphs) {
  ots::Buffer subtable(data, length);

  // Check Header.
  uint16_t offset_math_italics_correction_info = 0;
  uint16_t offset_math_top_accent_attachment = 0;
  uint16_t offset_extended_shaped_coverage = 0;
  uint16_t offset_math_kern_info = 0;
  if (!subtable.ReadU16(&offset_math_italics_correction_info) ||
      !subtable.ReadU16(&offset_math_top_accent_attachment) ||
      !subtable.ReadU16(&offset_extended_shaped_coverage) ||
      !subtable.ReadU16(&offset_math_kern_info)) {
    return OTS_FAILURE();
  }

  // Check subtables.
  // The specification does not say whether the offsets for
  // MathItalicsCorrectionInfo, MathTopAccentAttachment and MathKernInfo may
  // be NULL, but that's the case in some fonts (e.g STIX) so we accept that.
  if (offset_math_italics_correction_info) {
    if (offset_math_italics_correction_info >= length ||
        offset_math_italics_correction_info < kMathGlyphInfoHeaderSize ||
        !ParseMathItalicsCorrectionInfoTable(
            data + offset_math_italics_correction_info,
            length - offset_math_italics_correction_info,
            num_glyphs)) {
      return OTS_FAILURE();
    }
  }
  if (offset_math_top_accent_attachment) {
    if (offset_math_top_accent_attachment >= length ||
        offset_math_top_accent_attachment < kMathGlyphInfoHeaderSize ||
        !ParseMathTopAccentAttachmentTable(data +
                                           offset_math_top_accent_attachment,
                                           length -
                                           offset_math_top_accent_attachment,
                                           num_glyphs)) {
      return OTS_FAILURE();
    }
  }
  if (offset_extended_shaped_coverage) {
    if (offset_extended_shaped_coverage >= length ||
        offset_extended_shaped_coverage < kMathGlyphInfoHeaderSize ||
        !ots::ParseCoverageTable(data + offset_extended_shaped_coverage,
                                 length - offset_extended_shaped_coverage,
                                 num_glyphs)) {
      return OTS_FAILURE();
    }
  }
  if (offset_math_kern_info) {
    if (offset_math_kern_info >= length ||
        offset_math_kern_info < kMathGlyphInfoHeaderSize ||
        !ParseMathKernInfoTable(data + offset_math_kern_info,
                                length - offset_math_kern_info, num_glyphs)) {
      return OTS_FAILURE();
    }
  }

  return true;
}

bool 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(&subtable, data, length) ||
      !subtable.ReadU16(&part_count)) {
    return OTS_FAILURE();
  }

  const unsigned sequence_end = kMathValueRecordSize +
    static_cast<unsigned>(2) + part_count * kGlyphPartRecordSize;
  if (sequence_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }

  // Check the sequence of GlyphPartRecord.
  for (unsigned i = 0; i < part_count; ++i) {
    uint16_t glyph = 0;
    uint16_t part_flags = 0;
    if (!subtable.ReadU16(&glyph) ||
        !subtable.Skip(2 * 3) ||
        !subtable.ReadU16(&part_flags)) {
      return OTS_FAILURE();
    }
    if (glyph >= num_glyphs) {
      OTS_WARNING("bad glyph ID: %u", glyph);
      return OTS_FAILURE();
    }
    if (part_flags & ~0x00000001) {
      OTS_WARNING("unknown part flag: %u", part_flags);
      return OTS_FAILURE();
    }
  }

  return true;
}

bool ParseMathGlyphConstructionTable(const uint8_t *data,
                                     size_t length, const uint16_t num_glyphs) {
  ots::Buffer subtable(data, length);

  // Check the header.
  uint16_t offset_glyph_assembly = 0;
  uint16_t variant_count = 0;
  if (!subtable.ReadU16(&offset_glyph_assembly) ||
      !subtable.ReadU16(&variant_count)) {
    return OTS_FAILURE();
  }

  const unsigned sequence_end = static_cast<unsigned>(2 * 2) +
    variant_count * 2 * 2;
  if (sequence_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }

  // Check the GlyphAssembly offset.
  if (offset_glyph_assembly) {
    if (offset_glyph_assembly >= length ||
        offset_glyph_assembly < sequence_end) {
      return OTS_FAILURE();
    }
    if (!ParseGlyphAssemblyTable(data + offset_glyph_assembly,
                                 length - offset_glyph_assembly, num_glyphs)) {
      return OTS_FAILURE();
    }
  }

  // Check the sequence of MathGlyphVariantRecord.
  for (unsigned i = 0; i < variant_count; ++i) {
    uint16_t glyph = 0;
    if (!subtable.ReadU16(&glyph) ||
        !subtable.Skip(2)) {
      return OTS_FAILURE();
    }
    if (glyph >= num_glyphs) {
      OTS_WARNING("bad glyph ID: %u", glyph);
      return OTS_FAILURE();
    }
  }

  return true;
}

bool 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) {
  // Check coverage table.
  if (offset_coverage < sequence_end || offset_coverage >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseCoverageTable(data + offset_coverage,
                               length - offset_coverage,
                               num_glyphs, glyph_count)) {
    return OTS_FAILURE();
  }

  // Check sequence of MathGlyphConstruction.
  for (unsigned i = 0; i < glyph_count; ++i) {
      uint16_t offset_glyph_construction = 0;
      if (!subtable->ReadU16(&offset_glyph_construction)) {
        return OTS_FAILURE();
      }
      if (offset_glyph_construction < sequence_end ||
          offset_glyph_construction >= length ||
          !ParseMathGlyphConstructionTable(data + offset_glyph_construction,
                                           length - offset_glyph_construction,
                                           num_glyphs)) {
        return OTS_FAILURE();
      }
  }

  return true;
}

bool ParseMathVariantsTable(const uint8_t *data,
                            size_t length, const uint16_t num_glyphs) {
  ots::Buffer subtable(data, length);

  // Check the header.
  uint16_t offset_vert_glyph_coverage = 0;
  uint16_t offset_horiz_glyph_coverage = 0;
  uint16_t vert_glyph_count = 0;
  uint16_t horiz_glyph_count = 0;
  if (!subtable.Skip(2) ||  // MinConnectorOverlap
      !subtable.ReadU16(&offset_vert_glyph_coverage) ||
      !subtable.ReadU16(&offset_horiz_glyph_coverage) ||
      !subtable.ReadU16(&vert_glyph_count) ||
      !subtable.ReadU16(&horiz_glyph_count)) {
    return OTS_FAILURE();
  }

  const unsigned sequence_end = 5 * 2 + vert_glyph_count * 2 +
    horiz_glyph_count * 2;
  if (sequence_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }

  if (!ParseMathGlyphConstructionSequence(&subtable, data, length, num_glyphs,
                                          offset_vert_glyph_coverage,
                                          vert_glyph_count,
                                          sequence_end) ||
      !ParseMathGlyphConstructionSequence(&subtable, data, length, num_glyphs,
                                          offset_horiz_glyph_coverage,
                                          horiz_glyph_count,
                                          sequence_end)) {
    return OTS_FAILURE();
  }

  return true;
}

}  // namespace

#define DROP_THIS_TABLE \
  do { file->math->data = 0; file->math->length = 0; } while (0)

namespace ots {

bool ots_math_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
  // Grab the number of glyphs in the file from the maxp table to check
  // GlyphIDs in MATH table.
  if (!file->maxp) {
    return OTS_FAILURE();
  }
  const uint16_t num_glyphs = file->maxp->num_glyphs;

  Buffer table(data, length);

  OpenTypeMATH* math = new OpenTypeMATH;
  file->math = math;

  uint32_t version = 0;
  if (!table.ReadU32(&version)) {
    return OTS_FAILURE();
  }
  if (version != 0x00010000) {
    OTS_WARNING("bad MATH version");
    DROP_THIS_TABLE;
    return true;
  }

  uint16_t offset_math_constants = 0;
  uint16_t offset_math_glyph_info = 0;
  uint16_t offset_math_variants = 0;
  if (!table.ReadU16(&offset_math_constants) ||
      !table.ReadU16(&offset_math_glyph_info) ||
      !table.ReadU16(&offset_math_variants)) {
    return OTS_FAILURE();
  }

  if (offset_math_constants >= length ||
      offset_math_constants < kMathHeaderSize ||
      offset_math_glyph_info >= length ||
      offset_math_glyph_info < kMathHeaderSize ||
      offset_math_variants >= length ||
      offset_math_variants < kMathHeaderSize) {
    OTS_WARNING("bad offset in MATH header");
    DROP_THIS_TABLE;
    return true;
  }

  if (!ParseMathConstantsTable(data + offset_math_constants,
                               length - offset_math_constants)) {
    DROP_THIS_TABLE;
    return true;
  }
  if (!ParseMathGlyphInfoTable(data + offset_math_glyph_info,
                               length - offset_math_glyph_info, num_glyphs)) {
    DROP_THIS_TABLE;
    return true;
  }
  if (!ParseMathVariantsTable(data + offset_math_variants,
                              length - offset_math_variants, num_glyphs)) {
    DROP_THIS_TABLE;
    return true;
  }

  math->data = data;
  math->length = length;
  return true;
}

bool ots_math_should_serialise(OpenTypeFile *file) {
  return file->math != NULL && file->math->data != NULL;
}

bool ots_math_serialise(OTSStream *out, OpenTypeFile *file) {
  if (!out->Write(file->math->data, file->math->length)) {
    return OTS_FAILURE();
  }

  return true;
}

void ots_math_free(OpenTypeFile *file) {
  delete file->math;
}

}  // namespace ots

