1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 // loca - Index to Location
11 // http://www.microsoft.com/typography/otspec/loca.htm
13 #define TABLE_NAME "loca"
17 bool ots_loca_parse(Font
*font
, const uint8_t *data
, size_t length
) {
18 Buffer
table(data
, length
);
20 // We can't do anything useful in validating this data except to ensure that
21 // the values are monotonically increasing.
23 OpenTypeLOCA
*loca
= new OpenTypeLOCA
;
26 if (!font
->maxp
|| !font
->head
) {
27 return OTS_FAILURE_MSG("maxp or head tables missing from font, needed by loca");
30 const unsigned num_glyphs
= font
->maxp
->num_glyphs
;
31 unsigned last_offset
= 0;
32 loca
->offsets
.resize(num_glyphs
+ 1);
33 // maxp->num_glyphs is uint16_t, thus the addition never overflows.
35 if (font
->head
->index_to_loc_format
== 0) {
36 // Note that the <= here (and below) is correct. There is one more offset
37 // than the number of glyphs in order to give the length of the final
39 for (unsigned i
= 0; i
<= num_glyphs
; ++i
) {
41 if (!table
.ReadU16(&offset
)) {
42 return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i
);
44 if (offset
< last_offset
) {
45 return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset
, last_offset
, i
);
48 loca
->offsets
[i
] = offset
* 2;
51 for (unsigned i
= 0; i
<= num_glyphs
; ++i
) {
53 if (!table
.ReadU32(&offset
)) {
54 return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i
);
56 if (offset
< last_offset
) {
57 return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset
, last_offset
, i
);
60 loca
->offsets
[i
] = offset
;
67 bool ots_loca_should_serialise(Font
*font
) {
68 return font
->loca
!= NULL
;
71 bool ots_loca_serialise(OTSStream
*out
, Font
*font
) {
72 const OpenTypeLOCA
*loca
= font
->loca
;
73 const OpenTypeHEAD
*head
= font
->head
;
76 return OTS_FAILURE_MSG("Missing head table in font needed by loca");
79 if (head
->index_to_loc_format
== 0) {
80 for (unsigned i
= 0; i
< loca
->offsets
.size(); ++i
) {
81 const uint16_t offset
= static_cast<uint16_t>(loca
->offsets
[i
] >> 1);
82 if ((offset
!= (loca
->offsets
[i
] >> 1)) ||
83 !out
->WriteU16(offset
)) {
84 return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i
);
88 for (unsigned i
= 0; i
< loca
->offsets
.size(); ++i
) {
89 if (!out
->WriteU32(loca
->offsets
[i
])) {
90 return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i
);
98 void ots_loca_reuse(Font
*font
, Font
*other
) {
99 font
->loca
= other
->loca
;
100 font
->loca_reused
= true;
103 void ots_loca_free(Font
*font
) {