summaryrefslogtreecommitdiff
path: root/src/layeng/cr-lay-eng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/layeng/cr-lay-eng.c')
-rw-r--r--src/layeng/cr-lay-eng.c409
1 files changed, 362 insertions, 47 deletions
diff --git a/src/layeng/cr-lay-eng.c b/src/layeng/cr-lay-eng.c
index 90034b8..ffda035 100644
--- a/src/layeng/cr-lay-eng.c
+++ b/src/layeng/cr-lay-eng.c
@@ -27,6 +27,7 @@
*/
#include <gnome.h>
+#include <gdk/gdk.h>
#include <string.h>
#include "cr-lay-eng.h"
#include "cr-sel-eng.h"
@@ -45,15 +46,33 @@ struct _CRLayEngPriv
gboolean update_parent_box_size ;
CRCascade *cascade ;
CRSelEng *sel_eng ;
+ gulong xdpi ;/*x resolution*/
+ gulong ydpi ; /*y resolution*/
} ;
+enum CRDirection
+{
+ DIR_UNKNOWN = 0,
+ DIR_VERTICAL,
+ DIR_HORIZONTAL
+} ;
+
static gboolean gv_layeng_initialized = FALSE ;
+static void
+init_anonymous_text_box (CRBox *a_box) ;
+
+static enum CRStatus
+style_specified_2_computed_values (CRLayEng *a_this,
+ CRStyle *a_style,
+ CRBox *a_parent_box) ;
+
static CRBox *
create_box_tree_real (CRLayEng * a_this,
xmlNode *a_root_node,
CRBox *a_parent_box) ;
+
static glong
get_box_bottommost_y (CRBox *a_this) ;
@@ -86,6 +105,12 @@ static enum CRStatus
adjust_parent_inner_edge_size (CRLayEng *a_this,
CRBox *a_cur_box) ;
+static enum CRStatus
+normalize_num (CRLayEng *a_this,
+ CRNum *a_dest_num,
+ CRNum *a_src_num,
+ enum CRDirection a_dir) ;
+
/**********************
*Private methods.
**********************/
@@ -100,40 +125,319 @@ adjust_parent_inner_edge_size (CRLayEng *a_this,
static void
init_anonymous_text_box (CRBox *a_box)
{
+ glong i = 0 ;
+
g_return_if_fail (a_box && a_box->style) ;
+
+ for (i = 0 ; i< NB_NUM_PROPS ; i++)
+ {
+ switch (i)
+ {
+ case NUM_PROP_PADDING_TOP:
+ case NUM_PROP_PADDING_RIGHT:
+ case NUM_PROP_PADDING_BOTTOM:
+ case NUM_PROP_PADDING_LEFT:
+ case NUM_PROP_BORDER_TOP:
+ case NUM_PROP_BORDER_RIGHT:
+ case NUM_PROP_BORDER_BOTTOM:
+ case NUM_PROP_BORDER_LEFT:
+ case NUM_PROP_MARGIN_TOP:
+ case NUM_PROP_MARGIN_RIGHT:
+ case NUM_PROP_MARGIN_BOTTOM:
+ case NUM_PROP_MARGIN_LEFT:
+ cr_num_set (&a_box->style->num_props[i].sv,
+ 0, NUM_LENGTH_PX) ;
+ break ;
+
+ default:
+ break ;
+ }
+
+ }
- cr_num_set (&a_box->style->padding_top, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->padding_right, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->padding_bottom, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->padding_left, 0, NUM_LENGTH_PX) ;
-
- cr_num_set (&a_box->style->border_top, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->border_right, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->border_bottom, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->border_left, 0, NUM_LENGTH_PX) ;
-
- cr_num_set (&a_box->style->margin_top, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->margin_right, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->margin_bottom, 0, NUM_LENGTH_PX) ;
- cr_num_set (&a_box->style->margin_left, 0, NUM_LENGTH_PX) ;
-
- a_box->style->border_top_style = BORDER_STYLE_NONE ;
- a_box->style->border_right_style = BORDER_STYLE_NONE ;
- a_box->style->border_bottom_style = BORDER_STYLE_NONE ;
- a_box->style->border_left_style = BORDER_STYLE_NONE ;
-
- cr_num_set (&a_box->style->top.num, 0, NUM_LENGTH_PX) ;
- a_box->style->top.type = OFFSET_DEFINED ;
- cr_num_set (&a_box->style->right.num, 0, NUM_LENGTH_PX) ;
- a_box->style->right.type = OFFSET_DEFINED ;
- cr_num_set (&a_box->style->bottom.num, 0, NUM_LENGTH_PX) ;
- a_box->style->bottom.type = OFFSET_DEFINED ;
- cr_num_set (&a_box->style->left.num, 0, NUM_LENGTH_PX) ;
- a_box->style->left.type = OFFSET_DEFINED ;
+ for (i = 0 ; i< NB_BORDER_STYLE_PROPS ; i++)
+ {
+ a_box->style->border_style_props[i] = BORDER_STYLE_NONE ;
+ }
a_box->style->float_type = FLOAT_NONE ;
}
+
+static enum CRStatus
+normalize_num (CRLayEng *a_this,
+ CRNum *a_dest_num,
+ CRNum *a_src_num,
+ enum CRDirection a_dir)
+{
+ g_return_val_if_fail (a_this && a_dest_num
+ && a_src_num,
+ CR_BAD_PARAM_ERROR) ;
+
+ switch (a_src_num->type)
+ {
+ case NUM_LENGTH_PX:
+ cr_num_copy (a_dest_num, a_src_num) ;
+ /*a_dest_num->type = NUM_LENGTH_PX ;*/
+ break ;
+
+ case NUM_LENGTH_EM:
+ case NUM_LENGTH_EX:
+ break ;
+
+ case NUM_LENGTH_IN:
+ if (a_dir == DIR_HORIZONTAL)
+ {
+ a_dest_num->val = a_src_num->val
+ * PRIVATE (a_this)->xdpi ;
+ }
+ else if (a_dir == DIR_VERTICAL)
+ {
+ a_dest_num->val = a_src_num->val
+ * PRIVATE (a_this)->ydpi ;
+ }
+ else
+ {
+ cr_utils_trace_info ("Bad direction given") ;
+ return CR_BAD_PARAM_ERROR ;
+ }
+ a_dest_num->type = NUM_LENGTH_PX ;
+ break ;
+
+ case NUM_LENGTH_CM:
+ /*1 inch == 25.4 mm*/
+ if (a_dir == DIR_HORIZONTAL)
+ {
+ a_dest_num->val = a_src_num->val / 2.54 *
+ PRIVATE (a_this)->xdpi ;
+ }
+ else if (a_dir == DIR_VERTICAL)
+ {
+ a_dest_num->val = a_src_num->val / 2.54 *
+ PRIVATE (a_this)->ydpi ;
+ }
+ else
+ {
+ cr_utils_trace_info ("Bad direction given") ;
+ return CR_BAD_PARAM_ERROR ;
+ }
+
+ a_dest_num->type = NUM_LENGTH_PX ;
+ break ;
+
+ case NUM_LENGTH_MM:
+ /*1 inch == 25.4 mm*/
+ if (a_dir == DIR_HORIZONTAL)
+ {
+ a_dest_num->val = a_src_num->val / 25.4 *
+ PRIVATE (a_this)->xdpi ;
+ }
+ else if (a_dir == DIR_VERTICAL)
+ {
+ a_dest_num->val = a_src_num->val / 25.4 *
+ PRIVATE (a_this)->ydpi ;
+ }
+ else
+ {
+ cr_utils_trace_info ("Bad direction given") ;
+ return CR_BAD_PARAM_ERROR ;
+ }
+ a_dest_num->type = NUM_LENGTH_PX ;
+ break ;
+
+ case NUM_LENGTH_PT:
+ /*1 point == 1/72 inch*/
+ if (a_dir == DIR_HORIZONTAL)
+ {
+ a_dest_num->val = a_src_num->val *
+ PRIVATE (a_this)->xdpi / 72 ;
+ }
+ else if (a_dir == DIR_VERTICAL)
+ {
+ a_dest_num->val = a_src_num->val *
+ PRIVATE (a_this)->ydpi / 72 ;
+ }
+ else
+ {
+ cr_utils_trace_info ("Bad direction given") ;
+ return CR_BAD_PARAM_ERROR ;
+ }
+
+ a_dest_num->type = NUM_LENGTH_PX ;
+ break ;
+
+ case NUM_LENGTH_PC:
+ /*1 pica == 12 points*/
+ if (a_dir == DIR_HORIZONTAL)
+ {
+ a_dest_num->val = a_src_num->val *
+ PRIVATE (a_this)->xdpi / 72 * 12 ;
+ }
+ else if (a_dir == DIR_VERTICAL)
+ {
+ a_dest_num->val = a_src_num->val *
+ PRIVATE (a_this)->ydpi / 72 * 12 ;
+ }
+ else
+ {
+ cr_utils_trace_info ("Bad direction given") ;
+ return CR_BAD_PARAM_ERROR ;
+ }
+
+ a_dest_num->type = NUM_LENGTH_PX ;
+ break ;
+
+ case NUM_ANGLE_DEG:
+ a_dest_num->val = a_src_num->val ;
+
+ break ;
+ case NUM_ANGLE_RAD:
+ a_dest_num->val = a_src_num->val * 180 / 3.1415 ;
+ a_dest_num->type = NUM_ANGLE_DEG ;
+ break ;
+
+ case NUM_ANGLE_GRAD:
+ a_dest_num->val = a_src_num->val * 90 / 100 ;
+ a_dest_num->type = NUM_ANGLE_DEG ;
+ break ;
+
+ case NUM_TIME_MS:
+ a_dest_num->val = a_src_num->val ;
+
+ break ;
+
+ case NUM_TIME_S:
+ a_dest_num->val = a_src_num->val * 1000 ;
+ a_dest_num->type = NUM_TIME_MS ;
+ break ;
+
+ case NUM_FREQ_HZ:
+ a_dest_num->val = a_src_num->val ;
+ break ;
+
+ case NUM_FREQ_KHZ:
+ a_dest_num->val = a_src_num->val * 1000 ;
+ a_dest_num->type = NUM_FREQ_HZ ;
+ break ;
+
+ case NUM_PERCENTAGE:
+ cr_utils_trace_info ("a PERCENTAGE cannot be normalized") ;
+ return CR_BAD_PARAM_ERROR ;
+
+ default:
+
+ cr_num_copy (a_dest_num, a_src_num) ;
+ break ;
+ }
+
+ return CR_OK ;
+}
+
+static enum CRStatus
+style_specified_2_computed_values (CRLayEng *a_this,
+ CRStyle *a_style,
+ CRBox *a_parent_box)
+{
+ glong i = 0 ;
+ CRBoxEdge *parent_inner_edge = NULL;
+
+ g_return_val_if_fail (a_style && a_this,
+ CR_BAD_PARAM_ERROR) ;
+
+ /*
+ *walk thru the numerical properties (num_props) and
+ *compute their computed value.
+ */
+ for (i = 0 ; i < NB_NUM_PROPS ; i++)
+ {
+ switch (i)
+ {
+ case NUM_PROP_TOP:
+ case NUM_PROP_BOTTOM:
+ case NUM_PROP_PADDING_TOP:
+ case NUM_PROP_PADDING_BOTTOM:
+ case NUM_PROP_BORDER_TOP:
+ case NUM_PROP_BORDER_BOTTOM:
+ case NUM_PROP_MARGIN_TOP:
+ case NUM_PROP_MARGIN_BOTTOM:
+ if (a_style->num_props[i].sv.type == NUM_PERCENTAGE)
+ {
+ /*
+ *TODO: compute the computed value
+ *using the parent box size.
+ */
+ if (a_parent_box)
+ {
+ parent_inner_edge =
+ &a_parent_box->inner_edge ;
+ }
+
+ g_return_val_if_fail (parent_inner_edge,
+ CR_BAD_PARAM_ERROR) ;
+
+ a_style->num_props[i].cv.val =
+ parent_inner_edge->height *
+ a_style->num_props[i].sv.val / 100 ;
+ }
+ else
+ {
+ normalize_num (a_this,
+ &a_style->num_props[i].cv,
+ &a_style->num_props[i].sv,
+ DIR_VERTICAL) ;
+ }
+
+ break ;
+
+ case NUM_PROP_WIDTH:
+ case NUM_PROP_RIGHT:
+ case NUM_PROP_LEFT:
+ case NUM_PROP_PADDING_LEFT:
+ case NUM_PROP_PADDING_RIGHT:
+ case NUM_PROP_BORDER_LEFT:
+ case NUM_PROP_BORDER_RIGHT:
+ case NUM_PROP_MARGIN_LEFT:
+ case NUM_PROP_MARGIN_RIGHT:
+ if (a_style->num_props[i].sv.type == NUM_PERCENTAGE)
+ {
+ /*
+ *TODO: compute the computed value
+ *using the parent box size.
+ */
+ if (a_parent_box)
+ {
+ parent_inner_edge =
+ &a_parent_box->inner_edge ;
+ }
+
+ g_return_val_if_fail (parent_inner_edge,
+ CR_BAD_PARAM_ERROR) ;
+
+ a_style->num_props[i].cv.val =
+ parent_inner_edge->width *
+ a_style->num_props[i].sv.val / 100 ;
+ }
+ else
+ {
+ normalize_num (a_this,
+ &a_style->num_props[i].cv,
+ &a_style->num_props[i].sv,
+ DIR_HORIZONTAL) ;
+ }
+ break ;
+
+ default:
+ normalize_num (a_this,
+ &a_style->num_props[i].cv,
+ &a_style->num_props[i].sv,
+ DIR_UNKNOWN) ;
+ break ;
+ }
+ }
+
+ return CR_OK ;
+}
+
/**
*Creates a box sub tree from an xml node tree.
*@param a_this the current instance of #CRLayEng.
@@ -202,6 +506,9 @@ create_box_tree_real (CRLayEng * a_this,
*the positioning. The positioning will
*be updated later via the cr_box_layout() method.
*/
+ style_specified_2_computed_values
+ (a_this, style, a_parent_box) ;
+
cur_box = cr_box_new (style) ;
if (!cur_box)
{
@@ -479,20 +786,21 @@ compute_box_size (CRLayEng *a_this,
a_cur_box->border_edge.x =
a_cur_box->outer_edge.x
+
- a_cur_box->style->margin_left.val ;
+ a_cur_box->style->num_props[NUM_PROP_MARGIN_LEFT].cv.val ;
a_cur_box->border_edge.y =
a_cur_box->outer_edge.y
+
- a_cur_box->style->margin_top.val ;
+ a_cur_box->style->num_props[NUM_PROP_MARGIN_TOP].cv.val ;
a_cur_box->padding_edge.x =
a_cur_box->border_edge.x
+
- a_cur_box->style->border_left.val ;
+ a_cur_box->style->num_props[NUM_PROP_BORDER_LEFT].cv.val ;
+
a_cur_box->padding_edge.y =
a_cur_box->border_edge.y
+
- a_cur_box->style->border_top.val ;
+ a_cur_box->style->num_props[NUM_PROP_BORDER_TOP].cv.val ;
/*
*Step 2/
@@ -500,11 +808,11 @@ compute_box_size (CRLayEng *a_this,
a_cur_box->inner_edge.x =
a_cur_box->padding_edge.x
+
- a_cur_box->style->padding_left.val ;
+ a_cur_box->style->num_props[NUM_PROP_PADDING_LEFT].cv.val ;
a_cur_box->inner_edge.y =
a_cur_box->padding_edge.y
+
- a_cur_box->style->padding_left.val ;
+ a_cur_box->style->num_props[NUM_PROP_PADDING_LEFT].cv.val ;
/*
*Step 3.
@@ -566,25 +874,25 @@ compute_box_size (CRLayEng *a_this,
*(padding edge, border edge and outer edge)
******************************************/
a_cur_box->padding_edge.width = a_cur_box->inner_edge.width +
- a_cur_box->style->padding_right.val +
- a_cur_box->style->padding_left.val ;
+ a_cur_box->style->num_props[NUM_PROP_PADDING_RIGHT].cv.val +
+ a_cur_box->style->num_props[NUM_PROP_PADDING_LEFT].cv.val ;
a_cur_box->padding_edge.height = a_cur_box->inner_edge.height +
- a_cur_box->style->padding_top.val +
- a_cur_box->style->padding_bottom.val ;
+ a_cur_box->style->num_props[NUM_PROP_PADDING_TOP].cv.val +
+ a_cur_box->style->num_props[NUM_PROP_PADDING_BOTTOM].cv.val ;
a_cur_box->border_edge.width = a_cur_box->padding_edge.width +
- a_cur_box->style->border_right.val +
- a_cur_box->style->border_left.val ;
+ a_cur_box->style->num_props[NUM_PROP_BORDER_RIGHT].cv.val +
+ a_cur_box->style->num_props[NUM_PROP_BORDER_LEFT].cv.val ;
a_cur_box->border_edge.height = a_cur_box->padding_edge.height +
- a_cur_box->style->border_top.val +
- a_cur_box->style->border_bottom.val ;
+ a_cur_box->style->num_props[NUM_PROP_BORDER_TOP].cv.val +
+ a_cur_box->style->num_props[NUM_PROP_BORDER_BOTTOM].cv.val ;
a_cur_box->outer_edge.width = a_cur_box->border_edge.width +
- a_cur_box->style->margin_left.val +
- a_cur_box->style->margin_right.val ;
+ a_cur_box->style->num_props[NUM_PROP_MARGIN_LEFT].cv.val +
+ a_cur_box->style->num_props[NUM_PROP_MARGIN_RIGHT].cv.val ;
a_cur_box->outer_edge.height = a_cur_box->border_edge.height +
- a_cur_box->style->margin_top.val +
- a_cur_box->style->margin_bottom.val ;
+ a_cur_box->style->num_props[NUM_PROP_MARGIN_TOP].cv.val +
+ a_cur_box->style->num_props[NUM_PROP_MARGIN_BOTTOM].cv.val ;
return CR_OK ;
}
@@ -958,6 +1266,13 @@ cr_lay_eng_new (void)
}
memset (PRIVATE (result), 0, sizeof (CRLayEngPriv)) ;
+
+
+ PRIVATE (result)->xdpi = gdk_screen_width () /
+ gdk_screen_width_mm () * 25.4 ;
+ PRIVATE (result)->ydpi = gdk_screen_height () /
+ gdk_screen_height_mm () * 25.4 ;
+
return result ;
}
@@ -973,7 +1288,7 @@ cr_lay_eng_new (void)
enum CRStatus
cr_lay_eng_create_box_model (CRLayEng *a_this,
xmlDoc *a_doc,
- CRCascade *a_cascade,
+ CRCascade *a_cascade,
CRBoxModel **a_box_model)
{
xmlNode *root_node = NULL ;