// Copyright (c) 2011 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.

#include "gpos.h"

#include <limits>
#include <vector>

#include "gdef.h"
#include "gsub.h"
#include "layout.h"
#include "maxp.h"

// GPOS - The Glyph Positioning Table
// http://www.microsoft.com/typography/otspec/gpos.htm

namespace {

enum GPOS_TYPE {
  GPOS_TYPE_SINGLE_ADJUSTMENT = 1,
  GPOS_TYPE_PAIR_ADJUSTMENT = 2,
  GPOS_TYPE_CURSIVE_ATTACHMENT = 3,
  GPOS_TYPE_MARK_TO_BASE_ATTACHMENT = 4,
  GPOS_TYPE_MARK_TO_LIGATURE_ATTACHMENT = 5,
  GPOS_TYPE_MARK_TO_MARK_ATTACHMENT = 6,
  GPOS_TYPE_CONTEXT_POSITIONING = 7,
  GPOS_TYPE_CHAINED_CONTEXT_POSITIONING = 8,
  GPOS_TYPE_EXTENSION_POSITIONING = 9,
  GPOS_TYPE_RESERVED = 10
};

// The size of gpos header.
const unsigned kGposHeaderSize = 10;
// The maximum format number for anchor tables.
const uint16_t kMaxAnchorFormat = 3;
// The maximum number of class value.
const uint16_t kMaxClassDefValue = 0xFFFF;

// Lookup type parsers.
bool ParseSingleAdjustment(const ots::OpenTypeFile *file,
                           const uint8_t *data, const size_t length);
bool ParsePairAdjustment(const ots::OpenTypeFile *file,
                         const uint8_t *data, const size_t length);
bool ParseCursiveAttachment(const ots::OpenTypeFile *file,
                            const uint8_t *data, const size_t length);
bool ParseMarkToBaseAttachment(const ots::OpenTypeFile *file,
                               const uint8_t *data, const size_t length);
bool ParseMarkToLigatureAttachment(const ots::OpenTypeFile *file,
                                   const uint8_t *data, const size_t length);
bool ParseMarkToMarkAttachment(const ots::OpenTypeFile *file,
                               const uint8_t *data, const size_t length);
bool ParseContextPositioning(const ots::OpenTypeFile *file,
                             const uint8_t *data, const size_t length);
bool ParseChainedContextPositioning(const ots::OpenTypeFile *file,
                                    const uint8_t *data, const size_t length);
bool ParseExtensionPositioning(const ots::OpenTypeFile *file,
                               const uint8_t *data, const size_t length);

const ots::LookupSubtableParser::TypeParser kGposTypeParsers[] = {
  {GPOS_TYPE_SINGLE_ADJUSTMENT, ParseSingleAdjustment},
  {GPOS_TYPE_PAIR_ADJUSTMENT, ParsePairAdjustment},
  {GPOS_TYPE_CURSIVE_ATTACHMENT, ParseCursiveAttachment},
  {GPOS_TYPE_MARK_TO_BASE_ATTACHMENT, ParseMarkToBaseAttachment},
  {GPOS_TYPE_MARK_TO_LIGATURE_ATTACHMENT, ParseMarkToLigatureAttachment},
  {GPOS_TYPE_MARK_TO_MARK_ATTACHMENT, ParseMarkToMarkAttachment},
  {GPOS_TYPE_CONTEXT_POSITIONING, ParseContextPositioning},
  {GPOS_TYPE_CHAINED_CONTEXT_POSITIONING, ParseChainedContextPositioning},
  {GPOS_TYPE_EXTENSION_POSITIONING, ParseExtensionPositioning}
};

// TODO(bashi): Port Chromium's arraysize macro and use it instead of sizeof().
const ots::LookupSubtableParser kGposLookupSubtableParser = {
  sizeof(kGposTypeParsers) / sizeof(kGposTypeParsers[0]),
  GPOS_TYPE_EXTENSION_POSITIONING, kGposTypeParsers
};

// Shared Tables: ValueRecord, Anchor Table, and MarkArray

bool ParseValueRecord(ots::Buffer* subtable, const uint8_t *data,
                      const size_t length, const uint16_t value_format) {
  // Check existence of adjustment fields.
  for (unsigned i = 0; i < 4; ++i) {
    if ((value_format >> i) & 0x1) {
      // Just read the field since these fileds could take an arbitrary values.
      if (!subtable->Skip(2)) {
        return OTS_FAILURE();
      }
    }
  }

  // Check existence of offsets to device table.
  for (unsigned i = 0; i < 4; ++i) {
    if ((value_format >> (i + 4)) & 0x1) {
      uint16_t offset = 0;
      if (!subtable->ReadU16(&offset)) {
        return OTS_FAILURE();
      }
      if (offset) {
        // TODO(bashi): Is it possible that device tables locate before
        // this record? No fonts contain such offset AKAIF.
        if (offset >= length) {
          return OTS_FAILURE();
        }
        if (!ots::ParseDeviceTable(data + offset, length - offset)) {
          return OTS_FAILURE();
        }
      }
    }
  }
  return true;
}

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

  uint16_t format = 0;
  // Read format and skip 2 2-byte fields that could be arbitrary values.
  if (!subtable.ReadU16(&format) ||
      !subtable.Skip(4)) {
    return OTS_FAILURE();
  }

  if (format == 0 || format > kMaxAnchorFormat) {
    return OTS_FAILURE();
  }

  // Format 2 and 3 has additional fields.
  if (format == 2) {
    // Format 2 provides an index to a glyph contour point, which will take
    // arbitrary value.
    uint16_t anchor_point = 0;
    if (!subtable.ReadU16(&anchor_point)) {
      return OTS_FAILURE();
    }
  } else if (format == 3) {
    uint16_t offset_x_device = 0;
    uint16_t offset_y_device = 0;
    if (!subtable.ReadU16(&offset_x_device) ||
        !subtable.ReadU16(&offset_y_device)) {
      return OTS_FAILURE();
    }
    const unsigned format_end = static_cast<unsigned>(10);
    if (offset_x_device) {
      if (offset_x_device < format_end || offset_x_device >= length) {
        return OTS_FAILURE();
      }
      if (!ots::ParseDeviceTable(data + offset_x_device,
                                 length - offset_x_device)) {
        return OTS_FAILURE();
      }
    }
    if (offset_y_device) {
      if (offset_y_device < format_end || offset_y_device >= length) {
        return OTS_FAILURE();
      }
      if (!ots::ParseDeviceTable(data + offset_y_device,
                                 length - offset_y_device)) {
        return OTS_FAILURE();
      }
    }
  }
  return true;
}

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

  uint16_t mark_count = 0;
  if (!subtable.ReadU16(&mark_count)) {
    return OTS_FAILURE();
  }

  // MarkRecord consists of 4-bytes.
  const unsigned mark_records_end = 4 * static_cast<unsigned>(mark_count) + 2;
  if (mark_records_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }
  for (unsigned i = 0; i < mark_count; ++i) {
    uint16_t class_value = 0;
    uint16_t offset_mark_anchor = 0;
    if (!subtable.ReadU16(&class_value) ||
        !subtable.ReadU16(&offset_mark_anchor)) {
      return OTS_FAILURE();
    }
    // |class_value| may take arbitrary values including 0 here so we don't
    // check the value.
    if (offset_mark_anchor < mark_records_end ||
        offset_mark_anchor >= length) {
      return OTS_FAILURE();
    }
    if (!ParseAnchorTable(data + offset_mark_anchor,
                          length - offset_mark_anchor)) {
      return OTS_FAILURE();
    }
  }

  return true;
}

// Lookup Type 1:
// Single Adjustment Positioning Subtable
bool ParseSingleAdjustment(const ots::OpenTypeFile *file, const uint8_t *data,
                           const size_t length) {
  ots::Buffer subtable(data, length);

  uint16_t format = 0;
  uint16_t offset_coverage = 0;
  uint16_t value_format = 0;
  if (!subtable.ReadU16(&format) ||
      !subtable.ReadU16(&offset_coverage) ||
      !subtable.ReadU16(&value_format)) {
    return OTS_FAILURE();
  }

  if (format == 1) {
    // Format 1 exactly one value record.
    if (!ParseValueRecord(&subtable, data, length, value_format)) {
      return OTS_FAILURE();
    }
  } else if (format == 2) {
    uint16_t value_count = 0;
    if (!subtable.ReadU16(&value_count)) {
      return OTS_FAILURE();
    }
    for (unsigned i = 0; i < value_count; ++i) {
      if (!ParseValueRecord(&subtable, data, length, value_format)) {
        return OTS_FAILURE();
      }
    }
  } else {
    return OTS_FAILURE();
  }

  if (offset_coverage < subtable.offset() || offset_coverage >= length) {
    return OTS_FAILURE();
  }

  if (!ots::ParseCoverageTable(data + offset_coverage,
                               length - offset_coverage,
                               file->maxp->num_glyphs)) {
    return OTS_FAILURE();
  }

  return true;
}

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

  uint16_t value_count = 0;
  if (!subtable.ReadU16(&value_count)) {
    return OTS_FAILURE();
  }
  for (unsigned i = 0; i < value_count; ++i) {
    // Check pair value record.
    uint16_t glyph_id = 0;
    if (!subtable.ReadU16(&glyph_id)) {
      return OTS_FAILURE();
    }
    if (glyph_id >= num_glyphs) {
      return OTS_FAILURE();
    }
    if (!ParseValueRecord(&subtable, data, length, value_format1)) {
      return OTS_FAILURE();
    }
    if (!ParseValueRecord(&subtable, data, length, value_format2)) {
      return OTS_FAILURE();
    }
  }
  return true;
}

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

  // Skip 8 bytes that are already read before.
  if (!subtable.Skip(8)) {
    return OTS_FAILURE();
  }

  uint16_t pair_set_count = 0;
  if (!subtable.ReadU16(&pair_set_count)) {
    return OTS_FAILURE();
  }

  const unsigned pair_pos_end = 2 * static_cast<unsigned>(pair_set_count) + 10;
  if (pair_pos_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }
  for (unsigned i = 0; i < pair_set_count; ++i) {
    uint16_t pair_set_offset = 0;
    if (!subtable.ReadU16(&pair_set_offset)) {
      return OTS_FAILURE();
    }
    if (pair_set_offset < pair_pos_end || pair_set_offset >= length) {
      return OTS_FAILURE();
    }
    // Check pair set tables
    if (!ParsePairSetTable(data + pair_set_offset, length - pair_set_offset,
                           value_format1, value_format2,
                           num_glyphs)) {
      return OTS_FAILURE();
    }
  }

  return true;
}

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

  // Skip 8 bytes that are already read before.
  if (!subtable.Skip(8)) {
    return OTS_FAILURE();
  }

  uint16_t offset_class_def1 = 0;
  uint16_t offset_class_def2 = 0;
  uint16_t class1_count = 0;
  uint16_t class2_count = 0;
  if (!subtable.ReadU16(&offset_class_def1) ||
      !subtable.ReadU16(&offset_class_def2) ||
      !subtable.ReadU16(&class1_count) ||
      !subtable.ReadU16(&class2_count)) {
    return OTS_FAILURE();
  }

  // Check class 1 records.
  for (unsigned i = 0; i < class1_count; ++i) {
    // Check class 2 records.
    for (unsigned j = 0; j < class2_count; ++j) {
      if (value_format1 && !ParseValueRecord(&subtable, data, length,
                                             value_format1)) {
        return OTS_FAILURE();
      }
      if (value_format2 && !ParseValueRecord(&subtable, data, length,
                                             value_format2)) {
        return OTS_FAILURE();
      }
    }
  }

  // Check class definition tables.
  if (offset_class_def1 < subtable.offset() || offset_class_def1 >= length ||
      offset_class_def2 < subtable.offset() || offset_class_def2 >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseClassDefTable(data + offset_class_def1,
                               length - offset_class_def1,
                               num_glyphs, kMaxClassDefValue)) {
    return OTS_FAILURE();
  }
  if (!ots::ParseClassDefTable(data + offset_class_def2,
                               length - offset_class_def2,
                               num_glyphs, kMaxClassDefValue)) {
    return OTS_FAILURE();
  }

  return true;
}

// Lookup Type 2:
// Pair Adjustment Positioning Subtable
bool ParsePairAdjustment(const ots::OpenTypeFile *file, const uint8_t *data,
                         const size_t length) {
  ots::Buffer subtable(data, length);

  uint16_t format = 0;
  uint16_t offset_coverage = 0;
  uint16_t value_format1 = 0;
  uint16_t value_format2 = 0;
  if (!subtable.ReadU16(&format) ||
      !subtable.ReadU16(&offset_coverage) ||
      !subtable.ReadU16(&value_format1) ||
      !subtable.ReadU16(&value_format2)) {
    return OTS_FAILURE();
  }

  if (format == 1) {
    if (!ParsePairPosFormat1(data, length, value_format1, value_format2,
                             file->maxp->num_glyphs)) {
      return OTS_FAILURE();
    }
  } else if (format == 2) {
    if (!ParsePairPosFormat2(data, length, value_format1, value_format2,
                             file->maxp->num_glyphs)) {
      return OTS_FAILURE();
    }
  } else {
    return OTS_FAILURE();
  }

  if (offset_coverage < subtable.offset() || offset_coverage >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseCoverageTable(data + offset_coverage,
                               length - offset_coverage,
                               file->maxp->num_glyphs)) {
    return OTS_FAILURE();
  }

  return true;
}

// Lookup Type 3
// Cursive Attachment Positioning Subtable
bool ParseCursiveAttachment(const ots::OpenTypeFile *file, const uint8_t *data,
                            const size_t length) {
  ots::Buffer subtable(data, length);

  uint16_t format = 0;
  uint16_t offset_coverage = 0;
  uint16_t entry_exit_count = 0;
  if (!subtable.ReadU16(&format) ||
      !subtable.ReadU16(&offset_coverage) ||
      !subtable.ReadU16(&entry_exit_count)) {
    return OTS_FAILURE();
  }

  if (format != 1) {
    return OTS_FAILURE();
  }

  // Check entry exit records.
  const unsigned entry_exit_records_end =
      2 * static_cast<unsigned>(entry_exit_count) + 6;
  if (entry_exit_records_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }
  for (unsigned i = 0; i < entry_exit_count; ++i) {
    uint16_t offset_entry_anchor = 0;
    uint16_t offset_exit_anchor = 0;
    if (!subtable.ReadU16(&offset_entry_anchor) ||
        !subtable.ReadU16(&offset_exit_anchor)) {
      return OTS_FAILURE();
    }
    // These offsets could be NULL.
    if (offset_entry_anchor) {
      if (offset_entry_anchor < entry_exit_records_end ||
          offset_entry_anchor >= length) {
        return OTS_FAILURE();
      }
      if (!ParseAnchorTable(data + offset_entry_anchor,
                            length - offset_entry_anchor)) {
        return OTS_FAILURE();
      }
    }
    if (offset_exit_anchor) {
      if (offset_exit_anchor < entry_exit_records_end ||
         offset_exit_anchor >= length) {
        return OTS_FAILURE();
      }
      if (!ParseAnchorTable(data + offset_exit_anchor,
                            length - offset_exit_anchor)) {
        return OTS_FAILURE();
      }
    }
  }

  if (offset_coverage < subtable.offset() || offset_coverage >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseCoverageTable(data + offset_coverage,
                               length - offset_coverage,
                               file->maxp->num_glyphs)) {
    return OTS_FAILURE();
  }

  return true;
}

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

  uint16_t record_count = 0;
  if (!subtable.ReadU16(&record_count)) {
    return OTS_FAILURE();
  }

  const unsigned anchor_array_end = 2 * static_cast<unsigned>(record_count) *
      static_cast<unsigned>(class_count) + 2;
  if (anchor_array_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }
  for (unsigned i = 0; i < record_count; ++i) {
    for (unsigned j = 0; j < class_count; ++j) {
      uint16_t offset_record = 0;
      if (!subtable.ReadU16(&offset_record)) {
        return OTS_FAILURE();
      }
      // |offset_record| could be NULL.
      if (offset_record) {
        if (offset_record < anchor_array_end || offset_record >= length) {
          return OTS_FAILURE();
        }
        if (!ParseAnchorTable(data + offset_record,
                              length - offset_record)) {
          return OTS_FAILURE();
        }
      }
    }
  }
  return true;
}

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

  uint16_t ligature_count = 0;
  if (!subtable.ReadU16(&ligature_count)) {
    return OTS_FAILURE();
  }
  for (unsigned i = 0; i < ligature_count; ++i) {
    uint16_t offset_ligature_attach = 0;
    if (!subtable.ReadU16(&offset_ligature_attach)) {
      return OTS_FAILURE();
    }
    if (offset_ligature_attach < 2 || offset_ligature_attach >= length) {
      return OTS_FAILURE();
    }
    if (!ParseAnchorArrayTable(data + offset_ligature_attach,
                               length - offset_ligature_attach, class_count)) {
      return OTS_FAILURE();
    }
  }
  return true;
}

// Common parser for Lookup Type 4, 5 and 6.
bool ParseMarkToAttachmentSubtables(const ots::OpenTypeFile *file,
                                    const uint8_t *data, const size_t length,
                                    const GPOS_TYPE type) {
  ots::Buffer subtable(data, length);

  uint16_t format = 0;
  uint16_t offset_coverage1 = 0;
  uint16_t offset_coverage2 = 0;
  uint16_t class_count = 0;
  uint16_t offset_mark_array = 0;
  uint16_t offset_type_specific_array = 0;
  if (!subtable.ReadU16(&format) ||
      !subtable.ReadU16(&offset_coverage1) ||
      !subtable.ReadU16(&offset_coverage2) ||
      !subtable.ReadU16(&class_count) ||
      !subtable.ReadU16(&offset_mark_array) ||
      !subtable.ReadU16(&offset_type_specific_array)) {
    return OTS_FAILURE();
  }

  if (format != 1) {
    return OTS_FAILURE();
  }

  const unsigned header_end = static_cast<unsigned>(subtable.offset());
  if (header_end > std::numeric_limits<uint16_t>::max()) {
    return OTS_FAILURE();
  }
  if (offset_coverage1 < header_end || offset_coverage1 >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseCoverageTable(data + offset_coverage1,
                               length - offset_coverage1,
                               file->maxp->num_glyphs)) {
    return OTS_FAILURE();
  }
  if (offset_coverage2 < header_end || offset_coverage2 >= length) {
    return OTS_FAILURE();
  }
  if (!ots::ParseCoverageTable(data + offset_coverage2,
                               length - offset_coverage2,
                               file->maxp->num_glyphs)) {
    return OTS_FAILURE();
  }

  if (offset_mark_array < header_end || offset_mark_array >= length) {
    return OTS_FAILURE();
  }
  if (!ParseMarkArrayTable(data + offset_mark_array,
                           length - offset_mark_array, class_count)) {
    return OTS_FAILURE();
  }

  if (offset_type_specific_array < header_end ||
      offset_type_specific_array >= length) {
    return OTS_FAILURE();
  }
  if (type == GPOS_TYPE_MARK_TO_BASE_ATTACHMENT ||
      type == GPOS_TYPE_MARK_TO_MARK_ATTACHMENT) {
    if (!ParseAnchorArrayTable(data + offset_type_specific_array,
                               length - offset_type_specific_array,
                               class_count)) {
      return OTS_FAILURE();
    }
  } else if (type == GPOS_TYPE_MARK_TO_LIGATURE_ATTACHMENT) {
    if (!ParseLigatureArrayTable(data + offset_type_specific_array,
                                 length - offset_type_specific_array,
                                 class_count)) {
      return OTS_FAILURE();
    }
  } else {
    return OTS_FAILURE();
  }

  return true;
}

// Lookup Type 4:
// MarkToBase Attachment Positioning Subtable
bool ParseMarkToBaseAttachment(const ots::OpenTypeFile *file,
                               const uint8_t *data, const size_t length) {
  return ParseMarkToAttachmentSubtables(file, data, length,
                                        GPOS_TYPE_MARK_TO_BASE_ATTACHMENT);
}

// Lookup Type 5:
// MarkToLigature Attachment Positioning Subtable
bool ParseMarkToLigatureAttachment(const ots::OpenTypeFile *file,
                                   const uint8_t *data, const size_t length) {
  return ParseMarkToAttachmentSubtables(file, data, length,
                                        GPOS_TYPE_MARK_TO_LIGATURE_ATTACHMENT);
}

// Lookup Type 6:
// MarkToMark Attachment Positioning Subtable
bool ParseMarkToMarkAttachment(const ots::OpenTypeFile *file,
                               const uint8_t *data, const size_t length) {
  return ParseMarkToAttachmentSubtables(file, data, length,
                                        GPOS_TYPE_MARK_TO_MARK_ATTACHMENT);
}

// Lookup Type 7:
// Contextual Positioning Subtables
bool ParseContextPositioning(const ots::OpenTypeFile *file,
                             const uint8_t *data, const size_t length) {
  return ots::ParseContextSubtable(data, length, file->maxp->num_glyphs,
                                   file->gpos->num_lookups);
}

// Lookup Type 8:
// Chaining Contexual Positioning Subtable
bool ParseChainedContextPositioning(const ots::OpenTypeFile *file,
                                    const uint8_t *data, const size_t length) {
  return ots::ParseChainingContextSubtable(data, length,
                                           file->maxp->num_glyphs,
                                           file->gpos->num_lookups);
}

// Lookup Type 9:
// Extension Positioning
bool ParseExtensionPositioning(const ots::OpenTypeFile *file,
                               const uint8_t *data, const size_t length) {
  return ots::ParseExtensionSubtable(file, data, length,
                                     &kGposLookupSubtableParser);
}

}  // namespace

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

namespace ots {

// As far as I checked, following fonts contain invalid GPOS table and
// OTS will drop their GPOS table.
//
// # invalid delta format in device table
// samanata.ttf
//
// # bad size range in device table
// Sarai_07.ttf
//
// # bad offset to PairSetTable
// chandas1-2.ttf
//
// # bad offset to FeatureTable
// glrso12.ttf
// gllr12.ttf
// glbo12.ttf
// glb12.ttf
// glro12.ttf
// glbso12.ttf
// glrc12.ttf
// glrsc12.ttf
// glbs12.ttf
// glrs12.ttf
// glr12.ttf
//
// # ScriptRecords aren't sorted by tag
// Garogier_unhinted.otf
//
// # bad start coverage index in CoverageFormat2
// AndBasR.ttf
// CharisSILB.ttf
// CharisSILBI.ttf
// CharisSILI.ttf
// CharisSILR.ttf
// DoulosSILR.ttf
// GenBasBI.ttf
// GenBasI.ttf
// GenBkBasI.ttf
// GenBkBasB.ttf
// GenBkBasR.ttf
// Padauk-Bold.ttf
// Padauk.ttf
//
// # Contour point indexes aren't sorted
// Arial Unicode.ttf

bool ots_gpos_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
  // Parsing GPOS table requires num_glyphs which is contained in maxp table.
  if (!file->maxp) {
    return OTS_FAILURE();
  }

  Buffer table(data, length);

  OpenTypeGPOS *gpos = new OpenTypeGPOS;
  file->gpos = gpos;

  uint32_t version = 0;
  uint16_t offset_script_list = 0;
  uint16_t offset_feature_list = 0;
  uint16_t offset_lookup_list = 0;
  if (!table.ReadU32(&version) ||
      !table.ReadU16(&offset_script_list) ||
      !table.ReadU16(&offset_feature_list) ||
      !table.ReadU16(&offset_lookup_list)) {
    return OTS_FAILURE();
  }

  if (version != 0x00010000) {
    OTS_WARNING("bad GPOS version");
    DROP_THIS_TABLE;
    return true;
  }
  if ((offset_script_list < kGposHeaderSize ||
       offset_script_list >= length) ||
      (offset_feature_list < kGposHeaderSize ||
       offset_feature_list >= length) ||
      (offset_lookup_list < kGposHeaderSize ||
       offset_lookup_list >= length)) {
    OTS_WARNING("bad offset in GPOS header");
    DROP_THIS_TABLE;
    return true;
  }

  if (!ParseLookupListTable(file, data + offset_lookup_list,
                            length - offset_lookup_list,
                            &kGposLookupSubtableParser,
                            &gpos->num_lookups)) {
    OTS_WARNING("faild to parse lookup list table");
    DROP_THIS_TABLE;
    return true;
  }

  uint16_t num_features = 0;
  if (!ParseFeatureListTable(data + offset_feature_list,
                             length - offset_feature_list, gpos->num_lookups,
                             &num_features)) {
    OTS_WARNING("faild to parse feature list table");
    DROP_THIS_TABLE;
    return true;
  }

  if (!ParseScriptListTable(data + offset_script_list,
                            length - offset_script_list, num_features)) {
    OTS_WARNING("faild to parse script list table");
    DROP_THIS_TABLE;
    return true;
  }

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

bool ots_gpos_should_serialise(OpenTypeFile *file) {
  const bool needed_tables_dropped =
      (file->gdef && file->gdef->data == NULL) ||
      (file->gsub && file->gsub->data == NULL);
  return file->gpos != NULL && file->gpos->data != NULL &&
      !needed_tables_dropped;
}

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

  return true;
}

void ots_gpos_free(OpenTypeFile *file) {
  delete file->gpos;
}

}  // namespace ots

