⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dw_table.c

📁 嵌入式浏览器Dillo源码
💻 C
📖 第 1 页 / 共 4 页
字号:
   /* 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, "      sum of subsubs: %d / %d\n",              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, "      final: %d / %d\n",              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;              EXTR_VALUE (sub_extremes[i]) = 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]));               if (EXTR_VALUE (sub_extremes[i]) > 0) {                  delta = rest_w * EXTR_VALUE (sub_extremes[i]) / rest_n;                  rest_w -= delta;                  rest_n -= EXTR_VALUE (sub_extremes[i]);                  EXTR_VALUE (sub_extremes[i]) += delta;               }               DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "%d\n",                          EXTR_VALUE (sub_extremes[i]));            }      }   }}/* * Calculate the column widths of a subtable, fill table->width. */static void Dw_table_sub_calc_col_widths (DwTableSub *sub,                                          gint32 width,                                          gint32 total_width){   enum { AT_MIN, AT_MAX, AT_NORM }; /* for sub_status */   gint *sub_status;   gint32 avail_width, sub_width, width_norm_cols;   gint32 col_width, sum_sub_min_widths, sum_orig_sub_min_widths;   gint i, num_cols, cols_per_sub, num_norm_cols, num_nf_subs, num_nf_cols;   gint rest_w, rest_n, delta;   gboolean success;   gint32 border_spacing, diff;   DwExtremes extremes, *sub_extremes, sum_nf_sub_extremes;   num_cols = sub->end_col - sub->start_col;   if (num_cols == 1) {      /* single column */      DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "   single column at %d: width = %d\n",                 sub->start_col, width);      sub->table->col_width[sub->start_col] = width;   } else {      /* complex subtable       *       * The comments "STEP <n>" refer to the documentation in       * ../doc/DwTable.txt, "Calculating column widths". Read this       * parallel.       */      DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                 "   --> complex subtable from %d to %d, width = %d "                 "(total = %d)\n",                 sub->start_col, sub->end_col, width, total_width);      border_spacing = DW_WIDGET(sub->table)->style->border_spacing;      diff =  (sub->num_subs - 1) * border_spacing;      avail_width = width - diff;      extremes = sub->total_extremes;      if (width > extremes.max_width)         extremes.max_width = width;      sub_extremes = g_new (DwExtremes, sub->num_subs);      sum_sub_min_widths = 0;      /* ---- STEP 1: Calculate relative widths. ---- */      for (i = 0; i < sub->num_subs; i++) {         sub_extremes[i] = sub->subs[i].total_extremes;         if (sub->subs[i].use_percentage != USE_PERCENTAGE_NO) {            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                       "          sub %d [%s] has width of %g%% "                       "-> adjusting: %d/%d -> ",                       i, sub->subs[i].fixed_width ? "fixed" : "variable",                       100 * sub->subs[i].percentage,                       sub_extremes[i].min_width, sub_extremes[i].max_width);            col_width = sub->subs[i].percentage * total_width;            if (col_width < sub_extremes[i].min_width)               col_width = sub_extremes[i].min_width;            sub_extremes[i].min_width = col_width;            if (sub->subs[i].use_percentage == USE_PERCENTAGE_ALL)               sub_extremes[i].max_width = col_width;            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "%d/%d\n",                       sub_extremes[i].min_width, sub_extremes[i].max_width);         } else {            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                       "          sub %d [%s]: %d/%d\n", i,                       sub->subs[i].fixed_width ? "fixed" : "variable",                       sub_extremes[i].min_width, sub_extremes[i].max_width);         }         sum_sub_min_widths += sub_extremes[i].min_width;      }      /* ---- STEP 2: Eventually, decrease them again.  ---- */      if (sum_sub_min_widths > width) {         sum_orig_sub_min_widths = 0;         for (i = 0; i < sub->num_subs; i++)            sum_orig_sub_min_widths += sub->subs[i].total_extremes.min_width;         rest_w = sum_sub_min_widths - (width -diff);         rest_n = sum_sub_min_widths - sum_orig_sub_min_widths;         for (i = 0; i < sub->num_subs; i++) {            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                       "          decreasing sub %d: %d -> ",                       i, sub_extremes[i].min_width);            if (sub_extremes[i].min_width !=                sub->subs[i].total_extremes.min_width) {               delta =                  rest_w * (sub_extremes[i].min_width                            - sub->subs[i].total_extremes.min_width) / rest_n;               rest_w -= delta;               rest_n -= (sub_extremes[i].min_width                          - sub->subs[i].total_extremes.min_width);            } else               delta = 0;            sub_width = sub_extremes[i].min_width - delta;            Dw_table_sub_calc_col_widths (&sub->subs[i], sub_width,                                          total_width);            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "%d\n", sub_width);         }      } else {         /* ---- STEP 3: Eventually, increase the sub-subtable extremes ---- */         num_nf_subs = 0;         num_nf_cols = 0;         sum_nf_sub_extremes.min_width = 0;         sum_nf_sub_extremes.max_width = 0;         for (i = 0; i < sub->num_subs; i++)            if (!(sub->subs[i].fixed_width ||                  sub->subs[i].use_percentage == USE_PERCENTAGE_ALL)) {               num_nf_cols += (sub->subs[i].end_col - sub->subs[i].start_col);               num_nf_subs++;               sum_nf_sub_extremes.min_width += sub_extremes[i].min_width;               sum_nf_sub_extremes.max_width += sub_extremes[i].max_width;            }         /* If all subtables are fixed, unfix them all. */         if (num_nf_subs == 0) {            num_nf_subs = -1;            num_nf_cols = num_cols;         }         Dw_table_sub_adjust_col_widths            (sub, FALSE, extremes.min_width, sub_extremes, num_nf_subs,             num_nf_cols, sum_nf_sub_extremes.min_width);         Dw_table_sub_adjust_col_widths            (sub, TRUE, extremes.max_width, sub_extremes, num_nf_subs,             num_nf_cols, sum_nf_sub_extremes.max_width);         /* ---- STEP 4: Finally, calculate the widths. ---- */         sub_status = g_new (gint, sub->num_subs);         /* First, assume that all columns have the same width. */         for (i = 0; i < sub->num_subs; i++)            sub_status[i] = AT_NORM;         do {            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3, "       columns: ");            /* Calculate the normal width, and the number of columns at this               width. */            width_norm_cols = avail_width;            num_norm_cols = num_cols;            for (i = 0; i < sub->num_subs; i++) {               if (sub_status[i] != AT_NORM) {                  num_norm_cols -=                     (sub->subs[i].end_col - sub->subs[i].start_col);                  if (sub_status[i] == AT_MIN)                     width_norm_cols -= sub_extremes[i].min_width;                  else                     width_norm_cols -= sub_extremes[i].max_width;               }               DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3, "%c", "ian"[sub_status[i]]);            }            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 3, "\n");            DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2, "       norm: %d, width = %d\n",                       num_norm_cols, width_norm_cols);            /*             * Iteratively, test for minimum/maximum, and correct the             * status. As soon as one test fails, the status is             * changed, and the iteration starts again from the             * beginning.             */            success = TRUE;            for (i = 0; success && i < sub->num_subs; i++) {               cols_per_sub = (sub->subs[i].end_col - sub->subs[i].start_col);               switch (sub_status[i]) {               case AT_NORM:                  /* Columns at normal width must between min and max. */                  if (width_norm_cols * cols_per_sub                      < num_norm_cols * sub_extremes[i].min_width) {                     DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                                "       sub %d at min\n", i);                     sub_status[i] = AT_MIN;                     success = FALSE;                  } else if (width_norm_cols * cols_per_sub                             > num_norm_cols * sub_extremes[i].max_width) {                     DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                                "       sub %d at max\n", i);                     sub_status[i] = AT_MAX;                     success = FALSE;                  }                  break;               case AT_MIN:                  /* If the column is at min, the the normal width (which has                     been changed), must tested against the min. */                  if (width_norm_cols * cols_per_sub                      > num_norm_cols * sub_extremes[i].min_width) {                     DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                                "       sub %d at norm\n", i);                     sub_status[i] = AT_NORM;                     success = FALSE;                  }                  break;               case AT_MAX:                  /* If the column is at max, the the normal width (which has                     been changed), must tested against the max. */                  if (width_norm_cols * cols_per_sub                      < num_norm_cols * sub_extremes[i].max_width) {                     DEBUG_MSG (DEBUG_WIDTH_LEVEL + 2,                                "       sub %d at norm\n", i);                     sub_status[i] = AT_NORM;                     success = FALSE;                  }                  break;               }            }         } while (!success);         /* ---- STEP 5: Apply calculate the widths. ---- */         rest_n= num_norm_cols;         rest_w = width_norm_cols;         for (i = 0; i < sub->num_subs; i++) {            if (sub_status[i] == AT_MIN)               sub_width = sub_extremes[i].min_width;            else if (sub_status[i] == AT_MAX)               sub_width = sub_extremes[i].max_width;            else {               cols_per_sub = (sub->subs[i].end_col - sub->subs[i].start_col);               sub_width = rest_w * cols_per_sub / rest_n;               rest_w -= sub_width;               rest_n-= cols_per_sub;            }            Dw_table_sub_calc_col_widths (&sub->subs[i], sub_width,                                          total_width);         }         g_free (sub_status);      }      g_free (sub_extremes);   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -