130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/*
230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Copyright 2011 Google Inc. All Rights Reserved.
330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Licensed under the Apache License, Version 2.0 (the "License");
530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * you may not use this file except in compliance with the License.
630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * You may obtain a copy of the License at
730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *      http://www.apache.org/licenses/LICENSE-2.0
930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun *
1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * Unless required by applicable law or agreed to in writing, software
1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * distributed under the License is distributed on an "AS IS" BASIS,
1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * See the License for the specific language governing permissions and
1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * limitations under the License.
1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun */
1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/bitmap/eblc_table.h"
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <stdio.h>
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <stdlib.h>
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/math/font_math.h"
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/******************************************************************************
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * EblcTable class
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t EblcTable::Version() {
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return data_->ReadFixed(Offset::kVersion);
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t EblcTable::NumSizes() {
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return data_->ReadULongAsInt(Offset::kNumSizes);
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunBitmapSizeTable* EblcTable::GetBitmapSizeTable(int32_t index) {
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (index < 0 || index > NumSizes()) {
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if !defined (SFNTLY_NO_EXCEPTION)
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    throw IndexOutOfBoundException(
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        "Size table index is outside the range of tables.");
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return NULL;
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTableList* bitmap_size_table_list = GetBitmapSizeTableList();
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (bitmap_size_table_list) {
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return (*bitmap_size_table_list)[index];
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return NULL;
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunEblcTable::EblcTable(Header* header, ReadableFontData* data)
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    : SubTableContainerTable(header, data) {
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunBitmapSizeTableList* EblcTable::GetBitmapSizeTableList() {
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  AutoLock lock(bitmap_size_table_lock_);
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (bitmap_size_table_.empty()) {
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CreateBitmapSizeTable(data_, NumSizes(), &bitmap_size_table_);
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return &bitmap_size_table_;
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid EblcTable::CreateBitmapSizeTable(ReadableFontData* data,
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                      int32_t num_sizes,
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                      BitmapSizeTableList* output) {
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  assert(data);
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  assert(output);
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (int32_t i = 0; i < num_sizes; ++i) {
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    ReadableFontDataPtr new_data;
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    new_data.Attach(down_cast<ReadableFontData*>(
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        data->Slice(Offset::kBitmapSizeTableArrayStart +
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                    i * Offset::kBitmapSizeTableLength,
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                    Offset::kBitmapSizeTableLength)));
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    BitmapSizeTableBuilderPtr size_builder;
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    size_builder.Attach(
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        BitmapSizeTable::Builder::CreateBuilder(new_data, data));
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    BitmapSizeTablePtr size;
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    size.Attach(down_cast<BitmapSizeTable*>(size_builder->Build()));
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    output->push_back(size);
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun/******************************************************************************
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun * EblcTable::Builder class
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ******************************************************************************/
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunEblcTable::Builder::Builder(Header* header, WritableFontData* data)
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    : SubTableContainerTable::Builder(header, data) {
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunEblcTable::Builder::Builder(Header* header, ReadableFontData* data)
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    : SubTableContainerTable::Builder(header, data) {
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunEblcTable::Builder::~Builder() {
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t EblcTable::Builder::SubSerialize(WritableFontData* new_data) {
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // header
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t size = new_data->WriteFixed(0, kVersion);
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  size += new_data->WriteULong(size, size_table_builders_.size());
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // calculate the offsets
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // offset to the start of the size table array
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t size_table_start_offset = size;
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // walking offset in the size table array
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t size_table_offset = size_table_start_offset;
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // offset to the start of the whole index subtable block
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t sub_table_block_start_offset = size_table_offset +
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      size_table_builders_.size() * Offset::kBitmapSizeTableLength;
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // walking offset in the index subtable
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // points to the start of the current subtable block
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t current_sub_table_block_start_offset = sub_table_block_start_offset;
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t size_index = 0;
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (BitmapSizeTableBuilderList::iterator
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun           size_builder = size_table_builders_.begin(),
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun           size_builder_end = size_table_builders_.end();
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun       size_builder != size_builder_end; size_builder++) {
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    (*size_builder)->SetIndexSubTableArrayOffset(
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        current_sub_table_block_start_offset);
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    IndexSubTableBuilderList* index_sub_table_builder_list =
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        (*size_builder)->IndexSubTableBuilders();
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // walking offset within the current subTable array
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t index_sub_table_array_offset = current_sub_table_block_start_offset;
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // walking offset within the subTable entries
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t index_sub_table_offset = index_sub_table_array_offset +
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        index_sub_table_builder_list->size() * Offset::kIndexSubHeaderLength;
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    fprintf(stderr, "size %d: sizeTable=%x, current subTable Block=%x, ",
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            size_index, size_table_offset,
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            current_sub_table_block_start_offset);
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    fprintf(stderr, "index subTableStart=%x\n", index_sub_table_offset);
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    size_index++;
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t sub_table_index = 0;
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    for (IndexSubTableBuilderList::iterator
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun             index_sub_table_builder = index_sub_table_builder_list->begin(),
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun             index_sub_table_builder_end = index_sub_table_builder_list->end();
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         index_sub_table_builder != index_sub_table_builder_end;
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun         index_sub_table_builder++) {
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      fprintf(stderr, "\tsubTableIndex %d: format=%x, ", sub_table_index,
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              (*index_sub_table_builder)->index_format());
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      fprintf(stderr, "indexSubTableArrayOffset=%x, indexSubTableOffset=%x\n",
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              index_sub_table_array_offset, index_sub_table_offset);
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      sub_table_index++;
15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // array entry
15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      index_sub_table_array_offset += new_data->WriteUShort(
15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          index_sub_table_array_offset,
15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          (*index_sub_table_builder)->first_glyph_index());
15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      index_sub_table_array_offset += new_data->WriteUShort(
15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          index_sub_table_array_offset,
15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          (*index_sub_table_builder)->last_glyph_index());
16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      index_sub_table_array_offset += new_data->WriteULong(
16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          index_sub_table_array_offset,
16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          index_sub_table_offset - current_sub_table_block_start_offset);
16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // index sub table
16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      WritableFontDataPtr slice_index_sub_table;
16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      slice_index_sub_table.Attach(down_cast<WritableFontData*>(
16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          new_data->Slice(index_sub_table_offset)));
16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t current_sub_table_size =
16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          (*index_sub_table_builder)->SubSerialize(slice_index_sub_table);
17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t padding = FontMath::PaddingRequired(current_sub_table_size,
17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                  DataSize::kULONG);
17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      fprintf(stderr, "\t\tsubTableSize = %x, padding = %x\n",
17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              current_sub_table_size, padding);
17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      index_sub_table_offset += current_sub_table_size;
17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      index_sub_table_offset +=
17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          new_data->WritePadding(index_sub_table_offset, padding);
17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    }
18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // serialize size table
18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    (*size_builder)->SetIndexTableSize(
18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        index_sub_table_offset - current_sub_table_block_start_offset);
18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    WritableFontDataPtr slice_size_table;
18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    slice_size_table.Attach(down_cast<WritableFontData*>(
18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        new_data->Slice(size_table_offset)));
18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    size_table_offset += (*size_builder)->SubSerialize(slice_size_table);
18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    current_sub_table_block_start_offset = index_sub_table_offset;
19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return size + current_sub_table_block_start_offset;
19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunbool EblcTable::Builder::SubReadyToSerialize() {
19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (size_table_builders_.empty()) {
19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return false;
19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                            e = size_table_builders_.end();
20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                            b != e; b++) {
20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    if (!(*b)->SubReadyToSerialize()) {
20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return false;
20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    }
20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return true;
20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunint32_t EblcTable::Builder::SubDataSizeToSerialize() {
20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (size_table_builders_.empty()) {
21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    return 0;
21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t size = Offset::kHeaderLength;
21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  bool variable = false;
21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  size_t size_index = 0;
21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (BitmapSizeTableBuilderList::iterator b = size_table_builders_.begin(),
21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                            e = size_table_builders_.end();
21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                            b != e; b++) {
22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t size_builder_size = (*b)->SubDataSizeToSerialize();
22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    fprintf(stderr, "sizeIndex = %d, sizeBuilderSize=0x%x (%d)\n",
22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun            size_index++, size_builder_size, size_builder_size);
22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    variable = size_builder_size > 0 ? variable : true;
22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    size += abs(size_builder_size);
22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  fprintf(stderr, "eblc size=%d\n", size);
23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return variable ? -size : size;
23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid EblcTable::Builder::SubDataSet() {
23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Revert();
23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunBitmapSizeTableBuilderList* EblcTable::Builder::BitmapSizeBuilders() {
23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return GetSizeList();
24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid EblcTable::Builder::Revert() {
24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  size_table_builders_.clear();
24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  set_model_changed(false);
24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
24730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid EblcTable::Builder::GenerateLocaList(BitmapLocaList* output) {
24830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  assert(output);
24930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  BitmapSizeTableBuilderList* size_builder_list = GetSizeList();
25030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  output->clear();
25130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
25230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  int32_t size_index = 0;
25330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
25430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  for (BitmapSizeTableBuilderList::iterator b = size_builder_list->begin(),
25530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                            e = size_builder_list->end();
25630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                            b != e; b++) {
25730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#if defined (SFNTLY_DEBUG_BITMAP)
25830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    fprintf(stderr, "size table = %d\n", size_index++);
25930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif
26030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    BitmapGlyphInfoMap loca_map;
26130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    (*b)->GenerateLocaMap(&loca_map);
26230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    output->push_back(loca_map);
26330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
26430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
26530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
26630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH
26730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunFontDataTable* EblcTable::Builder::SubBuildTable(ReadableFontData* data) {
26830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<EblcTable> new_table = new EblcTable(header(), data);
26930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return new_table.Detach();
27030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
27130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
27230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static
27330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH EblcTable::Builder*
27430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EblcTable::Builder::CreateBuilder(Header* header, WritableFontData* data) {
27530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
27630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return new_builder.Detach();
27730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
27830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
27930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// static
28030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunCALLER_ATTACH EblcTable::Builder*
28130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    EblcTable::Builder::CreateBuilder(Header* header, ReadableFontData* data) {
28230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  Ptr<EblcTable::Builder> new_builder = new EblcTable::Builder(header, data);
28330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return new_builder.Detach();
28430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
28530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
28630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunBitmapSizeTableBuilderList* EblcTable::Builder::GetSizeList() {
28730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (size_table_builders_.empty()) {
28830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Initialize(InternalReadData(), &size_table_builders_);
28930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    set_model_changed();
29030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
29130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  return &size_table_builders_;
29230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
29330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
29430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid EblcTable::Builder::Initialize(ReadableFontData* data,
29530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                    BitmapSizeTableBuilderList* output) {
29630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  assert(output);
29730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  if (data) {
29830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t num_sizes = data->ReadULongAsInt(Offset::kNumSizes);
29930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    for (int32_t i = 0; i < num_sizes; ++i) {
30030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      ReadableFontDataPtr new_data;
30130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      new_data.Attach(down_cast<ReadableFontData*>(
30230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          data->Slice(Offset::kBitmapSizeTableArrayStart +
30330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      i * Offset::kBitmapSizeTableLength,
30430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      Offset::kBitmapSizeTableLength)));
30530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      BitmapSizeTableBuilderPtr size_builder;
30630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      size_builder.Attach(BitmapSizeTable::Builder::CreateBuilder(
30730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          new_data, data));
30830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      output->push_back(size_builder);
30930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    }
31030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  }
31130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}
31230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
31330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
314