// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Font management utilities

#include "./font.h"

#include <algorithm>

#include "./ots.h"
#include "./port.h"
#include "./store_bytes.h"

namespace woff2 {

Font::Table* Font::FindTable(uint32_t tag) {
  std::map<uint32_t, Font::Table>::iterator it = tables.find(tag);
  return it == tables.end() ? 0 : &it->second;
}

const Font::Table* Font::FindTable(uint32_t tag) const {
  std::map<uint32_t, Font::Table>::const_iterator it = tables.find(tag);
  return it == tables.end() ? 0 : &it->second;
}

bool ReadFont(const uint8_t* data, size_t len, Font* font) {
  ots::Buffer file(data, len);

  // We don't care about the search_range, entry_selector and range_shift
  // fields, they will always be computed upon writing the font.
  if (!file.ReadU32(&font->flavor) ||
      !file.ReadU16(&font->num_tables) ||
      !file.Skip(6)) {
    return OTS_FAILURE();
  }

  std::map<uint32_t, uint32_t> intervals;
  for (uint16_t i = 0; i < font->num_tables; ++i) {
    Font::Table table;
    if (!file.ReadU32(&table.tag) ||
        !file.ReadU32(&table.checksum) ||
        !file.ReadU32(&table.offset) ||
        !file.ReadU32(&table.length)) {
      return OTS_FAILURE();
    }
    if ((table.offset & 3) != 0 ||
        table.length > len ||
        len - table.length < table.offset) {
      return OTS_FAILURE();
    }
    intervals[table.offset] = table.length;
    table.data = data + table.offset;
    if (font->tables.find(table.tag) != font->tables.end()) {
      return OTS_FAILURE();
    }
    font->tables[table.tag] = table;
  }

  // Check that tables are non-overlapping.
  uint32_t last_offset = 12UL + 16UL * font->num_tables;
  for (const auto& i : intervals) {
    if (i.first < last_offset || i.first + i.second < i.first) {
      return OTS_FAILURE();
    }
    last_offset = i.first + i.second;
  }
  return true;
}

size_t FontFileSize(const Font& font) {
  size_t max_offset = 12ULL + 16ULL * font.num_tables;
  for (const auto& i : font.tables) {
    const Font::Table& table = i.second;
    size_t padding_size = (4 - (table.length & 3)) & 3;
    size_t end_offset = (padding_size + table.offset) + table.length;
    max_offset = std::max(max_offset, end_offset);
  }
  return max_offset;
}

bool WriteFont(const Font& font, uint8_t* dst, size_t dst_size) {
  if (dst_size < 12ULL + 16ULL * font.num_tables) {
    return OTS_FAILURE();
  }
  size_t offset = 0;
  StoreU32(font.flavor, &offset, dst);
  Store16(font.num_tables, &offset, dst);
  uint16_t max_pow2 = font.num_tables ? Log2Floor(font.num_tables) : 0;
  uint16_t search_range = max_pow2 ? 1 << (max_pow2 + 4) : 0;
  uint16_t range_shift = (font.num_tables << 4) - search_range;
  Store16(search_range, &offset, dst);
  Store16(max_pow2, &offset, dst);
  Store16(range_shift, &offset, dst);
  for (const auto& i : font.tables) {
    const Font::Table& table = i.second;
    StoreU32(table.tag, &offset, dst);
    StoreU32(table.checksum, &offset, dst);
    StoreU32(table.offset, &offset, dst);
    StoreU32(table.length, &offset, dst);
    if (table.offset + table.length < table.offset ||
        dst_size < table.offset + table.length) {
      return OTS_FAILURE();
    }
    memcpy(dst + table.offset, table.data, table.length);
    size_t padding_size = (4 - (table.length & 3)) & 3;
    if (table.offset + table.length + padding_size < padding_size ||
        dst_size < table.offset + table.length + padding_size) {
      return OTS_FAILURE();
    }
    memset(dst + table.offset + table.length, 0, padding_size);
  }
  return true;
}

int NumGlyphs(const Font& font) {
  const Font::Table* head_table = font.FindTable(kHeadTableTag);
  const Font::Table* loca_table = font.FindTable(kLocaTableTag);
  if (head_table == NULL || loca_table == NULL || head_table->length < 52) {
    return 0;
  }
  int index_fmt = head_table->data[51];
  return (loca_table->length / (index_fmt == 0 ? 2 : 4)) - 1;
}

bool GetGlyphData(const Font& font, int glyph_index,
                  const uint8_t** glyph_data, size_t* glyph_size) {
  if (glyph_index < 0) {
    return OTS_FAILURE();
  }
  const Font::Table* head_table = font.FindTable(kHeadTableTag);
  const Font::Table* loca_table = font.FindTable(kLocaTableTag);
  const Font::Table* glyf_table = font.FindTable(kGlyfTableTag);
  if (head_table == NULL || loca_table == NULL || glyf_table == NULL ||
      head_table->length < 52) {
    return OTS_FAILURE();
  }
  int index_fmt = head_table->data[51];
  ots::Buffer loca_buf(loca_table->data, loca_table->length);
  if (index_fmt == 0) {
    uint16_t offset1, offset2;
    if (!loca_buf.Skip(2 * glyph_index) ||
        !loca_buf.ReadU16(&offset1) ||
        !loca_buf.ReadU16(&offset2) ||
        offset2 < offset1 ||
        2 * offset2 > glyf_table->length) {
      return OTS_FAILURE();
    }
    *glyph_data = glyf_table->data + 2 * offset1;
    *glyph_size = 2 * (offset2 - offset1);
  } else {
    uint32_t offset1, offset2;
    if (!loca_buf.Skip(4 * glyph_index) ||
        !loca_buf.ReadU32(&offset1) ||
        !loca_buf.ReadU32(&offset2) ||
        offset2 < offset1 ||
        offset2 > glyf_table->length) {
      return OTS_FAILURE();
    }
    *glyph_data = glyf_table->data + offset1;
    *glyph_size = offset2 - offset1;
  }
  return true;
}

} // namespace woff2
