📄 dw_table.c
字号:
} } else { DEBUG_MSG (DEBUG_CALC_LEVEL + 2, " --> complex subtable from %d to %d\n", sub->start_col, sub->end_col); for (row = 0; row < sub->table->num_rows; row++) if (!a_Bitvec_get_bit (sub->removed_rows, row) && Dw_table_sub_spans_width (sub, row)) { a_Bitvec_set_bit (sub->spanning_rows, row); DEBUG_MSG (DEBUG_CALC_LEVEL + 1, " row %d spans width\n", row); } sub->num_subs = 0; sub->subs = g_new (DwTableSub, sub->end_col - sub->start_col); col = sub->start_col; while (col < sub->end_col) { DEBUG_MSG (DEBUG_CALC_LEVEL + 1, " column %d\n", col); sub->subs[sub->num_subs].table = sub->table; sub->subs[sub->num_subs].start_col = col; sub->subs[sub->num_subs].removed_rows = a_Bitvec_new (sub->table->num_rows); sub->subs[sub->num_subs].spanning_rows = a_Bitvec_new (sub->table->num_rows); /* Search for the greatest colspan value. */ most_right = col + 1; for (row = 0; row < sub->table->num_rows; row++) if (a_Bitvec_get_bit (sub->removed_rows, row) || a_Bitvec_get_bit (sub->spanning_rows, row)) a_Bitvec_set_bit (sub->subs[sub->num_subs].removed_rows, row); else { n = col + sub->table->num_cols * row; if (sub->table->children[n]) { if (sub->table->children[n]->type == DW_TABLE_CELL) { start_col = col; start_row = row; start_n = n; } else { start_col = sub->table->children[n]->data.span_space.start_col; start_row = sub->table->children[n]->data.span_space.start_row; start_n = start_col + sub->table->num_cols * start_row; } if (row == start_row) { colspan = sub->table->children[start_n]->data.cell.colspan - (col - start_col); if (start_col + colspan > most_right && start_col + colspan <= sub->end_col) most_right = start_col + colspan; } } } sub->subs[sub->num_subs].end_col = most_right; Dw_table_sub_calc_subs (&sub->subs[sub->num_subs]); sub->num_subs++; col = most_right; } DEBUG_MSG (DEBUG_CALC_LEVEL + 1, " <-- END\n"); }}/* * Create a DwTableSub for a table. */static void Dw_table_sub_create (DwTable *table){ if (table->sub) Dw_table_sub_free (table->sub); DEBUG_MSG (DEBUG_CALC_LEVEL + 3, "--> Dw_table_sub_create widths for (%d x %d) table.\n", table->num_cols, table->num_rows); table->sub = g_new (DwTableSub, 1); table->sub->table = table; table->sub->start_col = 0; table->sub->end_col = table->num_cols; table->sub->removed_rows = a_Bitvec_new (table->num_rows); table->sub->spanning_rows = a_Bitvec_new (table->num_rows); Dw_table_sub_calc_subs (table->sub); DEBUG_MSG (DEBUG_CALC_LEVEL + 2, "<-- END\n");}/* * Clean up a DwTableSub. Only for use by Dw_table_free_sub. */static void Dw_table_sub_clean_up (DwTableSub *sub){ gint i; a_Bitvec_free (sub->removed_rows); a_Bitvec_free (sub->spanning_rows); if (sub->subs) { for (i = 0; i < sub->num_subs; i++) Dw_table_sub_clean_up (&sub->subs[i]); g_free (sub->subs); }}/* * Free a DwTableSub. */static void Dw_table_sub_free (DwTableSub *sub){ Dw_table_sub_clean_up (sub); g_free (sub);}/* ---------------------------------------------------------------------- * * Specific Functions for Subtables * * NOTE: The spaces left of the left most column and right of the * right most column do not belong to a subtable. * * ---------------------------------------------------------------------- *//* * Calculate the extremes of a subtable. */static void Dw_table_sub_get_extremes (DwTableSub *sub){ gint i, row, n, start_col, start_row, start_n, num_cols, colspan; DwWidget *child, *widget; DwExtremes child_extremes, sum_extremes; gint32 col_width; gint32 border_spacing = DW_WIDGET(sub->table)->style->border_spacing; gfloat percentage; gfloat sum_percentage; gint use_percentage_map[3][3] = { { USE_PERCENTAGE_NO, USE_PERCENTAGE_SOME, -1 }, { USE_PERCENTAGE_SOME, USE_PERCENTAGE_SOME, USE_PERCENTAGE_SOME }, { USE_PERCENTAGE_SOME, USE_PERCENTAGE_SOME, USE_PERCENTAGE_ALL } }; num_cols = sub->end_col - sub->start_col; sub->use_percentage = USE_PERCENTAGE_NO; sub->fixed_width = FALSE; sub->percentage = 0; DEBUG_MSG (DEBUG_EXTR_LEVEL + 2, " [%p] subtable from %d to %d\n", sub->table, sub->start_col, sub->end_col); /* 1. cells spanning the whole width */ sub->span_extremes.min_width = 0; sub->span_extremes.max_width = 0; for (row = 0; row < sub->table->num_rows; row++) { if (!a_Bitvec_get_bit (sub->removed_rows, row) && a_Bitvec_get_bit (sub->spanning_rows, row)) { n = sub->start_col + row * sub->table->num_cols; if (sub->table->children[n]) { if (sub->table->children[n]->type == DW_TABLE_CELL) { start_row = row; start_n = n; } else { start_col = sub->table->children[n]->data.span_space.start_col; start_row = sub->table->children[n]->data.span_space.start_row; start_n = start_col + sub->table->num_cols * start_row; } if (row == start_row) { child = sub->table->children[start_n]->data.cell.widget; a_Dw_widget_get_extremes (child, &child_extremes); colspan = sub->table->children[start_n]->data.cell.colspan; /* Adjust width argument of the cell */ if (DW_STYLE_IS_ABS_LENGTH (child->style->width)) { col_width = DW_STYLE_ABS_LENGTH_VAL (child->style->width); if (col_width < child_extremes.min_width) col_width = child_extremes.min_width; child_extremes.min_width = col_width; child_extremes.max_width = col_width; sub->fixed_width = TRUE; DEBUG_MSG (DEBUG_EXTR_LEVEL, " [%p] following " "adjusted by %d pixels:\n", sub->table, col_width); } else if (DW_STYLE_IS_PER_LENGTH (child->style->width)) { percentage = DW_STYLE_PER_LENGTH_VAL (child->style->width); sub->percentage = MAX (sub->percentage, percentage); sub->use_percentage = USE_PERCENTAGE_ALL; DEBUG_MSG (DEBUG_EXTR_LEVEL, " [%p] following adjusted by %g %%\n", sub->table, 100 * sub->percentage); } if (num_cols != colspan) { child_extremes.min_width = child_extremes.min_width * num_cols / colspan; child_extremes.max_width = child_extremes.max_width * num_cols / colspan; } DEBUG_MSG (DEBUG_EXTR_LEVEL, " [%p], row %d: cell extremes: %d / %d " "[was multiplied by %d / %d]\n", sub->table, row, child_extremes.min_width, child_extremes.max_width, num_cols, colspan); if (child_extremes.min_width > sub->span_extremes.min_width) sub->span_extremes.min_width = child_extremes.min_width; if (child_extremes.max_width > sub->span_extremes.max_width) sub->span_extremes.max_width = child_extremes.max_width; } else { DEBUG_MSG (DEBUG_EXTR_LEVEL, " [%p] row %d: omitted\n", sub->table, row); } } } } DEBUG_MSG (DEBUG_EXTR_LEVEL + 1, " [%p] spanning subs: %d / %d\n", sub->table, sub->span_extremes.min_width, sub->span_extremes.max_width); if (sub->table->sub == sub) { /* Adjust width argument of the table (fixed, percentages later in the code). */ widget = DW_WIDGET (sub->table); if (DW_STYLE_IS_ABS_LENGTH (widget->style->width)) { col_width = DW_STYLE_ABS_LENGTH_VAL (widget->style->width); if (col_width < sub->span_extremes.min_width) col_width = sub->span_extremes.min_width; sub->span_extremes.min_width = col_width; sub->span_extremes.max_width = col_width; } } /* 2. subtables */ sum_extremes.min_width = (sub->num_subs - 1) * border_spacing; sum_extremes.max_width = (sub->num_subs - 1) * border_spacing; sum_percentage = 0; if (num_cols > 1) for (i = 0; i < sub->num_subs; i++) { Dw_table_sub_get_extremes (&sub->subs[i]); sum_extremes.min_width += sub->subs[i].total_extremes.min_width; sum_extremes.max_width += sub->subs[i].total_extremes.max_width; sum_percentage += sub->subs[i].percentage; if ((sub->use_percentage = use_percentage_map [sub->use_percentage][sub->subs[i].use_percentage]) == -1) sub->use_percentage = (i == 0) ? USE_PERCENTAGE_ALL : USE_PERCENTAGE_SOME; } DEBUG_MSG (DEBUG_EXTR_LEVEL + 1, " [%p] sum of subsubs: %d / %d\n", sub->table, sum_extremes.min_width, sum_extremes.max_width); if (sub->fixed_width) { sum_extremes.max_width = sum_extremes.min_width; sub->span_extremes.max_width = sub->span_extremes.min_width; } sub->total_extremes.min_width = MAX (sum_extremes.min_width, sub->span_extremes.min_width); sub->total_extremes.max_width = MAX (sum_extremes.max_width, sub->span_extremes.max_width); sub->percentage = MAX (sub->percentage, sum_percentage); DEBUG_MSG (DEBUG_EXTR_LEVEL + 1, " [%p] final: %d / %d\n", sub->table, sub->total_extremes.min_width, sub->total_extremes.max_width);}/* * Corrent minima or maxima, used by Dw_table_sub_calc_col_widths. */#define EXTR_VALUE(e) (max ? (e).max_width : (e).min_width)static void Dw_table_sub_adjust_col_widths (DwTableSub *sub, gboolean max, gint32 width, DwExtremes *sub_extremes, gint num_nf_subs, gint num_nf_cols, gint32 sum_nf_sub_widths){ gint i, cols_per_sub, rest_n, rest_w; gint32 sum_sub_widths, sum_orig_sub_widths, sub_extr_width, delta; sum_sub_widths = 0; sum_orig_sub_widths = 0; for (i = 0; i < sub->num_subs; i++) { sum_orig_sub_widths += EXTR_VALUE (sub->subs[i].total_extremes); sum_sub_widths += EXTR_VALUE (sub_extremes[i]); } DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " Comparing %s: total: %d, sum: %d\n", (max ? "max" : "min"), width, sum_sub_widths); if (num_nf_subs == -1) { /* If all subs are fixed, unfix them all. */ sum_nf_sub_widths = sum_sub_widths; num_nf_cols = sub->end_col - sub->start_col; } if (sum_sub_widths < width) { if (sum_nf_sub_widths == 0) { /* All non-fixed columns zero: Apportion the rest to the * non-fixed columns, according to the columns per subtable. */ rest_w = width - sum_sub_widths; rest_n = num_nf_cols; for (i = 0; i < sub->num_subs; i++) { if (num_nf_subs == -1 || !(sub->subs[i].fixed_width || sub->subs[i].use_percentage == USE_PERCENTAGE_ALL)) { cols_per_sub = (sub->subs[i].end_col - sub->subs[i].start_col); sub_extr_width = rest_w * cols_per_sub / rest_n; rest_w -= sub_extr_width; rest_n -= cols_per_sub; if (max) sub_extremes[i].max_width = sub_extr_width; else sub_extremes[i].min_width = sub_extr_width; } } } else { /* Apportion the rest, according to current values. */ rest_w = width - sum_sub_widths; rest_n = sum_nf_sub_widths; for (i = 0; i < sub->num_subs; i++) if (num_nf_subs == -1 || !(sub->subs[i].fixed_width || sub->subs[i].use_percentage == USE_PERCENTAGE_ALL)) { DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, " increasing sub %d: %d -> ", i, EXTR_VALUE (sub_extremes[i]));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -