format.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  1. /*****************************************************************************
  2. * format - A library for creating Excel XLSX format files.
  3. *
  4. * Used in conjunction with the libxlsxwriter library.
  5. *
  6. * Copyright 2014-2018, John McNamara, [email protected]. See LICENSE.txt.
  7. *
  8. */
  9. #include "xlsxwriter/xmlwriter.h"
  10. #include "xlsxwriter/format.h"
  11. #include "xlsxwriter/utility.h"
  12. /*****************************************************************************
  13. *
  14. * Private functions.
  15. *
  16. ****************************************************************************/
  17. /*
  18. * Create a new format object.
  19. */
  20. lxw_format *
  21. lxw_format_new()
  22. {
  23. lxw_format *format = calloc(1, sizeof(lxw_format));
  24. GOTO_LABEL_ON_MEM_ERROR(format, mem_error);
  25. format->xf_format_indices = NULL;
  26. format->xf_index = LXW_PROPERTY_UNSET;
  27. format->dxf_index = LXW_PROPERTY_UNSET;
  28. format->font_name[0] = '\0';
  29. format->font_scheme[0] = '\0';
  30. format->num_format[0] = '\0';
  31. format->num_format_index = 0;
  32. format->font_index = 0;
  33. format->has_font = LXW_FALSE;
  34. format->has_dxf_font = LXW_FALSE;
  35. format->font_size = 11.0;
  36. format->bold = LXW_FALSE;
  37. format->italic = LXW_FALSE;
  38. format->font_color = LXW_COLOR_UNSET;
  39. format->underline = LXW_FALSE;
  40. format->font_strikeout = LXW_FALSE;
  41. format->font_outline = LXW_FALSE;
  42. format->font_shadow = LXW_FALSE;
  43. format->font_script = LXW_FALSE;
  44. format->font_family = LXW_DEFAULT_FONT_FAMILY;
  45. format->font_charset = LXW_FALSE;
  46. format->font_condense = LXW_FALSE;
  47. format->font_extend = LXW_FALSE;
  48. format->theme = LXW_FALSE;
  49. format->hyperlink = LXW_FALSE;
  50. format->hidden = LXW_FALSE;
  51. format->locked = LXW_TRUE;
  52. format->text_h_align = LXW_ALIGN_NONE;
  53. format->text_wrap = LXW_FALSE;
  54. format->text_v_align = LXW_ALIGN_NONE;
  55. format->text_justlast = LXW_FALSE;
  56. format->rotation = 0;
  57. format->fg_color = LXW_COLOR_UNSET;
  58. format->bg_color = LXW_COLOR_UNSET;
  59. format->pattern = LXW_PATTERN_NONE;
  60. format->has_fill = LXW_FALSE;
  61. format->has_dxf_fill = LXW_FALSE;
  62. format->fill_index = 0;
  63. format->fill_count = 0;
  64. format->border_index = 0;
  65. format->has_border = LXW_FALSE;
  66. format->has_dxf_border = LXW_FALSE;
  67. format->border_count = 0;
  68. format->bottom = LXW_BORDER_NONE;
  69. format->left = LXW_BORDER_NONE;
  70. format->right = LXW_BORDER_NONE;
  71. format->top = LXW_BORDER_NONE;
  72. format->diag_border = LXW_BORDER_NONE;
  73. format->diag_type = LXW_BORDER_NONE;
  74. format->bottom_color = LXW_COLOR_UNSET;
  75. format->left_color = LXW_COLOR_UNSET;
  76. format->right_color = LXW_COLOR_UNSET;
  77. format->top_color = LXW_COLOR_UNSET;
  78. format->diag_color = LXW_COLOR_UNSET;
  79. format->indent = 0;
  80. format->shrink = LXW_FALSE;
  81. format->merge_range = LXW_FALSE;
  82. format->reading_order = 0;
  83. format->just_distrib = LXW_FALSE;
  84. format->color_indexed = LXW_FALSE;
  85. format->font_only = LXW_FALSE;
  86. return format;
  87. mem_error:
  88. lxw_format_free(format);
  89. return NULL;
  90. }
  91. /*
  92. * Free a format object.
  93. */
  94. void
  95. lxw_format_free(lxw_format *format)
  96. {
  97. if (!format)
  98. return;
  99. free(format);
  100. format = NULL;
  101. }
  102. /*
  103. * Check a user input color.
  104. */
  105. lxw_color_t
  106. lxw_format_check_color(lxw_color_t color)
  107. {
  108. if (color == LXW_COLOR_UNSET)
  109. return color;
  110. else
  111. return color & LXW_COLOR_MASK;
  112. }
  113. /*
  114. * Check a user input border.
  115. */
  116. STATIC uint8_t
  117. _check_border(uint8_t border)
  118. {
  119. if (border >= LXW_BORDER_THIN && border <= LXW_BORDER_SLANT_DASH_DOT)
  120. return border;
  121. else
  122. return LXW_BORDER_NONE;
  123. }
  124. /*****************************************************************************
  125. *
  126. * Public functions.
  127. *
  128. ****************************************************************************/
  129. /*
  130. * Returns a format struct suitable for hashing as a lookup key. This is
  131. * mainly a memcpy with any pointer members set to NULL.
  132. */
  133. STATIC lxw_format *
  134. _get_format_key(lxw_format *self)
  135. {
  136. lxw_format *key = calloc(1, sizeof(lxw_format));
  137. GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
  138. memcpy(key, self, sizeof(lxw_format));
  139. /* Set pointer members to NULL since they aren't part of the comparison. */
  140. key->xf_format_indices = NULL;
  141. key->num_xf_formats = NULL;
  142. key->list_pointers.stqe_next = NULL;
  143. return key;
  144. mem_error:
  145. return NULL;
  146. }
  147. /*
  148. * Returns a font struct suitable for hashing as a lookup key.
  149. */
  150. lxw_font *
  151. lxw_format_get_font_key(lxw_format *self)
  152. {
  153. lxw_font *key = calloc(1, sizeof(lxw_font));
  154. GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
  155. LXW_FORMAT_FIELD_COPY(key->font_name, self->font_name);
  156. key->font_size = self->font_size;
  157. key->bold = self->bold;
  158. key->italic = self->italic;
  159. key->font_color = self->font_color;
  160. key->underline = self->underline;
  161. key->font_strikeout = self->font_strikeout;
  162. key->font_outline = self->font_outline;
  163. key->font_shadow = self->font_shadow;
  164. key->font_script = self->font_script;
  165. key->font_family = self->font_family;
  166. key->font_charset = self->font_charset;
  167. key->font_condense = self->font_condense;
  168. key->font_extend = self->font_extend;
  169. return key;
  170. mem_error:
  171. return NULL;
  172. }
  173. /*
  174. * Returns a border struct suitable for hashing as a lookup key.
  175. */
  176. lxw_border *
  177. lxw_format_get_border_key(lxw_format *self)
  178. {
  179. lxw_border *key = calloc(1, sizeof(lxw_border));
  180. GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
  181. key->bottom = self->bottom;
  182. key->left = self->left;
  183. key->right = self->right;
  184. key->top = self->top;
  185. key->diag_border = self->diag_border;
  186. key->diag_type = self->diag_type;
  187. key->bottom_color = self->bottom_color;
  188. key->left_color = self->left_color;
  189. key->right_color = self->right_color;
  190. key->top_color = self->top_color;
  191. key->diag_color = self->diag_color;
  192. return key;
  193. mem_error:
  194. return NULL;
  195. }
  196. /*
  197. * Returns a pattern fill struct suitable for hashing as a lookup key.
  198. */
  199. lxw_fill *
  200. lxw_format_get_fill_key(lxw_format *self)
  201. {
  202. lxw_fill *key = calloc(1, sizeof(lxw_fill));
  203. GOTO_LABEL_ON_MEM_ERROR(key, mem_error);
  204. key->fg_color = self->fg_color;
  205. key->bg_color = self->bg_color;
  206. key->pattern = self->pattern;
  207. return key;
  208. mem_error:
  209. return NULL;
  210. }
  211. /*
  212. * Returns the XF index number used by Excel to identify a format.
  213. */
  214. int32_t
  215. lxw_format_get_xf_index(lxw_format *self)
  216. {
  217. lxw_format *format_key;
  218. lxw_format *existing_format;
  219. lxw_hash_element *hash_element;
  220. lxw_hash_table *formats_hash_table = self->xf_format_indices;
  221. int32_t index;
  222. /* Note: The formats_hash_table/xf_format_indices contains the unique and
  223. * more importantly the *used* formats in the workbook.
  224. */
  225. /* Format already has an index number so return it. */
  226. if (self->xf_index != LXW_PROPERTY_UNSET) {
  227. return self->xf_index;
  228. }
  229. /* Otherwise, the format doesn't have an index number so we assign one.
  230. * First generate a unique key to identify the format in the hash table.
  231. */
  232. format_key = _get_format_key(self);
  233. /* Return the default format index if the key generation failed. */
  234. if (!format_key)
  235. return 0;
  236. /* Look up the format in the hash table. */
  237. hash_element =
  238. lxw_hash_key_exists(formats_hash_table, format_key,
  239. sizeof(lxw_format));
  240. if (hash_element) {
  241. /* Format matches existing format with an index. */
  242. free(format_key);
  243. existing_format = hash_element->value;
  244. return existing_format->xf_index;
  245. }
  246. else {
  247. /* New format requiring an index. */
  248. index = formats_hash_table->unique_count;
  249. self->xf_index = index;
  250. lxw_insert_hash_element(formats_hash_table, format_key, self,
  251. sizeof(lxw_format));
  252. return index;
  253. }
  254. }
  255. /*
  256. * Set the font_name property.
  257. */
  258. void
  259. format_set_font_name(lxw_format *self, const char *font_name)
  260. {
  261. LXW_FORMAT_FIELD_COPY(self->font_name, font_name);
  262. }
  263. /*
  264. * Set the font_size property.
  265. */
  266. void
  267. format_set_font_size(lxw_format *self, double size)
  268. {
  269. if (size >= LXW_MIN_FONT_SIZE && size <= LXW_MAX_FONT_SIZE)
  270. self->font_size = size;
  271. }
  272. /*
  273. * Set the font_color property.
  274. */
  275. void
  276. format_set_font_color(lxw_format *self, lxw_color_t color)
  277. {
  278. self->font_color = lxw_format_check_color(color);
  279. }
  280. /*
  281. * Set the bold property.
  282. */
  283. void
  284. format_set_bold(lxw_format *self)
  285. {
  286. self->bold = LXW_TRUE;
  287. }
  288. /*
  289. * Set the italic property.
  290. */
  291. void
  292. format_set_italic(lxw_format *self)
  293. {
  294. self->italic = LXW_TRUE;
  295. }
  296. /*
  297. * Set the underline property.
  298. */
  299. void
  300. format_set_underline(lxw_format *self, uint8_t style)
  301. {
  302. if (style >= LXW_UNDERLINE_SINGLE
  303. && style <= LXW_UNDERLINE_DOUBLE_ACCOUNTING)
  304. self->underline = style;
  305. }
  306. /*
  307. * Set the font_strikeout property.
  308. */
  309. void
  310. format_set_font_strikeout(lxw_format *self)
  311. {
  312. self->font_strikeout = LXW_TRUE;
  313. }
  314. /*
  315. * Set the font_script property.
  316. */
  317. void
  318. format_set_font_script(lxw_format *self, uint8_t style)
  319. {
  320. if (style >= LXW_FONT_SUPERSCRIPT && style <= LXW_FONT_SUBSCRIPT)
  321. self->font_script = style;
  322. }
  323. /*
  324. * Set the font_outline property.
  325. */
  326. void
  327. format_set_font_outline(lxw_format *self)
  328. {
  329. self->font_outline = LXW_TRUE;
  330. }
  331. /*
  332. * Set the font_shadow property.
  333. */
  334. void
  335. format_set_font_shadow(lxw_format *self)
  336. {
  337. self->font_shadow = LXW_TRUE;
  338. }
  339. /*
  340. * Set the num_format property.
  341. */
  342. void
  343. format_set_num_format(lxw_format *self, const char *num_format)
  344. {
  345. LXW_FORMAT_FIELD_COPY(self->num_format, num_format);
  346. }
  347. /*
  348. * Set the unlocked property.
  349. */
  350. void
  351. format_set_unlocked(lxw_format *self)
  352. {
  353. self->locked = LXW_FALSE;
  354. }
  355. /*
  356. * Set the hidden property.
  357. */
  358. void
  359. format_set_hidden(lxw_format *self)
  360. {
  361. self->hidden = LXW_TRUE;
  362. }
  363. /*
  364. * Set the align property.
  365. */
  366. void
  367. format_set_align(lxw_format *self, uint8_t value)
  368. {
  369. if (value >= LXW_ALIGN_LEFT && value <= LXW_ALIGN_DISTRIBUTED) {
  370. self->text_h_align = value;
  371. }
  372. if (value >= LXW_ALIGN_VERTICAL_TOP
  373. && value <= LXW_ALIGN_VERTICAL_DISTRIBUTED) {
  374. self->text_v_align = value;
  375. }
  376. }
  377. /*
  378. * Set the text_wrap property.
  379. */
  380. void
  381. format_set_text_wrap(lxw_format *self)
  382. {
  383. self->text_wrap = LXW_TRUE;
  384. }
  385. /*
  386. * Set the rotation property.
  387. */
  388. void
  389. format_set_rotation(lxw_format *self, int16_t angle)
  390. {
  391. /* Convert user angle to Excel angle. */
  392. if (angle == 270) {
  393. self->rotation = 255;
  394. }
  395. else if (angle >= -90 || angle <= 90) {
  396. if (angle < 0)
  397. angle = -angle + 90;
  398. self->rotation = angle;
  399. }
  400. else {
  401. LXW_WARN("Rotation rotation outside range: -90 <= angle <= 90.");
  402. self->rotation = 0;
  403. }
  404. }
  405. /*
  406. * Set the indent property.
  407. */
  408. void
  409. format_set_indent(lxw_format *self, uint8_t value)
  410. {
  411. self->indent = value;
  412. }
  413. /*
  414. * Set the shrink property.
  415. */
  416. void
  417. format_set_shrink(lxw_format *self)
  418. {
  419. self->shrink = LXW_TRUE;
  420. }
  421. /*
  422. * Set the text_justlast property.
  423. */
  424. void
  425. format_set_text_justlast(lxw_format *self)
  426. {
  427. self->text_justlast = LXW_TRUE;
  428. }
  429. /*
  430. * Set the pattern property.
  431. */
  432. void
  433. format_set_pattern(lxw_format *self, uint8_t value)
  434. {
  435. self->pattern = value;
  436. }
  437. /*
  438. * Set the bg_color property.
  439. */
  440. void
  441. format_set_bg_color(lxw_format *self, lxw_color_t color)
  442. {
  443. self->bg_color = lxw_format_check_color(color);
  444. }
  445. /*
  446. * Set the fg_color property.
  447. */
  448. void
  449. format_set_fg_color(lxw_format *self, lxw_color_t color)
  450. {
  451. self->fg_color = lxw_format_check_color(color);
  452. }
  453. /*
  454. * Set the border property.
  455. */
  456. void
  457. format_set_border(lxw_format *self, uint8_t style)
  458. {
  459. style = _check_border(style);
  460. self->bottom = style;
  461. self->top = style;
  462. self->left = style;
  463. self->right = style;
  464. }
  465. /*
  466. * Set the border_color property.
  467. */
  468. void
  469. format_set_border_color(lxw_format *self, lxw_color_t color)
  470. {
  471. color = lxw_format_check_color(color);
  472. self->bottom_color = color;
  473. self->top_color = color;
  474. self->left_color = color;
  475. self->right_color = color;
  476. }
  477. /*
  478. * Set the bottom property.
  479. */
  480. void
  481. format_set_bottom(lxw_format *self, uint8_t style)
  482. {
  483. self->bottom = _check_border(style);
  484. }
  485. /*
  486. * Set the bottom_color property.
  487. */
  488. void
  489. format_set_bottom_color(lxw_format *self, lxw_color_t color)
  490. {
  491. self->bottom_color = lxw_format_check_color(color);
  492. }
  493. /*
  494. * Set the left property.
  495. */
  496. void
  497. format_set_left(lxw_format *self, uint8_t style)
  498. {
  499. self->left = _check_border(style);
  500. }
  501. /*
  502. * Set the left_color property.
  503. */
  504. void
  505. format_set_left_color(lxw_format *self, lxw_color_t color)
  506. {
  507. self->left_color = lxw_format_check_color(color);
  508. }
  509. /*
  510. * Set the right property.
  511. */
  512. void
  513. format_set_right(lxw_format *self, uint8_t style)
  514. {
  515. self->right = _check_border(style);
  516. }
  517. /*
  518. * Set the right_color property.
  519. */
  520. void
  521. format_set_right_color(lxw_format *self, lxw_color_t color)
  522. {
  523. self->right_color = lxw_format_check_color(color);
  524. }
  525. /*
  526. * Set the top property.
  527. */
  528. void
  529. format_set_top(lxw_format *self, uint8_t style)
  530. {
  531. self->top = _check_border(style);
  532. }
  533. /*
  534. * Set the top_color property.
  535. */
  536. void
  537. format_set_top_color(lxw_format *self, lxw_color_t color)
  538. {
  539. self->top_color = lxw_format_check_color(color);
  540. }
  541. /*
  542. * Set the diag_type property.
  543. */
  544. void
  545. format_set_diag_type(lxw_format *self, uint8_t type)
  546. {
  547. if (type >= LXW_DIAGONAL_BORDER_UP && type <= LXW_DIAGONAL_BORDER_UP_DOWN)
  548. self->diag_type = type;
  549. }
  550. /*
  551. * Set the diag_color property.
  552. */
  553. void
  554. format_set_diag_color(lxw_format *self, lxw_color_t color)
  555. {
  556. self->diag_color = lxw_format_check_color(color);
  557. }
  558. /*
  559. * Set the diag_border property.
  560. */
  561. void
  562. format_set_diag_border(lxw_format *self, uint8_t style)
  563. {
  564. self->diag_border = style;
  565. }
  566. /*
  567. * Set the num_format_index property.
  568. */
  569. void
  570. format_set_num_format_index(lxw_format *self, uint8_t value)
  571. {
  572. self->num_format_index = value;
  573. }
  574. /*
  575. * Set the valign property.
  576. */
  577. void
  578. format_set_valign(lxw_format *self, uint8_t value)
  579. {
  580. self->text_v_align = value;
  581. }
  582. /*
  583. * Set the reading_order property.
  584. */
  585. void
  586. format_set_reading_order(lxw_format *self, uint8_t value)
  587. {
  588. self->reading_order = value;
  589. }
  590. /*
  591. * Set the font_family property.
  592. */
  593. void
  594. format_set_font_family(lxw_format *self, uint8_t value)
  595. {
  596. self->font_family = value;
  597. }
  598. /*
  599. * Set the font_charset property.
  600. */
  601. void
  602. format_set_font_charset(lxw_format *self, uint8_t value)
  603. {
  604. self->font_charset = value;
  605. }
  606. /*
  607. * Set the font_scheme property.
  608. */
  609. void
  610. format_set_font_scheme(lxw_format *self, const char *font_scheme)
  611. {
  612. LXW_FORMAT_FIELD_COPY(self->font_scheme, font_scheme);
  613. }
  614. /*
  615. * Set the font_condense property.
  616. */
  617. void
  618. format_set_font_condense(lxw_format *self)
  619. {
  620. self->font_condense = LXW_TRUE;
  621. }
  622. /*
  623. * Set the font_extend property.
  624. */
  625. void
  626. format_set_font_extend(lxw_format *self)
  627. {
  628. self->font_extend = LXW_TRUE;
  629. }
  630. /*
  631. * Set the theme property.
  632. */
  633. void
  634. format_set_theme(lxw_format *self, uint8_t value)
  635. {
  636. self->theme = value;
  637. }