7#include "core/fpdfapi/font/cfx_cttgsubtable.h"
13#include "core/fxcrt/data_vector.h"
14#include "core/fxcrt/fx_system.h"
15#include "core/fxcrt/stl_util.h"
16#include "core/fxge/cfx_fontmapper.h"
20bool IsVerticalFeatureTag(uint32_t tag) {
21 static constexpr uint32_t kTags[] = {
25 return tag == kTags[0] || tag == kTags[1];
31 if (!LoadGSUBTable(gsub))
34 for (
const auto& script : script_list_) {
35 for (
const auto& record : script) {
36 for (uint16_t index : record) {
37 if (IsVerticalFeatureTag(feature_list_[index].feature_tag)) {
38 feature_set_.insert(index);
43 if (!feature_set_.empty()) {
48 for (
const FeatureRecord& feature : feature_list_) {
49 if (IsVerticalFeatureTag(feature.feature_tag)) {
50 feature_set_.insert(i);
59 if (FXSYS_UINT32_GET_MSBFIRST(gsub) != 0x00010000)
62 auto scriptlist_span = gsub.subspan(4, 2);
63 auto featurelist_span = gsub.subspan(6, 2);
64 auto lookuplist_span = gsub.subspan(8, 2);
65 size_t scriptlist_index = FXSYS_UINT16_GET_MSBFIRST(scriptlist_span);
66 size_t featurelist_index = FXSYS_UINT16_GET_MSBFIRST(featurelist_span);
67 size_t lookuplist_index = FXSYS_UINT16_GET_MSBFIRST(lookuplist_span);
68 Parse(gsub.subspan(scriptlist_index), gsub.subspan(featurelist_index),
69 gsub.subspan(lookuplist_index));
74 for (uint32_t item : feature_set_) {
75 absl::optional<uint32_t> result =
76 GetVerticalGlyphSub(feature_list_[item], glyphnum);
77 if (result.has_value())
78 return result.value();
84 const FeatureRecord& feature,
85 uint32_t glyphnum)
const {
86 for (
int index : feature.lookup_list_indices) {
87 if (!fxcrt::IndexInBounds(lookup_list_, index)) {
90 if (lookup_list_[index].lookup_type != 1) {
93 absl::optional<uint32_t> result =
94 GetVerticalGlyphSub2(lookup_list_[index], glyphnum);
95 if (result.has_value())
96 return result.value();
102 const Lookup& lookup,
103 uint32_t glyphnum)
const {
104 for (
const auto& sub_table : lookup.sub_tables) {
105 if (absl::holds_alternative<absl::monostate>(sub_table.table_data)) {
108 int index = GetCoverageIndex(sub_table.coverage, glyphnum);
109 if (absl::holds_alternative<int16_t>(sub_table.table_data)) {
111 return glyphnum + absl::get<int16_t>(sub_table.table_data);
114 const auto& substitutes =
115 absl::get<DataVector<uint16_t>>(sub_table.table_data);
116 if (fxcrt::IndexInBounds(substitutes, index)) {
117 return substitutes[index];
121 return absl::nullopt;
126 if (absl::holds_alternative<absl::monostate>(coverage)) {
130 if (absl::holds_alternative<DataVector<uint16_t>>(coverage)) {
132 const auto& glyph_array = absl::get<DataVector<uint16_t>>(coverage);
133 for (
const auto& glyph : glyph_array) {
134 if (
static_cast<uint32_t>(glyph) == g) {
142 const auto& range_records = absl::get<std::vector<RangeRecord>>(coverage);
143 for (
const auto& range_rec : range_records) {
144 uint32_t s = range_rec.start;
145 uint32_t e = range_rec.end;
146 uint32_t si = range_rec.start_coverage_index;
147 if (s <= g && g <= e) {
161 uint16_t ret = FXSYS_UINT16_GET_MSBFIRST(p);
163 return *
reinterpret_cast<int16_t*>(&ret);
167 uint16_t ret = FXSYS_UINT16_GET_MSBFIRST(p);
173 uint32_t ret = FXSYS_UINT32_GET_MSBFIRST(p);
175 return *
reinterpret_cast<int32_t*>(&ret);
179 uint32_t ret = FXSYS_UINT32_GET_MSBFIRST(p);
185 pdfium::span<
const uint8_t> featurelist,
186 pdfium::span<
const uint8_t> lookuplist) {
187 ParseScriptList(scriptlist);
188 ParseFeatureList(featurelist);
189 ParseLookupList(lookuplist);
193 const uint8_t* sp = raw.data();
194 script_list_ = std::vector<ScriptRecord>(GetUInt16(sp));
195 for (
auto& script : script_list_) {
198 script = ParseScript(&raw[GetUInt16(sp)]);
203 const uint8_t* raw) {
205 const uint8_t* sp = raw + 2;
206 ScriptRecord result(GetUInt16(sp));
207 for (
auto& record : result) {
210 record = ParseLangSys(&raw[GetUInt16(sp)]);
216 const uint8_t* raw) {
218 const uint8_t* sp = raw + 4;
219 FeatureIndices result(GetUInt16(sp));
220 for (
auto& element : result) {
221 element = GetUInt16(sp);
227 const uint8_t* sp = raw.data();
228 feature_list_ = std::vector<FeatureRecord>(GetUInt16(sp));
229 for (
auto& record : feature_list_) {
230 record.feature_tag = GetUInt32(sp);
231 record.lookup_list_indices =
232 ParseFeatureLookupListIndices(&raw[GetUInt16(sp)]);
237 const uint8_t* raw) {
239 const uint8_t* sp = raw + 2;
240 DataVector<uint16_t> result(GetUInt16(sp));
241 for (
auto& index : result) {
242 index = GetUInt16(sp);
248 const uint8_t* sp = raw.data();
249 lookup_list_ = std::vector<Lookup>(GetUInt16(sp));
250 for (
auto& lookup : lookup_list_) {
251 lookup = ParseLookup(&raw[GetUInt16(sp)]);
256 const uint8_t* sp = raw;
258 result.lookup_type = GetUInt16(sp);
261 result.sub_tables = Lookup::SubTables(GetUInt16(sp));
262 if (result.lookup_type != 1) {
266 for (
auto& sub_table : result.sub_tables) {
267 sub_table = ParseSingleSubst(&raw[GetUInt16(sp)]);
273 const uint8_t* raw) {
274 const uint8_t* sp = raw;
275 uint16_t format = GetUInt16(sp);
276 if (format != 1 && format != 2) {
277 return absl::monostate();
281 DataVector<uint16_t> glyph_array(GetUInt16(sp));
282 for (
auto& glyph : glyph_array) {
283 glyph = GetUInt16(sp);
288 std::vector<RangeRecord> range_records(GetUInt16(sp));
289 for (
auto& range_rec : range_records) {
290 range_rec.start = GetUInt16(sp);
291 range_rec.end = GetUInt16(sp);
292 range_rec.start_coverage_index = GetUInt16(sp);
294 return range_records;
298 const uint8_t* raw) {
299 const uint8_t* sp = raw;
300 uint16_t format = GetUInt16(sp);
302 if (format != 1 && format != 2) {
306 uint16_t offset = GetUInt16(sp);
307 rec.coverage = ParseCoverage(&raw[offset]);
309 rec.table_data = GetInt16(sp);
311 DataVector<uint16_t> table_data(GetUInt16(sp));
312 for (
auto& substitute : table_data) {
313 substitute = GetUInt16(sp);
315 rec.table_data = std::move(table_data);
331 SubTable&& that)
noexcept =
default;
340 Lookup&& that)
noexcept =
default;
uint32_t GetVerticalGlyph(uint32_t glyphnum) const
CFX_CTTGSUBTable(pdfium::span< const uint8_t > gsub)
static constexpr uint32_t MakeTag(char c1, char c2, char c3, char c4)