pango r2542 - in trunk: . docs docs/tmpl pango pango-view
- From: behdad svn gnome org
- To: svn-commits-list gnome org
- Subject: pango r2542 - in trunk: . docs docs/tmpl pango pango-view
- Date: Tue, 15 Jan 2008 01:20:44 +0000 (GMT)
Author: behdad
Date: Tue Jan 15 01:20:44 2008
New Revision: 2542
URL: http://svn.gnome.org/viewvc/pango?rev=2542&view=rev
Log:
2008-01-14 Behdad Esfahbod <behdad gnome org>
Bug 469313 â Add pango_layout_set_height()
Bug 508179 â PangoGlyphUnit confusion
* pango/pango-layout.h:
* pango/pango-layout-private.h:
* pango/pango-layout.c:
* pango/ellipsize.c (_pango_layout_line_ellipsize):
New public API:
pango_layout_set_height()
See docs for semantics. Currently only negative height values (number
of lines) is implemented.
* pango-view/viewer-render.c (make_layout), (output_body),
(parse_options):
Implement --height.
* pango/pango.def:
* docs/pango-sections.txt:
* docs/tmpl/layout.sgml:
Update.
2008-01-14 Behdad Esfahbod <behdad gnome org>
Bug 508179 â PangoGlyphUnit confusion
* pango/pangowin32.c:
* pango/glyphstring.c:
* pango/pango-layout.c (process_item): Remove all traces of
#PangoGlyphUnit
Modified:
trunk/ChangeLog
trunk/docs/pango-sections.txt
trunk/docs/tmpl/layout.sgml
trunk/pango-view/viewer-render.c
trunk/pango/ellipsize.c
trunk/pango/glyphstring.c
trunk/pango/pango-layout-private.h
trunk/pango/pango-layout.c
trunk/pango/pango-layout.h
trunk/pango/pango.def
trunk/pango/pangowin32.c
Modified: trunk/docs/pango-sections.txt
==============================================================================
--- trunk/docs/pango-sections.txt (original)
+++ trunk/docs/pango-sections.txt Tue Jan 15 01:20:44 2008
@@ -448,6 +448,8 @@
pango_layout_get_font_description
pango_layout_set_width
pango_layout_get_width
+pango_layout_set_height
+pango_layout_get_height
pango_layout_set_wrap
pango_layout_get_wrap
pango_layout_is_wrapped
Modified: trunk/docs/tmpl/layout.sgml
==============================================================================
--- trunk/docs/tmpl/layout.sgml (original)
+++ trunk/docs/tmpl/layout.sgml Tue Jan 15 01:20:44 2008
@@ -192,6 +192,24 @@
@Returns:
+<!-- ##### FUNCTION pango_layout_set_height ##### -->
+<para>
+
+</para>
+
+ layout:
+ height:
+
+
+<!-- ##### FUNCTION pango_layout_get_height ##### -->
+<para>
+
+</para>
+
+ layout:
+ Returns:
+
+
<!-- ##### FUNCTION pango_layout_set_wrap ##### -->
<para>
Modified: trunk/pango-view/viewer-render.c
==============================================================================
--- trunk/pango-view/viewer-render.c (original)
+++ trunk/pango-view/viewer-render.c Tue Jan 15 01:20:44 2008
@@ -53,6 +53,7 @@
const char *opt_text = NULL;
gboolean opt_waterfall = FALSE;
int opt_width = -1;
+int opt_height = -1;
int opt_indent = 0;
gboolean opt_justify = 0;
int opt_runs = 1;
@@ -117,16 +118,19 @@
pango_layout_set_ellipsize (layout, opt_ellipsize);
pango_layout_set_justify (layout, opt_justify);
pango_layout_set_single_paragraph_mode (layout, opt_single_par);
+ pango_layout_set_wrap (layout, opt_wrap);
font_description = get_font_description ();
if (size > 0)
pango_font_description_set_size (font_description, size * PANGO_SCALE);
if (opt_width > 0)
- {
- pango_layout_set_wrap (layout, opt_wrap);
- pango_layout_set_width (layout, (opt_width * opt_dpi * PANGO_SCALE + 36) / 72);
- }
+ pango_layout_set_width (layout, (opt_width * opt_dpi * PANGO_SCALE + 36) / 72);
+
+ if (opt_height > 0)
+ pango_layout_set_height (layout, (opt_height * opt_dpi * PANGO_SCALE + 36) / 72);
+ else
+ pango_layout_set_height (layout, opt_height);
if (opt_indent != 0)
pango_layout_set_indent (layout, (opt_indent * opt_dpi * PANGO_SCALE + 36) / 72);
@@ -220,14 +224,16 @@
pango_font_description_free (desc);
}
- pango_layout_get_extents (layout, NULL, &logical_rect);
+ pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
if (render_cb)
(*render_cb) (layout, x, y+*height, cb_context, cb_data);
- *width = MAX (*width, PANGO_PIXELS (logical_rect.x + logical_rect.width));
- *width = MAX (*width, PANGO_PIXELS (pango_layout_get_width (layout)));
- *height += PANGO_PIXELS (logical_rect.height);
+ *width = MAX (*width,
+ MAX (logical_rect.x + logical_rect.width,
+ PANGO_PIXELS (pango_layout_get_width (layout))));
+ *height += MAX (logical_rect.y + logical_rect.height,
+ PANGO_PIXELS (pango_layout_get_height (layout)));
}
}
@@ -516,7 +522,6 @@
}
-
static gboolean
parse_backend (const char *name,
const char *arg,
@@ -592,6 +597,8 @@
"Gravity hint", "natural/strong/line"},
{"header", 0, 0, G_OPTION_ARG_NONE, &opt_header,
"Display the options in the output", NULL},
+ {"height", 0, 0, G_OPTION_ARG_INT, &opt_height,
+ "Height in points (positive) or number of lines (negative) for ellipsizing", "+points/-numlines"},
{"hinting", 0, 0, G_OPTION_ARG_CALLBACK, &parse_hinting,
"Hinting style", "none/auto/full"},
{"indent", 0, 0, G_OPTION_ARG_INT, &opt_indent,
@@ -623,7 +630,7 @@
{"waterfall", 0, 0, G_OPTION_ARG_NONE, &opt_waterfall,
"Create a waterfall display", NULL},
{"width", 'w', 0, G_OPTION_ARG_INT, &opt_width,
- "Width in points to which to wrap output", "points"},
+ "Width in points to which to wrap lines or ellipsize", "points"},
{"wrap", 0, 0, G_OPTION_ARG_CALLBACK, &parse_wrap,
"Text wrapping mode (needs a width to be set)", "word/char/word-char"},
{NULL}
@@ -665,12 +672,6 @@
fail ("No viewer backend found");
}
- /* if wrap mode is set then width must be set */
- if (opt_width < 0 && opt_wrap_set)
- {
- g_printerr ("The wrap mode only has effect if a width is set\n");
- }
-
/* Get the text
*/
if (opt_text)
Modified: trunk/pango/ellipsize.c
==============================================================================
--- trunk/pango/ellipsize.c (original)
+++ trunk/pango/ellipsize.c Tue Jan 15 01:20:44 2008
@@ -723,22 +723,16 @@
**/
gboolean
_pango_layout_line_ellipsize (PangoLayoutLine *line,
- PangoAttrList *attrs)
+ PangoAttrList *attrs,
+ int goal_width)
{
EllipsizeState state;
- int goal_width;
gboolean is_ellipsized = FALSE;
- if (line->layout->ellipsize == PANGO_ELLIPSIZE_NONE ||
- line->layout->width < 0)
- goto ret;
+ g_return_val_if_fail (line->layout->ellipsize != PANGO_ELLIPSIZE_NONE && goal_width >= 0, is_ellipsized);
init_state (&state, line, attrs);
- goal_width = state.layout->width;
- if (state.layout->indent > 0 && state.layout->alignment != PANGO_ALIGN_CENTER)
- goal_width -= state.layout->indent;
-
if (state.total_width <= goal_width)
goto out;
@@ -758,6 +752,6 @@
out:
free_state (&state);
- ret:
+
return is_ellipsized;
}
Modified: trunk/pango/glyphstring.c
==============================================================================
--- trunk/pango/glyphstring.c (original)
+++ trunk/pango/glyphstring.c Tue Jan 15 01:20:44 2008
@@ -504,7 +504,7 @@
* @text: the text for the run
* @length: the number of bytes (not characters) in text.
* @analysis: the analysis information return from pango_itemize()
- * @x_pos: the x offset (in #PangoGlyphUnit)
+ * @x_pos: the x offset (in Pango units)
* @index_: location to store calculated byte index within @text
* @trailing: location to store a boolean indicating
* whether the user clicked on the leading or trailing
Modified: trunk/pango/pango-layout-private.h
==============================================================================
--- trunk/pango/pango-layout-private.h (original)
+++ trunk/pango/pango-layout-private.h Tue Jan 15 01:20:44 2008
@@ -40,7 +40,8 @@
gchar *text;
int length; /* length of text in bytes */
- int width; /* wrap width, in device units */
+ int width; /* wrap/ellipsize width, in device units, or -1 if not set */
+ int height; /* ellipsize width, in device units if positive, number of lines if negative */
int indent; /* amount by which first line should be shorter */
int spacing; /* spacing between lines */
@@ -75,7 +76,8 @@
};
gboolean _pango_layout_line_ellipsize (PangoLayoutLine *line,
- PangoAttrList *attrs);
+ PangoAttrList *attrs,
+ int goal_width);
G_END_DECLS
Modified: trunk/pango/pango-layout.c
==============================================================================
--- trunk/pango/pango-layout.c (original)
+++ trunk/pango/pango-layout.c Tue Jan 15 01:20:44 2008
@@ -189,6 +189,7 @@
layout->text = NULL;
layout->length = 0;
layout->width = -1;
+ layout->height = -1;
layout->indent = 0;
layout->alignment = PANGO_ALIGN_LEFT;
@@ -298,6 +299,7 @@
layout->text = g_strdup (src->text);
layout->length = src->length;
layout->width = src->width;
+ layout->height = src->height;
layout->indent = src->indent;
layout->spacing = src->spacing;
layout->justify = src->justify;
@@ -341,9 +343,10 @@
* pango_layout_set_width:
* @layout: a #PangoLayout.
* @width: the desired width in Pango units, or -1 to indicate that no
- * wrapping should be performed.
+ * wrapping or ellipsization should be performed.
*
- * Sets the width to which the lines of the #PangoLayout should wrap.
+ * Sets the width to which the lines of the #PangoLayout should wrap or
+ * ellipsized. The default value is -1: no width set.
**/
void
pango_layout_set_width (PangoLayout *layout,
@@ -364,7 +367,7 @@
*
* Gets the width to which the lines of the #PangoLayout should wrap.
*
- * Return value: the width, or -1 if no width set.
+ * Return value: the width in Pango units, or -1 if no width set.
**/
int
pango_layout_get_width (PangoLayout *layout)
@@ -374,6 +377,66 @@
}
/**
+ * pango_layout_set_height:
+ * @layout: a #PangoLayout.
+ * @height: the desired height of the layout in Pango units if positive,
+ * or desired number of lines if negative.
+ *
+ * Sets the height to which the #PangoLayout should be ellipsized at. There
+ * are two different behaviors, based on whether @height is positive or
+ * negative.
+ *
+ * If @height is positive, it will be the maximum height of the layout. Only
+ * lines would be shown that would fit, and if there is any text ommitted,
+ * an ellipsis added. At least one line is included in each paragraph regardless
+ * of how small the height value is. A value of zero will render exactly one
+ * line for the entire layout.
+ *
+ * If @height if it is negative, it will be the maximum number of lines per
+ * paragraph. That is, the total number of lines shown may well be more than
+ * this value if the layout contains multiple paragraphs of text.
+ * The default value of -1 means that first line of each paragraph is ellipsized.
+ *
+ * The height setting only has effect if a positive width is set on @layout
+ * and ellipsization mode of @layout is not %PANGO_ELLIPSIZE_NONE,
+ *
+ * Since: 1.20
+ **/
+void
+pango_layout_set_height (PangoLayout *layout,
+ int height)
+{
+ g_return_if_fail (layout != NULL);
+
+ if (height != layout->height)
+ {
+ layout->height = height;
+
+ if (layout->ellipsize != PANGO_ELLIPSIZE_NONE)
+ pango_layout_clear_lines (layout);
+ }
+}
+
+/**
+ * pango_layout_get_height:
+ * @layout: a #PangoLayout
+ *
+ * Gets the height of layout used for ellipsization. See
+ * pango_layout_set_height() for details.
+ *
+ * Return value: the height, in Pango units if positive, or
+ * number of lines if negative.
+ *
+ * Since: 1.20
+ **/
+int
+pango_layout_get_height (PangoLayout *layout)
+{
+ g_return_val_if_fail (layout != NULL, 0);
+ return layout->height;
+}
+
+/**
* pango_layout_set_wrap:
* @layout: a #PangoLayout
* @wrap: the wrap mode
@@ -475,7 +538,7 @@
* Gets the paragraph indent width in Pango units. A negative value
* indicates a hanging indentation.
*
- * Return value: the indent.
+ * Return value: the indent in Pango units.
**/
int
pango_layout_get_indent (PangoLayout *layout)
@@ -489,9 +552,8 @@
* @layout: a #PangoLayout.
* @spacing: the amount of spacing
*
- * Sets the amount of spacing in #PangoGlyphUnit between the lines of the
+ * Sets the amount of spacing in Pango unit between the lines of the
* layout.
- *
**/
void
pango_layout_set_spacing (PangoLayout *layout,
@@ -510,10 +572,9 @@
* pango_layout_get_spacing:
* @layout: a #PangoLayout
*
- * Gets the amount of spacing in #PangoGlyphUnit between the lines of the
- * layout.
+ * Gets the amount of spacing between the lines of the layout.
*
- * Return value: the spacing.
+ * Return value: the spacing in Pango units.
**/
int
pango_layout_get_spacing (PangoLayout *layout)
@@ -804,7 +865,6 @@
* as paragraph separators; instead, keep all text in a single paragraph,
* and display a glyph for paragraph separator characters. Used when
* you want to allow editing of newlines on a single text line.
- *
**/
void
pango_layout_set_single_paragraph_mode (PangoLayout *layout,
@@ -846,12 +906,15 @@
*
* Sets the type of ellipsization being performed for @layout.
* Depending on the ellipsization mode @ellipsize text is
- * removed from the start, middle, or end of lines so they
- * fit within the width of layout set with pango_layout_set_width ().
+ * removed from the start, middle, or end of text so they
+ * fit within the width and height of layout set with
+ * pango_layout_set_width() and pango_layout_set_height().
*
* If the layout contains characters such as newlines that
- * force it to be layed out in multiple lines, then each line
- * is ellipsized separately.
+ * force it to be layed out in multiple paragraphs, then whether
+ * each paragraph is ellipsized separately or the entire layout
+ * is ellipsized as a whole depends on the set height of the layout.
+ * See pango_layout_set_height() for details.
*
* Since: 1.6
**/
@@ -1348,7 +1411,7 @@
* @trailing: an integer indicating the edge of the grapheme to retrieve
* the position of. If > 0, the trailing edge of the grapheme,
* if 0, the leading of the grapheme.
- * @x_pos: location to store the x_offset (in #PangoGlyphUnit)
+ * @x_pos: location to store the x_offset (in Pango unit)
*
* Converts an index within a line to a X position.
*
@@ -1735,9 +1798,9 @@
/**
* pango_layout_xy_to_index:
* @layout: a #PangoLayout
- * @x: the X offset (in #PangoGlyphUnit)
+ * @x: the X offset (in Pango units)
* from the left edge of the layout.
- * @y: the Y offset (in #PangoGlyphUnit)
+ * @y: the Y offset (in Pango units)
* from the top edge of the layout
* @index_: location to store calculated byte index
* @trailing: location to store a integer indicating where
@@ -2940,16 +3003,17 @@
PangoAttrList *attrs; /* Attributes being used for itemization */
GList *items; /* This paragraph turned into items */
PangoDirection base_dir; /* Current resolved base direction */
- gboolean first_line; /* TRUE if this is the first line of the paragraph */
+ gboolean line_of_par; /* Line of the paragraph, starting at 1 for first line */
int line_start_index; /* Start index (byte offset) of line in layout->text */
int line_start_offset; /* Character offset of line in layout->text */
+ int line_width; /* Goal width of line currently processing; < 0 is infinite */
int remaining_width; /* Amount of space remaining on line; < 0 is infinite */
int start_offset; /* Character offset of first item in state->items in layout->text */
PangoGlyphString *glyphs; /* Glyphs for the first item in state->items */
ItemProperties properties; /* Properties for the first item in state->items */
- PangoGlyphUnit *log_widths; /* Logical widths for first item in state->items.. */
+ int *log_widths; /* Logical widths for first item in state->items.. */
int log_widths_offset; /* Offset into log_widths to the point corresponding
* to the remaining portion of the first item */
};
@@ -3146,7 +3210,7 @@
if (processing_new_item)
{
- state->log_widths = g_new (PangoGlyphUnit, item->num_chars);
+ state->log_widths = g_new (int, item->num_chars);
pango_glyph_string_get_logical_widths (state->glyphs,
layout->text + item->offset, item->length, item->analysis.level,
state->log_widths);
@@ -3298,6 +3362,15 @@
}
}
+static gboolean
+should_ellipsize_current_line (PangoLayout *layout,
+ ParaBreakState *state)
+{
+ return G_UNLIKELY (layout->ellipsize != PANGO_ELLIPSIZE_NONE &&
+ layout->width >= 0 &&
+ state->line_of_par == - layout->height);
+}
+
static void
process_line (PangoLayout *layout,
ParaBreakState *state)
@@ -3312,23 +3385,25 @@
line = pango_layout_line_new (layout);
line->start_index = state->line_start_index;
- line->is_paragraph_start = state->first_line;
+ line->is_paragraph_start = state->line_of_par == 1;
line_set_resolved_dir (line, state->base_dir);
- if (layout->ellipsize != PANGO_ELLIPSIZE_NONE)
- state->remaining_width = -1;
- else
+ state->line_width = layout->width;
+ if (state->line_width >= 0 && layout->alignment != PANGO_ALIGN_CENTER)
{
- state->remaining_width = layout->width;
-
- if (layout->alignment != PANGO_ALIGN_CENTER)
- {
- if (state->first_line && layout->indent >= 0)
- state->remaining_width -= layout->indent;
- else if (!state->first_line && layout->indent < 0)
- state->remaining_width += layout->indent;
- }
+ if (line->is_paragraph_start && layout->indent >= 0)
+ state->line_width -= layout->indent;
+ else if (!line->is_paragraph_start && layout->indent < 0)
+ state->line_width += layout->indent;
+
+ if (state->line_width < 0)
+ state->line_width = 0;
}
+
+ if (G_UNLIKELY (should_ellipsize_current_line (layout, state)))
+ state->remaining_width = -1;
+ else
+ state->remaining_width = state->line_width;
DEBUG ("starting to fill line", line, state);
while (state->items)
@@ -3398,10 +3473,10 @@
}
done:
- layout->is_wrapped = layout->is_wrapped || wrapped;
+ layout->is_wrapped |= wrapped;
pango_layout_line_postprocess (line, state, wrapped);
layout->lines = g_slist_prepend (layout->lines, line);
- state->first_line = FALSE;
+ state->line_of_par++;
state->line_start_index += line->length;
state->line_start_offset = state->start_offset;
}
@@ -3637,8 +3712,8 @@
if (state.items)
{
- state.first_line = TRUE;
state.base_dir = base_dir;
+ state.line_of_par = 1;
state.start_offset = start_offset;
state.line_start_offset = start_offset;
state.line_start_index = start - layout->text;
@@ -3646,6 +3721,11 @@
state.glyphs = NULL;
state.log_widths = NULL;
+ /* for deterministic bug haunting's sake set everything! */
+ state.line_width = -1;
+ state.remaining_width = -1;
+ state.log_widths_offset = 0;
+
while (state.items)
process_line (layout, &state);
}
@@ -3746,7 +3826,7 @@
/**
* pango_layout_line_x_to_index:
* @line: a #PangoLayoutLine
- * @x_pos: the X offset (in #PangoGlyphUnit)
+ * @x_pos: the X offset (in Pango units)
* from the left edge of the line.
* @index_: location to store calculated byte index for
* the grapheme in which the user clicked.
@@ -3970,7 +4050,7 @@
* with each range starting at <literal>(*ranges)[2*n]</literal>
* and of width <literal>(*ranges)[2*n + 1] - (*ranges)[2*n]</literal>.
* This array must be freed with g_free(). The coordinates are relative
- * to the layout and are in #PangoGlyphUnit.
+ * to the layout and are in Pango units.
* @n_ranges: The number of ranges stored in @ranges.
*
* Gets a list of visual ranges corresponding to a given logical range.
@@ -4846,6 +4926,9 @@
ADJUST
} mode;
+ /* FIXME
+ * if ellipsized the current line, remaining_width is -1 so we
+ * end up not justifying the ellipsized line. */
total_remaining_width = state->remaining_width;
if (total_remaining_width <= 0)
return;
@@ -4924,6 +5007,7 @@
gboolean wrapped)
{
PangoLayoutRun *last_run = line->runs->data;
+ gboolean ellipsized = FALSE;
/* NB: the runs are in reverse order at this point, since we prepended them to the list
*/
@@ -4936,8 +5020,12 @@
/* Ellipsize the line if necessary
*/
- if (_pango_layout_line_ellipsize (line, state->attrs))
- line->layout->is_ellipsized = TRUE;
+ if (G_UNLIKELY (state->line_width >= 0 &&
+ should_ellipsize_current_line (line->layout, state)))
+ {
+ ellipsized = _pango_layout_line_ellipsize (line, state->attrs, state->line_width);
+ line->layout->is_ellipsized |= ellipsized;
+ }
/* Truncate the logical-final whitespace in the line if we broke the line at it
*/
@@ -4960,7 +5048,7 @@
/* Distribute extra space between words if justifying and line was wrapped
*/
- if (wrapped && line->layout->justify)
+ if (line->layout->justify && (wrapped || ellipsized))
justify_words (line, state);
DEBUG ("after justification", line, state);
Modified: trunk/pango/pango-layout.h
==============================================================================
--- trunk/pango/pango-layout.h (original)
+++ trunk/pango/pango-layout.h Tue Jan 15 01:20:44 2008
@@ -121,6 +121,9 @@
void pango_layout_set_width (PangoLayout *layout,
int width);
int pango_layout_get_width (PangoLayout *layout);
+void pango_layout_set_height (PangoLayout *layout,
+ int height);
+int pango_layout_get_height (PangoLayout *layout);
void pango_layout_set_wrap (PangoLayout *layout,
PangoWrapMode wrap);
PangoWrapMode pango_layout_get_wrap (PangoLayout *layout);
Modified: trunk/pango/pango.def
==============================================================================
--- trunk/pango/pango.def (original)
+++ trunk/pango/pango.def Tue Jan 15 01:20:44 2008
@@ -221,6 +221,7 @@
pango_layout_get_ellipsize
pango_layout_get_extents
pango_layout_get_font_description
+ pango_layout_get_height
pango_layout_get_indent
pango_layout_get_iter
pango_layout_get_justify
@@ -281,6 +282,7 @@
pango_layout_set_auto_dir
pango_layout_set_ellipsize
pango_layout_set_font_description
+ pango_layout_set_height
pango_layout_set_indent
pango_layout_set_justify
pango_layout_set_markup
Modified: trunk/pango/pangowin32.c
==============================================================================
--- trunk/pango/pangowin32.c (original)
+++ trunk/pango/pangowin32.c Tue Jan 15 01:20:44 2008
@@ -240,7 +240,7 @@
guint16 *glyph_indexes;
gint *dX;
gint this_x;
- PangoGlyphUnit start_x_offset, x_offset, next_x_offset, cur_y_offset;
+ gint start_x_offset, x_offset, next_x_offset, cur_y_offset; /* in Pango units */
g_return_if_fail (glyphs != NULL);
@@ -278,7 +278,7 @@
* rendered by one call to ExtTextOutW().
*
* In order to minimize buildup of rounding errors, we keep track of
- * where the glyphs should be rendered in PangoGlyphUnits, and round
+ * where the glyphs should be rendered in Pango units, and round
* to pixels separately for each glyph,
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]