kmadej_fast_excel_fork 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.travis.yml +28 -0
  4. data/CHANGELOG.md +13 -0
  5. data/Gemfile +17 -0
  6. data/Gemfile.lock +70 -0
  7. data/Makefile +14 -0
  8. data/README.md +95 -0
  9. data/Rakefile +24 -0
  10. data/appveyor.yml +25 -0
  11. data/benchmarks/1k_rows.rb +59 -0
  12. data/benchmarks/20k_rows.rb +26 -0
  13. data/benchmarks/init.rb +59 -0
  14. data/benchmarks/memory.rb +49 -0
  15. data/examples/example.rb +42 -0
  16. data/examples/example_align.rb +23 -0
  17. data/examples/example_chart.rb +21 -0
  18. data/examples/example_colors.rb +37 -0
  19. data/examples/example_formula.rb +18 -0
  20. data/examples/example_image.rb +13 -0
  21. data/examples/example_styles.rb +27 -0
  22. data/examples/logo.png +0 -0
  23. data/extconf.rb +0 -0
  24. data/fast_excel.gemspec +20 -0
  25. data/lib/fast_excel.rb +600 -0
  26. data/lib/fast_excel/binding.rb +2819 -0
  27. data/lib/fast_excel/binding/chart.rb +2666 -0
  28. data/lib/fast_excel/binding/format.rb +1177 -0
  29. data/lib/fast_excel/binding/workbook.rb +338 -0
  30. data/lib/fast_excel/binding/worksheet.rb +1555 -0
  31. data/libxlsxwriter/.gitignore +49 -0
  32. data/libxlsxwriter/.indent.pro +125 -0
  33. data/libxlsxwriter/.travis.yml +25 -0
  34. data/libxlsxwriter/CONTRIBUTING.md +226 -0
  35. data/libxlsxwriter/Changes.txt +557 -0
  36. data/libxlsxwriter/LICENSE.txt +89 -0
  37. data/libxlsxwriter/Makefile +156 -0
  38. data/libxlsxwriter/Readme.md +78 -0
  39. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +30 -0
  40. data/libxlsxwriter/cocoapods/libxlsxwriter.modulemap +7 -0
  41. data/libxlsxwriter/include/xlsxwriter.h +23 -0
  42. data/libxlsxwriter/include/xlsxwriter/app.h +79 -0
  43. data/libxlsxwriter/include/xlsxwriter/chart.h +3476 -0
  44. data/libxlsxwriter/include/xlsxwriter/common.h +372 -0
  45. data/libxlsxwriter/include/xlsxwriter/content_types.h +74 -0
  46. data/libxlsxwriter/include/xlsxwriter/core.h +51 -0
  47. data/libxlsxwriter/include/xlsxwriter/custom.h +52 -0
  48. data/libxlsxwriter/include/xlsxwriter/drawing.h +111 -0
  49. data/libxlsxwriter/include/xlsxwriter/format.h +1214 -0
  50. data/libxlsxwriter/include/xlsxwriter/hash_table.h +76 -0
  51. data/libxlsxwriter/include/xlsxwriter/packager.h +80 -0
  52. data/libxlsxwriter/include/xlsxwriter/relationships.h +77 -0
  53. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +83 -0
  54. data/libxlsxwriter/include/xlsxwriter/styles.h +77 -0
  55. data/libxlsxwriter/include/xlsxwriter/theme.h +47 -0
  56. data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +214 -0
  57. data/libxlsxwriter/include/xlsxwriter/third_party/queue.h +694 -0
  58. data/libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h +53 -0
  59. data/libxlsxwriter/include/xlsxwriter/third_party/tree.h +801 -0
  60. data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +375 -0
  61. data/libxlsxwriter/include/xlsxwriter/utility.h +166 -0
  62. data/libxlsxwriter/include/xlsxwriter/workbook.h +757 -0
  63. data/libxlsxwriter/include/xlsxwriter/worksheet.h +2641 -0
  64. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +178 -0
  65. data/libxlsxwriter/lib/.gitignore +0 -0
  66. data/libxlsxwriter/libxlsxwriter.podspec +47 -0
  67. data/libxlsxwriter/src/Makefile +130 -0
  68. data/libxlsxwriter/src/app.c +443 -0
  69. data/libxlsxwriter/src/chart.c +6346 -0
  70. data/libxlsxwriter/src/content_types.c +345 -0
  71. data/libxlsxwriter/src/core.c +293 -0
  72. data/libxlsxwriter/src/custom.c +224 -0
  73. data/libxlsxwriter/src/drawing.c +746 -0
  74. data/libxlsxwriter/src/format.c +729 -0
  75. data/libxlsxwriter/src/hash_table.c +223 -0
  76. data/libxlsxwriter/src/packager.c +948 -0
  77. data/libxlsxwriter/src/relationships.c +245 -0
  78. data/libxlsxwriter/src/shared_strings.c +266 -0
  79. data/libxlsxwriter/src/styles.c +1088 -0
  80. data/libxlsxwriter/src/theme.c +348 -0
  81. data/libxlsxwriter/src/utility.c +515 -0
  82. data/libxlsxwriter/src/workbook.c +1930 -0
  83. data/libxlsxwriter/src/worksheet.c +5022 -0
  84. data/libxlsxwriter/src/xmlwriter.c +355 -0
  85. data/libxlsxwriter/third_party/minizip/Makefile +44 -0
  86. data/libxlsxwriter/third_party/minizip/Makefile.am +45 -0
  87. data/libxlsxwriter/third_party/minizip/Makefile.orig +25 -0
  88. data/libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt +6 -0
  89. data/libxlsxwriter/third_party/minizip/MiniZip64_info.txt +74 -0
  90. data/libxlsxwriter/third_party/minizip/README.txt +5 -0
  91. data/libxlsxwriter/third_party/minizip/configure.ac +32 -0
  92. data/libxlsxwriter/third_party/minizip/crypt.h +131 -0
  93. data/libxlsxwriter/third_party/minizip/ioapi.c +247 -0
  94. data/libxlsxwriter/third_party/minizip/ioapi.h +208 -0
  95. data/libxlsxwriter/third_party/minizip/iowin32.c +456 -0
  96. data/libxlsxwriter/third_party/minizip/iowin32.h +28 -0
  97. data/libxlsxwriter/third_party/minizip/make_vms.com +25 -0
  98. data/libxlsxwriter/third_party/minizip/miniunz.c +660 -0
  99. data/libxlsxwriter/third_party/minizip/miniunzip.1 +63 -0
  100. data/libxlsxwriter/third_party/minizip/minizip.1 +46 -0
  101. data/libxlsxwriter/third_party/minizip/minizip.c +520 -0
  102. data/libxlsxwriter/third_party/minizip/minizip.pc.in +12 -0
  103. data/libxlsxwriter/third_party/minizip/mztools.c +291 -0
  104. data/libxlsxwriter/third_party/minizip/mztools.h +37 -0
  105. data/libxlsxwriter/third_party/minizip/unzip.c +2125 -0
  106. data/libxlsxwriter/third_party/minizip/unzip.h +437 -0
  107. data/libxlsxwriter/third_party/minizip/zip.c +2007 -0
  108. data/libxlsxwriter/third_party/minizip/zip.h +367 -0
  109. data/libxlsxwriter/third_party/tmpfileplus/Makefile +42 -0
  110. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.c +342 -0
  111. data/libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h +53 -0
  112. data/libxlsxwriter/version.txt +1 -0
  113. data/test/date_test.rb +22 -0
  114. data/test/default_format_test.rb +19 -0
  115. data/test/format_test.rb +171 -0
  116. data/test/test_helper.rb +52 -0
  117. data/test/tmpfile_test.rb +23 -0
  118. data/test/worksheet_test.rb +86 -0
  119. metadata +182 -0
@@ -0,0 +1,1088 @@
1
+ /*****************************************************************************
2
+ * styles - A library for creating Excel XLSX styles files.
3
+ *
4
+ * Used in conjunction with the libxlsxwriter library.
5
+ *
6
+ * Copyright 2014-2017, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
7
+ *
8
+ */
9
+
10
+ #include "xlsxwriter/xmlwriter.h"
11
+ #include "xlsxwriter/styles.h"
12
+ #include "xlsxwriter/utility.h"
13
+
14
+ /*
15
+ * Forward declarations.
16
+ */
17
+
18
+ /*****************************************************************************
19
+ *
20
+ * Private functions.
21
+ *
22
+ ****************************************************************************/
23
+
24
+ /*
25
+ * Create a new styles object.
26
+ */
27
+ lxw_styles *
28
+ lxw_styles_new()
29
+ {
30
+ lxw_styles *styles = calloc(1, sizeof(lxw_styles));
31
+ GOTO_LABEL_ON_MEM_ERROR(styles, mem_error);
32
+
33
+ styles->xf_formats = calloc(1, sizeof(struct lxw_formats));
34
+ GOTO_LABEL_ON_MEM_ERROR(styles->xf_formats, mem_error);
35
+
36
+ STAILQ_INIT(styles->xf_formats);
37
+
38
+ return styles;
39
+
40
+ mem_error:
41
+ lxw_styles_free(styles);
42
+ return NULL;
43
+ }
44
+
45
+ /*
46
+ * Free a styles object.
47
+ */
48
+ void
49
+ lxw_styles_free(lxw_styles *styles)
50
+ {
51
+ lxw_format *format;
52
+
53
+ if (!styles)
54
+ return;
55
+
56
+ /* Free the formats in the styles. */
57
+ if (styles->xf_formats) {
58
+ while (!STAILQ_EMPTY(styles->xf_formats)) {
59
+ format = STAILQ_FIRST(styles->xf_formats);
60
+ STAILQ_REMOVE_HEAD(styles->xf_formats, list_pointers);
61
+ free(format);
62
+ }
63
+ free(styles->xf_formats);
64
+ }
65
+
66
+ free(styles);
67
+ }
68
+
69
+ /*****************************************************************************
70
+ *
71
+ * XML functions.
72
+ *
73
+ ****************************************************************************/
74
+
75
+ /*
76
+ * Write the XML declaration.
77
+ */
78
+ STATIC void
79
+ _styles_xml_declaration(lxw_styles *self)
80
+ {
81
+ lxw_xml_declaration(self->file);
82
+ }
83
+
84
+ /*
85
+ * Write the <styleSheet> element.
86
+ */
87
+ STATIC void
88
+ _write_style_sheet(lxw_styles *self)
89
+ {
90
+ struct xml_attribute_list attributes;
91
+ struct xml_attribute *attribute;
92
+ LXW_INIT_ATTRIBUTES();
93
+ LXW_PUSH_ATTRIBUTES_STR("xmlns",
94
+ "http://schemas.openxmlformats.org/spreadsheetml/2006/main");
95
+
96
+ lxw_xml_start_tag(self->file, "styleSheet", &attributes);
97
+
98
+ LXW_FREE_ATTRIBUTES();
99
+ }
100
+
101
+ /*
102
+ * Write the <numFmt> element.
103
+ */
104
+ STATIC void
105
+ _write_num_fmt(lxw_styles *self, uint16_t num_fmt_id, char *format_code)
106
+ {
107
+ struct xml_attribute_list attributes;
108
+ struct xml_attribute *attribute;
109
+
110
+ LXW_INIT_ATTRIBUTES();
111
+ LXW_PUSH_ATTRIBUTES_INT("numFmtId", num_fmt_id);
112
+ LXW_PUSH_ATTRIBUTES_STR("formatCode", format_code);
113
+
114
+ lxw_xml_empty_tag(self->file, "numFmt", &attributes);
115
+
116
+ LXW_FREE_ATTRIBUTES();
117
+ }
118
+
119
+ /*
120
+ * Write the <numFmts> element.
121
+ */
122
+ STATIC void
123
+ _write_num_fmts(lxw_styles *self)
124
+ {
125
+ struct xml_attribute_list attributes;
126
+ struct xml_attribute *attribute;
127
+ lxw_format *format;
128
+
129
+ if (!self->num_format_count)
130
+ return;
131
+
132
+ LXW_INIT_ATTRIBUTES();
133
+ LXW_PUSH_ATTRIBUTES_INT("count", self->num_format_count);
134
+
135
+ lxw_xml_start_tag(self->file, "numFmts", &attributes);
136
+
137
+ /* Write the numFmts elements. */
138
+ STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
139
+
140
+ /* Ignore built-in number formats, i.e., < 164. */
141
+ if (format->num_format_index < 164)
142
+ continue;
143
+
144
+ _write_num_fmt(self, format->num_format_index, format->num_format);
145
+ }
146
+
147
+ lxw_xml_end_tag(self->file, "numFmts");
148
+
149
+ LXW_FREE_ATTRIBUTES();
150
+ }
151
+
152
+ /*
153
+ * Write the <sz> element.
154
+ */
155
+ STATIC void
156
+ _write_font_size(lxw_styles *self, uint16_t font_size)
157
+ {
158
+ struct xml_attribute_list attributes;
159
+ struct xml_attribute *attribute;
160
+
161
+ LXW_INIT_ATTRIBUTES();
162
+ LXW_PUSH_ATTRIBUTES_INT("val", font_size);
163
+
164
+ lxw_xml_empty_tag(self->file, "sz", &attributes);
165
+
166
+ LXW_FREE_ATTRIBUTES();
167
+ }
168
+
169
+ /*
170
+ * Write the <color> element for themes.
171
+ */
172
+ STATIC void
173
+ _write_font_color_theme(lxw_styles *self, uint8_t theme)
174
+ {
175
+ struct xml_attribute_list attributes;
176
+ struct xml_attribute *attribute;
177
+
178
+ LXW_INIT_ATTRIBUTES();
179
+ LXW_PUSH_ATTRIBUTES_INT("theme", theme);
180
+
181
+ lxw_xml_empty_tag(self->file, "color", &attributes);
182
+
183
+ LXW_FREE_ATTRIBUTES();
184
+ }
185
+
186
+ /*
187
+ * Write the <color> element for RGB colors.
188
+ */
189
+ STATIC void
190
+ _write_font_color_rgb(lxw_styles *self, int32_t rgb)
191
+ {
192
+ struct xml_attribute_list attributes;
193
+ struct xml_attribute *attribute;
194
+ char rgb_str[LXW_ATTR_32];
195
+
196
+ lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", rgb & LXW_COLOR_MASK);
197
+
198
+ LXW_INIT_ATTRIBUTES();
199
+ LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
200
+
201
+ lxw_xml_empty_tag(self->file, "color", &attributes);
202
+
203
+ LXW_FREE_ATTRIBUTES();
204
+ }
205
+
206
+ /*
207
+ * Write the <name> element.
208
+ */
209
+ STATIC void
210
+ _write_font_name(lxw_styles *self, const char *font_name)
211
+ {
212
+ struct xml_attribute_list attributes;
213
+ struct xml_attribute *attribute;
214
+
215
+ LXW_INIT_ATTRIBUTES();
216
+
217
+ if (*font_name)
218
+ LXW_PUSH_ATTRIBUTES_STR("val", font_name);
219
+ else
220
+ LXW_PUSH_ATTRIBUTES_STR("val", LXW_DEFAULT_FONT_NAME);
221
+
222
+ lxw_xml_empty_tag(self->file, "name", &attributes);
223
+
224
+ LXW_FREE_ATTRIBUTES();
225
+ }
226
+
227
+ /*
228
+ * Write the <family> element.
229
+ */
230
+ STATIC void
231
+ _write_font_family(lxw_styles *self, uint8_t font_family)
232
+ {
233
+ struct xml_attribute_list attributes;
234
+ struct xml_attribute *attribute;
235
+
236
+ LXW_INIT_ATTRIBUTES();
237
+ LXW_PUSH_ATTRIBUTES_INT("val", font_family);
238
+
239
+ lxw_xml_empty_tag(self->file, "family", &attributes);
240
+
241
+ LXW_FREE_ATTRIBUTES();
242
+ }
243
+
244
+ /*
245
+ * Write the <scheme> element.
246
+ */
247
+ STATIC void
248
+ _write_font_scheme(lxw_styles *self, const char *font_scheme)
249
+ {
250
+ struct xml_attribute_list attributes;
251
+ struct xml_attribute *attribute;
252
+
253
+ LXW_INIT_ATTRIBUTES();
254
+
255
+ if (*font_scheme)
256
+ LXW_PUSH_ATTRIBUTES_STR("val", font_scheme);
257
+ else
258
+ LXW_PUSH_ATTRIBUTES_STR("val", "minor");
259
+
260
+ lxw_xml_empty_tag(self->file, "scheme", &attributes);
261
+
262
+ LXW_FREE_ATTRIBUTES();
263
+ }
264
+
265
+ /*
266
+ * Write the underline font element.
267
+ */
268
+ STATIC void
269
+ _write_font_underline(lxw_styles *self, uint8_t underline)
270
+ {
271
+ struct xml_attribute_list attributes;
272
+ struct xml_attribute *attribute;
273
+
274
+ LXW_INIT_ATTRIBUTES();
275
+
276
+ /* Handle the underline variants. */
277
+ if (underline == LXW_UNDERLINE_DOUBLE)
278
+ LXW_PUSH_ATTRIBUTES_STR("val", "double");
279
+ else if (underline == LXW_UNDERLINE_SINGLE_ACCOUNTING)
280
+ LXW_PUSH_ATTRIBUTES_STR("val", "singleAccounting");
281
+ else if (underline == LXW_UNDERLINE_DOUBLE_ACCOUNTING)
282
+ LXW_PUSH_ATTRIBUTES_STR("val", "doubleAccounting");
283
+ /* Default to single underline. */
284
+
285
+ lxw_xml_empty_tag(self->file, "u", &attributes);
286
+
287
+ LXW_FREE_ATTRIBUTES();
288
+
289
+ }
290
+
291
+ /*
292
+ * Write the <vertAlign> font sub-element.
293
+ */
294
+ STATIC void
295
+ _write_vert_align(lxw_styles *self, const char *align)
296
+ {
297
+ struct xml_attribute_list attributes;
298
+ struct xml_attribute *attribute;
299
+
300
+ LXW_INIT_ATTRIBUTES();
301
+ LXW_PUSH_ATTRIBUTES_STR("val", align);
302
+
303
+ lxw_xml_empty_tag(self->file, "vertAlign", &attributes);
304
+
305
+ LXW_FREE_ATTRIBUTES();
306
+ }
307
+
308
+ /*
309
+ * Write the <font> element.
310
+ */
311
+ STATIC void
312
+ _write_font(lxw_styles *self, lxw_format *format)
313
+ {
314
+ lxw_xml_start_tag(self->file, "font", NULL);
315
+
316
+ if (format->bold)
317
+ lxw_xml_empty_tag(self->file, "b", NULL);
318
+
319
+ if (format->italic)
320
+ lxw_xml_empty_tag(self->file, "i", NULL);
321
+
322
+ if (format->font_strikeout)
323
+ lxw_xml_empty_tag(self->file, "strike", NULL);
324
+
325
+ if (format->font_outline)
326
+ lxw_xml_empty_tag(self->file, "outline", NULL);
327
+
328
+ if (format->font_shadow)
329
+ lxw_xml_empty_tag(self->file, "shadow", NULL);
330
+
331
+ if (format->underline)
332
+ _write_font_underline(self, format->underline);
333
+
334
+ if (format->font_script == LXW_FONT_SUPERSCRIPT)
335
+ _write_vert_align(self, "superscript");
336
+
337
+ if (format->font_script == LXW_FONT_SUBSCRIPT)
338
+ _write_vert_align(self, "subscript");
339
+
340
+ if (format->font_size)
341
+ _write_font_size(self, format->font_size);
342
+
343
+ if (format->theme)
344
+ _write_font_color_theme(self, format->theme);
345
+ else if (format->font_color != LXW_COLOR_UNSET)
346
+ _write_font_color_rgb(self, format->font_color);
347
+ else
348
+ _write_font_color_theme(self, LXW_DEFAULT_FONT_THEME);
349
+
350
+ _write_font_name(self, format->font_name);
351
+ _write_font_family(self, format->font_family);
352
+
353
+ /* Only write the scheme element for the default font type if it
354
+ * is a hyperlink. */
355
+ if ((!*format->font_name
356
+ || strcmp(LXW_DEFAULT_FONT_NAME, format->font_name) == 0)
357
+ && !format->hyperlink) {
358
+ _write_font_scheme(self, format->font_scheme);
359
+ }
360
+
361
+ lxw_xml_end_tag(self->file, "font");
362
+ }
363
+
364
+ /*
365
+ * Write the <fonts> element.
366
+ */
367
+ STATIC void
368
+ _write_fonts(lxw_styles *self)
369
+ {
370
+ struct xml_attribute_list attributes;
371
+ struct xml_attribute *attribute;
372
+ lxw_format *format;
373
+
374
+ LXW_INIT_ATTRIBUTES();
375
+ LXW_PUSH_ATTRIBUTES_INT("count", self->font_count);
376
+
377
+ lxw_xml_start_tag(self->file, "fonts", &attributes);
378
+
379
+ STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
380
+ if (format->has_font)
381
+ _write_font(self, format);
382
+ }
383
+
384
+ lxw_xml_end_tag(self->file, "fonts");
385
+
386
+ LXW_FREE_ATTRIBUTES();
387
+ }
388
+
389
+ /*
390
+ * Write the default <fill> element.
391
+ */
392
+ STATIC void
393
+ _write_default_fill(lxw_styles *self, const char *pattern)
394
+ {
395
+ struct xml_attribute_list attributes;
396
+ struct xml_attribute *attribute;
397
+
398
+ LXW_INIT_ATTRIBUTES();
399
+ LXW_PUSH_ATTRIBUTES_STR("patternType", pattern);
400
+
401
+ lxw_xml_start_tag(self->file, "fill", NULL);
402
+ lxw_xml_empty_tag(self->file, "patternFill", &attributes);
403
+ lxw_xml_end_tag(self->file, "fill");
404
+
405
+ LXW_FREE_ATTRIBUTES();
406
+ }
407
+
408
+ /*
409
+ * Write the <fgColor> element.
410
+ */
411
+ STATIC void
412
+ _write_fg_color(lxw_styles *self, lxw_color_t color)
413
+ {
414
+ struct xml_attribute_list attributes;
415
+ struct xml_attribute *attribute;
416
+ char rgb_str[LXW_ATTR_32];
417
+
418
+ LXW_INIT_ATTRIBUTES();
419
+
420
+ lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", color & LXW_COLOR_MASK);
421
+ LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
422
+
423
+ lxw_xml_empty_tag(self->file, "fgColor", &attributes);
424
+
425
+ LXW_FREE_ATTRIBUTES();
426
+ }
427
+
428
+ /*
429
+ * Write the <bgColor> element.
430
+ */
431
+ STATIC void
432
+ _write_bg_color(lxw_styles *self, lxw_color_t color)
433
+ {
434
+ struct xml_attribute_list attributes;
435
+ struct xml_attribute *attribute;
436
+ char rgb_str[LXW_ATTR_32];
437
+
438
+ LXW_INIT_ATTRIBUTES();
439
+
440
+ if (color == LXW_COLOR_UNSET) {
441
+ LXW_PUSH_ATTRIBUTES_STR("indexed", "64");
442
+ }
443
+ else {
444
+ lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", color & LXW_COLOR_MASK);
445
+ LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
446
+ }
447
+
448
+ lxw_xml_empty_tag(self->file, "bgColor", &attributes);
449
+
450
+ LXW_FREE_ATTRIBUTES();
451
+ }
452
+
453
+ /*
454
+ * Write the <fill> element.
455
+ */
456
+ STATIC void
457
+ _write_fill(lxw_styles *self, lxw_format *format)
458
+ {
459
+ struct xml_attribute_list attributes;
460
+ struct xml_attribute *attribute;
461
+
462
+ uint8_t pattern = format->pattern;
463
+ lxw_color_t bg_color = format->bg_color;
464
+ lxw_color_t fg_color = format->fg_color;
465
+
466
+ char *patterns[] = {
467
+ "none",
468
+ "solid",
469
+ "mediumGray",
470
+ "darkGray",
471
+ "lightGray",
472
+ "darkHorizontal",
473
+ "darkVertical",
474
+ "darkDown",
475
+ "darkUp",
476
+ "darkGrid",
477
+ "darkTrellis",
478
+ "lightHorizontal",
479
+ "lightVertical",
480
+ "lightDown",
481
+ "lightUp",
482
+ "lightGrid",
483
+ "lightTrellis",
484
+ "gray125",
485
+ "gray0625",
486
+ };
487
+
488
+ LXW_INIT_ATTRIBUTES();
489
+
490
+ lxw_xml_start_tag(self->file, "fill", NULL);
491
+
492
+ if (pattern)
493
+ LXW_PUSH_ATTRIBUTES_STR("patternType", patterns[pattern]);
494
+
495
+ lxw_xml_start_tag(self->file, "patternFill", &attributes);
496
+
497
+ if (fg_color != LXW_COLOR_UNSET)
498
+ _write_fg_color(self, fg_color);
499
+
500
+ _write_bg_color(self, bg_color);
501
+
502
+ lxw_xml_end_tag(self->file, "patternFill");
503
+ lxw_xml_end_tag(self->file, "fill");
504
+
505
+ LXW_FREE_ATTRIBUTES();
506
+ }
507
+
508
+ /*
509
+ * Write the <fills> element.
510
+ */
511
+ STATIC void
512
+ _write_fills(lxw_styles *self)
513
+ {
514
+ struct xml_attribute_list attributes;
515
+ struct xml_attribute *attribute;
516
+ lxw_format *format;
517
+
518
+ LXW_INIT_ATTRIBUTES();
519
+ LXW_PUSH_ATTRIBUTES_INT("count", self->fill_count);
520
+
521
+ lxw_xml_start_tag(self->file, "fills", &attributes);
522
+
523
+ /* Write the default fills. */
524
+ _write_default_fill(self, "none");
525
+ _write_default_fill(self, "gray125");
526
+
527
+ STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
528
+ if (format->has_fill)
529
+ _write_fill(self, format);
530
+ }
531
+
532
+ lxw_xml_end_tag(self->file, "fills");
533
+
534
+ LXW_FREE_ATTRIBUTES();
535
+ }
536
+
537
+ /*
538
+ * Write the border <color> element.
539
+ */
540
+ STATIC void
541
+ _write_border_color(lxw_styles *self, lxw_color_t color)
542
+ {
543
+ struct xml_attribute_list attributes;
544
+ struct xml_attribute *attribute;
545
+ char rgb_str[LXW_ATTR_32];
546
+
547
+ LXW_INIT_ATTRIBUTES();
548
+
549
+ if (color != LXW_COLOR_UNSET) {
550
+ lxw_snprintf(rgb_str, LXW_ATTR_32, "FF%06X", color & LXW_COLOR_MASK);
551
+ LXW_PUSH_ATTRIBUTES_STR("rgb", rgb_str);
552
+ }
553
+ else {
554
+ LXW_PUSH_ATTRIBUTES_STR("auto", "1");
555
+ }
556
+
557
+ lxw_xml_empty_tag(self->file, "color", &attributes);
558
+
559
+ LXW_FREE_ATTRIBUTES();
560
+ }
561
+
562
+ /*
563
+ * Write the <border> sub elements such as <right>, <top>, etc.
564
+ */
565
+ STATIC void
566
+ _write_sub_border(lxw_styles *self, const char *type, uint8_t style,
567
+ lxw_color_t color)
568
+ {
569
+ struct xml_attribute_list attributes;
570
+ struct xml_attribute *attribute;
571
+
572
+ char *border_styles[] = {
573
+ "none",
574
+ "thin",
575
+ "medium",
576
+ "dashed",
577
+ "dotted",
578
+ "thick",
579
+ "double",
580
+ "hair",
581
+ "mediumDashed",
582
+ "dashDot",
583
+ "mediumDashDot",
584
+ "dashDotDot",
585
+ "mediumDashDotDot",
586
+ "slantDashDot",
587
+ };
588
+
589
+ if (!style) {
590
+ lxw_xml_empty_tag(self->file, type, NULL);
591
+ return;
592
+ }
593
+
594
+ LXW_INIT_ATTRIBUTES();
595
+ LXW_PUSH_ATTRIBUTES_STR("style", border_styles[style]);
596
+
597
+ lxw_xml_start_tag(self->file, type, &attributes);
598
+
599
+ _write_border_color(self, color);
600
+
601
+ lxw_xml_end_tag(self->file, type);
602
+
603
+ LXW_FREE_ATTRIBUTES();
604
+ }
605
+
606
+ /*
607
+ * Write the <border> element.
608
+ */
609
+ STATIC void
610
+ _write_border(lxw_styles *self, lxw_format *format)
611
+ {
612
+ struct xml_attribute_list attributes;
613
+ struct xml_attribute *attribute;
614
+
615
+ LXW_INIT_ATTRIBUTES();
616
+
617
+ /* Add attributes for diagonal borders. */
618
+ if (format->diag_type == LXW_DIAGONAL_BORDER_UP) {
619
+ LXW_PUSH_ATTRIBUTES_STR("diagonalUp", "1");
620
+ }
621
+ else if (format->diag_type == LXW_DIAGONAL_BORDER_DOWN) {
622
+ LXW_PUSH_ATTRIBUTES_STR("diagonalDown", "1");
623
+ }
624
+ else if (format->diag_type == LXW_DIAGONAL_BORDER_UP_DOWN) {
625
+ LXW_PUSH_ATTRIBUTES_STR("diagonalUp", "1");
626
+ LXW_PUSH_ATTRIBUTES_STR("diagonalDown", "1");
627
+ }
628
+
629
+ /* Ensure that a default diag border is set if the diag type is set. */
630
+ if (format->diag_type && !format->diag_border) {
631
+ format->diag_border = 1;
632
+ }
633
+
634
+ /* Write the start border tag. */
635
+ lxw_xml_start_tag(self->file, "border", &attributes);
636
+
637
+ /* Write the <border> sub elements. */
638
+ _write_sub_border(self, "left", format->left, format->left_color);
639
+ _write_sub_border(self, "right", format->right, format->right_color);
640
+ _write_sub_border(self, "top", format->top, format->top_color);
641
+ _write_sub_border(self, "bottom", format->bottom, format->bottom_color);
642
+ _write_sub_border(self,
643
+ "diagonal", format->diag_border, format->diag_color);
644
+
645
+ lxw_xml_end_tag(self->file, "border");
646
+
647
+ LXW_FREE_ATTRIBUTES();
648
+ }
649
+
650
+ /*
651
+ * Write the <borders> element.
652
+ */
653
+ STATIC void
654
+ _write_borders(lxw_styles *self)
655
+ {
656
+ struct xml_attribute_list attributes;
657
+ struct xml_attribute *attribute;
658
+ lxw_format *format;
659
+
660
+ LXW_INIT_ATTRIBUTES();
661
+ LXW_PUSH_ATTRIBUTES_INT("count", self->border_count);
662
+
663
+ lxw_xml_start_tag(self->file, "borders", &attributes);
664
+
665
+ STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
666
+ if (format->has_border)
667
+ _write_border(self, format);
668
+ }
669
+
670
+ lxw_xml_end_tag(self->file, "borders");
671
+
672
+ LXW_FREE_ATTRIBUTES();
673
+ }
674
+
675
+ /*
676
+ * Write the <xf> element for styles.
677
+ */
678
+ STATIC void
679
+ _write_style_xf(lxw_styles *self)
680
+ {
681
+ struct xml_attribute_list attributes;
682
+ struct xml_attribute *attribute;
683
+
684
+ LXW_INIT_ATTRIBUTES();
685
+ LXW_PUSH_ATTRIBUTES_STR("numFmtId", "0");
686
+ LXW_PUSH_ATTRIBUTES_STR("fontId", "0");
687
+ LXW_PUSH_ATTRIBUTES_STR("fillId", "0");
688
+ LXW_PUSH_ATTRIBUTES_STR("borderId", "0");
689
+
690
+ lxw_xml_empty_tag(self->file, "xf", &attributes);
691
+
692
+ LXW_FREE_ATTRIBUTES();
693
+ }
694
+
695
+ /*
696
+ * Write the <cellStyleXfs> element.
697
+ */
698
+ STATIC void
699
+ _write_cell_style_xfs(lxw_styles *self)
700
+ {
701
+ struct xml_attribute_list attributes;
702
+ struct xml_attribute *attribute;
703
+
704
+ LXW_INIT_ATTRIBUTES();
705
+ LXW_PUSH_ATTRIBUTES_STR("count", "1");
706
+
707
+ lxw_xml_start_tag(self->file, "cellStyleXfs", &attributes);
708
+ _write_style_xf(self);
709
+ lxw_xml_end_tag(self->file, "cellStyleXfs");
710
+
711
+ LXW_FREE_ATTRIBUTES();
712
+ }
713
+
714
+ /*
715
+ * Check if a format struct has alignment properties set and the
716
+ * "applyAlignment" attribute should be set.
717
+ */
718
+ STATIC uint8_t
719
+ _apply_alignment(lxw_format *format)
720
+ {
721
+ return format->text_h_align != LXW_ALIGN_NONE
722
+ || format->text_v_align != LXW_ALIGN_NONE
723
+ || format->indent != 0
724
+ || format->rotation != 0
725
+ || format->text_wrap != 0
726
+ || format->shrink != 0 || format->reading_order != 0;
727
+ }
728
+
729
+ /*
730
+ * Check if a format struct has alignment properties set apart from the
731
+ * LXW_ALIGN_VERTICAL_BOTTOM which Excel treats as a default.
732
+ */
733
+ STATIC uint8_t
734
+ _has_alignment(lxw_format *format)
735
+ {
736
+ return format->text_h_align != LXW_ALIGN_NONE
737
+ || !(format->text_v_align == LXW_ALIGN_NONE ||
738
+ format->text_v_align == LXW_ALIGN_VERTICAL_BOTTOM)
739
+ || format->indent != 0
740
+ || format->rotation != 0
741
+ || format->text_wrap != 0
742
+ || format->shrink != 0 || format->reading_order != 0;
743
+ }
744
+
745
+ /*
746
+ * Write the <alignment> element.
747
+ */
748
+ STATIC void
749
+ _write_alignment(lxw_styles *self, lxw_format *format)
750
+ {
751
+ struct xml_attribute_list attributes;
752
+ struct xml_attribute *attribute;
753
+ int16_t rotation = format->rotation;
754
+
755
+ LXW_INIT_ATTRIBUTES();
756
+
757
+ /* Indent is only allowed for horizontal left, right and distributed. */
758
+ /* If it is defined for any other alignment or no alignment has been */
759
+ /* set then default to left alignment. */
760
+ if (format->indent
761
+ && format->text_h_align != LXW_ALIGN_LEFT
762
+ && format->text_h_align != LXW_ALIGN_RIGHT
763
+ && format->text_h_align != LXW_ALIGN_DISTRIBUTED) {
764
+ format->text_h_align = LXW_ALIGN_LEFT;
765
+ }
766
+
767
+ /* Check for properties that are mutually exclusive. */
768
+ if (format->text_wrap)
769
+ format->shrink = 0;
770
+
771
+ if (format->text_h_align == LXW_ALIGN_FILL)
772
+ format->shrink = 0;
773
+
774
+ if (format->text_h_align == LXW_ALIGN_JUSTIFY)
775
+ format->shrink = 0;
776
+
777
+ if (format->text_h_align == LXW_ALIGN_DISTRIBUTED)
778
+ format->shrink = 0;
779
+
780
+ if (format->text_h_align != LXW_ALIGN_DISTRIBUTED)
781
+ format->just_distrib = 0;
782
+
783
+ if (format->indent)
784
+ format->just_distrib = 0;
785
+
786
+ if (format->text_h_align == LXW_ALIGN_LEFT)
787
+ LXW_PUSH_ATTRIBUTES_STR("horizontal", "left");
788
+
789
+ if (format->text_h_align == LXW_ALIGN_CENTER)
790
+ LXW_PUSH_ATTRIBUTES_STR("horizontal", "center");
791
+
792
+ if (format->text_h_align == LXW_ALIGN_RIGHT)
793
+ LXW_PUSH_ATTRIBUTES_STR("horizontal", "right");
794
+
795
+ if (format->text_h_align == LXW_ALIGN_FILL)
796
+ LXW_PUSH_ATTRIBUTES_STR("horizontal", "fill");
797
+
798
+ if (format->text_h_align == LXW_ALIGN_JUSTIFY)
799
+ LXW_PUSH_ATTRIBUTES_STR("horizontal", "justify");
800
+
801
+ if (format->text_h_align == LXW_ALIGN_CENTER_ACROSS)
802
+ LXW_PUSH_ATTRIBUTES_STR("horizontal", "centerContinuous");
803
+
804
+ if (format->text_h_align == LXW_ALIGN_DISTRIBUTED)
805
+ LXW_PUSH_ATTRIBUTES_STR("horizontal", "distributed");
806
+
807
+ if (format->just_distrib)
808
+ LXW_PUSH_ATTRIBUTES_STR("justifyLastLine", "1");
809
+
810
+ if (format->text_v_align == LXW_ALIGN_VERTICAL_TOP)
811
+ LXW_PUSH_ATTRIBUTES_STR("vertical", "top");
812
+
813
+ if (format->text_v_align == LXW_ALIGN_VERTICAL_CENTER)
814
+ LXW_PUSH_ATTRIBUTES_STR("vertical", "center");
815
+
816
+ if (format->text_v_align == LXW_ALIGN_VERTICAL_JUSTIFY)
817
+ LXW_PUSH_ATTRIBUTES_STR("vertical", "justify");
818
+
819
+ if (format->text_v_align == LXW_ALIGN_VERTICAL_DISTRIBUTED)
820
+ LXW_PUSH_ATTRIBUTES_STR("vertical", "distributed");
821
+
822
+ if (format->indent)
823
+ LXW_PUSH_ATTRIBUTES_INT("indent", format->indent);
824
+
825
+ /* Map rotation to Excel values. */
826
+ if (rotation) {
827
+ if (rotation == 270)
828
+ rotation = 255;
829
+ else if (rotation < 0)
830
+ rotation = -rotation + 90;
831
+
832
+ LXW_PUSH_ATTRIBUTES_INT("textRotation", rotation);
833
+ }
834
+
835
+ if (format->text_wrap)
836
+ LXW_PUSH_ATTRIBUTES_STR("wrapText", "1");
837
+
838
+ if (format->shrink)
839
+ LXW_PUSH_ATTRIBUTES_STR("shrinkToFit", "1");
840
+
841
+ if (format->reading_order == 1)
842
+ LXW_PUSH_ATTRIBUTES_STR("readingOrder", "1");
843
+
844
+ if (format->reading_order == 2)
845
+ LXW_PUSH_ATTRIBUTES_STR("readingOrder", "2");
846
+
847
+ if (!STAILQ_EMPTY(&attributes))
848
+ lxw_xml_empty_tag(self->file, "alignment", &attributes);
849
+
850
+ LXW_FREE_ATTRIBUTES();
851
+ }
852
+
853
+ /*
854
+ * Write the <protection> element.
855
+ */
856
+ STATIC void
857
+ _write_protection(lxw_styles *self, lxw_format *format)
858
+ {
859
+ struct xml_attribute_list attributes;
860
+ struct xml_attribute *attribute;
861
+
862
+ LXW_INIT_ATTRIBUTES();
863
+
864
+ if (!format->locked)
865
+ LXW_PUSH_ATTRIBUTES_STR("locked", "0");
866
+
867
+ if (format->hidden)
868
+ LXW_PUSH_ATTRIBUTES_STR("hidden", "1");
869
+
870
+ lxw_xml_empty_tag(self->file, "protection", &attributes);
871
+
872
+ LXW_FREE_ATTRIBUTES();
873
+ }
874
+
875
+ /*
876
+ * Write the <xf> element.
877
+ */
878
+ STATIC void
879
+ _write_xf(lxw_styles *self, lxw_format *format)
880
+ {
881
+ struct xml_attribute_list attributes;
882
+ struct xml_attribute *attribute;
883
+ uint8_t has_protection = (!format->locked) | format->hidden;
884
+ uint8_t has_alignment = _has_alignment(format);
885
+ uint8_t apply_alignment = _apply_alignment(format);
886
+
887
+ LXW_INIT_ATTRIBUTES();
888
+ LXW_PUSH_ATTRIBUTES_INT("numFmtId", format->num_format_index);
889
+ LXW_PUSH_ATTRIBUTES_INT("fontId", format->font_index);
890
+ LXW_PUSH_ATTRIBUTES_INT("fillId", format->fill_index);
891
+ LXW_PUSH_ATTRIBUTES_INT("borderId", format->border_index);
892
+ LXW_PUSH_ATTRIBUTES_STR("xfId", "0");
893
+
894
+ if (format->num_format_index > 0)
895
+ LXW_PUSH_ATTRIBUTES_STR("applyNumberFormat", "1");
896
+
897
+ /* Add applyFont attribute if XF format uses a font element. */
898
+ if (format->font_index > 0)
899
+ LXW_PUSH_ATTRIBUTES_STR("applyFont", "1");
900
+
901
+ /* Add applyFill attribute if XF format uses a fill element. */
902
+ if (format->fill_index > 0)
903
+ LXW_PUSH_ATTRIBUTES_STR("applyFill", "1");
904
+
905
+ /* Add applyBorder attribute if XF format uses a border element. */
906
+ if (format->border_index > 0)
907
+ LXW_PUSH_ATTRIBUTES_STR("applyBorder", "1");
908
+
909
+ /* We can also have applyAlignment without a sub-element. */
910
+ if (apply_alignment)
911
+ LXW_PUSH_ATTRIBUTES_STR("applyAlignment", "1");
912
+
913
+ if (has_protection)
914
+ LXW_PUSH_ATTRIBUTES_STR("applyProtection", "1");
915
+
916
+ /* Write XF with sub-elements if required. */
917
+ if (has_alignment || has_protection) {
918
+ lxw_xml_start_tag(self->file, "xf", &attributes);
919
+
920
+ if (has_alignment)
921
+ _write_alignment(self, format);
922
+
923
+ if (has_protection)
924
+ _write_protection(self, format);
925
+
926
+ lxw_xml_end_tag(self->file, "xf");
927
+ }
928
+ else {
929
+ lxw_xml_empty_tag(self->file, "xf", &attributes);
930
+ }
931
+
932
+ LXW_FREE_ATTRIBUTES();
933
+ }
934
+
935
+ /*
936
+ * Write the <cellXfs> element.
937
+ */
938
+ STATIC void
939
+ _write_cell_xfs(lxw_styles *self)
940
+ {
941
+ struct xml_attribute_list attributes;
942
+ struct xml_attribute *attribute;
943
+ lxw_format *format;
944
+
945
+ LXW_INIT_ATTRIBUTES();
946
+ LXW_PUSH_ATTRIBUTES_INT("count", self->xf_count);
947
+
948
+ lxw_xml_start_tag(self->file, "cellXfs", &attributes);
949
+
950
+ STAILQ_FOREACH(format, self->xf_formats, list_pointers) {
951
+ _write_xf(self, format);
952
+ }
953
+
954
+ lxw_xml_end_tag(self->file, "cellXfs");
955
+
956
+ LXW_FREE_ATTRIBUTES();
957
+ }
958
+
959
+ /*
960
+ * Write the <cellStyle> element.
961
+ */
962
+ STATIC void
963
+ _write_cell_style(lxw_styles *self)
964
+ {
965
+ struct xml_attribute_list attributes;
966
+ struct xml_attribute *attribute;
967
+
968
+ LXW_INIT_ATTRIBUTES();
969
+ LXW_PUSH_ATTRIBUTES_STR("name", "Normal");
970
+ LXW_PUSH_ATTRIBUTES_STR("xfId", "0");
971
+ LXW_PUSH_ATTRIBUTES_STR("builtinId", "0");
972
+
973
+ lxw_xml_empty_tag(self->file, "cellStyle", &attributes);
974
+
975
+ LXW_FREE_ATTRIBUTES();
976
+ }
977
+
978
+ /*
979
+ * Write the <cellStyles> element.
980
+ */
981
+ STATIC void
982
+ _write_cell_styles(lxw_styles *self)
983
+ {
984
+ struct xml_attribute_list attributes;
985
+ struct xml_attribute *attribute;
986
+ LXW_INIT_ATTRIBUTES();
987
+ LXW_PUSH_ATTRIBUTES_STR("count", "1");
988
+
989
+ lxw_xml_start_tag(self->file, "cellStyles", &attributes);
990
+ _write_cell_style(self);
991
+ lxw_xml_end_tag(self->file, "cellStyles");
992
+
993
+ LXW_FREE_ATTRIBUTES();
994
+ }
995
+
996
+ /*
997
+ * Write the <dxfs> element.
998
+ */
999
+ STATIC void
1000
+ _write_dxfs(lxw_styles *self)
1001
+ {
1002
+ struct xml_attribute_list attributes;
1003
+ struct xml_attribute *attribute;
1004
+
1005
+ LXW_INIT_ATTRIBUTES();
1006
+ LXW_PUSH_ATTRIBUTES_STR("count", "0");
1007
+
1008
+ lxw_xml_empty_tag(self->file, "dxfs", &attributes);
1009
+
1010
+ LXW_FREE_ATTRIBUTES();
1011
+ }
1012
+
1013
+ /*
1014
+ * Write the <tableStyles> element.
1015
+ */
1016
+ STATIC void
1017
+ _write_table_styles(lxw_styles *self)
1018
+ {
1019
+ struct xml_attribute_list attributes;
1020
+ struct xml_attribute *attribute;
1021
+
1022
+ LXW_INIT_ATTRIBUTES();
1023
+ LXW_PUSH_ATTRIBUTES_STR("count", "0");
1024
+ LXW_PUSH_ATTRIBUTES_STR("defaultTableStyle", "TableStyleMedium9");
1025
+ LXW_PUSH_ATTRIBUTES_STR("defaultPivotStyle", "PivotStyleLight16");
1026
+
1027
+ lxw_xml_empty_tag(self->file, "tableStyles", &attributes);
1028
+
1029
+ LXW_FREE_ATTRIBUTES();
1030
+ }
1031
+
1032
+ /*****************************************************************************
1033
+ *
1034
+ * XML file assembly functions.
1035
+ *
1036
+ ****************************************************************************/
1037
+
1038
+ /*
1039
+ * Assemble and write the XML file.
1040
+ */
1041
+ void
1042
+ lxw_styles_assemble_xml_file(lxw_styles *self)
1043
+ {
1044
+ /* Write the XML declaration. */
1045
+ _styles_xml_declaration(self);
1046
+
1047
+ /* Add the style sheet. */
1048
+ _write_style_sheet(self);
1049
+
1050
+ /* Write the number formats. */
1051
+ _write_num_fmts(self);
1052
+
1053
+ /* Write the fonts. */
1054
+ _write_fonts(self);
1055
+
1056
+ /* Write the fills. */
1057
+ _write_fills(self);
1058
+
1059
+ /* Write the borders element. */
1060
+ _write_borders(self);
1061
+
1062
+ /* Write the cellStyleXfs element. */
1063
+ _write_cell_style_xfs(self);
1064
+
1065
+ /* Write the cellXfs element. */
1066
+ _write_cell_xfs(self);
1067
+
1068
+ /* Write the cellStyles element. */
1069
+ _write_cell_styles(self);
1070
+
1071
+ /* Write the dxfs element. */
1072
+ _write_dxfs(self);
1073
+
1074
+ /* Write the tableStyles element. */
1075
+ _write_table_styles(self);
1076
+
1077
+ /* Write the colors element. */
1078
+ /* _write_colors(self); */
1079
+
1080
+ /* Close the style sheet tag. */
1081
+ lxw_xml_end_tag(self->file, "styleSheet");
1082
+ }
1083
+
1084
+ /*****************************************************************************
1085
+ *
1086
+ * Public functions.
1087
+ *
1088
+ ****************************************************************************/