/*
 * Copyright 2011 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.
 */

// type.h needs to be included first because of building issues on Windows
// Type aliases we delcare are defined in other headers and make the build
// fail otherwise.
#include "sfntly/port/type.h"
#include "sfntly/table/core/cmap_table.h"

#include <stdio.h>
#include <stdlib.h>

#include <utility>

#include "sfntly/font.h"
#include "sfntly/math/font_math.h"
#include "sfntly/port/endian.h"
#include "sfntly/port/exception_type.h"
#include "sfntly/table/core/name_table.h"

namespace sfntly {

const int32_t CMapTable::NOTDEF = 0;

CMapTable::CMapId CMapTable::WINDOWS_BMP = {
  PlatformId::kWindows,
  WindowsEncodingId::kUnicodeUCS2
};
CMapTable::CMapId CMapTable::WINDOWS_UCS4 = {
  PlatformId::kWindows,
  WindowsEncodingId::kUnicodeUCS4
};
CMapTable::CMapId CMapTable::MAC_ROMAN = {
  PlatformId::kWindows,
  MacintoshEncodingId::kRoman
};

/******************************************************************************
 * CMapTable class
 ******************************************************************************/
CMapTable::CMapTable(Header* header, ReadableFontData* data)
  : SubTableContainerTable(header, data) {
}

CMapTable::~CMapTable() {}

CALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t index) {
  if (index < 0 || index > NumCMaps()) {
#ifndef SFNTLY_NO_EXCEPTION
    throw IndexOutOfBoundException("Requested CMap index is out of bounds.");
#else
    return NULL;
#endif
  }
  int32_t platform_id = PlatformId(index);
  int32_t encoding_id = EncodingId(index);
  CMapId cmap_id = NewCMapId(platform_id, encoding_id);
  int32_t offset_ = Offset(index);
  Ptr<FontDataTable::Builder> cmap_builder =
      (CMap::Builder::GetBuilder(data_, offset_, cmap_id));
  if (!cmap_builder) {
#ifndef SFNTLY_NO_EXCEPTION
    throw NoSuchElementException("Cannot find builder for requested CMap.");
#else
    return NULL;
#endif
  }
  return down_cast<CMapTable::CMap*>(cmap_builder->Build());
}

CALLER_ATTACH CMapTable::CMap* CMapTable::GetCMap(const int32_t platform_id,
                                                  const int32_t encoding_id) {
  return GetCMap(NewCMapId(platform_id, encoding_id));
}

CALLER_ATTACH CMapTable::CMap*
CMapTable::GetCMap(const CMapTable::CMapId cmap_id) {
  CMapIdFilter id_filter(cmap_id);
  CMapIterator cmap_iterator(this, &id_filter);
  // There can only be one cmap with a particular CMapId
  if (cmap_iterator.HasNext()) {
    Ptr<CMapTable::CMap> cmap;
    cmap.Attach(cmap_iterator.Next());
    return cmap.Detach();
  }
#ifndef SFNTLY_NO_EXCEPTION
  throw NoSuchElementException();
#else
  return NULL;
#endif
}

int32_t CMapTable::Version() {
  return data_->ReadUShort(Offset::kVersion);
}

int32_t CMapTable::NumCMaps() {
  return data_->ReadUShort(Offset::kNumTables);
}

CMapTable::CMapId CMapTable::GetCMapId(int32_t index) {
  return NewCMapId(PlatformId(index), EncodingId(index));
}

int32_t CMapTable::PlatformId(int32_t index) {
  return data_->ReadUShort(Offset::kEncodingRecordPlatformId +
                           OffsetForEncodingRecord(index));
}

int32_t CMapTable::EncodingId(int32_t index) {
  return data_->ReadUShort(Offset::kEncodingRecordEncodingId +
                           OffsetForEncodingRecord(index));
}

int32_t CMapTable::Offset(int32_t index) {
  return data_->ReadULongAsInt(Offset::kEncodingRecordOffset +
                               OffsetForEncodingRecord(index));
}

int32_t CMapTable::OffsetForEncodingRecord(int32_t index) {
  return Offset::kEncodingRecordStart + index * Offset::kEncodingRecordSize;
}

CMapTable::CMapId CMapTable::NewCMapId(int32_t platform_id,
                                       int32_t encoding_id) {
  CMapId result;
  result.platform_id = platform_id;
  result.encoding_id = encoding_id;
  return result;
}

CMapTable::CMapId CMapTable::NewCMapId(const CMapId& obj) {
  CMapId result;
  result.platform_id = obj.platform_id;
  result.encoding_id = obj.encoding_id;
  return result;
}

/******************************************************************************
 * CMapTable::CMapIterator class
 ******************************************************************************/
CMapTable::CMapIterator::CMapIterator(CMapTable* table,
                                      const CMapFilter* filter)
    : table_index_(0), filter_(filter), table_(table) {
}

bool CMapTable::CMapIterator::HasNext() {
  if (!filter_) {
    if (table_index_ < table_->NumCMaps()) {
      return true;
    }
    return false;
  }

  for (; table_index_ < table_->NumCMaps(); ++table_index_) {
    if (filter_->accept(table_->GetCMapId(table_index_))) {
      return true;
    }
  }
  return false;
}

CALLER_ATTACH CMapTable::CMap* CMapTable::CMapIterator::Next() {
  if (!HasNext()) {
#ifndef SFNTLY_NO_EXCEPTION
    throw NoSuchElementException();
#else
    return NULL;
#endif
  }
  CMapPtr next_cmap;
  next_cmap.Attach(table_->GetCMap(table_index_++));
  if (next_cmap == NULL) {
#ifndef SFNTLY_NO_EXCEPTION
    throw NoSuchElementException("Error during the creation of the CMap");
#else
    return NULL;
#endif
  }
  return next_cmap.Detach();
}

/******************************************************************************
 * CMapTable::CMapId class
 ******************************************************************************/

/******************************************************************************
 * CMapTable::CMapIdComparator class
 ******************************************************************************/

bool CMapTable::CMapIdComparator::operator()(const CMapId& lhs,
                                             const CMapId& rhs) const {
  return ((lhs.platform_id << 8 | lhs.encoding_id) >
      (rhs.platform_id << 8 | rhs.encoding_id));
}

/******************************************************************************
 * CMapTable::CMapIdFilter class
 ******************************************************************************/
CMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id)
    : wanted_id_(wanted_id),
      comparator_(NULL) {
}

CMapTable::CMapIdFilter::CMapIdFilter(const CMapId wanted_id,
                                      const CMapIdComparator* comparator)
    : wanted_id_(wanted_id),
      comparator_(comparator) {
}

bool CMapTable::CMapIdFilter::accept(const CMapId& cmap_id) const {
  if (!comparator_)
    return wanted_id_ == cmap_id;
  return (*comparator_)(wanted_id_, cmap_id);
}

/******************************************************************************
 * CMapTable::CMap class
 ******************************************************************************/
CMapTable::CMap::CMap(ReadableFontData* data, int32_t format,
                      const CMapId& cmap_id)
    : SubTable(data), format_(format), cmap_id_(cmap_id) {
}

CMapTable::CMap::~CMap() {
}

/******************************************************************************
 * CMapTable::CMap::Builder class
 ******************************************************************************/
CMapTable::CMap::Builder::~Builder() {
}

CALLER_ATTACH CMapTable::CMap::Builder*
    CMapTable::CMap::Builder::GetBuilder(ReadableFontData* data, int32_t offset,
                                         const CMapId& cmap_id) {
  // NOT IMPLEMENTED: Java enum value validation
  int32_t format = data->ReadUShort(offset);
  CMapBuilderPtr builder;
  switch (format) {
    case CMapFormat::kFormat0:
      builder.Attach(CMapFormat0::Builder::NewInstance(data, offset, cmap_id));
      break;
    case CMapFormat::kFormat2:
#if defined (SFNTLY_DEBUG_CMAP)
      fprintf(stderr, "Requesting Format2 builder, but it's unsupported; "
              "returning NULL\n");
#endif
      break;
    case CMapFormat::kFormat4:
      builder.Attach(CMapFormat4::Builder::NewInstance(data, offset, cmap_id));
      break;
    default:
#ifdef SFNTLY_DEBUG_CMAP
      fprintf(stderr, "Unknown builder format requested\n");
#endif
      break;
  }
  return builder.Detach();
}

CALLER_ATTACH CMapTable::CMap::Builder*
CMapTable::CMap::Builder::GetBuilder(int32_t format, const CMapId& cmap_id) {
  Ptr<CMapTable::CMap::Builder> builder;
  switch (format) {
    case CMapFormat::kFormat0:
      builder.Attach(CMapFormat0::Builder::NewInstance(cmap_id));
      break;
    case CMapFormat::kFormat2:
#if defined (SFNTLY_DEBUG_CMAP)
      fprintf(stderr, "Requesting Format2 builder, but it's unsupported; "
              "returning NULL\n");
#endif
      break;
    case CMapFormat::kFormat4:
      builder.Attach(CMapFormat4::Builder::NewInstance(cmap_id));
      break;
    default:
#ifdef SFNTLY_DEBUG_CMAP
      fprintf(stderr, "Unknown builder format requested\n");
#endif
      break;
  }
  return builder.Detach();
}

CMapTable::CMap::Builder::Builder(ReadableFontData* data,
                                  int32_t format,
                                  const CMapId& cmap_id)
    : SubTable::Builder(data),
      format_(format),
      cmap_id_(cmap_id),
      language_(0) {
}

CMapTable::CMap::Builder::Builder(WritableFontData* data,
                                  int32_t format,
                                  const CMapId& cmap_id)
    : SubTable::Builder(data),
      format_(format),
      cmap_id_(cmap_id),
      language_(0) {
}

int32_t CMapTable::CMap::Builder::SubSerialize(WritableFontData* new_data) {
  return InternalReadData()->CopyTo(new_data);
}

bool CMapTable::CMap::Builder::SubReadyToSerialize() {
  return true;
}

int32_t CMapTable::CMap::Builder::SubDataSizeToSerialize() {
  ReadableFontDataPtr read_data = InternalReadData();
  if (!read_data)
    return 0;
  return read_data->Length();
}

void CMapTable::CMap::Builder::SubDataSet() {
  // NOP
}

/******************************************************************************
 * CMapTable::CMapFormat0
 ******************************************************************************/
CMapTable::CMapFormat0::~CMapFormat0() {
}

int32_t CMapTable::CMapFormat0::Language() {
  return 0;
}

int32_t CMapTable::CMapFormat0::GlyphId(int32_t character) {
  if (character < 0 || character > 255) {
    return CMapTable::NOTDEF;
  }
  return data_->ReadUByte(character + Offset::kFormat0GlyphIdArray);
}

CMapTable::CMapFormat0::CMapFormat0(ReadableFontData* data,
                                    const CMapId& cmap_id)
    : CMap(data, CMapFormat::kFormat0, cmap_id) {
}

CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat0::Iterator() {
  return new CMapTable::CMapFormat0::CharacterIterator(0, 0xff);
}


/******************************************************************************
 * CMapTable::CMapFormat0::CharacterIterator
 ******************************************************************************/
CMapTable::CMapFormat0::CharacterIterator::CharacterIterator(int32_t start,
                                                             int32_t end)
    : character_(start),
    max_character_(end) {
}

CMapTable::CMapFormat0::CharacterIterator::~CharacterIterator() {}

bool CMapTable::CMapFormat0::CharacterIterator::HasNext() {
  return character_ < max_character_;
}

int32_t CMapTable::CMapFormat0::CharacterIterator::Next() {
  if (HasNext())
    return character_++;
#ifndef SFNTLY_NO_EXCEPTION
  throw NoSuchElementException("No more characters to iterate.");
#endif
  return -1;
}

/******************************************************************************
 * CMapTable::CMapFormat0::Builder
 ******************************************************************************/
// static
CALLER_ATTACH CMapTable::CMapFormat0::Builder*
CMapTable::CMapFormat0::Builder::NewInstance(WritableFontData* data,
                                             int32_t offset,
                                             const CMapId& cmap_id) {
  WritableFontDataPtr wdata;
  if (data) {
    wdata.Attach(down_cast<WritableFontData*>(
        data->Slice(offset,
                    data->ReadUShort(offset + Offset::kFormat0Length))));
  }
  return new Builder(wdata, CMapFormat::kFormat0, cmap_id);
}

// static
CALLER_ATTACH CMapTable::CMapFormat0::Builder*
CMapTable::CMapFormat0::Builder::NewInstance(ReadableFontData* data,
                                             int32_t offset,
                                             const CMapId& cmap_id) {
  ReadableFontDataPtr rdata;
  if (data) {
    rdata.Attach(down_cast<ReadableFontData*>(
        data->Slice(offset,
                    data->ReadUShort(offset + Offset::kFormat0Length))));
  }
  return new Builder(rdata, CMapFormat::kFormat0, cmap_id);
}

// static
CALLER_ATTACH CMapTable::CMapFormat0::Builder*
CMapTable::CMapFormat0::Builder::NewInstance(const CMapId& cmap_id) {
  return new Builder(cmap_id);
}

// Always call NewInstance instead of the constructor for creating a new builder
// object! This refactoring avoids memory leaks when slicing the font data.
CMapTable::CMapFormat0::Builder::Builder(WritableFontData* data, int32_t offset,
                                         const CMapId& cmap_id)
    : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) {
  UNREFERENCED_PARAMETER(offset);
}

CMapTable::CMapFormat0::Builder::Builder(
    ReadableFontData* data,
    int32_t offset,
    const CMapId& cmap_id)
    : CMapTable::CMap::Builder(data, CMapFormat::kFormat0, cmap_id) {
  UNREFERENCED_PARAMETER(offset);
}

CMapTable::CMapFormat0::Builder::Builder(const CMapId& cmap_id)
    : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
                    CMapFormat::kFormat0,
                    cmap_id) {
}

CMapTable::CMapFormat0::Builder::~Builder() {
}

CALLER_ATTACH FontDataTable*
    CMapTable::CMapFormat0::Builder::SubBuildTable(ReadableFontData* data) {
  FontDataTablePtr table = new CMapFormat0(data, cmap_id());
  return table.Detach();
}

/******************************************************************************
 * CMapTable::CMapFormat2
 ******************************************************************************/
CMapTable::CMapFormat2::~CMapFormat2() {
}

int32_t CMapTable::CMapFormat2::Language() {
  return 0;
}

int32_t CMapTable::CMapFormat2::GlyphId(int32_t character) {
  if (character > 0xffff) {
    return CMapTable::NOTDEF;
  }

  uint32_t c = ToBE32(character);
  byte_t high_byte = (c >> 8) & 0xff;
  byte_t low_byte = c & 0xff;
  int32_t offset = SubHeaderOffset(high_byte);

  if (offset == 0) {
    low_byte = high_byte;
    high_byte = 0;
  }

  int32_t first_code = FirstCode(high_byte);
  int32_t entry_count = EntryCount(high_byte);

  if (low_byte < first_code || low_byte >= first_code + entry_count) {
    return CMapTable::NOTDEF;
  }

  int32_t id_range_offset = IdRangeOffset(high_byte);

  // position of idRangeOffset + value of idRangeOffset + index for low byte
  // = firstcode
  int32_t p_location = (offset + Offset::kFormat2SubHeader_idRangeOffset) +
      id_range_offset +
      (low_byte - first_code) * DataSize::kUSHORT;
  int p = data_->ReadUShort(p_location);
  if (p == 0) {
    return CMapTable::NOTDEF;
  }

  if (offset == 0) {
    return p;
  }
  int id_delta = IdDelta(high_byte);
  return (p + id_delta) % 65536;
}

int32_t CMapTable::CMapFormat2::BytesConsumed(int32_t character) {
  uint32_t c = ToBE32(character);
  int32_t high_byte = (c >> 8) & 0xff;
  int32_t offset = SubHeaderOffset(high_byte);
  return (offset == 0) ? 1 : 2;
}

CMapTable::CMapFormat2::CMapFormat2(ReadableFontData* data,
                                    const CMapId& cmap_id)
    : CMap(data, CMapFormat::kFormat2, cmap_id) {
}

int32_t CMapTable::CMapFormat2::SubHeaderOffset(int32_t sub_header_index) {
  return data_->ReadUShort(Offset::kFormat2SubHeaderKeys +
                           sub_header_index * DataSize::kUSHORT);
}

int32_t CMapTable::CMapFormat2::FirstCode(int32_t sub_header_index) {
  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
  return data_->ReadUShort(sub_header_offset +
                           Offset::kFormat2SubHeaderKeys +
                           Offset::kFormat2SubHeader_firstCode);
}

int32_t CMapTable::CMapFormat2::EntryCount(int32_t sub_header_index) {
  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
  return data_->ReadUShort(sub_header_offset +
                           Offset::kFormat2SubHeaderKeys +
                           Offset::kFormat2SubHeader_entryCount);
}

int32_t CMapTable::CMapFormat2::IdRangeOffset(int32_t sub_header_index) {
  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
  return data_->ReadUShort(sub_header_offset +
                           Offset::kFormat2SubHeaderKeys +
                           Offset::kFormat2SubHeader_idRangeOffset);
}

int32_t CMapTable::CMapFormat2::IdDelta(int32_t sub_header_index) {
  int32_t sub_header_offset = SubHeaderOffset(sub_header_index);
  return data_->ReadUShort(sub_header_offset +
                           Offset::kFormat2SubHeaderKeys +
                           Offset::kFormat2SubHeader_idDelta);
}

CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat2::Iterator() {
  // UNIMPLEMENTED
  return NULL;
}

/******************************************************************************
 * CMapTable::CMapFormat2::Builder
 ******************************************************************************/
CMapTable::CMapFormat2::Builder::Builder(WritableFontData* data,
                                         int32_t offset,
                                         const CMapId& cmap_id)
    : CMapTable::CMap::Builder(data ? down_cast<WritableFontData*>(
                                   data->Slice(offset, data->ReadUShort(
                                       offset + Offset::kFormat0Length)))
                               : reinterpret_cast<WritableFontData*>(NULL),
                               CMapFormat::kFormat2, cmap_id) {
  // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix.
}

CMapTable::CMapFormat2::Builder::Builder(ReadableFontData* data,
                                         int32_t offset,
                                         const CMapId& cmap_id)
    : CMapTable::CMap::Builder(data ? down_cast<ReadableFontData*>(
                                   data->Slice(offset, data->ReadUShort(
                                       offset + Offset::kFormat0Length)))
                               : reinterpret_cast<ReadableFontData*>(NULL),
                               CMapFormat::kFormat2, cmap_id) {
  // TODO(arthurhsu): FIXIT: heavy lifting and leak, need fix.
}

CMapTable::CMapFormat2::Builder::~Builder() {
}

CALLER_ATTACH FontDataTable*
    CMapTable::CMapFormat2::Builder::SubBuildTable(ReadableFontData* data) {
  FontDataTablePtr table = new CMapFormat2(data, cmap_id());
  return table.Detach();
}

/******************************************************************************
 * CMapTable::CMapFormat4
 ******************************************************************************/
CMapTable::CMapFormat4::CMapFormat4(ReadableFontData* data,
                                    const CMapId& cmap_id)
    : CMap(data, CMapFormat::kFormat4, cmap_id),
      seg_count_(SegCount(data)),
      start_code_offset_(StartCodeOffset(seg_count_)),
      id_delta_offset_(IdDeltaOffset(seg_count_)),
      glyph_id_array_offset_(GlyphIdArrayOffset(seg_count_)) {
}

CMapTable::CMapFormat4::~CMapFormat4() {
}

int32_t CMapTable::CMapFormat4::GlyphId(int32_t character) {
  int32_t segment = data_->SearchUShort(StartCodeOffset(seg_count_),
                                        DataSize::kUSHORT,
                                        Offset::kFormat4EndCount,
                                        DataSize::kUSHORT,
                                        seg_count_,
                                        character);
  if (segment == -1) {
    return CMapTable::NOTDEF;
  }
  int32_t start_code = StartCode(segment);
  return RetrieveGlyphId(segment, start_code, character);
}

int32_t CMapTable::CMapFormat4::RetrieveGlyphId(int32_t segment,
                                                int32_t start_code,
                                                int32_t character) {
  if (character < start_code) {
    return CMapTable::NOTDEF;
  }
  int32_t id_range_offset = IdRangeOffset(segment);
  if (id_range_offset == 0) {
    return (character + IdDelta(segment)) % 65536;
  }
  return data_->ReadUShort(id_range_offset +
                           IdRangeOffsetLocation(segment) +
                           2 * (character - start_code));
}

int32_t CMapTable::CMapFormat4::seg_count() {
  return seg_count_;
}

int32_t CMapTable::CMapFormat4::Length() {
  return Length(data_);
}

int32_t CMapTable::CMapFormat4::StartCode(int32_t segment) {
  if (!IsValidIndex(segment)) {
    return -1;
  }
  return StartCode(data_.p_, seg_count_, segment);
}

// static
int32_t CMapTable::CMapFormat4::Language(ReadableFontData* data) {
  int32_t language = data->ReadUShort(Offset::kFormat4Language);
  return language;
}

// static
int32_t CMapTable::CMapFormat4::Length(ReadableFontData* data) {
  int32_t length = data->ReadUShort(Offset::kFormat4Length);
  return length;
}

// static
int32_t CMapTable::CMapFormat4::SegCount(ReadableFontData* data) {
  int32_t seg_count = data->ReadUShort(Offset::kFormat4SegCountX2) / 2;
  return seg_count;
}

// static
int32_t CMapTable::CMapFormat4::StartCode(ReadableFontData* data,
                                          int32_t seg_count,
                                          int32_t index) {
  int32_t start_code = data->ReadUShort(StartCodeOffset(seg_count) +
                                        index * DataSize::kUSHORT);
  return start_code;
}

// static
int32_t CMapTable::CMapFormat4::StartCodeOffset(int32_t seg_count) {
  int32_t start_code_offset = Offset::kFormat4EndCount +
      (seg_count + 1) * DataSize::kUSHORT;
  return start_code_offset;
}

// static
int32_t CMapTable::CMapFormat4::EndCode(ReadableFontData* data,
                                        int32_t seg_count,
                                        int32_t index) {
  UNREFERENCED_PARAMETER(seg_count);
  int32_t end_code = data->ReadUShort(Offset::kFormat4EndCount +
                                      index * DataSize::kUSHORT);
  return end_code;
}

// static
int32_t CMapTable::CMapFormat4::IdDelta(ReadableFontData* data,
                                        int32_t seg_count,
                                        int32_t index) {
  int32_t id_delta = data->ReadUShort(IdDeltaOffset(seg_count) +
                                      index * DataSize::kUSHORT);
  return id_delta;
}

// static
int32_t CMapTable::CMapFormat4::IdDeltaOffset(int32_t seg_count) {
  int32_t id_delta_offset =
      Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT;
  return id_delta_offset;
}

// static
int32_t CMapTable::CMapFormat4::IdRangeOffset(ReadableFontData* data,
                                              int32_t seg_count,
                                              int32_t index) {
  int32_t id_range_offset =
      data->ReadUShort(IdRangeOffsetOffset(seg_count)
                       + index * DataSize::kUSHORT);
  return id_range_offset;
}

// static
int32_t CMapTable::CMapFormat4::IdRangeOffsetOffset(int32_t seg_count) {
  int32_t id_range_offset_offset =
      Offset::kFormat4EndCount + (2 * seg_count + 1) * DataSize::kUSHORT +
      seg_count * DataSize::kSHORT;
  return id_range_offset_offset;
}

// static
int32_t CMapTable::CMapFormat4::GlyphIdArrayOffset(int32_t seg_count) {
  int32_t glyph_id_array_offset =
      Offset::kFormat4EndCount + (3 * seg_count + 1) * DataSize::kUSHORT +
      seg_count * DataSize::kSHORT;
  return glyph_id_array_offset;
}

int32_t CMapTable::CMapFormat4::EndCode(int32_t segment) {
  if (IsValidIndex(segment)) {
    return EndCode(data_, seg_count_, segment);
  }
#if defined (SFNTLY_NO_EXCEPTION)
  return -1;
#else
  throw IllegalArgumentException();
#endif
}

bool CMapTable::CMapFormat4::IsValidIndex(int32_t segment) {
  if (segment < 0 || segment >= seg_count_) {
#if defined (SFNTLY_NO_EXCEPTION)
    return false;
#else
    throw IllegalArgumentException();
#endif
  }
  return true;
}

int32_t CMapTable::CMapFormat4::IdDelta(int32_t segment) {
  if (IsValidIndex(segment))
    return IdDelta(data_, seg_count_, segment);
  return -1;
}

int32_t CMapTable::CMapFormat4::IdRangeOffset(int32_t segment) {
  if (IsValidIndex(segment))
    return data_->ReadUShort(IdRangeOffsetLocation(segment));
  return -1;
}

int32_t CMapTable::CMapFormat4::IdRangeOffsetLocation(int32_t segment) {
  if (IsValidIndex(segment))
    return IdRangeOffsetOffset(seg_count_) + segment * DataSize::kUSHORT;
  return -1;
}

int32_t CMapTable::CMapFormat4::GlyphIdArray(int32_t index) {
  return data_->ReadUShort(glyph_id_array_offset_ + index * DataSize::kUSHORT);
}

int32_t CMapTable::CMapFormat4::Language() {
  return Language(data_);
}


CMapTable::CMap::CharacterIterator* CMapTable::CMapFormat4::Iterator() {
  return new CharacterIterator(this);
}

/******************************************************************************
 * CMapTable::CMapFormat4::CharacterIterator class
 ******************************************************************************/
CMapTable::CMapFormat4::CharacterIterator::CharacterIterator(
    CMapFormat4* parent)
    : parent_(parent),
      segment_index_(0),
      first_char_in_segment_(-1),
      last_char_in_segment_(-1),
      next_char_(-1),
      next_char_set_(false) {
}

bool CMapTable::CMapFormat4::CharacterIterator::HasNext() {
  if (next_char_set_)
    return true;
  while (segment_index_ < parent_->seg_count_) {
    if (first_char_in_segment_ < 0) {
      first_char_in_segment_ = parent_->StartCode(segment_index_);
      last_char_in_segment_ = parent_->EndCode(segment_index_);
      next_char_ = first_char_in_segment_;
      next_char_set_ = true;
      return true;
    }
    if (next_char_ < last_char_in_segment_) {
      next_char_++;
      next_char_set_ = true;
      return true;
    }
    segment_index_++;
    first_char_in_segment_ = -1;
  }
  return false;
}

int32_t CMapTable::CMapFormat4::CharacterIterator::Next() {
  if (!next_char_set_) {
    if (!HasNext()) {
#if defined (SFNTLY_NO_EXCEPTION)
      return -1;
#else
      throw NoSuchElementException("No more characters to iterate.");
#endif
    }
  }
  next_char_set_ = false;
  return next_char_;
}

/******************************************************************************
 * CMapTable::CMapFormat4::Builder::Segment class
 ******************************************************************************/
CMapTable::CMapFormat4::Builder::Segment::Segment() {}

CMapTable::CMapFormat4::Builder::Segment::Segment(Segment* other)
    : start_count_(other->start_count_),
      end_count_(other->end_count_),
      id_delta_(other->id_delta_),
      id_range_offset_(other->id_range_offset_) {
}

CMapTable::CMapFormat4::Builder::Segment::Segment(int32_t start_count,
                                                  int32_t end_count,
                                                  int32_t id_delta,
                                                  int32_t id_range_offset)
    : start_count_(start_count),
      end_count_(end_count),
      id_delta_(id_delta),
      id_range_offset_(id_range_offset) {
}

CMapTable::CMapFormat4::Builder::Segment::~Segment() {}

int32_t CMapTable::CMapFormat4::Builder::Segment::start_count() {
  return start_count_;
}

void
CMapTable::CMapFormat4::Builder::Segment::set_start_count(int32_t start_count) {
  start_count_ = start_count;
}

int32_t CMapTable::CMapFormat4::Builder::Segment::end_count() {
  return end_count_;
}

void
CMapTable::CMapFormat4::Builder::Segment::set_end_count(int32_t end_count) {
  end_count_ = end_count;
}

int32_t CMapTable::CMapFormat4::Builder::Segment::id_delta() {
  return id_delta_;
}

void
CMapTable::CMapFormat4::Builder::Segment::set_id_delta(int32_t id_delta) {
  id_delta_ = id_delta;
}

int32_t CMapTable::CMapFormat4::Builder::Segment::id_range_offset() {
  return id_range_offset_;
}

void
CMapTable::CMapFormat4::Builder::Segment::
set_id_range_offset(int32_t id_range_offset) {
  id_range_offset_ = id_range_offset;
}

// static
CALLER_ATTACH SegmentList*
CMapTable::CMapFormat4::Builder::Segment::DeepCopy(SegmentList* original) {
  SegmentList* list = new SegmentList;
  for (SegmentList::iterator it = original->begin(),
           e = original->end(); it != e; ++it) {
    list->push_back(*it);
  }
  return list;
}

/******************************************************************************
 * CMapTable::CMapFormat4::Builder class
 ******************************************************************************/
CALLER_ATTACH CMapTable::CMapFormat4::Builder*
CMapTable::CMapFormat4::Builder::NewInstance(ReadableFontData* data,
                                             int32_t offset,
                                             const CMapId& cmap_id) {
  ReadableFontDataPtr rdata;
  if (data) {
    rdata.Attach
        (down_cast<ReadableFontData*>
         (data->Slice(offset,
                      data->ReadUShort(offset + Offset::kFormat4Length))));
  }
  return new Builder(rdata, CMapFormat::kFormat4, cmap_id);
}

CALLER_ATTACH CMapTable::CMapFormat4::Builder*
CMapTable::CMapFormat4::Builder::NewInstance(WritableFontData* data,
                                             int32_t offset,
                                             const CMapId& cmap_id) {
  WritableFontDataPtr wdata;
  if (data) {
    wdata.Attach
        (down_cast<WritableFontData*>
         (data->Slice(offset,
                      data->ReadUShort(offset + Offset::kFormat4Length))));
  }
  return new Builder(wdata, CMapFormat::kFormat4, cmap_id);
}

CALLER_ATTACH CMapTable::CMapFormat4::Builder*
CMapTable::CMapFormat4::Builder::NewInstance(const CMapId& cmap_id) {
  return new Builder(cmap_id);
}

CMapTable::CMapFormat4::Builder::Builder(ReadableFontData* data, int32_t offset,
                                         const CMapId& cmap_id)
    : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) {
  UNREFERENCED_PARAMETER(offset);
}

CMapTable::CMapFormat4::Builder::Builder(WritableFontData* data, int32_t offset,
                                         const CMapId& cmap_id)
    : CMap::Builder(data, CMapFormat::kFormat4, cmap_id) {
  UNREFERENCED_PARAMETER(offset);
}

CMapTable::CMapFormat4::Builder::Builder(SegmentList* segments,
                                         IntegerList* glyph_id_array,
                                         const CMapId& cmap_id)
    : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
                    CMapFormat::kFormat4, cmap_id),
      segments_(segments->begin(), segments->end()),
      glyph_id_array_(glyph_id_array->begin(), glyph_id_array->end()) {
  set_model_changed();
}

CMapTable::CMapFormat4::Builder::Builder(const CMapId& cmap_id)
    : CMap::Builder(reinterpret_cast<ReadableFontData*>(NULL),
                    CMapFormat::kFormat4, cmap_id) {
}

CMapTable::CMapFormat4::Builder::~Builder() {}

void CMapTable::CMapFormat4::Builder::Initialize(ReadableFontData* data) {
  if (data == NULL || data->Length() == 0)
    return;

  // build segments
  int32_t seg_count = CMapFormat4::SegCount(data);
  for (int32_t index = 0; index < seg_count; ++index) {
    Ptr<Segment> segment = new Segment;
    segment->set_start_count(CMapFormat4::StartCode(data, seg_count, index));
#if defined SFNTLY_DEBUG_CMAP
    fprintf(stderr, "Segment %d; start %d\n", index, segment->start_count());
#endif
    segment->set_end_count(CMapFormat4::EndCode(data, seg_count, index));
    segment->set_id_delta(CMapFormat4::IdDelta(data, seg_count, index));
    segment->set_id_range_offset(CMapFormat4::IdRangeOffset(data,
                                                           seg_count,
                                                           index));
    segments_.push_back(segment);
  }

  // build glyph id array
  int32_t glyph_id_array_offset = CMapFormat4::GlyphIdArrayOffset(seg_count);
  int32_t glyph_id_array_length =
      (CMapFormat4::Length(data) - glyph_id_array_offset)
      / DataSize::kUSHORT;
  fprintf(stderr, "id array size %d\n", glyph_id_array_length);
  for (int32_t i = 0; i < glyph_id_array_length; i += DataSize::kUSHORT) {
    glyph_id_array_.push_back(data->ReadUShort(glyph_id_array_offset + i));
  }
}

SegmentList* CMapTable::CMapFormat4::Builder::segments() {
  if (segments_.empty()) {
    Initialize(InternalReadData());
    set_model_changed();
  }
  return &segments_;
}

void CMapTable::CMapFormat4::Builder::set_segments(SegmentList* segments) {
  segments_.assign(segments->begin(), segments->end());
  set_model_changed();
}

IntegerList* CMapTable::CMapFormat4::Builder::glyph_id_array() {
  if (glyph_id_array_.empty()) {
    Initialize(InternalReadData());
    set_model_changed();
  }
  return &glyph_id_array_;
}

void CMapTable::CMapFormat4::Builder::
set_glyph_id_array(IntegerList* glyph_id_array) {
  glyph_id_array_.assign(glyph_id_array->begin(), glyph_id_array->end());
  set_model_changed();
}

CALLER_ATTACH FontDataTable*
CMapTable::CMapFormat4::Builder::SubBuildTable(ReadableFontData* data) {
  FontDataTablePtr table = new CMapFormat4(data, cmap_id());
  return table.Detach();
}

void CMapTable::CMapFormat4::Builder::SubDataSet() {
  segments_.clear();
  glyph_id_array_.clear();
  set_model_changed();
}

int32_t CMapTable::CMapFormat4::Builder::SubDataSizeToSerialize() {
  if (!model_changed()) {
    return CMap::Builder::SubDataSizeToSerialize();
  }
  int32_t size = Offset::kFormat4FixedSize + segments_.size()
      * (3 * DataSize::kUSHORT + DataSize::kSHORT)
      + glyph_id_array_.size() * DataSize::kSHORT;
  return size;
}

bool CMapTable::CMapFormat4::Builder::SubReadyToSerialize() {
  if (!model_changed()) {
    return CMap::Builder::SubReadyToSerialize();
  }
  if (!segments()->empty()) {
    return true;
  }
  return false;
}

int32_t
CMapTable::CMapFormat4::Builder::SubSerialize(WritableFontData* new_data) {
  if (!model_changed()) {
    return CMap::Builder::SubSerialize(new_data);
  }
  int32_t index = 0;
  index += new_data->WriteUShort(index, CMapFormat::kFormat4);
  index += DataSize::kUSHORT;  // length - write this at the end
  index += new_data->WriteUShort(index, language());

  int32_t seg_count = segments_.size();
  index += new_data->WriteUShort(index, seg_count * 2);
  int32_t log2_seg_count = FontMath::Log2(seg_count);
  int32_t search_range = 1 << (log2_seg_count + 1);
  index += new_data->WriteUShort(index, search_range);
  int32_t entry_selector = log2_seg_count;
  index += new_data->WriteUShort(index, entry_selector);
  int32_t range_shift = 2 * seg_count - search_range;
  index += new_data->WriteUShort(index, range_shift);

  for (int32_t i = 0; i < seg_count; ++i) {
    index += new_data->WriteUShort(index, segments_[i]->end_count());
  }
  index += new_data->WriteUShort(index, 0);  // reserved ushort
  for (int32_t i = 0; i < seg_count; ++i) {
#if defined SFNTLY_DEBUG_CMAP
    fprintf(stderr, "Segment %d; start %d\n", i, segments_[i]->start_count());
#endif
    index += new_data->WriteUShort(index, segments_[i]->start_count());
  }
  for (int32_t i = 0; i < seg_count; ++i) {
    index += new_data->WriteShort(index, segments_[i]->id_delta());
  }
  for (int32_t i = 0; i < seg_count; ++i) {
    index += new_data->WriteUShort(index, segments_[i]->id_range_offset());
  }

#if defined SFNTLY_DEBUG_CMAP
  fprintf(stderr, "Glyph id array size %lu\n", glyph_id_array_.size());
#endif
  for (size_t i = 0; i < glyph_id_array_.size(); ++i) {
    index += new_data->WriteUShort(index, glyph_id_array_[i]);
  }

  new_data->WriteUShort(Offset::kFormat4Length, index);
  return index;
}

/******************************************************************************
 * CMapTable::Builder class
 ******************************************************************************/
CMapTable::Builder::Builder(Header* header, WritableFontData* data)
    : SubTableContainerTable::Builder(header, data), version_(0) {
}

CMapTable::Builder::Builder(Header* header, ReadableFontData* data)
    : SubTableContainerTable::Builder(header, data), version_(0) {
}

CMapTable::Builder::~Builder() {
}

int32_t CMapTable::Builder::SubSerialize(WritableFontData* new_data) {
  int32_t size = new_data->WriteUShort(CMapTable::Offset::kVersion,
                                       version_);
  size += new_data->WriteUShort(CMapTable::Offset::kNumTables,
                                GetCMapBuilders()->size());

  int32_t index_offset = size;
  size += GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize;
  for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
           e = GetCMapBuilders()->end(); it != e; ++it) {
    CMapBuilderPtr b = it->second;
    // header entry
    index_offset += new_data->WriteUShort(index_offset, b->platform_id());
    index_offset += new_data->WriteUShort(index_offset, b->encoding_id());
    index_offset += new_data->WriteULong(index_offset, size);

    // cmap
    FontDataPtr slice;
    slice.Attach(new_data->Slice(size));
    size += b->SubSerialize(down_cast<WritableFontData*>(slice.p_));
  }
  return size;
}

bool CMapTable::Builder::SubReadyToSerialize() {
  if (GetCMapBuilders()->empty())
    return false;

  // check each table
  for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
           e = GetCMapBuilders()->end(); it != e; ++it) {
    if (!it->second->SubReadyToSerialize())
      return false;
  }
  return true;
}

int32_t CMapTable::Builder::SubDataSizeToSerialize() {
  if (GetCMapBuilders()->empty())
    return 0;

  bool variable = false;
  int32_t size = CMapTable::Offset::kEncodingRecordStart +
      GetCMapBuilders()->size() * CMapTable::Offset::kEncodingRecordSize;

  // calculate size of each table
  for (CMapBuilderMap::iterator it = GetCMapBuilders()->begin(),
           e = GetCMapBuilders()->end(); it != e; ++it) {
    int32_t cmap_size = it->second->SubDataSizeToSerialize();
    size += abs(cmap_size);
    variable |= cmap_size <= 0;
  }
  return variable ? -size : size;
}

void CMapTable::Builder::SubDataSet() {
  GetCMapBuilders()->clear();
  Table::Builder::set_model_changed();
}

CALLER_ATTACH FontDataTable*
    CMapTable::Builder::SubBuildTable(ReadableFontData* data) {
  FontDataTablePtr table = new CMapTable(header(), data);
  return table.Detach();
}

CALLER_ATTACH CMapTable::Builder*
    CMapTable::Builder::CreateBuilder(Header* header,
                                      WritableFontData* data) {
  Ptr<CMapTable::Builder> builder;
  builder = new CMapTable::Builder(header, data);
  return builder.Detach();
}

// static
CALLER_ATTACH CMapTable::CMap::Builder*
    CMapTable::Builder::CMapBuilder(ReadableFontData* data, int32_t index) {
  if (index < 0 || index > NumCMaps(data)) {
#if !defined (SFNTLY_NO_EXCEPTION)
    throw IndexOutOfBoundException(
              "CMap table is outside of the bounds of the known tables.");
#endif
    return NULL;
  }

  int32_t platform_id = data->ReadUShort(Offset::kEncodingRecordPlatformId +
                                         OffsetForEncodingRecord(index));
  int32_t encoding_id = data->ReadUShort(Offset::kEncodingRecordEncodingId +
                                         OffsetForEncodingRecord(index));
  int32_t offset = data->ReadULongAsInt(Offset::kEncodingRecordOffset +
                                        OffsetForEncodingRecord(index));
  return CMap::Builder::GetBuilder(data, offset,
                                   NewCMapId(platform_id, encoding_id));
}

// static
int32_t CMapTable::Builder::NumCMaps(ReadableFontData* data) {
  if (data == NULL) {
    return 0;
  }
  return data->ReadUShort(Offset::kNumTables);
}

int32_t CMapTable::Builder::NumCMaps() {
  return GetCMapBuilders()->size();
}

void CMapTable::Builder::Initialize(ReadableFontData* data) {
  int32_t num_cmaps = NumCMaps(data);
  for (int32_t i = 0; i < num_cmaps; ++i) {
    CMapTable::CMap::Builder* cmap_builder = CMapBuilder(data, i);
    if (!cmap_builder)
      continue;
    cmap_builders_[cmap_builder->cmap_id()] = cmap_builder;
  }
}

CMapTable::CMap::Builder* CMapTable::Builder::NewCMapBuilder(
    const CMapId& cmap_id,
    ReadableFontData* data) {
  Ptr<WritableFontData> wfd;
  wfd.Attach(WritableFontData::CreateWritableFontData(data->Size()));
  data->CopyTo(wfd.p_);
  CMapTable::CMapBuilderPtr builder;
  builder.Attach(CMap::Builder::GetBuilder(wfd.p_, 0, cmap_id));
  CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders();
  cmap_builders->insert(std::make_pair(cmap_id, builder.p_));
  return builder.Detach();
}

CMapTable::CMap::Builder*
CMapTable::Builder::NewCMapBuilder(int32_t format, const CMapId& cmap_id) {
  Ptr<CMapTable::CMap::Builder> cmap_builder;
  cmap_builder.Attach(CMap::Builder::GetBuilder(format, cmap_id));
  CMapBuilderMap* cmap_builders = CMapTable::Builder::GetCMapBuilders();
  cmap_builders->insert(std::make_pair(cmap_id, cmap_builder.p_));
  return cmap_builder.Detach();
}

CMapTable::CMap::Builder*
CMapTable::Builder::CMapBuilder(const CMapId& cmap_id) {
  CMapBuilderMap* cmap_builders = this->GetCMapBuilders();
  CMapBuilderMap::iterator builder = cmap_builders->find(cmap_id);
  if (builder != cmap_builders->end())
    return builder->second;
#ifndef SFNTLY_NO_EXCEPTION
  throw NoSuchElementException("No builder found for cmap_id");
#else
  return NULL;
#endif
}

CMapTable::CMapBuilderMap* CMapTable::Builder::GetCMapBuilders() {
  if (cmap_builders_.empty()) {
    Initialize(InternalReadData());
    set_model_changed();
  }
  return &cmap_builders_;
}

}  // namespace sfntly
