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#ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// type.h needs to be included first because of building issues on Windows
2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Type aliases we delcare are defined in other headers and make the build
2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// fail otherwise.
2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/type.h"
2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <vector>
2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include <map>
2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/port/refcount.h"
2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/subtable.h"
2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "sfntly/table/subtable_container_table.h"
3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace sfntly {
3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// CMap subtable formats
3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstruct CMapFormat {
3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  enum {
3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat0 = 0,
3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat2 = 2,
3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat4 = 4,
3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat6 = 6,
4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat8 = 8,
4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat10 = 10,
4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat12 = 12,
4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat13 = 13,
4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    kFormat14 = 14
4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// A CMap table
4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass CMapTable : public SubTableContainerTable, public RefCounted<CMapTable> {
5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunpublic:
5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // CMapTable::CMapId
5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  struct CMapId {
5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t platform_id;
5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t encoding_id;
5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    bool operator==(const CMapId& obj) const {
5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      return platform_id == obj.platform_id && encoding_id == obj.encoding_id;
5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    }
5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static CMapId WINDOWS_BMP;
6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static CMapId WINDOWS_UCS4;
6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static CMapId MAC_ROMAN;
6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // CMapTable::CMapIdComparator
6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMapIdComparator {
6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    bool operator()(const CMapId& lhs, const CMapId& rhs) const;
6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // A filter on cmap
7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // CMapTable::CMapFilter
7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMapFilter {
7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Test on whether the cmap is acceptable or not
7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param cmap_id the id of the cmap
7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return true if the cmap is acceptable; false otherwise
7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual bool accept(const CMapId& cmap_id) const = 0;
7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Make gcc -Wnon-virtual-dtor happy.
7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~CMapFilter() {}
7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Filters CMaps by CMapId to implement CMapTable::get()
8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // wanted_id is the CMap we'd like to find.
8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // We compare the current CMap to it either by equality (==) or using a
8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // comparator.
8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // CMapTable::CMapIdFilter
8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMapIdFilter : public CMapFilter {
8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    explicit CMapIdFilter(const CMapId wanted_id);
8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapIdFilter(const CMapId wanted_id,
9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                 const CMapIdComparator* comparator);
9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    ~CMapIdFilter() {}
9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual bool accept(const CMapId& cmap_id) const;
9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapIdFilter& operator=(const CMapIdFilter& that);
9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    const CMapId wanted_id_;
9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    const CMapIdComparator *comparator_;
9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // The abstract base class for all cmaps.
10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  //
10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // CMap equality is based on the equality of the (@link {@link CMapId} that
10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // defines the CMap. In the cmap table for a font there can only be one cmap
10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // with a given cmap id (pair of platform and encoding ids) no matter what the
10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // type of the cmap is.
10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  //
10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // The cmap offers CharacterIterator to allow iteration over
10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // characters that are mapped by the cmap. This iteration mostly returns the
10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // characters mapped by the cmap. It will return all characters mapped by the
10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // cmap to anything but .notdef <b>but</b> it may return some that are not
11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // mapped or are mapped to .notdef. Various cmap tables provide ranges and
11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // such to describe characters for lookup but without going the full way to
11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // mapping to the glyph id it isn't always possible to tell if a character
11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // will end up with a valid glyph id. So, some of the characters returned from
11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // the Iterator may still end up pointing to the .notdef glyph. However, the
11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // number of such characters should be small in most cases with well designed
11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // cmaps.
11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class Builder;
11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMap : public SubTable {
11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // CMapTable::CMap::Builder
12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class Builder : public SubTable::Builder {
12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~Builder();
12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CALLER_ATTACH static Builder*
12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          GetBuilder(ReadableFontData* data,
12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                     int32_t offset,
12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                     const CMapId& cmap_id);
12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CALLER_ATTACH static Builder*
13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          GetBuilder(int32_t format,
13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                     const CMapId& cmap_id);
13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Note: yes, an object is returned on stack since it's small enough.
13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual CMapId cmap_id() { return cmap_id_; }
13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t platform_id() { return cmap_id_.platform_id; }
13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t format() { return format_; }
13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t language() { return language_; }
13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual void set_language(int32_t language) { language_ = language; }
14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     protected:
14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(ReadableFontData* data,
14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              int32_t format,
14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              const CMapId& cmap_id);
14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(WritableFontData* data,
14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              int32_t format,
14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              const CMapId& cmap_id);
14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t SubSerialize(WritableFontData* new_data);
15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual bool SubReadyToSerialize();
15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t SubDataSizeToSerialize();
15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual void SubDataSet();
15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     private:
15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t format_;
15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CMapId cmap_id_;
15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t language_;
15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      friend class CMapTable::Builder;
16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Abstract CMap character iterator
16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // The fully qualified name is CMapTable::CMap::CharacterIterator
16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class CharacterIterator {
16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~CharacterIterator() {}
16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual bool HasNext() = 0;
16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Returns -1 if there are no more characters to iterate through
16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // and exceptions are turned off
16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t Next() = 0;
17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     protected:
17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Use the CMap::Iterator method below instead of directly requesting
17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // a CharacterIterator.
17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CharacterIterator() {}
17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap(ReadableFontData* data, int32_t format, const CMapId& cmap_id);
17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~CMap();
17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual CMap::CharacterIterator* Iterator() = 0;
18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t format() { return format_; }
18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual CMapId cmap_id() { return cmap_id_; }
18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t platform_id() { return cmap_id_.platform_id; }
18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Get the language of the cmap.
18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    //
18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Note on the language field in 'cmap' subtables: The language field must
19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // be set to zero for all cmap subtables whose platform IDs are other than
19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Macintosh (platform ID 1). For cmap subtables whose platform IDs are
19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Macintosh, set this field to the Macintosh language ID of the cmap
19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // subtable plus one, or to zero if the cmap subtable is not
19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // language-specific. For example, a Mac OS Turkish cmap subtable must set
19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // this field to 18, since the Macintosh language ID for Turkish is 17. A
19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Mac OS Roman cmap subtable must set this field to 0, since Mac OS Roman
19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // is not a language-specific encoding.
19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    //
19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the language id
20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t Language() = 0;
20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Gets the glyph id for the character code provided.
20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // The character code provided must be in the encoding used by the cmap
20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // table.
20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphId(int32_t character) = 0;
20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t format_;
20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapId cmap_id_;
21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  typedef Ptr<CMap> CMapPtr;
21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  typedef Ptr<CMap::Builder> CMapBuilderPtr;
21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  typedef std::map<CMapId, CMapBuilderPtr, CMapIdComparator> CMapBuilderMap;
21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // A cmap format 0 sub table
21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMapFormat0 : public CMap, public RefCounted<CMapFormat0> {
21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // The fully qualified name is CMapTable::CMapFormat0::Builder
21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class Builder : public CMap::Builder,
22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                    public RefCounted<Builder> {
22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CALLER_ATTACH static Builder* NewInstance(ReadableFontData* data,
22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t offset,
22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                const CMapId& cmap_id);
22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CALLER_ATTACH static Builder* NewInstance(WritableFontData* data,
22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t offset,
22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                const CMapId& cmap_id);
22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CALLER_ATTACH static Builder* NewInstance(const CMapId& cmap_id);
22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~Builder();
23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     protected:
23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual CALLER_ATTACH FontDataTable*
23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          SubBuildTable(ReadableFontData* data);
23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     private:
23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // When creating a new CMapFormat0 Builder, use NewInstance instead of
23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // the constructors! This avoids a memory leak when slicing the FontData.
23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(const CMapId& cmap_id);
24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // The fully qualified name is CMapTable::CMapFormat0::CharacterIterator
24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class CharacterIterator : public CMap::CharacterIterator {
24530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
24630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~CharacterIterator();
24730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual bool HasNext();
24830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t Next();
24930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
25030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     private:
25130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CharacterIterator(int32_t start, int32_t end);
25230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      friend class CMapFormat0;
25330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t character_, max_character_;
25430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
25530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
25630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~CMapFormat0();
25730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t Language();
25830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphId(int32_t character);
25930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap::CharacterIterator* Iterator();
26030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
26130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
26230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapFormat0(ReadableFontData* data, const CMapId& cmap_id);
26330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
26430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
26530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // A cmap format 2 sub table
26630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // The format 2 cmap is used for multi-byte encodings such as SJIS,
26730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // EUC-JP/KR/CN, Big5, etc.
26830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMapFormat2 : public CMap, public RefCounted<CMapFormat2> {
26930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
27030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // CMapTable::CMapFormat2::Builder
27130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class Builder : public CMap::Builder,
27230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                    public RefCounted<Builder> {
27330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
27430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(ReadableFontData* data,
27530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              int32_t offset,
27630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              const CMapId& cmap_id);
27730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(WritableFontData* data,
27830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              int32_t offset,
27930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              const CMapId& cmap_id);
28030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~Builder();
28130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
28230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     protected:
28330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual CALLER_ATTACH FontDataTable*
28430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          SubBuildTable(ReadableFontData* data);
28530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
28630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // CMapTable::CMapFormat2::CharacterIterator
28730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class CharacterIterator : public CMap::CharacterIterator {
28830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
28930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~CharacterIterator();
29030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual bool hasNext();
29130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t next();
29230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
29330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     private:
29430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CharacterIterator();
29530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
29630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
29730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t Language();
29830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphId(int32_t character);
29930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
30030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Returns how many bytes would be consumed by a lookup of this character
30130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // with this cmap. This comes about because the cmap format 2 table is
30230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // designed around multi-byte encodings such as SJIS, EUC-JP, Big5, etc.
30330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // return the number of bytes consumed from this "character" - either 1 or 2
30430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t BytesConsumed(int32_t character);
30530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
30630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~CMapFormat2();
30730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
30830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
30930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapFormat2(ReadableFontData* data, const CMapId& cmap_id);
31030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
31130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t SubHeaderOffset(int32_t sub_header_index);
31230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t FirstCode(int32_t sub_header_index);
31330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t EntryCount(int32_t sub_header_index);
31430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t IdRangeOffset(int32_t sub_header_index);
31530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t IdDelta(int32_t sub_header_index);
31630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap::CharacterIterator* Iterator();
31730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
31830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
31930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // CMapTable::CMapFormat4
32030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMapFormat4 : public CMap,
32130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                      public RefCounted<CMapFormat4> {
32230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
32330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // CMapTable::CMapFormat4::Builder
32430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class Builder : public CMap::Builder,
32530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                    public RefCounted<Builder> {
32630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
32730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // CMapTable::CMapFormat4::Builder::Segment
32830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      class Segment : public RefCounted<Segment> {
32930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun       public:
33030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        Segment();
33130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        explicit Segment(Segment* other);
33230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        Segment(int32_t start_count,
33330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                int32_t end_count,
33430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                int32_t id_delta,
33530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                int32_t id_range_offset);
33630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        ~Segment();
33730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
33830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @return the startCount
33930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t start_count();
34030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @param startCount the startCount to set
34130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        void set_start_count(int32_t start_count);
34230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @return the endCount
34330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t end_count();
34430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @param endcount the endCount to set
34530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        void set_end_count(int32_t end_count);
34630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @return the idDelta
34730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t id_delta();
34830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @param idDelta the idDelta to set
34930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        void set_id_delta(int32_t id_delta);
35030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @return the idRangeOffset
35130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t id_range_offset();
35230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        // @param idRangeOffset the idRangeOffset to set
35330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        void set_id_range_offset(int32_t id_range_offset);
35430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
35530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        static CALLER_ATTACH
35630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        std::vector<Ptr<Segment> >*
35730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        DeepCopy(std::vector<Ptr<Segment> >* original);
35830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
35930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun       private:
36030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t start_count_;
36130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t end_count_;
36230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t id_delta_;
36330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun        int32_t id_range_offset_;
36430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      };
36530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      typedef std::vector<Ptr<Segment> > SegmentList;
36630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
36730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      static CALLER_ATTACH Builder* NewInstance(WritableFontData* data,
36830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t offset,
36930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                const CMapId& cmap_id);
37030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      static CALLER_ATTACH Builder* NewInstance(ReadableFontData* data,
37130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                int32_t offset,
37230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                const CMapId& cmap_id);
37330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      static CALLER_ATTACH Builder* NewInstance(const CMapId& cmap_id);
37430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~Builder();
37530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      SegmentList* segments();
37630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      void set_segments(SegmentList* segments);
37730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      IntegerList* glyph_id_array();
37830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      void set_glyph_id_array(IntegerList* glyph_id_array);
37930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
38030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     protected:
38130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
38230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
38330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      Builder(SegmentList* segments, IntegerList* glyph_id_array,
38430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun              const CMapId& cmap_id);
38530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      explicit Builder(const CMapId& cmap_id);
38630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
38730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual CALLER_ATTACH FontDataTable* SubBuildTable(
38830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun          ReadableFontData* data);
38930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual void SubDataSet();
39030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t SubDataSizeToSerialize();
39130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual bool SubReadyToSerialize();
39230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual int32_t SubSerialize(WritableFontData* new_data);
39330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
39430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     private:
39530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      void Initialize(ReadableFontData* data);
39630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
39730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      SegmentList segments_;
39830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      IntegerList glyph_id_array_;
39930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
40030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
40130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap::CharacterIterator* Iterator();
40230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // CMapTable::CMapFormat4::CharacterIterator
40330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    class CharacterIterator : public CMap::CharacterIterator {
40430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     public:
40530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      bool HasNext();
40630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t Next();
40730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      virtual ~CharacterIterator() {}
40830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
40930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun     private:
41030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      explicit CharacterIterator(CMapFormat4 *parent);
41130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      friend CMap::CharacterIterator* CMapFormat4::Iterator();
41230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
41330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      CMapFormat4* parent_;
41430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t segment_index_;
41530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t first_char_in_segment_;
41630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t last_char_in_segment_;
41730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      int32_t next_char_;
41830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      bool next_char_set_;
41930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
42030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
42130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t GlyphId(int32_t character);
42230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
42330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Lower level glyph code retrieval that requires processing the Format 4
42430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // segments to use.
42530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param segment the cmap segment
42630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param startCode the start code for the segment
42730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param character the character to be looked up
42830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the glyph id for the character; CMapTable.NOTDEF if not found
42930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t RetrieveGlyphId(int32_t segment,
43030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                            int32_t start_count,
43130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                            int32_t character);
43230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t Language();
43330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
43430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Get the count of the number of segments in this cmap.
43530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the number of segments
43630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t seg_count();
43730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t Length();
43830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Get the start code for a segment.
43930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param segment the segment in the lookup table
44030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the start code for a segment
44130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t StartCode(int32_t segment);
44230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Get the end code for a segment.
44330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param segment the segment in the look up table
44430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the end code for the segment
44530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t EndCode(int32_t segment);
44630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Get the id delta for a segment
44730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param segment the segment in the look up table
44830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the id delta for the segment
44930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t IdDelta(int32_t segment);
45030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Get the id range offset for a segment
45130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param segment the segment in the look up table
45230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the id range offset for the segment
45330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t IdRangeOffset(int32_t segment);
45430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Get the location of the id range offset for a segment
45530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @param segment the segment in the look up table
45630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // @return the location of the id range offset for the segment
45730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t IdRangeOffsetLocation(int32_t segment);
45830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Declared above to allow friending inside CharacterIterator class.
45930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // CMap::CharacterIterator* Iterator();
46030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~CMapFormat4();
46130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
46230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   protected:
46330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapFormat4(ReadableFontData* data, const CMapId& cmap_id);
46430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
46530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
46630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t Language(ReadableFontData* data);
46730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t Length(ReadableFontData* data);
46830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t SegCount(ReadableFontData* data);
46930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t StartCode(ReadableFontData* data,
47030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                             int32_t seg_count,
47130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                             int32_t index);
47230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t StartCodeOffset(int32_t seg_count);
47330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t EndCode(ReadableFontData* data,
47430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                           int32_t seg_count,
47530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                           int32_t index);
47630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t IdDelta(ReadableFontData* data,
47730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                           int32_t seg_count,
47830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                           int32_t index);
47930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t IdDeltaOffset(int32_t seg_count);
48030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t IdRangeOffset(ReadableFontData* data,
48130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                 int32_t seg_count,
48230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                 int32_t index);
48330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t IdRangeOffsetOffset(int32_t seg_count);
48430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t GlyphIdArrayOffset(int32_t seg_count);
48530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Refactored void to bool to work without exceptions.
48630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    bool IsValidIndex(int32_t segment);
48730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t GlyphIdArray(int32_t index);
48830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
48930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t seg_count_;
49030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t start_code_offset_;
49130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t id_delta_offset_;
49230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t glyph_id_array_offset_;
49330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
49430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
49530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // CMapTable::Builder
49630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class Builder : public SubTableContainerTable::Builder,
49730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                  public RefCounted<Builder> {
49830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
49930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Constructor scope is public because C++ does not allow base class to
50030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // instantiate derived class with protected constructors.
50130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(Header* header, WritableFontData* data);
50230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    Builder(Header* header, ReadableFontData* data);
50330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual ~Builder();
50430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
50530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t SubSerialize(WritableFontData* new_data);
50630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual bool SubReadyToSerialize();
50730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual int32_t SubDataSizeToSerialize();
50830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual void SubDataSet();
50930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
51030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
51130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static CALLER_ATTACH Builder* CreateBuilder(Header* header,
51230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                WritableFontData* data);
51330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
51430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap::Builder* NewCMapBuilder(const CMapId& cmap_id,
51530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                  ReadableFontData* data);
51630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // Create a new empty CMapBuilder of the type specified in the id.
51730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap::Builder* NewCMapBuilder(int32_t format, const CMapId& cmap_id);
51830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap::Builder* CMapBuilder(const CMapId& cmap_id);
51930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
52030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t NumCMaps();
52130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void SetVersion(int32_t version);
52230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
52330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapBuilderMap* GetCMapBuilders();
52430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
52530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   protected:
52630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static CALLER_ATTACH CMap::Builder* CMapBuilder(ReadableFontData* data,
52730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                                                    int32_t index);
52830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
52930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
53030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    void Initialize(ReadableFontData* data);
53130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    static int32_t NumCMaps(ReadableFontData* data);
53230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
53330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t version_;
53430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapBuilderMap cmap_builders_;
53530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
53630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  typedef Ptr<Builder> CMapTableBuilderPtr;
53730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
53830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  class CMapIterator {
53930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   public:
54030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    // If filter is NULL, filter through all tables.
54130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapIterator(CMapTable* table, const CMapFilter* filter);
54230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    bool HasNext();
54330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMap* Next();
54430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
54530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun   private:
54630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    int32_t table_index_;
54730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    const CMapFilter* filter_;
54830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    CMapTable* table_;
54930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
55030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
55130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Make a CMapId from a platform_id, encoding_id pair
55230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static CMapId NewCMapId(int32_t platform_id, int32_t encoding_id);
55330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Make a CMapId from another CMapId
55430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static CMapId NewCMapId(const CMapId& obj);
55530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
55630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Get the CMap with the specified parameters if it exists.
55730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Returns NULL otherwise.
55830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CALLER_ATTACH CMap* GetCMap(const int32_t index);
55930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CALLER_ATTACH CMap* GetCMap(const int32_t platform_id,
56030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun                              const int32_t encoding_id);
56130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CALLER_ATTACH CMap* GetCMap(const CMapId GetCMap_id);
56230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
56330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Get the table version.
56430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t Version();
56530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
56630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Get the number of cmaps within the CMap table.
56730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t NumCMaps();
56830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
56930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Get the cmap id for the cmap with the given index.
57030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Note: yes, an object is returned on stack since it's small enough.
57130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  //       This function is renamed from cmapId to GetCMapId().
57230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual CMapId GetCMapId(int32_t index);
57330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
57430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t PlatformId(int32_t index);
57530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t EncodingId(int32_t index);
57630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
57730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Get the offset in the table data for the cmap table with the given index.
57830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // The offset is from the beginning of the table.
57930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual int32_t Offset(int32_t index);
58030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
58130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  virtual ~CMapTable();
58230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
58330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static const int32_t NOTDEF;
58430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
58530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private:
58630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Offsets to specific elements in the underlying data. These offsets are
58730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // relative to the start of the table or the start of sub-blocks within
58830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // the table.
58930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  struct Offset {
59030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    enum {
59130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kVersion = 0,
59230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kNumTables = 2,
59330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kEncodingRecordStart = 4,
59430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
59530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // offsets relative to the encoding record
59630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kEncodingRecordPlatformId = 0,
59730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kEncodingRecordEncodingId = 2,
59830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kEncodingRecordOffset = 4,
59930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kEncodingRecordSize = 8,
60030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
60130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat = 0,
60230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
60330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 0: Byte encoding table
60430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat0Format = 0,
60530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat0Length = 2,
60630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat0Language = 4,
60730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat0GlyphIdArray = 6,
60830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
60930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 2: High-byte mapping through table
61030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2Format = 0,
61130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2Length = 2,
61230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2Language = 4,
61330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2SubHeaderKeys = 6,
61430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2SubHeaders = 518,
61530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // offset relative to the subHeader structure
61630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2SubHeader_firstCode = 0,
61730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2SubHeader_entryCount = 2,
61830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2SubHeader_idDelta = 4,
61930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2SubHeader_idRangeOffset = 6,
62030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat2SubHeader_structLength = 8,
62130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
62230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 4: Segment mapping to delta values
62330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4Format = 0,
62430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4Length = 2,
62530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4Language = 4,
62630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4SegCountX2 = 6,
62730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4SearchRange = 8,
62830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4EntrySelector = 10,
62930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4RangeShift = 12,
63030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4EndCount = 14,
63130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat4FixedSize = 16,
63230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
63330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // format 6: Trimmed table mapping
63430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat6Format = 0,
63530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat6Length = 2,
63630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat6Language = 4,
63730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat6FirstCode = 6,
63830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat6EntryCount = 8,
63930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat6GlyphIdArray = 10,
64030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
64130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 8: mixed 16-bit and 32-bit coverage
64230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Format = 0,
64330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Length = 4,
64430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Language = 8,
64530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Is32 = 12,
64630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8nGroups204 = 8204,
64730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Groups208 = 8208,
64830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // offset relative to the group structure
64930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Group_startCharCode = 0,
65030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Group_endCharCode = 4,
65130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Group_startGlyphId = 8,
65230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat8Group_structLength = 12,
65330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
65430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 10: Trimmed array
65530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat10Format = 0,
65630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat10Length = 4,
65730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat10Language = 8,
65830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat10StartCharCode = 12,
65930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat10NumChars = 16,
66030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat10Glyphs0 = 20,
66130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
66230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 12: Segmented coverage
66330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12Format = 0,
66430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12Length = 4,
66530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12Language = 8,
66630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12nGroups = 12,
66730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12Groups = 16,
66830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12Groups_structLength = 12,
66930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // offsets within the group structure
67030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12_startCharCode = 0,
67130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12_endCharCode = 4,
67230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat12_startGlyphId = 8,
67330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
67430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 13: Last Resort Font
67530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13Format = 0,
67630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13Length = 4,
67730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13Language = 8,
67830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13nGroups = 12,
67930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13Groups = 16,
68030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13Groups_structLength = 12,
68130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // offsets within the group structure
68230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13_startCharCode = 0,
68330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13_endCharCode = 4,
68430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat13_glyphId = 8,
68530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
68630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Format 14: Unicode Variation Sequences
68730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat14Format = 0,
68830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kFormat14Length = 2,
68930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
69030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // TODO(stuartg): finish tables
69130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Default UVS Table
69230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
69330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      // Non-default UVS Table
69430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun      kLast = -1
69530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun    };
69630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  };
69730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
69830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  CMapTable(Header* header, ReadableFontData* data);
69930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
70030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // Get the offset in the table data for the encoding record for the cmap with
70130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  // the given index. The offset is from the beginning of the table.
70230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun  static int32_t OffsetForEncodingRecord(int32_t index);
70330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun};
70430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef std::vector<CMapTable::CMapId> CMapIdList;
70530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef Ptr<CMapTable> CMapTablePtr;
70630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntypedef std::vector<Ptr<CMapTable::CMapFormat4::Builder::Segment> > SegmentList;
70730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}  // namespace sfntly
70830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun
70930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#endif  // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
710