1 #include "StandardFontsFile.h"
5 #include "../../Constants.h"
6 #include "../parse_error.h"
7 #include "../invalid_odb_error.h"
8 #include "../../ProtoBuf/enums.pb.h"
11 namespace 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))
return false;
28 auto fontsStandardFile = path /
"standard";
29 if (!std::filesystem::exists(fontsStandardFile))
31 auto message =
"fonts/standard file does not exist: [" + fontsStandardFile.string() +
"]";
32 throw invalid_odb_error(message.c_str());
35 standardFile.open(fontsStandardFile, std::ios::in);
36 if (!standardFile.is_open())
38 auto message =
"unable to open fonts/standard file: [" + fontsStandardFile.string() +
"]";
39 throw invalid_odb_error(message.c_str());
42 std::shared_ptr<CharacterBlock> pCurrentCharacterBlock;
43 std::shared_ptr<CharacterBlock::LineRecord> pCurrentLineRecord;
44 bool beginTokenFound =
false;
46 while (std::getline(standardFile, line))
51 Utils::str_trim(line);
54 std::stringstream lineStream(line);
55 if (line.find(Constants::COMMENT_TOKEN) == 0)
59 else if (line.find(
"XSIZE") == 0)
62 if (!(lineStream >> token))
64 throw_parse_error(m_path, line, token, lineNumber);
69 throw_parse_error(m_path, line, token, lineNumber);
72 if (!(lineStream >> token))
74 throw_parse_error(m_path, line, token, lineNumber);
77 m_xSize = std::stof(token);
79 else if (line.find(
"YSIZE") == 0)
82 if (!(lineStream >> token))
84 throw_parse_error(m_path, line, token, lineNumber);
89 throw_parse_error(m_path, line, token, lineNumber);
92 if (!(lineStream >> token))
94 throw_parse_error(m_path, line, token, lineNumber);
97 m_ySize = std::stof(token);
99 else if (line.find(
"OFFSET") == 0)
102 if (!(lineStream >> token))
104 throw_parse_error(m_path, line, token, lineNumber);
107 if (token !=
"OFFSET")
109 throw_parse_error(m_path, line, token, lineNumber);
112 if (!(lineStream >> token))
114 throw_parse_error(m_path, line, token, lineNumber);
117 m_offset = std::stof(token);
119 else if (line.find(CharacterBlock::BEGIN_TOKEN) == 0)
121 pCurrentCharacterBlock = std::make_shared<CharacterBlock>();
122 beginTokenFound =
true;
125 if (!(lineStream >> token))
127 throw_parse_error(m_path, line, token, lineNumber);
130 if (token != CharacterBlock::BEGIN_TOKEN)
132 throw_parse_error(m_path, line, token, lineNumber);
135 if (!(lineStream >> token))
137 throw_parse_error(m_path, line, token, lineNumber);
140 Utils::str_trim(token);
141 if (token.length() != 1)
143 throw_parse_error(m_path, line, token, lineNumber);
146 pCurrentCharacterBlock->character = token[0];
148 else if (line.find(CharacterBlock::END_TOKEN) == 0)
150 if (pCurrentCharacterBlock !=
nullptr && beginTokenFound)
152 m_characterBlocks.push_back(pCurrentCharacterBlock);
153 beginTokenFound =
false;
154 pCurrentCharacterBlock.reset();
158 throw_parse_error(m_path, line,
"", lineNumber);
161 else if (line.find(CharacterBlock::LineRecord::RECORD_TOKEN) == 0)
164 if (!(lineStream >> token))
166 throw_parse_error(m_path, line, token, lineNumber);
169 if (token != CharacterBlock::LineRecord::RECORD_TOKEN)
171 throw_parse_error(m_path, line, token, lineNumber);
174 if (pCurrentCharacterBlock ==
nullptr || !beginTokenFound)
176 throw_parse_error(m_path, line, token, lineNumber);
179 auto pLineRecord = std::make_shared<CharacterBlock::LineRecord>();
181 if (!(lineStream >> token))
183 throw_parse_error(m_path, line, token, lineNumber);
185 pLineRecord->xStart = std::stof(token);
187 if (!(lineStream >> token))
189 throw_parse_error(m_path, line, token, lineNumber);
191 pLineRecord->yStart = std::stof(token);
193 if (!(lineStream >> token))
195 throw_parse_error(m_path, line, token, lineNumber);
197 pLineRecord->xEnd = std::stof(token);
199 if (!(lineStream >> token))
201 throw_parse_error(m_path, line, token, lineNumber);
203 pLineRecord->yEnd = std::stof(token);
206 if (!(lineStream >> token))
208 throw_parse_error(m_path, line, token, lineNumber);
210 Utils::str_trim(token);
212 if (token.length() != 1)
214 throw_parse_error(m_path, line, token, lineNumber);
219 case 'P': pLineRecord->polarity = Polarity::Positive;
break;
220 case 'N': pLineRecord->polarity = Polarity::Negative;
break;
221 default: throw_parse_error(m_path, line, token, lineNumber);
225 if (!(lineStream >> token))
227 throw_parse_error(m_path, line, token, lineNumber);
229 Utils::str_trim(token);
231 if (token.length() != 1)
233 throw_parse_error(m_path, line, token, lineNumber);
238 case 'R': pLineRecord->shape = LineShape::Round;
break;
239 case 'S': pLineRecord->shape = LineShape::Square;
break;
240 default: throw_parse_error(m_path, line, token, lineNumber);
244 if (!(lineStream >> token))
246 throw_parse_error(m_path, line, token, lineNumber);
248 pLineRecord->width = std::stof(token);
250 pCurrentCharacterBlock->m_lineRecords.push_back(pLineRecord);
254 logwarn(
"unrecognized line: " + line);
255 throw_parse_error(m_path, line,
"", lineNumber);
260 standardFile.close();
262 catch (parse_error& pe)
264 auto m = pe.toString(
"Parse Error:");
267 standardFile.close();
270 catch (invalid_odb_error& ioe)
272 parse_info pi(m_path, line, lineNumber);
273 const auto m = pi.toString();
274 logexception_msg(ioe, m);
276 standardFile.close();
283 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile> StandardFontsFile::to_protobuf()
const
285 auto pStandardFontsFileMessage = std::make_unique<Odb::Lib::Protobuf::StandardFontsFile>();
286 pStandardFontsFileMessage->set_xsize(m_xSize);
287 pStandardFontsFileMessage->set_ysize(m_ySize);
288 pStandardFontsFileMessage->set_offset(m_offset);
289 for (
const auto& characterBlock : m_characterBlocks)
291 pStandardFontsFileMessage->add_m_characterblocks()->CopyFrom(*characterBlock->to_protobuf());
293 return pStandardFontsFileMessage;
296 void StandardFontsFile::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile& message)
298 m_xSize = message.xsize();
299 m_ySize = message.ysize();
300 m_offset = message.offset();
301 for (
const auto& characterBlockMessage : message.m_characterblocks())
303 auto pCharacterBlock = std::make_shared<CharacterBlock>();
304 pCharacterBlock->from_protobuf(characterBlockMessage);
305 m_characterBlocks.push_back(pCharacterBlock);
309 bool StandardFontsFile::Save(std::ostream& os)
314 StandardFontsFile::CharacterBlock::~CharacterBlock()
316 m_lineRecords.clear();
319 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> StandardFontsFile::CharacterBlock::to_protobuf()
const
321 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> pCharacterBlockMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock);
322 pCharacterBlockMessage->set_character(std::string(1, character));
323 for (
const auto& lineRecord : m_lineRecords)
325 pCharacterBlockMessage->add_m_linerecords()->CopyFrom(*lineRecord->to_protobuf());
327 return pCharacterBlockMessage;
330 void StandardFontsFile::CharacterBlock::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock& message)
332 if (! message.character().empty()) character = message.character()[0];
334 for (
const auto& lineRecordMessage : message.m_linerecords())
336 auto pLineRecord = std::make_shared<LineRecord>();
337 pLineRecord->from_protobuf(lineRecordMessage);
338 m_lineRecords.push_back(pLineRecord);
342 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> StandardFontsFile::CharacterBlock::LineRecord::to_protobuf()
const
344 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> pLineRecordMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord);
345 pLineRecordMessage->set_xstart(xStart);
346 pLineRecordMessage->set_ystart(yStart);
347 pLineRecordMessage->set_xend(xEnd);
348 pLineRecordMessage->set_yend(yEnd);
349 pLineRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
350 pLineRecordMessage->set_shape(
static_cast<Odb::Lib::Protobuf::LineShape
>(shape));
351 pLineRecordMessage->set_width(width);
352 return pLineRecordMessage;
355 void StandardFontsFile::CharacterBlock::LineRecord::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord& message)
357 xStart = message.xstart();
358 yStart = message.ystart();
359 xEnd = message.xend();
360 yEnd = message.yend();
361 polarity =
static_cast<Odb::Lib::Polarity
>(message.polarity());
362 shape =
static_cast<LineShape
>(message.shape());
363 width = message.width();