1#include "StandardFontsFile.h"
5#include "../../Constants.h"
6#include "../../Text/Utf8Sanitizer.h"
7#include "../parse_error.h"
8#include "../invalid_odb_error.h"
12namespace 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))
29 auto message =
"fonts directory does not exist: [" + path.string() +
"]";
30 throw invalid_odb_error(message);
33 auto fontsStandardFile = path /
"standard";
34 if (!std::filesystem::exists(fontsStandardFile))
36 auto message =
"fonts/standard file does not exist: [" + fontsStandardFile.string() +
"]";
37 throw invalid_odb_error(message);
40 standardFile.open(fontsStandardFile, std::ios::in);
41 if (!standardFile.is_open())
43 auto message =
"unable to open fonts/standard file: [" + fontsStandardFile.string() +
"]";
44 throw invalid_odb_error(message);
47 std::shared_ptr<CharacterBlock> pCurrentCharacterBlock;
48 std::shared_ptr<CharacterBlock::LineRecord> pCurrentLineRecord;
49 bool beginTokenFound =
false;
51 while (std::getline(standardFile, line))
56 Utils::str_trim(line);
59 std::stringstream lineStream(line);
60 if (line.find(Constants::COMMENT_TOKEN) == 0)
64 else if (line.find(
"XSIZE") == 0)
67 if (!(lineStream >> token))
69 throw_parse_error(m_path, line, token, lineNumber);
74 throw_parse_error(m_path, line, token, lineNumber);
77 if (!(lineStream >> token))
79 throw_parse_error(m_path, line, token, lineNumber);
82 m_xSize = std::stof(token);
84 else if (line.find(
"YSIZE") == 0)
87 if (!(lineStream >> token))
89 throw_parse_error(m_path, line, token, lineNumber);
94 throw_parse_error(m_path, line, token, lineNumber);
97 if (!(lineStream >> token))
99 throw_parse_error(m_path, line, token, lineNumber);
102 m_ySize = std::stof(token);
104 else if (line.find(
"OFFSET") == 0)
107 if (!(lineStream >> token))
109 throw_parse_error(m_path, line, token, lineNumber);
112 if (token !=
"OFFSET")
114 throw_parse_error(m_path, line, token, lineNumber);
117 if (!(lineStream >> token))
119 throw_parse_error(m_path, line, token, lineNumber);
122 m_offset = std::stof(token);
124 else if (line.find(CharacterBlock::BEGIN_TOKEN) == 0)
126 pCurrentCharacterBlock = std::make_shared<CharacterBlock>();
127 beginTokenFound =
true;
130 if (!(lineStream >> token))
132 throw_parse_error(m_path, line, token, lineNumber);
135 if (token != CharacterBlock::BEGIN_TOKEN)
137 throw_parse_error(m_path, line, token, lineNumber);
140 if (!(lineStream >> token))
142 throw_parse_error(m_path, line, token, lineNumber);
145 Utils::str_trim(token);
146 if (token.length() != 1)
148 throw_parse_error(m_path, line, token, lineNumber);
151 pCurrentCharacterBlock->character = token;
153 else if (line.find(CharacterBlock::END_TOKEN) == 0)
155 if (pCurrentCharacterBlock !=
nullptr && beginTokenFound)
157 m_characterBlocks.push_back(pCurrentCharacterBlock);
158 beginTokenFound =
false;
159 pCurrentCharacterBlock.reset();
163 throw_parse_error(m_path, line,
"", lineNumber);
166 else if (line.find(CharacterBlock::LineRecord::RECORD_TOKEN) == 0)
169 if (!(lineStream >> token))
171 throw_parse_error(m_path, line, token, lineNumber);
174 if (token != CharacterBlock::LineRecord::RECORD_TOKEN)
176 throw_parse_error(m_path, line, token, lineNumber);
179 if (pCurrentCharacterBlock ==
nullptr || !beginTokenFound)
181 throw_parse_error(m_path, line, token, lineNumber);
184 auto pLineRecord = std::make_shared<CharacterBlock::LineRecord>();
186 if (!(lineStream >> token))
188 throw_parse_error(m_path, line, token, lineNumber);
190 pLineRecord->xStart = std::stof(token);
192 if (!(lineStream >> token))
194 throw_parse_error(m_path, line, token, lineNumber);
196 pLineRecord->yStart = std::stof(token);
198 if (!(lineStream >> token))
200 throw_parse_error(m_path, line, token, lineNumber);
202 pLineRecord->xEnd = std::stof(token);
204 if (!(lineStream >> token))
206 throw_parse_error(m_path, line, token, lineNumber);
208 pLineRecord->yEnd = std::stof(token);
211 if (!(lineStream >> token))
213 throw_parse_error(m_path, line, token, lineNumber);
215 Utils::str_trim(token);
217 if (token.length() != 1)
219 throw_parse_error(m_path, line, token, lineNumber);
224 case 'P': pLineRecord->polarity = Polarity::Positive;
break;
225 case 'N': pLineRecord->polarity = Polarity::Negative;
break;
226 default: throw_parse_error(m_path, line, token, lineNumber);
230 if (!(lineStream >> token))
232 throw_parse_error(m_path, line, token, lineNumber);
234 Utils::str_trim(token);
236 if (token.length() != 1)
238 throw_parse_error(m_path, line, token, lineNumber);
243 case 'R': pLineRecord->shape = LineShape::Round;
break;
244 case 'S': pLineRecord->shape = LineShape::Square;
break;
245 default: throw_parse_error(m_path, line, token, lineNumber);
249 if (!(lineStream >> token))
251 throw_parse_error(m_path, line, token, lineNumber);
253 pLineRecord->width = std::stof(token);
255 pCurrentCharacterBlock->m_lineRecords.push_back(pLineRecord);
259 logwarn(
"unrecognized line: " + line);
260 throw_parse_error(m_path, line,
"", lineNumber);
265 standardFile.close();
267 catch (parse_error& pe)
269 auto m = pe.toString(
"Parse Error:");
272 standardFile.close();
275 catch (invalid_odb_error& ioe)
277 parse_info pi(m_path, line, lineNumber);
278 const auto m = pi.toString();
279 logexception_msg(ioe, m);
281 standardFile.close();
288 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile> StandardFontsFile::to_protobuf()
const
290 auto pStandardFontsFileMessage = std::make_unique<Odb::Lib::Protobuf::StandardFontsFile>();
291 pStandardFontsFileMessage->set_xsize(m_xSize);
292 pStandardFontsFileMessage->set_ysize(m_ySize);
293 pStandardFontsFileMessage->set_offset(m_offset);
294 for (
const auto& characterBlock : m_characterBlocks)
296 pStandardFontsFileMessage->add_m_characterblocks()->CopyFrom(*characterBlock->to_protobuf());
298 return pStandardFontsFileMessage;
301 void StandardFontsFile::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile& message)
303 m_xSize = message.xsize();
304 m_ySize = message.ysize();
305 m_offset = message.offset();
306 for (
const auto& characterBlockMessage : message.m_characterblocks())
308 auto pCharacterBlock = std::make_shared<CharacterBlock>();
309 pCharacterBlock->from_protobuf(characterBlockMessage);
310 m_characterBlocks.push_back(pCharacterBlock);
314 bool StandardFontsFile::Save(std::ostream& os)
319 StandardFontsFile::CharacterBlock::~CharacterBlock()
321 m_lineRecords.clear();
324 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> StandardFontsFile::CharacterBlock::to_protobuf()
const
326 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> pCharacterBlockMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock);
327 pCharacterBlockMessage->set_character(Odb::Lib::Text::ToUtf8(character));
328 for (
const auto& lineRecord : m_lineRecords)
330 pCharacterBlockMessage->add_m_linerecords()->CopyFrom(*lineRecord->to_protobuf());
332 return pCharacterBlockMessage;
335 void StandardFontsFile::CharacterBlock::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock& message)
337 if (! message.character().empty()) character = message.character();
339 for (
const auto& lineRecordMessage : message.m_linerecords())
341 auto pLineRecord = std::make_shared<LineRecord>();
342 pLineRecord->from_protobuf(lineRecordMessage);
343 m_lineRecords.push_back(pLineRecord);
347 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> StandardFontsFile::CharacterBlock::LineRecord::to_protobuf()
const
349 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> pLineRecordMessage(
new Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord);
350 pLineRecordMessage->set_xstart(xStart);
351 pLineRecordMessage->set_ystart(yStart);
352 pLineRecordMessage->set_xend(xEnd);
353 pLineRecordMessage->set_yend(yEnd);
354 pLineRecordMessage->set_polarity(
static_cast<Odb::Lib::Protobuf::Polarity
>(polarity));
355 pLineRecordMessage->set_shape(
static_cast<Odb::Lib::Protobuf::LineShape
>(shape));
356 pLineRecordMessage->set_width(width);
357 return pLineRecordMessage;
360 void StandardFontsFile::CharacterBlock::LineRecord::from_protobuf(
const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord& message)
362 xStart = message.xstart();
363 yStart = message.ystart();
364 xEnd = message.xend();
365 yEnd = message.yend();
366 polarity =
static_cast<Odb::Lib::Polarity
>(message.polarity());
367 shape =
static_cast<LineShape
>(message.shape());
368 width = message.width();