fast_excel 0.6.0 → 0.6.1

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 (97) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/test.yml +1 -1
  3. data/CHANGELOG.md +3 -1
  4. data/Rakefile +4 -1
  5. data/fast_excel.gemspec +1 -1
  6. data/lib/fast_excel/binding/workbook.rb +9 -0
  7. data/lib/fast_excel/binding/worksheet.rb +2 -2
  8. data/lib/fast_excel/binding.rb +16 -13
  9. data/libxlsxwriter/.cirrus.yml +9 -0
  10. data/libxlsxwriter/.github/workflows/cmake_actions.yml +10 -6
  11. data/libxlsxwriter/.github/workflows/code_style.yml +2 -0
  12. data/libxlsxwriter/.github/workflows/make_32_actions.yml +43 -0
  13. data/libxlsxwriter/.github/workflows/windows_build.yml +7 -6
  14. data/libxlsxwriter/.github/workflows/zig_build.yml +1 -3
  15. data/libxlsxwriter/.gitignore +9 -7
  16. data/libxlsxwriter/.indent.pro +6 -0
  17. data/libxlsxwriter/CMakeLists.txt +377 -238
  18. data/libxlsxwriter/Changes.txt +189 -0
  19. data/libxlsxwriter/LICENSE.txt +1 -1
  20. data/libxlsxwriter/Makefile +36 -4
  21. data/libxlsxwriter/Readme.md +1 -1
  22. data/libxlsxwriter/build.zig +181 -92
  23. data/libxlsxwriter/build.zig.zon +15 -4
  24. data/libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h +4 -0
  25. data/libxlsxwriter/include/xlsxwriter/app.h +2 -1
  26. data/libxlsxwriter/include/xlsxwriter/chart.h +134 -1
  27. data/libxlsxwriter/include/xlsxwriter/chartsheet.h +2 -1
  28. data/libxlsxwriter/include/xlsxwriter/comment.h +2 -1
  29. data/libxlsxwriter/include/xlsxwriter/common.h +12 -8
  30. data/libxlsxwriter/include/xlsxwriter/content_types.h +3 -1
  31. data/libxlsxwriter/include/xlsxwriter/core.h +2 -1
  32. data/libxlsxwriter/include/xlsxwriter/custom.h +2 -1
  33. data/libxlsxwriter/include/xlsxwriter/drawing.h +2 -1
  34. data/libxlsxwriter/include/xlsxwriter/format.h +34 -3
  35. data/libxlsxwriter/include/xlsxwriter/hash_table.h +2 -1
  36. data/libxlsxwriter/include/xlsxwriter/metadata.h +5 -1
  37. data/libxlsxwriter/include/xlsxwriter/packager.h +6 -1
  38. data/libxlsxwriter/include/xlsxwriter/relationships.h +3 -1
  39. data/libxlsxwriter/include/xlsxwriter/rich_value.h +51 -0
  40. data/libxlsxwriter/include/xlsxwriter/rich_value_rel.h +50 -0
  41. data/libxlsxwriter/include/xlsxwriter/rich_value_structure.h +53 -0
  42. data/libxlsxwriter/include/xlsxwriter/rich_value_types.h +49 -0
  43. data/libxlsxwriter/include/xlsxwriter/shared_strings.h +2 -1
  44. data/libxlsxwriter/include/xlsxwriter/styles.h +2 -1
  45. data/libxlsxwriter/include/xlsxwriter/table.h +2 -1
  46. data/libxlsxwriter/include/xlsxwriter/theme.h +2 -1
  47. data/libxlsxwriter/include/xlsxwriter/third_party/ioapi.h +4 -4
  48. data/libxlsxwriter/include/xlsxwriter/third_party/zip.h +3 -3
  49. data/libxlsxwriter/include/xlsxwriter/utility.h +58 -7
  50. data/libxlsxwriter/include/xlsxwriter/vml.h +2 -1
  51. data/libxlsxwriter/include/xlsxwriter/workbook.h +59 -2
  52. data/libxlsxwriter/include/xlsxwriter/worksheet.h +159 -13
  53. data/libxlsxwriter/include/xlsxwriter/xmlwriter.h +11 -10
  54. data/libxlsxwriter/include/xlsxwriter.h +5 -4
  55. data/libxlsxwriter/libxlsxwriter.podspec +6 -6
  56. data/libxlsxwriter/src/Makefile +2 -1
  57. data/libxlsxwriter/src/app.c +2 -1
  58. data/libxlsxwriter/src/chart.c +360 -63
  59. data/libxlsxwriter/src/chartsheet.c +2 -1
  60. data/libxlsxwriter/src/comment.c +2 -1
  61. data/libxlsxwriter/src/content_types.c +22 -1
  62. data/libxlsxwriter/src/core.c +2 -1
  63. data/libxlsxwriter/src/custom.c +2 -1
  64. data/libxlsxwriter/src/drawing.c +7 -3
  65. data/libxlsxwriter/src/format.c +21 -1
  66. data/libxlsxwriter/src/hash_table.c +2 -1
  67. data/libxlsxwriter/src/metadata.c +176 -20
  68. data/libxlsxwriter/src/packager.c +306 -6
  69. data/libxlsxwriter/src/relationships.c +25 -1
  70. data/libxlsxwriter/src/rich_value.c +191 -0
  71. data/libxlsxwriter/src/rich_value_rel.c +142 -0
  72. data/libxlsxwriter/src/rich_value_structure.c +162 -0
  73. data/libxlsxwriter/src/rich_value_types.c +199 -0
  74. data/libxlsxwriter/src/shared_strings.c +2 -1
  75. data/libxlsxwriter/src/styles.c +31 -7
  76. data/libxlsxwriter/src/table.c +2 -1
  77. data/libxlsxwriter/src/theme.c +2 -1
  78. data/libxlsxwriter/src/utility.c +136 -46
  79. data/libxlsxwriter/src/vml.c +2 -1
  80. data/libxlsxwriter/src/workbook.c +191 -10
  81. data/libxlsxwriter/src/worksheet.c +514 -34
  82. data/libxlsxwriter/src/xmlwriter.c +17 -22
  83. data/libxlsxwriter/third_party/minizip/Makefile.orig +1 -1
  84. data/libxlsxwriter/third_party/minizip/configure.ac +1 -1
  85. data/libxlsxwriter/third_party/minizip/ioapi.h +6 -6
  86. data/libxlsxwriter/third_party/minizip/miniunz.c +16 -2
  87. data/libxlsxwriter/third_party/minizip/unzip.c +4 -4
  88. data/libxlsxwriter/third_party/minizip/unzip.h +1 -1
  89. data/libxlsxwriter/third_party/minizip/zip.c +5 -5
  90. data/libxlsxwriter/third_party/minizip/zip.h +3 -3
  91. data/libxlsxwriter/version.txt +1 -1
  92. data/test/validations_test.rb +3 -3
  93. data/test/worksheet_test.rb +10 -2
  94. metadata +11 -4
  95. data/libxlsxwriter/cmake/FindMINIZIP.cmake +0 -121
  96. data/libxlsxwriter/cmake/FindPackage.cmake +0 -183
  97. data/libxlsxwriter/cmake/i686-toolchain.cmake +0 -7
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * SPDX-License-Identifier: BSD-2-Clause
7
+ * Copyright 2014-2026, John McNamara, jmcnamara@cpan.org.
7
8
  *
8
9
  */
9
10
 
@@ -102,6 +103,29 @@ _chart_free_data_labels(lxw_chart_series *series)
102
103
  free(series->data_labels);
103
104
  }
104
105
 
106
+ STATIC void
107
+ _chart_free_axis(lxw_chart_axis *axis)
108
+ {
109
+ if (!axis)
110
+ return;
111
+
112
+ _chart_free_font(axis->num_font);
113
+ _chart_free_font(axis->title.font);
114
+ _chart_free_range(axis->title.range);
115
+
116
+ free(axis->fill);
117
+ free(axis->line);
118
+ free(axis->pattern);
119
+ free(axis->title.name);
120
+ free(axis->title.layout);
121
+ free(axis->num_format);
122
+ free(axis->default_num_format);
123
+ free(axis->major_gridlines.line);
124
+ free(axis->minor_gridlines.line);
125
+
126
+ free(axis);
127
+ }
128
+
105
129
  /*
106
130
  * Free a series object.
107
131
  */
@@ -188,54 +212,30 @@ lxw_chart_free(lxw_chart *chart)
188
212
  free(chart->series_list);
189
213
  }
190
214
 
191
- /* X Axis. */
192
- if (chart->x_axis) {
193
- _chart_free_font(chart->x_axis->title.font);
194
- _chart_free_font(chart->x_axis->num_font);
195
- _chart_free_range(chart->x_axis->title.range);
196
- free(chart->x_axis->title.name);
197
- free(chart->x_axis->line);
198
- free(chart->x_axis->fill);
199
- free(chart->x_axis->pattern);
200
- free(chart->x_axis->major_gridlines.line);
201
- free(chart->x_axis->minor_gridlines.line);
202
- free(chart->x_axis->num_format);
203
- free(chart->x_axis->default_num_format);
204
- free(chart->x_axis);
205
- }
206
-
207
- /* Y Axis. */
208
- if (chart->y_axis) {
209
- _chart_free_font(chart->y_axis->title.font);
210
- _chart_free_font(chart->y_axis->num_font);
211
- _chart_free_range(chart->y_axis->title.range);
212
- free(chart->y_axis->title.name);
213
- free(chart->y_axis->line);
214
- free(chart->y_axis->fill);
215
- free(chart->y_axis->pattern);
216
- free(chart->y_axis->major_gridlines.line);
217
- free(chart->y_axis->minor_gridlines.line);
218
- free(chart->y_axis->num_format);
219
- free(chart->y_axis->default_num_format);
220
- free(chart->y_axis);
221
- }
215
+ /* X and Y Axis. */
216
+ _chart_free_axis(chart->x_axis);
217
+ _chart_free_axis(chart->y_axis);
222
218
 
223
219
  /* Chart title. */
224
220
  _chart_free_font(chart->title.font);
225
221
  _chart_free_range(chart->title.range);
226
222
  free(chart->title.name);
223
+ free(chart->title.layout);
227
224
 
228
225
  /* Chart legend. */
229
226
  _chart_free_font(chart->legend.font);
230
- free(chart->delete_series);
227
+ free(chart->legend.layout);
231
228
 
229
+ free(chart->delete_series);
232
230
  free(chart->default_marker);
233
231
 
234
232
  free(chart->chartarea_line);
235
233
  free(chart->chartarea_fill);
236
234
  free(chart->chartarea_pattern);
235
+
237
236
  free(chart->plotarea_line);
238
237
  free(chart->plotarea_fill);
238
+ free(chart->plotarea_layout);
239
239
  free(chart->plotarea_pattern);
240
240
 
241
241
  free(chart->drop_lines_line);
@@ -448,6 +448,44 @@ _chart_convert_pattern_args(lxw_chart_pattern *user_pattern)
448
448
  return pattern;
449
449
  }
450
450
 
451
+ /*
452
+ * Create a copy of a user supplied layout.
453
+ */
454
+ STATIC lxw_chart_layout *
455
+ _chart_convert_layout_args(lxw_chart_layout *user_layout,
456
+ enum lxw_chart_layout_type type)
457
+ {
458
+ lxw_chart_layout *layout = calloc(1, sizeof(struct lxw_chart_layout));
459
+ RETURN_ON_MEM_ERROR(layout, NULL);
460
+
461
+ /* Copy the user supplied properties. */
462
+ switch (type) {
463
+ case LXW_CHART_LAYOUT_LEGEND:
464
+ layout->x = user_layout->x;
465
+ layout->y = user_layout->y;
466
+ layout->width = user_layout->width;
467
+ layout->height = user_layout->height;
468
+ layout->has_inner = LXW_FALSE;
469
+ break;
470
+ case LXW_CHART_LAYOUT_PLOTAREA:
471
+ layout->x = user_layout->x;
472
+ layout->y = user_layout->y;
473
+ layout->width = user_layout->width;
474
+ layout->height = user_layout->height;
475
+ layout->has_inner = LXW_TRUE;
476
+ break;
477
+ default:
478
+ layout->x = user_layout->x;
479
+ layout->y = user_layout->y;
480
+ layout->width = 0.0;
481
+ layout->height = 0.0;
482
+ layout->has_inner = LXW_FALSE;
483
+ break;
484
+ }
485
+
486
+ return layout;
487
+ }
488
+
451
489
  /*
452
490
  * Set a marker type for a series.
453
491
  */
@@ -479,7 +517,7 @@ _chart_axis_set_default_num_format(lxw_chart_axis *axis, char *num_format)
479
517
  }
480
518
 
481
519
  /*
482
- * Verify that a X/Y error bar property is support for the chart type.
520
+ * Verify that a X/Y error bar property is supported for the chart type.
483
521
  * All chart types, except Bar have Y error bars. Only Bar and Scatter
484
522
  * support X error bars.
485
523
  */
@@ -644,13 +682,101 @@ _chart_write_style(lxw_chart *self)
644
682
  LXW_FREE_ATTRIBUTES();
645
683
  }
646
684
 
685
+ /*
686
+ * Write the <c:layoutTarget> element.
687
+ */
688
+ STATIC void
689
+ _chart_write_layout_target(lxw_chart *self)
690
+ {
691
+ struct xml_attribute_list attributes;
692
+ struct xml_attribute *attribute;
693
+
694
+ LXW_INIT_ATTRIBUTES();
695
+ LXW_PUSH_ATTRIBUTES_STR("val", "inner");
696
+
697
+ lxw_xml_empty_tag(self->file, "c:layoutTarget", &attributes);
698
+
699
+ LXW_FREE_ATTRIBUTES();
700
+ }
701
+
702
+ /*
703
+ * Write the <c:xMode> and <c:yMode> element.
704
+ */
705
+ STATIC void
706
+ _chart_write_layout_mode(lxw_chart *self, char *mode)
707
+ {
708
+ struct xml_attribute_list attributes;
709
+ struct xml_attribute *attribute;
710
+
711
+ LXW_INIT_ATTRIBUTES();
712
+ LXW_PUSH_ATTRIBUTES_STR("val", "edge");
713
+
714
+ lxw_xml_empty_tag(self->file, mode, &attributes);
715
+
716
+ LXW_FREE_ATTRIBUTES();
717
+ }
718
+
719
+ /*
720
+ * Write the layout dimension elements.
721
+ */
722
+ STATIC void
723
+ _chart_write_layout_dimension(lxw_chart *self, char *dimension, double value)
724
+ {
725
+ struct xml_attribute_list attributes;
726
+ struct xml_attribute *attribute;
727
+
728
+ LXW_INIT_ATTRIBUTES();
729
+ LXW_PUSH_ATTRIBUTES_DBL("val", value);
730
+
731
+ lxw_xml_empty_tag(self->file, dimension, &attributes);
732
+
733
+ LXW_FREE_ATTRIBUTES();
734
+ }
735
+
736
+ /*
737
+ * Write the <c:manualLayout> element.
738
+ */
739
+ STATIC void
740
+ _chart_write_manual_layout(lxw_chart *self, lxw_chart_layout *layout)
741
+ {
742
+ lxw_xml_start_tag(self->file, "c:manualLayout", NULL);
743
+
744
+ /* Write the c:layoutTarget element. */
745
+ if (layout->has_inner)
746
+ _chart_write_layout_target(self);
747
+
748
+ /* Write the c:xMode and c:yMode elements. */
749
+ _chart_write_layout_mode(self, "c:xMode");
750
+ _chart_write_layout_mode(self, "c:yMode");
751
+
752
+ /* Write the dimension elements. */
753
+ _chart_write_layout_dimension(self, "c:x", layout->x);
754
+ _chart_write_layout_dimension(self, "c:y", layout->y);
755
+ if (layout->width > 0.0)
756
+ _chart_write_layout_dimension(self, "c:w", layout->width);
757
+ if (layout->height > 0.0)
758
+ _chart_write_layout_dimension(self, "c:h", layout->height);
759
+
760
+ lxw_xml_end_tag(self->file, "c:manualLayout");
761
+ }
762
+
647
763
  /*
648
764
  * Write the <c:layout> element.
649
765
  */
650
766
  STATIC void
651
- _chart_write_layout(lxw_chart *self)
767
+ _chart_write_layout(lxw_chart *self, lxw_chart_layout *layout)
652
768
  {
653
- lxw_xml_empty_tag(self->file, "c:layout", NULL);
769
+ if (layout == NULL) {
770
+ lxw_xml_empty_tag(self->file, "c:layout", NULL);
771
+ }
772
+ else {
773
+ lxw_xml_start_tag(self->file, "c:layout", NULL);
774
+
775
+ /* Write the c:manualLayout element. */
776
+ _chart_write_manual_layout(self, layout);
777
+
778
+ lxw_xml_end_tag(self->file, "c:layout");
779
+ }
654
780
  }
655
781
 
656
782
  /*
@@ -1524,6 +1650,23 @@ _chart_write_tx_rich(lxw_chart *self, char *name, uint8_t is_horizontal,
1524
1650
  lxw_xml_end_tag(self->file, "c:tx");
1525
1651
  }
1526
1652
 
1653
+ /*
1654
+ * Write the <c:overlay> element.
1655
+ */
1656
+ STATIC void
1657
+ _chart_write_overlay(lxw_chart *self)
1658
+ {
1659
+ struct xml_attribute_list attributes;
1660
+ struct xml_attribute *attribute;
1661
+
1662
+ LXW_INIT_ATTRIBUTES();
1663
+ LXW_PUSH_ATTRIBUTES_STR("val", "1");
1664
+
1665
+ lxw_xml_empty_tag(self->file, "c:overlay", &attributes);
1666
+
1667
+ LXW_FREE_ATTRIBUTES();
1668
+ }
1669
+
1527
1670
  /*
1528
1671
  * Write the <c:title> element for rich strings.
1529
1672
  */
@@ -1537,7 +1680,11 @@ _chart_write_title_rich(lxw_chart *self, lxw_chart_title *title)
1537
1680
  title->font);
1538
1681
 
1539
1682
  /* Write the c:layout element. */
1540
- _chart_write_layout(self);
1683
+ _chart_write_layout(self, title->layout);
1684
+
1685
+ /* Write the c:overlay element. */
1686
+ if (title->has_overlay)
1687
+ _chart_write_overlay(self);
1541
1688
 
1542
1689
  lxw_xml_end_tag(self->file, "c:title");
1543
1690
  }
@@ -1554,7 +1701,11 @@ _chart_write_title_formula(lxw_chart *self, lxw_chart_title *title)
1554
1701
  _chart_write_tx_formula(self, title);
1555
1702
 
1556
1703
  /* Write the c:layout element. */
1557
- _chart_write_layout(self);
1704
+ _chart_write_layout(self, title->layout);
1705
+
1706
+ /* Write the c:overlay element. */
1707
+ if (title->has_overlay)
1708
+ _chart_write_overlay(self);
1558
1709
 
1559
1710
  /* Write the c:txPr element. */
1560
1711
  _chart_write_tx_pr(self, title->is_horizontal, title->font);
@@ -3692,23 +3843,6 @@ _chart_write_cross_between(lxw_chart *self, uint8_t position)
3692
3843
  LXW_FREE_ATTRIBUTES();
3693
3844
  }
3694
3845
 
3695
- /*
3696
- * Write the <c:overlay> element.
3697
- */
3698
- STATIC void
3699
- _chart_write_overlay(lxw_chart *self)
3700
- {
3701
- struct xml_attribute_list attributes;
3702
- struct xml_attribute *attribute;
3703
-
3704
- LXW_INIT_ATTRIBUTES();
3705
- LXW_PUSH_ATTRIBUTES_STR("val", "1");
3706
-
3707
- lxw_xml_empty_tag(self->file, "c:overlay", &attributes);
3708
-
3709
- LXW_FREE_ATTRIBUTES();
3710
- }
3711
-
3712
3846
  /*
3713
3847
  * Write the <c:legendPos> element.
3714
3848
  */
@@ -3795,7 +3929,7 @@ _chart_write_legend(lxw_chart *self)
3795
3929
  }
3796
3930
 
3797
3931
  /* Write the c:layout element. */
3798
- _chart_write_layout(self);
3932
+ _chart_write_layout(self, self->legend.layout);
3799
3933
 
3800
3934
  if (self->chart_group == LXW_CHART_PIE
3801
3935
  || self->chart_group == LXW_CHART_DOUGHNUT) {
@@ -4736,7 +4870,7 @@ _chart_write_scatter_plot_area(lxw_chart *self)
4736
4870
  lxw_xml_start_tag(self->file, "c:plotArea", NULL);
4737
4871
 
4738
4872
  /* Write the c:layout element. */
4739
- _chart_write_layout(self);
4873
+ _chart_write_layout(self, self->plotarea_layout);
4740
4874
 
4741
4875
  /* Write subclass chart type elements for primary and secondary axes. */
4742
4876
  self->write_chart_type(self);
@@ -4768,7 +4902,7 @@ _chart_write_pie_plot_area(lxw_chart *self)
4768
4902
  lxw_xml_start_tag(self->file, "c:plotArea", NULL);
4769
4903
 
4770
4904
  /* Write the c:layout element. */
4771
- _chart_write_layout(self);
4905
+ _chart_write_layout(self, self->plotarea_layout);
4772
4906
 
4773
4907
  /* Write subclass chart type elements for primary and secondary axes. */
4774
4908
  self->write_chart_type(self);
@@ -4789,7 +4923,7 @@ _chart_write_plot_area(lxw_chart *self)
4789
4923
  lxw_xml_start_tag(self->file, "c:plotArea", NULL);
4790
4924
 
4791
4925
  /* Write the c:layout element. */
4792
- _chart_write_layout(self);
4926
+ _chart_write_layout(self, self->plotarea_layout);
4793
4927
 
4794
4928
  /* Write subclass chart type elements for primary and secondary axes. */
4795
4929
  self->write_chart_type(self);
@@ -5399,6 +5533,12 @@ chart_series_set_pattern(lxw_chart_series *series, lxw_chart_pattern *pattern)
5399
5533
  void
5400
5534
  chart_series_set_marker_type(lxw_chart_series *series, uint8_t type)
5401
5535
  {
5536
+ if (type > LXW_CHART_MARKER_PLUS) {
5537
+ LXW_WARN_FORMAT1
5538
+ ("chart_series_set_marker_type(): invalid marker type: %d", type);
5539
+ return;
5540
+ }
5541
+
5402
5542
  if (!series->marker) {
5403
5543
  lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
5404
5544
  RETURN_VOID_ON_MEM_ERROR(marker);
@@ -5414,6 +5554,13 @@ chart_series_set_marker_type(lxw_chart_series *series, uint8_t type)
5414
5554
  void
5415
5555
  chart_series_set_marker_size(lxw_chart_series *series, uint8_t size)
5416
5556
  {
5557
+ if (size < 2 || size > 72) {
5558
+ LXW_WARN_FORMAT1
5559
+ ("chart_series_set_marker_size(): marker size '%d' outside Excel range: 2 <= size <= 72",
5560
+ size);
5561
+ return;
5562
+ }
5563
+
5417
5564
  if (!series->marker) {
5418
5565
  lxw_chart_marker *marker = calloc(1, sizeof(struct lxw_chart_marker));
5419
5566
  RETURN_VOID_ON_MEM_ERROR(marker);
@@ -5493,8 +5640,8 @@ chart_series_set_marker_pattern(lxw_chart_series *series,
5493
5640
  lxw_error
5494
5641
  chart_series_set_points(lxw_chart_series *series, lxw_chart_point *points[])
5495
5642
  {
5496
- uint16_t i = 0;
5497
- uint16_t point_count = 0;
5643
+ size_t i = 0;
5644
+ size_t point_count = 0;
5498
5645
 
5499
5646
  if (points == NULL)
5500
5647
  return LXW_ERROR_NULL_PARAMETER_IGNORED;
@@ -5564,8 +5711,8 @@ lxw_error
5564
5711
  chart_series_set_labels_custom(lxw_chart_series *series,
5565
5712
  lxw_chart_data_label *data_labels[])
5566
5713
  {
5567
- uint16_t i = 0;
5568
- uint16_t data_label_count = 0;
5714
+ size_t i = 0;
5715
+ size_t data_label_count = 0;
5569
5716
 
5570
5717
  if (data_labels == NULL)
5571
5718
  return LXW_ERROR_NULL_PARAMETER_IGNORED;
@@ -5640,6 +5787,13 @@ mem_error:
5640
5787
  void
5641
5788
  chart_series_set_labels_separator(lxw_chart_series *series, uint8_t separator)
5642
5789
  {
5790
+ if (separator > LXW_CHART_LABEL_SEPARATOR_SPACE) {
5791
+ LXW_WARN_FORMAT1
5792
+ ("chart_series_set_labels_separator(): invalid label separator: %d",
5793
+ separator);
5794
+ return;
5795
+ }
5796
+
5643
5797
  series->has_labels = LXW_TRUE;
5644
5798
  series->label_separator = separator;
5645
5799
  }
@@ -5650,6 +5804,13 @@ chart_series_set_labels_separator(lxw_chart_series *series, uint8_t separator)
5650
5804
  void
5651
5805
  chart_series_set_labels_position(lxw_chart_series *series, uint8_t position)
5652
5806
  {
5807
+ if (position > LXW_CHART_LABEL_POSITION_BEST_FIT) {
5808
+ LXW_WARN_FORMAT1
5809
+ ("chart_series_set_labels_position(): invalid label position: %d",
5810
+ position);
5811
+ return;
5812
+ }
5813
+
5653
5814
  series->has_labels = LXW_TRUE;
5654
5815
  series->show_labels_value = LXW_TRUE;
5655
5816
 
@@ -5771,6 +5932,13 @@ void
5771
5932
  chart_series_set_trendline(lxw_chart_series *series, uint8_t type,
5772
5933
  uint8_t value)
5773
5934
  {
5935
+ if (type > LXW_CHART_TRENDLINE_TYPE_AVERAGE) {
5936
+ LXW_WARN_FORMAT1
5937
+ ("chart_series_set_trendline(): invalid trendline type: %d",
5938
+ type);
5939
+ return;
5940
+ }
5941
+
5774
5942
  if (type == LXW_CHART_TRENDLINE_TYPE_POLY
5775
5943
  || type == LXW_CHART_TRENDLINE_TYPE_AVERAGE) {
5776
5944
 
@@ -6042,6 +6210,22 @@ chart_axis_set_name_range(lxw_chart_axis *axis, const char *sheetname,
6042
6210
  _chart_set_range(axis->title.range, sheetname, row, col, row, col);
6043
6211
  }
6044
6212
 
6213
+ /*
6214
+ * Set a layout for the chart axis name.
6215
+ */
6216
+ void
6217
+ chart_axis_set_name_layout(lxw_chart_axis *axis, lxw_chart_layout *layout)
6218
+ {
6219
+ if (!layout)
6220
+ return;
6221
+
6222
+ /* Free any previously allocated resource. */
6223
+ free(axis->title.layout);
6224
+
6225
+ axis->title.layout =
6226
+ _chart_convert_layout_args(layout, LXW_CHART_LAYOUT_AXIS_NAME);
6227
+ }
6228
+
6045
6229
  /*
6046
6230
  * Set an axis title/name font.
6047
6231
  */
@@ -6186,6 +6370,12 @@ chart_axis_off(lxw_chart_axis *axis)
6186
6370
  void
6187
6371
  chart_axis_set_position(lxw_chart_axis *axis, uint8_t position)
6188
6372
  {
6373
+ if (position > LXW_CHART_AXIS_POSITION_BETWEEN) {
6374
+ LXW_WARN_FORMAT1
6375
+ ("chart_axis_set_position(): invalid position: %d", position);
6376
+ return;
6377
+ }
6378
+
6189
6379
  LXW_WARN_CAT_AND_DATE_AXIS_ONLY("chart_axis_set_position");
6190
6380
 
6191
6381
  axis->position_axis = position;
@@ -6197,6 +6387,13 @@ chart_axis_set_position(lxw_chart_axis *axis, uint8_t position)
6197
6387
  void
6198
6388
  chart_axis_set_label_position(lxw_chart_axis *axis, uint8_t position)
6199
6389
  {
6390
+ if (position > LXW_CHART_AXIS_LABEL_POSITION_NONE) {
6391
+ LXW_WARN_FORMAT1
6392
+ ("chart_axis_set_label_position(): invalid label position: %d",
6393
+ position);
6394
+ return;
6395
+ }
6396
+
6200
6397
  axis->label_position = position;
6201
6398
  }
6202
6399
 
@@ -6243,6 +6440,13 @@ chart_axis_set_log_base(lxw_chart_axis *axis, uint16_t log_base)
6243
6440
  void
6244
6441
  chart_axis_set_major_tick_mark(lxw_chart_axis *axis, uint8_t type)
6245
6442
  {
6443
+ if (type > LXW_CHART_AXIS_TICK_MARK_CROSSING) {
6444
+ LXW_WARN_FORMAT1
6445
+ ("chart_axis_set_major_tick_mark(): invalid tick mark type: %d",
6446
+ type);
6447
+ return;
6448
+ }
6449
+
6246
6450
  axis->major_tick_mark = type;
6247
6451
  }
6248
6452
 
@@ -6252,6 +6456,13 @@ chart_axis_set_major_tick_mark(lxw_chart_axis *axis, uint8_t type)
6252
6456
  void
6253
6457
  chart_axis_set_minor_tick_mark(lxw_chart_axis *axis, uint8_t type)
6254
6458
  {
6459
+ if (type > LXW_CHART_AXIS_TICK_MARK_CROSSING) {
6460
+ LXW_WARN_FORMAT1
6461
+ ("chart_axis_set_minor_tick_mark(): invalid tick mark type: %d",
6462
+ type);
6463
+ return;
6464
+ }
6465
+
6255
6466
  axis->minor_tick_mark = type;
6256
6467
  }
6257
6468
 
@@ -6307,6 +6518,13 @@ chart_axis_set_minor_unit(lxw_chart_axis *axis, double unit)
6307
6518
  void
6308
6519
  chart_axis_set_display_units(lxw_chart_axis *axis, uint8_t units)
6309
6520
  {
6521
+ if (units > LXW_CHART_AXIS_UNITS_TRILLIONS) {
6522
+ LXW_WARN_FORMAT1
6523
+ ("chart_axis_set_display_units(): invalid display units: %d",
6524
+ units);
6525
+ return;
6526
+ }
6527
+
6310
6528
  LXW_WARN_VALUE_AXIS_ONLY("chart_axis_set_display_units");
6311
6529
 
6312
6530
  axis->display_units = units;
@@ -6388,6 +6606,13 @@ chart_axis_minor_gridlines_set_line(lxw_chart_axis *axis,
6388
6606
  void
6389
6607
  chart_axis_set_label_align(lxw_chart_axis *axis, uint8_t align)
6390
6608
  {
6609
+ if (align > LXW_CHART_AXIS_LABEL_ALIGN_RIGHT) {
6610
+ LXW_WARN_FORMAT1
6611
+ ("chart_axis_set_label_align(): invalid label alignment: %d",
6612
+ align);
6613
+ return;
6614
+ }
6615
+
6391
6616
  axis->label_align = align;
6392
6617
  }
6393
6618
 
@@ -6443,15 +6668,63 @@ chart_title_off(lxw_chart *self)
6443
6668
  self->title.off = LXW_TRUE;
6444
6669
  }
6445
6670
 
6671
+ /*
6672
+ * Set a layout for the chart title.
6673
+ */
6674
+ void
6675
+ chart_title_set_layout(lxw_chart *self, lxw_chart_layout *layout)
6676
+ {
6677
+ if (!layout)
6678
+ return;
6679
+
6680
+ /* Free any previously allocated resource. */
6681
+ free(self->title.layout);
6682
+
6683
+ self->title.layout =
6684
+ _chart_convert_layout_args(layout, LXW_CHART_LAYOUT_TITLE);
6685
+ }
6686
+
6687
+ /*
6688
+ * Overlay the chart title on the chart.
6689
+ */
6690
+ void
6691
+ chart_title_set_overlay(lxw_chart *self, uint8_t overlay)
6692
+ {
6693
+ self->title.has_overlay = overlay;
6694
+ }
6695
+
6446
6696
  /*
6447
6697
  * Set the chart legend position.
6448
6698
  */
6449
6699
  void
6450
6700
  chart_legend_set_position(lxw_chart *self, uint8_t position)
6451
6701
  {
6702
+ if (position > LXW_CHART_LEGEND_OVERLAY_TOP_RIGHT) {
6703
+ LXW_WARN_FORMAT1
6704
+ ("chart_legend_set_position(): invalid legend position: %d",
6705
+ position);
6706
+ return;
6707
+ }
6708
+
6452
6709
  self->legend.position = position;
6453
6710
  }
6454
6711
 
6712
+ /*
6713
+ * Set a layout for the chart legend.
6714
+ */
6715
+ void
6716
+ chart_legend_set_layout(lxw_chart *self, lxw_chart_layout *layout)
6717
+ {
6718
+ if (!layout)
6719
+ return;
6720
+
6721
+ /* Free any previously allocated resource. */
6722
+ free(self->legend.layout);
6723
+
6724
+ self->legend.layout =
6725
+ _chart_convert_layout_args(layout, LXW_CHART_LAYOUT_LEGEND);
6726
+ }
6727
+
6455
6728
  /*
6456
6729
  * Set the legend font.
6457
6730
  */
@@ -6583,6 +6856,23 @@ chart_plotarea_set_pattern(lxw_chart *self, lxw_chart_pattern *pattern)
6583
6856
  self->plotarea_pattern = _chart_convert_pattern_args(pattern);
6584
6857
  }
6585
6858
 
6859
+ /*
6860
+ * Set a layout for the plotarea.
6861
+ */
6862
+ void
6863
+ chart_plotarea_set_layout(lxw_chart *self, lxw_chart_layout *layout)
6864
+ {
6865
+ if (!layout)
6866
+ return;
6867
+
6868
+ /* Free any previously allocated resource. */
6869
+ free(self->plotarea_layout);
6870
+
6871
+ self->plotarea_layout =
6872
+ _chart_convert_layout_args(layout, LXW_CHART_LAYOUT_PLOTAREA);
6873
+
6874
+ }
6875
+
6586
6876
  /*
6587
6877
  * Turn on the chart data table.
6588
6878
  */
@@ -6702,6 +6992,13 @@ chart_set_series_overlap(lxw_chart *self, int8_t overlap)
6702
6992
  void
6703
6993
  chart_show_blanks_as(lxw_chart *self, uint8_t option)
6704
6994
  {
6995
+ if (option > LXW_CHART_BLANKS_AS_CONNECTED) {
6996
+ LXW_WARN_FORMAT1
6997
+ ("chart_show_blanks_as(): invalid blank display option: %d",
6998
+ option);
6999
+ return;
7000
+ }
7001
+
6705
7002
  self->show_blanks_as = option;
6706
7003
  }
6707
7004
 
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * SPDX-License-Identifier: BSD-2-Clause
7
+ * Copyright 2014-2026, John McNamara, jmcnamara@cpan.org.
7
8
  *
8
9
  */
9
10
 
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * SPDX-License-Identifier: BSD-2-Clause
7
+ * Copyright 2014-2026, John McNamara, jmcnamara@cpan.org.
7
8
  *
8
9
  */
9
10
 
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * Used in conjunction with the libxlsxwriter library.
5
5
  *
6
- * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt.
6
+ * SPDX-License-Identifier: BSD-2-Clause
7
+ * Copyright 2014-2026, John McNamara, jmcnamara@cpan.org.
7
8
  *
8
9
  */
9
10
 
@@ -390,3 +391,23 @@ lxw_ct_add_metadata(lxw_content_types *self)
390
391
  lxw_ct_add_override(self, "/xl/metadata.xml",
391
392
  LXW_APP_DOCUMENT "spreadsheetml.sheetMetadata+xml");
392
393
  }
394
+
395
+ /*
396
+ * Add the richValue files to the ContentTypes overrides.
397
+ */
398
+ void
399
+ lxw_ct_add_rich_value(lxw_content_types *self)
400
+ {
401
+ lxw_ct_add_override(self, "/xl/richData/rdRichValueTypes.xml",
402
+ LXW_APP_MSEXCEL "rdrichvaluetypes+xml");
403
+
404
+ lxw_ct_add_override(self, "/xl/richData/rdrichvalue.xml",
405
+ LXW_APP_MSEXCEL "rdrichvalue+xml");
406
+
407
+ lxw_ct_add_override(self, "/xl/richData/rdrichvaluestructure.xml",
408
+ LXW_APP_MSEXCEL "rdrichvaluestructure+xml");
409
+
410
+ lxw_ct_add_override(self, "/xl/richData/richValueRel.xml",
411
+ LXW_APP_MSEXCEL "richvaluerel+xml");
412
+
413
+ }