diff options
author | Owen Taylor <otaylor@redhat.com> | 2000-02-16 22:05:43 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2000-02-16 22:05:43 +0000 |
commit | 7f846326d416e9ab3eadca9f02b9a0129095f30b (patch) | |
tree | 4b2812b858cd830ca1282e3697d029ca347df24a | |
parent | 4f335d6e4a3f5b4e6ddd1cd78f919aa80c990262 (diff) | |
download | pango-7f846326d416e9ab3eadca9f02b9a0129095f30b.tar.gz |
Make refcounted.
Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com>
* libpango/pango-coverage.c (pango_coverage_get): Make refcounted.
* libpango/modules.c (struct _PangoEnginePair): Since we don't
currently unload engines, cache loaded engines. (Not really
quite satisfactory, but should work OK)
* libpango/pango-context.c (pango_context_get_font_description):
Added a global font description.
* libpango/modules.c (_pango_find_map): Allow NULL
language tags.
* libpango/pango-context.c (pango_itemize) examples/viewer.c:
Switch itemize over to take a PangoAttrList.
* examples/viewer.c: Conform to changes in itemization interface
* libpango/font.[ch]: Add a compare function for FontDescription
* libpango/pango-attributes.[ch]: Change the iteration iterface
to be more convenient.
* libpango/pango-context.[ch]: Add the ability to set a default font.
* libpango/pango-context.[ch]: Take the font for itemization from
the attributes on the text.
* libpango/pangox.c: Cache currently loaded fonts, and cache
coverages.
-rw-r--r-- | ChangeLog | 33 | ||||
-rw-r--r-- | ChangeLog.pre-1-0 | 33 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 33 | ||||
-rw-r--r-- | ChangeLog.pre-1-2 | 33 | ||||
-rw-r--r-- | ChangeLog.pre-1-4 | 33 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 33 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 33 | ||||
-rw-r--r-- | TODO | 5 | ||||
-rw-r--r-- | examples/viewer.c | 86 | ||||
-rw-r--r-- | pango/fonts.c | 34 | ||||
-rw-r--r-- | pango/modules.c | 55 | ||||
-rw-r--r-- | pango/pango-attributes.c | 107 | ||||
-rw-r--r-- | pango/pango-attributes.h | 5 | ||||
-rw-r--r-- | pango/pango-context.c | 347 | ||||
-rw-r--r-- | pango/pango-context.h | 59 | ||||
-rw-r--r-- | pango/pango-coverage.c | 51 | ||||
-rw-r--r-- | pango/pango-coverage.h | 5 | ||||
-rw-r--r-- | pango/pango-font.h | 45 | ||||
-rw-r--r-- | pango/pango-types.h | 5 | ||||
-rw-r--r-- | pango/pango.h | 14 | ||||
-rw-r--r-- | pango/pangox.c | 91 | ||||
-rw-r--r-- | pango/shape.c | 12 |
22 files changed, 853 insertions, 299 deletions
@@ -1,3 +1,35 @@ +Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-coverage.c (pango_coverage_get): Make refcounted. + + * libpango/modules.c (struct _PangoEnginePair): Since we don't + currently unload engines, cache loaded engines. (Not really + quite satisfactory, but should work OK) + + * libpango/pango-context.c (pango_context_get_font_description): + Added a global font description. + + * libpango/modules.c (_pango_find_map): Allow NULL + language tags. + + * libpango/pango-context.c (pango_itemize) examples/viewer.c: + Switch itemize over to take a PangoAttrList. + + * examples/viewer.c: Conform to changes in itemization interface + + * libpango/font.[ch]: Add a compare function for FontDescription + + * libpango/pango-attributes.[ch]: Change the iteration iterface + to be more convenient. + + * libpango/pango-context.[ch]: Add the ability to set a default font. + + * libpango/pango-context.[ch]: Take the font for itemization from + the attributes on the text. + + * libpango/pangox.c: Cache currently loaded fonts, and cache + coverages. + Tue Feb 15 02:35:56 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Add documentation for attributes. @@ -17,6 +49,7 @@ Fri Feb 11 16:04:50 2000 Owen Taylor <otaylor@redhat.com> * examples/HELLO.utf8: Change Maltese to a different phrase to include some unique Maltese characters. + (Suggestion from Steven R. Loomis) * libpango/Makefile.am modules/Makefile.am libpango/modules.c: Move pango.modules file to /var diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0 index 21363b54..fe9fb0f6 100644 --- a/ChangeLog.pre-1-0 +++ b/ChangeLog.pre-1-0 @@ -1,3 +1,35 @@ +Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-coverage.c (pango_coverage_get): Make refcounted. + + * libpango/modules.c (struct _PangoEnginePair): Since we don't + currently unload engines, cache loaded engines. (Not really + quite satisfactory, but should work OK) + + * libpango/pango-context.c (pango_context_get_font_description): + Added a global font description. + + * libpango/modules.c (_pango_find_map): Allow NULL + language tags. + + * libpango/pango-context.c (pango_itemize) examples/viewer.c: + Switch itemize over to take a PangoAttrList. + + * examples/viewer.c: Conform to changes in itemization interface + + * libpango/font.[ch]: Add a compare function for FontDescription + + * libpango/pango-attributes.[ch]: Change the iteration iterface + to be more convenient. + + * libpango/pango-context.[ch]: Add the ability to set a default font. + + * libpango/pango-context.[ch]: Take the font for itemization from + the attributes on the text. + + * libpango/pangox.c: Cache currently loaded fonts, and cache + coverages. + Tue Feb 15 02:35:56 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Add documentation for attributes. @@ -17,6 +49,7 @@ Fri Feb 11 16:04:50 2000 Owen Taylor <otaylor@redhat.com> * examples/HELLO.utf8: Change Maltese to a different phrase to include some unique Maltese characters. + (Suggestion from Steven R. Loomis) * libpango/Makefile.am modules/Makefile.am libpango/modules.c: Move pango.modules file to /var diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index 21363b54..fe9fb0f6 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,35 @@ +Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-coverage.c (pango_coverage_get): Make refcounted. + + * libpango/modules.c (struct _PangoEnginePair): Since we don't + currently unload engines, cache loaded engines. (Not really + quite satisfactory, but should work OK) + + * libpango/pango-context.c (pango_context_get_font_description): + Added a global font description. + + * libpango/modules.c (_pango_find_map): Allow NULL + language tags. + + * libpango/pango-context.c (pango_itemize) examples/viewer.c: + Switch itemize over to take a PangoAttrList. + + * examples/viewer.c: Conform to changes in itemization interface + + * libpango/font.[ch]: Add a compare function for FontDescription + + * libpango/pango-attributes.[ch]: Change the iteration iterface + to be more convenient. + + * libpango/pango-context.[ch]: Add the ability to set a default font. + + * libpango/pango-context.[ch]: Take the font for itemization from + the attributes on the text. + + * libpango/pangox.c: Cache currently loaded fonts, and cache + coverages. + Tue Feb 15 02:35:56 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Add documentation for attributes. @@ -17,6 +49,7 @@ Fri Feb 11 16:04:50 2000 Owen Taylor <otaylor@redhat.com> * examples/HELLO.utf8: Change Maltese to a different phrase to include some unique Maltese characters. + (Suggestion from Steven R. Loomis) * libpango/Makefile.am modules/Makefile.am libpango/modules.c: Move pango.modules file to /var diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index 21363b54..fe9fb0f6 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,3 +1,35 @@ +Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-coverage.c (pango_coverage_get): Make refcounted. + + * libpango/modules.c (struct _PangoEnginePair): Since we don't + currently unload engines, cache loaded engines. (Not really + quite satisfactory, but should work OK) + + * libpango/pango-context.c (pango_context_get_font_description): + Added a global font description. + + * libpango/modules.c (_pango_find_map): Allow NULL + language tags. + + * libpango/pango-context.c (pango_itemize) examples/viewer.c: + Switch itemize over to take a PangoAttrList. + + * examples/viewer.c: Conform to changes in itemization interface + + * libpango/font.[ch]: Add a compare function for FontDescription + + * libpango/pango-attributes.[ch]: Change the iteration iterface + to be more convenient. + + * libpango/pango-context.[ch]: Add the ability to set a default font. + + * libpango/pango-context.[ch]: Take the font for itemization from + the attributes on the text. + + * libpango/pangox.c: Cache currently loaded fonts, and cache + coverages. + Tue Feb 15 02:35:56 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Add documentation for attributes. @@ -17,6 +49,7 @@ Fri Feb 11 16:04:50 2000 Owen Taylor <otaylor@redhat.com> * examples/HELLO.utf8: Change Maltese to a different phrase to include some unique Maltese characters. + (Suggestion from Steven R. Loomis) * libpango/Makefile.am modules/Makefile.am libpango/modules.c: Move pango.modules file to /var diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index 21363b54..fe9fb0f6 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,35 @@ +Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-coverage.c (pango_coverage_get): Make refcounted. + + * libpango/modules.c (struct _PangoEnginePair): Since we don't + currently unload engines, cache loaded engines. (Not really + quite satisfactory, but should work OK) + + * libpango/pango-context.c (pango_context_get_font_description): + Added a global font description. + + * libpango/modules.c (_pango_find_map): Allow NULL + language tags. + + * libpango/pango-context.c (pango_itemize) examples/viewer.c: + Switch itemize over to take a PangoAttrList. + + * examples/viewer.c: Conform to changes in itemization interface + + * libpango/font.[ch]: Add a compare function for FontDescription + + * libpango/pango-attributes.[ch]: Change the iteration iterface + to be more convenient. + + * libpango/pango-context.[ch]: Add the ability to set a default font. + + * libpango/pango-context.[ch]: Take the font for itemization from + the attributes on the text. + + * libpango/pangox.c: Cache currently loaded fonts, and cache + coverages. + Tue Feb 15 02:35:56 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Add documentation for attributes. @@ -17,6 +49,7 @@ Fri Feb 11 16:04:50 2000 Owen Taylor <otaylor@redhat.com> * examples/HELLO.utf8: Change Maltese to a different phrase to include some unique Maltese characters. + (Suggestion from Steven R. Loomis) * libpango/Makefile.am modules/Makefile.am libpango/modules.c: Move pango.modules file to /var diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index 21363b54..fe9fb0f6 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,35 @@ +Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-coverage.c (pango_coverage_get): Make refcounted. + + * libpango/modules.c (struct _PangoEnginePair): Since we don't + currently unload engines, cache loaded engines. (Not really + quite satisfactory, but should work OK) + + * libpango/pango-context.c (pango_context_get_font_description): + Added a global font description. + + * libpango/modules.c (_pango_find_map): Allow NULL + language tags. + + * libpango/pango-context.c (pango_itemize) examples/viewer.c: + Switch itemize over to take a PangoAttrList. + + * examples/viewer.c: Conform to changes in itemization interface + + * libpango/font.[ch]: Add a compare function for FontDescription + + * libpango/pango-attributes.[ch]: Change the iteration iterface + to be more convenient. + + * libpango/pango-context.[ch]: Add the ability to set a default font. + + * libpango/pango-context.[ch]: Take the font for itemization from + the attributes on the text. + + * libpango/pangox.c: Cache currently loaded fonts, and cache + coverages. + Tue Feb 15 02:35:56 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Add documentation for attributes. @@ -17,6 +49,7 @@ Fri Feb 11 16:04:50 2000 Owen Taylor <otaylor@redhat.com> * examples/HELLO.utf8: Change Maltese to a different phrase to include some unique Maltese characters. + (Suggestion from Steven R. Loomis) * libpango/Makefile.am modules/Makefile.am libpango/modules.c: Move pango.modules file to /var diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index 21363b54..fe9fb0f6 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,35 @@ +Wed Feb 16 16:39:46 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-coverage.c (pango_coverage_get): Make refcounted. + + * libpango/modules.c (struct _PangoEnginePair): Since we don't + currently unload engines, cache loaded engines. (Not really + quite satisfactory, but should work OK) + + * libpango/pango-context.c (pango_context_get_font_description): + Added a global font description. + + * libpango/modules.c (_pango_find_map): Allow NULL + language tags. + + * libpango/pango-context.c (pango_itemize) examples/viewer.c: + Switch itemize over to take a PangoAttrList. + + * examples/viewer.c: Conform to changes in itemization interface + + * libpango/font.[ch]: Add a compare function for FontDescription + + * libpango/pango-attributes.[ch]: Change the iteration iterface + to be more convenient. + + * libpango/pango-context.[ch]: Add the ability to set a default font. + + * libpango/pango-context.[ch]: Take the font for itemization from + the attributes on the text. + + * libpango/pangox.c: Cache currently loaded fonts, and cache + coverages. + Tue Feb 15 02:35:56 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Add documentation for attributes. @@ -17,6 +49,7 @@ Fri Feb 11 16:04:50 2000 Owen Taylor <otaylor@redhat.com> * examples/HELLO.utf8: Change Maltese to a different phrase to include some unique Maltese characters. + (Suggestion from Steven R. Loomis) * libpango/Makefile.am modules/Makefile.am libpango/modules.c: Move pango.modules file to /var @@ -63,6 +63,11 @@ Documentation General ======= +* Remove the extraneous font argument from the script_shape vfunc + in ShapeEngine. + +* rename pango_context_set_size() to pango_context_set_font_size() + * PangoAttrList currently takes the policy of "most recent wins" when multiple attributes of the same type are present for a range. It would map better on the TkText tag-based API if attributes diff --git a/examples/viewer.c b/examples/viewer.c index 4967a35e..4670454b 100644 --- a/examples/viewer.c +++ b/examples/viewer.c @@ -61,8 +61,7 @@ struct _Line { }; static PangoFontDescription font_description; -static double font_size = 16; -static PangoFont *font = NULL; +static double font_size = 16000; static Paragraph *highlight_para; static int highlight_offset; @@ -146,6 +145,7 @@ split_paragraphs (char *text) para->text = last_para; para->length = p - last_para; para->height = 0; + para->lines = NULL; last_para = next; result = g_list_prepend (result, para); @@ -220,8 +220,8 @@ break_run (char *text, buf = pango_glyph_string_new(); - pango_shape (font, text + item->offset, item->length, &item->analysis, buf); - pango_x_extents (font, buf, NULL, NULL, &width, NULL, NULL, logical_ascent, logical_descent); + pango_shape (text + item->offset, item->length, &item->analysis, buf); + pango_x_extents (item->analysis.font, buf, NULL, NULL, &width, NULL, NULL, logical_ascent, logical_descent); result = FALSE; *new_item = NULL; @@ -272,6 +272,7 @@ break_run (char *text, (*new_item)->length = item->length - length; (*new_item)->num_chars = item->num_chars - num_chars; (*new_item)->analysis = item->analysis; + pango_font_ref ((*new_item)->analysis.font); item->length = length; item->num_chars = num_chars; @@ -291,6 +292,29 @@ break_run (char *text, return result; } +static void +free_item (PangoItem *item) +{ + pango_font_unref (item->analysis.font); + g_free (item); +} + +static void +free_line (Line *line) +{ + g_list_foreach (line->runs, (GFunc)free_item, NULL); + g_list_free (line->runs); + g_free (line); +} + +static void +para_free_lines (Paragraph *para) +{ + g_list_foreach (para->lines, (GFunc)free_line, NULL); + g_list_free (para->lines); + para->lines = NULL; +} + /* Break a paragraph into a list of lines which fit into * width, and compute the total height of the new paragraph */ @@ -302,11 +326,16 @@ layout_paragraph (Paragraph *para, int width) int remaining_width; int height = 0; PangoDirection base_dir = pango_context_get_base_dir (context); + PangoAttrList *attrs; /* Break paragraph into runs with consistent shaping engine * and direction */ - runs = pango_itemize (context, para->text, para->length, NULL, 0); + attrs = pango_attr_list_new (); + runs = pango_itemize (context, para->text, para->length, attrs); + pango_attr_list_unref (attrs); + + para_free_lines (para); /* Break runs to fit on each line */ @@ -410,8 +439,8 @@ runs_x_to_cp (char *text, GList *runs, int x, int *offset) { PangoItem *item = runs->data; - pango_shape (font, text + item->offset, item->length, &item->analysis, buf); - pango_x_extents (font, buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); + pango_shape (text + item->offset, item->length, &item->analysis, buf); + pango_x_extents (item->analysis.font, buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); if (x >= pixels && x < pixels + width) { @@ -505,8 +534,8 @@ runs_char_bounds (char *text, GList *runs, int offset, int *x, int *width) { PangoItem *item = runs->data; - pango_shape (font, text + item->offset, item->length, &item->analysis, buf); - pango_x_extents (font, buf, NULL, NULL, &run_width, NULL, NULL, NULL, NULL); + pango_shape (text + item->offset, item->length, &item->analysis, buf); + pango_x_extents (item->analysis.font, buf, NULL, NULL, &run_width, NULL, NULL, NULL, NULL); if (offset >= item->offset && offset < item->offset + item->length) @@ -659,21 +688,20 @@ expose_paragraph (Paragraph *para, GdkDrawable *drawable, int width; /* Convert the item into glyphs */ - pango_shape (font, - para->text + item->offset, item->length, + pango_shape (para->text + item->offset, item->length, &item->analysis, buf); /* Render the glyphs to the screen */ pango_x_render (GDK_DISPLAY(), GDK_WINDOW_XWINDOW (drawable), - GDK_GC_XGC (gc), font, buf, x + x_off, + GDK_GC_XGC (gc), item->analysis.font, buf, x + x_off, y + line->ascent); /* Advance to next x position */ if (run_list->next) { - pango_x_extents (font, buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); + pango_x_extents (item->analysis.font, buf, NULL, NULL, &width, NULL, NULL, NULL, NULL); x_off += width; } @@ -697,7 +725,7 @@ size_allocate (GtkWidget *layout, GtkAllocation *allocation, GList *paragraphs) { GList *tmp_list; int height = 0; - + tmp_list = paragraphs; while (tmp_list) { @@ -806,15 +834,8 @@ checkbutton_toggled (GtkWidget *widget, gpointer data) static void reload_font () { - PangoFont *new_font; - - new_font = pango_context_load_font (context, &font_description, font_size); - - if (new_font) - { - pango_font_unref (font); - font = new_font; - } + pango_context_set_font_description (context, &font_description); + pango_context_set_size (context, font_size); if (layout) gtk_widget_queue_resize (layout); @@ -841,7 +862,7 @@ set_style (GtkWidget *entry, gpointer data) void font_size_changed (GtkAdjustment *adj) { - font_size = adj->value; + font_size = (int)(adj->value * 1000 + 0.5); reload_font(); } @@ -1125,7 +1146,7 @@ make_font_selector (void) gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0); adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (spin_button)); - adj->value = font_size; + adj->value = font_size / 1000.; adj->lower = 0; adj->upper = 1024; adj->step_increment = 1; @@ -1176,20 +1197,9 @@ main (int argc, char **argv) font_description.weight = 500; font_description.stretch = PANGO_STRETCH_NORMAL; - font = pango_context_load_font (context, &font_description, font_size); - if (!font) - { - g_free (font_description.family_name); - font_description.family_name = g_strdup ("fixed"); - font = pango_context_load_font (context, &font_description, font_size); + pango_context_set_font_description (context, &font_description); + pango_context_set_size (context, font_size); - if (!font) - { - g_warning ("Can't load an initial font!\n"); - exit (1); - } - } - /* Create the user interface */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); diff --git a/pango/fonts.c b/pango/fonts.c index b52742aa..a66fde54 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -31,7 +31,7 @@ * must be freed using pango_font_description_free(). **/ PangoFontDescription * -pango_font_description_copy (PangoFontDescription *desc) +pango_font_description_copy (const PangoFontDescription *desc) { PangoFontDescription *result = g_new (PangoFontDescription, 1); @@ -43,6 +43,32 @@ pango_font_description_copy (PangoFontDescription *desc) } /** + * pango_font_description_compare: + * @desc1: a #PangoFontDescription + * @desc2: another #PangoFontDescription + * + * Compare two font descriptions for equality. + * + * Return value: %TRUE if the two font descriptions are proveably + * identical. (Two font descriptions may result in + * identical fonts being loaded, but still compare + * %FALSE.) + **/ +gboolean +pango_font_description_compare (const PangoFontDescription *desc1, + const PangoFontDescription *desc2) +{ + g_return_val_if_fail (desc1 != NULL, FALSE); + g_return_val_if_fail (desc2 != NULL, FALSE); + + return (desc1->style == desc2->style && + desc1->variant == desc2->variant && + desc1->weight == desc2->weight && + desc1->stretch == desc2->stretch && + g_strcasecmp (desc1->family_name, desc2->family_name)); +} + +/** * pango_font_description_free: * @desc: a #PangoFontDescription * @@ -278,9 +304,9 @@ pango_font_map_unref (PangoFontMap *fontmap) * Returns the font loaded, or %NULL if no font matched. **/ PangoFont * -pango_font_map_load_font (PangoFontMap *fontmap, - PangoFontDescription *desc, - double size) +pango_font_map_load_font (PangoFontMap *fontmap, + const PangoFontDescription *desc, + double size) { g_return_val_if_fail (fontmap != NULL, NULL); diff --git a/pango/modules.c b/pango/modules.c index 36040000..f2433ca8 100644 --- a/pango/modules.c +++ b/pango/modules.c @@ -34,15 +34,16 @@ typedef struct _PangoEnginePair PangoEnginePair; struct _PangoMapInfo { - gchar *lang; - gchar *engine_type; - gchar *render_type; + const gchar *lang; + const gchar *engine_type; + const gchar *render_type; }; struct _PangoEnginePair { - gchar *module; PangoEngineInfo info; + gchar *module; + PangoEngine *engine; }; GList *engines; @@ -67,9 +68,9 @@ _pango_find_map (const char *lang, map_hash = g_hash_table_new ((GHashFunc)map_info_hash, (GCompareFunc)map_info_equal); - map_info.lang = (char *)lang; - map_info.engine_type = (char *)engine_type; - map_info.render_type = (char *)render_type; + map_info.lang = lang ? lang : "NONE"; + map_info.engine_type = engine_type; + map_info.render_type = render_type; map = g_hash_table_lookup (map_hash, &map_info); if (!map) @@ -103,28 +104,30 @@ _pango_load_engine (const char *id) { GModule *module; PangoEngine *(*load) (const gchar *id); - PangoEngine *engine; - - module = g_module_open (pair->module, 0); - if (!module) - { - fprintf(stderr, "Cannot load module %s: %s\n", - pair->module, g_module_error()); - return NULL; - } - g_module_symbol (module, "script_engine_load", (gpointer)&load); - if (!load) + if (!pair->engine) { - fprintf(stderr, "cannot retrieve script_engine_load from %s: %s\n", - pair->module, g_module_error()); - g_module_close (module); - return NULL; + module = g_module_open (pair->module, 0); + if (!module) + { + fprintf(stderr, "Cannot load module %s: %s\n", + pair->module, g_module_error()); + return NULL; + } + + g_module_symbol (module, "script_engine_load", (gpointer)&load); + if (!load) + { + fprintf(stderr, "cannot retrieve script_engine_load from %s: %s\n", + pair->module, g_module_error()); + g_module_close (module); + return NULL; + } + + pair->engine = (*load) (id); } - engine = (*load) (id); - - return engine; + return pair->engine; } } @@ -291,6 +294,8 @@ read_modules (void) g_list_free (ranges); g_free (line); + pair->engine = NULL; + engines = g_list_prepend (engines, pair); } engines = g_list_reverse (engines); diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 35f353db..cdbbbbbb 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -32,6 +32,8 @@ struct _PangoAttrIterator { GSList *next_attribute; GList *attribute_stack; + int start_index; + int end_index; }; static PangoAttribute *pango_attr_color_new (const PangoAttrClass *klass, @@ -550,6 +552,8 @@ pango_attr_list_unref (PangoAttrList *list) } g_slist_free (list->attributes); + + g_free (list); } } @@ -726,22 +730,42 @@ pango_attr_list_change (PangoAttrList *list, PangoAttrIterator * pango_attr_list_get_iterator (PangoAttrList *list) { - PangoAttrIterator *result; + PangoAttrIterator *iterator; g_return_val_if_fail (list != NULL, NULL); - result = g_new (PangoAttrIterator, 1); - result->next_attribute = list->attributes; - result->attribute_stack = NULL; + iterator = g_new (PangoAttrIterator, 1); + iterator->next_attribute = list->attributes; + iterator->attribute_stack = NULL; - while (result->next_attribute && - ((PangoAttribute *)result->next_attribute->data)->start_index == 0) - { - result->attribute_stack = g_list_prepend (result->attribute_stack, result->next_attribute->data); - result->next_attribute = result->next_attribute->next; - } + iterator->start_index = 0; + iterator->end_index = 0; - return result; + if (!pango_attr_iterator_next (iterator)) + iterator->end_index = G_MAXINT; + + return iterator; +} + +/** + * pango_attr_iterator_range: + * @iterator: a #PangoAttrIterator + * @start: location to store the start of the range + * @end: location to store the end of the range + * + * Get the range of the current segment. + **/ +void +pango_attr_iterator_range (PangoAttrIterator *iterator, + gint *start, + gint *end) +{ + g_return_if_fail (iterator != NULL); + + if (start) + *start = iterator->start_index; + if (end) + *end = iterator->end_index; } /** @@ -750,63 +774,52 @@ pango_attr_list_get_iterator (PangoAttrList *list) * * Advance the iterator until the next change of style. * - * Return value: the index of the next change of position, or -1 if iterator - * is at the end of the list. + * Return value: %FALSE if the iterator is at the end of the list, otherwise %TRUE **/ -int +gboolean pango_attr_iterator_next (PangoAttrIterator *iterator) { - int next_index = G_MAXINT; GList *tmp_list; g_return_val_if_fail (iterator != NULL, -1); if (!iterator->next_attribute && !iterator->attribute_stack) - return -1; - - tmp_list = iterator->attribute_stack; - while (tmp_list) - { - PangoAttribute *attr = tmp_list->data; - if (attr->end_index < next_index) - next_index = attr->end_index; - } + return FALSE; - tmp_list = iterator->attribute_stack; + iterator->start_index = iterator->end_index; + iterator->end_index = G_MAXINT; - if (iterator->next_attribute) - { - int next_start = ((PangoAttribute *)iterator->next_attribute->data)->start_index; - - if (next_start <= next_index) - { - do - { - iterator->attribute_stack = g_list_prepend (iterator->attribute_stack, iterator->next_attribute->data); - iterator->next_attribute = iterator->next_attribute->next; - } - while (iterator->next_attribute && - ((PangoAttribute *)iterator->next_attribute->data)->start_index == next_start); - } - - if (next_start < next_index) - return next_start; - } - + tmp_list = iterator->attribute_stack; while (tmp_list) { GList *next = tmp_list->next; + PangoAttribute *attr = tmp_list->data; - if (((PangoAttribute *)tmp_list->data)->start_index == next_index) + if (attr->end_index == iterator->start_index) { iterator->attribute_stack = g_list_remove_link (iterator->attribute_stack, tmp_list); g_list_free_1 (tmp_list); } + else + { + iterator->end_index = MIN (iterator->end_index, attr->end_index); + } tmp_list = next; } - - return next_index; + + while (iterator->next_attribute && + ((PangoAttribute *)iterator->next_attribute->data)->start_index == iterator->start_index) + { + iterator->attribute_stack = g_list_prepend (iterator->attribute_stack, iterator->next_attribute->data); + iterator->end_index = MIN (iterator->end_index, ((PangoAttribute *)iterator->next_attribute->data)->end_index); + iterator->next_attribute = iterator->next_attribute->next; + } + + if (iterator->next_attribute) + iterator->end_index = MIN (iterator->end_index, ((PangoAttribute *)iterator->next_attribute->data)->start_index); + + return TRUE; } /** diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index 322c5c75..8c72d750 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -121,7 +121,10 @@ void pango_attr_list_change (PangoAttrList *list, PangoAttribute *attr); PangoAttrIterator * pango_attr_list_get_iterator (PangoAttrList *list); -int pango_attr_iterator_next (PangoAttrIterator *iterator); +void pango_attr_iterator_range (PangoAttrIterator *iterator, + gint *start, + gint *end); +gboolean pango_attr_iterator_next (PangoAttrIterator *iterator); void pango_attr_iterator_destroy (PangoAttrIterator *iterator); PangoAttribute *pango_attr_iterator_get (PangoAttrIterator *iterator, PangoAttrType type); diff --git a/pango/pango-context.c b/pango/pango-context.c index 2e8c6700..fe8d955e 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -26,17 +26,26 @@ #include "utils.h" #include "modules.h" - struct _PangoContext { gint ref_count; char *lang; PangoDirection base_dir; + PangoFontDescription *font_desc; + int size; GSList *font_maps; }; +static void add_engines (PangoContext *context, + gchar *text, + gint length, + PangoAttrList *attrs, + PangoEngineShape **shape_engines, + PangoEngineInfo **lang_engines, + PangoFont **fonts); + /** * pango_context_new: * @@ -48,11 +57,21 @@ PangoContext * pango_context_new (void) { PangoContext *result = g_new (PangoContext, 1); + PangoFontDescription desc; + result->ref_count = 1; result->base_dir = PANGO_DIRECTION_LTR; result->lang = NULL; result->font_maps = NULL; + desc.family_name = "serif"; + desc.style = PANGO_STYLE_NORMAL; + desc.variant = PANGO_VARIANT_NORMAL; + desc.weight = PANGO_WEIGHT_NORMAL; + desc.stretch = PANGO_STRETCH_NORMAL; + + result->font_desc = pango_font_description_copy (&desc); + return result; } @@ -311,9 +330,9 @@ pango_context_list_families (PangoContext *context, * Returns the font loaded, or %NULL if no font matched. **/ PangoFont * -pango_context_load_font (PangoContext *context, - PangoFontDescription *desc, - gdouble size) +pango_context_load_font (PangoContext *context, + const PangoFontDescription *desc, + gdouble size) { GSList *tmp_list; @@ -335,6 +354,41 @@ pango_context_load_font (PangoContext *context, } /** + * pango_context_set_font_description: + * @context: a #PangoContext + * @desc: the new pango font description + * + * Set the default font description for the context + **/ +void +pango_context_set_font_description (PangoContext *context, + const PangoFontDescription *desc) +{ + g_return_if_fail (context != NULL); + g_return_if_fail (desc != NULL); + + pango_font_description_free (context->font_desc); + context->font_desc = pango_font_description_copy (desc); +} + +/** + * pango_context_get_font_description: + * @context: a #PangoContext + * + * Retrieve the default font description for the context. + * + * Return value: a newly allocated copy of the contexts default font description. + * This value must be free with pango_font_description_free() + **/ +PangoFontDescription * +pango_context_get_font_description (PangoContext *context) +{ + g_return_val_if_fail (context != NULL, NULL); + + return pango_font_description_copy (context->font_desc); +} + +/** * pango_context_set_lang: * @context: a #PangoContext * @lang: the new language tag. @@ -370,6 +424,38 @@ pango_context_get_lang (PangoContext *context) } /** + * pango_context_get_size: + * @context: a #PangoContext + * + * Retrieves the default font size for the context. + * + * Return value: the default font size in 1000ths of a point. + **/ +int +pango_context_get_size (PangoContext *context) +{ + g_return_val_if_fail (context != NULL, 0); + + return context->size; +} + +/** + * pango_context_set_size: + * @context: a #PangoContext + * @lang: the new default font size in points in 1000ths of a point. + * + * Sets the default font size for the context. + **/ +void +pango_context_set_size (PangoContext *context, + int size) +{ + g_return_if_fail (context != NULL); + + context->size = size; +} + +/** * pango_context_set_base_dir: * @context: a #PangoContext * @direction: the new base direction @@ -401,15 +487,6 @@ pango_context_get_base_dir (PangoContext *context) return context->base_dir; } -static void add_engines (PangoContext *context, - gchar *text, - gint length, - PangoLangRange *lang_info, - gint n_langs, - gboolean force_exact, - PangoEngineInfo **shape_engines, - PangoEngineInfo **lang_engines); - /** * pango_itemize: * @context: a structure holding information that affects @@ -417,8 +494,7 @@ static void add_engines (PangoContext *context, * @text: the text to itemize. * @length: the number of bytes (not characters) in text. * This must be >= 0. - * @lang_info: an array of language tagging information. - * @n_langs: the number of elements in @lang_info. + * @attr: the set of attributes that apply to @text. * * Breaks a piece of text into segments with consistent * directional level and shaping engine. @@ -427,10 +503,9 @@ static void add_engines (PangoContext *context, */ GList * pango_itemize (PangoContext *context, - gchar *text, - gint length, - PangoLangRange *lang_info, - gint n_langs) + gchar *text, + gint length, + PangoAttrList *attrs) { guint16 *text_ucs2; gint n_chars; @@ -441,8 +516,9 @@ pango_itemize (PangoContext *context, char *p, *next; GList *result = NULL; - PangoEngineInfo **shape_engines; + PangoEngineShape **shape_engines; PangoEngineInfo **lang_engines; + PangoFont **fonts; g_return_val_if_fail (context != NULL, NULL); g_return_val_if_fail (text != NULL, NULL); @@ -471,27 +547,19 @@ pango_itemize (PangoContext *context, * but also more complicated... we take the simple * approach for now. */ - shape_engines = g_new0 (PangoEngineInfo *, n_chars); + shape_engines = g_new0 (PangoEngineShape *, n_chars); lang_engines = g_new0 (PangoEngineInfo *, n_chars); + fonts = g_new0 (PangoFont *, n_chars); fribidi_log2vis_get_embedding_levels (text_ucs2, n_chars, &base_dir, embedding_levels); - /* Now, make shaping-engine affilitations for characters in - * each run that have high-affinity. This means that there - * is a shaping engine specific to the current - * language/character pair. + /* Now, fill in the appropriate shapers, language engines and fonts for + * each character. */ - add_engines (context, text, length, lang_info, n_langs, - TRUE, shape_engines, lang_engines); + add_engines (context, text, length, attrs, shape_engines, lang_engines, fonts); - /* Fill in low-affinity shaping-engine affiliations for - * remainder of characters. - */ - - add_engines (context, text, length, lang_info, n_langs, - FALSE, shape_engines, lang_engines); /* Make a GList of PangoItems out of the above results */ @@ -505,105 +573,214 @@ pango_itemize (PangoContext *context, if (i == 0 || embedding_levels[i] != embedding_levels[i-1] || shape_engines[i] != shape_engines[i-1] || - lang_engines[i] != lang_engines[i-1]) + lang_engines[i] != lang_engines[i-1] || + fonts[i] != fonts[i-1]) { - if (item) - result = g_list_prepend (result, item); item = g_new (PangoItem, 1); item->offset = p - text; item->num_chars = 0; item->analysis.level = embedding_levels[i]; - if (shape_engines[i]) - item->analysis.shape_engine = (PangoEngineShape *)_pango_load_engine (shape_engines[i]->id); - else - item->analysis.shape_engine = NULL; + item->analysis.shape_engine = shape_engines[i]; if (lang_engines[i]) item->analysis.lang_engine = (PangoEngineLang *)_pango_load_engine (lang_engines[i]->id); else item->analysis.lang_engine = NULL; + + item->analysis.font = fonts[i]; + + result = g_list_prepend (result, item); } + else + pango_font_unref (fonts[i]); item->length = (next - text) - item->offset; item->num_chars++; p = next; } - if (item) - result = g_list_prepend (result, item); - + g_free (embedding_levels); + g_free (shape_engines); + g_free (lang_engines); + g_free (fonts); + g_free (text_ucs2); return g_list_reverse (result); } +static PangoFont * +get_font (PangoFont **fonts, + PangoCoverage **coverages, + int n_families, + GUChar4 wc) +{ + PangoFont *result = NULL; + PangoCoverageLevel best_level = PANGO_COVERAGE_NONE; + + int i; + + for (i=0; i<n_families; i++) + { + if (fonts[i]) + { + PangoCoverageLevel level = pango_coverage_get (coverages[i], wc); + + if (!result || level > best_level) + { + result = fonts[i]; + best_level = level; + } + } + } + + if (result) + pango_font_ref (result); + + return result; +} + static void -add_engines (PangoContext *context, - gchar *text, - gint length, - PangoLangRange *lang_info, - gint n_langs, - gboolean force_exact, - PangoEngineInfo **shape_engines, - PangoEngineInfo **lang_engines) +add_engines (PangoContext *context, + gchar *text, + gint length, + PangoAttrList *attrs, + PangoEngineShape **shape_engines, + PangoEngineInfo **lang_engines, + PangoFont **fonts) { char *pos; - char *last_lang = NULL; + char *lang = NULL; + int next_index = 0; gint n_chars; PangoMap *shape_map = NULL; PangoMap *lang_map = NULL; + PangoFontDescription current_desc = { 0 }; + int current_size = 0; + int next_size = 0; + + /* FIXME: Remove this artificial limit */ + + int n_families = 0; +#define MAX_FAMILIES 16 + PangoFont *current_fonts[MAX_FAMILIES]; + PangoCoverage *current_coverages[MAX_FAMILIES]; + + PangoAttrIterator *iterator; + PangoAttribute *attr; + GUChar4 wc; int i, j; n_chars = unicode_strlen (text, length); + iterator = pango_attr_list_get_iterator (attrs); + pos = text; - last_lang = NULL; - for (i=0, j=0; i<n_chars; i++) + for (i=0; i<n_chars; i++) { - char *lang; PangoSubmap *submap; PangoMapEntry *entry; - while (j < n_langs && lang_info[j].start < pos - text) - j++; - - if (j < n_langs && (pos - text) < lang_info[j].start + lang_info[j].length) - lang = lang_info[j].lang; - else - lang = context->lang; - - if (last_lang != lang || - last_lang == 0 || lang == 0 || - strcmp (lang, last_lang) != 0) + if (i == next_index) { - lang_map = _pango_find_map (lang, PANGO_ENGINE_TYPE_LANG, - PANGO_RENDER_TYPE_NONE); - shape_map = _pango_find_map (lang, PANGO_ENGINE_TYPE_SHAPE, - "PangoRenderX"); - last_lang = lang; - } + char *next_lang; + PangoFontDescription next_desc; + + attr = pango_attr_iterator_get (iterator, PANGO_ATTR_LANG); + if (attr) + next_lang = ((PangoAttrString *)attr)->value; + else + next_lang = context->lang; - pos = unicode_get_utf8 (pos, &wc); + if (i == 0 || + (lang != next_lang && + (lang == NULL || next_lang == NULL || strcmp (lang, next_lang) != 0))) + { + lang = next_lang; + + lang_map = _pango_find_map (next_lang, PANGO_ENGINE_TYPE_LANG, + PANGO_RENDER_TYPE_NONE); + shape_map = _pango_find_map (next_lang, PANGO_ENGINE_TYPE_SHAPE, + "PangoRenderX"); + } - if (!lang_engines[i]) - { - submap = &lang_map->submaps[wc / 256]; - entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256]; + pango_attr_iterator_get_font (iterator, context->font_desc, &next_desc); + + attr = pango_attr_iterator_get (iterator, PANGO_ATTR_SIZE); + if (attr) + next_size = ((PangoAttrInt *)attr)->value; + else + next_size = context->size; - if (entry->info && (!force_exact || entry->is_exact)) - lang_engines[i] = entry->info; + if (i == 0 || + !pango_font_description_compare (¤t_desc, &next_desc) || + current_size != next_size) + { + char **families; + + current_desc = next_desc; + current_size = next_size; + + for (j=0; j<n_families; j++) + { + if (current_fonts[j]) + { + pango_font_unref (current_fonts[j]); + pango_coverage_unref (current_coverages[j]); + } + } + + families = g_strsplit (current_desc.family_name, ",", -1); + n_families = 0; + while (families[n_families]) + n_families++; + + if (n_families > MAX_FAMILIES) + n_families = MAX_FAMILIES; + + for (j=0; j<n_families; j++) + { + next_desc.family_name = families[j]; + current_fonts[j] = pango_context_load_font (context, &next_desc, next_size / 1000.); + + if (current_fonts[j]) + current_coverages[j] = pango_font_get_coverage (current_fonts[j], lang); + } + + g_strfreev (families); + } + + pango_attr_iterator_range (iterator, NULL, &next_index); + pango_attr_iterator_next (iterator); } - if (!shape_engines[i]) - { - submap = &shape_map->submaps[wc / 256]; - entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256]; + pos = unicode_get_utf8 (pos, &wc); + + submap = &lang_map->submaps[wc / 256]; + entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256]; + + lang_engines[i] = entry->info; + + fonts[i] = get_font (current_fonts, current_coverages, n_families, wc); - if (entry->info && (!force_exact || entry->is_exact)) - shape_engines[i] = entry->info; + /* FIXME: handle reference counting properly on the shapers */ + if (fonts[i]) + shape_engines[i] = pango_font_find_shaper (fonts[i], lang, wc); + else + shape_engines[i] = NULL; + } + + for (j=0; j<n_families; j++) + { + if (current_fonts[j]) + { + pango_font_unref (current_fonts[j]); + pango_coverage_unref (current_coverages[j]); } } + + pango_attr_iterator_destroy (iterator); } diff --git a/pango/pango-context.h b/pango/pango-context.h index 64fe06ac..bc8badf9 100644 --- a/pango/pango-context.h +++ b/pango/pango-context.h @@ -23,6 +23,7 @@ #define __PANGO_CONTEXT_H__ #include <pango-font.h> +#include <pango-attributes.h> #ifdef __cplusplus extern "C" { @@ -33,31 +34,43 @@ extern "C" { */ typedef struct _PangoContext PangoContext; -PangoContext * pango_context_new (void); -void pango_context_ref (PangoContext *context); -void pango_context_unref (PangoContext *context); +PangoContext *pango_context_new (void); +void pango_context_ref (PangoContext *context); +void pango_context_unref (PangoContext *context); +void pango_context_add_font_map (PangoContext *context, + PangoFontMap *font_map); +void pango_context_list_fonts (PangoContext *context, + const char *family, + PangoFontDescription ***descs, + int *n_descs); +void pango_context_list_families (PangoContext *context, + gchar ***families, + int *n_families); +PangoFont * pango_context_load_font (PangoContext *context, + const PangoFontDescription *desc, + gdouble size); -void pango_context_add_font_map (PangoContext *context, - PangoFontMap *font_map); - -void pango_context_list_fonts (PangoContext *context, - const char *family, - PangoFontDescription ***descs, - int *n_descs); -void pango_context_list_families (PangoContext *context, - gchar ***families, - int *n_families); -PangoFont * pango_context_load_font (PangoContext *context, - PangoFontDescription *desc, - gdouble size); - -void pango_context_set_lang (PangoContext *context, - const char *lang); -char * pango_context_get_lang (PangoContext *context); -void pango_context_set_base_dir (PangoContext *context, - PangoDirection direction); -PangoDirection pango_context_get_base_dir (PangoContext *context); +void pango_context_set_font_description (PangoContext *context, + const PangoFontDescription *desc); +PangoFontDescription *pango_context_get_font_description (PangoContext *context); +char * pango_context_get_lang (PangoContext *context); +void pango_context_set_lang (PangoContext *context, + const char *lang); +int pango_context_get_size (PangoContext *context); +void pango_context_set_size (PangoContext *context, + int size); +void pango_context_set_base_dir (PangoContext *context, + PangoDirection direction); +PangoDirection pango_context_get_base_dir (PangoContext *context); +/* Break a string of Unicode characters into segments with + * consistent shaping/language engine and bidrectional level. + * Returns a GList of PangoItem's + */ +GList *pango_itemize (PangoContext *context, + gchar *text, + gint length, + PangoAttrList *attrs); #ifdef __cplusplus } diff --git a/pango/pango-coverage.c b/pango/pango-coverage.c index d6ce8812..cc9ca246 100644 --- a/pango/pango-coverage.c +++ b/pango/pango-coverage.c @@ -39,6 +39,7 @@ struct _PangoBlockInfo struct _PangoCoverage { + guint ref_count; int n_blocks; int data_size; @@ -50,7 +51,8 @@ struct _PangoCoverage * * Create a new #PangoCoverage * - * Return value: a new PangoCoverage object, initialized to PANGO_COVERAGE_NONE + * Return value: a new PangoCoverage object, initialized to %PANGO_COVERAGE_NONE + * with a reference count of 0. **/ PangoCoverage * pango_coverage_new (void) @@ -60,6 +62,7 @@ pango_coverage_new (void) coverage->n_blocks = N_BLOCKS_INCREMENT; coverage->blocks = g_new (PangoBlockInfo, coverage->n_blocks); + coverage->ref_count = 1; for (i=0; i<coverage->n_blocks; i++) { @@ -74,9 +77,11 @@ pango_coverage_new (void) * pango_coverage_copy: * @coverage: a #PangoCoverage * - * Copy an existing #PangoCoverage + * Copy an existing #PangoCoverage. (This function may now be unecessary + * since we refcount the structure. Mail otaylor@redhat.com if you + * use it.) * - * Return value: a copy of @coverage + * Return value: a copy of @coverage with a reference count of 1 **/ PangoCoverage * pango_coverage_copy (PangoCoverage *coverage) @@ -88,6 +93,7 @@ pango_coverage_copy (PangoCoverage *coverage) result->n_blocks = coverage->n_blocks; result->blocks = g_new (PangoBlockInfo, coverage->n_blocks); + result->ref_count = 1; for (i=0; i<coverage->n_blocks; i++) { @@ -106,24 +112,47 @@ pango_coverage_copy (PangoCoverage *coverage) } /** - * pango_coverage_destroy: + * pango_coverage_ref: * @coverage: a #PangoCoverage * - * Destroy a #PangoCoverage object, freeing associated memory + * Increase the reference count on the #PangoCoverage by one **/ -void pango_coverage_destroy (PangoCoverage *coverage) +void +pango_coverage_ref (PangoCoverage *coverage) +{ + g_return_if_fail (coverage != NULL); + + coverage->ref_count++; +} + +/** + * pango_coverage_unref: + * @coverage: a #PangoCoverage + * + * Increase the reference count on the #PangoCoverage by one. + * if the result is zero, free the coverage and all associated memory. + **/ +void +pango_coverage_unref (PangoCoverage *coverage) { int i; g_return_if_fail (coverage != NULL); + g_return_if_fail (coverage->ref_count > 0); - for (i=0; i<coverage->n_blocks; i++) + coverage->ref_count--; + + if (coverage->ref_count == 0) { - if (coverage->blocks[i].data) - g_free (coverage->blocks[i].data); + for (i=0; i<coverage->n_blocks; i++) + { + if (coverage->blocks[i].data) + g_free (coverage->blocks[i].data); + } + + g_free (coverage->blocks); + g_free (coverage); } - - g_free (coverage); } /** diff --git a/pango/pango-coverage.h b/pango/pango-coverage.h index 2b613f94..08febeb7 100644 --- a/pango/pango-coverage.h +++ b/pango/pango-coverage.h @@ -38,8 +38,9 @@ typedef enum { } PangoCoverageLevel; PangoCoverage * pango_coverage_new (void); +void pango_coverage_ref (PangoCoverage *coverage); +void pango_coverage_unref (PangoCoverage *coverage); PangoCoverage * pango_coverage_copy (PangoCoverage *coverage); -void pango_coverage_destroy (PangoCoverage *coverage); PangoCoverageLevel pango_coverage_get (PangoCoverage *coverage, int index); void pango_coverage_set (PangoCoverage *coverage, @@ -53,3 +54,5 @@ void pango_coverage_max (PangoCoverage *coverage, #endif /* __cplusplus */ #endif __PANGO_COVERAGE_H__ + + diff --git a/pango/pango-font.h b/pango/pango-font.h index 161236e6..1c262609 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -30,7 +30,6 @@ extern "C" { #include <pango-types.h> typedef struct _PangoFontDescription PangoFontDescription; -typedef struct _PangoFont PangoFont; typedef struct _PangoFontClass PangoFontClass; typedef struct _PangoFontMap PangoFontMap; typedef struct _PangoFontMapClass PangoFontMapClass; @@ -72,10 +71,12 @@ struct _PangoFontDescription { PangoStretch stretch; }; -PangoFontDescription *pango_font_description_copy (PangoFontDescription *desc); -void pango_font_description_free (PangoFontDescription *desc); -void pango_font_descriptions_free (PangoFontDescription **descs, - int n_descs); +PangoFontDescription *pango_font_description_copy (const PangoFontDescription *desc); +gboolean pango_font_description_compare (const PangoFontDescription *desc1, + const PangoFontDescription *desc2); +void pango_font_description_free (PangoFontDescription *desc); +void pango_font_descriptions_free (PangoFontDescription **descs, + int n_descs); /* Logical fonts */ @@ -130,25 +131,25 @@ struct _PangoFontMap struct _PangoFontMapClass { - void (*destroy) (PangoFontMap *fontmap); - PangoFont *(*load_font) (PangoFontMap *fontmap, - PangoFontDescription *desc, - double size); - void (*list_fonts) (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs); - void (*list_families) (PangoFontMap *fontmap, - gchar ***families, - int *n_families); + void (*destroy) (PangoFontMap *fontmap); + PangoFont *(*load_font) (PangoFontMap *fontmap, + const PangoFontDescription *desc, + double size); + void (*list_fonts) (PangoFontMap *fontmap, + const gchar *family, + PangoFontDescription ***descs, + int *n_descs); + void (*list_families) (PangoFontMap *fontmap, + gchar ***families, + int *n_families); }; -void pango_font_map_init (PangoFontMap *fontmap); -void pango_font_map_ref (PangoFontMap *fontmap); -void pango_font_map_unref (PangoFontMap *fontmap); -PangoFont *pango_font_map_load_font (PangoFontMap *fontmap, - PangoFontDescription *desc, - double size); +void pango_font_map_init (PangoFontMap *fontmap); +void pango_font_map_ref (PangoFontMap *fontmap); +void pango_font_map_unref (PangoFontMap *fontmap); +PangoFont *pango_font_map_load_font (PangoFontMap *fontmap, + const PangoFontDescription *desc, + double size); void pango_font_map_list_fonts (PangoFontMap *fontmap, const gchar *family, diff --git a/pango/pango-types.h b/pango/pango-types.h index 46dc794b..33ef0195 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -38,13 +38,16 @@ typedef struct _PangoLogAttr PangoLogAttr; typedef struct _PangoEngineLang PangoEngineLang; typedef struct _PangoEngineShape PangoEngineShape; +typedef struct _PangoFont PangoFont; + /* Information about a segment of text with a consistent * shaping/language engine and bidirectional level */ struct _PangoAnalysis { PangoEngineShape *shape_engine; - PangoEngineLang *lang_engine; + PangoEngineLang *lang_engine; + PangoFont *font; guint8 level; }; diff --git a/pango/pango.h b/pango/pango.h index 60993938..f06c52cd 100644 --- a/pango/pango.h +++ b/pango/pango.h @@ -28,6 +28,7 @@ extern "C" { #endif /* __cplusplus */ +#include <pango-attributes.h> #include <pango-context.h> #include <pango-coverage.h> #include <pango-engine.h> @@ -36,16 +37,6 @@ extern "C" { #include <pango-layout.h> #include <pango-types.h> -/* Break a string of Unicode characters into segments with - * consistent shaping/language engine and bidrectional level. - * Returns a GList of PangoItem's - */ -GList *pango_itemize (PangoContext *context, - gchar *text, - gint length, - PangoLangRange *lang_info, - gint n_langs); - /* Logical attributes of a character */ struct _PangoLogAttr { @@ -66,8 +57,7 @@ void pango_break (gchar *text, /* Turn a string of characters into a string of glyphs */ -void pango_shape (PangoFont *font, - gchar *text, +void pango_shape (gchar *text, gint length, PangoAnalysis *analysis, PangoGlyphString *glyphs); diff --git a/pango/pangox.c b/pango/pangox.c index bcc175d1..80b18395 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -49,6 +49,9 @@ struct _PangoXFontEntry { char *xlfd; PangoFontDescription description; + PangoCoverage *coverage; + + GSList *cached_fonts; }; struct _PangoXFamilyEntry @@ -81,6 +84,8 @@ struct _PangoXFont int n_subfonts; int max_subfonts; + + PangoXFontEntry *entry; /* Used to remove cached fonts */ }; struct _PangoXFontMap @@ -155,18 +160,18 @@ const struct { { "condensed", PANGO_STRETCH_CONDENSED }, }; -static void pango_x_font_map_destroy (PangoFontMap *fontmap); -static PangoFont *pango_x_font_map_load_font (PangoFontMap *fontmap, - PangoFontDescription *desc, - double size); -static void pango_x_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs); -static void pango_x_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, - int *n_families); -static void pango_x_font_map_read_aliases (PangoXFontMap *xfontmap); +static void pango_x_font_map_destroy (PangoFontMap *fontmap); +static PangoFont *pango_x_font_map_load_font (PangoFontMap *fontmap, + const PangoFontDescription *desc, + double size); +static void pango_x_font_map_list_fonts (PangoFontMap *fontmap, + const gchar *family, + PangoFontDescription ***descs, + int *n_descs); +static void pango_x_font_map_list_families (PangoFontMap *fontmap, + gchar ***families, + int *n_families); +static void pango_x_font_map_read_aliases (PangoXFontMap *xfontmap); static void pango_x_font_destroy (PangoFont *font); static PangoFontDescription *pango_x_font_describe (PangoFont *font); @@ -296,9 +301,9 @@ pango_x_get_family_entry (PangoXFontMap *xfontmap, } static PangoFont * -pango_x_font_map_load_font (PangoFontMap *fontmap, - PangoFontDescription *description, - double size) +pango_x_font_map_load_font (PangoFontMap *fontmap, + const PangoFontDescription *description, + double size) { PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap; PangoXFamilyEntry *family_entry; @@ -339,8 +344,27 @@ pango_x_font_map_load_font (PangoFontMap *fontmap, if (best_match) { - /* FIXME: cache fonts */ - result = pango_x_load_font_with_size (xfontmap->display, best_match->xlfd, size); + GSList *tmp_list = best_match->cached_fonts; + + while (tmp_list) + { + PangoXFont *xfont = tmp_list->data; + if (xfont->size == size) + { + result = (PangoFont *)xfont; + pango_font_ref (result); + break; + } + tmp_list = tmp_list->next; + } + + if (!result) + { + result = pango_x_load_font_with_size (xfontmap->display, best_match->xlfd, size); + ((PangoXFont *)result)->entry = best_match; + best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, result); + } + } } @@ -853,6 +877,8 @@ pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap, g_free (font_entry->description.family_name); font_entry->description.family_name = family_entry->family_name; + font_entry->cached_fonts = NULL; + font_entry->coverage = NULL; } if (ferror (infile)) @@ -1137,6 +1163,8 @@ pango_x_insert_font (PangoXFontMap *xfontmap, font_entry = g_new (PangoXFontEntry, 1); font_entry->description = description; font_entry->description.family_name = family_entry->family_name; + font_entry->cached_fonts = NULL; + font_entry->coverage = NULL; font_entry->xlfd = g_strconcat ("-*-", family_buffer, @@ -1194,7 +1222,7 @@ pango_x_load_font (Display *display, result->fonts = g_strsplit(spec, ",", -1); for (result->n_fonts = 0; result->fonts[result->n_fonts]; result->n_fonts++) - /* Nothing */ + ; /* Nothing */ result->subfonts_by_charset = g_hash_table_new (g_str_hash, g_str_equal); result->subfonts = g_new (PangoXSubfontInfo *, 1); @@ -1203,6 +1231,7 @@ pango_x_load_font (Display *display, result->max_subfonts = 1; result->size = -1; + result->entry = NULL; return (PangoFont *)result; } @@ -1238,7 +1267,7 @@ pango_x_load_font_with_size (Display *display, result->fonts = g_strsplit(spec, ",", -1); for (result->n_fonts = 0; result->fonts[result->n_fonts]; result->n_fonts++) - /* Nothing */ + ; /* Nothing */ result->subfonts_by_charset = g_hash_table_new (g_str_hash, g_str_equal); result->subfonts = g_new (PangoXSubfontInfo *, 1); @@ -1247,6 +1276,7 @@ pango_x_load_font_with_size (Display *display, result->max_subfonts = 1; result->size = size; + result->entry = NULL; return (PangoFont *)result; } @@ -1637,7 +1667,7 @@ pango_x_make_matching_xlfd (PangoXFontMap *xfontmap, char *xlfd, const char *cha } } - /* g_free (dash_charset); */ + g_free (dash_charset); return result; } @@ -1803,6 +1833,9 @@ pango_x_font_destroy (PangoFont *font) g_hash_table_foreach (xfont->subfonts_by_charset, subfonts_foreach, NULL); g_hash_table_destroy (xfont->subfonts_by_charset); + if (xfont->entry) + xfont->entry->cached_fonts = g_slist_remove (xfont->entry->cached_fonts, xfont); + g_strfreev (xfont->fonts); g_free (font); } @@ -1819,7 +1852,7 @@ free_coverages_foreach (gpointer key, gpointer value, gpointer data) { - pango_coverage_destroy (value); + pango_coverage_unref (value); } static PangoCoverage * @@ -1834,7 +1867,15 @@ pango_x_font_get_coverage (PangoFont *font, PangoCoverage *result; PangoCoverageLevel font_level; GHashTable *coverage_hash; - + PangoXFont *xfont = (PangoXFont *)font; + + if (xfont->entry) + if (xfont->entry->coverage) + { + pango_coverage_ref (xfont->entry->coverage); + return xfont->entry->coverage; + } + result = pango_coverage_new (); coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); @@ -1869,6 +1910,12 @@ pango_x_font_get_coverage (PangoFont *font, g_hash_table_foreach (coverage_hash, free_coverages_foreach, NULL); g_hash_table_destroy (coverage_hash); + if (xfont->entry) + { + xfont->entry->coverage = result; + pango_coverage_ref (result); + } + return result; } diff --git a/pango/shape.c b/pango/shape.c index 0f5efb39..04a966e0 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -24,7 +24,6 @@ /** * pango_shape: - * @font: font to use for shaping * @text: the text to process * @length: the length (in bytes) of @text * @analysis: #PangoAnalysis structure from PangoItemize @@ -35,14 +34,13 @@ * convert the characters into glyphs. You may also pass * in only a substring of the item from pango_itemize(). */ -void pango_shape (PangoFont *font, - gchar *text, - gint length, - PangoAnalysis *analysis, - PangoGlyphString *glyphs) +void pango_shape (gchar *text, + gint length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs) { if (analysis->shape_engine) - analysis->shape_engine->script_shape (font, text, length, analysis, glyphs); + analysis->shape_engine->script_shape (analysis->font, text, length, analysis, glyphs); else pango_glyph_string_set_size (glyphs, 0); } |