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

📄 dw_page.c

📁 浏览器的源代码,可移植到嵌入式设备.
💻 C
📖 第 1 页 / 共 5 页
字号:
                  if (word->style->text_decoration                      & DW_STYLE_TEXT_DECORATION_LINE_THROUGH)                     gdk_draw_line (window, hl_gc,                                    start_hl,                                    y_viewport_base                                    - word->size.ascent / 2 + diff,                                    start_hl + width_hl - 1,                                    y_viewport_base                                    - word->size.ascent / 2 + diff);               }            }         }         break;      case DW_CONTENT_WIDGET:         child = word->content.data.widget;         if (p_Dw_widget_intersect (child, area, &child_area))            a_Dw_widget_draw (child, &child_area, event);         break;      case DW_CONTENT_ANCHOR: case DW_CONTENT_BREAK:         /* nothing - an anchor/break isn't seen */         /*          * Historical note:          * > BUG: sometimes anchors have x_space;          * > we subtract that just in case --EG          * This is inconsistent with other parts of the code, so it should          * be tried to prevent this earlier.--SG          */         /*          * x_viewport -= word->size.width + word->eff_space;          * x_widget -= word->size.width + word->eff_space;          */#if 0         /* Useful for testing: draw breaks. */         if (word->content.type == DW_CONTENT_BREAK)            gdk_draw_rectangle (window, gc, TRUE,                                p_Dw_widget_x_world_to_viewport (widget,                                   widget->allocation.x +                                      Dw_page_line_total_x_offset(page, line)),                                y_viewport_base + line->descent,                                DW_WIDGET_CONTENT_WIDTH(widget),                                word->content.data.break_space);#endif         break;      default:         g_warning ("BUG!!! at (%d, %d).", x_viewport, y_viewport_base + diff);         break;      }      x_viewport += word->size.width + word->eff_space;      x_widget += word->size.width + word->eff_space;   }}/* * Find the first line index that includes y, relative to top of widget. */static gint Dw_page_find_line_index (DwPage *page, gint y){   gint max_index = page->num_lines - 1;   gint step, index, low = 0;   step = (page->num_lines + 1) >> 1;   while ( step > 1 ) {      index = low + step;      if (index <= max_index &&          Dw_page_line_total_y_offset_i (page, index) < y)         low = index;      step = (step + 1) >> 1;   }   if (low < max_index && Dw_page_line_total_y_offset_i (page, low + 1) < y)      low++;   /*    * This new routine returns the line number between (top) and    * (top + size.ascent + size.descent + break_space): the space    * _below_ the line is considered part of the line.  Old routine    * returned line number between (top - previous_line->break_space)    * and (top + size.ascent + size.descent): the space _above_ the    * line was considered part of the line.  This is important for    * Dw_page_find_link() --EG    * That function has now been inlined into Dw_page_motion_notify() --JV    */   return low;}/* * Find the line of word <word_index>. */static gint Dw_page_find_line_of_word (DwPage *page, gint word_index){   gint high = page->num_lines - 1, index, low = 0;   g_return_val_if_fail (word_index >= 0, -1);   g_return_val_if_fail (word_index < page->num_words, -1);   while (TRUE) {      index = (low + high) / 2;      if (word_index >= page->lines[index].first_word) {         if (word_index < page->lines[index].last_word)            return index;         else            low = index + 1;      } else         high = index - 1;   }}/* * Draw the actual lines, starting at (x, y) in toplevel Dw coords. * (former Dw_page_expose_lines) */static void Dw_page_draw (DwWidget *widget,                          DwRectangle *area,                          GdkEventExpose *event){   DwPage *page;   gint line_index;   DwPageLine *line;   p_Dw_widget_draw_widget_box (widget, area, FALSE);   page = DW_PAGE (widget);   line_index = Dw_page_find_line_index (page, area->y);   for (; line_index < page->num_lines; line_index++) {      line = &(page->lines[line_index]);      if (Dw_page_line_total_y_offset(page, line) >= area->y + area->height)         break;      Dw_page_draw_line (page, line, area, event);   }}/* * Find the index of the word, or -1. */static gint Dw_page_find_word (DwPage *page, gint x, gint y){   gint line_index, word_index;   gint x_cursor, last_x_cursor;   DwPageLine *line;   DwPageWord *word;   if ( (line_index = Dw_page_find_line_index (page, y)) >= page->num_lines )      return -1;   line = &page->lines[line_index];   if (Dw_page_line_total_y_offset(page, line) + line->ascent + line->descent       <= y)      return -1;   x_cursor = Dw_page_line_total_x_offset (page, line);   for (word_index = line->first_word; word_index < line->last_word;        word_index++) {      word = &page->words[word_index];      last_x_cursor = x_cursor;      x_cursor += word->size.width + word->eff_space;      if (last_x_cursor <= x && x_cursor > x)         return word_index;   }   return -1;}/* * Construct an iterator for a word. */static DwIterator *Dw_page_construct_iterator (DwPage *page, gint word_index){   DwIterator *it;   it = Dw_page_iterator (DW_WIDGET (page), DW_CONTENT_ALL, FALSE);   //DW_CONTENT_TEXT | DW_CONTENT_WIDGET, FALSE);   ((DwIteratorInt*)it)->pos = word_index;   it->content = page->words[word_index].content;   return it;}/* * Send event to selection. */static gboolean Dw_page_send_selection_event (DwPage *page,                                              gint (*fn) (Selection*,                                                          DwIterator *,                                                          gint, gint,                                                          GdkEventButton*,                                                          gboolean                                                             within_content),                                              gint32 x, gint32 y,                                              GdkEventButton *event){   DwIterator *it;   DwPageLine *line, *last_line;   gint32 next_word_start_x, word_start_x, word_x, next_word_x, yfirst, ylast;   gint char_pos = 0, word_index, line_index, link;   DwPageWord *word;   gboolean found;   gboolean within_content;   DEBUG_MSG (DEBUG_EVENT_LEVEL,              "Dw_page_send_selection_event: x = %d, y = %d\n", x, y);   if (page->num_words == 0) {      DEBUG_MSG (DEBUG_EVENT_LEVEL, "  no words\n");      return FALSE;   }   /* In most cases true, so set here: */   link = -1;   within_content = TRUE;   last_line = &page->lines[page->num_lines - 1];   yfirst = Dw_page_line_total_y_offset_i (page, 0);   ylast =      Dw_page_line_total_y_offset (page, last_line) +      last_line->ascent + last_line->descent;   if (y < yfirst) {      /* Above the first line: take the first word. */      DEBUG_MSG (DEBUG_EVENT_LEVEL, "  above first line (at %d)\n", yfirst);      within_content = FALSE;      word_index = 0;      char_pos = 0;   } else if (y >= ylast) {      /* Below the last line: take the last word. */      DEBUG_MSG (DEBUG_EVENT_LEVEL, "  below last line (at %d)\n", ylast);      within_content = FALSE;      word_index = page->num_words - 1;      word = &page->words[word_index];      char_pos = word->content.type == DW_CONTENT_TEXT ?         strlen (word->content.data.text) : 0;   } else {      line_index = Dw_page_find_line_index (page, y);      line = &page->lines[line_index];      DEBUG_MSG (DEBUG_EVENT_LEVEL, "  in line %d\n", line_index);      /* Pointer within the break space? */      if (y > (Dw_page_line_total_y_offset(page, line) + line->ascent +               line->descent)) {         /* Choose this break. */         DEBUG_MSG (DEBUG_EVENT_LEVEL, "    break\n");         within_content = FALSE;         word_index = line->last_word - 1;         char_pos = 0;      } else if (x < Dw_page_line_total_x_offset (page, line)) {         /* Left of the first word in the line. */         DEBUG_MSG (DEBUG_EVENT_LEVEL, "    left of this line\n");         word_index = line->first_word;         within_content = FALSE;         char_pos = 0;      } else {         next_word_start_x = Dw_page_line_total_x_offset (page, line);         found = FALSE;         for (word_index = line->first_word;              !found && word_index < line->last_word;              word_index++) {            word = &page->words[word_index];            word_start_x = next_word_start_x;            next_word_start_x += word->size.width + word->eff_space;            DEBUG_MSG (DEBUG_EVENT_LEVEL,                       "    word %d (%s) from %d to %d, delta = %d + %d\n",                       word_index, a_Dw_content_text (&word->content),                       word_start_x, next_word_start_x,                       word->size.width, word->eff_space);            if (x >= word_start_x && x < next_word_start_x) {               DEBUG_MSG (DEBUG_EVENT_LEVEL,                          "    found word %d (%s)\n",                          word_index, a_Dw_content_text (&word->content));               /* We have found the word. */               if (word->content.type == DW_CONTENT_TEXT) {                  /* Search the character the mouse pointer is in.                   * next_word_x is the right side of this character. */                  char_pos = 0;                  while ((next_word_x = word_start_x +                          gdk_text_width(word->style->font->font,                                         word->content.data.text,                                         char_pos))                         <= x)                     char_pos++;                  /* The left side of this character. */                  word_x =                     word_start_x + gdk_text_width (word->style->font->font,                                                    word->content.data.text,                                                    char_pos - 1);                  /* If the mouse pointer is left from the middle, use the left                   * position, otherwise, use the right one. */                  if (x <= (word_x + next_word_x) / 2)                     char_pos--;               } else {                  /* Depends on whether the pointer is within the left or                   * right half of the (non-text) word. */                  if (x >= (word_start_x + next_word_start_x) / 2)                     char_pos = SELECTION_EOW;                  else                     char_pos = 0;               }               found = TRUE;               link = word->style ? word->style->x_link : -1;               break;            }         }         if (!found) {            /* No word found in this line (i.e. we are on the right side),             * take the last of this line. */            DEBUG_MSG (DEBUG_EVENT_LEVEL, "    not found\n");            within_content = FALSE;            word_index = line->last_word - 1;            if (word_index >= page->num_words)               word_index--;            word = &page->words[word_index];            char_pos = word->content.type == DW_CONTENT_TEXT ?               strlen (word->content.data.text) : SELECTION_EOW;         }      }   }   word = &page->words[word_index];   it = Dw_page_construct_iterator (page, word_index);   DEBUG_MSG (DEBUG_EVENT_LEVEL, "-> word %d (of %d), char %d, link %d: %s\n",              word_index, page->num_words, char_pos, link,              a_Dw_iterator_text (it));   return fn (GTK_DW_VIEWPORT(DW_WIDGET(page)->viewport)->selection,              it, char_pos, link, event, within_content);}/* * Standard Dw function. */static gboolean Dw_page_button_press  (DwWidget *widget,                                       gint32 x,                                       gint32 y,                                       GdkEventButton *event){   return Dw_page_send_selection_event (DW_PAGE (widget),                                        a_Selection_button_press, x, y,                                        event);}/* * Standard Dw function. */static gboolean Dw_page_button_release (DwWidget *widget,                                        gint32 x,                                        gint32 y,                                        GdkEventButton *event){   return Dw_page_send_selection_event (DW_PAGE (widget),                                        a_Selection_button_release, x, y,                                        event);}/* * Standard Dw function. */static gbool

⌨️ 快捷键说明

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