PageRenderTime 30ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/cssed-0.4.0/libcroco/parser/cr-style.c

#
C | 2851 lines | 2260 code | 387 blank | 204 comment | 487 complexity | 06c6bad09f7687ac494c1b3febb81d02 MD5 | raw file
Possible License(s): GPL-2.0
  1. /* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */
  2. /*
  3. * This file is part of The Croco Library
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of version 2.1 of
  7. * the GNU Lesser General Public
  8. * License as published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the
  16. * GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  19. * USA
  20. *
  21. * Author: Dodji Seketeli.
  22. * see COPYRIGTHS file for copyright information
  23. */
  24. #include <string.h>
  25. #include "cr-style.h"
  26. /**
  27. *@file
  28. *The definition of the #CRStyle class.
  29. */
  30. /**
  31. *A property ID.
  32. *Each supported css property has an ID which is
  33. *an entry into a property "population" jump table.
  34. *each entry of the property population jump table
  35. *contains code to tranform the literal form of
  36. *a property value into a strongly typed value.
  37. */
  38. enum CRPropertyID {
  39. PROP_ID_NOT_KNOWN = 0,
  40. PROP_ID_PADDING_TOP,
  41. PROP_ID_PADDING_RIGHT,
  42. PROP_ID_PADDING_BOTTOM,
  43. PROP_ID_PADDING_LEFT,
  44. PROP_ID_PADDING,
  45. PROP_ID_BORDER_TOP_WIDTH,
  46. PROP_ID_BORDER_RIGHT_WIDTH,
  47. PROP_ID_BORDER_BOTTOM_WIDTH,
  48. PROP_ID_BORDER_LEFT_WIDTH,
  49. PROP_ID_BORDER_WIDTH,
  50. PROP_ID_BORDER_TOP_STYLE,
  51. PROP_ID_BORDER_RIGHT_STYLE,
  52. PROP_ID_BORDER_BOTTOM_STYLE,
  53. PROP_ID_BORDER_LEFT_STYLE,
  54. PROP_ID_BORDER_STYLE,
  55. PROP_ID_BORDER_TOP_COLOR,
  56. PROP_ID_BORDER_RIGHT_COLOR,
  57. PROP_ID_BORDER_BOTTOM_COLOR,
  58. PROP_ID_BORDER_LEFT_COLOR,
  59. PROP_ID_BORDER_TOP,
  60. PROP_ID_BORDER_RIGHT,
  61. PROP_ID_BORDER_BOTTOM,
  62. PROP_ID_BORDER_LEFT,
  63. PROP_ID_BORDER,
  64. PROP_ID_MARGIN_TOP,
  65. PROP_ID_MARGIN_RIGHT,
  66. PROP_ID_MARGIN_BOTTOM,
  67. PROP_ID_MARGIN_LEFT,
  68. PROP_ID_MARGIN,
  69. PROP_ID_DISPLAY,
  70. PROP_ID_POSITION,
  71. PROP_ID_TOP,
  72. PROP_ID_RIGHT,
  73. PROP_ID_BOTTOM,
  74. PROP_ID_LEFT,
  75. PROP_ID_FLOAT,
  76. PROP_ID_WIDTH,
  77. PROP_ID_COLOR,
  78. PROP_ID_BACKGROUND_COLOR,
  79. PROP_ID_FONT_FAMILY,
  80. PROP_ID_FONT_SIZE,
  81. PROP_ID_FONT_STYLE,
  82. PROP_ID_FONT_WEIGHT,
  83. PROP_ID_WHITE_SPACE,
  84. /*should be the last one. */
  85. NB_PROP_IDS
  86. };
  87. typedef struct _CRPropertyDesc CRPropertyDesc;
  88. struct _CRPropertyDesc {
  89. const guchar *name;
  90. enum CRPropertyID prop_id;
  91. };
  92. static CRPropertyDesc gv_prop_table[] = {
  93. {"padding-top", PROP_ID_PADDING_TOP},
  94. {"padding-right", PROP_ID_PADDING_RIGHT},
  95. {"padding-bottom", PROP_ID_PADDING_BOTTOM},
  96. {"padding-left", PROP_ID_PADDING_LEFT},
  97. {"padding", PROP_ID_PADDING},
  98. {"border-top-width", PROP_ID_BORDER_TOP_WIDTH},
  99. {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH},
  100. {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH},
  101. {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH},
  102. {"border-width", PROP_ID_BORDER_WIDTH},
  103. {"border-top-style", PROP_ID_BORDER_TOP_STYLE},
  104. {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE},
  105. {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE},
  106. {"border-left-style", PROP_ID_BORDER_LEFT_STYLE},
  107. {"border-style", PROP_ID_BORDER_STYLE},
  108. {"border-top", PROP_ID_BORDER_TOP},
  109. {"border-right", PROP_ID_BORDER_RIGHT},
  110. {"border-bottom", PROP_ID_BORDER_BOTTOM},
  111. {"border-left", PROP_ID_BORDER_LEFT},
  112. {"border", PROP_ID_BORDER},
  113. {"margin-top", PROP_ID_MARGIN_TOP},
  114. {"margin-right", PROP_ID_MARGIN_RIGHT},
  115. {"margin-bottom", PROP_ID_MARGIN_BOTTOM},
  116. {"margin-left", PROP_ID_MARGIN_LEFT},
  117. {"margin", PROP_ID_MARGIN},
  118. {"display", PROP_ID_DISPLAY},
  119. {"position", PROP_ID_POSITION},
  120. {"top", PROP_ID_TOP},
  121. {"right", PROP_ID_RIGHT},
  122. {"bottom", PROP_ID_BOTTOM},
  123. {"left", PROP_ID_LEFT},
  124. {"float", PROP_ID_FLOAT},
  125. {"width", PROP_ID_WIDTH},
  126. {"color", PROP_ID_COLOR},
  127. {"border-top-color", PROP_ID_BORDER_TOP_COLOR},
  128. {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR},
  129. {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR},
  130. {"border-left-color", PROP_ID_BORDER_LEFT_COLOR},
  131. {"background-color", PROP_ID_BACKGROUND_COLOR},
  132. {"font-family", PROP_ID_FONT_FAMILY},
  133. {"font-size", PROP_ID_FONT_SIZE},
  134. {"font-style", PROP_ID_FONT_STYLE},
  135. {"font-weight", PROP_ID_FONT_WEIGHT},
  136. {"white-space", PROP_ID_WHITE_SPACE},
  137. /*must be the last one */
  138. {NULL, 0}
  139. };
  140. /**
  141. *A the key/value pair of this hash table
  142. *are:
  143. *key => name of the the css propertie found in gv_prop_table
  144. *value => matching property id found in gv_prop_table.
  145. *So this hash table is here just to retrieval of a property id
  146. *from a property name.
  147. */
  148. static GHashTable *gv_prop_hash = NULL;
  149. /**
  150. *incremented by each new instance of #CRStyle
  151. *and decremented at the it destroy time.
  152. *When this reaches zero, gv_prop_hash is destroyed.
  153. */
  154. static gulong gv_prop_hash_ref_count = 0;
  155. struct CRNumPropEnumDumpInfo {
  156. enum CRNumProp code;
  157. const gchar *str;
  158. };
  159. static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = {
  160. {NUM_PROP_TOP, "top"},
  161. {NUM_PROP_RIGHT, "right"},
  162. {NUM_PROP_BOTTOM, "bottom"},
  163. {NUM_PROP_LEFT, "left"},
  164. {NUM_PROP_PADDING_TOP, "padding-top"},
  165. {NUM_PROP_PADDING_RIGHT, "padding-right"},
  166. {NUM_PROP_PADDING_BOTTOM, "padding-bottom"},
  167. {NUM_PROP_PADDING_LEFT, "padding-left"},
  168. {NUM_PROP_BORDER_TOP, "border-top"},
  169. {NUM_PROP_BORDER_RIGHT, "border-right"},
  170. {NUM_PROP_BORDER_BOTTOM, "border-bottom"},
  171. {NUM_PROP_BORDER_LEFT, "border-left"},
  172. {NUM_PROP_MARGIN_TOP, "margin-top"},
  173. {NUM_PROP_MARGIN_RIGHT, "margin-right"},
  174. {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"},
  175. {NUM_PROP_MARGIN_LEFT, "margin-left"},
  176. {NUM_PROP_WIDTH, "width"},
  177. {0, NULL}
  178. };
  179. struct CRRgbPropEnumDumpInfo {
  180. enum CRRgbProp code;
  181. const gchar *str;
  182. };
  183. static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = {
  184. {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"},
  185. {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"},
  186. {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"},
  187. {RGB_PROP_BORDER_LEFT_COLOR, "left-color"},
  188. {RGB_PROP_COLOR, "color"},
  189. {RGB_PROP_BACKGROUND_COLOR, "background-color"},
  190. {0, NULL}
  191. };
  192. struct CRBorderStylePropEnumDumpInfo {
  193. enum CRBorderStyleProp code;
  194. const gchar *str;
  195. };
  196. static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[]
  197. = {
  198. {BORDER_STYLE_PROP_TOP, "border-style-top"},
  199. {BORDER_STYLE_PROP_RIGHT, "border-style-right"},
  200. {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"},
  201. {BORDER_STYLE_PROP_LEFT, "border-style-left"},
  202. {0, NULL}
  203. };
  204. static enum CRStatus
  205. cr_style_init_properties (void);
  206. enum CRDirection {
  207. DIR_TOP = 0,
  208. DIR_RIGHT,
  209. DIR_BOTTOM,
  210. DIR_LEFT,
  211. /*must be the last one */
  212. NB_DIRS
  213. };
  214. static const gchar *num_prop_code_to_string (enum CRNumProp a_code);
  215. static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code);
  216. static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp
  217. a_code);
  218. static enum CRStatus
  219. set_prop_padding_x_from_value (CRStyle * a_style,
  220. CRTerm * a_value, enum CRDirection a_dir);
  221. static enum CRStatus
  222. set_prop_border_x_width_from_value (CRStyle * a_style,
  223. CRTerm * a_value,
  224. enum CRDirection a_dir);
  225. static enum CRStatus
  226. set_prop_border_width_from_value (CRStyle *a_style,
  227. CRTerm *a_value) ;
  228. static enum CRStatus
  229. set_prop_border_x_style_from_value (CRStyle * a_style,
  230. CRTerm * a_value,
  231. enum CRDirection a_dir);
  232. static enum CRStatus
  233. set_prop_border_style_from_value (CRStyle *a_style,
  234. CRTerm *a_value) ;
  235. static enum CRStatus
  236. set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
  237. enum CRDirection a_dir);
  238. static enum CRStatus
  239. set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value);
  240. static enum CRStatus
  241. set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value);
  242. static enum CRStatus
  243. set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
  244. enum CRDirection a_dir);
  245. static enum CRStatus
  246. set_prop_float (CRStyle * a_style, CRTerm * a_value);
  247. static enum CRStatus
  248. set_prop_width (CRStyle * a_style, CRTerm * a_value);
  249. static enum CRStatus
  250. set_prop_color (CRStyle * a_style, CRTerm * a_value);
  251. static enum CRStatus
  252. set_prop_background_color (CRStyle * a_style, CRTerm * a_value);
  253. static enum CRStatus
  254. set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
  255. enum CRDirection a_dir);
  256. static enum CRStatus
  257. set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
  258. enum CRDirection a_dir);
  259. static enum CRStatus
  260. set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value);
  261. static enum CRStatus
  262. set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value);
  263. static enum CRStatus
  264. set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value);
  265. static enum CRStatus
  266. set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value);
  267. static enum CRStatus
  268. init_style_font_size_field (CRStyle * a_style);
  269. static enum CRStatus
  270. set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value);
  271. static enum CRStatus
  272. set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value);
  273. static enum CRStatus
  274. set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value);
  275. static const gchar *
  276. num_prop_code_to_string (enum CRNumProp a_code)
  277. {
  278. gint len = sizeof (gv_num_props_dump_infos) /
  279. sizeof (struct CRNumPropEnumDumpInfo);
  280. if (a_code >= len) {
  281. cr_utils_trace_info ("A field has been added "
  282. "to 'enum CRNumProp' and no matching"
  283. " entry has been "
  284. "added to gv_num_prop_dump_infos table.\n"
  285. "Please add the missing matching entry");
  286. return NULL;
  287. }
  288. if (gv_num_props_dump_infos[a_code].code != a_code) {
  289. cr_utils_trace_info ("mismatch between the order of fields in"
  290. " 'enum CRNumProp' and "
  291. "the order of entries in "
  292. "the gv_num_prop_dump_infos table");
  293. return NULL;
  294. }
  295. return gv_num_props_dump_infos[a_code].str;
  296. }
  297. static const gchar *
  298. rgb_prop_code_to_string (enum CRRgbProp a_code)
  299. {
  300. gint len = sizeof (gv_rgb_props_dump_infos) /
  301. sizeof (struct CRRgbPropEnumDumpInfo);
  302. if (a_code >= len) {
  303. cr_utils_trace_info ("A field has been added "
  304. "to 'enum CRRgbProp' and no matching"
  305. " entry has been "
  306. "added to gv_rgb_prop_dump_infos table.\n"
  307. "Please add the missing matching entry");
  308. return NULL;
  309. }
  310. if (gv_rgb_props_dump_infos[a_code].code != a_code) {
  311. cr_utils_trace_info ("mismatch between the order of fields in"
  312. " 'enum CRRgbProp' and "
  313. "the order of entries in "
  314. "the gv_rgb_props_dump_infos table");
  315. return NULL;
  316. }
  317. return gv_rgb_props_dump_infos[a_code].str;
  318. }
  319. static const gchar *
  320. border_style_prop_code_to_string (enum CRBorderStyleProp a_code)
  321. {
  322. gint len = sizeof (gv_border_style_props_dump_infos) /
  323. sizeof (struct CRBorderStylePropEnumDumpInfo);
  324. if (a_code >= len) {
  325. cr_utils_trace_info ("A field has been added "
  326. "to 'enum CRBorderStyleProp' and no matching"
  327. " entry has been "
  328. "added to gv_border_style_prop_dump_infos table.\n"
  329. "Please add the missing matching entry");
  330. return NULL;
  331. }
  332. if (gv_border_style_props_dump_infos[a_code].code != a_code) {
  333. cr_utils_trace_info ("mismatch between the order of fields in"
  334. " 'enum CRBorderStyleProp' and "
  335. "the order of entries in "
  336. "the gv_border_style_props_dump_infos table");
  337. return NULL;
  338. }
  339. return gv_border_style_props_dump_infos[a_code].str;
  340. }
  341. static enum CRStatus
  342. cr_style_init_properties (void)
  343. {
  344. if (!gv_prop_hash) {
  345. gulong i = 0;
  346. gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal);
  347. if (!gv_prop_hash) {
  348. cr_utils_trace_info ("Out of memory");
  349. return CR_ERROR;
  350. }
  351. /*load gv_prop_hash from gv_prop_table */
  352. for (i = 0; gv_prop_table[i].name; i++) {
  353. g_hash_table_insert
  354. (gv_prop_hash,
  355. (gpointer) gv_prop_table[i].name,
  356. GINT_TO_POINTER (gv_prop_table[i].prop_id));
  357. }
  358. }
  359. return CR_OK;
  360. }
  361. static enum CRPropertyID
  362. cr_style_get_prop_id (const guchar * a_prop)
  363. {
  364. gpointer *raw_id = NULL;
  365. if (!gv_prop_hash) {
  366. cr_style_init_properties ();
  367. }
  368. raw_id = g_hash_table_lookup (gv_prop_hash, a_prop);
  369. if (!raw_id) {
  370. return PROP_ID_NOT_KNOWN;
  371. }
  372. return GPOINTER_TO_INT (raw_id);
  373. }
  374. static enum CRStatus
  375. set_prop_padding_x_from_value (CRStyle * a_style,
  376. CRTerm * a_value, enum CRDirection a_dir)
  377. {
  378. enum CRStatus status = CR_OK;
  379. CRNum *num_val = NULL;
  380. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  381. if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT)
  382. return CR_BAD_PARAM_ERROR;
  383. switch (a_dir) {
  384. case DIR_TOP:
  385. num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv;
  386. break;
  387. case DIR_RIGHT:
  388. num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv;
  389. break;
  390. case DIR_BOTTOM:
  391. num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv;
  392. break;
  393. case DIR_LEFT:
  394. num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv;
  395. break;
  396. default:
  397. return CR_BAD_PARAM_ERROR;
  398. }
  399. if (a_value->type == TERM_IDENT) {
  400. if (a_value->content.str
  401. && a_value->content.str->stryng
  402. && a_value->content.str->stryng->str
  403. && !strncmp ((guchar *) "inherit",
  404. a_value->content.str->stryng->str,
  405. sizeof ("inherit")-1)) {
  406. status = cr_num_set (num_val, 0.0, NUM_INHERIT);
  407. return CR_OK;
  408. } else
  409. return CR_UNKNOWN_TYPE_ERROR;
  410. }
  411. g_return_val_if_fail (a_value->type == TERM_NUMBER
  412. && a_value->content.num, CR_UNKNOWN_TYPE_ERROR);
  413. switch (a_value->content.num->type) {
  414. case NUM_LENGTH_EM:
  415. case NUM_LENGTH_EX:
  416. case NUM_LENGTH_PX:
  417. case NUM_LENGTH_IN:
  418. case NUM_LENGTH_CM:
  419. case NUM_LENGTH_MM:
  420. case NUM_LENGTH_PT:
  421. case NUM_LENGTH_PC:
  422. case NUM_PERCENTAGE:
  423. status = cr_num_copy (num_val, a_value->content.num);
  424. break;
  425. default:
  426. status = CR_UNKNOWN_TYPE_ERROR;
  427. break;
  428. }
  429. return status;
  430. }
  431. static enum CRStatus
  432. set_prop_border_x_width_from_value (CRStyle * a_style,
  433. CRTerm * a_value,
  434. enum CRDirection a_dir)
  435. {
  436. enum CRStatus status = CR_OK;
  437. CRNum *num_val = NULL;
  438. g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR);
  439. switch (a_dir) {
  440. case DIR_TOP:
  441. num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv;
  442. break;
  443. case DIR_RIGHT:
  444. num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv;
  445. break;
  446. case DIR_BOTTOM:
  447. num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv;
  448. break;
  449. case DIR_LEFT:
  450. num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv;
  451. break;
  452. default:
  453. return CR_BAD_PARAM_ERROR;
  454. break;
  455. }
  456. if (a_value->type == TERM_IDENT) {
  457. if (a_value->content.str
  458. && a_value->content.str->stryng
  459. && a_value->content.str->stryng->str) {
  460. if (!strncmp ("thin",
  461. a_value->content.str->stryng->str,
  462. sizeof ("thin")-1)) {
  463. cr_num_set (num_val, BORDER_THIN,
  464. NUM_LENGTH_PX);
  465. } else if (!strncmp
  466. ("medium",
  467. a_value->content.str->stryng->str,
  468. sizeof ("medium")-1)) {
  469. cr_num_set (num_val, BORDER_MEDIUM,
  470. NUM_LENGTH_PX);
  471. } else if (!strncmp ("thick",
  472. a_value->content.str->stryng->str,
  473. sizeof ("thick")-1)) {
  474. cr_num_set (num_val, BORDER_THICK,
  475. NUM_LENGTH_PX);
  476. } else {
  477. return CR_UNKNOWN_TYPE_ERROR;
  478. }
  479. }
  480. } else if (a_value->type == TERM_NUMBER) {
  481. if (a_value->content.num) {
  482. cr_num_copy (num_val, a_value->content.num);
  483. }
  484. } else if (a_value->type != TERM_NUMBER
  485. || a_value->content.num == NULL) {
  486. return CR_UNKNOWN_TYPE_ERROR;
  487. }
  488. return status;
  489. }
  490. static enum CRStatus
  491. set_prop_border_width_from_value (CRStyle *a_style,
  492. CRTerm *a_value)
  493. {
  494. CRTerm *cur_term = NULL ;
  495. enum CRDirection direction = DIR_TOP ;
  496. g_return_val_if_fail (a_style && a_value,
  497. CR_BAD_PARAM_ERROR) ;
  498. cur_term = a_value ;
  499. if (!cur_term)
  500. return CR_ERROR ;
  501. for (direction = DIR_TOP ;
  502. direction < NB_DIRS ; direction ++) {
  503. set_prop_border_x_width_from_value (a_style,
  504. cur_term,
  505. direction) ;
  506. }
  507. cur_term = cur_term->next ;
  508. if (!cur_term)
  509. return CR_OK ;
  510. set_prop_border_x_width_from_value (a_style, cur_term,
  511. DIR_RIGHT) ;
  512. set_prop_border_x_width_from_value (a_style, cur_term,
  513. DIR_LEFT) ;
  514. cur_term = cur_term->next ;
  515. if (!cur_term)
  516. return CR_OK ;
  517. set_prop_border_x_width_from_value (a_style, cur_term,
  518. DIR_BOTTOM) ;
  519. cur_term = cur_term->next ;
  520. if (!cur_term)
  521. return CR_OK ;
  522. set_prop_border_x_width_from_value (a_style, cur_term,
  523. DIR_LEFT) ;
  524. return CR_OK ;
  525. }
  526. static enum CRStatus
  527. set_prop_border_x_style_from_value (CRStyle * a_style,
  528. CRTerm * a_value, enum CRDirection a_dir)
  529. {
  530. enum CRStatus status = CR_OK;
  531. enum CRBorderStyle *border_style_ptr = NULL;
  532. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  533. switch (a_dir) {
  534. case DIR_TOP:
  535. border_style_ptr = &a_style->
  536. border_style_props[BORDER_STYLE_PROP_TOP];
  537. break;
  538. case DIR_RIGHT:
  539. border_style_ptr =
  540. &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT];
  541. break;
  542. case DIR_BOTTOM:
  543. border_style_ptr = &a_style->
  544. border_style_props[BORDER_STYLE_PROP_BOTTOM];
  545. break;
  546. case DIR_LEFT:
  547. border_style_ptr = &a_style->
  548. border_style_props[BORDER_STYLE_PROP_LEFT];
  549. break;
  550. default:
  551. break;
  552. }
  553. if (a_value->type != TERM_IDENT || !a_value->content.str) {
  554. return CR_UNKNOWN_TYPE_ERROR;
  555. }
  556. if (!strncmp ("none",
  557. a_value->content.str->stryng->str,
  558. sizeof ("none")-1)) {
  559. *border_style_ptr = BORDER_STYLE_NONE;
  560. } else if (!strncmp ("hidden",
  561. a_value->content.str->stryng->str,
  562. sizeof ("hidden")-1)) {
  563. *border_style_ptr = BORDER_STYLE_HIDDEN;
  564. } else if (!strncmp ("dotted",
  565. a_value->content.str->stryng->str,
  566. sizeof ("dotted")-1)) {
  567. *border_style_ptr = BORDER_STYLE_DOTTED;
  568. } else if (!strncmp ("dashed",
  569. a_value->content.str->stryng->str, sizeof ("dashed")-1)) {
  570. *border_style_ptr = BORDER_STYLE_DASHED;
  571. } else if (!strncmp ("solid",
  572. a_value->content.str->stryng->str, sizeof ("solid")-1)) {
  573. *border_style_ptr = BORDER_STYLE_SOLID;
  574. } else if (!strncmp ("double",
  575. a_value->content.str->stryng->str, sizeof ("double")-1)) {
  576. *border_style_ptr = BORDER_STYLE_DOUBLE;
  577. } else if (!strncmp ("groove",
  578. a_value->content.str->stryng->str, sizeof ("groove")-1)) {
  579. *border_style_ptr = BORDER_STYLE_GROOVE;
  580. } else if (!strncmp ("ridge",
  581. a_value->content.str->stryng->str,
  582. sizeof ("ridge")-1)) {
  583. *border_style_ptr = BORDER_STYLE_RIDGE;
  584. } else if (!strncmp ("inset",
  585. a_value->content.str->stryng->str,
  586. sizeof ("inset")-1)) {
  587. *border_style_ptr = BORDER_STYLE_INSET;
  588. } else if (!strncmp ("outset",
  589. a_value->content.str->stryng->str,
  590. sizeof ("outset")-1)) {
  591. *border_style_ptr = BORDER_STYLE_OUTSET;
  592. } else if (!strncmp ("inherit",
  593. a_value->content.str->stryng->str,
  594. sizeof ("inherit")-1)) {
  595. *border_style_ptr = BORDER_STYLE_INHERIT;
  596. } else {
  597. status = CR_UNKNOWN_TYPE_ERROR;
  598. }
  599. return status;
  600. }
  601. static enum CRStatus
  602. set_prop_border_style_from_value (CRStyle *a_style,
  603. CRTerm *a_value)
  604. {
  605. CRTerm *cur_term = NULL ;
  606. enum CRDirection direction = DIR_TOP ;
  607. g_return_val_if_fail (a_style && a_value,
  608. CR_BAD_PARAM_ERROR) ;
  609. cur_term = a_value ;
  610. if (!cur_term || cur_term->type != TERM_IDENT) {
  611. return CR_ERROR ;
  612. }
  613. for (direction = DIR_TOP ;
  614. direction < NB_DIRS ;
  615. direction ++) {
  616. set_prop_border_x_style_from_value (a_style,
  617. cur_term,
  618. direction) ;
  619. }
  620. cur_term = cur_term->next ;
  621. if (!cur_term || cur_term->type != TERM_IDENT) {
  622. return CR_OK ;
  623. }
  624. set_prop_border_x_style_from_value (a_style, cur_term,
  625. DIR_RIGHT) ;
  626. set_prop_border_x_style_from_value (a_style, cur_term,
  627. DIR_LEFT) ;
  628. cur_term = cur_term->next ;
  629. if (!cur_term || cur_term->type != TERM_IDENT) {
  630. return CR_OK ;
  631. }
  632. set_prop_border_x_style_from_value (a_style, cur_term,
  633. DIR_BOTTOM) ;
  634. cur_term = cur_term->next ;
  635. if (!cur_term || cur_term->type != TERM_IDENT) {
  636. return CR_OK ;
  637. }
  638. set_prop_border_x_style_from_value (a_style, cur_term,
  639. DIR_LEFT) ;
  640. return CR_OK ;
  641. }
  642. static enum CRStatus
  643. set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value,
  644. enum CRDirection a_dir)
  645. {
  646. enum CRStatus status = CR_OK;
  647. CRNum *num_val = NULL;
  648. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  649. switch (a_dir) {
  650. case DIR_TOP:
  651. num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv;
  652. break;
  653. case DIR_RIGHT:
  654. num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv;
  655. break;
  656. case DIR_BOTTOM:
  657. num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv;
  658. break;
  659. case DIR_LEFT:
  660. num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv;
  661. break;
  662. default:
  663. break;
  664. }
  665. switch (a_value->type) {
  666. case TERM_IDENT:
  667. if (a_value->content.str
  668. && a_value->content.str->stryng
  669. && a_value->content.str->stryng->str
  670. && !strcmp (a_value->content.str->stryng->str,
  671. "inherit")) {
  672. status = cr_num_set (num_val, 0.0, NUM_INHERIT);
  673. } else if (a_value->content.str
  674. && a_value->content.str->stryng
  675. && !strcmp (a_value->content.str->stryng->str,
  676. "auto")) {
  677. status = cr_num_set (num_val, 0.0, NUM_AUTO);
  678. } else {
  679. status = CR_UNKNOWN_TYPE_ERROR;
  680. }
  681. break ;
  682. case TERM_NUMBER:
  683. status = cr_num_copy (num_val, a_value->content.num);
  684. break;
  685. default:
  686. status = CR_UNKNOWN_TYPE_ERROR;
  687. break;
  688. }
  689. return status;
  690. }
  691. struct CRPropDisplayValPair {
  692. const guchar *prop_name;
  693. enum CRDisplayType type;
  694. };
  695. static enum CRStatus
  696. set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value)
  697. {
  698. static const struct CRPropDisplayValPair disp_vals_map[] = {
  699. {"none", DISPLAY_NONE},
  700. {"inline", DISPLAY_INLINE},
  701. {"block", DISPLAY_BLOCK},
  702. {"run-in", DISPLAY_RUN_IN},
  703. {"compact", DISPLAY_COMPACT},
  704. {"marker", DISPLAY_MARKER},
  705. {"table", DISPLAY_TABLE},
  706. {"inline-table", DISPLAY_INLINE_TABLE},
  707. {"table-row-group", DISPLAY_TABLE_ROW_GROUP},
  708. {"table-header-group", DISPLAY_TABLE_HEADER_GROUP},
  709. {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP},
  710. {"table-row", DISPLAY_TABLE_ROW},
  711. {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP},
  712. {"table-column", DISPLAY_TABLE_COLUMN},
  713. {"table-cell", DISPLAY_TABLE_CELL},
  714. {"table-caption", DISPLAY_TABLE_CAPTION},
  715. {"inherit", DISPLAY_INHERIT},
  716. {NULL, DISPLAY_NONE}
  717. };
  718. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  719. switch (a_value->type) {
  720. case TERM_IDENT:
  721. {
  722. int i = 0;
  723. if (!a_value->content.str
  724. || !a_value->content.str->stryng
  725. || !a_value->content.str->stryng->str)
  726. break;
  727. for (i = 0; disp_vals_map[i].prop_name; i++) {
  728. if (!strncmp
  729. (disp_vals_map[i].prop_name,
  730. a_value->content.str->stryng->str,
  731. strlen (disp_vals_map[i].prop_name))) {
  732. a_style->display =
  733. disp_vals_map[i].type;
  734. break;
  735. }
  736. }
  737. }
  738. break;
  739. default:
  740. break;
  741. }
  742. return CR_OK;
  743. }
  744. struct CRPropPositionValPair {
  745. const guchar *name;
  746. enum CRPositionType type;
  747. };
  748. static enum CRStatus
  749. set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value)
  750. {
  751. enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR;
  752. static const struct CRPropPositionValPair position_vals_map[] = {
  753. {"static", POSITION_STATIC},
  754. {"relative", POSITION_RELATIVE},
  755. {"absolute", POSITION_ABSOLUTE},
  756. {"fixed", POSITION_FIXED},
  757. {"inherit", POSITION_INHERIT},
  758. {NULL, POSITION_STATIC}
  759. /*must alwas be the last one */
  760. };
  761. g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR);
  762. switch (a_value->type) {
  763. case TERM_IDENT:
  764. {
  765. int i = 0;
  766. if (!a_value->content.str
  767. || !a_value->content.str->stryng
  768. || !a_value->content.str->stryng->str)
  769. break;
  770. for (i = 0; position_vals_map[i].name; i++) {
  771. if (!strncmp (position_vals_map[i].name,
  772. a_value->content.str->stryng->str,
  773. strlen (position_vals_map[i].
  774. name))) {
  775. a_style->position =
  776. position_vals_map[i].type;
  777. status = CR_OK;
  778. break;
  779. }
  780. }
  781. }
  782. break;
  783. default:
  784. break;
  785. }
  786. return CR_OK;
  787. }
  788. static enum CRStatus
  789. set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value,
  790. enum CRDirection a_dir)
  791. {
  792. CRNum *box_offset = NULL;
  793. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  794. if (!(a_value->type == TERM_NUMBER)
  795. && !(a_value->type == TERM_IDENT)) {
  796. return CR_UNKNOWN_PROP_VAL_ERROR;
  797. }
  798. switch (a_dir) {
  799. case DIR_TOP:
  800. box_offset = &a_style->num_props[NUM_PROP_TOP].sv;
  801. break;
  802. case DIR_RIGHT:
  803. box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv;
  804. break;
  805. case DIR_BOTTOM:
  806. box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv;
  807. break;
  808. case DIR_LEFT:
  809. box_offset = &a_style->num_props[NUM_PROP_LEFT].sv;
  810. break;
  811. default:
  812. break;
  813. }
  814. box_offset->type = NUM_AUTO;
  815. if (a_value->type == TERM_NUMBER && a_value->content.num) {
  816. cr_num_copy (box_offset, a_value->content.num);
  817. } else if (a_value->type == TERM_IDENT
  818. && a_value->content.str
  819. && a_value->content.str->stryng
  820. && a_value->content.str->stryng->str) {
  821. if (!strncmp ("inherit",
  822. a_value->content.str->stryng->str,
  823. sizeof ("inherit")-1)) {
  824. cr_num_set (box_offset, 0.0, NUM_INHERIT);
  825. } else if (!strncmp ("auto",
  826. a_value->content.str->stryng->str,
  827. sizeof ("auto")-1)) {
  828. box_offset->type = NUM_AUTO;
  829. }
  830. }
  831. return CR_OK;
  832. }
  833. static enum CRStatus
  834. set_prop_float (CRStyle * a_style, CRTerm * a_value)
  835. {
  836. g_return_val_if_fail (a_style && a_value,
  837. CR_BAD_PARAM_ERROR);
  838. /*the default float type as specified by the css2 spec */
  839. a_style->float_type = FLOAT_NONE;
  840. if (a_value->type != TERM_IDENT
  841. || !a_value->content.str
  842. || !a_value->content.str->stryng
  843. || !a_value->content.str->stryng->str) {
  844. /*unknow type, the float type is set to it's default value */
  845. return CR_OK;
  846. }
  847. if (!strncmp ("none",
  848. a_value->content.str->stryng->str,
  849. sizeof ("none")-1)) {
  850. a_style->float_type = FLOAT_NONE;
  851. } else if (!strncmp ("left",
  852. a_value->content.str->stryng->str,
  853. sizeof ("left")-1)) {
  854. a_style->float_type = FLOAT_LEFT;
  855. } else if (!strncmp ("right",
  856. a_value->content.str->stryng->str,
  857. sizeof ("right")-1)) {
  858. a_style->float_type = FLOAT_RIGHT;
  859. } else if (!strncmp ("inherit",
  860. a_value->content.str->stryng->str,
  861. sizeof ("inherit")-1)) {
  862. a_style->float_type = FLOAT_INHERIT;
  863. }
  864. return CR_OK;
  865. }
  866. static enum CRStatus
  867. set_prop_width (CRStyle * a_style, CRTerm * a_value)
  868. {
  869. CRNum *width = NULL;
  870. g_return_val_if_fail (a_style
  871. && a_value,
  872. CR_BAD_PARAM_ERROR);
  873. width = &a_style->num_props[NUM_PROP_WIDTH].sv;
  874. cr_num_set (width, 0.0, NUM_AUTO);
  875. if (a_value->type == TERM_IDENT) {
  876. if (a_value->content.str
  877. && a_value->content.str->stryng
  878. && a_value->content.str->stryng->str) {
  879. if (!strncmp ("auto",
  880. a_value->content.str->stryng->str,
  881. sizeof ("auto")-1)) {
  882. cr_num_set (width, 0.0, NUM_AUTO);
  883. } else if (!strncmp ("inherit",
  884. a_value->content.str->stryng->str,
  885. sizeof ("inherit")-1)) {
  886. cr_num_set (width, 0.0, NUM_INHERIT);
  887. }
  888. }
  889. } else if (a_value->type == TERM_NUMBER) {
  890. if (a_value->content.num) {
  891. cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv,
  892. a_value->content.num);
  893. }
  894. }
  895. return CR_OK;
  896. }
  897. static enum CRStatus
  898. set_prop_color (CRStyle * a_style, CRTerm * a_value)
  899. {
  900. enum CRStatus status = CR_OK;
  901. CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv;
  902. g_return_val_if_fail (a_style
  903. && a_value, CR_BAD_PARAM_ERROR);
  904. status = cr_rgb_set_from_term (a_rgb, a_value);
  905. return status;
  906. }
  907. static enum CRStatus
  908. set_prop_background_color (CRStyle * a_style, CRTerm * a_value)
  909. {
  910. enum CRStatus status = CR_OK;
  911. CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv;
  912. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  913. status = cr_rgb_set_from_term (rgb, a_value);
  914. return status;
  915. }
  916. /**
  917. *Sets border-top-color, border-right-color,
  918. *border-bottom-color or border-left-color properties
  919. *in the style structure. The value is taken from a
  920. *css2 term of type IDENT or RGB.
  921. *@param a_style the style structure to set.
  922. *@param a_value the css2 term to take the color information from.
  923. *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM).
  924. *@return CR_OK upon successfull completion, an error code otherwise.
  925. */
  926. static enum CRStatus
  927. set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value,
  928. enum CRDirection a_dir)
  929. {
  930. CRRgb *rgb_color = NULL;
  931. enum CRStatus status = CR_OK;
  932. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  933. switch (a_dir) {
  934. case DIR_TOP:
  935. rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv;
  936. break;
  937. case DIR_RIGHT:
  938. rgb_color =
  939. &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv;
  940. break;
  941. case DIR_BOTTOM:
  942. rgb_color =
  943. &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv;
  944. break;
  945. case DIR_LEFT:
  946. rgb_color =
  947. &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv;
  948. break;
  949. default:
  950. cr_utils_trace_info ("unknown DIR type");
  951. return CR_BAD_PARAM_ERROR;
  952. }
  953. status = CR_UNKNOWN_PROP_VAL_ERROR;
  954. if (a_value->type == TERM_IDENT) {
  955. if (a_value->content.str
  956. && a_value->content.str->stryng
  957. && a_value->content.str->stryng->str) {
  958. status = cr_rgb_set_from_name
  959. (rgb_color,
  960. a_value->content.str->stryng->str);
  961. }
  962. if (status != CR_OK) {
  963. cr_rgb_set_from_name (rgb_color, "black");
  964. }
  965. } else if (a_value->type == TERM_RGB) {
  966. if (a_value->content.rgb) {
  967. status = cr_rgb_set_from_rgb
  968. (rgb_color, a_value->content.rgb);
  969. }
  970. }
  971. return status;
  972. }
  973. static enum CRStatus
  974. set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value,
  975. enum CRDirection a_dir)
  976. {
  977. CRTerm *cur_term = NULL;
  978. enum CRStatus status = CR_OK;
  979. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  980. for (cur_term = a_value;
  981. cur_term;
  982. cur_term = cur_term->next) {
  983. status = set_prop_border_x_width_from_value (a_style,
  984. cur_term, a_dir);
  985. if (status != CR_OK) {
  986. status = set_prop_border_x_style_from_value
  987. (a_style, cur_term, a_dir);
  988. }
  989. if (status != CR_OK) {
  990. status = set_prop_border_x_color_from_value
  991. (a_style, cur_term, a_dir);
  992. }
  993. }
  994. return CR_OK;
  995. }
  996. static enum CRStatus
  997. set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value)
  998. {
  999. enum CRDirection direction = 0;
  1000. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1001. for (direction = 0; direction < NB_DIRS; direction++) {
  1002. set_prop_border_x_from_value (a_style,
  1003. a_value,
  1004. direction);
  1005. }
  1006. return CR_OK;
  1007. }
  1008. static enum CRStatus
  1009. set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value)
  1010. {
  1011. CRTerm *cur_term = NULL;
  1012. enum CRDirection direction = 0;
  1013. enum CRStatus status = CR_OK;
  1014. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1015. cur_term = a_value;
  1016. /*filter the eventual non NUMBER terms some user can have written here*/
  1017. while (cur_term && cur_term->type != TERM_NUMBER) {
  1018. cur_term = cur_term->next;
  1019. }
  1020. if (!cur_term)
  1021. return CR_ERROR ;
  1022. for (direction = 0; direction < NB_DIRS; direction++) {
  1023. set_prop_padding_x_from_value (a_style, cur_term, direction);
  1024. }
  1025. cur_term = cur_term->next;
  1026. /*filter non NUMBER terms that some users can have written here...*/
  1027. while (cur_term && cur_term->type != TERM_NUMBER) {
  1028. cur_term = cur_term->next;
  1029. }
  1030. /*the user can have just written padding: 1px*/
  1031. if (!cur_term)
  1032. return CR_OK;
  1033. set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT);
  1034. set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
  1035. while (cur_term && cur_term->type != TERM_NUMBER) {
  1036. cur_term = cur_term->next;
  1037. }
  1038. if (!cur_term)
  1039. return CR_OK;
  1040. set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM);
  1041. while (cur_term && cur_term->type != TERM_NUMBER) {
  1042. cur_term = cur_term->next;
  1043. }
  1044. if (!cur_term)
  1045. return CR_OK;
  1046. status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT);
  1047. return status;
  1048. }
  1049. static enum CRStatus
  1050. set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value)
  1051. {
  1052. CRTerm *cur_term = NULL;
  1053. enum CRDirection direction = 0;
  1054. enum CRStatus status = CR_OK;
  1055. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1056. cur_term = a_value;
  1057. while (cur_term && cur_term->type != TERM_NUMBER) {
  1058. cur_term = cur_term->next;
  1059. }
  1060. if (!cur_term)
  1061. return CR_OK;
  1062. for (direction = 0; direction < NB_DIRS; direction++) {
  1063. set_prop_margin_x_from_value (a_style, cur_term, direction);
  1064. }
  1065. cur_term = cur_term->next;
  1066. while (cur_term && cur_term->type != TERM_NUMBER) {
  1067. cur_term = cur_term->next;
  1068. }
  1069. if (!cur_term)
  1070. return CR_OK;
  1071. set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT);
  1072. set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
  1073. while (cur_term && cur_term->type != TERM_NUMBER) {
  1074. cur_term = cur_term->next;
  1075. }
  1076. if (!cur_term)
  1077. return CR_OK;
  1078. set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM);
  1079. while (cur_term && cur_term->type != TERM_NUMBER) {
  1080. cur_term = cur_term->next;
  1081. }
  1082. if (!cur_term)
  1083. return CR_OK;
  1084. status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT);
  1085. return status;
  1086. }
  1087. static enum CRStatus
  1088. set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value)
  1089. {
  1090. CRTerm *cur_term = NULL;
  1091. CRFontFamily *font_family = NULL,
  1092. *cur_ff = NULL,
  1093. *cur_ff2 = NULL;
  1094. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1095. if (a_value->type == TERM_IDENT &&
  1096. a_value->content.str &&
  1097. a_value->content.str->stryng &&
  1098. a_value->content.str->stryng->str &&
  1099. !strcmp ("inherit", a_value->content.str->stryng->str))
  1100. {
  1101. font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL);
  1102. goto out;
  1103. }
  1104. for (cur_term = a_value; cur_term; cur_term = cur_term->next) {
  1105. switch (cur_term->type) {
  1106. case TERM_IDENT:
  1107. {
  1108. enum CRFontFamilyType font_type;
  1109. if (cur_term->content.str
  1110. && cur_term->content.str->stryng
  1111. && cur_term->content.str->stryng->str
  1112. && !strcmp
  1113. (cur_term->content.str->stryng->str,
  1114. "sans-serif")) {
  1115. font_type = FONT_FAMILY_SANS_SERIF;
  1116. } else if (cur_term->content.str
  1117. && cur_term->content.str->stryng
  1118. && cur_term->content.str->stryng->str
  1119. && !strcmp
  1120. (cur_term->content.str->stryng->str,
  1121. "serif")) {
  1122. font_type = FONT_FAMILY_SERIF;
  1123. } else if (cur_term->content.str
  1124. && cur_term->content.str->stryng
  1125. && cur_term->content.str->stryng->str
  1126. && !strcmp (cur_term->content.str->stryng->str,
  1127. "cursive")) {
  1128. font_type = FONT_FAMILY_CURSIVE;
  1129. } else if (cur_term->content.str
  1130. && cur_term->content.str->stryng
  1131. && cur_term->content.str->stryng->str
  1132. && !strcmp (cur_term->content.str->stryng->str,
  1133. "fantasy")) {
  1134. font_type = FONT_FAMILY_FANTASY;
  1135. } else if (cur_term->content.str
  1136. && cur_term->content.str->stryng
  1137. && cur_term->content.str->stryng->str
  1138. && !strcmp (cur_term->content.str->stryng->str,
  1139. "monospace")) {
  1140. font_type = FONT_FAMILY_MONOSPACE;
  1141. } else {
  1142. /*
  1143. *unknown property value.
  1144. *ignore it.
  1145. */
  1146. continue;
  1147. }
  1148. cur_ff = cr_font_family_new (font_type, NULL);
  1149. }
  1150. break;
  1151. case TERM_STRING:
  1152. {
  1153. if (cur_term->content.str
  1154. && cur_term->content.str->stryng
  1155. && cur_term->content.str->stryng->str) {
  1156. cur_ff = cr_font_family_new
  1157. (FONT_FAMILY_NON_GENERIC,
  1158. cur_term->content.str->stryng->str);
  1159. }
  1160. }
  1161. break;
  1162. default:
  1163. break;
  1164. }
  1165. cur_ff2 = cr_font_family_append (font_family, cur_ff);
  1166. if (cur_ff2) {
  1167. font_family = cur_ff2;
  1168. }
  1169. }
  1170. out:
  1171. if (font_family) {
  1172. if (a_style->font_family) {
  1173. cr_font_family_destroy (a_style->font_family);
  1174. a_style->font_family = NULL ;
  1175. }
  1176. a_style->font_family = font_family;
  1177. font_family = NULL ;
  1178. }
  1179. return CR_OK;
  1180. }
  1181. static enum CRStatus
  1182. init_style_font_size_field (CRStyle * a_style)
  1183. {
  1184. g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR);
  1185. memset (&a_style->font_size, 0,
  1186. sizeof (CRFontSizeVal)) ;
  1187. /*
  1188. if (!a_style->font_size) {
  1189. a_style->font_size = cr_font_size_new ();
  1190. if (!a_style->font_size) {
  1191. return CR_INSTANCIATION_FAILED_ERROR;
  1192. }
  1193. } else {
  1194. cr_font_size_clear (a_style->font_size);
  1195. }
  1196. */
  1197. return CR_OK;
  1198. }
  1199. static enum CRStatus
  1200. set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value)
  1201. {
  1202. enum CRStatus status = CR_OK;
  1203. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1204. switch (a_value->type) {
  1205. case TERM_IDENT:
  1206. if (a_value->content.str
  1207. && a_value->content.str->stryng
  1208. && a_value->content.str->stryng->str
  1209. && !strcmp (a_value->content.str->stryng->str,
  1210. "xx-small")) {
  1211. status = init_style_font_size_field (a_style);
  1212. g_return_val_if_fail (status == CR_OK, status);
  1213. a_style->font_size.sv.type =
  1214. PREDEFINED_ABSOLUTE_FONT_SIZE;
  1215. a_style->font_size.sv.value.predefined =
  1216. FONT_SIZE_XX_SMALL;
  1217. } else if (a_value->content.str
  1218. && a_value->content.str->stryng
  1219. && a_value->content.str->stryng->str
  1220. && !strcmp (a_value->content.str->stryng->str,
  1221. "x-small")) {
  1222. status = init_style_font_size_field (a_style);
  1223. g_return_val_if_fail (status == CR_OK, status);
  1224. a_style->font_size.sv.type =
  1225. PREDEFINED_ABSOLUTE_FONT_SIZE;
  1226. a_style->font_size.sv.value.predefined =
  1227. FONT_SIZE_X_SMALL;
  1228. } else if (a_value->content.str
  1229. && a_value->content.str->stryng
  1230. && a_value->content.str->stryng->str
  1231. && !strcmp (a_value->content.str->stryng->str,
  1232. "small")) {
  1233. status = init_style_font_size_field (a_style);
  1234. g_return_val_if_fail (status == CR_OK, status);
  1235. a_style->font_size.sv.type =
  1236. PREDEFINED_ABSOLUTE_FONT_SIZE;
  1237. a_style->font_size.sv.value.predefined =
  1238. FONT_SIZE_SMALL;
  1239. } else if (a_value->content.str
  1240. && a_value->content.str->stryng
  1241. && a_value->content.str->stryng->str
  1242. && !strcmp (a_value->content.str->stryng->str, "medium")) {
  1243. status = init_style_font_size_field (a_style);
  1244. g_return_val_if_fail (status == CR_OK, status);
  1245. a_style->font_size.sv.type =
  1246. PREDEFINED_ABSOLUTE_FONT_SIZE;
  1247. a_style->font_size.sv.value.predefined =
  1248. FONT_SIZE_MEDIUM;
  1249. } else if (a_value->content.str
  1250. && a_value->content.str->stryng
  1251. && a_value->content.str->stryng->str
  1252. && !strcmp (a_value->content.str->stryng->str,
  1253. "large")) {
  1254. status = init_style_font_size_field (a_style);
  1255. g_return_val_if_fail (status == CR_OK, status);
  1256. a_style->font_size.sv.type =
  1257. PREDEFINED_ABSOLUTE_FONT_SIZE;
  1258. a_style->font_size.sv.value.predefined =
  1259. FONT_SIZE_LARGE;
  1260. } else if (a_value->content.str
  1261. && a_value->content.str->stryng
  1262. && a_value->content.str->stryng->str
  1263. && !strcmp (a_value->content.str->stryng->str,
  1264. "x-large")) {
  1265. status = init_style_font_size_field (a_style);
  1266. g_return_val_if_fail (status == CR_OK, status);
  1267. a_style->font_size.sv.type =
  1268. PREDEFINED_ABSOLUTE_FONT_SIZE;
  1269. a_style->font_size.sv.value.predefined =
  1270. FONT_SIZE_X_LARGE;
  1271. } else if (a_value->content.str
  1272. && a_value->content.str->stryng
  1273. && a_value->content.str->stryng->str
  1274. && !strcmp (a_value->content.str->stryng->str,
  1275. "xx-large")) {
  1276. status = init_style_font_size_field (a_style);
  1277. g_return_val_if_fail (status == CR_OK, status);
  1278. a_style->font_size.sv.type =
  1279. PREDEFINED_ABSOLUTE_FONT_SIZE;
  1280. a_style->font_size.sv.value.predefined =
  1281. FONT_SIZE_XX_LARGE;
  1282. } else if (a_value->content.str
  1283. && a_value->content.str->stryng
  1284. && a_value->content.str->stryng->str
  1285. && !strcmp (a_value->content.str->stryng->str,
  1286. "larger")) {
  1287. status = init_style_font_size_field (a_style);
  1288. g_return_val_if_fail (status == CR_OK, status);
  1289. a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
  1290. a_style->font_size.sv.value.relative = FONT_SIZE_LARGER;
  1291. } else if (a_value->content.str
  1292. && a_value->content.str->stryng
  1293. && a_value->content.str->stryng->str
  1294. && !strcmp (a_value->content.str->stryng->str,
  1295. "smaller")) {
  1296. status = init_style_font_size_field (a_style);
  1297. g_return_val_if_fail (status == CR_OK, status);
  1298. a_style->font_size.sv.type = RELATIVE_FONT_SIZE;
  1299. a_style->font_size.sv.value.relative =
  1300. FONT_SIZE_SMALLER;
  1301. } else if (a_value->content.str
  1302. && a_value->content.str->stryng
  1303. && a_value->content.str->stryng->str
  1304. && !strcmp (a_value->content.str->stryng->str, "inherit")) {
  1305. status = init_style_font_size_field (a_style);
  1306. g_return_val_if_fail (status == CR_OK, status);
  1307. a_style->font_size.sv.type = INHERITED_FONT_SIZE;
  1308. } else {
  1309. cr_utils_trace_info ("Unknow value of font-size") ;
  1310. status = init_style_font_size_field (a_style);
  1311. return CR_UNKNOWN_PROP_VAL_ERROR;
  1312. }
  1313. break;
  1314. case TERM_NUMBER:
  1315. if (a_value->content.num) {
  1316. status = init_style_font_size_field (a_style);
  1317. g_return_val_if_fail (status == CR_OK, status);
  1318. a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE;
  1319. cr_num_copy (&a_style->font_size.sv.value.absolute,
  1320. a_value->content.num) ;
  1321. }
  1322. break;
  1323. default:
  1324. status = init_style_font_size_field (a_style);
  1325. return CR_UNKNOWN_PROP_VAL_ERROR;
  1326. }
  1327. return CR_OK;
  1328. }
  1329. static enum CRStatus
  1330. set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value)
  1331. {
  1332. enum CRStatus status = CR_OK;
  1333. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1334. switch (a_value->type) {
  1335. case TERM_IDENT:
  1336. if (a_value->content.str
  1337. && a_value->content.str->stryng
  1338. && a_value->content.str->stryng->str) {
  1339. if (!strcmp (a_value->content.str->stryng->str, "normal")) {
  1340. a_style->font_style = FONT_STYLE_NORMAL;
  1341. } else if (!strcmp
  1342. (a_value->content.str->stryng->str,
  1343. "italic")) {
  1344. a_style->font_style = FONT_STYLE_ITALIC;
  1345. } else if (!strcmp
  1346. (a_value->content.str->stryng->str,
  1347. "oblique")) {
  1348. a_style->font_style = FONT_STYLE_OBLIQUE;
  1349. } else if (!strcmp
  1350. (a_value->content.str->stryng->str,
  1351. "inherit")) {
  1352. a_style->font_style = FONT_STYLE_INHERIT;
  1353. } else {
  1354. status = CR_UNKNOWN_PROP_VAL_ERROR;
  1355. }
  1356. }
  1357. break;
  1358. default:
  1359. status = CR_UNKNOWN_PROP_VAL_ERROR;
  1360. break;
  1361. }
  1362. return status;
  1363. }
  1364. static enum CRStatus
  1365. set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value)
  1366. {
  1367. enum CRStatus status = CR_OK;
  1368. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1369. switch (a_value->type) {
  1370. case TERM_IDENT:
  1371. if (a_value->content.str
  1372. && a_value->content.str->stryng
  1373. && a_value->content.str->stryng->str) {
  1374. if (!strcmp (a_value->content.str->stryng->str,
  1375. "normal")) {
  1376. a_style->font_weight = FONT_WEIGHT_NORMAL;
  1377. } else if (!strcmp (a_value->content.str->stryng->str,
  1378. "bold")) {
  1379. a_style->font_weight = FONT_WEIGHT_BOLD;
  1380. } else if (!strcmp (a_value->content.str->stryng->str,
  1381. "bolder")) {
  1382. a_style->font_weight = FONT_WEIGHT_BOLDER;
  1383. } else if (!strcmp (a_value->content.str->stryng->str,
  1384. "lighter")) {
  1385. a_style->font_weight = FONT_WEIGHT_LIGHTER;
  1386. } else if (!strcmp (a_value->content.str->stryng->str,
  1387. "inherit")) {
  1388. a_style->font_weight = FONT_WEIGHT_INHERIT;
  1389. } else {
  1390. status = CR_UNKNOWN_PROP_VAL_ERROR;
  1391. }
  1392. }
  1393. break;
  1394. case TERM_NUMBER:
  1395. if (a_value->content.num
  1396. && (a_value->content.num->type == NUM_GENERIC
  1397. || a_value->content.num->type == NUM_AUTO)) {
  1398. if (a_value->content.num->val <= 150) {
  1399. a_style->font_weight = FONT_WEIGHT_100;
  1400. } else if (a_value->content.num->val <= 250) {
  1401. a_style->font_weight = FONT_WEIGHT_200;
  1402. } else if (a_value->content.num->val <= 350) {
  1403. a_style->font_weight = FONT_WEIGHT_300;
  1404. } else if (a_value->content.num->val <= 450) {
  1405. a_style->font_weight = FONT_WEIGHT_400;
  1406. } else if (a_value->content.num->val <= 550) {
  1407. a_style->font_weight = FONT_WEIGHT_500;
  1408. } else if (a_value->content.num->val <= 650) {
  1409. a_style->font_weight = FONT_WEIGHT_600;
  1410. } else if (a_value->content.num->val <= 750) {
  1411. a_style->font_weight = FONT_WEIGHT_700;
  1412. } else if (a_value->content.num->val <= 850) {
  1413. a_style->font_weight = FONT_WEIGHT_800;
  1414. } else {
  1415. a_style->font_weight = FONT_WEIGHT_900;
  1416. }
  1417. }
  1418. break;
  1419. default:
  1420. status = CR_UNKNOWN_PROP_VAL_ERROR;
  1421. break;
  1422. }
  1423. return status;
  1424. }
  1425. static enum CRStatus
  1426. set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value)
  1427. {
  1428. enum CRStatus status = CR_OK;
  1429. g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR);
  1430. switch (a_value->type) {
  1431. case TERM_IDENT:
  1432. if (a_value->content.str && a_value->content.str->stryng) {
  1433. if (!strcmp (a_value->content.str->stryng->str, "normal")) {
  1434. a_style->white_space = WHITE_SPACE_NORMAL;
  1435. } else if (!strcmp (a_value->content.str->stryng->str,
  1436. "pre")) {
  1437. a_style->font_weight = WHITE_SPACE_PRE;
  1438. } else if (!strcmp (a_value->content.str->stryng->str,
  1439. "nowrap")) {
  1440. a_style->white_space = WHITE_SPACE_NOWRAP;
  1441. } else if (!strcmp (a_value->content.str->stryng->str,
  1442. "inherit")) {
  1443. a_style->white_space = WHITE_SPACE_INHERIT;
  1444. } else {
  1445. status = CR_UNKNOWN_PROP_VAL_ERROR;
  1446. }
  1447. }
  1448. break;
  1449. default:
  1450. status = CR_UNKNOWN_PROP_VAL_ERROR;
  1451. break;
  1452. }
  1453. return status;
  1454. }
  1455. /******************
  1456. *Public methods
  1457. ******************/
  1458. /**
  1459. *Default constructor of #CRStyle.
  1460. *@param a_set_props_to_initial_values if TRUE, the style properties
  1461. *will be set to the default values. Only the style properties of the
  1462. *root box should be set to their initial values.
  1463. *Otherwise, the style values are set to their default value.
  1464. *Read the CSS2 spec, chapters 6.1.1 to 6.2.
  1465. */
  1466. CRStyle *
  1467. cr_style_new (gboolean a_set_props_to_initial_values)
  1468. {
  1469. CRStyle *result = NULL;
  1470. result = g_try_malloc (sizeof (CRStyle));
  1471. if (!result) {
  1472. cr_utils_trace_info ("Out of memory");
  1473. return NULL;
  1474. }
  1475. memset (result, 0, sizeof (CRStyle));
  1476. gv_prop_hash_ref_count++;
  1477. if (a_set_props_to_initial_values == TRUE) {
  1478. cr_style_set_props_to_initial_values (result);
  1479. } else {
  1480. cr_style_set_props_to_default_values (result);
  1481. }
  1482. return result;
  1483. }
  1484. /**
  1485. *Sets the style properties to their default values according to the css2 spec
  1486. * i.e inherit if the property is inherited, its initial value otherwise.
  1487. *@param a_this the current instance of #CRStyle.
  1488. *@return CR_OK upon successfull completion, an error code otherwise.
  1489. */
  1490. enum CRStatus
  1491. cr_style_set_props_to_default_values (CRStyle * a_this)
  1492. {
  1493. glong i = 0;
  1494. g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
  1495. for (i = 0; i < NB_NUM_PROPS; i++)
  1496. {
  1497. switch (i)
  1498. {
  1499. case NUM_PROP_WIDTH:
  1500. case NUM_PROP_TOP:
  1501. case NUM_PROP_RIGHT:
  1502. case NUM_PROP_BOTTOM:
  1503. case NUM_PROP_LEFT:
  1504. cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
  1505. break;
  1506. case NUM_PROP_PADDING_TOP:
  1507. case NUM_PROP_PADDING_RIGHT:
  1508. case NUM_PROP_PADDING_BOTTOM:
  1509. case NUM_PROP_PADDING_LEFT:
  1510. case NUM_PROP_BORDER_TOP:
  1511. case NUM_PROP_BORDER_RIGHT:
  1512. case NUM_PROP_BORDER_BOTTOM:
  1513. case NUM_PROP_BORDER_LEFT:
  1514. case NUM_PROP_MARGIN_TOP:
  1515. case NUM_PROP_MARGIN_RIGHT:
  1516. case NUM_PROP_MARGIN_BOTTOM:
  1517. case NUM_PROP_MARGIN_LEFT:
  1518. cr_num_set (&a_this->num_props[i].sv,
  1519. 0, NUM_LENGTH_PX);
  1520. break;
  1521. default:
  1522. cr_utils_trace_info ("Unknown property");
  1523. break;
  1524. }
  1525. }
  1526. for (i = 0; i < NB_RGB_PROPS; i++) {
  1527. switch (i) {
  1528. /*default foreground color is black */
  1529. case RGB_PROP_COLOR:
  1530. /*
  1531. *REVIEW: color is inherited and the default value is
  1532. *ua dependant.
  1533. */
  1534. cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv,
  1535. TRUE) ;
  1536. break;
  1537. /*default background color is white */
  1538. case RGB_PROP_BACKGROUND_COLOR:
  1539. /* TODO: the default value should be transparent */
  1540. cr_rgb_set (&a_this->rgb_props[i].sv,
  1541. 255, 255, 255, FALSE);
  1542. cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
  1543. TRUE) ;
  1544. break;
  1545. default:
  1546. /*
  1547. *TODO: for BORDER_COLOR the initial value should
  1548. * be the same as COLOR
  1549. */
  1550. cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0,
  1551. FALSE);
  1552. break;
  1553. }
  1554. }
  1555. for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
  1556. a_this->border_style_props[i] = BORDER_STYLE_NONE;
  1557. }
  1558. a_this->display = DISPLAY_INLINE;
  1559. a_this->position = POSITION_STATIC;
  1560. a_this->float_type = FLOAT_NONE;
  1561. a_this->parent_style = NULL;
  1562. a_this->font_style = FONT_STYLE_INHERIT;
  1563. a_this->font_variant = FONT_VARIANT_INHERIT;
  1564. a_this->font_weight = FONT_WEIGHT_INHERIT;
  1565. a_this->font_family = NULL;
  1566. cr_font_size_set_to_inherit (&a_this->font_size.sv) ;
  1567. cr_font_size_clear (&a_this->font_size.cv) ;
  1568. cr_font_size_clear (&a_this->font_size.av) ;
  1569. /* To make the inheritance resolution possible and efficient */
  1570. a_this->inherited_props_resolved = FALSE ;
  1571. return CR_OK;
  1572. }
  1573. /**
  1574. *Sets the style properties to their initial value according to the css2 spec.
  1575. *This function should be used to initialize the style of the root element
  1576. *of an xml tree.
  1577. *Some properties are user agent dependant like font-family, and
  1578. *are not initialized, read the spec to make you renderer compliant.
  1579. *@param a_this the current instance of #CRStyle.
  1580. *@return CR_OK upon successfull completion, an error code otherwise.
  1581. */
  1582. enum CRStatus
  1583. cr_style_set_props_to_initial_values (CRStyle *a_this)
  1584. {
  1585. glong i = 0;
  1586. g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
  1587. for (i = 0; i < NB_NUM_PROPS; i++) {
  1588. switch (i) {
  1589. case NUM_PROP_WIDTH:
  1590. cr_num_set (&a_this->num_props[i].sv, 800,
  1591. NUM_LENGTH_PX) ;
  1592. break ;
  1593. case NUM_PROP_TOP:
  1594. case NUM_PROP_RIGHT:
  1595. case NUM_PROP_BOTTOM:
  1596. case NUM_PROP_LEFT:
  1597. cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO);
  1598. break;
  1599. case NUM_PROP_PADDING_TOP:
  1600. case NUM_PROP_PADDING_RIGHT:
  1601. case NUM_PROP_PADDING_BOTTOM:
  1602. case NUM_PROP_PADDING_LEFT:
  1603. case NUM_PROP_BORDER_TOP:
  1604. case NUM_PROP_BORDER_RIGHT:
  1605. case NUM_PROP_BORDER_BOTTOM:
  1606. case NUM_PROP_BORDER_LEFT:
  1607. case NUM_PROP_MARGIN_TOP:
  1608. case NUM_PROP_MARGIN_RIGHT:
  1609. case NUM_PROP_MARGIN_BOTTOM:
  1610. case NUM_PROP_MARGIN_LEFT:
  1611. cr_num_set (&a_this->num_props[i].sv,
  1612. 0, NUM_LENGTH_PX);
  1613. break;
  1614. default:
  1615. cr_utils_trace_info ("Unknown property");
  1616. break;
  1617. }
  1618. }
  1619. for (i = 0; i < NB_RGB_PROPS; i++) {
  1620. switch (i) {
  1621. /*default foreground color is black */
  1622. case RGB_PROP_COLOR:
  1623. cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
  1624. break;
  1625. /*default background color is white */
  1626. case RGB_PROP_BACKGROUND_COLOR:
  1627. cr_rgb_set (&a_this->rgb_props[i].sv,
  1628. 255, 255, 255, FALSE);
  1629. cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv,
  1630. TRUE) ;
  1631. break;
  1632. default:
  1633. cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE);
  1634. break;
  1635. }
  1636. }
  1637. for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
  1638. a_this->border_style_props[i] = BORDER_STYLE_NONE;
  1639. }
  1640. a_this->display = DISPLAY_BLOCK;
  1641. a_this->position = POSITION_STATIC;
  1642. a_this->float_type = FLOAT_NONE;
  1643. a_this->font_style = FONT_STYLE_NORMAL;
  1644. a_this->font_variant = FONT_VARIANT_NORMAL;
  1645. a_this->font_weight = FONT_WEIGHT_NORMAL;
  1646. a_this->font_stretch = FONT_STRETCH_NORMAL;
  1647. a_this->white_space = WHITE_SPACE_NORMAL;
  1648. cr_font_size_set_predefined_absolute_font_size
  1649. (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ;
  1650. a_this->inherited_props_resolved = FALSE ;
  1651. return CR_OK;
  1652. }
  1653. /**
  1654. *Resolves the inherited properties.
  1655. *The function sets the "inherited" properties to either the value of
  1656. *their parent properties.
  1657. *This function is *NOT* recursive. So the inherited properties of
  1658. *the parent style must have been resolved prior to calling this function.
  1659. *@param a_this the instance where
  1660. *@return CR_OK if a root node is found and the propagation is successful,
  1661. *an error code otherwise
  1662. */
  1663. enum CRStatus
  1664. cr_style_resolve_inherited_properties (CRStyle *a_this)
  1665. {
  1666. enum CRStatus ret = CR_OK;
  1667. glong i = 0;
  1668. g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
  1669. g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ;
  1670. if (a_this->inherited_props_resolved == TRUE)
  1671. return CR_OK ;
  1672. for (i=0 ; i < NB_NUM_PROPS ;i++) {
  1673. if (a_this->num_props[i].sv.type == NUM_INHERIT) {
  1674. cr_num_copy (&a_this->num_props[i].cv,
  1675. &a_this->parent_style->num_props[i].cv);
  1676. }
  1677. }
  1678. for (i=0; i < NB_RGB_PROPS; i++) {
  1679. if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) {
  1680. cr_rgb_copy (
  1681. &a_this->rgb_props[i].cv,
  1682. &a_this->parent_style->rgb_props[i].cv);
  1683. }
  1684. }
  1685. for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) {
  1686. if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) {
  1687. a_this->border_style_props[i] =
  1688. a_this->parent_style->border_style_props[i];
  1689. }
  1690. }
  1691. if (a_this->display == DISPLAY_INHERIT) {
  1692. a_this->display = a_this->parent_style->display;
  1693. }
  1694. if (a_this->position == POSITION_INHERIT) {
  1695. a_this->position = a_this->parent_style->position;
  1696. }
  1697. if (a_this->float_type == FLOAT_INHERIT) {
  1698. a_this->float_type = a_this->parent_style->float_type;
  1699. }
  1700. if (a_this->font_style == FONT_STYLE_INHERIT) {
  1701. a_this->font_style = a_this->parent_style->font_style;
  1702. }
  1703. if (a_this->font_variant == FONT_VARIANT_INHERIT) {
  1704. a_this->font_variant = a_this->parent_style->font_variant;
  1705. }
  1706. if (a_this->font_weight == FONT_WEIGHT_INHERIT) {
  1707. a_this->font_weight = a_this->parent_style->font_weight;
  1708. }
  1709. if (a_this->font_stretch == FONT_STRETCH_INHERIT) {
  1710. a_this->font_stretch = a_this->parent_style->font_stretch;
  1711. }
  1712. /*NULL is inherit marker for font_famiy*/
  1713. if (a_this->font_family == NULL) {
  1714. a_this->font_family = a_this->parent_style->font_family;
  1715. }
  1716. if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) {
  1717. cr_font_size_copy (&a_this->font_size.cv,
  1718. &a_this->parent_style->font_size.cv) ;
  1719. }
  1720. a_this->inherited_props_resolved = TRUE ;
  1721. return ret;
  1722. }
  1723. /**
  1724. *Walks through a css2 property declaration, and populated the
  1725. *according field(s) in the #CRStyle structure.
  1726. *If the properties or their value(s) are/is not known,
  1727. *sets the corresponding field(s) of #CRStyle to its/their default
  1728. *value(s)
  1729. *@param a_this the instance of #CRStyle to set.
  1730. *@param a_decl the declaration from which the #CRStyle fields are set.
  1731. *@return CR_OK upon successfull completion, an error code otherwise.
  1732. */
  1733. enum CRStatus
  1734. cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl)
  1735. {
  1736. CRTerm *value = NULL;
  1737. enum CRStatus status = CR_OK;
  1738. enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN;
  1739. g_return_val_if_fail (a_this && a_decl
  1740. && a_decl
  1741. && a_decl->property
  1742. && a_decl->property->stryng
  1743. && a_decl->property->stryng->str,
  1744. CR_BAD_PARAM_ERROR);
  1745. prop_id = cr_style_get_prop_id
  1746. (a_decl->property->stryng->str);
  1747. value = a_decl->value;
  1748. switch (prop_id) {
  1749. case PROP_ID_PADDING_TOP:
  1750. status = set_prop_padding_x_from_value
  1751. (a_this, value, DIR_TOP);
  1752. break;
  1753. case PROP_ID_PADDING_RIGHT:
  1754. status = set_prop_padding_x_from_value
  1755. (a_this, value, DIR_RIGHT);
  1756. break;
  1757. case PROP_ID_PADDING_BOTTOM:
  1758. status = set_prop_padding_x_from_value
  1759. (a_this, value, DIR_BOTTOM);
  1760. break;
  1761. case PROP_ID_PADDING_LEFT:
  1762. status = set_prop_padding_x_from_value
  1763. (a_this, value, DIR_LEFT);
  1764. break;
  1765. case PROP_ID_PADDING:
  1766. status = set_prop_padding_from_value (a_this, value) ;
  1767. break;
  1768. case PROP_ID_BORDER_TOP_WIDTH:
  1769. status = set_prop_border_x_width_from_value (a_this, value,
  1770. DIR_TOP);
  1771. break;
  1772. case PROP_ID_BORDER_RIGHT_WIDTH:
  1773. status = set_prop_border_x_width_from_value (a_this, value,
  1774. DIR_RIGHT);
  1775. break;
  1776. case PROP_ID_BORDER_BOTTOM_WIDTH:
  1777. status = set_prop_border_x_width_from_value (a_this, value,
  1778. DIR_BOTTOM);
  1779. break;
  1780. case PROP_ID_BORDER_LEFT_WIDTH:
  1781. status = set_prop_border_x_width_from_value (a_this, value,
  1782. DIR_LEFT);
  1783. break;
  1784. case PROP_ID_BORDER_WIDTH:
  1785. status = set_prop_border_width_from_value (a_this, value) ;
  1786. break ;
  1787. case PROP_ID_BORDER_TOP_STYLE:
  1788. status = set_prop_border_x_style_from_value (a_this, value,
  1789. DIR_TOP);
  1790. break;
  1791. case PROP_ID_BORDER_RIGHT_STYLE:
  1792. status = set_prop_border_x_style_from_value (a_this, value,
  1793. DIR_RIGHT);
  1794. break;
  1795. case PROP_ID_BORDER_BOTTOM_STYLE:
  1796. status = set_prop_border_x_style_from_value (a_this, value,
  1797. DIR_BOTTOM);
  1798. break;
  1799. case PROP_ID_BORDER_LEFT_STYLE:
  1800. status = set_prop_border_x_style_from_value (a_this, value,
  1801. DIR_LEFT);
  1802. break;
  1803. case PROP_ID_BORDER_STYLE:
  1804. status = set_prop_border_style_from_value (a_this, value) ;
  1805. break ;
  1806. case PROP_ID_BORDER_TOP_COLOR:
  1807. status = set_prop_border_x_color_from_value (a_this, value,
  1808. DIR_TOP);
  1809. break;
  1810. case PROP_ID_BORDER_RIGHT_COLOR:
  1811. status = set_prop_border_x_color_from_value (a_this, value,
  1812. DIR_RIGHT);
  1813. break;
  1814. case PROP_ID_BORDER_BOTTOM_COLOR:
  1815. status = set_prop_border_x_color_from_value (a_this, value,
  1816. DIR_BOTTOM);
  1817. break;
  1818. case PROP_ID_BORDER_LEFT_COLOR:
  1819. status = set_prop_border_x_color_from_value (a_this, value,
  1820. DIR_BOTTOM);
  1821. break;
  1822. case PROP_ID_BORDER_TOP:
  1823. status = set_prop_border_x_from_value (a_this, value,
  1824. DIR_TOP);
  1825. break;
  1826. case PROP_ID_BORDER_RIGHT:
  1827. status = set_prop_border_x_from_value (a_this, value,
  1828. DIR_RIGHT);
  1829. break;
  1830. case PROP_ID_BORDER_BOTTOM:
  1831. status = set_prop_border_x_from_value (a_this, value,
  1832. DIR_BOTTOM);
  1833. break;
  1834. case PROP_ID_BORDER_LEFT:
  1835. status = set_prop_border_x_from_value (a_this, value,
  1836. DIR_LEFT);
  1837. break;
  1838. case PROP_ID_MARGIN_TOP:
  1839. status = set_prop_margin_x_from_value (a_this, value,
  1840. DIR_TOP);
  1841. break;
  1842. case PROP_ID_BORDER:
  1843. status = set_prop_border_from_value (a_this, value);
  1844. break;
  1845. case PROP_ID_MARGIN_RIGHT:
  1846. status = set_prop_margin_x_from_value (a_this, value,
  1847. DIR_RIGHT);
  1848. break;
  1849. case PROP_ID_MARGIN_BOTTOM:
  1850. status = set_prop_margin_x_from_value (a_this, value,
  1851. DIR_BOTTOM);
  1852. break;
  1853. case PROP_ID_MARGIN_LEFT:
  1854. status = set_prop_margin_x_from_value (a_this, value,
  1855. DIR_LEFT);
  1856. break;
  1857. case PROP_ID_MARGIN:
  1858. status = set_prop_margin_from_value (a_this, value);
  1859. break;
  1860. case PROP_ID_DISPLAY:
  1861. status = set_prop_display_from_value (a_this, value);
  1862. break;
  1863. case PROP_ID_POSITION:
  1864. status = set_prop_position_from_value (a_this, value);
  1865. break;
  1866. case PROP_ID_TOP:
  1867. status = set_prop_x_from_value (a_this, value, DIR_TOP);
  1868. break;
  1869. case PROP_ID_RIGHT:
  1870. status = set_prop_x_from_value (a_this, value, DIR_RIGHT);
  1871. break;
  1872. case PROP_ID_BOTTOM:
  1873. status = set_prop_x_from_value (a_this, value, DIR_BOTTOM);
  1874. break;
  1875. case PROP_ID_LEFT:
  1876. status = set_prop_x_from_value (a_this, value, DIR_LEFT);
  1877. break;
  1878. case PROP_ID_FLOAT:
  1879. status = set_prop_float (a_this, value);
  1880. break;
  1881. case PROP_ID_WIDTH:
  1882. status = set_prop_width (a_this, value);
  1883. break;
  1884. case PROP_ID_COLOR:
  1885. status = set_prop_color (a_this, value);
  1886. break;
  1887. case PROP_ID_BACKGROUND_COLOR:
  1888. status = set_prop_background_color (a_this, value);
  1889. break;
  1890. case PROP_ID_FONT_FAMILY:
  1891. status = set_prop_font_family_from_value (a_this, value);
  1892. break;
  1893. case PROP_ID_FONT_SIZE:
  1894. status = set_prop_font_size_from_value (a_this, value);
  1895. break;
  1896. case PROP_ID_FONT_STYLE:
  1897. status = set_prop_font_style_from_value (a_this, value);
  1898. break;
  1899. case PROP_ID_FONT_WEIGHT:
  1900. status = set_prop_font_weight_from_value (a_this, value);
  1901. break;
  1902. case PROP_ID_WHITE_SPACE:
  1903. status = set_prop_white_space_from_value(a_this, value);
  1904. break;
  1905. default:
  1906. return CR_UNKNOWN_TYPE_ERROR;
  1907. }
  1908. return status;
  1909. }
  1910. /**
  1911. *Increases the reference count
  1912. *of the current instance of #CRStyle.
  1913. *@param a_this the current instance of #CRStyle.
  1914. *@return CR_OK upon successfull completion, an error code
  1915. *otherwise.
  1916. */
  1917. enum CRStatus
  1918. cr_style_ref (CRStyle * a_this)
  1919. {
  1920. g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR);
  1921. a_this->ref_count++;
  1922. return CR_OK;
  1923. }
  1924. /**
  1925. *Decreases the reference count of
  1926. *the current instance of #CRStyle.
  1927. *If the reference count reaches 0, the
  1928. *instance of #CRStyle is destoyed.
  1929. *@param a_this the current instance of #CRStyle.
  1930. *@return TRUE if the instance has been destroyed, FALSE
  1931. *otherwise.
  1932. */
  1933. gboolean
  1934. cr_style_unref (CRStyle * a_this)
  1935. {
  1936. g_return_val_if_fail (a_this, FALSE);
  1937. if (a_this->ref_count)
  1938. a_this->ref_count--;
  1939. if (!a_this->ref_count) {
  1940. cr_style_destroy (a_this);
  1941. return TRUE;
  1942. }
  1943. return FALSE;
  1944. }
  1945. /**
  1946. *Duplicates the current instance of #CRStyle .
  1947. *The newly created instance of #CRStyle must be
  1948. *freed using cr_style_destroy ().
  1949. *@param a_this the current instance of #CRStyle.
  1950. *@return the newly duplicated instance of #CRStyle.
  1951. */
  1952. CRStyle *
  1953. cr_style_dup (CRStyle * a_this)
  1954. {
  1955. CRStyle *result = NULL;
  1956. g_return_val_if_fail (a_this, NULL);
  1957. result = cr_style_new (FALSE);
  1958. if (!result) {
  1959. cr_utils_trace_info ("Out of memory");
  1960. return NULL;
  1961. }
  1962. cr_style_copy (result, a_this);
  1963. return result;
  1964. }
  1965. /**
  1966. *Copies a style data structure into another.
  1967. *TODO: this is actually broken because it's based
  1968. *on memcpy although some data stuctures of CRStyle should
  1969. *be properly duplicated.
  1970. *@param a_dest the destination style datastructure
  1971. *@param a_src the source style datastructure.
  1972. *@return CR_OK upon succesfull completion, an error code otherwise
  1973. */
  1974. enum CRStatus
  1975. cr_style_copy (CRStyle * a_dest, CRStyle * a_src)
  1976. {
  1977. g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR);
  1978. memcpy (a_dest, a_src, sizeof (CRStyle));
  1979. return CR_OK;
  1980. }
  1981. /**
  1982. *dump a CRNumpPropVal in a string.
  1983. *@param a_prop_val the numerical property value to dump
  1984. *@param a_str the string to dump the numerical propertie into.
  1985. *Note that the string value is appended to a_str.
  1986. *@param a_nb_indent the number white chars of indentation.
  1987. */
  1988. enum CRStatus
  1989. cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val,
  1990. GString * a_str, guint a_nb_indent)
  1991. {
  1992. enum CRStatus status = CR_OK;
  1993. guchar *tmp_str = NULL;
  1994. GString *str = NULL;
  1995. g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
  1996. str = g_string_new (NULL);
  1997. cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
  1998. g_string_append (str, "NumPropVal {");
  1999. tmp_str = cr_num_to_string (&a_prop_val->sv);
  2000. if (!tmp_str) {
  2001. status = CR_ERROR;
  2002. goto cleanup;
  2003. }
  2004. g_string_append_printf (str, "sv: %s ", tmp_str);
  2005. g_free (tmp_str);
  2006. tmp_str = NULL;
  2007. tmp_str = cr_num_to_string (&a_prop_val->cv);
  2008. if (!tmp_str) {
  2009. status = CR_ERROR;
  2010. goto cleanup;
  2011. }
  2012. g_string_append_printf (str, "cv: %s ", tmp_str);
  2013. g_free (tmp_str);
  2014. tmp_str = NULL;
  2015. tmp_str = cr_num_to_string (&a_prop_val->av);
  2016. if (!tmp_str) {
  2017. status = CR_ERROR;
  2018. goto cleanup;
  2019. }
  2020. g_string_append_printf (str, "av: %s ", tmp_str);
  2021. g_free (tmp_str);
  2022. tmp_str = NULL;
  2023. g_string_append (str, "}");
  2024. g_string_append (a_str, str->str);
  2025. status = CR_OK;
  2026. cleanup:
  2027. if (tmp_str) {
  2028. g_free (tmp_str);
  2029. tmp_str = NULL;
  2030. }
  2031. if (str) {
  2032. g_string_free (str, TRUE);
  2033. }
  2034. return status;
  2035. }
  2036. enum CRStatus
  2037. cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val,
  2038. GString * a_str, guint a_nb_indent)
  2039. {
  2040. enum CRStatus status = CR_OK;
  2041. guchar *tmp_str = NULL;
  2042. GString *str = NULL;
  2043. g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR);
  2044. str = g_string_new (NULL);
  2045. cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
  2046. g_string_append (str, "RGBPropVal {");
  2047. tmp_str = cr_rgb_to_string (&a_prop_val->sv);
  2048. if (!tmp_str) {
  2049. status = CR_ERROR;
  2050. goto cleanup;
  2051. }
  2052. g_string_append_printf (str, "sv: %s ", tmp_str);
  2053. g_free (tmp_str);
  2054. tmp_str = NULL;
  2055. tmp_str = cr_rgb_to_string (&a_prop_val->cv);
  2056. if (!tmp_str) {
  2057. status = CR_ERROR;
  2058. goto cleanup;
  2059. }
  2060. g_string_append_printf (str, "cv: %s ", tmp_str);
  2061. g_free (tmp_str);
  2062. tmp_str = NULL;
  2063. tmp_str = cr_rgb_to_string (&a_prop_val->av);
  2064. if (!tmp_str) {
  2065. status = CR_ERROR;
  2066. goto cleanup;
  2067. }
  2068. g_string_append_printf (str, "av: %s ", tmp_str);
  2069. g_free (tmp_str);
  2070. tmp_str = NULL;
  2071. g_string_append (str, "}");
  2072. g_string_append (a_str, str->str);
  2073. status = CR_OK;
  2074. cleanup:
  2075. if (tmp_str) {
  2076. g_free (tmp_str);
  2077. tmp_str = NULL;
  2078. }
  2079. if (str) {
  2080. g_string_free (str, TRUE);
  2081. }
  2082. return status;
  2083. }
  2084. enum CRStatus
  2085. cr_style_border_style_to_string (enum CRBorderStyle a_prop,
  2086. GString * a_str, guint a_nb_indent)
  2087. {
  2088. gchar *str = NULL;
  2089. g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
  2090. switch (a_prop) {
  2091. case BORDER_STYLE_NONE:
  2092. str = (gchar *) "border-style-none";
  2093. break;
  2094. case BORDER_STYLE_HIDDEN:
  2095. str = (gchar *) "border-style-hidden";
  2096. break;
  2097. case BORDER_STYLE_DOTTED:
  2098. str = (gchar *) "border-style-dotted";
  2099. break;
  2100. case BORDER_STYLE_DASHED:
  2101. str = (gchar *) "border-style-dashed";
  2102. break;
  2103. case BORDER_STYLE_SOLID:
  2104. str = (gchar *) "border-style-solid";
  2105. break;
  2106. case BORDER_STYLE_DOUBLE:
  2107. str = (gchar *) "border-style-double";
  2108. break;
  2109. case BORDER_STYLE_GROOVE:
  2110. str = (gchar *) "border-style-groove";
  2111. break;
  2112. case BORDER_STYLE_RIDGE:
  2113. str = (gchar *) "border-style-ridge";
  2114. break;
  2115. case BORDER_STYLE_INSET:
  2116. str = (gchar *) "border-style-inset";
  2117. break;
  2118. case BORDER_STYLE_OUTSET:
  2119. str = (gchar *) "border-style-outset";
  2120. break;
  2121. default:
  2122. str = (gchar *) "unknown border style";
  2123. break;
  2124. }
  2125. cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
  2126. g_string_append (a_str, str);
  2127. return CR_OK;
  2128. }
  2129. enum CRStatus
  2130. cr_style_display_type_to_string (enum CRDisplayType a_code,
  2131. GString * a_str, guint a_nb_indent)
  2132. {
  2133. gchar *str = NULL;
  2134. g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
  2135. switch (a_code) {
  2136. case DISPLAY_NONE:
  2137. str = (gchar *) "display-none";
  2138. break;
  2139. case DISPLAY_INLINE:
  2140. str = (gchar *) "display-inline";
  2141. break;
  2142. case DISPLAY_BLOCK:
  2143. str = (gchar *) "display-block";
  2144. break;
  2145. case DISPLAY_LIST_ITEM:
  2146. str = (gchar *) "display-list-item";
  2147. break;
  2148. case DISPLAY_RUN_IN:
  2149. str = (gchar *) "display-run-in";
  2150. break;
  2151. case DISPLAY_COMPACT:
  2152. str = (gchar *) "display-compact";
  2153. break;
  2154. case DISPLAY_MARKER:
  2155. str = (gchar *) "display-marker";
  2156. break;
  2157. case DISPLAY_TABLE:
  2158. str = (gchar *) "display-table";
  2159. break;
  2160. case DISPLAY_INLINE_TABLE:
  2161. str = (gchar *) "display-inline-table";
  2162. break;
  2163. case DISPLAY_TABLE_ROW_GROUP:
  2164. str = (gchar *) "display-table-row-group";
  2165. break;
  2166. case DISPLAY_TABLE_HEADER_GROUP:
  2167. str = (gchar *) "display-table-header-group";
  2168. break;
  2169. case DISPLAY_TABLE_FOOTER_GROUP:
  2170. str = (gchar *) "display-table-footer-group";
  2171. break;
  2172. case DISPLAY_TABLE_ROW:
  2173. str = (gchar *) "display-table-row";
  2174. break;
  2175. case DISPLAY_TABLE_COLUMN_GROUP:
  2176. str = (gchar *) "display-table-column-group";
  2177. break;
  2178. case DISPLAY_TABLE_COLUMN:
  2179. str = (gchar *) "display-table-column";
  2180. break;
  2181. case DISPLAY_TABLE_CELL:
  2182. str = (gchar *) "display-table-cell";
  2183. break;
  2184. case DISPLAY_TABLE_CAPTION:
  2185. str = (gchar *) "display-table-caption";
  2186. break;
  2187. case DISPLAY_INHERIT:
  2188. str = (gchar *) "display-inherit";
  2189. break;
  2190. default:
  2191. str = (gchar *) "unknown display property";
  2192. break;
  2193. }
  2194. cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
  2195. g_string_append (a_str, str);
  2196. return CR_OK;
  2197. }
  2198. enum CRStatus
  2199. cr_style_position_type_to_string (enum CRPositionType a_code,
  2200. GString * a_str, guint a_nb_indent)
  2201. {
  2202. gchar *str = NULL;
  2203. g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
  2204. switch (a_code) {
  2205. case POSITION_STATIC:
  2206. str = (gchar *) "position-static";
  2207. break;
  2208. case POSITION_RELATIVE:
  2209. str = (gchar *) "position-relative";
  2210. break;
  2211. case POSITION_ABSOLUTE:
  2212. str = (gchar *) "position-absolute";
  2213. break;
  2214. case POSITION_FIXED:
  2215. str = (gchar *) "position-fixed";
  2216. break;
  2217. case POSITION_INHERIT:
  2218. str = (gchar *) "position-inherit";
  2219. break;
  2220. default:
  2221. str = (gchar *) "unknown static property";
  2222. }
  2223. cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
  2224. g_string_append (a_str, str);
  2225. return CR_OK;
  2226. }
  2227. enum CRStatus
  2228. cr_style_float_type_to_string (enum CRFloatType a_code,
  2229. GString * a_str, guint a_nb_indent)
  2230. {
  2231. gchar *str = NULL;
  2232. g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
  2233. switch (a_code) {
  2234. case FLOAT_NONE:
  2235. str = (gchar *) "float-none";
  2236. break;
  2237. case FLOAT_LEFT:
  2238. str = (gchar *) "float-left";
  2239. break;
  2240. case FLOAT_RIGHT:
  2241. str = (gchar *) "float-right";
  2242. break;
  2243. case FLOAT_INHERIT:
  2244. str = (gchar *) "float-inherit";
  2245. break;
  2246. default:
  2247. str = (gchar *) "unknown float property value";
  2248. break;
  2249. }
  2250. cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
  2251. g_string_append (a_str, str);
  2252. return CR_OK;
  2253. }
  2254. enum CRStatus
  2255. cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code,
  2256. GString * a_str, guint a_nb_indent)
  2257. {
  2258. gchar *str = NULL;
  2259. g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR);
  2260. switch (a_code) {
  2261. case WHITE_SPACE_NORMAL:
  2262. str = (gchar *) "normal";
  2263. break;
  2264. case WHITE_SPACE_PRE:
  2265. str = (gchar *) "pre";
  2266. break;
  2267. case WHITE_SPACE_NOWRAP:
  2268. str = (gchar *) "nowrap";
  2269. break;
  2270. case WHITE_SPACE_INHERIT:
  2271. str = (gchar *) "inherited";
  2272. break;
  2273. default:
  2274. str = (gchar *) "unknow white space property value";
  2275. break;
  2276. }
  2277. cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent);
  2278. g_string_append (a_str, str);
  2279. return CR_OK;
  2280. }
  2281. /**
  2282. *Serializes in instance of #CRStyle into
  2283. *a string
  2284. *@param a_this the instance of #CRStyle to serialize
  2285. *@param a_str the string to serialise the style into.
  2286. *if *a_str is NULL, a new GString is instanciated, otherwise
  2287. *the style serialisation is appended to the existed *a_str
  2288. *@param the number of white space char to use for indentation.
  2289. *@return CR_OK upon successful completion, an error code otherwise.
  2290. */
  2291. enum CRStatus
  2292. cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent)
  2293. {
  2294. const gint INTERNAL_INDENT = 2;
  2295. gint indent = a_nb_indent + INTERNAL_INDENT;
  2296. gchar *tmp_str = NULL;
  2297. GString *str = NULL;
  2298. gint i = 0;
  2299. g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR);
  2300. if (!*a_str) {
  2301. str = g_string_new (NULL);
  2302. } else {
  2303. str = *a_str;
  2304. }
  2305. cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
  2306. g_string_append (str, "style {\n");
  2307. /*loop over the num_props and to_string() them */
  2308. for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) {
  2309. /*
  2310. *to_string() the name of the num_prop
  2311. *(using num_prop_code_to_string)
  2312. *before outputing it value
  2313. */
  2314. cr_utils_dump_n_chars2 (' ', str, indent);
  2315. tmp_str = (gchar *) num_prop_code_to_string (i);
  2316. if (tmp_str) {
  2317. g_string_append_printf (str, "%s: ", tmp_str);
  2318. } else {
  2319. g_string_append (str, "NULL");
  2320. }
  2321. tmp_str = NULL;
  2322. cr_style_num_prop_val_to_string (&a_this->num_props[i], str,
  2323. a_nb_indent +
  2324. INTERNAL_INDENT);
  2325. g_string_append (str, "\n");
  2326. }
  2327. /*loop over the rgb_props and to_string() them all */
  2328. for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) {
  2329. tmp_str = (gchar *) rgb_prop_code_to_string (i);
  2330. cr_utils_dump_n_chars2 (' ', str, indent);
  2331. if (tmp_str) {
  2332. g_string_append_printf (str, "%s: ", tmp_str);
  2333. } else {
  2334. g_string_append (str, "NULL: ");
  2335. }
  2336. tmp_str = NULL;
  2337. cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str,
  2338. a_nb_indent +
  2339. INTERNAL_INDENT);
  2340. g_string_append (str, "\n");
  2341. }
  2342. /*loop over the border_style_props and to_string() them */
  2343. for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) {
  2344. tmp_str = (gchar *) border_style_prop_code_to_string (i);
  2345. cr_utils_dump_n_chars2 (' ', str, indent);
  2346. if (tmp_str) {
  2347. g_string_append_printf (str, "%s: ", tmp_str);
  2348. } else {
  2349. g_string_append (str, "NULL: ");
  2350. }
  2351. tmp_str = NULL;
  2352. cr_style_border_style_to_string (a_this->
  2353. border_style_props[i], str,
  2354. 0);
  2355. g_string_append (str, "\n");
  2356. }
  2357. cr_utils_dump_n_chars2 (' ', str, indent);
  2358. g_string_append (str, "display: ");
  2359. cr_style_display_type_to_string (a_this->display, str, 0);
  2360. g_string_append (str, "\n");
  2361. cr_utils_dump_n_chars2 (' ', str, indent);
  2362. g_string_append (str, "position: ");
  2363. cr_style_position_type_to_string (a_this->position, str, 0);
  2364. g_string_append (str, "\n");
  2365. cr_utils_dump_n_chars2 (' ', str, indent);
  2366. g_string_append (str, "float-type: ");
  2367. cr_style_float_type_to_string (a_this->float_type, str, 0);
  2368. g_string_append (str, "\n");
  2369. cr_utils_dump_n_chars2 (' ', str, indent);
  2370. g_string_append (str, "white-space: ");
  2371. cr_style_white_space_type_to_string (a_this->white_space, str, 0);
  2372. g_string_append (str, "\n");
  2373. cr_utils_dump_n_chars2 (' ', str, indent);
  2374. g_string_append (str, "font-family: ");
  2375. tmp_str = cr_font_family_to_string (a_this->font_family, TRUE);
  2376. if (tmp_str) {
  2377. g_string_append (str, tmp_str);
  2378. g_free (tmp_str);
  2379. tmp_str = NULL;
  2380. } else {
  2381. g_string_append (str, "NULL");
  2382. }
  2383. g_string_append (str, "\n");
  2384. cr_utils_dump_n_chars2 (' ', str, indent);
  2385. tmp_str = cr_font_size_to_string (&a_this->font_size.sv);
  2386. if (tmp_str) {
  2387. g_string_append_printf (str, "font-size {sv:%s, ",
  2388. tmp_str) ;
  2389. } else {
  2390. g_string_append (str, "font-size {sv:NULL, ");
  2391. }
  2392. tmp_str = cr_font_size_to_string (&a_this->font_size.cv);
  2393. if (tmp_str) {
  2394. g_string_append_printf (str, "cv:%s, ", tmp_str);
  2395. } else {
  2396. g_string_append (str, "cv:NULL, ");
  2397. }
  2398. tmp_str = cr_font_size_to_string (&a_this->font_size.av);
  2399. if (tmp_str) {
  2400. g_string_append_printf (str, "av:%s}", tmp_str);
  2401. } else {
  2402. g_string_append (str, "av:NULL}");
  2403. }
  2404. tmp_str = NULL;
  2405. g_string_append (str, "\n");
  2406. cr_utils_dump_n_chars2 (' ', str, indent);
  2407. tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust);
  2408. if (tmp_str) {
  2409. g_string_append_printf (str, "font-size-adjust: %s", tmp_str);
  2410. } else {
  2411. g_string_append (str, "font-size-adjust: NULL");
  2412. }
  2413. tmp_str = NULL;
  2414. g_string_append (str, "\n");
  2415. cr_utils_dump_n_chars2 (' ', str, indent);
  2416. tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style);
  2417. if (tmp_str) {
  2418. g_string_append_printf (str, "font-style: %s", tmp_str);
  2419. } else {
  2420. g_string_append (str, "font-style: NULL");
  2421. }
  2422. tmp_str = NULL;
  2423. g_string_append (str, "\n");
  2424. cr_utils_dump_n_chars2 (' ', str, indent);
  2425. tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant);
  2426. if (tmp_str) {
  2427. g_string_append_printf (str, "font-variant: %s", tmp_str);
  2428. } else {
  2429. g_string_append (str, "font-variant: NULL");
  2430. }
  2431. tmp_str = NULL;
  2432. g_string_append (str, "\n");
  2433. cr_utils_dump_n_chars2 (' ', str, indent);
  2434. tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight);
  2435. if (tmp_str) {
  2436. g_string_append_printf (str, "font-weight: %s", tmp_str);
  2437. } else {
  2438. g_string_append (str, "font-weight: NULL");
  2439. }
  2440. tmp_str = NULL;
  2441. g_string_append (str, "\n");
  2442. cr_utils_dump_n_chars2 (' ', str, indent);
  2443. tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch);
  2444. if (tmp_str) {
  2445. g_string_append_printf (str, "font-stretch: %s", tmp_str);
  2446. } else {
  2447. g_string_append (str, "font-stretch: NULL");
  2448. }
  2449. tmp_str = NULL;
  2450. g_string_append (str, "\n");
  2451. cr_utils_dump_n_chars2 (' ', str, a_nb_indent);
  2452. g_string_append (str, "}");
  2453. return CR_OK;
  2454. }
  2455. /**
  2456. *Destructor of the #CRStyle class.
  2457. *@param a_this the instance to destroy.
  2458. */
  2459. void
  2460. cr_style_destroy (CRStyle * a_this)
  2461. {
  2462. g_return_if_fail (a_this);
  2463. g_free (a_this);
  2464. }