7#include "core/fpdfapi/font/cpdf_cmapparser.h"
13#include "core/fpdfapi/cmaps/fpdf_cmaps.h"
14#include "core/fpdfapi/parser/cpdf_array.h"
15#include "core/fpdfapi/parser/cpdf_dictionary.h"
16#include "core/fpdfapi/parser/cpdf_simple_parser.h"
17#include "core/fxcrt/fx_extension.h"
18#include "core/fxcrt/fx_safe_types.h"
19#include "third_party/base/check.h"
23ByteStringView CMap_GetString(ByteStringView word) {
24 if (word.GetLength() <= 2)
25 return ByteStringView();
26 return word.Last(word.GetLength() - 2);
34 m_pCMap->SetAdditionalMappings(std::move(m_AdditionalCharcodeToCIDMappings));
35 m_pCMap->SetMixedFourByteLeadingRanges(std::move(m_Ranges));
39 DCHECK(!word.IsEmpty());
41 if (word ==
"begincidchar") {
42 m_Status = kProcessingCidChar;
44 }
else if (word ==
"begincidrange") {
45 m_Status = kProcessingCidRange;
47 }
else if (word ==
"endcidrange" || word ==
"endcidchar") {
49 }
else if (word ==
"/WMode") {
50 m_Status = kProcessingWMode;
51 }
else if (word ==
"/Registry") {
52 m_Status = kProcessingRegistry;
53 }
else if (word ==
"/Ordering") {
54 m_Status = kProcessingOrdering;
55 }
else if (word ==
"/Supplement") {
56 m_Status = kProcessingSupplement;
57 }
else if (word ==
"begincodespacerange") {
58 m_Status = kProcessingCodeSpaceRange;
60 }
else if (word ==
"usecmap") {
61 }
else if (m_Status == kProcessingCidChar) {
63 }
else if (m_Status == kProcessingCidRange) {
65 }
else if (m_Status == kProcessingRegistry) {
67 }
else if (m_Status == kProcessingOrdering) {
68 m_pCMap->SetCharset(CharsetFromOrdering(CMap_GetString(word)));
70 }
else if (m_Status == kProcessingSupplement) {
72 }
else if (m_Status == kProcessingWMode) {
73 m_pCMap->SetVertical(GetCode(word) != 0);
75 }
else if (m_Status == kProcessingCodeSpaceRange) {
76 HandleCodeSpaceRange(word);
82 DCHECK(m_Status == kProcessingCidChar || m_Status == kProcessingCidRange);
83 bool bChar = m_Status == kProcessingCidChar;
85 m_CodePoints[m_CodeSeq] = GetCode(word);
87 int nRequiredCodePoints = bChar ? 2 : 3;
88 if (m_CodeSeq < nRequiredCodePoints)
91 uint32_t StartCode = m_CodePoints[0];
96 StartCID =
static_cast<uint16_t>(m_CodePoints[1]);
98 EndCode = m_CodePoints[1];
99 StartCID =
static_cast<uint16_t>(m_CodePoints[2]);
101 if (EndCode < CPDF_CMap::kDirectMapTableSize) {
102 m_pCMap->SetDirectCharcodeToCIDTableRange(StartCode, EndCode, StartCID);
104 m_AdditionalCharcodeToCIDMappings.push_back({StartCode, EndCode, StartCID});
110 if (word !=
"endcodespacerange") {
111 if (word.IsEmpty() || word[0] !=
'<')
115 absl::optional<CPDF_CMap::CodeRange> range =
116 GetCodeRange(m_LastWord.AsStringView(), word);
117 if (range.has_value())
118 m_PendingRanges.push_back(range.value());
124 size_t nSegs = m_Ranges.size() + m_PendingRanges.size();
126 const auto& first_range =
127 !m_Ranges.empty() ? m_Ranges[0] : m_PendingRanges[0];
128 m_pCMap->SetCodingScheme(first_range.m_CharSize == 2 ? CPDF_CMap::TwoBytes
129 : CPDF_CMap::OneByte);
130 }
else if (nSegs > 1) {
131 m_pCMap->SetCodingScheme(CPDF_CMap::MixedFourBytes);
132 m_Ranges.reserve(nSegs);
133 std::move(m_PendingRanges.begin(), m_PendingRanges.end(),
134 std::back_inserter(m_Ranges));
135 m_PendingRanges.clear();
145 FX_SAFE_UINT32 num = 0;
146 if (word[0] ==
'<') {
147 for (size_t i = 1; i < word.GetLength() && isxdigit(word[i]); ++i) {
148 num = num * 16 + FXSYS_HexCharToInt(word[i]);
152 return num.ValueOrDie();
155 for (size_t i = 0; i < word.GetLength() && isdigit(word[i]); ++i) {
160 return num.ValueOrDie();
165 ByteStringView first,
166 ByteStringView second) {
167 if (first.IsEmpty() || first[0] !=
'<')
168 return absl::nullopt;
171 for (i = 1; i < first.GetLength(); ++i) {
175 size_t char_size = (i - 1) / 2;
177 return absl::nullopt;
180 range.m_CharSize = char_size;
181 for (i = 0; i < range.m_CharSize; ++i) {
182 uint8_t digit1 = first[i * 2 + 1];
183 uint8_t digit2 = first[i * 2 + 2];
188 size_t size = second.GetLength();
189 for (i = 0; i < range.m_CharSize; ++i) {
190 size_t i1 = i * 2 + 1;
192 uint8_t digit1 = i1 < size ? second[i1] :
'0';
193 uint8_t digit2 = i2 < size ? second[i2] :
'0';
203 nullptr,
"GB1",
"CNS1",
"Japan1",
"Korea1",
"UCS"};
205 "Too many CID sets");
207 for (size_t charset = 1; charset <
std::size(kCharsetNames); ++charset) {
208 if (ordering == kCharsetNames[charset])
209 return static_cast<
CIDSet>(charset);
static CIDSet CharsetFromOrdering(ByteStringView ordering)
CPDF_CMapParser(CPDF_CMap *pCMap)
void ParseWord(ByteStringView word)
int FXSYS_DecimalCharToInt(wchar_t c)
int FXSYS_HexCharToInt(char c)