/* Copyright 2013 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

/* Library for preprocessing fonts as part of the WOFF 2.0 conversion. */

#include "./transform.h"

#include <complex>  // for std::abs

#if !defined(STARBOARD)
#include <cstring>
#else
#include "starboard/client_porting/poem/string_poem.h"
#endif

#include "./buffer.h"
#include "./font.h"
#include "./glyph.h"
#include "./table_tags.h"
#include "./variable_length.h"

namespace woff2 {

namespace {

const int FLAG_ARG_1_AND_2_ARE_WORDS = 1 << 0;
const int FLAG_WE_HAVE_INSTRUCTIONS = 1 << 8;

void WriteBytes(std::vector<uint8_t>* out, const uint8_t* data, size_t len) {
  if (len == 0) return;
  size_t offset = out->size();
  out->resize(offset + len);
  memcpy(&(*out)[offset], data, len);
}

void WriteBytes(std::vector<uint8_t>* out, const std::vector<uint8_t>& in) {
  for (size_t i = 0; i < in.size(); ++i) {
    out->push_back(in[i]);
  }
}

void WriteUShort(std::vector<uint8_t>* out, int value) {
  out->push_back(value >> 8);
  out->push_back(value & 255);
}

void WriteLong(std::vector<uint8_t>* out, int value) {
  out->push_back((value >> 24) & 255);
  out->push_back((value >> 16) & 255);
  out->push_back((value >> 8) & 255);
  out->push_back(value & 255);
}

// Glyf table preprocessing, based on
// GlyfEncoder.java
class GlyfEncoder {
 public:
  explicit GlyfEncoder(int num_glyphs)
      : n_glyphs_(num_glyphs) {
    bbox_bitmap_.resize(((num_glyphs + 31) >> 5) << 2);
  }

  bool Encode(int glyph_id, const Glyph& glyph) {
    if (glyph.composite_data_size > 0) {
      WriteCompositeGlyph(glyph_id, glyph);
    } else if (glyph.contours.size() > 0) {
      WriteSimpleGlyph(glyph_id, glyph);
    } else {
      WriteUShort(&n_contour_stream_, 0);
    }
    return true;
  }

  void GetTransformedGlyfBytes(std::vector<uint8_t>* result) {
    WriteLong(result, 0);  // version
    WriteUShort(result, n_glyphs_);
    WriteUShort(result, 0);  // index_format, will be set later
    WriteLong(result, n_contour_stream_.size());
    WriteLong(result, n_points_stream_.size());
    WriteLong(result, flag_byte_stream_.size());
    WriteLong(result, glyph_stream_.size());
    WriteLong(result, composite_stream_.size());
    WriteLong(result, bbox_bitmap_.size() + bbox_stream_.size());
    WriteLong(result, instruction_stream_.size());
    WriteBytes(result, n_contour_stream_);
    WriteBytes(result, n_points_stream_);
    WriteBytes(result, flag_byte_stream_);
    WriteBytes(result, glyph_stream_);
    WriteBytes(result, composite_stream_);
    WriteBytes(result, bbox_bitmap_);
    WriteBytes(result, bbox_stream_);
    WriteBytes(result, instruction_stream_);
  }

 private:
  void WriteInstructions(const Glyph& glyph) {
    Write255UShort(&glyph_stream_, glyph.instructions_size);
    WriteBytes(&instruction_stream_,
               glyph.instructions_data, glyph.instructions_size);
  }

  bool ShouldWriteSimpleGlyphBbox(const Glyph& glyph) {
    if (glyph.contours.empty() || glyph.contours[0].empty()) {
      return glyph.x_min || glyph.y_min || glyph.x_max || glyph.y_max;
    }

    int16_t x_min = glyph.contours[0][0].x;
    int16_t y_min = glyph.contours[0][0].y;
    int16_t x_max = x_min;
    int16_t y_max = y_min;
    for (const auto& contour : glyph.contours) {
      for (const auto& point : contour) {
        if (point.x < x_min) x_min = point.x;
        if (point.x > x_max) x_max = point.x;
        if (point.y < y_min) y_min = point.y;
        if (point.y > y_max) y_max = point.y;
      }
    }

    if (glyph.x_min != x_min)
      return true;
    if (glyph.y_min != y_min)
      return true;
    if (glyph.x_max != x_max)
      return true;
    if (glyph.y_max != y_max)
      return true;

    return false;
  }

  void WriteSimpleGlyph(int glyph_id, const Glyph& glyph) {
    int num_contours = glyph.contours.size();
    WriteUShort(&n_contour_stream_, num_contours);
    if (ShouldWriteSimpleGlyphBbox(glyph)) {
      WriteBbox(glyph_id, glyph);
    }
    for (int i = 0; i < num_contours; i++) {
      Write255UShort(&n_points_stream_, glyph.contours[i].size());
    }
    int lastX = 0;
    int lastY = 0;
    for (int i = 0; i < num_contours; i++) {
      int num_points = glyph.contours[i].size();
      for (int j = 0; j < num_points; j++) {
        int x = glyph.contours[i][j].x;
        int y = glyph.contours[i][j].y;
        int dx = x - lastX;
        int dy = y - lastY;
        WriteTriplet(glyph.contours[i][j].on_curve, dx, dy);
        lastX = x;
        lastY = y;
      }
    }
    if (num_contours > 0) {
      WriteInstructions(glyph);
    }
  }

  void WriteCompositeGlyph(int glyph_id, const Glyph& glyph) {
    WriteUShort(&n_contour_stream_, -1);
    WriteBbox(glyph_id, glyph);
    WriteBytes(&composite_stream_,
               glyph.composite_data,
               glyph.composite_data_size);
    if (glyph.have_instructions) {
      WriteInstructions(glyph);
    }
  }

  void WriteBbox(int glyph_id, const Glyph& glyph) {
    bbox_bitmap_[glyph_id >> 3] |= 0x80 >> (glyph_id & 7);
    WriteUShort(&bbox_stream_, glyph.x_min);
    WriteUShort(&bbox_stream_, glyph.y_min);
    WriteUShort(&bbox_stream_, glyph.x_max);
    WriteUShort(&bbox_stream_, glyph.y_max);
  }

  void WriteTriplet(bool on_curve, int x, int y) {
    int abs_x = std::abs(x);
    int abs_y = std::abs(y);
    int on_curve_bit = on_curve ? 0 : 128;
    int x_sign_bit = (x < 0) ? 0 : 1;
    int y_sign_bit = (y < 0) ? 0 : 1;
    int xy_sign_bits = x_sign_bit + 2 * y_sign_bit;
    if (x == 0 && abs_y < 1280) {
      flag_byte_stream_.push_back(on_curve_bit +
                                  ((abs_y & 0xf00) >> 7) + y_sign_bit);
      glyph_stream_.push_back(abs_y & 0xff);
    } else if (y == 0 && abs_x < 1280) {
      flag_byte_stream_.push_back(on_curve_bit + 10 +
                                  ((abs_x & 0xf00) >> 7) + x_sign_bit);
      glyph_stream_.push_back(abs_x & 0xff);
    } else if (abs_x < 65 && abs_y < 65) {
      flag_byte_stream_.push_back(on_curve_bit + 20 +
                                  ((abs_x - 1) & 0x30) +
                                  (((abs_y - 1) & 0x30) >> 2) +
                                  xy_sign_bits);
      glyph_stream_.push_back((((abs_x - 1) & 0xf) << 4) | ((abs_y - 1) & 0xf));
    } else if (abs_x < 769 && abs_y < 769) {
      flag_byte_stream_.push_back(on_curve_bit + 84 +
                                  12 * (((abs_x - 1) & 0x300) >> 8) +
                                  (((abs_y - 1) & 0x300) >> 6) + xy_sign_bits);
      glyph_stream_.push_back((abs_x - 1) & 0xff);
      glyph_stream_.push_back((abs_y - 1) & 0xff);
    } else if (abs_x < 4096 && abs_y < 4096) {
      flag_byte_stream_.push_back(on_curve_bit + 120 + xy_sign_bits);
      glyph_stream_.push_back(abs_x >> 4);
      glyph_stream_.push_back(((abs_x & 0xf) << 4) | (abs_y >> 8));
      glyph_stream_.push_back(abs_y & 0xff);
    } else {
      flag_byte_stream_.push_back(on_curve_bit + 124 + xy_sign_bits);
      glyph_stream_.push_back(abs_x >> 8);
      glyph_stream_.push_back(abs_x & 0xff);
      glyph_stream_.push_back(abs_y >> 8);
      glyph_stream_.push_back(abs_y & 0xff);
    }
  }

  std::vector<uint8_t> n_contour_stream_;
  std::vector<uint8_t> n_points_stream_;
  std::vector<uint8_t> flag_byte_stream_;
  std::vector<uint8_t> composite_stream_;
  std::vector<uint8_t> bbox_bitmap_;
  std::vector<uint8_t> bbox_stream_;
  std::vector<uint8_t> glyph_stream_;
  std::vector<uint8_t> instruction_stream_;
  int n_glyphs_;
};

}  // namespace

bool TransformGlyfAndLocaTables(Font* font) {
  // no transform for CFF
  const Font::Table* glyf_table = font->FindTable(kGlyfTableTag);
  const Font::Table* loca_table = font->FindTable(kLocaTableTag);

  // If you don't have glyf/loca this transform isn't very interesting
  if (loca_table == NULL && glyf_table == NULL) {
    return true;
  }
  // It would be best if you didn't have just one of glyf/loca
  if ((glyf_table == NULL) != (loca_table == NULL)) {
    return FONT_COMPRESSION_FAILURE();
  }
  // Must share neither or both loca & glyf
  if (loca_table->IsReused() != glyf_table->IsReused()) {
    return FONT_COMPRESSION_FAILURE();
  }
  if (loca_table->IsReused()) {
    return true;
  }

  Font::Table* transformed_glyf = &font->tables[kGlyfTableTag ^ 0x80808080];
  Font::Table* transformed_loca = &font->tables[kLocaTableTag ^ 0x80808080];

  int num_glyphs = NumGlyphs(*font);
  GlyfEncoder encoder(num_glyphs);
  for (int i = 0; i < num_glyphs; ++i) {
    Glyph glyph;
    const uint8_t* glyph_data;
    size_t glyph_size;
    if (!GetGlyphData(*font, i, &glyph_data, &glyph_size) ||
        (glyph_size > 0 && !ReadGlyph(glyph_data, glyph_size, &glyph))) {
      return FONT_COMPRESSION_FAILURE();
    }
    encoder.Encode(i, glyph);
  }
  encoder.GetTransformedGlyfBytes(&transformed_glyf->buffer);

  const Font::Table* head_table = font->FindTable(kHeadTableTag);
  if (head_table == NULL || head_table->length < 52) {
    return FONT_COMPRESSION_FAILURE();
  }
  transformed_glyf->buffer[7] = head_table->data[51];  // index_format

  transformed_glyf->tag = kGlyfTableTag ^ 0x80808080;
  transformed_glyf->length = transformed_glyf->buffer.size();
  transformed_glyf->data = transformed_glyf->buffer.data();

  transformed_loca->tag = kLocaTableTag ^ 0x80808080;
  transformed_loca->length = 0;
  transformed_loca->data = NULL;

  return true;
}

// See https://www.microsoft.com/typography/otspec/hmtx.htm
// See WOFF2 spec, 5.4. Transformed hmtx table format
bool TransformHmtxTable(Font* font) {
  const Font::Table* glyf_table = font->FindTable(kGlyfTableTag);
  const Font::Table* hmtx_table = font->FindTable(kHmtxTableTag);
  const Font::Table* hhea_table = font->FindTable(kHheaTableTag);

  // If you don't have hmtx or a glyf not much is going to happen here
  if (hmtx_table == NULL || glyf_table == NULL) {
    return true;
  }

  // hmtx without hhea doesn't make sense
  if (hhea_table == NULL) {
    return FONT_COMPRESSION_FAILURE();
  }

  // Skip 34 to reach 'hhea' numberOfHMetrics
  Buffer hhea_buf(hhea_table->data, hhea_table->length);
  uint16_t num_hmetrics;
  if (!hhea_buf.Skip(34) || !hhea_buf.ReadU16(&num_hmetrics)) {
    return FONT_COMPRESSION_FAILURE();
  }

  // Must have at least one hMetric
  if (num_hmetrics < 1) {
    return FONT_COMPRESSION_FAILURE();
  }

  int num_glyphs = NumGlyphs(*font);

  // Most fonts can be transformed; assume it's a go until proven otherwise
  std::vector<uint16_t> advance_widths;
  std::vector<int16_t> proportional_lsbs;
  std::vector<int16_t> monospace_lsbs;

  bool remove_proportional_lsb = true;
  bool remove_monospace_lsb = (num_glyphs - num_hmetrics) > 0;

  Buffer hmtx_buf(hmtx_table->data, hmtx_table->length);
  for (int i = 0; i < num_glyphs; i++) {
    Glyph glyph;
    const uint8_t* glyph_data;
    size_t glyph_size;
    if (!GetGlyphData(*font, i, &glyph_data, &glyph_size) ||
        (glyph_size > 0 && !ReadGlyph(glyph_data, glyph_size, &glyph))) {
      return FONT_COMPRESSION_FAILURE();
    }

    uint16_t advance_width = 0;
    int16_t lsb = 0;

    if (i < num_hmetrics) {
      // [0, num_hmetrics) are proportional hMetrics
      if (!hmtx_buf.ReadU16(&advance_width)) {
        return FONT_COMPRESSION_FAILURE();
      }

      if (!hmtx_buf.ReadS16(&lsb)) {
        return FONT_COMPRESSION_FAILURE();
      }

      if (glyph_size > 0 && glyph.x_min != lsb) {
        remove_proportional_lsb = false;
      }

      advance_widths.push_back(advance_width);
      proportional_lsbs.push_back(lsb);
    } else {
      // [num_hmetrics, num_glyphs) are monospace leftSideBearing's
      if (!hmtx_buf.ReadS16(&lsb)) {
        return FONT_COMPRESSION_FAILURE();
      }
      if (glyph_size > 0 && glyph.x_min != lsb) {
        remove_monospace_lsb = false;
      }
      monospace_lsbs.push_back(lsb);
    }

    // If we know we can't optimize, bail out completely
    if (!remove_proportional_lsb && !remove_monospace_lsb) {
      return true;
    }
  }

  Font::Table* transformed_hmtx = &font->tables[kHmtxTableTag ^ 0x80808080];

  uint8_t flags = 0;
  size_t transformed_size = 1 + 2 * advance_widths.size();
  if (remove_proportional_lsb) {
    flags |= 1;
  } else {
    transformed_size += 2 * proportional_lsbs.size();
  }
  if (remove_monospace_lsb) {
    flags |= 1 << 1;
  } else {
    transformed_size += 2 * monospace_lsbs.size();
  }

  transformed_hmtx->buffer.reserve(transformed_size);
  std::vector<uint8_t>* out = &transformed_hmtx->buffer;
  WriteBytes(out, &flags, 1);
  for (uint16_t advance_width : advance_widths) {
    WriteUShort(out, advance_width);
  }

  if (!remove_proportional_lsb) {
    for (int16_t lsb : proportional_lsbs) {
      WriteUShort(out, lsb);
    }
  }
  if (!remove_monospace_lsb) {
    for (int16_t lsb : monospace_lsbs) {
      WriteUShort(out, lsb);
    }
  }

  transformed_hmtx->tag = kHmtxTableTag ^ 0x80808080;
  transformed_hmtx->flag_byte = 1 << 6;
  transformed_hmtx->length = transformed_hmtx->buffer.size();
  transformed_hmtx->data = transformed_hmtx->buffer.data();


  return true;
}

} // namespace woff2
