1#include "StandardFontsFile.h"
5#include "../../Constants.h"
6#include "../parse_error.h"
7#include "../invalid_odb_error.h"
11namespace Odb::Lib::FileModel::Design
13 StandardFontsFile::~StandardFontsFile()
15 m_characterBlocks.clear();
18 bool StandardFontsFile::Parse(std::filesystem::path path)
20 std::ifstream standardFile;
26 if (!OdbFile::Parse(path))
28 auto message =
"fonts directory does not exist: [" + path.string() +
"]";
29 throw invalid_odb_error(message);
32 auto fontsStandardFile = path /
"standard";
33 if (!std::filesystem::exists(fontsStandardFile))
35 auto message =
"fonts/standard file does not exist: [" + fontsStandardFile.string() +
"]";
36 throw invalid_odb_error(message);
39 standardFile.open(fontsStandardFile, std::ios::in);
40 if (!standardFile.is_open())
42 auto message =
"unable to open fonts/standard file: [" + fontsStandardFile.string() +
"]";
43 throw invalid_odb_error(message);
46 std::shared_ptr<CharacterBlock> pCurrentCharacterBlock;
47 std::shared_ptr<CharacterBlock::LineRecord> pCurrentLineRecord;
48 bool beginTokenFound =
false;
50 while (std::getline(standardFile, line))
55 Utils::str_trim(line);
58 std::stringstream lineStream(line);
59 if (line.find(Constants::COMMENT_TOKEN) == 0)
63 else if (line.find(
"XSIZE") == 0)
66 if (!(lineStream >> token))
68 throw_parse_error(m_path, line, token, lineNumber);
73 throw_parse_error(m_path, line, token, lineNumber);
76 if (!(lineStream >> token))
78 throw_parse_error(m_path, line, token, lineNumber);
81 m_xSize = std::stof(token);
83 else if (line.find(
"YSIZE") == 0)
86 if (!(lineStream >> token))
88 throw_parse_error(m_path, line, token, lineNumber);
93 throw_parse_error(m_path, line, token, lineNumber);
96 if (!(lineStream >> token))
98 throw_parse_error(m_path, line, token, lineNumber);
101 m_ySize = std::stof(token);
103 else if (line.find(
"OFFSET") == 0)
106 if (!(lineStream >> token))
108 throw_parse_error(m_path, line, token, lineNumber);
111 if (token !=
"OFFSET")
113 throw_parse_error(m_path, line, token, lineNumber);
116 if (!(lineStream >> token))
118 throw_parse_error(m_path, line, token, lineNumber);
121 m_offset = std::stof(token);
123 else if (line.find(CharacterBlock::BEGIN_TOKEN) == 0)
125 pCurrentCharacterBlock = std::make_shared<CharacterBlock>();
126 beginTokenFound =
true;
129 if (!(lineStream >> token))
131 throw_parse_error(m_path, line, token, lineNumber);
134 if (token != CharacterBlock::BEGIN_TOKEN)
136 throw_parse_error(m_path, line, token, lineNumber);
139 if (!(lineStream >> token))
141 throw_parse_error(m_path, line, token, lineNumber);
144 Utils::str_trim(token);
145 if (token.length() != 1)
147 throw_parse_error(m_path, line, token, lineNumber);
150 pCurrentCharacterBlock->character = token[0];
152 else if (line.find(CharacterBlock::END_TOKEN) == 0)
154 if (pCurrentCharacterBlock !=
nullptr && beginTokenFound)
156 m_characterBlocks.push_back(pCurrentCharacterBlock);
157 beginTokenFound =
false;
158 pCurrentCharacterBlock.reset();
162 throw_parse_error(m_path, line,
"", lineNumber);
165 else if (line.find(CharacterBlock::LineRecord::RECORD_TOKEN) == 0)
168 if (!(lineStream >> token))
170 throw_parse_error(m_path, line, token, lineNumber);
173 if (token != CharacterBlock::LineRecord::RECORD_TOKEN)
175 throw_parse_error(m_path, line, token, lineNumber);
178 if (pCurrentCharacterBlock ==
nullptr || !beginTokenFound)
180 throw_parse_error(m_path, line, token, lineNumber);
183 auto pLineRecord = std::make_shared<CharacterBlock::LineRecord>();
185 if (!(lineStream >> token))
187 throw_parse_error(m_path, line, token, lineNumber);
189 pLineRecord->xStart = std::stof(token);
191 if (!(lineStream >> token))
193 throw_parse_error(m_path, line, token, lineNumber);
195 pLineRecord->yStart = std::stof(token);
197 if (!(lineStream >> token))
199 throw_parse_error(m_path, line, token, lineNumber);
201 pLineRecord->xEnd = std::stof(token);
203 if (!(lineStream >> token))
205 throw_parse_error(m_path, line, token, lineNumber);
207 pLineRecord->yEnd = std::stof(token);
210 if (!(lineStream >> token))
212 throw_parse_error(m_path, line, token, lineNumber);
214 Utils::str_trim(token);
216 if (token.length() != 1)
218 throw_parse_error(m_path, line, token, lineNumber);
223 case 'P': pLineRecord->polarity = Polarity::Positive;
break;
224 case 'N': pLineRecord->polarity = Polarity::Negative;
break;
225 default: throw_parse_error(m_path, line, token, lineNumber);
229 if (!(lineStream >> token))
231 throw_parse_error(m_path, line, token, lineNumber);
233 Utils::str_trim(token);
235 if (token.length() != 1)
237 throw_parse_error(m_path, line, token, lineNumber);
242 case 'R': pLineRecord->shape = LineShape::Round;
break;
243 case 'S': pLineRecord->shape = LineShape::Square;
break;
244 default: throw_parse_error(m_path, line, token, lineNumber);
248 if (!(lineStream >> token))
250 throw_parse_error(m_path, line, token, lineNumber);
252 pLineRecord->width = std::stof(token);
254 pCurrentCharacterBlock->m_lineRecords.push_back(pLineRecord);
258 logwarn(
"unrecognized line: " + line);
259 throw_parse_error(m_path, line,
"", lineNumber);
264 standardFile.close();
266 catch (parse_error& pe)
268 auto m = pe.toString(
"Parse Error:");
271 standardFile.close();
274 catch (invalid_odb_error& ioe)
276 parse_info pi(m_path, line, lineNumber);
277 const auto m = pi.toString();
278 logexception_msg(ioe, m);
280 standardFile.close();
287 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile> StandardFontsFile::to_protobuf()
const
289 auto pStandardFontsFileMessage = std::make_unique<Odb::Lib::Protobuf::StandardFontsFile>();
290 pStandardFontsFileMessage->set_xsize(m_xSize);
291 pStandardFontsFileMessage->set_ysize(m_ySize);
292 pStandardFontsFileMessage->set_offset(m_offset);
293 for (
const auto& characterBlock : m_characterBlocks)
295 pStandardFontsFileMessage->add_m_characterblocks()->CopyFrom(*characterBlock->to_protobuf());
297 return pStandardFontsFileMessage;
300 void StandardFontsFile::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile& message)
302 m_xSize = message.xsize();
303 m_ySize = message.ysize();
304 m_offset = message.offset();
305 for (
const auto& characterBlockMessage : message.m_characterblocks())
307 auto pCharacterBlock = std::make_shared<CharacterBlock>();
308 pCharacterBlock->from_protobuf(characterBlockMessage);
309 m_characterBlocks.push_back(pCharacterBlock);
313 bool StandardFontsFile::Save(std::ostream& os)
318 StandardFontsFile::CharacterBlock::~CharacterBlock()
320 m_lineRecords.clear();
323 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> StandardFontsFile::CharacterBlock::to_protobuf()
const
325 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> pCharacterBlockMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock);
326 pCharacterBlockMessage->set_character(std::string(1, character));
327 for (
const auto& lineRecord : m_lineRecords)
329 pCharacterBlockMessage->add_m_linerecords()->CopyFrom(*lineRecord->to_protobuf());
331 return pCharacterBlockMessage;
334 void StandardFontsFile::CharacterBlock::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock& message)
336 if (! message.character().empty()) character = message.character()[0];
338 for (
const auto& lineRecordMessage : message.m_linerecords())
340 auto pLineRecord = std::make_shared<LineRecord>();
341 pLineRecord->from_protobuf(lineRecordMessage);
342 m_lineRecords.push_back(pLineRecord);
346 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> StandardFontsFile::CharacterBlock::LineRecord::to_protobuf()
const
348 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> pLineRecordMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord);
349 pLineRecordMessage->set_xstart(xStart);
350 pLineRecordMessage->set_ystart(yStart);
351 pLineRecordMessage->set_xend(xEnd);
352 pLineRecordMessage->set_yend(yEnd);
353 pLineRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
354 pLineRecordMessage->set_shape(
static_cast<Odb::Lib::Protobuf::LineShape
>(shape));
355 pLineRecordMessage->set_width(width);
356 return pLineRecordMessage;
359 void StandardFontsFile::CharacterBlock::LineRecord::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord& message)
361 xStart = message.xstart();
362 yStart = message.ystart();
363 xEnd = message.xend();
364 yEnd = message.yend();
365 polarity =
static_cast<Odb::Lib::Polarity
>(message.polarity());
366 shape =
static_cast<LineShape
>(message.shape());
367 width = message.width();