1 #include "StandardFontsFile.h"
6 #include "../../Constants.h"
7 #include "../parse_error.h"
8 #include "../invalid_odb_error.h"
9 #include "../../ProtoBuf/enums.pb.h"
12 namespace Odb::Lib::FileModel::Design
14 StandardFontsFile::~StandardFontsFile()
16 m_characterBlocks.clear();
19 bool StandardFontsFile::Parse(std::filesystem::path path)
21 std::ifstream standardFile;
27 if (!OdbFile::Parse(path))
return false;
29 auto fontsStandardFile = path /
"standard";
30 if (!std::filesystem::exists(fontsStandardFile))
32 auto message =
"fonts/standard file does not exist: [" + fontsStandardFile.string() +
"]";
33 throw invalid_odb_error(message.c_str());
36 standardFile.open(fontsStandardFile, std::ios::in);
37 if (!standardFile.is_open())
39 auto message =
"unable to open fonts/standard file: [" + fontsStandardFile.string() +
"]";
40 throw invalid_odb_error(message.c_str());
43 std::shared_ptr<CharacterBlock> pCurrentCharacterBlock;
44 std::shared_ptr<CharacterBlock::LineRecord> pCurrentLineRecord;
45 bool beginTokenFound =
false;
47 while (std::getline(standardFile, line))
52 Utils::str_trim(line);
55 std::stringstream lineStream(line);
56 if (line.find(Constants::COMMENT_TOKEN) == 0)
60 else if (line.find(
"XSIZE") == 0)
63 if (!(lineStream >> token))
65 throw_parse_error(m_path, line, token, lineNumber);
70 throw_parse_error(m_path, line, token, lineNumber);
73 if (!(lineStream >> token))
75 throw_parse_error(m_path, line, token, lineNumber);
78 m_xSize = std::stof(token);
80 else if (line.find(
"YSIZE") == 0)
83 if (!(lineStream >> token))
85 throw_parse_error(m_path, line, token, lineNumber);
90 throw_parse_error(m_path, line, token, lineNumber);
93 if (!(lineStream >> token))
95 throw_parse_error(m_path, line, token, lineNumber);
98 m_ySize = std::stof(token);
100 else if (line.find(
"OFFSET") == 0)
103 if (!(lineStream >> token))
105 throw_parse_error(m_path, line, token, lineNumber);
108 if (token !=
"OFFSET")
110 throw_parse_error(m_path, line, token, lineNumber);
113 if (!(lineStream >> token))
115 throw_parse_error(m_path, line, token, lineNumber);
118 m_offset = std::stof(token);
120 else if (line.find(CharacterBlock::BEGIN_TOKEN) == 0)
122 pCurrentCharacterBlock = std::make_shared<CharacterBlock>();
123 beginTokenFound =
true;
126 if (!(lineStream >> token))
128 throw_parse_error(m_path, line, token, lineNumber);
131 if (token != CharacterBlock::BEGIN_TOKEN)
133 throw_parse_error(m_path, line, token, lineNumber);
136 if (!(lineStream >> token))
138 throw_parse_error(m_path, line, token, lineNumber);
141 Utils::str_trim(token);
142 if (token.length() != 1)
144 throw_parse_error(m_path, line, token, lineNumber);
147 pCurrentCharacterBlock->character = token[0];
149 else if (line.find(CharacterBlock::END_TOKEN) == 0)
151 if (pCurrentCharacterBlock !=
nullptr && beginTokenFound)
153 m_characterBlocks.push_back(pCurrentCharacterBlock);
154 beginTokenFound =
false;
155 pCurrentCharacterBlock.reset();
159 throw_parse_error(m_path, line,
"", lineNumber);
162 else if (line.find(CharacterBlock::LineRecord::RECORD_TOKEN) == 0)
165 if (!(lineStream >> token))
167 throw_parse_error(m_path, line, token, lineNumber);
170 if (token != CharacterBlock::LineRecord::RECORD_TOKEN)
172 throw_parse_error(m_path, line, token, lineNumber);
175 if (pCurrentCharacterBlock ==
nullptr || !beginTokenFound)
177 throw_parse_error(m_path, line, token, lineNumber);
180 auto pLineRecord = std::make_shared<CharacterBlock::LineRecord>();
182 if (!(lineStream >> token))
184 throw_parse_error(m_path, line, token, lineNumber);
186 pLineRecord->xStart = std::stof(token);
188 if (!(lineStream >> token))
190 throw_parse_error(m_path, line, token, lineNumber);
192 pLineRecord->yStart = std::stof(token);
194 if (!(lineStream >> token))
196 throw_parse_error(m_path, line, token, lineNumber);
198 pLineRecord->xEnd = std::stof(token);
200 if (!(lineStream >> token))
202 throw_parse_error(m_path, line, token, lineNumber);
204 pLineRecord->yEnd = std::stof(token);
207 if (!(lineStream >> token))
209 throw_parse_error(m_path, line, token, lineNumber);
211 Utils::str_trim(token);
213 if (token.length() != 1)
215 throw_parse_error(m_path, line, token, lineNumber);
220 case 'P': pLineRecord->polarity = Polarity::Positive;
break;
221 case 'N': pLineRecord->polarity = Polarity::Negative;
break;
222 default: throw_parse_error(m_path, line, token, lineNumber);
226 if (!(lineStream >> token))
228 throw_parse_error(m_path, line, token, lineNumber);
230 Utils::str_trim(token);
232 if (token.length() != 1)
234 throw_parse_error(m_path, line, token, lineNumber);
239 case 'R': pLineRecord->shape = LineShape::Round;
break;
240 case 'S': pLineRecord->shape = LineShape::Square;
break;
241 default: throw_parse_error(m_path, line, token, lineNumber);
245 if (!(lineStream >> token))
247 throw_parse_error(m_path, line, token, lineNumber);
249 pLineRecord->width = std::stof(token);
251 pCurrentCharacterBlock->m_lineRecords.push_back(pLineRecord);
255 logwarn(
"unrecognized line: " + line);
256 throw_parse_error(m_path, line,
"", lineNumber);
261 standardFile.close();
263 catch (parse_error& pe)
265 auto m = pe.toString(
"Parse Error:");
268 standardFile.close();
271 catch (invalid_odb_error& ioe)
273 parse_info pi(m_path, line, lineNumber);
274 const auto m = pi.toString();
275 logexception_msg(ioe, m);
277 standardFile.close();
284 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile> StandardFontsFile::to_protobuf()
const
286 auto pStandardFontsFileMessage = std::make_unique<Odb::Lib::Protobuf::StandardFontsFile>();
287 pStandardFontsFileMessage->set_xsize(m_xSize);
288 pStandardFontsFileMessage->set_ysize(m_ySize);
289 pStandardFontsFileMessage->set_offset(m_offset);
290 for (
const auto& characterBlock : m_characterBlocks)
292 pStandardFontsFileMessage->add_m_characterblocks()->CopyFrom(*characterBlock->to_protobuf());
294 return pStandardFontsFileMessage;
297 void StandardFontsFile::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile& message)
299 m_xSize = message.xsize();
300 m_ySize = message.ysize();
301 m_offset = message.offset();
302 for (
const auto& characterBlockMessage : message.m_characterblocks())
304 auto pCharacterBlock = std::make_shared<CharacterBlock>();
305 pCharacterBlock->from_protobuf(characterBlockMessage);
306 m_characterBlocks.push_back(pCharacterBlock);
310 StandardFontsFile::CharacterBlock::~CharacterBlock()
312 m_lineRecords.clear();
315 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> StandardFontsFile::CharacterBlock::to_protobuf()
const
317 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> pCharacterBlockMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock);
318 pCharacterBlockMessage->set_character(std::string(1, character));
319 for (
const auto& lineRecord : m_lineRecords)
321 pCharacterBlockMessage->add_m_linerecords()->CopyFrom(*lineRecord->to_protobuf());
323 return pCharacterBlockMessage;
326 void StandardFontsFile::CharacterBlock::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock& message)
328 if (! message.character().empty()) character = message.character()[0];
330 for (
const auto& lineRecordMessage : message.m_linerecords())
332 auto pLineRecord = std::make_shared<LineRecord>();
333 pLineRecord->from_protobuf(lineRecordMessage);
334 m_lineRecords.push_back(pLineRecord);
338 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> StandardFontsFile::CharacterBlock::LineRecord::to_protobuf()
const
340 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> pLineRecordMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord);
341 pLineRecordMessage->set_xstart(xStart);
342 pLineRecordMessage->set_ystart(yStart);
343 pLineRecordMessage->set_xend(xEnd);
344 pLineRecordMessage->set_yend(yEnd);
345 pLineRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
346 pLineRecordMessage->set_shape(
static_cast<Odb::Lib::Protobuf::LineShape
>(shape));
347 pLineRecordMessage->set_width(width);
348 return pLineRecordMessage;
351 void StandardFontsFile::CharacterBlock::LineRecord::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord& message)
353 xStart = message.xstart();
354 yStart = message.ystart();
355 xEnd = message.xend();
356 yEnd = message.yend();
357 polarity =
static_cast<Odb::Lib::Polarity
>(message.polarity());
358 shape =
static_cast<LineShape
>(message.shape());
359 width = message.width();