/* Copyright (C) 2026 Carl Hetherington This file is part of libttf. libttf is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. libttf is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with libttf. If not, see . */ #include "name_table.h" #include "table.h" #include "tags.h" #include "util.h" #include using namespace ttf; Table::Table(Source& source, int header_index) : _header_index(header_index) , _checksum(source.get_uint32()) , _offset(source.get_uint32()) , _length(source.get_uint32()) { } OtherTable::OtherTable(Source& source, int header_index, uint32_t tag) : Table(source, header_index) , _tag(tag) { _data = source.get_block(_offset, _length); } void OtherTable::write(Sink& header_sink, Sink&& data_sink) const { header_sink.put(_tag); header_sink.put(checksum(_data)); header_sink.put(data_sink.offset()); header_sink.put(static_cast(_data.size())); data_sink.put(_data); data_sink.pad(); } HeadTable::HeadTable(Source& source, int header_index) : Table(source, header_index) { _data = source.get_block(_offset, _length); } void HeadTable::write(Sink& header_sink, Sink&& data_sink) const { header_sink.put(HEAD); if (_data.size() < 12) { throw InvalidTableSize(); } std::vector data = _data; /* Zero out the checkSumAdjustment */ data[8] = 0; data[9] = 0; data[10] = 0; data[11] = 0; header_sink.put(checksum(data)); header_sink.put(data_sink.offset()); header_sink.put(static_cast(data.size())); data_sink.put(data); data_sink.pad(); } void HeadTable::set_checksum_adjustment(Sink& data_sink, uint32_t adjustment) { data_sink.put(adjustment, _offset + 8); } std::shared_ptr ttf::make_table(Source& source, int header_index) { auto const tag = source.get_uint32(); std::shared_ptr
table; switch (tag) { case NAME: return std::make_shared(source, header_index); case HEAD: return std::make_shared(source, header_index); default: return std::make_shared(source, header_index, tag); } }