diff options
author | Owen Taylor <otaylor@redhat.com> | 2000-03-13 15:59:09 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2000-03-13 15:59:09 +0000 |
commit | a6128c9efba496a2193894ec9ebe7a14404df72e (patch) | |
tree | ae1e9c9be775c9b2fe75e51c33b2a9ebd69a272a /pango | |
parent | df19b2f5a156b717186f8cbc6b1ad39d2401ab90 (diff) | |
download | pango-a6128c9efba496a2193894ec9ebe7a14404df72e.tar.gz |
Memory management functions for PangoItem.
Mon Mar 13 10:54:48 2000 Owen Taylor <otaylor@redhat.com>
* pango/pango-item.[ch]: Memory management functions for PangoItem.
* pango/*.[ch]: Random constification.
* pango/pangox.c pango/pango-layout.c pango/pango-context.c:
Add an extra_attrs field to PangoItem. Use this to handle underlining
for PangoLayout.
* examples/viewer.c (reload_font): Make paragraphs global
to save the complexity of passing it around all over the place.
* pango/pango-layout.[ch] (pango_layout_context_changed): Add
a function to reset the layout on changes to the layout's
context.
* pango/pangox.c (pango_x_make_matching_xlfd): Prefer bitmap
to scaleable if the discrepancy is < 1 pixel. (Probably not
the ideal criterion.)
* pango/pangox.c (pango_x_font_map_for_display): Fix resolution
computation error.
* pango/pango-layout.c (pango_layout_check_lines): Handle
text with embedded newlines.
* pango/pangox.c (pango_x_render_layout): Fix y to refer
to the top of the layout, not the baseline of the first
line.
* pango/pango-layout.c (process_item): Don't wrap if width is
set to -1.
* Makefile.am configure.in **/*.[ch]: move libpango/ directory
and fix all headers to install under include/pango/
Diffstat (limited to 'pango')
-rw-r--r-- | pango/Makefile.am | 8 | ||||
-rw-r--r-- | pango/break.c | 14 | ||||
-rw-r--r-- | pango/glyphstring.c | 8 | ||||
-rw-r--r-- | pango/itemize.c | 2 | ||||
-rw-r--r-- | pango/mapping.c | 2 | ||||
-rw-r--r-- | pango/modules.c | 2 | ||||
-rw-r--r-- | pango/modules.h | 2 | ||||
-rw-r--r-- | pango/pango-attributes.c | 117 | ||||
-rw-r--r-- | pango/pango-attributes.h | 44 | ||||
-rw-r--r-- | pango/pango-context.c | 49 | ||||
-rw-r--r-- | pango/pango-context.h | 6 | ||||
-rw-r--r-- | pango/pango-coverage.c | 2 | ||||
-rw-r--r-- | pango/pango-engine.h | 7 | ||||
-rw-r--r-- | pango/pango-font.h | 4 | ||||
-rw-r--r-- | pango/pango-glyph.h | 5 | ||||
-rw-r--r-- | pango/pango-item.c | 90 | ||||
-rw-r--r-- | pango/pango-item.h | 60 | ||||
-rw-r--r-- | pango/pango-layout.c | 202 | ||||
-rw-r--r-- | pango/pango-layout.h | 7 | ||||
-rw-r--r-- | pango/pango-types.h | 18 | ||||
-rw-r--r-- | pango/pango.h | 30 | ||||
-rw-r--r-- | pango/pangox.c | 97 | ||||
-rw-r--r-- | pango/pangox.h | 2 | ||||
-rw-r--r-- | pango/reorder-items.c | 2 | ||||
-rw-r--r-- | pango/shape.c | 4 |
25 files changed, 596 insertions, 188 deletions
diff --git a/pango/Makefile.am b/pango/Makefile.am index 930526cd..acf3c95d 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -1,6 +1,6 @@ ## Process this file with automake to create Makefile.in. -INCLUDES=-DSYSCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" +INCLUDES=-DSYSCONFDIR=\"$(sysconfdir)\" -DLOCALSTATEDIR=\"$(localstatedir)\" -I$(top_srcdir) lib_LTLIBRARIES = libpango.la libpangox.la bin_PROGRAMS = pango-querymodules @@ -15,6 +15,7 @@ libpango_la_SOURCES = \ pango-attributes.c \ pango-context.c \ pango-coverage.c \ + pango-item.c \ pango-layout.c \ reorder-items.c \ shape.c \ @@ -31,7 +32,9 @@ libpangox_la_SOURCES = \ libpango_la_LDFLAGS = -release $(VERSION) libpangox_la_LDFLAGS = -release $(VERSION) -include_HEADERS = \ +pangoincludedir=$(includedir)/pango + +pangoinclude_HEADERS = \ pango.h \ pango-attributes.h \ pango-context.h \ @@ -39,6 +42,7 @@ include_HEADERS = \ pango-engine.h \ pango-font.h \ pango-glyph.h \ + pango-item.h \ pango-layout.h \ pango-types.h \ pangox.h diff --git a/pango/break.c b/pango/break.c index 997635b3..811d5482 100644 --- a/pango/break.c +++ b/pango/break.c @@ -19,7 +19,7 @@ * Boston, MA 02111-1307, USA. */ -#include <pango.h> +#include "pango.h" #include <unicode.h> #include "utils.h" @@ -33,15 +33,15 @@ * Determines possible line, word, and character breaks * for a string of Unicode text. */ -void pango_break (gchar *text, - gint length, - PangoAnalysis *analysis, - PangoLogAttr *attrs) +void pango_break (const gchar *text, + gint length, + PangoAnalysis *analysis, + PangoLogAttr *attrs) { /* Pseudo-implementation */ - gchar *cur = text; - gchar *next; + const gchar *cur = text; + const gchar *next; gint i = 0; GUChar4 wc; diff --git a/pango/glyphstring.c b/pango/glyphstring.c index d3030e39..476604ce 100644 --- a/pango/glyphstring.c +++ b/pango/glyphstring.c @@ -20,8 +20,8 @@ */ #include <glib.h> -#include <pango-glyph.h> -#include <pango-font.h> +#include <pango/pango-glyph.h> +#include <pango/pango-font.h> #include <unicode.h> /** @@ -195,7 +195,7 @@ pango_glyph_string_extents (PangoGlyphString *glyphs, **/ void pango_glyph_string_get_logical_widths (PangoGlyphString *glyphs, - char *text, + const char *text, int length, int embedding_level, int *logical_widths) @@ -204,7 +204,7 @@ pango_glyph_string_get_logical_widths (PangoGlyphString *glyphs, int last_cluster = 0; int width = 0; int last_cluster_width = 0; - char *p = text; + const char *p = text; for (i=0; i<=glyphs->num_glyphs; i++) { diff --git a/pango/itemize.c b/pango/itemize.c index 0f552915..71d8e940 100644 --- a/pango/itemize.c +++ b/pango/itemize.c @@ -135,7 +135,7 @@ pango_itemize (PangoContext *context, { if (item) result = g_list_prepend (result, item); - item = g_new (PangoItem, 1); + item = pango_item_new (); item->offset = p - text; item->num_chars = 0; item->analysis.level = embedding_levels[i]; diff --git a/pango/mapping.c b/pango/mapping.c index 3ad923ee..c58a1187 100644 --- a/pango/mapping.c +++ b/pango/mapping.c @@ -28,7 +28,7 @@ * cursor positioning is allowed within clusters or not. */ -#include <pango.h> +#include <pango/pango.h> #include <unicode.h> /** diff --git a/pango/modules.c b/pango/modules.c index fe8ef52d..816acbea 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -24,7 +24,7 @@ #include <string.h> #include <gmodule.h> -#include <pango.h> +#include <pango/pango.h> #include "modules.h" #include "utils.h" diff --git a/pango/modules.h b/pango/modules.h index 111baf8e..972d0892 100644 --- a/pango/modules.h +++ b/pango/modules.h @@ -19,7 +19,7 @@ * Boston, MA 02111-1307, USA. */ -#include <pango-engine.h> +#include <pango/pango-engine.h> #ifndef __MODULES_H__ #define __MODULES_H__ diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 4929dc8a..52a1cbaf 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -19,7 +19,7 @@ * Boston, MA 02111-1307, USA. */ -#include <pango-attributes.h> +#include <pango/pango-attributes.h> struct _PangoAttrList { @@ -434,7 +434,7 @@ pango_attr_stretch_new (PangoStretch stretch) * Return value: the new #PangoAttribute. **/ PangoAttribute * -pango_attr_underline_new (gboolean underline) +pango_attr_underline_new (PangoUnderline underline) { static const PangoAttrClass klass = { PANGO_ATTR_UNDERLINE, @@ -866,6 +866,8 @@ pango_attr_iterator_get (PangoAttrIterator *iterator, if (attr->klass->type == type) return attr; + + tmp_list = tmp_list->next; } return NULL; @@ -882,35 +884,108 @@ pango_attr_iterator_get (PangoAttrIterator *iterator, * an attribute in the #PangoAttrList associated with the structure, * or with @base. If you want to save this value, you should * allocate it on the stack and then use pango_font_description_copy(). + * @extra_attrs: if non-%NULL, location in which to store a list of non-font + * attributes at the the current position; only the highest priority + * value of each attribute will be added to this list. In order + * to free this value, you must call pango_attribute_destroy() on + * each member. + * + * Get the font **/ void -pango_attr_iterator_get_font (PangoAttrIterator *iterator, - PangoFontDescription *base, - PangoFontDescription *current) +pango_attr_iterator_get_font (PangoAttrIterator *iterator, + PangoFontDescription *base, + PangoFontDescription *current, + GSList **extra_attrs) { - PangoAttribute *attr; + GList *tmp_list1; + GSList *tmp_list2; + + gboolean have_family = FALSE; + gboolean have_style = FALSE; + gboolean have_variant = FALSE; + gboolean have_weight = FALSE; + gboolean have_stretch = FALSE; + gboolean have_size = FALSE; g_return_if_fail (iterator != NULL); *current = *base; - if ((attr = pango_attr_iterator_get (iterator, PANGO_ATTR_FAMILY))) - current->family_name = ((PangoAttrString *)attr)->value; - - if ((attr = pango_attr_iterator_get (iterator, PANGO_ATTR_STYLE))) - current->style = ((PangoAttrInt *)attr)->value; - - if ((attr = pango_attr_iterator_get (iterator, PANGO_ATTR_VARIANT))) - current->variant = ((PangoAttrInt *)attr)->value; + if (extra_attrs) + *extra_attrs = NULL; - if ((attr = pango_attr_iterator_get (iterator, PANGO_ATTR_WEIGHT))) - current->weight = ((PangoAttrInt *)attr)->value; - - if ((attr = pango_attr_iterator_get (iterator, PANGO_ATTR_STRETCH))) - current->stretch = ((PangoAttrInt *)attr)->value; + tmp_list1 = iterator->attribute_stack; + while (tmp_list1) + { + PangoAttribute *attr = tmp_list1->data; + tmp_list1 = tmp_list1->next; - if ((attr = pango_attr_iterator_get (iterator, PANGO_ATTR_SIZE))) - current->size = ((PangoAttrInt *)attr)->value; + switch (attr->klass->type) + { + case PANGO_ATTR_FAMILY: + if (!have_family) + { + have_family = TRUE; + current->family_name = ((PangoAttrString *)attr)->value; + } + break; + case PANGO_ATTR_STYLE: + if (!have_style) + { + have_style = TRUE; + current->style = ((PangoAttrInt *)attr)->value; + } + break; + case PANGO_ATTR_VARIANT: + if (!have_variant) + { + have_variant = TRUE; + current->variant = ((PangoAttrInt *)attr)->value; + } + break; + case PANGO_ATTR_WEIGHT: + if (!have_weight) + { + have_weight = TRUE; + current->weight = ((PangoAttrInt *)attr)->value; + } + break; + case PANGO_ATTR_STRETCH: + if (!have_stretch) + { + have_stretch = TRUE; + current->stretch = ((PangoAttrInt *)attr)->value; + } + break; + case PANGO_ATTR_SIZE: + if (!have_size) + { + have_size = TRUE; + current->size = ((PangoAttrInt *)attr)->value; + } + break; + default: + if (extra_attrs) + { + gboolean found = FALSE; + + tmp_list2 = *extra_attrs; + while (tmp_list2) + { + PangoAttribute *old_attr = tmp_list2->data; + if (attr->klass->type == old_attr->klass->type) + { + found = TRUE; + break; + } + } + + if (!found) + *extra_attrs = g_slist_prepend (*extra_attrs, pango_attribute_copy (attr)); + } + } + } } diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 8c72d750..19b9b638 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -22,7 +22,7 @@ #ifndef __PANGO_ATTRIBUTES_H__ #define __PANGO_ATTRIBUTES_H__ -#include <pango-font.h> +#include <pango/pango-font.h> #ifdef __cplusplus extern "C" { @@ -53,6 +53,13 @@ typedef enum { PANGO_ATTR_RISE /* PangoAttrInt */ } PangoAttrType; +typedef enum { + PANGO_UNDERLINE_NONE, + PANGO_UNDERLINE_SINGLE, + PANGO_UNDERLINE_DOUBLE, + PANGO_UNDERLINE_LOW +} PangoUnderline; + struct _PangoAttribute { const PangoAttrClass *klass; @@ -95,22 +102,22 @@ void pango_attribute_destroy (PangoAttribute *attr); gboolean pango_attribute_compare (const PangoAttribute *attr1, const PangoAttribute *attr2); -PangoAttribute *pango_attr_lang_new (const char *lang); -PangoAttribute *pango_attr_family_new (const char *family); -PangoAttribute *pango_attr_foreground_new (guint16 red, - guint16 green, - guint16 blue); -PangoAttribute *pango_attr_background_new (guint16 red, - guint16 green, - guint16 blue); -PangoAttribute *pango_attr_size_new (int size); -PangoAttribute *pango_attr_style_new (PangoStyle style); -PangoAttribute *pango_attr_weight_new (PangoWeight weight); -PangoAttribute *pango_attr_variant_new (PangoVariant variant); -PangoAttribute *pango_attr_stretch_new (PangoStretch stretch); -PangoAttribute *pango_attr_underline_new (gboolean underline); -PangoAttribute *pango_attr_strikethrough_new (gboolean strikethrough); -PangoAttribute *pango_attr_rise_new (int rise); +PangoAttribute *pango_attr_lang_new (const char *lang); +PangoAttribute *pango_attr_family_new (const char *family); +PangoAttribute *pango_attr_foreground_new (guint16 red, + guint16 green, + guint16 blue); +PangoAttribute *pango_attr_background_new (guint16 red, + guint16 green, + guint16 blue); +PangoAttribute *pango_attr_size_new (int size); +PangoAttribute *pango_attr_style_new (PangoStyle style); +PangoAttribute *pango_attr_weight_new (PangoWeight weight); +PangoAttribute *pango_attr_variant_new (PangoVariant variant); +PangoAttribute *pango_attr_stretch_new (PangoStretch stretch); +PangoAttribute *pango_attr_underline_new (PangoUnderline underline); +PangoAttribute *pango_attr_strikethrough_new (gboolean strikethrough); +PangoAttribute *pango_attr_rise_new (int rise); PangoAttrList * pango_attr_list_new (void); void pango_attr_list_ref (PangoAttrList *list); @@ -130,7 +137,8 @@ PangoAttribute *pango_attr_iterator_get (PangoAttrIterator *iterator, PangoAttrType type); void pango_attr_iterator_get_font (PangoAttrIterator *iterator, PangoFontDescription *base, - PangoFontDescription *current); + PangoFontDescription *current, + GSList **extra_attrs); #ifdef __cplusplus } diff --git a/pango/pango-context.c b/pango/pango-context.c index a6b7cccc..cfc778b5 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -19,7 +19,7 @@ * Boston, MA 02111-1307, USA. */ -#include <pango-context.h> +#include <pango/pango-context.h> #include <fribidi/fribidi.h> #include <unicode.h> #include "iconv.h" @@ -38,12 +38,13 @@ struct _PangoContext }; static void add_engines (PangoContext *context, - gchar *text, + const gchar *text, gint length, PangoAttrList *attrs, PangoEngineShape **shape_engines, PangoEngineInfo **lang_engines, - PangoFont **fonts); + PangoFont **fonts, + GSList **extra_attr_lists); /** * pango_context_new: @@ -468,7 +469,7 @@ pango_context_get_base_dir (PangoContext *context) */ GList * pango_itemize (PangoContext *context, - char *text, + const char *text, int length, PangoAttrList *attrs) { @@ -478,11 +479,13 @@ pango_itemize (PangoContext *context, FriBidiCharType base_dir; gint i; PangoItem *item; - char *p, *next; + const char *p; + const char *next; GList *result = NULL; PangoEngineShape **shape_engines; PangoEngineInfo **lang_engines; + GSList **extra_attr_lists; PangoFont **fonts; g_return_val_if_fail (context != NULL, NULL); @@ -517,6 +520,7 @@ pango_itemize (PangoContext *context, shape_engines = g_new0 (PangoEngineShape *, n_chars); lang_engines = g_new0 (PangoEngineInfo *, n_chars); fonts = g_new0 (PangoFont *, n_chars); + extra_attr_lists = g_new0 (GSList *, n_chars); fribidi_log2vis_get_embedding_levels (text_ucs2, n_chars, &base_dir, embedding_levels); @@ -525,7 +529,8 @@ pango_itemize (PangoContext *context, * each character. */ - add_engines (context, text, length, attrs, shape_engines, lang_engines, fonts); + add_engines (context, text, length, attrs, shape_engines, lang_engines, fonts, + extra_attr_lists); /* Make a GList of PangoItems out of the above results @@ -541,7 +546,8 @@ pango_itemize (PangoContext *context, embedding_levels[i] != embedding_levels[i-1] || shape_engines[i] != shape_engines[i-1] || lang_engines[i] != lang_engines[i-1] || - fonts[i] != fonts[i-1]) + fonts[i] != fonts[i-1] || + extra_attr_lists[i] != extra_attr_lists[i-1]) { item = g_new (PangoItem, 1); item->offset = p - text; @@ -557,6 +563,22 @@ pango_itemize (PangoContext *context, item->analysis.font = fonts[i]; + /* Copy the extra attribute list if necessary */ + if (extra_attr_lists[i] && i != 0 && extra_attr_lists[i] == extra_attr_lists[i-1]) + { + GSList *tmp_list = extra_attr_lists[i]; + item->extra_attrs = NULL; + while (tmp_list) + { + item->extra_attrs = g_slist_prepend (item->extra_attrs, + pango_attribute_copy (tmp_list->data)); + tmp_list = tmp_list->next; + } + item->extra_attrs = g_slist_reverse (item->extra_attrs); + } + else + item->extra_attrs = extra_attr_lists[i]; + result = g_list_prepend (result, item); } else @@ -571,6 +593,7 @@ pango_itemize (PangoContext *context, g_free (shape_engines); g_free (lang_engines); g_free (fonts); + g_free (extra_attr_lists); g_free (text_ucs2); @@ -610,16 +633,18 @@ get_font (PangoFont **fonts, static void add_engines (PangoContext *context, - gchar *text, + const gchar *text, gint length, PangoAttrList *attrs, PangoEngineShape **shape_engines, PangoEngineInfo **lang_engines, - PangoFont **fonts) + PangoFont **fonts, + GSList **extra_attr_lists) { - char *pos; + const char *pos; char *lang = NULL; int next_index = 0; + GSList *extra_attrs = NULL; gint n_chars; PangoMap *shape_map = NULL; PangoMap *lang_map = NULL; @@ -671,7 +696,7 @@ add_engines (PangoContext *context, "PangoRenderX"); } - pango_attr_iterator_get_font (iterator, context->font_desc, &next_desc); + pango_attr_iterator_get_font (iterator, context->font_desc, &next_desc, &extra_attrs); if (i == 0 || !pango_font_description_compare (¤t_desc, &next_desc)) @@ -727,6 +752,8 @@ add_engines (PangoContext *context, shape_engines[i] = pango_font_find_shaper (fonts[i], lang, wc); else shape_engines[i] = NULL; + + extra_attr_lists[i] = extra_attrs; } for (j=0; j<n_families; j++) diff --git a/pango/pango-context.h b/pango/pango-context.h index 8aa0d0bf..9a5885c5 100644 --- a/pango/pango-context.h +++ b/pango/pango-context.h @@ -22,8 +22,8 @@ #ifndef __PANGO_CONTEXT_H__ #define __PANGO_CONTEXT_H__ -#include <pango-font.h> -#include <pango-attributes.h> +#include <pango/pango-font.h> +#include <pango/pango-attributes.h> #ifdef __cplusplus extern "C" { @@ -64,7 +64,7 @@ PangoDirection pango_context_get_base_dir (PangoContext * Returns a GList of PangoItem's */ GList *pango_itemize (PangoContext *context, - gchar *text, + const char *text, gint length, PangoAttrList *attrs); diff --git a/pango/pango-coverage.c b/pango/pango-coverage.c index cc9ca246..286c3977 100644 --- a/pango/pango-coverage.c +++ b/pango/pango-coverage.c @@ -21,7 +21,7 @@ #include <string.h> -#include <pango-coverage.h> +#include <pango/pango-coverage.h> typedef struct _PangoBlockInfo PangoBlockInfo; diff --git a/pango/pango-engine.h b/pango/pango-engine.h index 9d56163a..7c00ac19 100644 --- a/pango/pango-engine.h +++ b/pango/pango-engine.h @@ -22,9 +22,10 @@ #ifndef __PANGO_ENGINE_H__ #define __PANGO_ENGINE_H__ -#include <pango-types.h> -#include <pango-font.h> -#include <pango-glyph.h> +#include <pango/pango-types.h> +#include <pango/pango-item.h> +#include <pango/pango-font.h> +#include <pango/pango-glyph.h> #ifdef __cplusplus extern "C" { diff --git a/pango/pango-font.h b/pango/pango-font.h index 1a5d6fd7..f6fd7ea4 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -26,8 +26,8 @@ extern "C" { #endif /* __cplusplus */ -#include <pango-coverage.h> -#include <pango-types.h> +#include <pango/pango-coverage.h> +#include <pango/pango-types.h> typedef struct _PangoFontDescription PangoFontDescription; typedef struct _PangoFontClass PangoFontClass; diff --git a/pango/pango-glyph.h b/pango/pango-glyph.h index 433e71f2..f4ef2fa4 100644 --- a/pango/pango-glyph.h +++ b/pango/pango-glyph.h @@ -22,7 +22,8 @@ #ifndef __PANGO_GLYPH_H__ #define __PANGO_GLYPH_H__ -#include <pango-types.h> +#include <pango/pango-types.h> +#include <pango/pango-item.h> #ifdef __cplusplus extern "C" { @@ -89,7 +90,7 @@ void pango_glyph_string_extents (PangoGlyphString *glyphs, PangoRectangle *logical_rect); void pango_glyph_string_get_logical_widths (PangoGlyphString *glyphs, - char *text, + const char *text, int length, int embedding_level, int *logical_widths); diff --git a/pango/pango-item.c b/pango/pango-item.c new file mode 100644 index 00000000..826552f8 --- /dev/null +++ b/pango/pango-item.c @@ -0,0 +1,90 @@ +/* Pango + * pango-item.c: Single run handling + * + * Copyright (C) 2000 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <pango-attributes.h> +#include <pango-item.h> + +/** + * pango_item_new: + * + * Creates a new #PangoItem structure initialized to default values. + * + * Return value: the new #PangoItem + **/ +PangoItem * +pango_item_new (void) +{ + PangoItem *result = g_new0 (PangoItem, 1); + + return result; +} + +/** + * pango_item_copy: + * @item: a #PangoItem + * + * Copy an existing #PangoItem structure. + * + * Return value: the new #PangoItem + **/ +PangoItem * +pango_item_copy (PangoItem *item) +{ + GSList *extra_attrs, *tmp_list; + PangoItem *result = g_new (PangoItem, 1); + + result->offset = item->offset; + result->length = item->length; + result->num_chars = item->num_chars; + + extra_attrs = NULL; + tmp_list = item->extra_attrs; + while (tmp_list) + { + extra_attrs = g_slist_prepend (extra_attrs, pango_attribute_copy (tmp_list->data)); + tmp_list = tmp_list->next; + } + + result->extra_attrs = g_slist_reverse (extra_attrs); + + result->analysis = item->analysis; + pango_font_ref (result->analysis.font); + + return result; +} + +/** + * pango_item_free: + * @item: a #PangoItem + * + * Free a #PangoItem and all associated memory. + **/ +void +pango_item_free (PangoItem *item) +{ + if (item->extra_attrs) + g_slist_foreach (item->extra_attrs, (GFunc)pango_attribute_destroy, NULL); + + pango_font_unref (item->analysis.font); + + g_free (item); +} + diff --git a/pango/pango-item.h b/pango/pango-item.h new file mode 100644 index 00000000..8530f82a --- /dev/null +++ b/pango/pango-item.h @@ -0,0 +1,60 @@ +/* Pango + * pango-item.h: Structure for storing run information + * + * Copyright (C) 2000 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGO_ITEM_H__ +#define __PANGO_ITEM_H__ + +#include <pango/pango-types.h> +#include <pango/pango-item.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _PangoAnalysis PangoAnalysis; +typedef struct _PangoItem PangoItem; + +struct _PangoAnalysis +{ + PangoEngineShape *shape_engine; + PangoEngineLang *lang_engine; + PangoFont *font; + guint8 level; +}; + +struct _PangoItem +{ + gint offset; + gint length; + gint num_chars; + GSList *extra_attrs; + PangoAnalysis analysis; +}; + +PangoItem *pango_item_new (void); +PangoItem *pango_item_copy (PangoItem *item); +void pango_item_free (PangoItem *item); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif __PANGO_ITEM_H__ diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 19b532fd..cc6734e7 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -19,8 +19,9 @@ * Boston, MA 02111-1307, USA. */ -#include <pango-layout.h> -#include <pango.h> /* For pango_shape() */ +#include <pango/pango-layout.h> +#include <pango/pango.h> /* For pango_shape() */ +#include <string.h> #include <unicode.h> #define LINE_IS_VALID(line) ((line)->layout != NULL) @@ -56,6 +57,9 @@ static void pango_layout_check_lines (PangoLayout *layout); static PangoLayoutLine * pango_layout_line_new (PangoLayout *layout); static void pango_layout_line_reorder (PangoLayoutLine *line); +static void pango_layout_get_item_properties (PangoItem *item, + PangoUnderline *uline); + /** * pango_layout_new: * @context: a #PangoContext @@ -149,8 +153,11 @@ pango_layout_set_width (PangoLayout *layout, { g_return_if_fail (layout != NULL); - layout->width = width; - pango_layout_clear_lines (layout); + if (width != layout->width) + { + layout->width = width; + pango_layout_clear_lines (layout); + } } /** @@ -185,8 +192,11 @@ pango_layout_set_indent (PangoLayout *layout, { g_return_if_fail (layout != NULL); - layout->indent = indent; - pango_layout_clear_lines (layout); + if (indent != layout->indent) + { + layout->indent = indent; + pango_layout_clear_lines (layout); + } } /** @@ -327,6 +337,21 @@ pango_layout_set_text (PangoLayout *layout, } /** + * pango_layout_context_changed: + * @layout: a #PangoLayout + * + * Forces recomputation of any state in the #PangoLayout that + * might depend on the layout's context. This function should + * be called if you make changes to the context subsequent + * to creating the layout. + **/ +void +pango_layout_context_changed (PangoLayout *layout) +{ + pango_layout_clear_lines (layout); +} + +/** * pango_layout_get_line_count: * @layout: #PangoLayout * @@ -754,7 +779,10 @@ insert_run (PangoLayoutLine *line, PangoItem *item, PangoGlyphString *glyphs) } static gboolean -process_item (PangoLayoutLine *line, PangoItem *item, char *text, int *remaining_width) +process_item (PangoLayoutLine *line, + PangoItem *item, + const char *text, + int *remaining_width) { PangoGlyphString *glyphs = pango_glyph_string_new (); PangoRectangle logical_rect; @@ -764,6 +792,12 @@ process_item (PangoLayoutLine *line, PangoItem *item, char *text, int *remaining return FALSE; pango_shape (text + item->offset, item->length, &item->analysis, glyphs); + if (*remaining_width < 0) + { + insert_run (line, item, glyphs); + return TRUE; + } + pango_glyph_string_extents (glyphs, item->analysis.font, NULL, &logical_rect); width = logical_rect.width; @@ -801,10 +835,10 @@ process_item (PangoLayoutLine *line, PangoItem *item, char *text, int *remaining if (num_chars != 0) /* Succesfully broke the item */ { - char *p; + const char *p; gint n; - PangoItem *new_item = g_new (PangoItem, 1); + PangoItem *new_item = pango_item_copy (item); /* Determine utf8 length corresponding to num_chars. Slow? */ @@ -815,13 +849,9 @@ process_item (PangoLayoutLine *line, PangoItem *item, char *text, int *remaining length = p - (text + item->offset); - new_item->offset = item->offset; new_item->length = length; new_item->num_chars = num_chars; - new_item->analysis = item->analysis; - pango_font_ref (new_item->analysis.font); - item->offset += length; item->length -= length; item->num_chars -= num_chars; @@ -855,6 +885,8 @@ static void pango_layout_check_lines (PangoLayout *layout) { GList *items, *tmp_list; + const char *start; + gboolean done = FALSE; PangoLayoutLine *line; int remaining_width; @@ -862,51 +894,70 @@ pango_layout_check_lines (PangoLayout *layout) if (layout->lines) return; - line = pango_layout_line_new (layout); - remaining_width = (layout->indent >= 0) ? layout->width - layout->indent : layout->indent; - - /* FIXME, should we force people to set the attrs? */ - if (layout->attrs) - items = pango_itemize (layout->context, layout->text, layout->length, layout->attrs); - else + start = layout->text; + do { - PangoAttrList *attrs = pango_attr_list_new (); - items = pango_itemize (layout->context, layout->text, layout->length, attrs); - pango_attr_list_unref (attrs); - } - - tmp_list = items; + const char *end = start; - while (tmp_list) - { - PangoItem *item = tmp_list->data; - gboolean fits; + while (end != layout->text + layout->length && *end != '\n') + end++; - fits = process_item (line, item, layout->text, &remaining_width); - - if (fits) - tmp_list = tmp_list->next; + if (end == layout->text + layout->length) + done = TRUE; + + line = pango_layout_line_new (layout); + remaining_width = (layout->indent >= 0) ? layout->width - layout->indent : layout->indent; - if (!fits) + /* FIXME, should we force people to set the attrs? */ + if (layout->attrs) + items = pango_itemize (layout->context, start, end - start, layout->attrs); + else { - /* Complete line - */ - line->runs = g_slist_reverse (line->runs); - pango_layout_line_reorder (line); + PangoAttrList *attrs = pango_attr_list_new (); + items = pango_itemize (layout->context, start, end - start, attrs); + pango_attr_list_unref (attrs); + } + + tmp_list = items; + + while (tmp_list) + { + PangoItem *item = tmp_list->data; + gboolean fits; + + fits = process_item (line, item, start, &remaining_width); - layout->lines = g_slist_prepend (layout->lines, line); + if (fits) + tmp_list = tmp_list->next; + + if (!fits) + { + /* Complete line + */ + line->runs = g_slist_reverse (line->runs); + pango_layout_line_reorder (line); + + layout->lines = g_slist_prepend (layout->lines, line); + + line = pango_layout_line_new (layout); + remaining_width = (layout->indent >= 0) ? layout->width : layout->indent + layout->indent; + } + } + + line->runs = g_slist_reverse (line->runs); + pango_layout_line_reorder (line); + + layout->lines = g_slist_prepend (layout->lines, line); - line = pango_layout_line_new (layout); - remaining_width = (layout->indent >= 0) ? layout->width : layout->indent + layout->indent; + g_list_free (tmp_list); + + if (!done) + { + start = end + 1; } } - - line->runs = g_slist_reverse (line->runs); - pango_layout_line_reorder (line); + while (!done); - layout->lines = g_slist_prepend (layout->lines, line); - - g_list_free (tmp_list); layout->lines = g_slist_reverse (layout->lines); } @@ -1073,13 +1124,39 @@ pango_layout_line_get_extents (PangoLayoutLine *line, { PangoLayoutRun *run = tmp_list->data; int new_pos; + PangoUnderline uline = PANGO_UNDERLINE_NONE; PangoRectangle run_ink; PangoRectangle run_logical; - + + pango_layout_get_item_properties (run->item, &uline); pango_glyph_string_extents (run->glyphs, run->item->analysis.font, - ink_rect ? &run_ink : NULL, + (ink_rect || uline != PANGO_UNDERLINE_NONE) ? &run_ink : NULL, &run_logical); + + switch (uline) + { + case PANGO_UNDERLINE_NONE: + break; + case PANGO_UNDERLINE_SINGLE: + if (ink_rect) + run_ink.height = MAX (run_ink.height, 2 * PANGO_SCALE - run_ink.y); + run_logical.height = MAX (run_logical.height, 2 * PANGO_SCALE - run_logical.y); + break; + case PANGO_UNDERLINE_DOUBLE: + if (ink_rect) + run_ink.height = MAX (run_ink.height, 4 * PANGO_SCALE - run_ink.y); + run_logical.height = MAX (run_logical.height, 4 * PANGO_SCALE - run_logical.y); + break; + case PANGO_UNDERLINE_LOW: + if (ink_rect) + run_ink.height += 2 * PANGO_SCALE; + + /* FIXME: Should this simply be run_logical.height += 2 * PANGO_SCALE instead? + */ + run_logical.height = MAX (run_logical.height, run_ink.y + run_ink.height - run_logical.y); + break; + } if (ink_rect) { @@ -1203,3 +1280,28 @@ pango_layout_line_reorder (PangoLayoutLine *line) g_slist_free (logical_runs); } +/* This utility function is duplicated here and in pango-layout.c; should it be + * public? Trouble is - what is the appropriate set of properties? + */ +static void +pango_layout_get_item_properties (PangoItem *item, + PangoUnderline *uline) +{ + GSList *tmp_list = item->extra_attrs; + + while (tmp_list) + { + PangoAttribute *attr = tmp_list->data; + + switch (attr->klass->type) + { + case PANGO_ATTR_UNDERLINE: + if (uline) + *uline = ((PangoAttrInt *)attr)->value; + + default: + break; + } + tmp_list = tmp_list->next; + } +} diff --git a/pango/pango-layout.h b/pango/pango-layout.h index ecc5b631..c7713aa1 100644 --- a/pango/pango-layout.h +++ b/pango/pango-layout.h @@ -22,9 +22,9 @@ #ifndef __PANGO_LAYOUT_H__ #define __PANGO_LAYOUT_H__ -#include <pango-attributes.h> -#include <pango-context.h> -#include <pango-glyph.h> +#include <pango/pango-attributes.h> +#include <pango/pango-context.h> +#include <pango/pango-glyph.h> #ifdef __cplusplus extern "C" { @@ -77,6 +77,7 @@ void pango_layout_set_alignment (PangoLayout *layout, PangoAlignment alignment); PangoAlignment pango_layout_get_alignment (PangoLayout *layout); +void pango_layout_context_changed (PangoLayout *layout); void pango_layout_index_to_pos (PangoLayout *layout, int index, diff --git a/pango/pango-types.h b/pango/pango-types.h index 9d31603c..a0a41b0a 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -30,8 +30,6 @@ #define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) #endif -typedef struct _PangoAnalysis PangoAnalysis; -typedef struct _PangoItem PangoItem; typedef struct _PangoLangRange PangoLangRange; typedef struct _PangoLogAttr PangoLogAttr; @@ -56,6 +54,8 @@ struct _PangoRectangle int height; }; +#define PANGO_SCALE 1000 + /* Macros to translate from extents rectangles to ascent/descent/lbearing/rbearing */ #define PANGO_ASCENT(rect) (-(rect).y) @@ -67,20 +67,6 @@ struct _PangoRectangle * shaping/language engine and bidirectional level */ -struct _PangoAnalysis { - PangoEngineShape *shape_engine; - PangoEngineLang *lang_engine; - PangoFont *font; - guint8 level; -}; - -struct _PangoItem { - gint offset; - gint length; - gint num_chars; - PangoAnalysis analysis; -}; - typedef enum { PANGO_DIRECTION_LTR, PANGO_DIRECTION_RTL, diff --git a/pango/pango.h b/pango/pango.h index f06c52cd..3e7d1d5d 100644 --- a/pango/pango.h +++ b/pango/pango.h @@ -28,45 +28,43 @@ extern "C" { #endif /* __cplusplus */ -#include <pango-attributes.h> -#include <pango-context.h> -#include <pango-coverage.h> -#include <pango-engine.h> -#include <pango-font.h> -#include <pango-glyph.h> -#include <pango-layout.h> -#include <pango-types.h> +#include <pango/pango-attributes.h> +#include <pango/pango-context.h> +#include <pango/pango-coverage.h> +#include <pango/pango-engine.h> +#include <pango/pango-font.h> +#include <pango/pango-glyph.h> +#include <pango/pango-item.h> +#include <pango/pango-layout.h> +#include <pango/pango-types.h> /* Logical attributes of a character */ -struct _PangoLogAttr { +struct _PangoLogAttr +{ guint is_break : 1; /* Break in front of character */ guint is_white : 1; guint is_char_stop : 1; guint is_word_stop : 1; - /* Uniscript has is_invalid */ }; /* Determine information about cluster/word/line breaks in a string * of Unicode text. */ -void pango_break (gchar *text, - gint length, +void pango_break (const gchar *text, + gint length, PangoAnalysis *analysis, PangoLogAttr *attrs); /* Turn a string of characters into a string of glyphs */ -void pango_shape (gchar *text, +void pango_shape (const gchar *text, gint length, PangoAnalysis *analysis, PangoGlyphString *glyphs); -/* [ pango_place - subsume into g_script_shape? ] */ - GList *pango_reorder_items (GList *logical_items); - #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/pango/pangox.c b/pango/pangox.c index 30a2e3d1..d16d598c 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -99,7 +99,7 @@ struct _PangoXFontMap int n_fonts; - double resolution; /* (points / pixel) * 1000 */ + double resolution; /* (points / pixel) * PANGO_SCALE */ }; /* This is the largest field length we will accept. If a fontname has a field @@ -211,6 +211,8 @@ static gint pango_x_get_size (PangoXFontMap *fontmap, const char *fontname); static void pango_x_insert_font (PangoXFontMap *fontmap, const char *fontname); +static void pango_x_get_item_properties (PangoItem *item, + PangoUnderline *uline); static GList *fontmaps; @@ -280,11 +282,12 @@ pango_x_font_map_for_display (Display *display) fontmaps = g_list_prepend (fontmaps, xfontmap); - /* This is a little screwed up, since different screens might have different resolutions + /* This is a little screwed up, since different screens on the same display + * might have different resolutions */ screen = DefaultScreen (xfontmap->display); - xfontmap->resolution = (1000. * 72. / 25.4) * ((double) DisplayWidthMM (xfontmap->display, screen) / - DisplayHeight (xfontmap->display, screen)); + xfontmap->resolution = (PANGO_SCALE * 72.27 / 25.4) * ((double) DisplayWidthMM (xfontmap->display, screen) / + DisplayWidth (xfontmap->display, screen)); return (PangoFontMap *)xfontmap; } @@ -1356,8 +1359,8 @@ pango_x_render (Display *display, } XDrawString16 (display, d, gc, - x + (x_off + glyphs->glyphs[i].geometry.x_offset) / 1000, - y + glyphs->glyphs[i].geometry.y_offset / 1000, + x + (x_off + glyphs->glyphs[i].geometry.x_offset) / PANGO_SCALE, + y + glyphs->glyphs[i].geometry.y_offset / PANGO_SCALE, &c, 1); } @@ -1378,17 +1381,17 @@ pango_x_font_get_glyph_extents (PangoFont *font, { if (ink_rect) { - ink_rect->x = 1000 * cs->lbearing; - ink_rect->width = 1000 * (cs->rbearing - cs->lbearing); - ink_rect->y = 1000 * -cs->ascent; - ink_rect->height = cs->ascent + cs->descent; + ink_rect->x = PANGO_SCALE * cs->lbearing; + ink_rect->width = PANGO_SCALE * (cs->rbearing - cs->lbearing); + ink_rect->y = PANGO_SCALE * -cs->ascent; + ink_rect->height = PANGO_SCALE * (cs->ascent + cs->descent); } if (logical_rect) { logical_rect->x = 0; - logical_rect->width = 1000 * cs->width; - logical_rect->y = - 1000 * subfont->font_struct->ascent; - logical_rect->height = 1000 * (subfont->font_struct->ascent + subfont->font_struct->descent); + logical_rect->width = PANGO_SCALE * cs->width; + logical_rect->y = - PANGO_SCALE * subfont->font_struct->ascent; + logical_rect->height = PANGO_SCALE * (subfont->font_struct->ascent + subfont->font_struct->descent); } } else @@ -1526,7 +1529,7 @@ pango_x_make_matching_xlfd (PangoXFontMap *xfontmap, char *xlfd, const char *cha if (!closest_match || new_distance < match_distance || - (new_distance == 0 && match_scaleable && font_size != 0)) + (new_distance < PANGO_SCALE && match_scaleable && font_size != 0)) { closest_match = tmp_xlfd; match_scaleable = (font_size == 0); @@ -2023,26 +2026,52 @@ pango_x_render_layout_line (Display *display, { GSList *tmp_list = line->runs; PangoRectangle logical_rect; + PangoRectangle ink_rect; int x_off = 0; pango_layout_line_get_extents (line,NULL, &logical_rect); - y += PANGO_ASCENT (logical_rect) / 1000; while (tmp_list) { + PangoUnderline uline = PANGO_UNDERLINE_NONE; PangoLayoutRun *run = tmp_list->data; tmp_list = tmp_list->next; + pango_x_get_item_properties (run->item, &uline); + + if (uline == PANGO_UNDERLINE_NONE) + pango_glyph_string_extents (run->glyphs, run->item->analysis.font, + NULL, &logical_rect); + else + pango_glyph_string_extents (run->glyphs, run->item->analysis.font, + &ink_rect, &logical_rect); + pango_x_render (display, drawable, gc, run->item->analysis.font, run->glyphs, - x + x_off / 1000, y); + x + x_off / PANGO_SCALE, y); - if (tmp_list) + switch (uline) { - pango_glyph_string_extents (run->glyphs, run->item->analysis.font, - NULL, &logical_rect); - x_off += logical_rect.width; + case PANGO_UNDERLINE_NONE: + break; + case PANGO_UNDERLINE_DOUBLE: + XDrawLine (display, drawable, gc, + x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + 4, + x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 4); + /* Fall through */ + case PANGO_UNDERLINE_SINGLE: + XDrawLine (display, drawable, gc, + x + (x_off + ink_rect.x) -1, y + 2, + x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + 2); + break; + case PANGO_UNDERLINE_LOW: + XDrawLine (display, drawable, gc, + x + (x_off + ink_rect.x) / PANGO_SCALE - 1, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2, + x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 2); + break; } + + x_off += logical_rect.width; } } @@ -2120,9 +2149,35 @@ pango_x_render_layout (Display *display, } pango_x_render_layout_line (display, drawable, gc, - line, x + x_offset / 1000, y + y_offset / 1000); + line, x + x_offset / PANGO_SCALE, y + (y_offset - logical_rect.y) / PANGO_SCALE); y_offset += logical_rect.height; tmp_list = tmp_list->next; } } + +/* This utility function is duplicated here and in pango-layout.c; should it be + * public? Trouble is - what is the appropriate set of properties? + */ +static void +pango_x_get_item_properties (PangoItem *item, + PangoUnderline *uline) +{ + GSList *tmp_list = item->extra_attrs; + + while (tmp_list) + { + PangoAttribute *attr = tmp_list->data; + + switch (attr->klass->type) + { + case PANGO_ATTR_UNDERLINE: + if (uline) + *uline = ((PangoAttrInt *)attr)->value; + + default: + break; + } + tmp_list = tmp_list->next; + } +} diff --git a/pango/pangox.h b/pango/pangox.h index ad312f2c..3c077a44 100644 --- a/pango/pangox.h +++ b/pango/pangox.h @@ -23,7 +23,7 @@ #define __PANGOX_H__ #include <glib.h> -#include <pango.h> +#include <pango/pango.h> #ifdef __cplusplus extern "C" { diff --git a/pango/reorder-items.c b/pango/reorder-items.c index 18d68ab6..3e938240 100644 --- a/pango/reorder-items.c +++ b/pango/reorder-items.c @@ -19,7 +19,7 @@ * Boston, MA 02111-1307, USA. */ -#include <pango.h> +#include <pango/pango.h> /* * NB: The contents of the file implement the exact same algorithm diff --git a/pango/shape.c b/pango/shape.c index 04a966e0..7209d97a 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -19,7 +19,7 @@ * Boston, MA 02111-1307, USA. */ -#include <pango.h> +#include <pango/pango.h> #include "utils.h" /** @@ -34,7 +34,7 @@ * convert the characters into glyphs. You may also pass * in only a substring of the item from pango_itemize(). */ -void pango_shape (gchar *text, +void pango_shape (const gchar *text, gint length, PangoAnalysis *analysis, PangoGlyphString *glyphs) |