summaryrefslogtreecommitdiff
path: root/src/name_table.h
blob: c687284c7fbff9c91240250d2029fe2c2954d0f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
    Copyright (C) 2026 Carl Hetherington <cth@carlh.net>

    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 <http://www.gnu.org/licenses/>.

*/


#include "table.h"
#include <boost/optional.hpp>
#include <boost/variant2/variant.hpp>
#include <algorithm>


namespace ttf {


/** The 'name' table */
class NameTable : public Table
{
public:
	NameTable(Source& source, int header_index);

	enum class Identifier {
		COPYRIGHT_NOTICE,
		FONT_FAMILY,
		FONT_SUBFAMILY,
		UNIQUE_SUBFAMILY_IDENTIFICATION,
		FULL_NAME,
		NAME_TABLE_VERSION,
		POSTSCRIPT_NAME,
		TRADEMARK_NOTICE,
		MANUFACTURER_NAME,
		DESIGNER,
		DESCRIPTION,
		VENDOR_URL,
		DESIGNER_URL,
		LICENSE,
		LICENSE_URL,
		RESERVED,
		PREFERRED_FAMILY,
		PREFERRED_SUBFAMILY,
		COMPATIBLE_FULL,
		SAMPLE_TEXT,
		OPENTYPE_0,
		OPENTYPE_1,
		OPENTYPE_2,
		OPENTYPE_3,
		OPENTYPE_4,
		VARIATIONS_PREFIX,
	};

	using Name = boost::variant2::variant<std::string, std::wstring>;
	std::vector<Name> names(Identifier id) const;

	void set_names(Identifier id, std::string const& name, std::wstring const& wname);

	void write(Sink& header_sink, Sink&& data_sink) const override;

private:
	class NameRecord
	{
	public:
		explicit NameRecord(Source& table_source, Source& name_source, int header_index);
		NameRecord(int header_index_, uint16_t platform_id_, uint16_t platform_specific_id_, uint16_t language_id_, Identifier name_id_, std::string name_);
		NameRecord(int header_index_, uint16_t platform_id_, uint16_t platform_specific_id_, uint16_t language_id_, Identifier name_id_, std::wstring name_);

		void write(Sink& table_sink, Sink& name_sink) const;

		int header_index;
		uint16_t platform_id;
		uint16_t platform_specific_id;
		uint16_t language_id;
		uint16_t name_id;

		uint16_t original_offset = 0;

		boost::variant2::variant<std::string, std::wstring> name;
	};

	template <class T>
	std::vector<NameRecord>::iterator find(Identifier id)
	{
		return std::find_if(_name_records.begin(), _name_records.end(), [id](NameRecord const& record) {
			return record.name_id == static_cast<uint16_t>(id) && boost::variant2::get_if<T>(&record.name);
		});
	}

	template <class T>
	std::vector<NameRecord>::const_iterator find(Identifier id) const
	{
		return std::find_if(_name_records.begin(), _name_records.end(), [id](NameRecord const& record) {
			return record.name_id == static_cast<uint16_t>(id) && boost::variant2::get_if<T>(&record.name);
		});
	}

	uint16_t _format;

	/** Sorted in order that the strings are written to the file (not necessarily
	 *  the order of the header)
	 */
	std::vector<NameRecord> _name_records;
};


}