PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/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

Large files files are truncated, but you can click here to view the full file

  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->

Large files files are truncated, but you can click here to view the full file