1 /*
2  *    Copyright 2013, 2015, 2016 Kai Pastor
3  *
4  *    This file is part of OpenOrienteering.
5  *
6  *    OpenOrienteering is free software: you can redistribute it and/or modify
7  *    it under the terms of the GNU General Public License as published by
8  *    the Free Software Foundation, either version 3 of the License, or
9  *    (at your option) any later version.
10  *
11  *    OpenOrienteering is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  *
16  *    You should have received a copy of the GNU General Public License
17  *    along with OpenOrienteering.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef OPENORIENTEERING_OCD_TYPES_V8_H
21 #define OPENORIENTEERING_OCD_TYPES_V8_H
22 
23 #include <array>
24 
25 #include "ocd_types.h"
26 
27 namespace Ocd
28 {
29 
30 #pragma pack(push, 1)
31 
32 	// Not found in OCD >= V9.
33 	// Common default values, not preserved on import.
34 	struct CmykScreenV8
35 	{
36 		quint16 cyan_freq     = 1500;
37 		quint16 cyan_angle    =  150;
38 		quint16 magenta_freq  = 1500;
39 		quint16 magenta_angle =  750;
40 		quint16 yellow_freq   = 1500;
41 		quint16 yellow_angle  =    0;
42 		quint16 black_freq    = 1500;
43 		quint16 black_angle   =  450;
44 	};
45 
46 	inline bool operator==(const CmykScreenV8& lhs, const CmykScreenV8& rhs)
47 	{
48 		return 0 == memcmp(&lhs, &rhs, sizeof(CmykScreenV8));
49 	}
50 
51 	inline bool operator!=(const CmykScreenV8& lhs, const CmykScreenV8& rhs)
52 	{
53 		return !(lhs == rhs);
54 	}
55 
56 	struct CmykV8
57 	{
58 		quint8 cyan;
59 		quint8 magenta;
60 		quint8 yellow;
61 		quint8 black;
62 	};
63 
64 	struct ColorInfoV8
65 	{
66 		quint16 number;
67 		quint16 RESERVED_MEMBER;
68 		CmykV8  cmyk;
69 		PascalString<31> name;
70 		quint8  separations[32];
71 	};
72 
73 	struct SeparationInfoV8
74 	{
75 		PascalString<15> name;
76 		CmykV8  cmyk;
77 		quint16 raster_freq;
78 		quint16 raster_angle;
79 	};
80 
81 	struct SymbolHeaderV8
82 	{
83 		quint16 num_colors;
84 		quint16 num_separations;
85 		CmykScreenV8 cmyk_screen;
86 		quint16 RESERVED_MEMBER[2];
87 		ColorInfoV8 color_info[256];
88 		SeparationInfoV8 separation_info[32];
89 	};
90 
91 	struct FileHeaderV8 : public FileHeaderGeneric
92 	{
93 		quint32 first_symbol_block;
94 		quint32 first_object_block;
95 		quint32 setup_pos;
96 		quint32 setup_size;
97 		quint32 info_pos;
98 		quint32 info_size;
99 		quint32 first_string_block;
100 		quint32 RESERVED_MEMBER[3];
101 		SymbolHeaderV8 symbol_header;
102 	};
103 
104 
105 	struct IconV9;
106 
107 	struct IconV8
108 	{
109 		quint8  bits[264];
lengthIconV8110 		static constexpr unsigned length() { return 264; }
111 
heightIconV8112 		static constexpr int height() { return 22; }
widthIconV8113 		static constexpr int width() { return 22; }
114 
115 		template<typename RGB>
paletteIconV8116 		static std::array<RGB, 16> palette() {
117 			return {
118 				RGB{   0,   0,   0 },
119 				RGB{ 128,   0,   0 },
120 				RGB{ 0,   128,   0 },
121 				RGB{ 128, 128,   0 },
122 				RGB{   0,   0, 128 },
123 				RGB{ 128,   0, 128 },
124 				RGB{   0, 128, 128 },
125 				RGB{ 128, 128, 128 },
126 				RGB{ 192, 192, 192 },
127 				RGB{ 255,   0,   0 },
128 				RGB{   0, 255,   0 },
129 				RGB{ 255, 255,   0 },
130 				RGB{   0,   0, 255 },
131 				RGB{ 255,   0, 255 },
132 				RGB{   0, 255, 255 },
133 				RGB{ 255, 255, 255 }
134 			};
135 		}
136 
137 		IconV9 uncompress() const;  // may throw
138 	};
139 
140 	bool operator==(const IconV8& lhs, const IconV8& rhs);
141 
142 	inline bool operator!=(const IconV8& lhs, const IconV8& rhs) { return !(lhs == rhs); }
143 
144 	struct BaseSymbolV8
145 	{
146 		using IndexEntryType = SymbolIndexEntry;
147 		static const int symbol_number_factor = 10;
148 
149 		quint16 size;
150 		quint16 number;
151 		quint16 type;
152 		quint8  type2;
153 		quint8  flags;
154 		quint16 extent;
155 		quint8  selected;
156 		quint8  status;
157 		quint16 RESERVED_MEMBER[2];
158 		qint32  file_pos;
159 		quint8  colors[32];
160 		PascalString<31> description;
161 		IconV8  icon;
162 	};
163 
164 	struct PointSymbolElementV8
165 	{
166 		quint16 type;
167 		quint16 flags;
168 		quint16 color;
169 		qint16  line_width;
170 		qint16  diameter;
171 		quint16 num_coords;
172 		quint32 RESERVED_MEMBER;
173 
174 		enum PointSymbolElementTypes
175 		{
176 			TypeLine   = 1,
177 			TypeArea   = 2,
178 			TypeCircle = 3,
179 			TypeDot    = 4
180 		};
181 
182 		enum Flags
183 		{
184 			NoFlags        = 0,
185 			RoundStyle     = 1,
186 			FlatMiterStyle = 4,
187 		};
188 	};
189 
190 	struct PointSymbolV8
191 	{
192 		using BaseSymbol = BaseSymbolV8;
193 		using Element    = PointSymbolElementV8;
194 
195 		BaseSymbol base;
196 
197 		quint16 data_size;
198 		quint16 RESERVED_MEMBER;
199 		Element begin_of_elements[1];
200 	};
201 
202 	struct LineSymbolCommonV8
203 	{
204 		quint16 line_color;
205 		quint16 line_width;
206 		quint16 line_style;
207 		qint16  dist_from_start;
208 		qint16  dist_from_end;
209 		qint16  main_length;
210 		qint16  end_length;
211 		qint16  main_gap;
212 		qint16  sec_gap;
213 		qint16  end_gap;
214 		qint16  min_sym;
215 		qint16  num_prim_sym;
216 		qint16  prim_sym_dist;
217 		quint16 double_mode;
218 		quint16 double_flags;
219 		quint16 double_color;
220 		quint16 double_left_color;
221 		quint16 double_right_color;
222 		qint16  double_width;
223 		qint16  double_left_width;
224 		qint16  double_right_width;
225 		qint16  double_length;
226 		qint16  double_gap;
227 		quint16 double_background_color_V11; /// \since V11
228 		quint16 RESERVED_MEMBER[2];
229 		quint16 dec_mode;
230 		quint16 dec_last;
231 		quint16 RESERVED_MEMBER;
232 		quint16 framing_color;
233 		qint16  framing_width;
234 		quint16 framing_style;
235 		quint16 primary_data_size;
236 		quint16 secondary_data_size;
237 		quint16 corner_data_size;
238 		quint16 start_data_size;
239 		quint16 end_data_size;
240 		quint8  active_symbols_V11;          /// \since V11
241 		quint8  RESERVED_MEMBER;
242 
243 		enum LineStyleFlag
244 		{
245 			BevelJoin_FlatCap    = 0,
246 			RoundJoin_RoundCap   = 1,
247 			BevelJoin_PointedCap = 2,
248 			RoundJoin_PointedCap = 3,
249 			MiterJoin_FlatCap    = 4,
250 			MiterJoin_PointedCap = 6
251 		};
252 
253 		enum DoubleLineFlags
254 		{
255 			DoubleFlagFillColorOn       = 1,
256 			DoubleFlagBackgroundColorOn = 2,
257 		};
258 
259 		enum DoubleLineMode
260 		{
261 			DoubleLineOff              = 0,
262 			DoubleLineContinuous       = 1,
263 			DoubleLineLeftBorderDashed = 2,
264 			DoubleLineBordersDashed    = 3,
265 			DoubleLineAllDashed        = 4,
266 		};
267 	};
268 
269 	struct LineSymbolV8
270 	{
271 		using BaseSymbol = BaseSymbolV8;
272 		using Element    = PointSymbolElementV8;
273 
274 		BaseSymbol base;
275 
276 		LineSymbolCommonV8 common;
277 
278 		Element begin_of_elements[1];
279 	};
280 
281 	struct AreaSymbolCommonV8
282 	{
283 		quint16 fill_color;
284 		quint16 hatch_mode;
285 		quint16 hatch_color;
286 		quint16 hatch_line_width;
287 		quint16 hatch_dist;
288 		qint16  hatch_angle_1;
289 		qint16  hatch_angle_2;
290 		quint8  fill_on_V9;         /// \since V9
291 		quint8  border_on_V9;       /// \since V9
292 		quint8  structure_mode;
293 		quint8  structure_draw_V12; /// \since V12
294 		quint16 structure_width;
295 		quint16 structure_height;
296 		qint16  structure_angle;
297 	};
298 
299 	struct AreaSymbolV8
300 	{
301 		using BaseSymbol = BaseSymbolV8;
302 		using Element    = PointSymbolElementV8;
303 
304 		BaseSymbol base;
305 
306 		quint16 RESERVED_MEMBER;    // formerly known as area_flags
307 		quint16 fill_on;
308 		AreaSymbolCommonV8 common;
309 		quint16 RESERVED_MEMBER;
310 		quint16 data_size;
311 
312 		Element begin_of_elements[1];
313 	};
314 
315 	struct BasicTextAttributesV8
316 	{
317 		quint16 color;
318 		quint16 font_size;
319 		quint16 font_weight;
320 		quint8  font_italic;
321 		quint8  charset_V8_ONLY;         /// V8 text symbols only
322 		quint16 char_spacing;
323 		quint16 word_spacing;
324 		quint16 alignment;
325 	};
326 
327 	struct SpecialTextAttributesV8
328 	{
329 		quint16 line_spacing;
330 		qint16  para_spacing;
331 		quint16 indent_first_line;
332 		quint16 indent_other_lines;
333 		quint16 num_tabs;
334 		quint32 tab_pos[32];
335 		quint16 line_below_on;
336 		quint16 line_below_color;
337 		quint16 line_below_width;
338 		quint16 line_below_offset;
339 	};
340 
341 	struct FramingAttributesV8
342 	{
343 		quint8  mode;                    /// 16 bit in V8
344 		quint8  line_style_V9;           /// \since V9
345 		quint8  point_symbol_on_V10;     /// \since V10
346 		quint32 point_symbol_number_V10; /// \since V10
347 		char    RESERVED_MEMBER[19];
348 		quint16 border_left_V9;          /// \since V9; TextSymbol only
349 		quint16 border_bottom_V9;        /// \since V9; TextSymbol only
350 		quint16 border_right_V9;         /// \since V9; TextSymbol only
351 		quint16 border_top_V9;           /// \since V9; TextSymbol only
352 		quint16 color;
353 		quint16 line_width;
354 		quint16 font_weight;             /// TextSymbol only
355 		quint16 italic;                  /// TextSymbol only
356 		quint16 offset_x;
357 		quint16 offset_y;
358 	};
359 
360 	struct TextSymbolV8
361 	{
362 		using BaseSymbol = BaseSymbolV8;
363 
364 		BaseSymbol base;
365 
366 		PascalString<31>        font_name;
367 		BasicTextAttributesV8   basic;
368 		SpecialTextAttributesV8 special;
369 		quint16                 RESERVED_MEMBER;
370 		FramingAttributesV8     framing;
371 	};
372 
373 	struct LineTextSymbolV8 /// \todo use and test...
374 	{
375 		using BaseSymbol = BaseSymbolV8;
376 
377 		BaseSymbol base;
378 
379 		PascalString<31>      font_name;
380 		BasicTextAttributesV8 basic;
381 		FramingAttributesV8   framing;
382 	};
383 
384 	struct RectangleSymbolV8
385 	{
386 		using BaseSymbol = BaseSymbolV8;
387 
388 		BaseSymbol base;
389 
390 		quint16 line_color;
391 		quint16 line_width;
392 		quint16 corner_radius;
393 		quint16 grid_flags;
394 		quint16 cell_width;
395 		quint16 cell_height;
396 		quint16 RESERVED_MEMBER[2];
397 		quint16 unnumbered_cells;
398 		PascalString<3> unnumbered_text;
399 		quint16 RESERVED_MEMBER;
400 		PascalString<31> RESERVED_MEMBER;
401 		quint16 RESERVED_MEMBER[6];
402 	};
403 
404 	struct ObjectIndexEntryV8
405 	{
406 		OcdPoint32 bottom_left_bound;
407 		OcdPoint32 top_right_bound;
408 		quint32 pos;
409 		quint16 size;      /// Different interpretation for version < 8
410 		qint16  symbol;
411 	};
412 
413 	struct ObjectV8
414 	{
415 		using IndexEntryType = ObjectIndexEntryV8;
416 
417 		qint16  symbol;
418 		quint8  type;
419 		quint8  unicode;
420 		quint16 num_items;
421 		quint16 num_text;
422 		qint16  angle;
423 		quint16 RESERVED_MEMBER;
424 		quint32 RESERVED_MEMBER;
425 		PascalString<15> reserved;
426 
427 		OcdPoint32 coords[1];
428 	};
429 
430 	typedef double PascalDouble;
431 
432 	struct GpsPointV8
433 	{
434 		OcdPoint32 map_point;
435 		PascalDouble lat;
436 		PascalDouble lon;
437 		PascalString<15> name;
438 	};
439 
440 	struct PrintSetupV8
441 	{
442 		OcdPoint32 bottom_left;
443 		OcdPoint32 top_right;
444 		quint16 grid_enabled;
445 		qint16  grid_color;
446 		qint16  overlap_x;
447 		qint16  overlap_y;
448 		PascalDouble scale;
449 		quint16 intensity;
450 		quint16 line_width;
451 		quint16 RESERVED_MEMBER[4];
452 	};
453 
454 	struct ExportSetupV8
455 	{
456 		OcdPoint32 bottom_left;
457 		OcdPoint32 top_right;
458 	};
459 
460 	struct ZoomRectV8
461 	{
462 		PascalDouble zoom;
463 		OcdPoint32 center;
464 	};
465 
466 	struct SetupV8
467 	{
468 		OcdPoint32 center;
469 		PascalDouble grid_dist;
470 		quint16 work_mode;
471 		quint16 line_mode;
472 		quint16 edit_mode;
473 		qint16  selected_symbol;
474 		PascalDouble map_scale;
475 		PascalDouble real_offset_x;
476 		PascalDouble real_offset_y;
477 		PascalDouble real_angle;
478 		PascalDouble real_grid;
479 		PascalDouble gps_angle;
480 		GpsPointV8 gps_adjustment[12];
481 		quint32 num_gps_adjustments;
482 		PascalDouble RESERVED_MEMBER[2];
483 		OcdPoint32 RESERVED_MEMBER;
484 		char    RESERVED_MEMBER[256];
485 		quint16 RESERVED_MEMBER[2];
486 		PascalDouble RESERVED_MEMBER;
487 		OcdPoint32 RESERVED_MEMBER;
488 		PascalDouble RESERVED_MEMBER;
489 		PrintSetupV8 print_setup;
490 		ExportSetupV8 export_setup;
491 		PascalDouble zoom;
492 		ZoomRectV8 zoom_history[8];
493 		quint32 zoom_history_size;
494 		// V6 header ends here, but Mapper doesn't use the following fields.
495 		quint16 real_coords_IGNORED;
496 		char    filename_IGNORED[256];
497 		quint16 hatch_areas_IGNORED;
498 		quint16 dim_templates_IGNORED;
499 		quint16 hide_templates_IGNORED;
500 		quint16 template_mode_IGNORED;
501 		qint16  template_color_IGNORED;
502 	};
503 
504 #pragma pack(pop)
505 
506 	/** OCD file format version 8 trait. */
507 	struct FormatV8
508 	{
509 		constexpr static quint16 version = 8;
510 		using FileHeader      = FileHeaderV8;
511 		using BaseSymbol      = BaseSymbolV8;
512 		using PointSymbol     = PointSymbolV8;
513 		using LineSymbol      = LineSymbolV8;
514 		using AreaSymbol      = AreaSymbolV8;
515 		using TextSymbol      = TextSymbolV8;
516 		using LineTextSymbol  = LineTextSymbolV8;
517 		using RectangleSymbol = RectangleSymbolV8;
518 		using Object          = ObjectV8;
519 		using Encoding        = Custom8BitEncoding;
520 	};
521 }
522 
523 
524 OCD_EXPLICIT_INSTANTIATION(extern template, Ocd::FormatV8)
525 
526 
527 #endif // OPENORIENTEERING_OCD_TYPES_V8_H
528