1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/ots/src/loca.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,100 @@ 1.4 +// Copyright (c) 2009 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "loca.h" 1.9 + 1.10 +#include "head.h" 1.11 +#include "maxp.h" 1.12 + 1.13 +// loca - Index to Location 1.14 +// http://www.microsoft.com/typography/otspec/loca.htm 1.15 + 1.16 +#define TABLE_NAME "loca" 1.17 + 1.18 +namespace ots { 1.19 + 1.20 +bool ots_loca_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { 1.21 + Buffer table(data, length); 1.22 + 1.23 + // We can't do anything useful in validating this data except to ensure that 1.24 + // the values are monotonically increasing. 1.25 + 1.26 + OpenTypeLOCA *loca = new OpenTypeLOCA; 1.27 + file->loca = loca; 1.28 + 1.29 + if (!file->maxp || !file->head) { 1.30 + return OTS_FAILURE_MSG("maxp or head tables missing from font, needed by loca"); 1.31 + } 1.32 + 1.33 + const unsigned num_glyphs = file->maxp->num_glyphs; 1.34 + unsigned last_offset = 0; 1.35 + loca->offsets.resize(num_glyphs + 1); 1.36 + // maxp->num_glyphs is uint16_t, thus the addition never overflows. 1.37 + 1.38 + if (file->head->index_to_loc_format == 0) { 1.39 + // Note that the <= here (and below) is correct. There is one more offset 1.40 + // than the number of glyphs in order to give the length of the final 1.41 + // glyph. 1.42 + for (unsigned i = 0; i <= num_glyphs; ++i) { 1.43 + uint16_t offset = 0; 1.44 + if (!table.ReadU16(&offset)) { 1.45 + return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i); 1.46 + } 1.47 + if (offset < last_offset) { 1.48 + return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset, last_offset, i); 1.49 + } 1.50 + last_offset = offset; 1.51 + loca->offsets[i] = offset * 2; 1.52 + } 1.53 + } else { 1.54 + for (unsigned i = 0; i <= num_glyphs; ++i) { 1.55 + uint32_t offset = 0; 1.56 + if (!table.ReadU32(&offset)) { 1.57 + return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i); 1.58 + } 1.59 + if (offset < last_offset) { 1.60 + return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset, last_offset, i); 1.61 + } 1.62 + last_offset = offset; 1.63 + loca->offsets[i] = offset; 1.64 + } 1.65 + } 1.66 + 1.67 + return true; 1.68 +} 1.69 + 1.70 +bool ots_loca_should_serialise(OpenTypeFile *file) { 1.71 + return file->loca != NULL; 1.72 +} 1.73 + 1.74 +bool ots_loca_serialise(OTSStream *out, OpenTypeFile *file) { 1.75 + const OpenTypeLOCA *loca = file->loca; 1.76 + const OpenTypeHEAD *head = file->head; 1.77 + 1.78 + if (!head) { 1.79 + return OTS_FAILURE_MSG("Missing head table in font needed by loca"); 1.80 + } 1.81 + 1.82 + if (head->index_to_loc_format == 0) { 1.83 + for (unsigned i = 0; i < loca->offsets.size(); ++i) { 1.84 + if (!out->WriteU16(loca->offsets[i] >> 1)) { 1.85 + return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i); 1.86 + } 1.87 + } 1.88 + } else { 1.89 + for (unsigned i = 0; i < loca->offsets.size(); ++i) { 1.90 + if (!out->WriteU32(loca->offsets[i])) { 1.91 + return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i); 1.92 + } 1.93 + } 1.94 + } 1.95 + 1.96 + return true; 1.97 +} 1.98 + 1.99 +void ots_loca_free(OpenTypeFile *file) { 1.100 + delete file->loca; 1.101 +} 1.102 + 1.103 +} // namespace ots