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

📄 dw_page.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 5 页
字号:
      case DW_STYLE_TEXT_ALIGN_JUSTIFY:  /* see some lines above */      case DW_STYLE_TEXT_ALIGN_STRING:   /* handled elsewhere (in future) */         left_offset = 0;         break;      case DW_STYLE_TEXT_ALIGN_RIGHT:         left_offset = avail_width - page->last_line_width;         break;      case DW_STYLE_TEXT_ALIGN_CENTER:         left_offset = (avail_width - page->last_line_width) / 2;         break;      default:         /* compiler happiness */         left_offset = 0;      }      /* For large lines (images etc), which do not fit into the viewport: */      if (left_offset < 0)         left_offset = 0;      if (page->list_item && last_line == page->lines) {         /* List item markers are always on the left. */         last_line->left_offset = 0;         page->words[0].eff_space = page->words[0].orig_space + left_offset;         DBG_OBJ_ARRSET_NUM (page, "words.%d.eff_space", 0,                             page->words[0].eff_space);      } else         last_line->left_offset = left_offset;   }   page->must_queue_resize = TRUE;   DBG_MSG_END (page);}/* * Calculate the size of a widget within the page. * (Subject of change in the near future!) */static void Dw_page_calc_widget_size (DwPage *page,                                      DwWidget *widget,                                      DwRequisition *size){   DwRequisition requisition;   gint32 avail_width, avail_ascent, avail_descent;   /* We ignore line1_offset[_eff]. */   avail_width =      page->avail_width - p_Dw_style_box_diff_width (DW_WIDGET(page)->style)      - page->inner_padding;   avail_ascent =      page->avail_ascent - p_Dw_style_box_diff_height (DW_WIDGET(page)->style);   avail_descent = page->avail_descent;   if (DW_WIDGET_USES_HINTS (widget)) {      a_Dw_widget_set_width (widget, avail_width);      a_Dw_widget_set_ascent (widget, avail_ascent);      a_Dw_widget_set_descent (widget, avail_descent);      a_Dw_widget_size_request (widget, size);      size->ascent -= widget->style->margin.top;      size->descent -= widget->style->margin.bottom;   } else {      /* TODO: Use margin.{top|bottom} here, like above.       * (No harm for the next future.) */      if (widget->style->width == DW_STYLE_LENGTH_AUTO ||          widget->style->height == DW_STYLE_LENGTH_AUTO)         a_Dw_widget_size_request (widget, &requisition);      if (widget->style->width == DW_STYLE_LENGTH_AUTO)         size->width = requisition.width;      else if (DW_STYLE_IS_ABS_LENGTH (widget->style->width))         /* Fixed lengths are only applied to the content, so we have to          * add padding, border and margin. */         size->width = DW_STYLE_ABS_LENGTH_VAL (widget->style->width)            + p_Dw_style_box_diff_width (widget->style);      else         size->width =            DW_STYLE_PER_LENGTH_VAL (widget->style->width) * avail_width;      if (widget->style->height == DW_STYLE_LENGTH_AUTO) {         size->ascent = requisition.ascent;         size->descent = requisition.descent;      } else if (DW_STYLE_IS_ABS_LENGTH (widget->style->height)) {         /* Fixed lengths are only applied to the content, so we have to          * add padding, border and margin. */         size->ascent =            DW_STYLE_ABS_LENGTH_VAL (widget->style->height)            + p_Dw_style_box_diff_height (widget->style);         size->descent = 0;      } else {         size->ascent =            DW_STYLE_PER_LENGTH_VAL (widget->style->height) * avail_ascent;         size->descent =            DW_STYLE_PER_LENGTH_VAL (widget->style->height) * avail_descent;      }   }}/* * Rewrap the page from the line from which this is necessary. * There are basically two times we'll want to do this: * either when the viewport is resized, or when the size changes on one * of the child widgets. */static void Dw_page_rewrap (DwPage *page){   DwWidget *widget;   gint i, word_index;   DwPageWord *word;   DwPageLine *last_line;   if (page->wrap_ref == -1)      /* page does not have to be rewrapped */      return;   widget = DW_WIDGET (page);   DBG_MSGF (page, "wrap", 0,             "Dw_page_rewrap: page->wrap_ref = %d, in page with %d word(s)",             page->wrap_ref, page->num_words);   DBG_MSG_START (page);   /* All lines up from page->wrap_ref will be rebuild from the word list,    * the line list up from this position is rebuild. */   page->num_lines = page->wrap_ref;   page->last_line_width = 0;   DBG_OBJ_SET_NUM(page, "num_lines", page->num_lines);   DBG_OBJ_SET_NUM(page, "last_line_width", page->last_line_width);   /* In the word list, we start at the last word, plus one (see definition    * of last_word), in the line before. */   if (page->wrap_ref > 0) {      /* Note: In this case, Dw_page_real_word_wrap will immediately find       * the need to rewrap the line, since we start with the last one (plus       * one). This is also the reason, why page->last_line_width is set       * to the length of the line. */      last_line = &page->lines[page->num_lines - 1];      page->last_line_par_min = last_line->par_min;      page->last_line_par_max = last_line->par_max;      word_index = last_line->last_word;      for (i = last_line->first_word; i < last_line->last_word - 1; i++)         page->last_line_width += (page->words[i].size.width +                                   page->words[i].orig_space);      page->last_line_width +=         page->words[last_line->last_word - 1].size.width;   } else {      page->last_line_par_min = 0;      page->last_line_par_max = 0;      word_index = 0;   }   for (; word_index < page->num_words; word_index++) {      word = &page->words[word_index];      if (word->content.type == DW_CONTENT_WIDGET)         Dw_page_calc_widget_size (page, word->content.data.widget,                                   &word->size);      Dw_page_word_wrap (page, word_index);      if (word->content.type == DW_CONTENT_WIDGET) {         word->content.data.widget->parent_ref = page->num_lines - 1;         DBG_OBJ_SET_NUM (word->content.data.widget, "parent_ref",                          word->content.data.widget->parent_ref);      }      DEBUG_MSG(DEBUG_REWRAP_LEVEL,                "Assigning parent_ref = %d to rewrapped word %d, "                "in page with %d word(s)\n",                page->num_lines - 1, word_index, page->num_words);      if ( word->content.type == DW_CONTENT_ANCHOR )         p_Dw_gtk_viewport_put_anchor            (widget, word->content.data.anchor,             Dw_page_line_total_y_offset (page,                                          &page->lines[page->num_lines - 1]));   }   /* Next time, the page will not have to be rewrapped. */   page->wrap_ref = -1;   DBG_MSG_END (page);}/* * Paint a line * - x and y are toplevel dw coordinates (Question: what Dw? Changed. Test!) * - area is used always (ev. set it to event->area) * - event is only used when is_expose */static void Dw_page_draw_line (DwPage *page,                               DwPageLine *line,                               DwRectangle *area,                               GdkEventExpose *event){   DwWidget *widget;   DwPageWord *word;   gint word_index;   gint32 x_widget, y_widget, x_viewport, y_viewport, y_viewport_base;   gint32 start_hl, width_hl;   gint32 diff, word_len, eff_hl_end, layer;   DwWidget *child;   DwRectangle child_area;   GdkWindow *window;   GdkGC *gc, *hl_gc;   DwStyleColor *page_bg_color, *word_bg_color;   /* Here's an idea on how to optimize this routine to minimize the number    * of calls to gdk_draw_string:    *    * Copy the text from the words into a buffer, adding a new word    * only if: the attributes match, and the spacing is either zero or    * equal to the width of ' '. In the latter case, copy a " " into    * the buffer. Then draw the buffer. */   widget = DW_WIDGET (page);   window = DW_WIDGET_WINDOW (widget);   page_bg_color = p_Dw_widget_get_bg_color (widget);   x_widget = Dw_page_line_total_x_offset(page,line);   x_viewport =      p_Dw_widget_x_world_to_viewport (widget,                                       widget->allocation.x + x_widget);   y_widget = Dw_page_line_total_y_offset(page,line);   y_viewport =      p_Dw_widget_y_world_to_viewport (widget,                                       widget->allocation.y + y_widget);   y_viewport_base = y_viewport + line->ascent;   for (word_index = line->first_word; word_index < line->last_word;        word_index++) {      word = &page->words[word_index];      diff = 0;      gc = word->style->color->gc;      DBG_OBJ_ARRSET_NUM (page, "words.%d.<i>drawn at</i>.x", word_index,                          x_widget);      DBG_OBJ_ARRSET_NUM (page, "words.%d.<i>drawn at</i>.y", word_index,                          y_widget);      switch (word->content.type) {      case DW_CONTENT_TEXT:         if (word->style->background_color)            word_bg_color = word->style->background_color;         else            word_bg_color = page_bg_color;         /* Adjust the text baseline if the word is <SUP>-ed or <SUB>-ed. */         if (word->style->valign == DW_STYLE_VALIGN_SUB)            diff = word->size.ascent / 2;         else if (word->style->valign == DW_STYLE_VALIGN_SUPER)            diff -= word->size.ascent / 3;         /* Draw background (color, image), when given. */         /* todo: Test (word->style->background_color) is incomplete, and          * should in future include background images. */         if (word->style->background_color &&             word->size.width > 0)            p_Dw_widget_draw_box (widget, word->style, area,                                  x_widget,                                  y_widget + line->ascent - word->size.ascent,                                  word->size.width,                                  word->size.ascent + word->size.descent,                                  FALSE);         /* Draw space background (color, image), when given. */         /* todo: Test (word->space_style->background_color) is incomplete, and          * should in future include background images. */         if (word->space_style->background_color &&             word->eff_space > 0)            p_Dw_widget_draw_box (widget, word->space_style, area,                                  x_widget + word->size.width,                                  y_widget + line->ascent - word->size.ascent,                                  word->eff_space,                                  word->size.ascent + word->size.descent,                                  FALSE);         gdk_draw_string (window, word->style->font->font, gc,                          x_viewport, y_viewport_base + diff,                          word->content.data.text);         /* underline */         if (word->style->text_decoration & DW_STYLE_TEXT_DECORATION_UNDERLINE)            gdk_draw_line (window, gc,                           x_viewport, y_viewport_base + 1 + diff,                           x_viewport + word->size.width - 1,                           y_viewport_base + 1 + diff);         if (word_index + 1 < line->last_word &&             (word->space_style->text_decoration              & DW_STYLE_TEXT_DECORATION_UNDERLINE))            gdk_draw_line (window, gc,                           x_viewport + word->size.width,                           y_viewport_base + 1 + diff,                           x_viewport + word->size.width + word->eff_space - 1,                           y_viewport_base + 1 + diff);         /* strike-through */         if (word->style->text_decoration             & DW_STYLE_TEXT_DECORATION_LINE_THROUGH)            gdk_draw_line (window, gc,                           x_viewport,                           y_viewport_base - word->size.ascent / 2 + diff,                           x_viewport + word->size.width - 1,                           y_viewport_base - word->size.ascent / 2 + diff);         if (word_index + 1 < line->last_word &&             (word->space_style->text_decoration              & DW_STYLE_TEXT_DECORATION_LINE_THROUGH))            gdk_draw_line (window, gc,                           x_viewport + word->size.width,                           y_viewport_base - word->size.ascent / 2 + diff,                           x_viewport + word->size.width + word->eff_space - 1,                           y_viewport_base - word->size.ascent / 2 + diff);         for (layer = 0; layer < DW_HIGHLIGHT_NUM_LAYERS; layer++) {            if (word->hl_start[layer] != -1) {               word_len = strlen (word->content.data.text);               eff_hl_end = MIN (word_len, word->hl_end[layer]);               start_hl = x_viewport +                  gdk_text_width (word->style->font->font,                                  word->content.data.text,                                  word->hl_start[layer]);               width_hl =                  gdk_text_width (word->style->font->font,                                  word->content.data.text                                  + word->hl_start[layer],                                  eff_hl_end - word->hl_start[layer]);               /* If the space after this word highlighted, and this word                * is not the last one in this line, highlight also the                * space. */               /* todo: This should also be done with spaces after non-text                * words, but this is not yet defined very well. */               if (word->hl_end[layer] > eff_hl_end &&                   word_index < page->num_words &&                   word_index != line->last_word - 1)                  width_hl += word->eff_space;               if (width_hl != 0) {                  /* Draw background for highlighted text. */                  gdk_draw_rectangle (window, word_bg_color->inverse_gc,                                      TRUE, start_hl,                                      y_viewport_base - word->size.ascent,                                      width_hl,                                      word->size.ascent + word->size.descent);                  /* Highlight the text. */                  hl_gc = word->style->color->inverse_gc;                  gdk_draw_text (window, word->style->font->font, hl_gc,                                 start_hl, y_viewport_base + diff,                                 word->content.data.text                                 + word->hl_start[layer],                                 eff_hl_end - word->hl_start[layer]);                  /* underline and strike-through */                  if (word->style->text_decoration                      & DW_STYLE_TEXT_DECORATION_UNDERLINE)                     gdk_draw_line (window, hl_gc,                                    start_hl, y_viewport_base + 1 + diff,                                    start_hl + width_hl - 1,                                    y_viewport_base + 1 + diff);

⌨️ 快捷键说明

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