Line data Source code
1 : /*
2 : * Copyright 2011 Google Inc. All Rights Reserved.
3 : *
4 : * Licensed under the Apache License, Version 2.0 (the "License");
5 : * you may not use this file except in compliance with the License.
6 : * You may obtain a copy of the License at
7 : *
8 : * http://www.apache.org/licenses/LICENSE-2.0
9 : *
10 : * Unless required by applicable law or agreed to in writing, software
11 : * distributed under the License is distributed on an "AS IS" BASIS,
12 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : * See the License for the specific language governing permissions and
14 : * limitations under the License.
15 : */
16 :
17 : #ifndef SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
18 : #define SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
19 :
20 : // type.h needs to be included first because of building issues on Windows
21 : // Type aliases we delcare are defined in other headers and make the build
22 : // fail otherwise.
23 : #include "sfntly/port/type.h"
24 : #include <vector>
25 : #include <map>
26 :
27 : #include "sfntly/port/refcount.h"
28 : #include "sfntly/table/subtable.h"
29 : #include "sfntly/table/subtable_container_table.h"
30 :
31 : namespace sfntly {
32 :
33 : // CMap subtable formats
34 : struct CMapFormat {
35 : enum {
36 : kFormat0 = 0,
37 : kFormat2 = 2,
38 : kFormat4 = 4,
39 : kFormat6 = 6,
40 : kFormat8 = 8,
41 : kFormat10 = 10,
42 : kFormat12 = 12,
43 : kFormat13 = 13,
44 : kFormat14 = 14
45 : };
46 : };
47 :
48 : // A CMap table
49 : class CMapTable : public SubTableContainerTable, public RefCounted<CMapTable> {
50 : public:
51 : // CMapTable::CMapId
52 : struct CMapId {
53 : int32_t platform_id;
54 : int32_t encoding_id;
55 0 : bool operator==(const CMapId& obj) const {
56 0 : return platform_id == obj.platform_id && encoding_id == obj.encoding_id;
57 : }
58 : };
59 : static CMapId WINDOWS_BMP;
60 : static CMapId WINDOWS_UCS4;
61 : static CMapId MAC_ROMAN;
62 :
63 : // CMapTable::CMapIdComparator
64 : class CMapIdComparator {
65 : public:
66 : bool operator()(const CMapId& lhs, const CMapId& rhs) const;
67 : };
68 :
69 : // A filter on cmap
70 : // CMapTable::CMapFilter
71 0 : class CMapFilter {
72 : public:
73 : // Test on whether the cmap is acceptable or not
74 : // @param cmap_id the id of the cmap
75 : // @return true if the cmap is acceptable; false otherwise
76 : virtual bool accept(const CMapId& cmap_id) const = 0;
77 : // Make gcc -Wnon-virtual-dtor happy.
78 0 : virtual ~CMapFilter() {}
79 : };
80 :
81 : // Filters CMaps by CMapId to implement CMapTable::get()
82 : // wanted_id is the CMap we'd like to find.
83 : // We compare the current CMap to it either by equality (==) or using a
84 : // comparator.
85 : // CMapTable::CMapIdFilter
86 : class CMapIdFilter : public CMapFilter {
87 : public:
88 : explicit CMapIdFilter(const CMapId wanted_id);
89 : CMapIdFilter(const CMapId wanted_id,
90 : const CMapIdComparator* comparator);
91 0 : ~CMapIdFilter() {}
92 : virtual bool accept(const CMapId& cmap_id) const;
93 : private:
94 : CMapIdFilter& operator=(const CMapIdFilter& that);
95 : const CMapId wanted_id_;
96 : const CMapIdComparator *comparator_;
97 : };
98 :
99 : // The abstract base class for all cmaps.
100 : //
101 : // CMap equality is based on the equality of the (@link {@link CMapId} that
102 : // defines the CMap. In the cmap table for a font there can only be one cmap
103 : // with a given cmap id (pair of platform and encoding ids) no matter what the
104 : // type of the cmap is.
105 : //
106 : // The cmap offers CharacterIterator to allow iteration over
107 : // characters that are mapped by the cmap. This iteration mostly returns the
108 : // characters mapped by the cmap. It will return all characters mapped by the
109 : // cmap to anything but .notdef <b>but</b> it may return some that are not
110 : // mapped or are mapped to .notdef. Various cmap tables provide ranges and
111 : // such to describe characters for lookup but without going the full way to
112 : // mapping to the glyph id it isn't always possible to tell if a character
113 : // will end up with a valid glyph id. So, some of the characters returned from
114 : // the Iterator may still end up pointing to the .notdef glyph. However, the
115 : // number of such characters should be small in most cases with well designed
116 : // cmaps.
117 : class Builder;
118 : class CMap : public SubTable {
119 : public:
120 : // CMapTable::CMap::Builder
121 : class Builder : public SubTable::Builder {
122 : public:
123 : virtual ~Builder();
124 :
125 : CALLER_ATTACH static Builder*
126 : GetBuilder(ReadableFontData* data,
127 : int32_t offset,
128 : const CMapId& cmap_id);
129 : CALLER_ATTACH static Builder*
130 : GetBuilder(int32_t format,
131 : const CMapId& cmap_id);
132 :
133 : // Note: yes, an object is returned on stack since it's small enough.
134 0 : virtual CMapId cmap_id() { return cmap_id_; }
135 0 : virtual int32_t platform_id() { return cmap_id_.platform_id; }
136 0 : virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
137 0 : virtual int32_t format() { return format_; }
138 0 : virtual int32_t language() { return language_; }
139 0 : virtual void set_language(int32_t language) { language_ = language; }
140 :
141 : protected:
142 : Builder(ReadableFontData* data,
143 : int32_t format,
144 : const CMapId& cmap_id);
145 : Builder(WritableFontData* data,
146 : int32_t format,
147 : const CMapId& cmap_id);
148 :
149 : virtual int32_t SubSerialize(WritableFontData* new_data);
150 : virtual bool SubReadyToSerialize();
151 : virtual int32_t SubDataSizeToSerialize();
152 : virtual void SubDataSet();
153 :
154 : private:
155 : int32_t format_;
156 : CMapId cmap_id_;
157 : int32_t language_;
158 :
159 : friend class CMapTable::Builder;
160 : };
161 : // Abstract CMap character iterator
162 : // The fully qualified name is CMapTable::CMap::CharacterIterator
163 : class CharacterIterator {
164 : public:
165 0 : virtual ~CharacterIterator() {}
166 : virtual bool HasNext() = 0;
167 : // Returns -1 if there are no more characters to iterate through
168 : // and exceptions are turned off
169 : virtual int32_t Next() = 0;
170 :
171 : protected:
172 : // Use the CMap::Iterator method below instead of directly requesting
173 : // a CharacterIterator.
174 0 : CharacterIterator() {}
175 : };
176 :
177 : CMap(ReadableFontData* data, int32_t format, const CMapId& cmap_id);
178 : virtual ~CMap();
179 :
180 : virtual CMap::CharacterIterator* Iterator() = 0;
181 :
182 0 : virtual int32_t format() { return format_; }
183 0 : virtual CMapId cmap_id() { return cmap_id_; }
184 0 : virtual int32_t platform_id() { return cmap_id_.platform_id; }
185 0 : virtual int32_t encoding_id() { return cmap_id_.encoding_id; }
186 :
187 : // Get the language of the cmap.
188 : //
189 : // Note on the language field in 'cmap' subtables: The language field must
190 : // be set to zero for all cmap subtables whose platform IDs are other than
191 : // Macintosh (platform ID 1). For cmap subtables whose platform IDs are
192 : // Macintosh, set this field to the Macintosh language ID of the cmap
193 : // subtable plus one, or to zero if the cmap subtable is not
194 : // language-specific. For example, a Mac OS Turkish cmap subtable must set
195 : // this field to 18, since the Macintosh language ID for Turkish is 17. A
196 : // Mac OS Roman cmap subtable must set this field to 0, since Mac OS Roman
197 : // is not a language-specific encoding.
198 : //
199 : // @return the language id
200 : virtual int32_t Language() = 0;
201 :
202 : // Gets the glyph id for the character code provided.
203 : // The character code provided must be in the encoding used by the cmap
204 : // table.
205 : virtual int32_t GlyphId(int32_t character) = 0;
206 :
207 : private:
208 : int32_t format_;
209 : CMapId cmap_id_;
210 : };
211 : typedef Ptr<CMap> CMapPtr;
212 : typedef Ptr<CMap::Builder> CMapBuilderPtr;
213 : typedef std::map<CMapId, CMapBuilderPtr, CMapIdComparator> CMapBuilderMap;
214 :
215 : // A cmap format 0 sub table
216 : class CMapFormat0 : public CMap, public RefCounted<CMapFormat0> {
217 : public:
218 : // The fully qualified name is CMapTable::CMapFormat0::Builder
219 : class Builder : public CMap::Builder,
220 : public RefCounted<Builder> {
221 : public:
222 : CALLER_ATTACH static Builder* NewInstance(ReadableFontData* data,
223 : int32_t offset,
224 : const CMapId& cmap_id);
225 : CALLER_ATTACH static Builder* NewInstance(WritableFontData* data,
226 : int32_t offset,
227 : const CMapId& cmap_id);
228 : CALLER_ATTACH static Builder* NewInstance(const CMapId& cmap_id);
229 : virtual ~Builder();
230 :
231 : protected:
232 : virtual CALLER_ATTACH FontDataTable*
233 : SubBuildTable(ReadableFontData* data);
234 :
235 : private:
236 : // When creating a new CMapFormat0 Builder, use NewInstance instead of
237 : // the constructors! This avoids a memory leak when slicing the FontData.
238 : Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
239 : Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
240 : Builder(const CMapId& cmap_id);
241 : };
242 :
243 : // The fully qualified name is CMapTable::CMapFormat0::CharacterIterator
244 : class CharacterIterator : public CMap::CharacterIterator {
245 : public:
246 : virtual ~CharacterIterator();
247 : virtual bool HasNext();
248 : virtual int32_t Next();
249 :
250 : private:
251 : CharacterIterator(int32_t start, int32_t end);
252 : friend class CMapFormat0;
253 : int32_t character_, max_character_;
254 : };
255 :
256 : virtual ~CMapFormat0();
257 : virtual int32_t Language();
258 : virtual int32_t GlyphId(int32_t character);
259 : CMap::CharacterIterator* Iterator();
260 :
261 : private:
262 : CMapFormat0(ReadableFontData* data, const CMapId& cmap_id);
263 : };
264 :
265 : // A cmap format 2 sub table
266 : // The format 2 cmap is used for multi-byte encodings such as SJIS,
267 : // EUC-JP/KR/CN, Big5, etc.
268 : class CMapFormat2 : public CMap, public RefCounted<CMapFormat2> {
269 : public:
270 : // CMapTable::CMapFormat2::Builder
271 : class Builder : public CMap::Builder,
272 : public RefCounted<Builder> {
273 : public:
274 : Builder(ReadableFontData* data,
275 : int32_t offset,
276 : const CMapId& cmap_id);
277 : Builder(WritableFontData* data,
278 : int32_t offset,
279 : const CMapId& cmap_id);
280 : virtual ~Builder();
281 :
282 : protected:
283 : virtual CALLER_ATTACH FontDataTable*
284 : SubBuildTable(ReadableFontData* data);
285 : };
286 : // CMapTable::CMapFormat2::CharacterIterator
287 : class CharacterIterator : public CMap::CharacterIterator {
288 : public:
289 : virtual ~CharacterIterator();
290 : virtual bool hasNext();
291 : virtual int32_t next();
292 :
293 : private:
294 : CharacterIterator();
295 : };
296 :
297 : virtual int32_t Language();
298 : virtual int32_t GlyphId(int32_t character);
299 :
300 : // Returns how many bytes would be consumed by a lookup of this character
301 : // with this cmap. This comes about because the cmap format 2 table is
302 : // designed around multi-byte encodings such as SJIS, EUC-JP, Big5, etc.
303 : // return the number of bytes consumed from this "character" - either 1 or 2
304 : virtual int32_t BytesConsumed(int32_t character);
305 :
306 : virtual ~CMapFormat2();
307 :
308 : private:
309 : CMapFormat2(ReadableFontData* data, const CMapId& cmap_id);
310 :
311 : int32_t SubHeaderOffset(int32_t sub_header_index);
312 : int32_t FirstCode(int32_t sub_header_index);
313 : int32_t EntryCount(int32_t sub_header_index);
314 : int32_t IdRangeOffset(int32_t sub_header_index);
315 : int32_t IdDelta(int32_t sub_header_index);
316 : CMap::CharacterIterator* Iterator();
317 : };
318 :
319 : // CMapTable::CMapFormat4
320 : class CMapFormat4 : public CMap,
321 : public RefCounted<CMapFormat4> {
322 : public:
323 : // CMapTable::CMapFormat4::Builder
324 : class Builder : public CMap::Builder,
325 : public RefCounted<Builder> {
326 : public:
327 : // CMapTable::CMapFormat4::Builder::Segment
328 : class Segment : public RefCounted<Segment> {
329 : public:
330 : Segment();
331 : explicit Segment(Segment* other);
332 : Segment(int32_t start_count,
333 : int32_t end_count,
334 : int32_t id_delta,
335 : int32_t id_range_offset);
336 : ~Segment();
337 :
338 : // @return the startCount
339 : int32_t start_count();
340 : // @param startCount the startCount to set
341 : void set_start_count(int32_t start_count);
342 : // @return the endCount
343 : int32_t end_count();
344 : // @param endcount the endCount to set
345 : void set_end_count(int32_t end_count);
346 : // @return the idDelta
347 : int32_t id_delta();
348 : // @param idDelta the idDelta to set
349 : void set_id_delta(int32_t id_delta);
350 : // @return the idRangeOffset
351 : int32_t id_range_offset();
352 : // @param idRangeOffset the idRangeOffset to set
353 : void set_id_range_offset(int32_t id_range_offset);
354 :
355 : static CALLER_ATTACH
356 : std::vector<Ptr<Segment> >*
357 : DeepCopy(std::vector<Ptr<Segment> >* original);
358 :
359 : private:
360 : int32_t start_count_;
361 : int32_t end_count_;
362 : int32_t id_delta_;
363 : int32_t id_range_offset_;
364 : };
365 : typedef std::vector<Ptr<Segment> > SegmentList;
366 :
367 : static CALLER_ATTACH Builder* NewInstance(WritableFontData* data,
368 : int32_t offset,
369 : const CMapId& cmap_id);
370 : static CALLER_ATTACH Builder* NewInstance(ReadableFontData* data,
371 : int32_t offset,
372 : const CMapId& cmap_id);
373 : static CALLER_ATTACH Builder* NewInstance(const CMapId& cmap_id);
374 : virtual ~Builder();
375 : SegmentList* segments();
376 : void set_segments(SegmentList* segments);
377 : IntegerList* glyph_id_array();
378 : void set_glyph_id_array(IntegerList* glyph_id_array);
379 :
380 : protected:
381 : Builder(WritableFontData* data, int32_t offset, const CMapId& cmap_id);
382 : Builder(ReadableFontData* data, int32_t offset, const CMapId& cmap_id);
383 : Builder(SegmentList* segments, IntegerList* glyph_id_array,
384 : const CMapId& cmap_id);
385 : explicit Builder(const CMapId& cmap_id);
386 :
387 : virtual CALLER_ATTACH FontDataTable* SubBuildTable(
388 : ReadableFontData* data);
389 : virtual void SubDataSet();
390 : virtual int32_t SubDataSizeToSerialize();
391 : virtual bool SubReadyToSerialize();
392 : virtual int32_t SubSerialize(WritableFontData* new_data);
393 :
394 : private:
395 : void Initialize(ReadableFontData* data);
396 :
397 : SegmentList segments_;
398 : IntegerList glyph_id_array_;
399 : };
400 :
401 : CMap::CharacterIterator* Iterator();
402 : // CMapTable::CMapFormat4::CharacterIterator
403 : class CharacterIterator : public CMap::CharacterIterator {
404 : public:
405 : bool HasNext();
406 : int32_t Next();
407 0 : virtual ~CharacterIterator() {}
408 :
409 : private:
410 : explicit CharacterIterator(CMapFormat4 *parent);
411 : friend CMap::CharacterIterator* CMapFormat4::Iterator();
412 :
413 : CMapFormat4* parent_;
414 : int32_t segment_index_;
415 : int32_t first_char_in_segment_;
416 : int32_t last_char_in_segment_;
417 : int32_t next_char_;
418 : bool next_char_set_;
419 : };
420 :
421 : virtual int32_t GlyphId(int32_t character);
422 :
423 : // Lower level glyph code retrieval that requires processing the Format 4
424 : // segments to use.
425 : // @param segment the cmap segment
426 : // @param startCode the start code for the segment
427 : // @param character the character to be looked up
428 : // @return the glyph id for the character; CMapTable.NOTDEF if not found
429 : int32_t RetrieveGlyphId(int32_t segment,
430 : int32_t start_count,
431 : int32_t character);
432 : virtual int32_t Language();
433 :
434 : // Get the count of the number of segments in this cmap.
435 : // @return the number of segments
436 : int32_t seg_count();
437 : int32_t Length();
438 : // Get the start code for a segment.
439 : // @param segment the segment in the lookup table
440 : // @return the start code for a segment
441 : int32_t StartCode(int32_t segment);
442 : // Get the end code for a segment.
443 : // @param segment the segment in the look up table
444 : // @return the end code for the segment
445 : int32_t EndCode(int32_t segment);
446 : // Get the id delta for a segment
447 : // @param segment the segment in the look up table
448 : // @return the id delta for the segment
449 : int32_t IdDelta(int32_t segment);
450 : // Get the id range offset for a segment
451 : // @param segment the segment in the look up table
452 : // @return the id range offset for the segment
453 : int32_t IdRangeOffset(int32_t segment);
454 : // Get the location of the id range offset for a segment
455 : // @param segment the segment in the look up table
456 : // @return the location of the id range offset for the segment
457 : int32_t IdRangeOffsetLocation(int32_t segment);
458 : // Declared above to allow friending inside CharacterIterator class.
459 : // CMap::CharacterIterator* Iterator();
460 : virtual ~CMapFormat4();
461 :
462 : protected:
463 : CMapFormat4(ReadableFontData* data, const CMapId& cmap_id);
464 :
465 : private:
466 : static int32_t Language(ReadableFontData* data);
467 : static int32_t Length(ReadableFontData* data);
468 : static int32_t SegCount(ReadableFontData* data);
469 : static int32_t StartCode(ReadableFontData* data,
470 : int32_t seg_count,
471 : int32_t index);
472 : static int32_t StartCodeOffset(int32_t seg_count);
473 : static int32_t EndCode(ReadableFontData* data,
474 : int32_t seg_count,
475 : int32_t index);
476 : static int32_t IdDelta(ReadableFontData* data,
477 : int32_t seg_count,
478 : int32_t index);
479 : static int32_t IdDeltaOffset(int32_t seg_count);
480 : static int32_t IdRangeOffset(ReadableFontData* data,
481 : int32_t seg_count,
482 : int32_t index);
483 : static int32_t IdRangeOffsetOffset(int32_t seg_count);
484 : static int32_t GlyphIdArrayOffset(int32_t seg_count);
485 : // Refactored void to bool to work without exceptions.
486 : bool IsValidIndex(int32_t segment);
487 : int32_t GlyphIdArray(int32_t index);
488 :
489 : int32_t seg_count_;
490 : int32_t start_code_offset_;
491 : int32_t id_delta_offset_;
492 : int32_t glyph_id_array_offset_;
493 : };
494 :
495 : // CMapTable::Builder
496 : class Builder : public SubTableContainerTable::Builder,
497 : public RefCounted<Builder> {
498 : public:
499 : // Constructor scope is public because C++ does not allow base class to
500 : // instantiate derived class with protected constructors.
501 : Builder(Header* header, WritableFontData* data);
502 : Builder(Header* header, ReadableFontData* data);
503 : virtual ~Builder();
504 :
505 : virtual int32_t SubSerialize(WritableFontData* new_data);
506 : virtual bool SubReadyToSerialize();
507 : virtual int32_t SubDataSizeToSerialize();
508 : virtual void SubDataSet();
509 : virtual CALLER_ATTACH FontDataTable* SubBuildTable(ReadableFontData* data);
510 :
511 : static CALLER_ATTACH Builder* CreateBuilder(Header* header,
512 : WritableFontData* data);
513 :
514 : CMap::Builder* NewCMapBuilder(const CMapId& cmap_id,
515 : ReadableFontData* data);
516 : // Create a new empty CMapBuilder of the type specified in the id.
517 : CMap::Builder* NewCMapBuilder(int32_t format, const CMapId& cmap_id);
518 : CMap::Builder* CMapBuilder(const CMapId& cmap_id);
519 :
520 : int32_t NumCMaps();
521 : void SetVersion(int32_t version);
522 :
523 : CMapBuilderMap* GetCMapBuilders();
524 :
525 : protected:
526 : static CALLER_ATTACH CMap::Builder* CMapBuilder(ReadableFontData* data,
527 : int32_t index);
528 :
529 : private:
530 : void Initialize(ReadableFontData* data);
531 : static int32_t NumCMaps(ReadableFontData* data);
532 :
533 : int32_t version_;
534 : CMapBuilderMap cmap_builders_;
535 : };
536 : typedef Ptr<Builder> CMapTableBuilderPtr;
537 :
538 : class CMapIterator {
539 : public:
540 : // If filter is NULL, filter through all tables.
541 : CMapIterator(CMapTable* table, const CMapFilter* filter);
542 : bool HasNext();
543 : CMap* Next();
544 :
545 : private:
546 : int32_t table_index_;
547 : const CMapFilter* filter_;
548 : CMapTable* table_;
549 : };
550 :
551 : // Make a CMapId from a platform_id, encoding_id pair
552 : static CMapId NewCMapId(int32_t platform_id, int32_t encoding_id);
553 : // Make a CMapId from another CMapId
554 : static CMapId NewCMapId(const CMapId& obj);
555 :
556 : // Get the CMap with the specified parameters if it exists.
557 : // Returns NULL otherwise.
558 : CALLER_ATTACH CMap* GetCMap(const int32_t index);
559 : CALLER_ATTACH CMap* GetCMap(const int32_t platform_id,
560 : const int32_t encoding_id);
561 : CALLER_ATTACH CMap* GetCMap(const CMapId GetCMap_id);
562 :
563 : // Get the table version.
564 : virtual int32_t Version();
565 :
566 : // Get the number of cmaps within the CMap table.
567 : virtual int32_t NumCMaps();
568 :
569 : // Get the cmap id for the cmap with the given index.
570 : // Note: yes, an object is returned on stack since it's small enough.
571 : // This function is renamed from cmapId to GetCMapId().
572 : virtual CMapId GetCMapId(int32_t index);
573 :
574 : virtual int32_t PlatformId(int32_t index);
575 : virtual int32_t EncodingId(int32_t index);
576 :
577 : // Get the offset in the table data for the cmap table with the given index.
578 : // The offset is from the beginning of the table.
579 : virtual int32_t Offset(int32_t index);
580 :
581 : virtual ~CMapTable();
582 :
583 : static const int32_t NOTDEF;
584 :
585 : private:
586 : // Offsets to specific elements in the underlying data. These offsets are
587 : // relative to the start of the table or the start of sub-blocks within
588 : // the table.
589 : struct Offset {
590 : enum {
591 : kVersion = 0,
592 : kNumTables = 2,
593 : kEncodingRecordStart = 4,
594 :
595 : // offsets relative to the encoding record
596 : kEncodingRecordPlatformId = 0,
597 : kEncodingRecordEncodingId = 2,
598 : kEncodingRecordOffset = 4,
599 : kEncodingRecordSize = 8,
600 :
601 : kFormat = 0,
602 :
603 : // Format 0: Byte encoding table
604 : kFormat0Format = 0,
605 : kFormat0Length = 2,
606 : kFormat0Language = 4,
607 : kFormat0GlyphIdArray = 6,
608 :
609 : // Format 2: High-byte mapping through table
610 : kFormat2Format = 0,
611 : kFormat2Length = 2,
612 : kFormat2Language = 4,
613 : kFormat2SubHeaderKeys = 6,
614 : kFormat2SubHeaders = 518,
615 : // offset relative to the subHeader structure
616 : kFormat2SubHeader_firstCode = 0,
617 : kFormat2SubHeader_entryCount = 2,
618 : kFormat2SubHeader_idDelta = 4,
619 : kFormat2SubHeader_idRangeOffset = 6,
620 : kFormat2SubHeader_structLength = 8,
621 :
622 : // Format 4: Segment mapping to delta values
623 : kFormat4Format = 0,
624 : kFormat4Length = 2,
625 : kFormat4Language = 4,
626 : kFormat4SegCountX2 = 6,
627 : kFormat4SearchRange = 8,
628 : kFormat4EntrySelector = 10,
629 : kFormat4RangeShift = 12,
630 : kFormat4EndCount = 14,
631 : kFormat4FixedSize = 16,
632 :
633 : // format 6: Trimmed table mapping
634 : kFormat6Format = 0,
635 : kFormat6Length = 2,
636 : kFormat6Language = 4,
637 : kFormat6FirstCode = 6,
638 : kFormat6EntryCount = 8,
639 : kFormat6GlyphIdArray = 10,
640 :
641 : // Format 8: mixed 16-bit and 32-bit coverage
642 : kFormat8Format = 0,
643 : kFormat8Length = 4,
644 : kFormat8Language = 8,
645 : kFormat8Is32 = 12,
646 : kFormat8nGroups204 = 8204,
647 : kFormat8Groups208 = 8208,
648 : // offset relative to the group structure
649 : kFormat8Group_startCharCode = 0,
650 : kFormat8Group_endCharCode = 4,
651 : kFormat8Group_startGlyphId = 8,
652 : kFormat8Group_structLength = 12,
653 :
654 : // Format 10: Trimmed array
655 : kFormat10Format = 0,
656 : kFormat10Length = 4,
657 : kFormat10Language = 8,
658 : kFormat10StartCharCode = 12,
659 : kFormat10NumChars = 16,
660 : kFormat10Glyphs0 = 20,
661 :
662 : // Format 12: Segmented coverage
663 : kFormat12Format = 0,
664 : kFormat12Length = 4,
665 : kFormat12Language = 8,
666 : kFormat12nGroups = 12,
667 : kFormat12Groups = 16,
668 : kFormat12Groups_structLength = 12,
669 : // offsets within the group structure
670 : kFormat12_startCharCode = 0,
671 : kFormat12_endCharCode = 4,
672 : kFormat12_startGlyphId = 8,
673 :
674 : // Format 13: Last Resort Font
675 : kFormat13Format = 0,
676 : kFormat13Length = 4,
677 : kFormat13Language = 8,
678 : kFormat13nGroups = 12,
679 : kFormat13Groups = 16,
680 : kFormat13Groups_structLength = 12,
681 : // offsets within the group structure
682 : kFormat13_startCharCode = 0,
683 : kFormat13_endCharCode = 4,
684 : kFormat13_glyphId = 8,
685 :
686 : // Format 14: Unicode Variation Sequences
687 : kFormat14Format = 0,
688 : kFormat14Length = 2,
689 :
690 : // TODO(stuartg): finish tables
691 : // Default UVS Table
692 :
693 : // Non-default UVS Table
694 : kLast = -1
695 : };
696 : };
697 :
698 : CMapTable(Header* header, ReadableFontData* data);
699 :
700 : // Get the offset in the table data for the encoding record for the cmap with
701 : // the given index. The offset is from the beginning of the table.
702 : static int32_t OffsetForEncodingRecord(int32_t index);
703 : };
704 : typedef std::vector<CMapTable::CMapId> CMapIdList;
705 : typedef Ptr<CMapTable> CMapTablePtr;
706 : typedef std::vector<Ptr<CMapTable::CMapFormat4::Builder::Segment> > SegmentList;
707 : } // namespace sfntly
708 :
709 : #endif // SFNTLY_CPP_SRC_SFNTLY_TABLE_CORE_CMAP_TABLE_H_
|