diff options
author | Owen Taylor <otaylor@redhat.com> | 2000-03-10 16:57:19 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2000-03-10 16:57:19 +0000 |
commit | df19b2f5a156b717186f8cbc6b1ad39d2401ab90 (patch) | |
tree | adcbef84798b47a7aad12a55221989cbd8ec5dc0 /pango | |
parent | c01dbb8d33281a5cdea16525904ff28ca61620fd (diff) | |
download | pango-df19b2f5a156b717186f8cbc6b1ad39d2401ab90.tar.gz |
Release pango-0.8
Thu Mar 9 19:55:21 2000 Owen Taylor <otaylor@redhat.com>
* Release pango-0.8
* docs/TEXT/coding-style: Added some notes about coding style
within Pango.
* modules/*.[ch]: New version from Karl Koehler adding support
for vowels marks, better ligatures.
* docs/tmpl/*: Doc updates
* libpango/pango-layout.[ch] libpango/pangox/.[ch]: Add functions
for handling paragraphs as 2-D objects, not simple lists of lines,
to make things easier for people using pango-layout.
* examples/viewer.c: Simplify using the now 2-D layout-capabable
PangoLayout.
* libpango/fonts.c (pango_font_{get_coverage,find_shaper}): Allow
NULL language tag.
* libpango/modules.c (_pango_find_map): Fix for allowing
NULL language tag.
Diffstat (limited to 'pango')
-rw-r--r-- | pango/fonts.c | 2 | ||||
-rw-r--r-- | pango/modules.c | 2 | ||||
-rw-r--r-- | pango/pango-layout.c | 372 | ||||
-rw-r--r-- | pango/pango-layout.h | 70 | ||||
-rw-r--r-- | pango/pangox.c | 98 | ||||
-rw-r--r-- | pango/pangox.h | 8 |
6 files changed, 496 insertions, 56 deletions
diff --git a/pango/fonts.c b/pango/fonts.c index 9ff5d7d6..5b74a0f7 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -469,7 +469,6 @@ pango_font_get_coverage (PangoFont *font, const char *lang) { g_return_val_if_fail (font != NULL, NULL); - g_return_val_if_fail (lang != NULL, NULL); return font->klass->get_coverage (font, lang); } @@ -491,7 +490,6 @@ pango_font_find_shaper (PangoFont *font, guint32 ch) { g_return_val_if_fail (font != NULL, NULL); - g_return_val_if_fail (lang != NULL, NULL); return font->klass->find_shaper (font, lang, ch); } diff --git a/pango/modules.c b/pango/modules.c index f2433ca8..fe8ef52d 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -76,7 +76,7 @@ _pango_find_map (const char *lang, if (!map) { PangoMapInfo *new_info = g_new (PangoMapInfo, 1); - new_info->lang = g_strdup (lang); + new_info->lang = g_strdup (map_info.lang); new_info->engine_type = g_strdup (engine_type); new_info->render_type = g_strdup (render_type); diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 04b440df..19b532fd 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -36,7 +36,10 @@ struct _PangoLayout gchar *text; int length; /* length of text in bytes */ int width; /* wrap width, in device units */ - int first_line_width; /* wrap width for first line, in device units */ + int indent; /* amount by which first line should be shorter */ + + guint justify : 1; + guint alignment : 2; GSList *lines; }; @@ -80,7 +83,10 @@ pango_layout_new (PangoContext *context) layout->text = NULL; layout->length = 0; layout->width = -1; - layout->first_line_width = -1; + layout->indent = 0; + + layout->alignment = PANGO_ALIGN_LEFT; + layout->justify = FALSE; layout->lines = NULL; @@ -135,7 +141,7 @@ pango_layout_unref (PangoLayout *layout) * @width: the desired width, or -1 to indicate that no wrapping should be * performed. * - * Set the width to which the lines of the #PangoLayout should be wrapped. + * Sets the width to which the lines of the #PangoLayout should be wrapped. **/ void pango_layout_set_width (PangoLayout *layout, @@ -148,35 +154,70 @@ pango_layout_set_width (PangoLayout *layout, } /** - * pango_layout_set_first_width: + * pango_layout_get_width: + * @layout: a #PangoLayout + * + * Gets the width to which the lines of the #PangoLayout should be wrapped. + * + * Return value: the width + **/ +int +pango_layout_get_width (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, 0); + return layout->width; +} + +/** + * pango_layout_set_indent * @layout: a #PangoLayout. - * @width: the desired width, or -1 to indicate that it should be the same - * as the the width set by pango_layout_set_width(). + * @indent: the amount by which to indent * - * Set the width to which the first line of the #PangoLayout should be - * wrapped. + * Sets the amount by which the first line should be shorter than the + * rest of the lines. This may be negative, in which case + * the subsequent lines will be shorter than the first line. (However, + * in either case, the entire width of the layout will be given by + * the value **/ void -pango_layout_set_first_line_width (PangoLayout *layout, - int width) +pango_layout_set_indent (PangoLayout *layout, + int indent) { g_return_if_fail (layout != NULL); - layout->first_line_width = width; + layout->indent = indent; pango_layout_clear_lines (layout); } /** + * pango_layout_get_indent: + * @layout: a #PangoLayout + * + * Gets the amount by which the first line should be shorter than the + * rest of the lines. + * + * Return value: the indent + **/ +int +pango_layout_get_indent (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, 0); + return layout->indent; +} + +/** * pango_layout_set_attributes: * @layout: a #PangoLayout * @attrs: a #PangoAttrList * - * Set the text attributes for a layout object + * Sets the text attributes for a layout object **/ void -pango_layout_set_attributes (PangoLayout *layout, - PangoAttrList *attrs) +pango_layout_set_attributes (PangoLayout *layout, + PangoAttrList *attrs) { + g_return_if_fail (layout != NULL); + if (layout->attrs) pango_attr_list_unref (layout->attrs); @@ -186,6 +227,74 @@ pango_layout_set_attributes (PangoLayout *layout, } /** + * pango_layout_set_justify: + * @layout: a #PangoLayout + * @justify: whether the lines in the layout should be justified. + * + * Sets whether or not each complete line should be stretched to + * fill the entire width of the layout. This stretching is typically + * done by adding whitespace, but for some scripts (such as Arabic), + * the justification is done by extending the characters. + **/ +void +pango_layout_set_justify (PangoLayout *layout, + gboolean justify) +{ + g_return_if_fail (layout != NULL); + + layout->justify = justify; +} + +/** + * pango_layout_get_justify: + * @layout: a #PangoLayout + * + * Gets whether or not each complete line should be stretched to + * fill the entire width of the layout. + * + * Return value: the justify + **/ +gboolean +pango_layout_get_justify (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, FALSE); + return layout->justify; +} + +/** + * pango_layout_set_alignment: + * @layout: a #PangoLayout + * @alignment: the new alignment + * + * Sets the alignment for the layout (how partial lines are + * positioned within the horizontal space available.) + **/ +void +pango_layout_set_alignment (PangoLayout *layout, + PangoAlignment alignment) +{ + g_return_if_fail (layout != NULL); + + layout->alignment = alignment; +} + +/** + * pango_layout_get_alignment: + * @layout: a #PangoLayout + * + * Sets the alignment for the layout (how partial lines are + * positioned within the horizontal space available.) + * + * Return value: the alignment value + **/ +PangoAlignment +pango_layout_get_alignment (PangoLayout *layout) +{ + g_return_val_if_fail (layout != NULL, PANGO_ALIGN_LEFT); + return layout->alignment; +} + +/** * pango_layout_set_text: * @layout: a #PangoLayout * @text: a UTF8-string @@ -231,7 +340,6 @@ pango_layout_get_line_count (PangoLayout *layout) g_return_val_if_fail (layout != NULL, 0); pango_layout_check_lines (layout); - return g_slist_length (layout->lines); } @@ -259,7 +367,7 @@ pango_layout_get_lines (PangoLayout *layout) * @line: the index of a line, which must be between 0 and * pango_layout_get_line_count(layout) - 1, inclusive. * - * Retrieve a particular line from a #PangoLayout + * Retrieves a particular line from a #PangoLayout * * Return value: the requested #PangoLayoutLine, or %NULL if the * index is out of range. This layout line can @@ -357,7 +465,7 @@ pango_layout_index_to_line_x (PangoLayout *layout, int tmp_line = 0; int bytes_seen = 0; - g_return_if_fail (line != NULL); + g_return_if_fail (layout != NULL); pango_layout_check_lines (layout); @@ -385,6 +493,230 @@ pango_layout_index_to_line_x (PangoLayout *layout, *x_pos = -1; } +/** + * pango_layout_xy_to_index: + * @layout: a #PangoLayout + * @x: the X offset (in thousandths of a device unit) + * from the left edge of the layout. + * @y: the Y offset (in thousandths of a device unit) + * from the top edge of the layout + * @index: location to store calculated byte index + * @trailing: location to store a integer indicating where + * in the cluster the user clicked. If the script + * allows positioning within the cluster, it is either + * 0 or 1; otherwise it is either 0 or the number + * of characters in the cluster. In either case + * 0 represents the trailing edge of the cluster. + * + * Convert from X and Y position within a layout to the byte + * offset to the character at that logical position. + * + * Return value: TRUE if the position was within the layout + **/ +gboolean +pango_layout_xy_to_index (PangoLayout *layout, + int x, + int y, + int *index, + gboolean *trailing) +{ + GSList *line_list; + int y_offset = 0; + + g_return_val_if_fail (layout != NULL, FALSE); + + pango_layout_check_lines (layout); + + line_list = layout->lines; + while (line_list) + { + PangoLayoutLine *line = line_list->data; + PangoRectangle logical_rect; + + pango_layout_line_get_extents (line, NULL, &logical_rect); + + if (y_offset + logical_rect.height >= y) + { + int x_offset; + + if (layout->width != 1 && layout->alignment == PANGO_ALIGN_RIGHT) + x_offset = layout->width - logical_rect.width; + else if (layout->width != 1 && layout->alignment == PANGO_ALIGN_CENTER) + x_offset = (layout->width - logical_rect.width) / 2; + else + x_offset = 0; + + return pango_layout_line_x_to_index (line, x - x_offset, index, trailing); + } + + y_offset += logical_rect.height; + line_list = line_list->next; + } + + return FALSE; +} + +/** + * pango_layout_index_to_pos: + * @layout: a #PangoLayout + * @index: byte index within @layout + * @pos: rectangle in which to store the position of the character + * + * Convert from an index within a PangoLayout to the onscreen position + * corresponding to that character, which is represented as rectangle. + * Note that pos->x is always the leading edge of the character. If the + * and pos->x + pos->width the trailing edge of the character. If the + * directionality of the character is right-to-left, then pos->width + * will be negative. + **/ +void +pango_layout_index_to_pos (PangoLayout *layout, + int index, + PangoRectangle *pos) +{ + PangoRectangle logical_rect; + GSList *tmp_list; + int bytes_seen = 0; + + g_return_if_fail (layout != NULL); + g_return_if_fail (index >= 0 && index < layout->length); + + pos->y = 0; + + pango_layout_check_lines (layout); + + tmp_list = layout->lines; + while (tmp_list) + { + PangoLayoutLine *layout_line = tmp_list->data; + + pango_layout_line_get_extents (layout_line, NULL, &logical_rect); + + if (bytes_seen + layout_line->length > index) + { + int x_pos; + int x_offset; + + if (layout->width != 1 && layout->alignment == PANGO_ALIGN_RIGHT) + x_offset = layout->width - logical_rect.width; + else if (layout->width != 1 && layout->alignment == PANGO_ALIGN_CENTER) + x_offset = (layout->width - logical_rect.width) / 2; + else + x_offset = 0; + + pos->height = logical_rect.height; + + pango_layout_line_index_to_x (layout_line, index, FALSE, &x_pos); + pos->x = x_pos; + + pango_layout_line_index_to_x (layout_line, index, TRUE, &x_pos); + pos->width = x_pos - pos->x; + + pos->x += x_offset; + + return; + } + + tmp_list = tmp_list->next; + bytes_seen += layout_line->length; + pos->y += logical_rect.height; + } +} + +/** + * pango_layout_get_extents: + * @layout: a #PangoLayout + * @ink_rect: rectangle used to store the extents of the glyph string as drawn + * or %NULL to indicate that the result is not needed. + * @logical_rect: rectangle used to store the logical extents of the glyph string + * or %NULL to indicate that the result is not needed. + * + * Compute the logical and ink extents of a layout line. See the documentation + * for pango_font_get_glyph_extents() for details about the interpretation + * of the rectangles. + */ +void +pango_layout_get_extents (PangoLayout *layout, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) +{ + GSList *line_list; + int y_offset = 0; + + g_return_if_fail (layout != NULL); + + pango_layout_check_lines (layout); + + line_list = layout->lines; + while (line_list) + { + PangoLayoutLine *line = line_list->data; + PangoRectangle line_ink; + PangoRectangle line_logical; + + int x_offset; + int new_pos; + + pango_layout_line_get_extents (line, ink_rect ? &line_ink : NULL, &line_logical); + + if (layout->width != 1 && layout->alignment == PANGO_ALIGN_RIGHT) + x_offset = layout->width - line_logical.width; + else if (layout->width != 1 && layout->alignment == PANGO_ALIGN_CENTER) + x_offset = (layout->width - line_logical.width) / 2; + else + x_offset = 0; + + if (ink_rect) + { + if (line_list == layout->lines) + { + ink_rect->x = line_ink.x + x_offset; + ink_rect->y = line_ink.y; + ink_rect->width = line_ink.width; + ink_rect->height = line_ink.height; + } + else + { + new_pos = MIN (ink_rect->x, line_ink.x + x_offset); + ink_rect->width = MAX (ink_rect->x + ink_rect->width, + line_ink.x + line_ink.width + x_offset) - new_pos; + ink_rect->x = new_pos; + + new_pos = MIN (ink_rect->y, line_ink.y + y_offset); + ink_rect->height = MAX (ink_rect->y + ink_rect->height, + line_ink.y + line_ink.height + y_offset) - new_pos; + ink_rect->y = new_pos; + } + } + + if (logical_rect) + { + if (line_list == layout->lines) + { + logical_rect->x = line_logical.x + x_offset; + logical_rect->y = line_logical.y; + logical_rect->width = line_logical.width; + logical_rect->height = line_logical.height; + } + else + { + new_pos = MIN (logical_rect->x, line_logical.x + x_offset); + logical_rect->width = MAX (logical_rect->x + logical_rect->width, + line_logical.x + line_logical.width + x_offset) - new_pos; + logical_rect->x = new_pos; + + new_pos = MIN (logical_rect->y, line_logical.y + y_offset); + logical_rect->height = MAX (logical_rect->y + logical_rect->height, + line_logical.y + line_logical.height + y_offset) - new_pos; + logical_rect->y = new_pos; + } + } + + y_offset += line_logical.height; + line_list = line_list->next; + } +} + static void pango_layout_clear_lines (PangoLayout *layout) { @@ -531,7 +863,7 @@ pango_layout_check_lines (PangoLayout *layout) return; line = pango_layout_line_new (layout); - remaining_width = layout->first_line_width; + remaining_width = (layout->indent >= 0) ? layout->width - layout->indent : layout->indent; /* FIXME, should we force people to set the attrs? */ if (layout->attrs) @@ -565,7 +897,7 @@ pango_layout_check_lines (PangoLayout *layout) layout->lines = g_slist_prepend (layout->lines, line); line = pango_layout_line_new (layout); - remaining_width = layout->width; + remaining_width = (layout->indent >= 0) ? layout->width : layout->indent + layout->indent; } } @@ -596,7 +928,7 @@ pango_layout_line_ref (PangoLayoutLine *line) /** * pango_layout_line_unref: - * @line: + * @line: a #PangoLayoutLine * * Decrease the reference count of a #PangoLayoutLine by one. * if the result is zero, the line and all associated memory diff --git a/pango/pango-layout.h b/pango/pango-layout.h index 75e82bad..ecc5b631 100644 --- a/pango/pango-layout.h +++ b/pango/pango-layout.h @@ -34,6 +34,12 @@ typedef struct _PangoLayout PangoLayout; typedef struct _PangoLayoutLine PangoLayoutLine; typedef struct _PangoLayoutRun PangoLayoutRun; +typedef enum { + PANGO_ALIGN_LEFT, + PANGO_ALIGN_CENTER, + PANGO_ALIGN_RIGHT +} PangoAlignment; + struct _PangoLayoutLine { PangoLayout *layout; @@ -47,29 +53,47 @@ struct _PangoLayoutRun PangoGlyphString *glyphs; }; -PangoLayout * pango_layout_new (PangoContext *context); -void pango_layout_ref (PangoLayout *layout); -void pango_layout_unref (PangoLayout *layout); -void pango_layout_set_width (PangoLayout *layout, - int width); -void pango_layout_set_justify (PangoLayout *layout, - gboolean justify); -void pango_layout_set_first_line_width (PangoLayout *layout, - int width); -void pango_layout_set_attributes (PangoLayout *layout, - PangoAttrList *attrs); -void pango_layout_set_text (PangoLayout *layout, - char *text, - int length); -int pango_layout_get_line_count (PangoLayout *layout); -PangoLayoutLine * pango_layout_get_line (PangoLayout *layout, - int line); -GSList * pango_layout_get_lines (PangoLayout *layout); -void pango_layout_index_to_line_x (PangoLayout *layout, - int index, - gboolean trailing, - int *line, - int *x_pos); +PangoLayout *pango_layout_new (PangoContext *context); +void pango_layout_ref (PangoLayout *layout); +void pango_layout_unref (PangoLayout *layout); + + +void pango_layout_set_attributes (PangoLayout *layout, + PangoAttrList *attrs); +void pango_layout_set_text (PangoLayout *layout, + char *text, + int length); + +void pango_layout_set_width (PangoLayout *layout, + int width); +int pango_layout_get_width (PangoLayout *layout); +void pango_layout_set_indent (PangoLayout *layout, + int indent); +int pango_layout_get_indent (PangoLayout *layout); +void pango_layout_set_justify (PangoLayout *layout, + gboolean justify); +gboolean pango_layout_get_justify (PangoLayout *layout); +void pango_layout_set_alignment (PangoLayout *layout, + PangoAlignment alignment); +PangoAlignment pango_layout_get_alignment (PangoLayout *layout); + + +void pango_layout_index_to_pos (PangoLayout *layout, + int index, + PangoRectangle *pos); +gboolean pango_layout_xy_to_index (PangoLayout *layout, + int x, + int y, + int *index, + gboolean *trailing); +void pango_layout_get_extents (PangoLayout *layout, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect); + +int pango_layout_get_line_count (PangoLayout *layout); +PangoLayoutLine *pango_layout_get_line (PangoLayout *layout, + int line); +GSList * pango_layout_get_lines (PangoLayout *layout); void pango_layout_line_ref (PangoLayoutLine *line); void pango_layout_line_unref (PangoLayoutLine *line); diff --git a/pango/pangox.c b/pango/pangox.c index 423722e5..30a2e3d1 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -2004,19 +2004,18 @@ pango_x_get_unknown_glyph (PangoFont *font) /** * pango_x_render_layout_line: - * @display: the X display - * @d: the drawable on which to draw string - * @gc: the graphics context - * @line: a #PangoLayoutLine - * @glyphs: the glyph string to draw - * @x: the x position of start of string (in pixels) - * @y: the y position of baseline (in pixels) + * @display: the X display + * @drawable: the drawable on which to draw string + * @gc: the graphics context + * @line: a #PangoLayoutLine + * @x: the x position of start of string (in pixels) + * @y: the y position of baseline (in pixels) * * Render a #PangoLayoutLine onto an X drawable */ void pango_x_render_layout_line (Display *display, - Drawable d, + Drawable drawable, GC gc, PangoLayoutLine *line, int x, @@ -2035,7 +2034,7 @@ pango_x_render_layout_line (Display *display, PangoLayoutRun *run = tmp_list->data; tmp_list = tmp_list->next; - pango_x_render (display, d, gc, run->item->analysis.font, run->glyphs, + pango_x_render (display, drawable, gc, run->item->analysis.font, run->glyphs, x + x_off / 1000, y); if (tmp_list) @@ -2046,3 +2045,84 @@ pango_x_render_layout_line (Display *display, } } } + +/** + * pango_x_render_layout: + * @display: the X display + * @drawable: the drawable on which to draw string + * @gc: the graphics context + * @layout: a #PangoLayout + * @x: the X position of the left of the layout (in pixels) + * @y: the Y position of the top of the layout (in pixels) + * + * Render a #PangoLayoutLine onto an X drawable + */ +void +pango_x_render_layout (Display *display, + Drawable drawable, + GC gc, + PangoLayout *layout, + int x, + int y) +{ + PangoRectangle logical_rect; + GSList *tmp_list; + PangoAlignment align; + int indent; + int width; + int y_offset = 0; + + gboolean first = FALSE; + + g_return_if_fail (display != NULL); + g_return_if_fail (layout != NULL); + + indent = pango_layout_get_indent (layout); + width = pango_layout_get_width (layout); + align = pango_layout_get_alignment (layout); + + tmp_list = pango_layout_get_lines (layout); + while (tmp_list) + { + PangoLayoutLine *line = tmp_list->data; + int x_offset; + + pango_layout_line_get_extents (line, NULL, &logical_rect); + + if (width != 1 && align == PANGO_ALIGN_RIGHT) + x_offset = width - logical_rect.width; + else if (width != 1 && align == PANGO_ALIGN_CENTER) + x_offset = (width - logical_rect.width) / 2; + else + x_offset = 0; + + if (first) + { + if (indent > 0) + { + if (align == PANGO_ALIGN_LEFT) + x_offset += indent; + else + x_offset -= indent; + } + + first = FALSE; + } + else + { + if (indent < 0) + { + if (align == PANGO_ALIGN_LEFT) + x_offset -= indent; + else + x_offset += indent; + } + } + + pango_x_render_layout_line (display, drawable, gc, + line, x + x_offset / 1000, y + y_offset / 1000); + + y_offset += logical_rect.height; + tmp_list = tmp_list->next; + } +} diff --git a/pango/pangox.h b/pango/pangox.h index 2e92347d..ad312f2c 100644 --- a/pango/pangox.h +++ b/pango/pangox.h @@ -46,11 +46,17 @@ void pango_x_render (Display *display, gint x, gint y); void pango_x_render_layout_line (Display *display, - Drawable d, + Drawable drawable, GC gc, PangoLayoutLine *line, int x, int y); +void pango_x_render_layout (Display *display, + Drawable drawable, + GC gc, + PangoLayout *layout, + int x, + int y); /* API for rendering modules */ |