// Copyright (c) 2009 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 "loca.h"

#include "head.h"
#include "maxp.h"

// loca - Index to Location
// http://www.microsoft.com/typography/otspec/loca.htm

#define TABLE_NAME "loca"

namespace ots {

bool ots_loca_parse(Font *font, const uint8_t *data, size_t length) {
  Buffer table(data, length);

  // We can't do anything useful in validating this data except to ensure that
  // the values are monotonically increasing.

  OpenTypeLOCA *loca = new OpenTypeLOCA;
  font->loca = loca;

  if (!font->maxp || !font->head) {
    return OTS_FAILURE_MSG("maxp or head tables missing from font, needed by loca");
  }

  const unsigned num_glyphs = font->maxp->num_glyphs;
  unsigned last_offset = 0;
  loca->offsets.resize(num_glyphs + 1);
  // maxp->num_glyphs is uint16_t, thus the addition never overflows.

  if (font->head->index_to_loc_format == 0) {
    // Note that the <= here (and below) is correct. There is one more offset
    // than the number of glyphs in order to give the length of the final
    // glyph.
    for (unsigned i = 0; i <= num_glyphs; ++i) {
      uint16_t offset = 0;
      if (!table.ReadU16(&offset)) {
        return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i);
      }
      if (offset < last_offset) {
        return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset, last_offset, i);
      }
      last_offset = offset;
      loca->offsets[i] = offset * 2;
    }
  } else {
    for (unsigned i = 0; i <= num_glyphs; ++i) {
      uint32_t offset = 0;
      if (!table.ReadU32(&offset)) {
        return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i);
      }
      if (offset < last_offset) {
        return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset, last_offset, i);
      }
      last_offset = offset;
      loca->offsets[i] = offset;
    }
  }

  return true;
}

bool ots_loca_should_serialise(Font *font) {
  return font->loca != NULL;
}

bool ots_loca_serialise(OTSStream *out, Font *font) {
  const OpenTypeLOCA *loca = font->loca;
  const OpenTypeHEAD *head = font->head;

  if (!head) {
    return OTS_FAILURE_MSG("Missing head table in font needed by loca");
  }

  if (head->index_to_loc_format == 0) {
    for (unsigned i = 0; i < loca->offsets.size(); ++i) {
      const uint16_t offset = static_cast<uint16_t>(loca->offsets[i] >> 1);
      if ((offset != (loca->offsets[i] >> 1)) ||
          !out->WriteU16(offset)) {
        return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i);
      }
    }
  } else {
    for (unsigned i = 0; i < loca->offsets.size(); ++i) {
      if (!out->WriteU32(loca->offsets[i])) {
        return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i);
      }
    }
  }

  return true;
}

void ots_loca_reuse(Font *font, Font *other) {
  font->loca = other->loca;
  font->loca_reused = true;
}

void ots_loca_free(Font *font) {
  delete font->loca;
}

}  // namespace ots

#undef TABLE_NAME
