PageRenderTime 53ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/peek-build/src/netdepends/libcss/src/select/computed.c

https://bitbucket.org/C0deMaver1ck/peeklinux
C | 1009 lines | 656 code | 153 blank | 200 comment | 230 complexity | 6b9e650fee7f2a7c3afb7da149e32772 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. * This file is part of LibCSS
  3. * Licensed under the MIT License,
  4. * http://www.opensource.org/licenses/mit-license.php
  5. * Copyright 2009 John-Mark Bell <jmb@netsurf-browser.org>
  6. */
  7. #include <string.h>
  8. #include "select/computed.h"
  9. #include "select/dispatch.h"
  10. #include "select/propget.h"
  11. #include "select/propset.h"
  12. #include "utils/utils.h"
  13. static css_error compute_border_colors(css_computed_style *style);
  14. static css_error compute_absolute_border_width(css_computed_style *style,
  15. const css_hint_length *ex_size);
  16. static css_error compute_absolute_border_side_width(css_computed_style *style,
  17. const css_hint_length *ex_size,
  18. uint8_t (*get)(const css_computed_style *style,
  19. css_fixed *len, css_unit *unit),
  20. css_error (*set)(css_computed_style *style, uint8_t type,
  21. css_fixed len, css_unit unit));
  22. static css_error compute_absolute_sides(css_computed_style *style,
  23. const css_hint_length *ex_size);
  24. static css_error compute_absolute_clip(css_computed_style *style,
  25. const css_hint_length *ex_size);
  26. static css_error compute_absolute_line_height(css_computed_style *style,
  27. const css_hint_length *ex_size);
  28. static css_error compute_absolute_margins(css_computed_style *style,
  29. const css_hint_length *ex_size);
  30. static css_error compute_absolute_padding(css_computed_style *style,
  31. const css_hint_length *ex_size);
  32. static css_error compute_absolute_vertical_align(css_computed_style *style,
  33. const css_hint_length *ex_size);
  34. static css_error compute_absolute_length(css_computed_style *style,
  35. const css_hint_length *ex_size,
  36. uint8_t (*get)(const css_computed_style *style,
  37. css_fixed *len, css_unit *unit),
  38. css_error (*set)(css_computed_style *style, uint8_t type,
  39. css_fixed len, css_unit unit));
  40. static css_error compute_absolute_length_auto(css_computed_style *style,
  41. const css_hint_length *ex_size,
  42. uint8_t (*get)(const css_computed_style *style,
  43. css_fixed *len, css_unit *unit),
  44. css_error (*set)(css_computed_style *style, uint8_t type,
  45. css_fixed len, css_unit unit));
  46. static css_error compute_absolute_length_none(css_computed_style *style,
  47. const css_hint_length *ex_size,
  48. uint8_t (*get)(const css_computed_style *style,
  49. css_fixed *len, css_unit *unit),
  50. css_error (*set)(css_computed_style *style, uint8_t type,
  51. css_fixed len, css_unit unit));
  52. static css_error compute_absolute_length_normal(css_computed_style *style,
  53. const css_hint_length *ex_size,
  54. uint8_t (*get)(const css_computed_style *style,
  55. css_fixed *len, css_unit *unit),
  56. css_error (*set)(css_computed_style *style, uint8_t type,
  57. css_fixed len, css_unit unit));
  58. static css_error compute_absolute_length_pair(css_computed_style *style,
  59. const css_hint_length *ex_size,
  60. uint8_t (*get)(const css_computed_style *style,
  61. css_fixed *len1, css_unit *unit1,
  62. css_fixed *len2, css_unit *unit2),
  63. css_error (*set)(css_computed_style *style, uint8_t type,
  64. css_fixed len1, css_unit unit1,
  65. css_fixed len2, css_unit unit2));
  66. /**
  67. * Create a computed style
  68. *
  69. * \param alloc Memory (de)allocation function
  70. * \param pw Pointer to client-specific data
  71. * \param result Pointer to location to receive result
  72. * \return CSS_OK on success,
  73. * CSS_NOMEM on memory exhaustion,
  74. * CSS_BADPARM on bad parameters.
  75. */
  76. css_error css_computed_style_create(css_allocator_fn alloc, void *pw,
  77. css_computed_style **result)
  78. {
  79. css_computed_style *s;
  80. if (alloc == NULL || result == NULL)
  81. return CSS_BADPARM;
  82. s = alloc(NULL, sizeof(css_computed_style), pw);
  83. if (s == NULL)
  84. return CSS_NOMEM;
  85. memset(s, 0, sizeof(css_computed_style));
  86. s->alloc = alloc;
  87. s->pw = pw;
  88. *result = s;
  89. return CSS_OK;
  90. }
  91. /**
  92. * Destroy a computed style
  93. *
  94. * \param style Style to destroy
  95. * \return CSS_OK on success, appropriate error otherwise
  96. */
  97. css_error css_computed_style_destroy(css_computed_style *style)
  98. {
  99. if (style == NULL)
  100. return CSS_BADPARM;
  101. if (style->uncommon != NULL) {
  102. if (style->uncommon->counter_increment != NULL) {
  103. css_computed_counter *c;
  104. for (c = style->uncommon->counter_increment;
  105. c->name != NULL; c++) {
  106. lwc_string_unref(c->name);
  107. }
  108. style->alloc(style->uncommon->counter_increment, 0,
  109. style->pw);
  110. }
  111. if (style->uncommon->counter_reset != NULL) {
  112. css_computed_counter *c;
  113. for (c = style->uncommon->counter_reset;
  114. c->name != NULL; c++) {
  115. lwc_string_unref(c->name);
  116. }
  117. style->alloc(style->uncommon->counter_reset, 0,
  118. style->pw);
  119. }
  120. if (style->uncommon->cursor != NULL) {
  121. lwc_string **s;
  122. for (s = style->uncommon->cursor; *s != NULL; s++) {
  123. lwc_string_unref(*s);
  124. }
  125. style->alloc(style->uncommon->cursor, 0, style->pw);
  126. }
  127. if (style->uncommon->content != NULL) {
  128. css_computed_content_item *c;
  129. for (c = style->uncommon->content;
  130. c->type != CSS_COMPUTED_CONTENT_NONE;
  131. c++) {
  132. switch (c->type) {
  133. case CSS_COMPUTED_CONTENT_STRING:
  134. lwc_string_unref(c->data.string);
  135. break;
  136. case CSS_COMPUTED_CONTENT_URI:
  137. lwc_string_unref(c->data.uri);
  138. break;
  139. case CSS_COMPUTED_CONTENT_ATTR:
  140. lwc_string_unref(c->data.attr);
  141. break;
  142. case CSS_COMPUTED_CONTENT_COUNTER:
  143. lwc_string_unref(c->data.counter.name);
  144. break;
  145. case CSS_COMPUTED_CONTENT_COUNTERS:
  146. lwc_string_unref(c->data.counters.name);
  147. lwc_string_unref(c->data.counters.sep);
  148. break;
  149. default:
  150. break;
  151. }
  152. }
  153. style->alloc(style->uncommon->content, 0, style->pw);
  154. }
  155. style->alloc(style->uncommon, 0, style->pw);
  156. }
  157. if (style->page != NULL) {
  158. style->alloc(style->page, 0, style->pw);
  159. }
  160. if (style->aural != NULL) {
  161. style->alloc(style->aural, 0, style->pw);
  162. }
  163. if (style->font_family != NULL) {
  164. lwc_string **s;
  165. for (s = style->font_family; *s != NULL; s++) {
  166. lwc_string_unref(*s);
  167. }
  168. style->alloc(style->font_family, 0, style->pw);
  169. }
  170. if (style->quotes != NULL) {
  171. lwc_string **s;
  172. for (s = style->quotes; *s != NULL; s++) {
  173. lwc_string_unref(*s);
  174. }
  175. style->alloc(style->quotes, 0, style->pw);
  176. }
  177. if (style->list_style_image != NULL)
  178. lwc_string_unref(style->list_style_image);
  179. if (style->background_image != NULL)
  180. lwc_string_unref(style->background_image);
  181. style->alloc(style, 0, style->pw);
  182. return CSS_OK;
  183. }
  184. /**
  185. * Populate a blank computed style with Initial values
  186. *
  187. * \param style Computed style to populate
  188. * \param handler Dispatch table of handler functions
  189. * \param pw Client-specific private data for handler functions
  190. * \return CSS_OK on success.
  191. */
  192. css_error css_computed_style_initialise(css_computed_style *style,
  193. css_select_handler *handler, void *pw)
  194. {
  195. css_select_state state;
  196. uint32_t i;
  197. css_error error;
  198. if (style == NULL)
  199. return CSS_BADPARM;
  200. state.node = NULL;
  201. state.pseudo_element = CSS_PSEUDO_ELEMENT_NONE;
  202. state.media = CSS_MEDIA_ALL;
  203. state.result = style;
  204. state.handler = handler;
  205. state.pw = pw;
  206. for (i = 0; i < CSS_N_PROPERTIES; i++) {
  207. /* No need to initialise anything other than the normal
  208. * properties -- the others are handled by the accessors */
  209. if (prop_dispatch[i].inherited == false &&
  210. prop_dispatch[i].group == GROUP_NORMAL) {
  211. error = prop_dispatch[i].initial(&state);
  212. if (error != CSS_OK)
  213. return error;
  214. }
  215. }
  216. return CSS_OK;
  217. }
  218. /**
  219. * Compose two computed styles
  220. *
  221. * \param parent Parent style
  222. * \param child Child style
  223. * \param compute_font_size Function to compute an absolute font size
  224. * \param pw Client data for compute_font_size
  225. * \param result Pointer to style to compose into
  226. * \return CSS_OK on success, appropriate error otherwise.
  227. *
  228. * \pre \a parent is a fully composed style (thus has no inherited properties)
  229. *
  230. * \note \a child and \a result may point at the same object
  231. */
  232. css_error css_computed_style_compose(const css_computed_style *parent,
  233. const css_computed_style *child,
  234. css_error (*compute_font_size)(void *pw,
  235. const css_hint *parent, css_hint *size),
  236. void *pw,
  237. css_computed_style *result)
  238. {
  239. css_error error = CSS_OK;
  240. size_t i;
  241. /* Iterate through the properties */
  242. for (i = 0; i < CSS_N_PROPERTIES; i++) {
  243. /* Skip any in extension blocks if the block does not exist */
  244. if (prop_dispatch[i].group == GROUP_UNCOMMON &&
  245. parent->uncommon == NULL &&
  246. child->uncommon == NULL)
  247. continue;
  248. if (prop_dispatch[i].group == GROUP_PAGE &&
  249. parent->page == NULL && child->page == NULL)
  250. continue;
  251. if (prop_dispatch[i].group == GROUP_AURAL &&
  252. parent->aural == NULL && child->aural == NULL)
  253. continue;
  254. /* Compose the property */
  255. error = prop_dispatch[i].compose(parent, child, result);
  256. if (error != CSS_OK)
  257. break;
  258. }
  259. /* Finally, compute absolute values for everything */
  260. return compute_absolute_values(parent, result, compute_font_size, pw);
  261. }
  262. /******************************************************************************
  263. * Library internals *
  264. ******************************************************************************/
  265. /**
  266. * Compute the absolute values of a style
  267. *
  268. * \param parent Parent style, or NULL for tree root
  269. * \param style Computed style to process
  270. * \param compute_font_size Callback to calculate an absolute font-size
  271. * \param pw Private word for callback
  272. * \return CSS_OK on success.
  273. */
  274. css_error compute_absolute_values(const css_computed_style *parent,
  275. css_computed_style *style,
  276. css_error (*compute_font_size)(void *pw,
  277. const css_hint *parent, css_hint *size),
  278. void *pw)
  279. {
  280. css_hint psize, size, ex_size;
  281. css_error error;
  282. /* Ensure font-size is absolute */
  283. if (parent != NULL) {
  284. psize.status = get_font_size(parent,
  285. &psize.data.length.value,
  286. &psize.data.length.unit);
  287. }
  288. size.status = get_font_size(style,
  289. &size.data.length.value,
  290. &size.data.length.unit);
  291. error = compute_font_size(pw, parent != NULL ? &psize : NULL, &size);
  292. if (error != CSS_OK)
  293. return error;
  294. error = set_font_size(style, size.status,
  295. size.data.length.value,
  296. size.data.length.unit);
  297. if (error != CSS_OK)
  298. return error;
  299. /* Compute the size of an ex unit */
  300. ex_size.status = CSS_FONT_SIZE_DIMENSION;
  301. ex_size.data.length.value = INTTOFIX(1);
  302. ex_size.data.length.unit = CSS_UNIT_EX;
  303. error = compute_font_size(pw, &size, &ex_size);
  304. if (error != CSS_OK)
  305. return error;
  306. /* Convert ex size into ems */
  307. if (size.data.length.value != 0)
  308. ex_size.data.length.value = FDIV(ex_size.data.length.value,
  309. size.data.length.value);
  310. else
  311. ex_size.data.length.value = 0;
  312. ex_size.data.length.unit = CSS_UNIT_EM;
  313. /* Fix up background-position */
  314. error = compute_absolute_length_pair(style, &ex_size.data.length,
  315. get_background_position,
  316. set_background_position);
  317. if (error != CSS_OK)
  318. return error;
  319. /* Fix up border-{top,right,bottom,left}-color */
  320. error = compute_border_colors(style);
  321. if (error != CSS_OK)
  322. return error;
  323. /* Fix up border-{top,right,bottom,left}-width */
  324. error = compute_absolute_border_width(style, &ex_size.data.length);
  325. if (error != CSS_OK)
  326. return error;
  327. /* Fix up sides */
  328. error = compute_absolute_sides(style, &ex_size.data.length);
  329. if (error != CSS_OK)
  330. return error;
  331. /* Fix up height */
  332. error = compute_absolute_length_auto(style, &ex_size.data.length,
  333. get_height, set_height);
  334. if (error != CSS_OK)
  335. return error;
  336. /* Fix up line-height (must be before vertical-align) */
  337. error = compute_absolute_line_height(style, &ex_size.data.length);
  338. if (error != CSS_OK)
  339. return error;
  340. /* Fix up margins */
  341. error = compute_absolute_margins(style, &ex_size.data.length);
  342. if (error != CSS_OK)
  343. return error;
  344. /* Fix up max-height */
  345. error = compute_absolute_length_none(style, &ex_size.data.length,
  346. get_max_height, set_max_height);
  347. if (error != CSS_OK)
  348. return error;
  349. /* Fix up max-width */
  350. error = compute_absolute_length_none(style, &ex_size.data.length,
  351. get_max_width, set_max_width);
  352. if (error != CSS_OK)
  353. return error;
  354. /* Fix up min-height */
  355. error = compute_absolute_length(style, &ex_size.data.length,
  356. get_min_height, set_min_height);
  357. if (error != CSS_OK)
  358. return error;
  359. /* Fix up min-width */
  360. error = compute_absolute_length(style, &ex_size.data.length,
  361. get_min_width, set_min_width);
  362. if (error != CSS_OK)
  363. return error;
  364. /* Fix up padding */
  365. error = compute_absolute_padding(style, &ex_size.data.length);
  366. if (error != CSS_OK)
  367. return error;
  368. /* Fix up text-indent */
  369. error = compute_absolute_length(style, &ex_size.data.length,
  370. get_text_indent, set_text_indent);
  371. if (error != CSS_OK)
  372. return error;
  373. /* Fix up vertical-align */
  374. error = compute_absolute_vertical_align(style, &ex_size.data.length);
  375. if (error != CSS_OK)
  376. return error;
  377. /* Fix up width */
  378. error = compute_absolute_length_auto(style, &ex_size.data.length,
  379. get_width, set_width);
  380. if (error != CSS_OK)
  381. return error;
  382. /* Uncommon properties */
  383. if (style->uncommon != NULL) {
  384. /* Fix up border-spacing */
  385. error = compute_absolute_length_pair(style,
  386. &ex_size.data.length,
  387. get_border_spacing,
  388. set_border_spacing);
  389. if (error != CSS_OK)
  390. return error;
  391. /* Fix up clip */
  392. error = compute_absolute_clip(style, &ex_size.data.length);
  393. if (error != CSS_OK)
  394. return error;
  395. /* Fix up letter-spacing */
  396. error = compute_absolute_length_normal(style,
  397. &ex_size.data.length,
  398. get_letter_spacing,
  399. set_letter_spacing);
  400. if (error != CSS_OK)
  401. return error;
  402. /* Fix up outline-width */
  403. error = compute_absolute_border_side_width(style,
  404. &ex_size.data.length,
  405. get_outline_width,
  406. set_outline_width);
  407. if (error != CSS_OK)
  408. return error;
  409. /* Fix up word spacing */
  410. error = compute_absolute_length_normal(style,
  411. &ex_size.data.length,
  412. get_word_spacing,
  413. set_word_spacing);
  414. if (error != CSS_OK)
  415. return error;
  416. }
  417. return CSS_OK;
  418. }
  419. /******************************************************************************
  420. * Absolute value calculators
  421. ******************************************************************************/
  422. /**
  423. * Compute border colours, replacing any set to initial with
  424. * the computed value of color.
  425. *
  426. * \param style The style to process
  427. * \return CSS_OK on success
  428. */
  429. css_error compute_border_colors(css_computed_style *style)
  430. {
  431. css_color color, bcol;
  432. css_error error;
  433. css_computed_color(style, &color);
  434. if (get_border_top_color(style, &bcol) == CSS_BORDER_COLOR_INITIAL) {
  435. error = set_border_top_color(style,
  436. CSS_BORDER_COLOR_COLOR, color);
  437. if (error != CSS_OK)
  438. return error;
  439. }
  440. if (get_border_right_color(style, &bcol) == CSS_BORDER_COLOR_INITIAL) {
  441. error = set_border_right_color(style,
  442. CSS_BORDER_COLOR_COLOR, color);
  443. if (error != CSS_OK)
  444. return error;
  445. }
  446. if (get_border_bottom_color(style, &bcol) == CSS_BORDER_COLOR_INITIAL) {
  447. error = set_border_bottom_color(style,
  448. CSS_BORDER_COLOR_COLOR, color);
  449. if (error != CSS_OK)
  450. return error;
  451. }
  452. if (get_border_left_color(style, &bcol) == CSS_BORDER_COLOR_INITIAL) {
  453. error = set_border_left_color(style,
  454. CSS_BORDER_COLOR_COLOR, color);
  455. if (error != CSS_OK)
  456. return error;
  457. }
  458. return CSS_OK;
  459. }
  460. /**
  461. * Compute absolute border widths
  462. *
  463. * \param style Style to process
  464. * \param ex_size Ex size in ems
  465. * \return CSS_OK on success
  466. */
  467. css_error compute_absolute_border_width(css_computed_style *style,
  468. const css_hint_length *ex_size)
  469. {
  470. css_error error;
  471. error = compute_absolute_border_side_width(style, ex_size,
  472. get_border_top_width,
  473. set_border_top_width);
  474. if (error != CSS_OK)
  475. return error;
  476. error = compute_absolute_border_side_width(style, ex_size,
  477. get_border_right_width,
  478. set_border_right_width);
  479. if (error != CSS_OK)
  480. return error;
  481. error = compute_absolute_border_side_width(style, ex_size,
  482. get_border_bottom_width,
  483. set_border_bottom_width);
  484. if (error != CSS_OK)
  485. return error;
  486. error = compute_absolute_border_side_width(style, ex_size,
  487. get_border_left_width,
  488. set_border_left_width);
  489. if (error != CSS_OK)
  490. return error;
  491. return CSS_OK;
  492. }
  493. /**
  494. * Compute an absolute border side width
  495. *
  496. * \param style Style to process
  497. * \param ex_size Ex size, in ems
  498. * \param get Function to read length
  499. * \param set Function to write length
  500. * \return CSS_OK on success
  501. */
  502. css_error compute_absolute_border_side_width(css_computed_style *style,
  503. const css_hint_length *ex_size,
  504. uint8_t (*get)(const css_computed_style *style,
  505. css_fixed *len, css_unit *unit),
  506. css_error (*set)(css_computed_style *style, uint8_t type,
  507. css_fixed len, css_unit unit))
  508. {
  509. css_fixed length;
  510. css_unit unit;
  511. uint8_t type;
  512. type = get(style, &length, &unit);
  513. if (type == CSS_BORDER_WIDTH_THIN) {
  514. length = INTTOFIX(1);
  515. unit = CSS_UNIT_PX;
  516. } else if (type == CSS_BORDER_WIDTH_MEDIUM) {
  517. length = INTTOFIX(2);
  518. unit = CSS_UNIT_PX;
  519. } else if (type == CSS_BORDER_WIDTH_THICK) {
  520. length = INTTOFIX(4);
  521. unit = CSS_UNIT_PX;
  522. }
  523. if (unit == CSS_UNIT_EX) {
  524. length = FMUL(length, ex_size->value);
  525. unit = ex_size->unit;
  526. }
  527. return set(style, CSS_BORDER_WIDTH_WIDTH, length, unit);
  528. }
  529. /**
  530. * Compute absolute clip
  531. *
  532. * \param style Style to process
  533. * \param ex_size Ex size in ems
  534. * \return CSS_OK on success
  535. */
  536. css_error compute_absolute_clip(css_computed_style *style,
  537. const css_hint_length *ex_size)
  538. {
  539. css_computed_clip_rect rect = { 0, 0, 0, 0, CSS_UNIT_PX, CSS_UNIT_PX,
  540. CSS_UNIT_PX, CSS_UNIT_PX, false, false, false, false };
  541. css_error error;
  542. if (get_clip(style, &rect) == CSS_CLIP_RECT) {
  543. if (rect.top_auto == false) {
  544. if (rect.tunit == CSS_UNIT_EX) {
  545. rect.top = FMUL(rect.top, ex_size->value);
  546. rect.tunit = ex_size->unit;
  547. }
  548. }
  549. if (rect.right_auto == false) {
  550. if (rect.runit == CSS_UNIT_EX) {
  551. rect.right = FMUL(rect.right, ex_size->value);
  552. rect.runit = ex_size->unit;
  553. }
  554. }
  555. if (rect.bottom_auto == false) {
  556. if (rect.bunit == CSS_UNIT_EX) {
  557. rect.bottom = FMUL(rect.bottom, ex_size->value);
  558. rect.bunit = ex_size->unit;
  559. }
  560. }
  561. if (rect.left_auto == false) {
  562. if (rect.lunit == CSS_UNIT_EX) {
  563. rect.left = FMUL(rect.left, ex_size->value);
  564. rect.lunit = ex_size->unit;
  565. }
  566. }
  567. error = set_clip(style, CSS_CLIP_RECT, &rect);
  568. if (error != CSS_OK)
  569. return error;
  570. }
  571. return CSS_OK;
  572. }
  573. /**
  574. * Compute absolute line-height
  575. *
  576. * \param style Style to process
  577. * \param ex_size Ex size, in ems
  578. * \return CSS_OK on success
  579. */
  580. css_error compute_absolute_line_height(css_computed_style *style,
  581. const css_hint_length *ex_size)
  582. {
  583. css_fixed length = 0;
  584. css_unit unit = CSS_UNIT_PX;
  585. uint8_t type;
  586. css_error error;
  587. type = get_line_height(style, &length, &unit);
  588. if (type == CSS_LINE_HEIGHT_DIMENSION) {
  589. if (unit == CSS_UNIT_EX) {
  590. length = FMUL(length, ex_size->value);
  591. unit = ex_size->unit;
  592. }
  593. error = set_line_height(style, type, length, unit);
  594. if (error != CSS_OK)
  595. return error;
  596. }
  597. return CSS_OK;
  598. }
  599. /**
  600. * Compute the absolute values of {top,right,bottom,left}
  601. *
  602. * \param style Style to process
  603. * \param ex_size Ex size, in ems
  604. * \return CSS_OK on success
  605. */
  606. css_error compute_absolute_sides(css_computed_style *style,
  607. const css_hint_length *ex_size)
  608. {
  609. css_error error;
  610. /* Calculate absolute lengths for sides */
  611. error = compute_absolute_length_auto(style, ex_size, get_top, set_top);
  612. if (error != CSS_OK)
  613. return error;
  614. error = compute_absolute_length_auto(style, ex_size,
  615. get_right, set_right);
  616. if (error != CSS_OK)
  617. return error;
  618. error = compute_absolute_length_auto(style, ex_size,
  619. get_bottom, set_bottom);
  620. if (error != CSS_OK)
  621. return error;
  622. error = compute_absolute_length_auto(style, ex_size,
  623. get_left, set_left);
  624. if (error != CSS_OK)
  625. return error;
  626. return CSS_OK;
  627. }
  628. /**
  629. * Compute absolute margins
  630. *
  631. * \param style Style to process
  632. * \param ex_size Ex size, in ems
  633. * \return CSS_OK on success
  634. */
  635. css_error compute_absolute_margins(css_computed_style *style,
  636. const css_hint_length *ex_size)
  637. {
  638. css_error error;
  639. error = compute_absolute_length_auto(style, ex_size,
  640. get_margin_top, set_margin_top);
  641. if (error != CSS_OK)
  642. return error;
  643. error = compute_absolute_length_auto(style, ex_size,
  644. get_margin_right, set_margin_right);
  645. if (error != CSS_OK)
  646. return error;
  647. error = compute_absolute_length_auto(style, ex_size,
  648. get_margin_bottom, set_margin_bottom);
  649. if (error != CSS_OK)
  650. return error;
  651. error = compute_absolute_length_auto(style, ex_size,
  652. get_margin_left, set_margin_left);
  653. if (error != CSS_OK)
  654. return error;
  655. return CSS_OK;
  656. }
  657. /**
  658. * Compute absolute padding
  659. *
  660. * \param style Style to process
  661. * \param ex_size Ex size, in ems
  662. * \return CSS_OK on success
  663. */
  664. css_error compute_absolute_padding(css_computed_style *style,
  665. const css_hint_length *ex_size)
  666. {
  667. css_error error;
  668. error = compute_absolute_length(style, ex_size,
  669. get_padding_top, set_padding_top);
  670. if (error != CSS_OK)
  671. return error;
  672. error = compute_absolute_length(style, ex_size,
  673. get_padding_right, set_padding_right);
  674. if (error != CSS_OK)
  675. return error;
  676. error = compute_absolute_length(style, ex_size,
  677. get_padding_bottom, set_padding_bottom);
  678. if (error != CSS_OK)
  679. return error;
  680. error = compute_absolute_length(style, ex_size,
  681. get_padding_left, set_padding_left);
  682. if (error != CSS_OK)
  683. return error;
  684. return CSS_OK;
  685. }
  686. /**
  687. * Compute absolute vertical-align
  688. *
  689. * \param style Style to process
  690. * \param ex_size Ex size, in ems
  691. * \return CSS_OK on success
  692. */
  693. css_error compute_absolute_vertical_align(css_computed_style *style,
  694. const css_hint_length *ex_size)
  695. {
  696. css_fixed length = 0;
  697. css_unit unit = CSS_UNIT_PX;
  698. uint8_t type;
  699. css_error error;
  700. type = get_vertical_align(style, &length, &unit);
  701. if (type == CSS_VERTICAL_ALIGN_SET) {
  702. if (unit == CSS_UNIT_EX) {
  703. length = FMUL(length, ex_size->value);
  704. unit = ex_size->unit;
  705. }
  706. error = set_vertical_align(style, type, length, unit);
  707. if (error != CSS_OK)
  708. return error;
  709. }
  710. return CSS_OK;
  711. }
  712. /**
  713. * Compute the absolute value of length
  714. *
  715. * \param style Style to process
  716. * \param ex_size Ex size, in ems
  717. * \param get Function to read length
  718. * \param set Function to write length
  719. * \return CSS_OK on success
  720. */
  721. css_error compute_absolute_length(css_computed_style *style,
  722. const css_hint_length *ex_size,
  723. uint8_t (*get)(const css_computed_style *style,
  724. css_fixed *len, css_unit *unit),
  725. css_error (*set)(css_computed_style *style, uint8_t type,
  726. css_fixed len, css_unit unit))
  727. {
  728. css_fixed length;
  729. css_unit unit;
  730. uint8_t type;
  731. type = get(style, &length, &unit);
  732. if (unit == CSS_UNIT_EX) {
  733. length = FMUL(length, ex_size->value);
  734. unit = ex_size->unit;
  735. }
  736. return set(style, type, length, unit);
  737. }
  738. /**
  739. * Compute the absolute value of length or auto
  740. *
  741. * \param style Style to process
  742. * \param ex_size Ex size, in ems
  743. * \param get Function to read length
  744. * \param set Function to write length
  745. * \return CSS_OK on success
  746. */
  747. css_error compute_absolute_length_auto(css_computed_style *style,
  748. const css_hint_length *ex_size,
  749. uint8_t (*get)(const css_computed_style *style,
  750. css_fixed *len, css_unit *unit),
  751. css_error (*set)(css_computed_style *style, uint8_t type,
  752. css_fixed len, css_unit unit))
  753. {
  754. css_fixed length;
  755. css_unit unit;
  756. uint8_t type;
  757. type = get(style, &length, &unit);
  758. if (type != CSS_BOTTOM_AUTO) {
  759. if (unit == CSS_UNIT_EX) {
  760. length = FMUL(length, ex_size->value);
  761. unit = ex_size->unit;
  762. }
  763. return set(style, CSS_BOTTOM_SET, length, unit);
  764. }
  765. return set(style, CSS_BOTTOM_AUTO, 0, CSS_UNIT_PX);
  766. }
  767. /**
  768. * Compute the absolute value of length or none
  769. *
  770. * \param style Style to process
  771. * \param ex_size Ex size, in ems
  772. * \param get Function to read length
  773. * \param set Function to write length
  774. * \return CSS_OK on success
  775. */
  776. css_error compute_absolute_length_none(css_computed_style *style,
  777. const css_hint_length *ex_size,
  778. uint8_t (*get)(const css_computed_style *style,
  779. css_fixed *len, css_unit *unit),
  780. css_error (*set)(css_computed_style *style, uint8_t type,
  781. css_fixed len, css_unit unit))
  782. {
  783. css_fixed length;
  784. css_unit unit;
  785. uint8_t type;
  786. type = get(style, &length, &unit);
  787. if (type != CSS_MAX_HEIGHT_NONE) {
  788. if (unit == CSS_UNIT_EX) {
  789. length = FMUL(length, ex_size->value);
  790. unit = ex_size->unit;
  791. }
  792. return set(style, CSS_MAX_HEIGHT_SET, length, unit);
  793. }
  794. return set(style, CSS_MAX_HEIGHT_NONE, 0, CSS_UNIT_PX);
  795. }
  796. /**
  797. * Compute the absolute value of length or normal
  798. *
  799. * \param style Style to process
  800. * \param ex_size Ex size, in ems
  801. * \param get Function to read length
  802. * \param set Function to write length
  803. * \return CSS_OK on success
  804. */
  805. css_error compute_absolute_length_normal(css_computed_style *style,
  806. const css_hint_length *ex_size,
  807. uint8_t (*get)(const css_computed_style *style,
  808. css_fixed *len, css_unit *unit),
  809. css_error (*set)(css_computed_style *style, uint8_t type,
  810. css_fixed len, css_unit unit))
  811. {
  812. css_fixed length;
  813. css_unit unit;
  814. uint8_t type;
  815. type = get(style, &length, &unit);
  816. if (type != CSS_LETTER_SPACING_NORMAL) {
  817. if (unit == CSS_UNIT_EX) {
  818. length = FMUL(length, ex_size->value);
  819. unit = ex_size->unit;
  820. }
  821. return set(style, CSS_LETTER_SPACING_SET, length, unit);
  822. }
  823. return set(style, CSS_LETTER_SPACING_NORMAL, 0, CSS_UNIT_PX);
  824. }
  825. /**
  826. * Compute the absolute value of length pair
  827. *
  828. * \param style Style to process
  829. * \param ex_size Ex size, in ems
  830. * \param get Function to read length
  831. * \param set Function to write length
  832. * \return CSS_OK on success
  833. */
  834. css_error compute_absolute_length_pair(css_computed_style *style,
  835. const css_hint_length *ex_size,
  836. uint8_t (*get)(const css_computed_style *style,
  837. css_fixed *len1, css_unit *unit1,
  838. css_fixed *len2, css_unit *unit2),
  839. css_error (*set)(css_computed_style *style, uint8_t type,
  840. css_fixed len1, css_unit unit1,
  841. css_fixed len2, css_unit unit2))
  842. {
  843. css_fixed length1, length2;
  844. css_unit unit1, unit2;
  845. uint8_t type;
  846. type = get(style, &length1, &unit1, &length2, &unit2);
  847. if (unit1 == CSS_UNIT_EX) {
  848. length1 = FMUL(length1, ex_size->value);
  849. unit1 = ex_size->unit;
  850. }
  851. if (unit2 == CSS_UNIT_EX) {
  852. length2 = FMUL(length2, ex_size->value);
  853. unit2 = ex_size->unit;
  854. }
  855. return set(style, type, length1, unit1, length2, unit2);
  856. }