gfx/ots/src/loca.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #include "loca.h"
michael@0 6
michael@0 7 #include "head.h"
michael@0 8 #include "maxp.h"
michael@0 9
michael@0 10 // loca - Index to Location
michael@0 11 // http://www.microsoft.com/typography/otspec/loca.htm
michael@0 12
michael@0 13 #define TABLE_NAME "loca"
michael@0 14
michael@0 15 namespace ots {
michael@0 16
michael@0 17 bool ots_loca_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
michael@0 18 Buffer table(data, length);
michael@0 19
michael@0 20 // We can't do anything useful in validating this data except to ensure that
michael@0 21 // the values are monotonically increasing.
michael@0 22
michael@0 23 OpenTypeLOCA *loca = new OpenTypeLOCA;
michael@0 24 file->loca = loca;
michael@0 25
michael@0 26 if (!file->maxp || !file->head) {
michael@0 27 return OTS_FAILURE_MSG("maxp or head tables missing from font, needed by loca");
michael@0 28 }
michael@0 29
michael@0 30 const unsigned num_glyphs = file->maxp->num_glyphs;
michael@0 31 unsigned last_offset = 0;
michael@0 32 loca->offsets.resize(num_glyphs + 1);
michael@0 33 // maxp->num_glyphs is uint16_t, thus the addition never overflows.
michael@0 34
michael@0 35 if (file->head->index_to_loc_format == 0) {
michael@0 36 // Note that the <= here (and below) is correct. There is one more offset
michael@0 37 // than the number of glyphs in order to give the length of the final
michael@0 38 // glyph.
michael@0 39 for (unsigned i = 0; i <= num_glyphs; ++i) {
michael@0 40 uint16_t offset = 0;
michael@0 41 if (!table.ReadU16(&offset)) {
michael@0 42 return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i);
michael@0 43 }
michael@0 44 if (offset < last_offset) {
michael@0 45 return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset, last_offset, i);
michael@0 46 }
michael@0 47 last_offset = offset;
michael@0 48 loca->offsets[i] = offset * 2;
michael@0 49 }
michael@0 50 } else {
michael@0 51 for (unsigned i = 0; i <= num_glyphs; ++i) {
michael@0 52 uint32_t offset = 0;
michael@0 53 if (!table.ReadU32(&offset)) {
michael@0 54 return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i);
michael@0 55 }
michael@0 56 if (offset < last_offset) {
michael@0 57 return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offset, last_offset, i);
michael@0 58 }
michael@0 59 last_offset = offset;
michael@0 60 loca->offsets[i] = offset;
michael@0 61 }
michael@0 62 }
michael@0 63
michael@0 64 return true;
michael@0 65 }
michael@0 66
michael@0 67 bool ots_loca_should_serialise(OpenTypeFile *file) {
michael@0 68 return file->loca != NULL;
michael@0 69 }
michael@0 70
michael@0 71 bool ots_loca_serialise(OTSStream *out, OpenTypeFile *file) {
michael@0 72 const OpenTypeLOCA *loca = file->loca;
michael@0 73 const OpenTypeHEAD *head = file->head;
michael@0 74
michael@0 75 if (!head) {
michael@0 76 return OTS_FAILURE_MSG("Missing head table in font needed by loca");
michael@0 77 }
michael@0 78
michael@0 79 if (head->index_to_loc_format == 0) {
michael@0 80 for (unsigned i = 0; i < loca->offsets.size(); ++i) {
michael@0 81 if (!out->WriteU16(loca->offsets[i] >> 1)) {
michael@0 82 return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i);
michael@0 83 }
michael@0 84 }
michael@0 85 } else {
michael@0 86 for (unsigned i = 0; i < loca->offsets.size(); ++i) {
michael@0 87 if (!out->WriteU32(loca->offsets[i])) {
michael@0 88 return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i);
michael@0 89 }
michael@0 90 }
michael@0 91 }
michael@0 92
michael@0 93 return true;
michael@0 94 }
michael@0 95
michael@0 96 void ots_loca_free(OpenTypeFile *file) {
michael@0 97 delete file->loca;
michael@0 98 }
michael@0 99
michael@0 100 } // namespace ots

mercurial