📄 dw_page.c
字号:
extremes->max_width = 0; } else if (page->wrap_ref == -1) { /* no rewrap necessary -> values in lines are up to date */ line = &page->lines[page->num_lines - 1]; if (page->words[line->first_word].style->nowrap) extremes->min_width = MAX (line->max_word_min, line->par_min); else extremes->min_width = line->max_word_min; extremes->max_width = MAX (line->max_par_max, line->par_max); } else { /* Calculate the extremes, based on the values in the line from where a rewrap is necessary. */ if (page->wrap_ref == 0) { extremes->min_width = 0; extremes->max_width = 0; par_min = 0; par_max = 0; } else { line = &page->lines[page->wrap_ref - 1]; extremes->min_width = line->max_word_min; extremes->max_width = line->max_par_max; par_min = line->par_min; par_max = line->par_max; } for (line_index = page->wrap_ref; line_index < page->num_lines; line_index++) { line = &page->lines[line_index]; nowrap = page->words[line->first_word].style->nowrap; for (word_index = line->first_word; word_index < line->last_word; word_index++) { word = &page->words[word_index]; Dw_page_get_word_extremes (word, &word_extremes); /* For the first word, we simply add the line1_offset. */ if (word_index == 0) { word_extremes.min_width += page->line1_offset; word_extremes.max_width += page->line1_offset; } if (nowrap) par_min += word_extremes.min_width + word->orig_space; else if (extremes->min_width < word_extremes.min_width) extremes->min_width = word_extremes.min_width; par_max += word_extremes.max_width + word->orig_space; DEBUG_MSG (1, " word \"%s\": max_width = %d\n", word->content_type == DW_PAGE_CONTENT_TEXT ? word->content.text : "<no text>", word_extremes.max_width); } if ( ( line->last_word > line->first_word && page->words[line->last_word - 1].content_type == DW_PAGE_CONTENT_BREAK ) || line_index == page->num_lines - 1 ) { word = &page->words[line->last_word - 1]; par_max -= word->orig_space; DEBUG_MSG (2, " par_max = %d, after word %d (\"%s\")\n", par_max, line->last_word - 1, word->content_type == DW_PAGE_CONTENT_TEXT ? word->content.text : "<no text>"); if (extremes->max_width < par_max) extremes->max_width = par_max; if (nowrap) { par_min -= word->orig_space; if (extremes->min_width < par_min) extremes->min_width = par_min; } par_min = 0; par_max = 0; } } DEBUG_MSG (3, " Result: %d, %d\n", extremes->min_width, extremes->max_width); } extremes->min_width += page->inner_padding + p_Dw_style_box_diff_width (widget->style); extremes->max_width += page->inner_padding + p_Dw_style_box_diff_width (widget->style);}/* * Standard Dw function */static void Dw_page_size_allocate (DwWidget *widget, DwAllocation *allocation){ DwPage *page; int line_index, word_index; DwPageLine *line; DwPageWord *word; int x_cursor; DwAllocation child_allocation; page = DW_PAGE (widget); for (line_index = 0; line_index < page->num_lines; line_index++) { line = &(page->lines[line_index]); 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]); if (word->content_type == DW_PAGE_CONTENT_WIDGET) { /* todo: justification within the line is done here! */ child_allocation.x = x_cursor + allocation->x; /* align=top: child_allocation.y = line->top + allocation->y; */ /* align=bottom (base line) */ child_allocation.y = line->top + allocation->y + (line->ascent - word->size.ascent); child_allocation.width = word->size.width; child_allocation.ascent = word->size.ascent; child_allocation.descent = word->size.descent; a_Dw_widget_size_allocate (word->content.widget, &child_allocation); } x_cursor += (word->size.width + word->eff_space); } }}/* * Implementation for both mark_size_change and mark_extremes_change. */static void Dw_page_mark_change (DwWidget *widget, gint ref){ DwPage *page; if (ref != -1) { page = DW_PAGE (widget); if (page->wrap_ref == -1) page->wrap_ref = ref; else page->wrap_ref = MIN(page->wrap_ref, ref); }}/* * Standard Dw function */static void Dw_page_set_width (DwWidget *widget, gint32 width){ DwPage *page; page = DW_PAGE (widget); /* If limit_text_width is set to YES, a queue_resize may also be necessary. */ if (page->avail_width != width || prefs.limit_text_width) { page->avail_width = width; p_Dw_widget_queue_resize (widget, 0, FALSE); page->must_queue_resize = FALSE; }}/* * Standard Dw function */static void Dw_page_set_ascent (DwWidget *widget, gint32 ascent){ DwPage *page; page = DW_PAGE (widget); if (page->avail_ascent != ascent) { page->avail_ascent = ascent; p_Dw_widget_queue_resize (widget, 0, FALSE); page->must_queue_resize = FALSE; }}/* * Standard Dw function */static void Dw_page_set_descent (DwWidget *widget, gint32 descent){ DwPage *page; page = DW_PAGE (widget); if (page->avail_descent != descent) { page->avail_descent = descent; p_Dw_widget_queue_resize (widget, 0, FALSE); page->must_queue_resize = FALSE; }}/* * Standard Dw function */static void Dw_page_add (DwContainer *container, DwWidget *widget){ /* todo */}/* * Standard Dw function */static void Dw_page_remove (DwContainer *container, DwWidget *widget){ /* todo */}/* * Standard Dw function */static void Dw_page_forall (DwContainer *container, DwCallback callback, gpointer callback_data){ DwPage *page; int word_index; DwPageWord *word; page = DW_PAGE (container); for(word_index = 0; word_index < page->num_words; word_index++) { word = &page->words[word_index]; if (word->content_type == DW_PAGE_CONTENT_WIDGET) (*callback) (word->content.widget, callback_data); }}/* * This function is called in two cases: (i) when a word is added (by * Dw_page_add_word), and (ii) when a page has to be (partially) * rewrapped. It does word wrap, and adds new lines, if necesary. */static void Dw_page_word_wrap (DwPage *page, gint word_ind){ DwPageLine *last_line, *plast_line; DwPageWord *word, *last_word; gint32 avail_width, last_space, left_offset; gboolean new_line = FALSE, new_par = FALSE; DwWidget *widget = DW_WIDGET (page); DwExtremes word_extremes; avail_width = page->avail_width - p_Dw_style_box_diff_width(widget->style) - page->inner_padding; if (prefs.limit_text_width && avail_width > widget->viewport->allocation.width - 10) avail_width = widget->viewport->allocation.width - 10; word = &page->words[word_ind]; if (page->num_lines == 0) { new_line = TRUE; new_par = TRUE; last_line = NULL; } else { last_line = &page->lines[page->num_lines - 1]; if (page->num_words > 0) { last_word = &page->words[word_ind - 1]; if (last_word->content_type == DW_PAGE_CONTENT_BREAK) { /* last word is a break */ new_line = TRUE; new_par = TRUE; } else if (word->style->nowrap) { new_line = FALSE; new_par = FALSE; } else { if (last_line->first_word != word_ind) { /* does new word fit into the last line? */ new_line = (page->last_line_width + last_word->orig_space + word->size.width > avail_width); } } } } /* Has sometimes the wrong value. */ word->eff_space = word->orig_space; if (last_line != NULL && new_line && !new_par && word->style->text_align == DW_STYLE_TEXT_ALIGN_JUSTIFY) { /* Justified lines. To avoid rounding errors, the calculation is based on accumulated values (*_cum). */ gint i; gint32 orig_space_sum, orig_space_cum; gint32 eff_space_diff_cum, last_eff_space_diff_cum; gint32 diff; diff = avail_width - page->last_line_width; if (diff > 0) { orig_space_sum = 0; for (i = last_line->first_word; i < last_line->last_word - 1; i++) orig_space_sum += page->words[i].orig_space; orig_space_cum = 0; last_eff_space_diff_cum = 0; for (i = last_line->first_word; i < last_line->last_word - 1; i++) { orig_space_cum += page->words[i].orig_space; if (orig_space_cum == 0) eff_space_diff_cum = last_eff_space_diff_cum; else eff_space_diff_cum = diff * orig_space_cum / orig_space_sum; page->words[i].eff_space = page->words[i].orig_space + (eff_space_diff_cum - last_eff_space_diff_cum); last_eff_space_diff_cum = eff_space_diff_cum; } } } if (new_line) { /* Add a new line. */ page->num_lines++; a_List_add(page->lines, page->num_lines, page->num_lines_max); last_line = &page->lines[page->num_lines - 1]; if (page->num_lines == 1) plast_line = NULL; else plast_line = &page->lines[page->num_lines - 2]; if (plast_line) { /* second or more lines: copy values of last line */ last_line->top = plast_line->top + plast_line->ascent + plast_line->descent + plast_line->break_space; last_line->max_line_width = plast_line->max_line_width; last_line->max_word_min = plast_line->max_word_min; last_line->max_par_max = plast_line->max_par_max; last_line->par_min = plast_line->par_min; last_line->par_max = plast_line->par_max; } else { /* first line: initialize values */ last_line->top = p_Dw_style_box_offset_y (DW_WIDGET(page)->style); last_line->max_line_width = page->line1_offset; last_line->max_word_min = 0; last_line->max_par_max = 0; last_line->par_min = page->line1_offset; last_line->par_max = page->line1_offset; } last_line->first_word = last_line->last_word = word_ind; last_line->ascent = 0; last_line->descent = 0; last_line->break_space = 0; last_line->left_offset = 0; /* update values in line */ last_line->max_line_width = MAX (last_line->max_line_width, page->last_line_width); if (page->num_lines > 1) page->last_line_width = 0; else page->last_line_width = page->line1_offset; if (new_par) { last_line->max_par_max = MAX (last_line->max_par_max, last_line->par_max); if (page->num_lines > 1) { last_line->par_min = 0; last_line->par_max = 0; } else { last_line->par_min = page->line1_offset; last_line->par_max = page->line1_offset; } } } last_line->last_word = word_ind + 1; last_line->ascent = MAX (last_line->ascent, word->size.ascent); last_line->descent = MAX (last_line->descent, word->size.descent);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -