OdbDesignLib
OdbDesign ODB++ Parsing Library
 
Loading...
Searching...
No Matches
StandardFontsFile.cpp
1#include "StandardFontsFile.h"
2#include "Logger.h"
3#include <fstream>
4#include "str_utils.h"
5#include "../../Constants.h"
6#include "../parse_error.h"
7#include "../invalid_odb_error.h"
8#include "enums.pb.h"
9
10
11namespace Odb::Lib::FileModel::Design
12{
13 StandardFontsFile::~StandardFontsFile()
14 {
15 m_characterBlocks.clear();
16 }
17
18 bool StandardFontsFile::Parse(std::filesystem::path path)
19 {
20 std::ifstream standardFile;
21 int lineNumber = 0;
22 std::string line;
23
24 try
25 {
26 if (!OdbFile::Parse(path))
27 {
28 auto message = "fonts directory does not exist: [" + path.string() + "]";
29 throw invalid_odb_error(message);
30 }
31
32 auto fontsStandardFile = path / "standard";
33 if (!std::filesystem::exists(fontsStandardFile))
34 {
35 auto message = "fonts/standard file does not exist: [" + fontsStandardFile.string() + "]";
36 throw invalid_odb_error(message);
37 }
38
39 standardFile.open(fontsStandardFile, std::ios::in);
40 if (!standardFile.is_open())
41 {
42 auto message = "unable to open fonts/standard file: [" + fontsStandardFile.string() + "]";
43 throw invalid_odb_error(message);
44 }
45
46 std::shared_ptr<CharacterBlock> pCurrentCharacterBlock;
47 std::shared_ptr<CharacterBlock::LineRecord> pCurrentLineRecord;
48 bool beginTokenFound = false;
49
50 while (std::getline(standardFile, line))
51 {
52 lineNumber++;
53
54 // trim whitespace from beginning and end of line
55 Utils::str_trim(line);
56 if (!line.empty())
57 {
58 std::stringstream lineStream(line);
59 if (line.find(Constants::COMMENT_TOKEN) == 0)
60 {
61 // comment line
62 }
63 else if (line.find("XSIZE") == 0)
64 {
65 std::string token;
66 if (!(lineStream >> token))
67 {
68 throw_parse_error(m_path, line, token, lineNumber);
69 }
70
71 if (token != "XSIZE")
72 {
73 throw_parse_error(m_path, line, token, lineNumber);
74 }
75
76 if (!(lineStream >> token))
77 {
78 throw_parse_error(m_path, line, token, lineNumber);
79 }
80
81 m_xSize = std::stof(token);
82 }
83 else if (line.find("YSIZE") == 0)
84 {
85 std::string token;
86 if (!(lineStream >> token))
87 {
88 throw_parse_error(m_path, line, token, lineNumber);
89 }
90
91 if (token != "YSIZE")
92 {
93 throw_parse_error(m_path, line, token, lineNumber);
94 }
95
96 if (!(lineStream >> token))
97 {
98 throw_parse_error(m_path, line, token, lineNumber);
99 }
100
101 m_ySize = std::stof(token);
102 }
103 else if (line.find("OFFSET") == 0)
104 {
105 std::string token;
106 if (!(lineStream >> token))
107 {
108 throw_parse_error(m_path, line, token, lineNumber);
109 }
110
111 if (token != "OFFSET")
112 {
113 throw_parse_error(m_path, line, token, lineNumber);
114 }
115
116 if (!(lineStream >> token))
117 {
118 throw_parse_error(m_path, line, token, lineNumber);
119 }
120
121 m_offset = std::stof(token);
122 }
123 else if (line.find(CharacterBlock::BEGIN_TOKEN) == 0)
124 {
125 pCurrentCharacterBlock = std::make_shared<CharacterBlock>();
126 beginTokenFound = true;
127
128 std::string token;
129 if (!(lineStream >> token))
130 {
131 throw_parse_error(m_path, line, token, lineNumber);
132 }
133
134 if (token != CharacterBlock::BEGIN_TOKEN)
135 {
136 throw_parse_error(m_path, line, token, lineNumber);
137 }
138
139 if (!(lineStream >> token))
140 {
141 throw_parse_error(m_path, line, token, lineNumber);
142 }
143
144 Utils::str_trim(token);
145 if (token.length() != 1)
146 {
147 throw_parse_error(m_path, line, token, lineNumber);
148 }
149
150 pCurrentCharacterBlock->character = token[0];
151 }
152 else if (line.find(CharacterBlock::END_TOKEN) == 0)
153 {
154 if (pCurrentCharacterBlock != nullptr && beginTokenFound)
155 {
156 m_characterBlocks.push_back(pCurrentCharacterBlock);
157 beginTokenFound = false;
158 pCurrentCharacterBlock.reset();
159 }
160 else
161 {
162 throw_parse_error(m_path, line, "", lineNumber);
163 }
164 }
165 else if (line.find(CharacterBlock::LineRecord::RECORD_TOKEN) == 0)
166 {
167 std::string token;
168 if (!(lineStream >> token))
169 {
170 throw_parse_error(m_path, line, token, lineNumber);
171 }
172
173 if (token != CharacterBlock::LineRecord::RECORD_TOKEN)
174 {
175 throw_parse_error(m_path, line, token, lineNumber);
176 }
177
178 if (pCurrentCharacterBlock == nullptr || !beginTokenFound)
179 {
180 throw_parse_error(m_path, line, token, lineNumber);
181 }
182
183 auto pLineRecord = std::make_shared<CharacterBlock::LineRecord>();
184
185 if (!(lineStream >> token))
186 {
187 throw_parse_error(m_path, line, token, lineNumber);
188 }
189 pLineRecord->xStart = std::stof(token);
190
191 if (!(lineStream >> token))
192 {
193 throw_parse_error(m_path, line, token, lineNumber);
194 }
195 pLineRecord->yStart = std::stof(token);
196
197 if (!(lineStream >> token))
198 {
199 throw_parse_error(m_path, line, token, lineNumber);
200 }
201 pLineRecord->xEnd = std::stof(token);
202
203 if (!(lineStream >> token))
204 {
205 throw_parse_error(m_path, line, token, lineNumber);
206 }
207 pLineRecord->yEnd = std::stof(token);
208
209 // polarity
210 if (!(lineStream >> token))
211 {
212 throw_parse_error(m_path, line, token, lineNumber);
213 }
214 Utils::str_trim(token);
215
216 if (token.length() != 1)
217 {
218 throw_parse_error(m_path, line, token, lineNumber);
219 }
220
221 switch (token[0])
222 {
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);
226 }
227
228 // shape
229 if (!(lineStream >> token))
230 {
231 throw_parse_error(m_path, line, token, lineNumber);
232 }
233 Utils::str_trim(token);
234
235 if (token.length() != 1)
236 {
237 throw_parse_error(m_path, line, token, lineNumber);
238 }
239
240 switch (token[0])
241 {
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);
245 }
246
247 // width
248 if (!(lineStream >> token))
249 {
250 throw_parse_error(m_path, line, token, lineNumber);
251 }
252 pLineRecord->width = std::stof(token);
253
254 pCurrentCharacterBlock->m_lineRecords.push_back(pLineRecord);
255 }
256 else
257 {
258 logwarn("unrecognized line: " + line);
259 throw_parse_error(m_path, line, "", lineNumber);
260 }
261 }
262 }
263
264 standardFile.close();
265 }
266 catch (parse_error& pe)
267 {
268 auto m = pe.toString("Parse Error:");
269 logerror(m);
270 // cleanup file
271 standardFile.close();
272 throw pe;
273 }
274 catch (invalid_odb_error& ioe)
275 {
276 parse_info pi(m_path, line, lineNumber);
277 const auto m = pi.toString();
278 logexception_msg(ioe, m);
279 // cleanup file
280 standardFile.close();
281 throw ioe;
282 }
283
284 return true;
285 }
286
287 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile> StandardFontsFile::to_protobuf() const
288 {
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)
294 {
295 pStandardFontsFileMessage->add_m_characterblocks()->CopyFrom(*characterBlock->to_protobuf());
296 }
297 return pStandardFontsFileMessage;
298 }
299
300 void StandardFontsFile::from_protobuf(const Odb::Lib::Protobuf::StandardFontsFile& message)
301 {
302 m_xSize = message.xsize();
303 m_ySize = message.ysize();
304 m_offset = message.offset();
305 for (const auto& characterBlockMessage : message.m_characterblocks())
306 {
307 auto pCharacterBlock = std::make_shared<CharacterBlock>();
308 pCharacterBlock->from_protobuf(characterBlockMessage);
309 m_characterBlocks.push_back(pCharacterBlock);
310 }
311 }
312
313 bool StandardFontsFile::Save(std::ostream& os)
314 {
315 return true;
316 }
317
318 StandardFontsFile::CharacterBlock::~CharacterBlock()
319 {
320 m_lineRecords.clear();
321 }
322
323 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock> StandardFontsFile::CharacterBlock::to_protobuf() const
324 {
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)
328 {
329 pCharacterBlockMessage->add_m_linerecords()->CopyFrom(*lineRecord->to_protobuf());
330 }
331 return pCharacterBlockMessage;
332 }
333
334 void StandardFontsFile::CharacterBlock::from_protobuf(const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock& message)
335 {
336 if (! message.character().empty()) character = message.character()[0];
337
338 for (const auto& lineRecordMessage : message.m_linerecords())
339 {
340 auto pLineRecord = std::make_shared<LineRecord>();
341 pLineRecord->from_protobuf(lineRecordMessage);
342 m_lineRecords.push_back(pLineRecord);
343 }
344 }
345
346 std::unique_ptr<Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord> StandardFontsFile::CharacterBlock::LineRecord::to_protobuf() const
347 {
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;
357 }
358
359 void StandardFontsFile::CharacterBlock::LineRecord::from_protobuf(const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord& message)
360 {
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();
368 }
369
370}