📄 dw_page.c
字号:
+ word->hl_start[layer], eff_hl_end - word->hl_start[layer]);#else GetTextExtent (hdc, word->content.data.text, word->hl_start[layer], &ext); start_hl = x_viewport + ext.cx; GetTextExtent (hdc, word->content.data.text + word->hl_start[layer], eff_hl_end - word->hl_start[layer], &ext); width_hl = ext.cx;#endif /* 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. */#if 0 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); 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);#else SetBrushColor (hdc, word_bg_color->inverse_pixel); FillBox (hdc, start_hl, y_viewport_base - word->size.ascent, width_hl, word->size.ascent + word->size.descent); SetTextColor (hdc, word->style->color->inverse_pixel); TextOutLen (hdc, start_hl, y_viewport_base + diff - line->ascent, word->content.data.text + word->hl_start[layer], eff_hl_end - word->hl_start[layer]); SetPenColor (hdc, word->style->color->inverse_pixel); if (word->style->text_decoration & DW_STYLE_TEXT_DECORATION_UNDERLINE) { MoveTo (hdc, start_hl, y_viewport_base + 1 + diff); LineTo (hdc, start_hl + width_hl - 1, y_viewport_base + 1 + diff); } if (word->style->text_decoration & DW_STYLE_TEXT_DECORATION_LINE_THROUGH) { MoveTo (hdc, start_hl, y_viewport_base - word->size.ascent / 2 + diff); LineTo (hdc, start_hl + width_hl - 1, y_viewport_base - word->size.ascent / 2 + diff); }#endif } } } break; case DW_CONTENT_WIDGET: child = word->content.data.widget; if (p_Dw_widget_intersect (child, area, &child_area)) a_Dw_widget_draw (child, hdc, &child_area); break; case DW_CONTENT_ANCHOR: case DW_CONTENT_BREAK: /* nothing - an anchor/break isn't seen */ /* BUG: sometimes anchors have x_space; * we subtract that just in case --EG */ 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 */ 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, HDC hdc, DwRectangle *area){ DwPage *page; gint line_index; DwPageLine *line; p_Dw_widget_draw_widget_box (widget, hdc, 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, hdc, line, area); }}/* * 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;}/* * Find a link given a coordinate location relative to the window */static gint Dw_page_find_link (DwPage *page, gint x, gint y){ gint word_index; if ((word_index = Dw_page_find_word (page, x, y)) == -1) return -1; else return page->words[word_index].style->x_link;}/* * 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;}#if 0/* * 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -