kmadej_fast_excel_fork 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ ****************************************************************************/