📄 dw_page.c
字号:
/* * Standard Dw function * * The ascent of a page is the ascent of the first line, plus * padding/border/margin. This can be used to align the first lines * of several pages in a horizontal line. */static void Dw_page_size_request (DwWidget *widget, DwRequisition *requisition){ DwPage *page = DW_PAGE (widget); DwPageLine *last_line; Dw_page_rewrap (page); if (page->num_lines > 0) { last_line = &page->lines[page->num_lines - 1]; requisition->width = MAX (last_line->max_line_width, page->last_line_width); /* Note: the break_space of the last line is ignored, so breaks at the end of a page are not visible. */ requisition->ascent = page->lines[0].ascent; requisition->descent = last_line->top + last_line->ascent + last_line->descent - page->lines[0].ascent; } else { requisition->width = page->last_line_width; requisition->ascent = 0; requisition->descent = 0; } requisition->width += page->inner_padding + p_Dw_style_box_diff_width (widget->style); requisition->ascent += p_Dw_style_box_offset_y (widget->style); requisition->descent += p_Dw_style_box_rest_height (widget->style); if (requisition->width < page->avail_width) requisition->width = page->avail_width;}/* * Get the extremes of a word within a page. */static void Dw_page_get_word_extremes (DwPageWord *word, DwExtremes *extremes){ if (word->content.type == DW_CONTENT_WIDGET) { if (DW_WIDGET_USES_HINTS (word->content.data.widget)) a_Dw_widget_get_extremes (word->content.data.widget, extremes); else { if (DW_STYLE_IS_PER_LENGTH(word->content.data.widget->style->width)) { extremes->min_width = 0; if (DW_WIDGET_HAS_CONTENT (word->content.data.widget)) extremes->max_width = DW_INFINITY; else extremes->max_width = 0; } else if (DW_STYLE_IS_ABS_LENGTH (word->content.data.widget->style->width)) { /* Fixed lengths are only applied to the content, so we have to * add padding, border and margin. */ extremes->min_width = extremes->max_width = DW_STYLE_ABS_LENGTH_VAL(word->content.data.widget->style->width) + p_Dw_style_box_diff_width(word->style); } else a_Dw_widget_get_extremes (word->content.data.widget, extremes); } } else { extremes->min_width = word->size.width; extremes->max_width = word->size.width; }}/* * Standard Dw function */static void Dw_page_get_extremes (DwWidget *widget, DwExtremes *extremes){ DwPage *page = DW_PAGE (widget); DwExtremes word_extremes; DwPageLine *line; DwPageWord *word; gint word_index, line_index; gint32 par_min, par_max; gboolean nowrap; DBG_MSG (widget, "extremes", 0, "Dw_page_get_extremes"); DBG_MSG_START (widget); if (page->num_lines == 0) { /* empty page */ extremes->min_width = 0; 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]; /* Historical note: The former distinction between lines with and without * words[first_word]->nowrap set is no longer necessary, since * Dw_page_real_word_wrap sets max_word_min to the correct value in any * case. */ extremes->min_width = line->max_word_min; extremes->max_width = MAX (line->max_par_max, page->last_line_par_max); DBG_MSG (widget, "extremes", 0, "simple case"); } else { /* Calculate the extremes, based on the values in the line from where a rewrap is necessary. */ DBG_MSG (widget, "extremes", 0, "complex case"); 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]; extremes->min_width = line->max_word_min; extremes->max_width = line->max_par_max; par_min = line->par_min; par_max = line->par_max; DBG_MSGF (widget, "extremes", 0, "par_min = %d", par_min); } _MSG ("*** par_min = %d\n", par_min); for (line_index = page->wrap_ref; line_index < page->num_lines; line_index++) { DBG_MSGF (widget, "extremes", 0, "line %d", line_index); DBG_MSG_START (widget); line = &page->lines[line_index]; nowrap = page->words[line->first_word].style->white_space != DW_STYLE_WHITE_SPACE_NORMAL; DEBUG_MSG (DEBUG_SIZE_LEVEL, " line %d (of %d), nowrap = %d\n", line_index, page->num_lines, 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 (!page->ignore_line1_offset_sometimes && word_index == 0) { word_extremes.min_width += page->line1_offset; DEBUG_MSG (DEBUG_SIZE_LEVEL + 1, " (next plus %d)\n", page->line1_offset); } if (nowrap) { par_min += word_extremes.min_width + word->orig_space; DBG_MSGF (widget, "extremes", 0, "par_min = %d", par_min); } 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 (DEBUG_SIZE_LEVEL + 1, " word %s: max_width = %d\n", a_Dw_content_text (&word->content), word_extremes.max_width); } if ( ( line->last_word > line->first_word && page->words[line->last_word - 1].content.type == DW_CONTENT_BREAK ) || line_index == page->num_lines - 1 ) { word = &page->words[line->last_word - 1]; par_max -= word->orig_space; DEBUG_MSG (DEBUG_SIZE_LEVEL + 2, " par_max = %d, after word %d (%s)\n", par_max, line->last_word - 1, a_Dw_content_text (&word->content)); if (extremes->max_width < par_max) extremes->max_width = par_max; if (nowrap) { par_min -= word->orig_space; DBG_MSGF (widget, "extremes", 0, "par_min = %d", par_min); if (extremes->min_width < par_min) extremes->min_width = par_min; DEBUG_MSG (DEBUG_SIZE_LEVEL + 2, " par_min = %d, after word %d (%s)\n", par_min, line->last_word - 1, a_Dw_content_text (&word->content)); } par_min = 0; par_max = 0; } DBG_MSG_END (widget); } DEBUG_MSG (DEBUG_SIZE_LEVEL + 3, " Result: %d, %d\n", extremes->min_width, extremes->max_width); } DBG_MSGF (widget, "extremes", 0, "width difference: %d + %d", page->inner_padding, p_Dw_style_box_diff_width (widget->style)); 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); DBG_MSG_END (widget);}/* * 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]); switch (word->content.type) { case DW_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 = allocation->y + Dw_page_line_total_y_offset_allocation (page, line, allocation) + (line->ascent - word->size.ascent) - word->content.data.widget->style->margin.top; child_allocation.width = word->size.width; child_allocation.ascent = word->size.ascent + word->content.data.widget->style->margin.top; child_allocation.descent = word->size.descent + word->content.data.widget->style->margin.bottom; a_Dw_widget_size_allocate (word->content.data.widget, &child_allocation); break; case DW_CONTENT_ANCHOR: p_Dw_gtk_viewport_put_anchor (widget, word->content.data.anchor, Dw_page_line_total_y_offset_allocation (page, line, allocation)); break; default: /* make compiler happy */ break; } 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); DBG_MSGF (page, "wrap", 0, "Dw_page_mark_size_change (ref = %d)", ref); if (page->wrap_ref == -1) page->wrap_ref = ref; else page->wrap_ref = MIN (page->wrap_ref, ref); DBG_OBJ_SET_NUM (page, "wrap_ref", page->wrap_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) { DEBUG_MSG(DEBUG_REWRAP_LEVEL, "Dw_page_set_width: Calling p_Dw_widget_queue_resize, " "in page with %d word(s)\n", page->num_words); 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) { DEBUG_MSG(DEBUG_REWRAP_LEVEL, "Dw_page_set_ascent: Calling p_Dw_widget_queue_resize, " "in page with %d word(s)\n", page->num_words); 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) { DEBUG_MSG(DEBUG_REWRAP_LEVEL, "Dw_page_set_descent: Calling p_Dw_widget_queue_resize, " "in page with %d word(s)\n", page->num_words); page->avail_descent = descent; p_Dw_widget_queue_resize (widget, 0, FALSE); page->must_queue_resize = FALSE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -