diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | ChangeLog.pre-1-0 | 20 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 20 | ||||
-rw-r--r-- | ChangeLog.pre-1-2 | 20 | ||||
-rw-r--r-- | ChangeLog.pre-1-4 | 20 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 20 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 20 | ||||
-rw-r--r-- | docs/pango-docs.sgml | 2 | ||||
-rw-r--r-- | docs/pango-sections.txt | 43 | ||||
-rw-r--r-- | docs/tmpl/fonts.sgml | 166 | ||||
-rw-r--r-- | docs/tmpl/main.sgml | 93 | ||||
-rw-r--r-- | docs/tmpl/pango-x.sgml | 9 | ||||
-rw-r--r-- | examples/viewer.c | 150 | ||||
-rw-r--r-- | pango/Makefile.am | 3 | ||||
-rw-r--r-- | pango/fonts.c | 150 | ||||
-rw-r--r-- | pango/modules.h | 2 | ||||
-rw-r--r-- | pango/pango-context.c | 501 | ||||
-rw-r--r-- | pango/pango-context.h | 62 | ||||
-rw-r--r-- | pango/pango-coverage.c | 299 | ||||
-rw-r--r-- | pango/pango-coverage.h | 55 | ||||
-rw-r--r-- | pango/pango-engine.h | 98 | ||||
-rw-r--r-- | pango/pango-font.h | 153 | ||||
-rw-r--r-- | pango/pango-glyph.h | 112 | ||||
-rw-r--r-- | pango/pango-layout.h | 44 | ||||
-rw-r--r-- | pango/pango-types.h | 76 | ||||
-rw-r--r-- | pango/pango.h | 255 | ||||
-rw-r--r-- | pango/pangox.c | 528 | ||||
-rw-r--r-- | pango/pangox.h | 2 |
28 files changed, 2658 insertions, 285 deletions
@@ -1,3 +1,23 @@ +Wed Feb 2 00:07:13 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-*.h: The great header file reorganization. + Split up roughtly by objects. + + * libpango/pango-font.h libpango/fonts.h: Add generic + font-loading and listing interfaces. + + * libpango/pangox.c: Implement font-listing/loading interfaces + for X. + + * libpango/pango-context.[ch]: Flesh out context structure. + Add appropriate accesors, font loading-methods, etc. + + * libpango/pango-coverage.[ch]: Coverage map objects. + + * examples/viewer.c: First stab at adding font-selection. Majorly + deficient for the moment until we add font lists and fallbacks + based on coverage maps. + Thu Jan 27 16:50:51 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Updates to match recent API changes. diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0 index a9badb41..2bc2292c 100644 --- a/ChangeLog.pre-1-0 +++ b/ChangeLog.pre-1-0 @@ -1,3 +1,23 @@ +Wed Feb 2 00:07:13 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-*.h: The great header file reorganization. + Split up roughtly by objects. + + * libpango/pango-font.h libpango/fonts.h: Add generic + font-loading and listing interfaces. + + * libpango/pangox.c: Implement font-listing/loading interfaces + for X. + + * libpango/pango-context.[ch]: Flesh out context structure. + Add appropriate accesors, font loading-methods, etc. + + * libpango/pango-coverage.[ch]: Coverage map objects. + + * examples/viewer.c: First stab at adding font-selection. Majorly + deficient for the moment until we add font lists and fallbacks + based on coverage maps. + Thu Jan 27 16:50:51 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Updates to match recent API changes. diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10 index a9badb41..2bc2292c 100644 --- a/ChangeLog.pre-1-10 +++ b/ChangeLog.pre-1-10 @@ -1,3 +1,23 @@ +Wed Feb 2 00:07:13 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-*.h: The great header file reorganization. + Split up roughtly by objects. + + * libpango/pango-font.h libpango/fonts.h: Add generic + font-loading and listing interfaces. + + * libpango/pangox.c: Implement font-listing/loading interfaces + for X. + + * libpango/pango-context.[ch]: Flesh out context structure. + Add appropriate accesors, font loading-methods, etc. + + * libpango/pango-coverage.[ch]: Coverage map objects. + + * examples/viewer.c: First stab at adding font-selection. Majorly + deficient for the moment until we add font lists and fallbacks + based on coverage maps. + Thu Jan 27 16:50:51 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Updates to match recent API changes. diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2 index a9badb41..2bc2292c 100644 --- a/ChangeLog.pre-1-2 +++ b/ChangeLog.pre-1-2 @@ -1,3 +1,23 @@ +Wed Feb 2 00:07:13 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-*.h: The great header file reorganization. + Split up roughtly by objects. + + * libpango/pango-font.h libpango/fonts.h: Add generic + font-loading and listing interfaces. + + * libpango/pangox.c: Implement font-listing/loading interfaces + for X. + + * libpango/pango-context.[ch]: Flesh out context structure. + Add appropriate accesors, font loading-methods, etc. + + * libpango/pango-coverage.[ch]: Coverage map objects. + + * examples/viewer.c: First stab at adding font-selection. Majorly + deficient for the moment until we add font lists and fallbacks + based on coverage maps. + Thu Jan 27 16:50:51 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Updates to match recent API changes. diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4 index a9badb41..2bc2292c 100644 --- a/ChangeLog.pre-1-4 +++ b/ChangeLog.pre-1-4 @@ -1,3 +1,23 @@ +Wed Feb 2 00:07:13 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-*.h: The great header file reorganization. + Split up roughtly by objects. + + * libpango/pango-font.h libpango/fonts.h: Add generic + font-loading and listing interfaces. + + * libpango/pangox.c: Implement font-listing/loading interfaces + for X. + + * libpango/pango-context.[ch]: Flesh out context structure. + Add appropriate accesors, font loading-methods, etc. + + * libpango/pango-coverage.[ch]: Coverage map objects. + + * examples/viewer.c: First stab at adding font-selection. Majorly + deficient for the moment until we add font lists and fallbacks + based on coverage maps. + Thu Jan 27 16:50:51 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Updates to match recent API changes. diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6 index a9badb41..2bc2292c 100644 --- a/ChangeLog.pre-1-6 +++ b/ChangeLog.pre-1-6 @@ -1,3 +1,23 @@ +Wed Feb 2 00:07:13 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-*.h: The great header file reorganization. + Split up roughtly by objects. + + * libpango/pango-font.h libpango/fonts.h: Add generic + font-loading and listing interfaces. + + * libpango/pangox.c: Implement font-listing/loading interfaces + for X. + + * libpango/pango-context.[ch]: Flesh out context structure. + Add appropriate accesors, font loading-methods, etc. + + * libpango/pango-coverage.[ch]: Coverage map objects. + + * examples/viewer.c: First stab at adding font-selection. Majorly + deficient for the moment until we add font lists and fallbacks + based on coverage maps. + Thu Jan 27 16:50:51 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Updates to match recent API changes. diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8 index a9badb41..2bc2292c 100644 --- a/ChangeLog.pre-1-8 +++ b/ChangeLog.pre-1-8 @@ -1,3 +1,23 @@ +Wed Feb 2 00:07:13 2000 Owen Taylor <otaylor@redhat.com> + + * libpango/pango-*.h: The great header file reorganization. + Split up roughtly by objects. + + * libpango/pango-font.h libpango/fonts.h: Add generic + font-loading and listing interfaces. + + * libpango/pangox.c: Implement font-listing/loading interfaces + for X. + + * libpango/pango-context.[ch]: Flesh out context structure. + Add appropriate accesors, font loading-methods, etc. + + * libpango/pango-coverage.[ch]: Coverage map objects. + + * examples/viewer.c: First stab at adding font-selection. Majorly + deficient for the moment until we add font lists and fallbacks + based on coverage maps. + Thu Jan 27 16:50:51 2000 Owen Taylor <otaylor@redhat.com> * docs/**: Updates to match recent API changes. diff --git a/docs/pango-docs.sgml b/docs/pango-docs.sgml index dfa790c9..26019c4d 100644 --- a/docs/pango-docs.sgml +++ b/docs/pango-docs.sgml @@ -2,6 +2,7 @@ <!entity pango-main SYSTEM "sgml/main.sgml"> <!entity pango-glyphs SYSTEM "sgml/glyphs.sgml"> <!entity pango-fonts SYSTEM "sgml/fonts.sgml"> +<!entity pango-coverage-maps SYSTEM "sgml/coverage-maps.sgml"> <!entity pango-engines SYSTEM "sgml/engines.sgml"> <!entity pango-x SYSTEM "sgml/pango-x.sgml"> ]> @@ -15,6 +16,7 @@ &pango-main; &pango-glyphs; &pango-fonts; + &pango-coverage-maps; &pango-engines; </chapter> diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt index 09c7836b..a40bf383 100644 --- a/docs/pango-sections.txt +++ b/docs/pango-sections.txt @@ -10,6 +10,17 @@ PangoLangRange PangoDirection pango_reorder_items <SUBSECTION> +pango_context_new +pango_context_ref +pango_context_unref +pango_context_add_font_map +pango_context_get_base_dir +pango_context_set_base_dir +pango_context_get_lang +pango_context_set_lang +pango_context_load_font +pango_context_list_fonts +<SUBSECTION> pango_break PangoLogAttr <SUBSECTION> @@ -35,15 +46,46 @@ pango_glyph_string_free </SECTION> <SECTION> +<TITLE>Coverage Maps</TITLE> +<FILE>coverage-maps</FILE> +PangoCoverage +PangoCoverageLevel +pango_coverage_new +pango_coverage_copy +pango_coverage_destroy +pango_coverage_get +pango_coverage_max +pango_coverage_set +</SECTION> + +<SECTION> <TITLE>Fonts</TITLE> <FILE>fonts</FILE> +PangoFontDescription +PangoStyle +PangoWeight +PangoVariant +PangoStretch PangoFont PangoFontClass +PangoFontMap +PangoFontMapClass +pango_font_description_copy +pango_font_descriptions_free +pango_font_description_free pango_font_init pango_font_ref pango_font_unref +pango_font_find_shaper +pango_font_describe +pango_font_get_coverage pango_font_get_data pango_font_set_data +pango_font_map_init +pango_font_map_ref +pango_font_map_unref +pango_font_map_load_font +pango_font_map_list_fonts </SECTION> <SECTION> @@ -70,6 +112,7 @@ PANGO_RENDER_TYPE_X PANGO_X_MAKE_GLYPH PANGO_X_GLYPH_SUBFONT PANGO_X_GLYPH_INDEX +pango_x_get_context pango_x_load_font pango_x_render pango_x_extents diff --git a/docs/tmpl/fonts.sgml b/docs/tmpl/fonts.sgml index 715fbe6f..c4180422 100644 --- a/docs/tmpl/fonts.sgml +++ b/docs/tmpl/fonts.sgml @@ -20,6 +20,57 @@ respectively. </para> +<!-- ##### STRUCT PangoFontDescription ##### --> +<para> + +</para> + +@family_name: +@style: +@variant: +@weight: +@stretch: + +<!-- ##### ENUM PangoStyle ##### --> +<para> + +</para> + +@PANGO_STYLE_NORMAL: +@PANGO_STYLE_OBLIQUE: +@PANGO_STYLE_ITALIC: + +<!-- ##### ENUM PangoWeight ##### --> +<para> + +</para> + +@PANGO_WEIGHT_NORMAL: +@PANGO_WEIGHT_BOLD: + +<!-- ##### ENUM PangoVariant ##### --> +<para> + +</para> + +@PANGO_VARIANT_NORMAL: +@PANGO_VARIANT_SMALL_CAPS: + +<!-- ##### ENUM PangoStretch ##### --> +<para> + +</para> + +@PANGO_STRETCH_ULTRA_CONDENSED: +@PANGO_STRETCH_EXTRA_CONDENSED: +@PANGO_STRETCH_CONDENSED: +@PANGO_STRETCH_SEMI_CONDENSED: +@PANGO_STRETCH_NORMAL: +@PANGO_STRETCH_SEMI_EXPANDED: +@PANGO_STRETCH_EXPANDED: +@PANGO_STRETCH_EXTRA_EXPANDED: +@PANGO_STRETCH_ULTRA_EXPANDED: + <!-- ##### STRUCT PangoFont ##### --> <para> The #PangoFont structure is used to represent @@ -69,6 +120,45 @@ It contains the following member: </para> +<!-- ##### STRUCT PangoFontMap ##### --> +<para> + +</para> + +@klass: + +<!-- ##### STRUCT PangoFontMapClass ##### --> +<para> + +</para> + + +<!-- ##### FUNCTION pango_font_description_copy ##### --> +<para> + +</para> + +@desc: +@Returns: + + +<!-- ##### FUNCTION pango_font_descriptions_free ##### --> +<para> + +</para> + +@descs: +@n_descs: + + +<!-- ##### FUNCTION pango_font_description_free ##### --> +<para> + +</para> + +@desc: + + <!-- ##### FUNCTION pango_font_init ##### --> <para> @@ -93,6 +183,37 @@ It contains the following member: @font: +<!-- ##### FUNCTION pango_font_find_shaper ##### --> +<para> + +</para> + +@font: +@lang: +@ch: +@Returns: +<!-- # Unused Parameters # --> +@char: + + +<!-- ##### FUNCTION pango_font_describe ##### --> +<para> + +</para> + +@font: +@Returns: + + +<!-- ##### FUNCTION pango_font_get_coverage ##### --> +<para> + +</para> + +@font: +@Returns: + + <!-- ##### FUNCTION pango_font_get_data ##### --> <para> @@ -114,3 +235,48 @@ It contains the following member: @destroy_func: +<!-- ##### FUNCTION pango_font_map_init ##### --> +<para> + +</para> + +@fontmap: + + +<!-- ##### FUNCTION pango_font_map_ref ##### --> +<para> + +</para> + +@fontmap: + + +<!-- ##### FUNCTION pango_font_map_unref ##### --> +<para> + +</para> + +@fontmap: + + +<!-- ##### FUNCTION pango_font_map_load_font ##### --> +<para> + +</para> + +@fontmap: +@desc: +@size: +@Returns: + + +<!-- ##### FUNCTION pango_font_map_list_fonts ##### --> +<para> + +</para> + +@fontmap: +@descs: +@n_descs: + + diff --git a/docs/tmpl/main.sgml b/docs/tmpl/main.sgml index 2ce87e0e..449e6963 100644 --- a/docs/tmpl/main.sgml +++ b/docs/tmpl/main.sgml @@ -56,9 +56,6 @@ the following fields: </tbody></tgroup></informaltable> </para> -@lang: -@render_type: -@direction: <!-- ##### STRUCT PangoItem ##### --> <para> @@ -181,6 +178,96 @@ It contains the following fields: @Returns: +<!-- ##### FUNCTION pango_context_new ##### --> +<para> + +</para> + +@Returns: + + +<!-- ##### FUNCTION pango_context_ref ##### --> +<para> + +</para> + +@context: + + +<!-- ##### FUNCTION pango_context_unref ##### --> +<para> + +</para> + +@context: + + +<!-- ##### FUNCTION pango_context_add_font_map ##### --> +<para> + +</para> + +@context: +@font_map: + + +<!-- ##### FUNCTION pango_context_get_base_dir ##### --> +<para> + +</para> + +@context: +@Returns: + + +<!-- ##### FUNCTION pango_context_set_base_dir ##### --> +<para> + +</para> + +@context: +@direction: + + +<!-- ##### FUNCTION pango_context_get_lang ##### --> +<para> + +</para> + +@context: +@Returns: + + +<!-- ##### FUNCTION pango_context_set_lang ##### --> +<para> + +</para> + +@context: +@lang: + + +<!-- ##### FUNCTION pango_context_load_font ##### --> +<para> + +</para> + +@context: +@desc: +@size: +@Returns: + + +<!-- ##### FUNCTION pango_context_list_fonts ##### --> +<para> + +</para> + +@context: +@descs: +@n_descs: + + <!-- ##### FUNCTION pango_break ##### --> <para> diff --git a/docs/tmpl/pango-x.sgml b/docs/tmpl/pango-x.sgml index a92c36e8..8b75e862 100644 --- a/docs/tmpl/pango-x.sgml +++ b/docs/tmpl/pango-x.sgml @@ -55,6 +55,15 @@ X Window System. @glyph: +<!-- ##### FUNCTION pango_x_get_context ##### --> +<para> + +</para> + +@display: +@Returns: + + <!-- ##### FUNCTION pango_x_load_font ##### --> <para> diff --git a/examples/viewer.c b/examples/viewer.c index c5411ab8..9d512dd3 100644 --- a/examples/viewer.c +++ b/examples/viewer.c @@ -60,6 +60,7 @@ struct _Line { int offset; /* Offset from left margin line, in pixels */ }; +PangoFontDescription font_description; static PangoFont *font = NULL; static Paragraph *highlight_para; static int highlight_offset; @@ -67,7 +68,7 @@ static int highlight_offset; static GtkWidget *message_label; GtkWidget *layout; -gboolean global_rtl; +PangoContext *context; /* Read an entire file into a string */ @@ -294,15 +295,12 @@ layout_paragraph (Paragraph *para, int width) GList *runs; int remaining_width; int height = 0; - PangoContext context; + PangoDirection base_dir = pango_context_get_base_dir (context); /* Break paragraph into runs with consistent shaping engine * and direction */ - context.lang = "en_US"; - context.render_type = PANGO_RENDER_TYPE_X; - context.direction = global_rtl ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR; - runs = pango_itemize (&context, para->text, para->length, NULL, 0); + runs = pango_itemize (context, para->text, para->length, NULL, 0); /* Break runs to fit on each line */ @@ -370,7 +368,7 @@ layout_paragraph (Paragraph *para, int width) */ GList *visual_list; - line->offset = global_rtl ? remaining_width : 0; + line->offset = (base_dir == PANGO_DIRECTION_RTL) ? remaining_width : 0; line->runs = g_list_reverse (line->runs); remaining_width = width; height += line->ascent + line->descent; @@ -550,6 +548,7 @@ char_bounds (GList *paragraphs, Paragraph *para, int offset, GList *para_list, *line_list, *run_list; int pixels = 0; int chars_seen = 0; + PangoDirection base_dir = pango_context_get_base_dir (context); para_list = paragraphs; while (para_list) @@ -576,7 +575,7 @@ char_bounds (GList *paragraphs, Paragraph *para, int offset, x, width); *y = pixels; *height = line->ascent + line->descent; - if (global_rtl) + if (base_dir == PANGO_DIRECTION_RTL) *x += line->offset; return; @@ -794,17 +793,128 @@ button_press (GtkWidget *layout, GdkEventButton *event, GList *paragraphs) static void checkbutton_toggled (GtkWidget *widget, gpointer data) { - global_rtl = GTK_TOGGLE_BUTTON (widget)->active; + pango_context_set_base_dir (context, GTK_TOGGLE_BUTTON (widget)->active ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR); gtk_widget_queue_resize (layout); } +static void +reload_font () +{ + PangoFont *new_font; + + new_font = pango_context_load_font (context, &font_description, 16.); + + if (new_font) + { + pango_font_unref (font); + font = new_font; + } + + gtk_widget_queue_resize (layout); +} + +void +set_family (GtkWidget *menu_item, gpointer data) +{ + char *label = gtk_object_get_data (GTK_OBJECT (menu_item), "family"); + + g_free (font_description.family_name); + font_description.family_name = g_strdup (label); + + reload_font (); +} + +GtkWidget * +make_families_menu () +{ + GtkWidget *menu, *menu_item, *option_menu; + GHashTable *families_hash = g_hash_table_new (g_str_hash, g_str_equal); + GSList *families = NULL; + GSList *tmp_list; + int i; + + PangoFontDescription **descs; + int n_descs; + int index, active = -1; + + pango_context_list_fonts (context, &descs, &n_descs); + + for (i=0; i<n_descs; i++) + { + if (!g_hash_table_lookup (families_hash, descs[i]->family_name)) + { + g_hash_table_insert (families_hash, descs[i]->family_name, descs[i]); + families = g_slist_prepend (families, descs[i]->family_name); + } + } + + families = g_slist_reverse (families); + + menu = gtk_menu_new (); + + tmp_list = families; + index = 0; + while (tmp_list) + { + if (strcmp (tmp_list->data, font_description.family_name) == 0) + active = index; + + menu_item = gtk_menu_item_new_with_label (tmp_list->data); + gtk_object_set_data_full (GTK_OBJECT (menu_item), "family", + g_strdup (tmp_list->data), (GtkDestroyNotify)g_free); + + gtk_signal_connect (GTK_OBJECT (menu_item), "activate", + GTK_SIGNAL_FUNC (set_family), NULL); + gtk_widget_show (menu_item); + gtk_menu_append (GTK_MENU (menu), menu_item); + + tmp_list = tmp_list->next; + index++; + } + + g_hash_table_destroy (families_hash); + g_slist_free (families); + + pango_font_descriptions_free (descs, n_descs); + + option_menu = gtk_option_menu_new (); + gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); + + if (active != -1) + gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), active); + + return option_menu; +} + + +GtkWidget * +make_font_selector (void) +{ + GtkWidget *hbox; + GtkWidget *util_hbox; + GtkWidget *label; + GtkWidget *option_menu; + + hbox = gtk_hbox_new (FALSE, 4); + + util_hbox = gtk_hbox_new (FALSE, 2); + label = gtk_label_new ("Family:"); + gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0); + option_menu = make_families_menu (); + gtk_box_pack_start (GTK_BOX (util_hbox), option_menu, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0); + + return hbox; +} + int main (int argc, char **argv) { char *text; GtkWidget *window; GtkWidget *scrollwin; - GtkWidget *vbox; + GtkWidget *vbox, *hbox; GtkWidget *frame; GtkWidget *checkbutton; GList *paragraphs; @@ -825,6 +935,19 @@ main (int argc, char **argv) paragraphs = split_paragraphs (text); + context = pango_x_get_context (GDK_DISPLAY()); + pango_context_set_lang (context, "en_US"); + pango_context_set_base_dir (context, PANGO_DIRECTION_LTR); + + font_description.family_name = g_strdup ("fixed"); + font_description.style = PANGO_STYLE_NORMAL; + font_description.variant = PANGO_VARIANT_NORMAL; + font_description.weight = 500; + font_description.stretch = PANGO_STRETCH_NORMAL; + + font = pango_context_load_font (context, &font_description, 16.); + +#if 0 /* We hard code a font globally for now */ font = pango_x_load_font (GDK_DISPLAY(), @@ -832,6 +955,8 @@ main (int argc, char **argv) "-tamil-tscakaram-medium-r-normal--*-120-*-*-*-*-tscii-0," "-gnu-unifont-medium-r-normal--*-160-*-*-c-*-iso10646-1," "-*-*-medium-r-normal--*-160-*-*-*-*-*-*"); +#endif + /* Create the user interface */ @@ -841,9 +966,12 @@ main (int argc, char **argv) gtk_signal_connect (GTK_OBJECT (window), "destroy", GTK_SIGNAL_FUNC (gtk_main_quit), NULL); - vbox = gtk_vbox_new (FALSE, 3); + vbox = gtk_vbox_new (FALSE, 4); gtk_container_add (GTK_CONTAINER (window), vbox); + hbox = make_font_selector (); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + scrollwin = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); diff --git a/pango/Makefile.am b/pango/Makefile.am index e134358b..aae52f6c 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -8,10 +8,11 @@ libpango_la_SOURCES = \ fonts.c \ glyphstring.c \ pangox.c \ - itemize.c \ mapping.c \ modules.c \ modules.h \ + pango-context.c \ + pango-coverage.c \ reorder-items.c \ shape.c \ utils.c \ diff --git a/pango/fonts.c b/pango/fonts.c index ed016031..421fcf4b 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -22,6 +22,66 @@ #include "pango.h" /** + * pango_font_description_copy: + * @desc: a #PangoFontDescription + * + * Make a copy of a #PangoFontDescription. + * + * Return value: a newly allocated #PangoFontDescription. This value + * must be freed using pango_font_description_free(). + **/ +PangoFontDescription * +pango_font_description_copy (PangoFontDescription *desc) +{ + PangoFontDescription *result = g_new (PangoFontDescription, 1); + + *result = *desc; + + result->family_name = g_strdup (result->family_name); + + return result; +} + +/** + * pango_font_description_free: + * @desc: a #PangoFontDescription + * + * Free a font description returned from pango_font_describe() + * or pango_font_description_copy(). + **/ +void pango_font_description_free (PangoFontDescription *desc) +{ + if (desc) + { + if (desc->family_name) + g_free (desc->family_name); + + g_free (desc); + } +} + +/** + * pango_font_descriptions_free: + * @descs: a pointer to an array of #PangoFontDescription + * @n_descs: number of font descriptions in @descs + * + * Free a list of font descriptions from pango_font_map_list_fonts() + **/ +void +pango_font_descriptions_free (PangoFontDescription **descs, + int n_descs) +{ + int i; + + if (descs) + { + for (i = 0; i<n_descs; i++) + pango_font_description_free (descs[i]); + g_free (descs); + } +} + +/** * pango_font_init: * @font: a #PangoFont * @@ -115,3 +175,93 @@ pango_font_get_data (PangoFont *font, return g_datalist_get_data (&font->data, key); } + +/** + * pango_font_map_init: + * @fontmap: a #PangoFontMap + * + * Initialize a #PangoFontMap structure. This should + * only be called from the "new" routine of code which + * is implementing a "subclass" of #PangoFontMap + */ +void +pango_font_map_init (PangoFontMap *fontmap) +{ + g_return_if_fail (fontmap != NULL); + + fontmap->ref_count = 1; +} + +/** + * pango_font_map_ref: + * @fontmap: a #PangoFontMap + * + * Increase the reference count of a #PangoFontMap. + */ +void +pango_font_map_ref (PangoFontMap *fontmap) +{ + g_return_if_fail (fontmap != NULL); + + fontmap->ref_count++; +} + + +/** + * pango_font_map_unref: + * @fontmap: a #PangoFontMap + * + * Decrease the reference count of a #PangoFontMap. + * if the result is zero, destroy the font + * and free the associated memory. + */ +void +pango_font_map_unref (PangoFontMap *fontmap) +{ + g_return_if_fail (fontmap != NULL); + g_return_if_fail (fontmap->ref_count > 0); + + fontmap->ref_count--; + if (fontmap->ref_count == 0) + fontmap->klass->destroy (fontmap); +} + +/** + * pango_font_map_load_font: + * @fontmap: a #PangoFontMap + * @desc: a #PangoFontDescription describing the font to load + * @size: the size at which to load the font (in points) + * + * Load the font in the fontmap that is the closest match for @desc. + * + * Returns the font loaded, or %NULL if no font matched. + **/ +PangoFont * +pango_font_map_load_font (PangoFontMap *fontmap, + PangoFontDescription *desc, + double size) +{ + g_return_val_if_fail (fontmap != NULL, NULL); + + return fontmap->klass->load_font (fontmap, desc, size); +} + +/** + * pango_font_map_list_fonts: + * @fontmap: a #PangoFontMap + * @descs: location to store a pointer to an array of pointers to + * #PangoFontDescription. This array should be freed + * with pango_font_descriptions_free(). + * @n_descs: location to store the number of elements in @descs + * + * List all fonts in a fontmap. + **/ +void +pango_font_map_list_fonts (PangoFontMap *fontmap, + PangoFontDescription ***descs, + int *n_descs) +{ + g_return_if_fail (fontmap != NULL); + + fontmap->klass->list_fonts (fontmap, descs, n_descs); +} diff --git a/pango/modules.h b/pango/modules.h index 14617461..f6003d57 100644 --- a/pango/modules.h +++ b/pango/modules.h @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +#include <pango-engine.h> + #ifndef __MODULES_H__ #define __MODULES_H__ diff --git a/pango/pango-context.c b/pango/pango-context.c new file mode 100644 index 00000000..7a369a86 --- /dev/null +++ b/pango/pango-context.c @@ -0,0 +1,501 @@ +/* Pango + * pango-context.c: Contexts for itemization and shaping + * + * 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-context.h> +#include <fribidi/fribidi.h> +#include <unicode.h> +#include "iconv.h" +#include "utils.h" +#include "modules.h" + + +struct _PangoContext +{ + gint ref_count; + + char *lang; + PangoDirection base_dir; + + GSList *font_maps; +}; + +/** + * pango_context_new: + * + * Creates a new #PangoContext initialized to default value. + * + * Return value: the new #PangoContext + **/ +PangoContext * +pango_context_new (void) +{ + PangoContext *result = g_new (PangoContext, 1); + result->ref_count = 1; + result->base_dir = PANGO_DIRECTION_LTR; + result->lang = NULL; + result->font_maps = NULL; + + return result; +} + +/** + * pango_context_ref: + * @context: a #PangoContext + * + * Increases the reference count of a #PangoContext. + **/ +void +pango_context_ref (PangoContext *context) +{ + g_return_if_fail (context != NULL); + + context->ref_count++; +} + + +/** + * pango_context_unref: + * @context: a #PangoContext + * + * Decreases the reference count of a #PangoContext. + * if the result is zero, destroy the context + * and free the associated memory. + */ +void +pango_context_unref (PangoContext *context) +{ + g_return_if_fail (context != NULL); + + context->ref_count--; + if (context->ref_count == 0) + { + if (context->lang) + g_free (context->lang); + + g_slist_foreach (context->font_maps, (GFunc)pango_font_map_unref, NULL); + g_slist_free (context->font_maps); + } +} + +/** + * pango_context_add_font_map: + * @context: a #PangoContext + * @font_map: the #PangoFontMap to add. + * + * Add a font map to the list of font maps that are searched for fonts + * when fonts are looked-up in this context. + **/ +void +pango_context_add_font_map (PangoContext *context, + PangoFontMap *font_map) +{ + g_return_if_fail (context != NULL); + g_return_if_fail (font_map != NULL); + + context->font_maps = g_slist_append (context->font_maps, font_map); +} + +/** + * pango_context_list_fonts: + * @context: a #PangoContext + * @descs: location to store a pointer to an array of pointers to + * #PangoFontDescription. This array should be freed + * with pango_font_descriptions_free() + * @n_descs: location to store the number of elements in @descs + * + * Lists all fonts in all fontmaps for this context. + **/ +void +pango_context_list_fonts (PangoContext *context, + PangoFontDescription ***descs, + int *n_descs) +{ + int n_maps; + + g_return_if_fail (context != NULL); + g_return_if_fail (descs == NULL || n_descs != NULL); + + if (n_descs == NULL) + return; + + n_maps = g_slist_length (context->font_maps); + + if (n_maps == 0) + { + if (n_descs) + *n_descs = 0; + return; + } + else if (n_maps == 1) + pango_font_map_list_fonts (context->font_maps->data, descs, n_descs); + else + { + PangoFontDescription ***tmp_descs; + int *tmp_n_descs; + int total_n_descs = 0; + GSList *tmp_list; + int i; + + tmp_descs = g_new (PangoFontDescription **, n_maps); + tmp_n_descs = g_new (int, n_maps); + + *n_descs = 0; + + tmp_list = context->font_maps; + for (i = 0; i<n_maps; i++) + { + pango_font_map_list_fonts (tmp_list->data, &tmp_descs[i], &tmp_n_descs[i]); + *n_descs += tmp_n_descs[i]; + + tmp_list = tmp_list->next; + } + + if (descs) + { + *descs = g_new (PangoFontDescription *, *n_descs); + + total_n_descs = 0; + for (i = 0; i<n_maps; i++) + { + memcpy (&(*descs)[total_n_descs], tmp_descs[i], tmp_n_descs[i] * sizeof (PangoFontDescription *)); + total_n_descs += tmp_n_descs[i]; + pango_font_descriptions_free (tmp_descs[i], tmp_n_descs[i]); + } + } + else + { + for (i = 0; i<n_maps; i++) + pango_font_descriptions_free (tmp_descs[i], tmp_n_descs[i]); + } + + g_free (tmp_descs); + g_free (tmp_n_descs); + } +} + +/** + * pango_context_load_font: + * @context: a #PangoContext + * @desc: a #PangoFontDescription describing the font to load + * @size: the size at which to load the font (in points) + * + * Loads the font in one of the fontmaps in the context + * that is the closest match for @desc. + * + * Returns the font loaded, or %NULL if no font matched. + **/ +PangoFont * +pango_context_load_font (PangoContext *context, + PangoFontDescription *desc, + gdouble size) +{ + GSList *tmp_list; + + g_return_val_if_fail (context != NULL, NULL); + + tmp_list = context->font_maps; + while (tmp_list) + { + PangoFont *font; + + font = pango_font_map_load_font (tmp_list->data, desc, size); + if (font) + return font; + + tmp_list = tmp_list->next; + } + + return NULL; +} + +/** + * pango_context_set_lang: + * @context: a #PangoContext + * @lang: the new language tag. + * + * Sets the global language tag for the context. + **/ +void +pango_context_set_lang (PangoContext *context, + const char *lang) +{ + g_return_if_fail (context != NULL); + + if (context->lang) + g_free (context->lang); + + context->lang = g_strdup (lang); +} + +/** + * pango_context_get_lang: + * @context: a #PangoContext + * + * Retrieves the global language tag for the context. + * + * Return value: the global language tag. This value must be freed with g_free(). + **/ +char * +pango_context_get_lang (PangoContext *context) +{ + g_return_val_if_fail (context != NULL, NULL); + + return g_strdup (context->lang); +} + +/** + * pango_context_set_base_dir: + * @context: a #PangoContext + * @direction: the new base direction + * + * Sets the base direction for the context. + **/ +void +pango_context_set_base_dir (PangoContext *context, + PangoDirection direction) +{ + g_return_if_fail (context != NULL); + + context->base_dir = direction; +} + +/** + * pango_context_get_base_dir: + * @context: + * + * Retrieves the base direction for the context. + * + * Return value: the base direction for the context. + **/ +PangoDirection +pango_context_get_base_dir (PangoContext *context) +{ + g_return_val_if_fail (context != NULL, PANGO_DIRECTION_LTR); + + 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 + the itemization process. + * @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. + * + * Breaks a piece of text into segments with consistent + * directional level and shaping engine. + * + * Returns a GList of PangoItem structures. + */ +GList * +pango_itemize (PangoContext *context, + gchar *text, + gint length, + PangoLangRange *lang_info, + gint n_langs) +{ + guint16 *text_ucs2; + gint n_chars; + guint8 *embedding_levels; + FriBidiCharType base_dir; + gint i; + PangoItem *item; + char *p, *next; + GList *result = NULL; + + PangoEngineInfo **shape_engines; + PangoEngineInfo **lang_engines; + + g_return_val_if_fail (context != NULL, NULL); + g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (length >= 0, NULL); + + + if (context->base_dir == PANGO_DIRECTION_RTL) + base_dir = FRIBIDI_TYPE_RTL; + else + base_dir = FRIBIDI_TYPE_LTR; + + if (length == 0) + return NULL; + + /* First, apply the bidirectional algorithm to break + * the text into directional runs. + */ + text_ucs2 = _pango_utf8_to_ucs2 (text, length); + if (!text_ucs2) + return NULL; + + n_chars = unicode_strlen (text, length); + embedding_levels = g_new (guint8, n_chars); + + /* Storing these as ranges would be a lot more efficient, + * but also more complicated... we take the simple + * approach for now. + */ + shape_engines = g_new0 (PangoEngineInfo *, n_chars); + lang_engines = g_new0 (PangoEngineInfo *, 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. + */ + + add_engines (context, text, length, lang_info, n_langs, + TRUE, shape_engines, lang_engines); + + /* 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 + */ + + item = NULL; + p = text; + for (i=0; i<n_chars; i++) + { + next = unicode_next_utf8 (p); + + if (i == 0 || + embedding_levels[i] != embedding_levels[i-1] || + shape_engines[i] != shape_engines[i-1] || + lang_engines[i] != lang_engines[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; + + if (lang_engines[i]) + item->analysis.lang_engine = (PangoEngineLang *)_pango_load_engine (lang_engines[i]->id); + else + item->analysis.lang_engine = NULL; + } + + item->length = (next - text) - item->offset; + item->num_chars++; + p = next; + } + + if (item) + result = g_list_prepend (result, item); + + g_free (text_ucs2); + + return g_list_reverse (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) +{ + char *pos; + char *last_lang = NULL; + gint n_chars; + PangoMap *shape_map = NULL; + PangoMap *lang_map = NULL; + GUChar4 wc; + int i, j; + + n_chars = unicode_strlen (text, length); + + pos = text; + last_lang = NULL; + for (i=0, j=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) + { + 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; + } + + pos = unicode_get_utf8 (pos, &wc); + + if (!lang_engines[i]) + { + submap = &lang_map->submaps[wc / 256]; + entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256]; + + if (entry->info && (!force_exact || entry->is_exact)) + lang_engines[i] = entry->info; + } + + if (!shape_engines[i]) + { + submap = &shape_map->submaps[wc / 256]; + entry = submap->is_leaf ? &submap->d.entry : &submap->d.leaves[wc % 256]; + + if (entry->info && (!force_exact || entry->is_exact)) + shape_engines[i] = entry->info; + } + } +} + diff --git a/pango/pango-context.h b/pango/pango-context.h new file mode 100644 index 00000000..642f3d49 --- /dev/null +++ b/pango/pango-context.h @@ -0,0 +1,62 @@ +/* Pango + * pango-context.h: Rendering contexts + * + * 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_CONTEXT_H__ +#define __PANGO_CONTEXT_H__ + +#include <pango-font.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Sort of like a GC - application set information about how + * to handle scripts + */ +typedef struct _PangoContext PangoContext; + +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, + PangoFontDescription ***descs, + int *n_descs); +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); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif __PANGO_CONTEXT_H__ diff --git a/pango/pango-coverage.c b/pango/pango-coverage.c new file mode 100644 index 00000000..38bc62ca --- /dev/null +++ b/pango/pango-coverage.c @@ -0,0 +1,299 @@ +/* Pango + * pango-coverage.c: Coverage maps for fonts + * + * 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-coverage.h> + +typedef struct _PangoBlockInfo PangoBlockInfo; + +#define N_BLOCKS_INCREMENT 256 + +/* The structure of a PangoCoverage object is a two-level table, with blocks of size 256. + * each block is stored as a packed array of 2 bit values for each index, in LSB order. + */ + +struct _PangoBlockInfo +{ + guchar *data; + PangoCoverageLevel level; /* Used if data == NULL */ +}; + +struct _PangoCoverage +{ + int n_blocks; + int data_size; + + PangoBlockInfo *blocks; +}; + +/** + * pango_coverage_new: + * + * Create a new #PangoCoverage + * + * Return value: a new PangoCoverage object, initialized to PANGO_COVERAGE_NONE + **/ +PangoCoverage * +pango_coverage_new (void) +{ + int i; + PangoCoverage *coverage = g_new (PangoCoverage, 1); + + coverage->n_blocks = N_BLOCKS_INCREMENT; + coverage->blocks = g_new (PangoBlockInfo, coverage->n_blocks); + + for (i=0; i<coverage->n_blocks; i++) + { + coverage->blocks[i].data = NULL; + coverage->blocks[i].level = PANGO_COVERAGE_NONE; + } + + return coverage; +} + +/** + * pango_coverage_copy: + * @coverage: a #PangoCoverage + * + * Copy an existing #PangoCoverage + * + * Return value: a copy of @coverage + **/ +PangoCoverage * +pango_coverage_copy (PangoCoverage *coverage) +{ + int i; + PangoCoverage *result = g_new (PangoCoverage, 1); + + g_return_val_if_fail (coverage != NULL, NULL); + + result->n_blocks = coverage->n_blocks; + result->blocks = g_new (PangoBlockInfo, coverage->n_blocks); + + for (i=0; i<coverage->n_blocks; i++) + { + if (coverage->blocks[i].data) + { + result->blocks[i].data = g_new (guchar, 64); + memcpy (result->blocks[i].data, coverage->blocks[i].data, 64); + } + else + result->blocks[i].data = NULL; + + result->blocks[i].level = coverage->blocks[i].level; + } + + return result; +} + +/** + * pango_coverage_destroy: + * @coverage: a #PangoCoverage + * + * Destroy a #PangoCoverage object, freeing associated memory + **/ +void pango_coverage_destroy (PangoCoverage *coverage) +{ + int i; + + g_return_if_fail (coverage != NULL); + + for (i=0; i<coverage->n_blocks; i++) + { + if (coverage->blocks[i].data) + g_free (coverage->blocks[i].data); + } + + g_free (coverage); +} + +/** + * pango_coverage_get: + * @coverage: a #PangoCoverage + * @index: the index to check + * + * Determine whether a particular index is covered by @coverage + * + * Return value: + **/ +PangoCoverageLevel +pango_coverage_get (PangoCoverage *coverage, + int index) +{ + int block_index; + + g_return_val_if_fail (coverage != NULL, PANGO_COVERAGE_NONE); + + block_index = index / 256; + + if (block_index > coverage->n_blocks) + return PANGO_COVERAGE_NONE; + else + { + guchar *data = coverage->blocks[block_index].data; + if (data) + { + int i = index % 256; + int shift = (i % 4) * 2; + + return (data[i/4] >> shift) & 0x3; + } + else + return coverage->blocks[block_index].level; + } +} + +/** + * pango_coverage_set: + * @coverage: a #PangoCoverage + * @index: the index to modify + * @level: the new level for @index + * + * Modify a particular index within @coverage + **/ +void pango_coverage_set (PangoCoverage *coverage, + int index, + PangoCoverageLevel level) +{ + int block_index, i; + guchar *data; + + g_return_if_fail (coverage != NULL); + g_return_if_fail (level < 0 || level > 3); + + block_index = index / 256; + + if (block_index > coverage->n_blocks) + { + coverage->n_blocks += N_BLOCKS_INCREMENT; + coverage->blocks = g_renew (PangoBlockInfo, coverage->blocks, coverage->n_blocks); + } + + data = coverage->blocks[block_index].data; + if (!data) + { + if (level == coverage->blocks[block_index].level) + return; + + data = g_new0 (guchar, 64); + coverage->blocks[block_index].data = data; + } + + i = index % 256; + data[i] |= level << ((i % 4) * 2); +} + +/** + * pango_coverage_max: + * @coverage: a #PangoCoverage + * @other: another #PangoCoverage + * + * Set the coverage for each index in @coverage to be the max (better) + * value of the current coverage for the index and the coverage for + * the corresponding index in @other. + **/ +void pango_coverage_max (PangoCoverage *coverage, + PangoCoverage *other) +{ + int block_index, i; + int old_blocks; + + g_return_if_fail (coverage != NULL); + + old_blocks = MIN (coverage->n_blocks, other->n_blocks); + + if (other->n_blocks > coverage->n_blocks) + { + coverage->n_blocks += N_BLOCKS_INCREMENT; + coverage->blocks = g_renew (PangoBlockInfo, coverage->blocks, coverage->n_blocks); + + for (block_index = old_blocks; block_index < coverage->n_blocks; block_index++) + { + if (other->blocks[block_index].data) + { + coverage->blocks[block_index].data = g_new (guchar, 64); + memcpy (coverage->blocks[block_index].data, other->blocks[block_index].data, 64); + } + else + coverage->blocks[block_index].data = NULL; + + coverage->blocks[block_index].level = other->blocks[block_index].level; + } + } + + for (block_index = 0; block_index < old_blocks; block_index++) + { + if (!coverage->blocks[block_index].data && !other->blocks[block_index].data) + { + coverage->blocks[block_index].level = MAX (coverage->blocks[block_index].level, other->blocks[block_index].level); + } + else if (coverage->blocks[block_index].data && other->blocks[block_index].data) + { + guchar *data = coverage->blocks[block_index].data; + + for (i=0; i<64; i++) + { + int byte1 = data[i]; + int byte2 = other->blocks[block_index].data[i]; + + /* There are almost certainly some clever logical ops to do this */ + data[i] = + MAX (byte1 & 0x3, byte2 & 0x3) | + MAX (byte1 & 0xc, byte2 & 0xc) | + MAX (byte1 & 0x30, byte2 & 0x30) | + MAX (byte1 & 0xc0, byte2 & 0xc00); + } + } + else + { + guchar *src, *dest; + int level, byte2; + + if (coverage->blocks[block_index].data) + { + src = dest = coverage->blocks[block_index].data; + level = other->blocks[block_index].level; + } + else + { + src = other->blocks[block_index].data; + dest = g_new (guchar, 64); + coverage->blocks[block_index].data = dest; + level = coverage->blocks[block_index].level; + } + + byte2 = level | (level << 2) | (level << 4) | (level << 6); + + for (i=0; i<64; i++) + { + int byte1 = src[i]; + + /* There are almost certainly some clever logical ops to do this */ + dest[i] = + MAX (byte1 & 0x3, byte2 & 0x3) | + MAX (byte1 & 0xc, byte2 & 0xc) | + MAX (byte1 & 0x30, byte2 & 0x30) | + MAX (byte1 & 0xc0, byte2 & 0xc00); + } + } + } +} + + diff --git a/pango/pango-coverage.h b/pango/pango-coverage.h new file mode 100644 index 00000000..2b613f94 --- /dev/null +++ b/pango/pango-coverage.h @@ -0,0 +1,55 @@ +/* Pango + * pango-coverage.h: Coverage sets for fonts + * + * 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_COVERAGE_H__ +#define __PANGO_COVERAGE_H__ + +#include <glib.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _PangoCoverage PangoCoverage; + +typedef enum { + PANGO_COVERAGE_NONE, + PANGO_COVERAGE_FALLBACK, + PANGO_COVERAGE_APPROXIMATE, + PANGO_COVERAGE_EXACT +} PangoCoverageLevel; + +PangoCoverage * pango_coverage_new (void); +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, + int index, + PangoCoverageLevel level); +void pango_coverage_max (PangoCoverage *coverage, + PangoCoverage *other); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif __PANGO_COVERAGE_H__ diff --git a/pango/pango-engine.h b/pango/pango-engine.h new file mode 100644 index 00000000..ccd7b219 --- /dev/null +++ b/pango/pango-engine.h @@ -0,0 +1,98 @@ +/* Pango + * pango-engine.h: Module 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. + */ + +#ifndef __PANGO_ENGINE_H__ +#define __PANGO_ENGINE_H__ + +#include <pango-types.h> +#include <pango-font.h> +#include <pango-glyph.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Module API */ + +#define PANGO_ENGINE_TYPE_LANG "PangoEngineLang" +#define PANGO_ENGINE_TYPE_SHAPE "PangoEngineShape" + +#define PANGO_RENDER_TYPE_NONE "PangoRenderNone" + +typedef struct _PangoEngineInfo PangoEngineInfo; +typedef struct _PangoEngineRange PangoEngineRange; +typedef struct _PangoEngine PangoEngine; + +struct _PangoEngineRange +{ + guint32 start; + guint32 end; + gchar *langs; +}; + +struct _PangoEngineInfo +{ + gchar *id; + gchar *engine_type; + gchar *render_type; + PangoEngineRange *ranges; + gint n_ranges; +}; + +struct _PangoEngine +{ + gchar *id; + gchar *type; + gint length; +}; + +struct _PangoEngineLang +{ + PangoEngine engine; + void (*script_break) (gchar *text, + int len, + PangoAnalysis *analysis, + PangoLogAttr *attrs); +}; + +struct _PangoEngineShape +{ + PangoEngine engine; + void (*script_shape) (PangoFont *font, + char *text, + int length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs); +}; + +/* A module should export the following functions */ + +void script_engine_list (PangoEngineInfo **engines, + int *n_engines); +PangoEngine *script_engine_load (const char *id); +void script_engine_unload (PangoEngine *engine); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif __PANGO_ENGINE_H__ diff --git a/pango/pango-font.h b/pango/pango-font.h new file mode 100644 index 00000000..45d90e75 --- /dev/null +++ b/pango/pango-font.h @@ -0,0 +1,153 @@ +/* Pango + * pango-font.h: Font 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. + */ + +#ifndef __PANGO_FONT_H__ +#define __PANGO_FONT_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include <pango-coverage.h> +#include <pango-types.h> + +typedef struct _PangoFontDescription PangoFontDescription; +typedef struct _PangoFont PangoFont; +typedef struct _PangoFontClass PangoFontClass; +typedef struct _PangoFontMap PangoFontMap; +typedef struct _PangoFontMapClass PangoFontMapClass; + +typedef enum { + PANGO_STYLE_NORMAL, + PANGO_STYLE_OBLIQUE, + PANGO_STYLE_ITALIC +} PangoStyle; + +typedef enum { + PANGO_VARIANT_NORMAL, + PANGO_VARIANT_SMALL_CAPS +} PangoVariant; + +typedef enum { + PANGO_WEIGHT_NORMAL = 400, + PANGO_WEIGHT_BOLD = 700 +} PangoWeight; + +typedef enum { + PANGO_STRETCH_ULTRA_CONDENSED, + PANGO_STRETCH_EXTRA_CONDENSED, + PANGO_STRETCH_CONDENSED, + PANGO_STRETCH_SEMI_CONDENSED, + PANGO_STRETCH_NORMAL, + PANGO_STRETCH_SEMI_EXPANDED, + PANGO_STRETCH_EXPANDED, + PANGO_STRETCH_EXTRA_EXPANDED, + PANGO_STRETCH_ULTRA_EXPANDED +} PangoStretch; + +struct _PangoFontDescription { + gchar *family_name; + + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + 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); + +/* Logical fonts + */ +struct _PangoFont +{ + PangoFontClass *klass; + + /*< private >*/ + gint ref_count; + GData *data; +}; + +struct _PangoFontClass +{ + void (*destroy) (PangoFont *font); + PangoFontDescription *(*describe) (PangoFont *font); + PangoCoverage * (*get_coverage) (PangoFont *font); + PangoEngineShape * (*find_shaper) (PangoFont *font, + const gchar *lang, + guint32 ch); +}; + +void pango_font_init (PangoFont *font); +void pango_font_ref (PangoFont *font); +void pango_font_unref (PangoFont *font); +gpointer pango_font_get_data (PangoFont *font, + gchar *key); +void pango_font_set_data (PangoFont *font, + gchar *key, + gpointer data, + GDestroyNotify destroy_func); + +PangoFontDescription *pango_font_describe (PangoFont *font); +PangoCoverage * pango_font_get_coverage (PangoFont *font); +PangoEngineShape * pango_font_find_shaper (PangoFont *font, + const gchar *lang, + guint32 ch); + +/* + * Font Map + */ + +struct _PangoFontMap +{ + PangoFontMapClass *klass; + + /*< private >*/ + gint ref_count; +}; + +struct _PangoFontMapClass +{ + void (*destroy) (PangoFontMap *fontmap); + PangoFont *(*load_font) (PangoFontMap *fontmap, + PangoFontDescription *desc, + double size); + void (*list_fonts) (PangoFontMap *fontmap, + PangoFontDescription ***descs, + int *n_descs); +}; + +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_list_fonts (PangoFontMap *fontmap, + PangoFontDescription ***descs, + int *n_descs); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif __PANGO_FONT_H__ diff --git a/pango/pango-glyph.h b/pango/pango-glyph.h new file mode 100644 index 00000000..b19cc782 --- /dev/null +++ b/pango/pango-glyph.h @@ -0,0 +1,112 @@ +/* Pango + * pango-glyph.h: Glyph storage + * + * 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_GLYPH_H__ +#define __PANGO_GLYPH_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _PangoGlyphGeometry PangoGlyphGeometry; +typedef struct _PangoGlyphVisAttr PangoGlyphVisAttr; +typedef struct _PangoGlyphInfo PangoGlyphInfo; +typedef struct _PangoGlyphString PangoGlyphString; + +/* 64'ths of a point - 1/4608 in, 5.51 * 10^-5 in. */ +typedef guint32 PangoGlyphUnit; + +/* A index of a glyph into a font. Rendering system dependent + */ +typedef guint32 PangoGlyph; + +/* Positioning information about a glyph + */ +struct _PangoGlyphGeometry +{ + PangoGlyphUnit width; + PangoGlyphUnit x_offset; + PangoGlyphUnit y_offset; +}; + +/* Visual attributes of a glyph + */ +struct _PangoGlyphVisAttr +{ + guint is_cluster_start : 1; +}; + +/* A single glyph + */ +struct _PangoGlyphInfo +{ + PangoGlyph glyph; + PangoGlyphGeometry geometry; + PangoGlyphVisAttr attr; +}; + +/* A string of glyphs with positional information and visual attributes - + * ready for drawing + */ +struct _PangoGlyphString { + gint num_glyphs; + + PangoGlyphInfo *glyphs; + + /* This is a memory inefficient way of representing the + * information here - each value gives the character index + * of the start of the cluster to which the glyph belongs. + */ + gint *log_clusters; + + /*< private >*/ + gint space; +}; + +PangoGlyphString *pango_glyph_string_new (void); +void pango_glyph_string_set_size (PangoGlyphString *string, + gint new_len); +void pango_glyph_string_free (PangoGlyphString *string); + +void pango_cp_to_x (gchar *text, + gint length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs, + gint char_pos, + gboolean trailing, + gint *x_pos); +void pango_x_to_cp (gchar *text, + gint length, + PangoAnalysis *analysis, + PangoGlyphString *glyphs, + gint x_pos, + gint *char_pos, + gint *trailing); + +void pango_justify (PangoGlyphString *glyphs, + gint new_line_width, + gint min_kashida_width); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif __PANGO_GLYPH_H__ diff --git a/pango/pango-layout.h b/pango/pango-layout.h new file mode 100644 index 00000000..cdbde021 --- /dev/null +++ b/pango/pango-layout.h @@ -0,0 +1,44 @@ +/* Pango + * pango-layout.h: Highlevel layout driver + * + * 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_LAYOUT_H__ +#define __PANGO_LAYOUT_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef struct _PangoLayout PangoLayout; + + /* + pango_layout_new (char *text, int length); + pango_layout_get_glyph_strings (); + pango_layout_cp_to_xy (); + pango_layout_xy_to_cp (); + pango_layout_justify (); + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif __PANGO_LAYOUT_H__ + diff --git a/pango/pango-types.h b/pango/pango-types.h new file mode 100644 index 00000000..f702a722 --- /dev/null +++ b/pango/pango-types.h @@ -0,0 +1,76 @@ +/* Pango + * pango-types.h: + * + * Copyright (C) 1999 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_TYPES_H__ +#define __PANGO_TYPES_H__ + +#include <glib.h> +typedef struct _PangoAnalysis PangoAnalysis; +typedef struct _PangoItem PangoItem; +typedef struct _PangoLangRange PangoLangRange; +typedef struct _PangoLogAttr PangoLogAttr; + +typedef struct _PangoEngineLang PangoEngineLang; +typedef struct _PangoEngineShape PangoEngineShape; + +/* Information about a segment of text with a consistent + * shaping/language engine and bidirectional level + */ + +struct _PangoAnalysis { + PangoEngineShape *shape_engine; + PangoEngineLang *lang_engine; + guint8 level; +}; + +struct _PangoItem { + gint offset; + gint length; + gint num_chars; + PangoAnalysis analysis; +}; + +typedef enum { + PANGO_DIRECTION_LTR, + PANGO_DIRECTION_RTL, + PANGO_DIRECTION_TTB +} PangoDirection; + +/* Language tagging information + */ +struct _PangoLangRange +{ + gint start; + gint length; + gchar *lang; +}; + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __PANGO_TYPES_H__ */ + diff --git a/pango/pango.h b/pango/pango.h index 96697408..60993938 100644 --- a/pango/pango.h +++ b/pango/pango.h @@ -19,16 +19,6 @@ * Boston, MA 02111-1307, USA. */ -/* The API here is based fairly closely on Microsoft's Uniscript - * API. Differences here: - * - * - Memory management is more convenient (Pango handles - * all buffer reallocation) - * - Unicode strings are represented in UTF-8 - * - Representation of fonts and glyphs is abstracted to be - * rendering-system dependent. - */ - #ifndef __PANGO_H__ #define __PANGO_H__ @@ -38,79 +28,23 @@ extern "C" { #endif /* __cplusplus */ -typedef struct _PangoAnalysis PangoAnalysis; -typedef struct _PangoItem PangoItem; -typedef struct _PangoContext PangoContext; -typedef struct _PangoLangRange PangoLangRange; -typedef struct _PangoLogAttr PangoLogAttr; - -typedef struct _PangoFont PangoFont; -typedef struct _PangoFontClass PangoFontClass; - -typedef struct _PangoGlyphGeometry PangoGlyphGeometry; -typedef struct _PangoGlyphVisAttr PangoGlyphVisAttr; -typedef struct _PangoGlyphInfo PangoGlyphInfo; -typedef struct _PangoGlyphString PangoGlyphString; - -typedef struct _PangoEngineInfo PangoEngineInfo; -typedef struct _PangoEngineRange PangoEngineRange; -typedef struct _PangoEngine PangoEngine; -typedef struct _PangoEngineLang PangoEngineLang; -typedef struct _PangoEngineShape PangoEngineShape; - -/* 64'ths of a point - 1/4608 in, 5.51 * 10^-5 in. */ -typedef guint32 PangoGlyphUnit; - -/* Information about a segment of text with a consistent - * shaping/language engine and bidirectional level - */ -struct _PangoAnalysis { - PangoEngineShape *shape_engine; - PangoEngineLang *lang_engine; - guint8 level; -}; - -struct _PangoItem { - gint offset; - gint length; - gint num_chars; - PangoAnalysis analysis; -}; - -/* Sort of like a GC - application set information about how - * to handle scripts - */ - -typedef enum { - PANGO_DIRECTION_LTR, - PANGO_DIRECTION_RTL, - PANGO_DIRECTION_TTB -} PangoDirection; - -struct _PangoContext { - gchar *lang; - gchar *render_type; - PangoDirection direction; -}; - -/* Language tagging information - */ -struct _PangoLangRange -{ - gint start; - gint length; - gchar *lang; -}; +#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> /* 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); + gchar *text, + gint length, + PangoLangRange *lang_info, + gint n_langs); /* Logical attributes of a character */ @@ -130,89 +64,6 @@ void pango_break (gchar *text, PangoAnalysis *analysis, PangoLogAttr *attrs); -/* - * FONT OPERATIONS - */ - -/* This structure represents a logical font */ -struct _PangoFont { - PangoFontClass *klass; - - /*< private >*/ - gint ref_count; - GData *data; -}; - -struct _PangoFontClass { - void (*destroy) (PangoFont *font); -}; - -void pango_font_init (PangoFont *font); -void pango_font_ref (PangoFont *font); -void pango_font_unref (PangoFont *font); -gpointer pango_font_get_data (PangoFont *font, - gchar *key); -void pango_font_set_data (PangoFont *font, - gchar *key, - gpointer data, - GDestroyNotify destroy_func); - -/* - * GLYPH STORAGE - */ - -/* A index of a glyph into a font. Rendering system dependent - */ -typedef guint32 PangoGlyph; - -/* Positioning information about a glyph - */ -struct _PangoGlyphGeometry -{ - PangoGlyphUnit width; - PangoGlyphUnit x_offset; - PangoGlyphUnit y_offset; -}; - -/* Visual attributes of a glyph - */ -struct _PangoGlyphVisAttr -{ - guint is_cluster_start : 1; -}; - -/* A single glyph - */ -struct _PangoGlyphInfo -{ - PangoGlyph glyph; - PangoGlyphGeometry geometry; - PangoGlyphVisAttr attr; -}; - -/* A string of glyphs with positional information and visual attributes - - * ready for drawing - */ -struct _PangoGlyphString { - gint num_glyphs; - - PangoGlyphInfo *glyphs; - - /* This is a memory inefficient way of representing the - * information here - each value gives the character index - * of the start of the cluster to which the glyph belongs. - */ - gint *log_clusters; - - /*< private >*/ - gint space; -}; - -PangoGlyphString *pango_glyph_string_new (void); -void pango_glyph_string_set_size (PangoGlyphString *string, - gint new_len); -void pango_glyph_string_free (PangoGlyphString *string); - /* Turn a string of characters into a string of glyphs */ void pango_shape (PangoFont *font, @@ -225,90 +76,6 @@ void pango_shape (PangoFont *font, GList *pango_reorder_items (GList *logical_items); -/* Take a PangoGlyphString and add justification to fill to a - * given width - */ -void pango_justify (PangoGlyphString *glyphs, - gint new_line_width, - gint min_kashida_width); - -/* For selection/cursor positioning - turn a character position into a - * X position. - */ -void pango_cp_to_x (gchar *text, - gint length, - PangoAnalysis *analysis, - PangoGlyphString *glyphs, - gint char_pos, - gboolean trailing, - gint *x_pos); - - -/* For selection/cursor positioning - turn a X position into a - * character position - */ -void pango_x_to_cp (gchar *text, - gint length, - PangoAnalysis *analysis, - PangoGlyphString *glyphs, - gint x_pos, - gint *char_pos, - gint *trailing); - -/* Module API */ - -#define PANGO_ENGINE_TYPE_LANG "PangoEngineLang" -#define PANGO_ENGINE_TYPE_SHAPE "PangoEngineShape" - -#define PANGO_RENDER_TYPE_NONE "PangoRenderNone" - -struct _PangoEngineRange -{ - guint32 start; - guint32 end; - gchar *langs; -}; - -struct _PangoEngineInfo -{ - gchar *id; - gchar *engine_type; - gchar *render_type; - PangoEngineRange *ranges; - gint n_ranges; -}; - -struct _PangoEngine -{ - gchar *id; - gchar *type; - gint length; -}; - -struct _PangoEngineLang -{ - PangoEngine engine; - void (*script_break) (gchar *text, - gint len, - PangoAnalysis *analysis, - PangoLogAttr *attrs); -}; - -struct _PangoEngineShape { - PangoEngine engine; - void (*script_shape) (PangoFont *font, - gchar *text, - gint length, - PangoAnalysis *analysis, - PangoGlyphString *glyphs); -}; - -/* A module should export the following functions */ - -void script_engine_list (PangoEngineInfo **engines, - gint *n_engines); -PangoEngine *script_engine_load (const gchar *id); -void script_engine_unload (PangoEngine *engine); #ifdef __cplusplus } diff --git a/pango/pangox.c b/pango/pangox.c index 4a9e68fb..60dda86b 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -22,18 +22,41 @@ #include <X11/Xlib.h> #include "pangox.h" #include <ctype.h> +#include <math.h> #include <stdio.h> #include <string.h> typedef struct _PangoXFont PangoXFont; +typedef struct _PangoXFontMap PangoXFontMap; typedef struct _PangoXSubfontInfo PangoXSubfontInfo; -struct _PangoXSubfontInfo { - gchar *xlfd; +typedef struct _PangoXFamilyEntry PangoXFamilyEntry; +typedef struct _PangoXFontEntry PangoXFontEntry; + +#ifndef G_N_ELEMENTS +#define G_N_ELEMENTS(arr) (sizeof(arr) / sizeof((arr)[0])) +#endif + +struct _PangoXFontEntry +{ + char *xlfd_prefix; + PangoFontDescription description; +}; + +struct _PangoXFamilyEntry +{ + char *family_name; + GSList *font_entries; +}; + +struct _PangoXSubfontInfo +{ + char *xlfd; XFontStruct *font_struct; }; -struct _PangoXFont { +struct _PangoXFont +{ PangoFont font; Display *display; @@ -47,10 +70,89 @@ struct _PangoXFont { PangoXSubfontInfo **subfonts; - gint n_subfonts; - gint max_subfonts; + int n_subfonts; + int max_subfonts; +}; + +struct _PangoXFontMap +{ + PangoFontMap fontmap; + + Display *display; + + GHashTable *families; + + int n_fonts; +}; + +/* This is the largest field length we will accept. If a fontname has a field + larger than this we will skip it. */ +#define XLFD_MAX_FIELD_LEN 64 +#define MAX_FONTS 32767 + +/* These are the field numbers in the X Logical Font Description fontnames, + e.g. -adobe-courier-bold-o-normal--25-180-100-100-m-150-iso8859-1 */ +typedef enum +{ + XLFD_FOUNDRY = 0, + XLFD_FAMILY = 1, + XLFD_WEIGHT = 2, + XLFD_SLANT = 3, + XLFD_SET_WIDTH = 4, + XLFD_ADD_STYLE = 5, + XLFD_PIXELS = 6, + XLFD_POINTS = 7, + XLFD_RESOLUTION_X = 8, + XLFD_RESOLUTION_Y = 9, + XLFD_SPACING = 10, + XLFD_AVERAGE_WIDTH = 11, + XLFD_CHARSET = 12, + XLFD_NUM_FIELDS +} FontField; + +const struct { + const gchar *text; + PangoWeight value; +} weights_map[] = { + { "light", 300 }, + { "regular", 400 }, + { "book", 400 }, + { "medium", 500 }, + { "semibold", 600 }, + { "demibold", 600 }, + { "bold", 700 }, + { "extrabold", 800 }, + { "ultrabold", 800 }, + { "heavy", 900 }, + { "black", 900 } }; +const struct { + const gchar *text; + PangoStyle value; +} styles_map[] = { + { "r", PANGO_STYLE_NORMAL }, + { "i", PANGO_STYLE_ITALIC }, + { "o", PANGO_STYLE_OBLIQUE } +}; + +const struct { + const gchar *text; + PangoStretch value; +} stretches_map[] = { + { "normal", PANGO_STRETCH_NORMAL }, + { "semicondensed", PANGO_STRETCH_SEMI_CONDENSED }, + { "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, + PangoFontDescription ***descs, + int *n_descs); + static PangoXSubfontInfo * pango_x_find_subfont (PangoFont *font, PangoXSubfont subfont_index); static XCharStruct * pango_x_get_per_char (PangoFont *font, @@ -64,10 +166,385 @@ static gboolean pango_x_find_glyph (PangoFont *font, static XFontStruct * pango_x_get_font_struct (PangoFont *font, PangoXSubfontInfo *info); +static gboolean pango_x_is_xlfd_font_name (const char *fontname); +static char * pango_x_get_xlfd_field (const char *fontname, + FontField field_num, + char *buffer); +static void pango_x_insert_font (PangoXFontMap *fontmap, + char *fontname); + +static GList *fontmaps; + PangoFontClass pango_x_font_class = { pango_x_font_destroy }; +PangoFontMapClass pango_x_font_map_class = { + pango_x_font_map_destroy, + pango_x_font_map_load_font, + pango_x_font_map_list_fonts +}; + +static PangoFontMap * +pango_x_font_map_for_display (Display *display) +{ + PangoXFontMap *xfontmap; + GList *tmp_list = fontmaps; + char **xfontnames; + int num_fonts, i; + + while (tmp_list) + { + xfontmap = tmp_list->data; + + if (xfontmap->display == display) + { + pango_font_map_ref ((PangoFontMap *)xfontmap); + return (PangoFontMap *)xfontmap; + } + } + + xfontmap = g_new (PangoXFontMap, 1); + + xfontmap->fontmap.klass = &pango_x_font_map_class; + xfontmap->display = display; + xfontmap->families = g_hash_table_new (g_str_hash, g_str_equal); + xfontmap->n_fonts = 0; + + pango_font_map_init ((PangoFontMap *)xfontmap); + + /* Get a maximum of MAX_FONTS fontnames from the X server. + Use "-*" as the pattern rather than "-*-*-*-*-*-*-*-*-*-*-*-*-*-*" since + the latter may result in fonts being returned which don't actually exist. + xlsfonts also uses "*" so I think it's OK. "-*" gets rid of aliases. */ + xfontnames = XListFonts (xfontmap->display, "-*", MAX_FONTS, &num_fonts); + if (num_fonts == MAX_FONTS) + g_warning("MAX_FONTS exceeded. Some fonts may be missing."); + + /* Insert the font families into the main table */ + for (i = 0; i < num_fonts; i++) + { + if (pango_x_is_xlfd_font_name (xfontnames[i])) + pango_x_insert_font (xfontmap, xfontnames[i]); + } + + XFreeFontNames (xfontnames); + + return (PangoFontMap *)xfontmap; +} + +static void +pango_x_font_map_destroy (PangoFontMap *fontmap) +{ + fontmaps = g_list_remove (fontmaps, fontmap); + + g_free (fontmap); +} + +static PangoFont * +pango_x_font_map_load_font (PangoFontMap *fontmap, + PangoFontDescription *description, + double size) +{ + PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap; + PangoXFamilyEntry *family_entry; + PangoXFontEntry *font_entry; + PangoFont *result = NULL; + GSList *tmp_list; + gchar *name; + int size_decipoints; + + g_return_val_if_fail (size > 0, NULL); + + name = g_strdup (description->family_name); + g_strdown (name); + + size_decipoints = floor(size*10 + 0.5); + + family_entry = g_hash_table_lookup (xfontmap->families, name); + if (family_entry) + { + tmp_list = family_entry->font_entries; + while (tmp_list) + { + font_entry = tmp_list->data; + + if (font_entry->description.style == description->style && + font_entry->description.variant == description->variant && + font_entry->description.weight == description->weight && + font_entry->description.stretch == description->stretch) + { + /* Construct and XLFD for the sized font. The first 5 fields of the + * XLFD are stored in the xlfd_prefix. + */ + + char *xlfd = g_strdup_printf ("%s*-%d-*-*-*-*-*-*", font_entry->xlfd_prefix, size_decipoints); + /* FIXME: cache fonts */ + result = pango_x_load_font (xfontmap->display, xlfd); + g_free (xlfd); + + break; + } + + tmp_list = tmp_list->next; + } + } + + g_free (name); + return result; +} + +typedef struct +{ + int n_found; + PangoFontDescription **descs; +} ListFontsInfo; + + +static void +list_fonts_foreach (gpointer key, gpointer value, gpointer user_data) +{ + PangoXFamilyEntry *entry = value; + ListFontsInfo *info = user_data; + + GSList *tmp_list = entry->font_entries; + + while (tmp_list) + { + PangoXFontEntry *font_entry = tmp_list->data; + + info->descs[info->n_found++] = pango_font_description_copy (&font_entry->description); + tmp_list = tmp_list->next; + } +} + +static void +pango_x_font_map_list_fonts (PangoFontMap *fontmap, + PangoFontDescription ***descs, + int *n_descs) +{ + PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap; + ListFontsInfo info; + + if (!n_descs) + return; + + *n_descs = xfontmap->n_fonts; + if (!descs) + return; + + *descs = g_new (PangoFontDescription *, xfontmap->n_fonts); + + info.descs = *descs; + info.n_found = 0; + + g_hash_table_foreach (xfontmap->families, list_fonts_foreach, &info); +} + +/* + * Returns TRUE if the fontname is a valid XLFD. + * (It just checks if the number of dashes is 14, and that each + * field < XLFD_MAX_FIELD_LEN characters long - that's not in the XLFD but it + * makes it easier for me). + */ +static gboolean +pango_x_is_xlfd_font_name (const char *fontname) +{ + int i = 0; + int field_len = 0; + + while (*fontname) + { + if (*fontname++ == '-') + { + if (field_len > XLFD_MAX_FIELD_LEN) return FALSE; + field_len = 0; + i++; + } + else + field_len++; + } + + return (i == 14) ? TRUE : FALSE; +} + +/* + * This fills the buffer with the specified field from the X Logical Font + * Description name, and returns it. If fontname is NULL or the field is + * longer than XFLD_MAX_FIELD_LEN it returns NULL. + * Note: For the charset field, we also return the encoding, e.g. 'iso8859-1'. + */ +static char* +pango_x_get_xlfd_field (const char *fontname, + FontField field_num, + char *buffer) +{ + const char *t1, *t2; + int countdown, len, num_dashes; + + if (!fontname) + return NULL; + + /* we assume this is a valid fontname...that is, it has 14 fields */ + + countdown = field_num; + t1 = fontname; + while (*t1 && (countdown >= 0)) + if (*t1++ == '-') + countdown--; + + num_dashes = (field_num == XLFD_CHARSET) ? 2 : 1; + for (t2 = t1; *t2; t2++) + { + if (*t2 == '-' && --num_dashes == 0) + break; + } + + if (t1 != t2) + { + /* Check we don't overflow the buffer */ + len = (long) t2 - (long) t1; + if (len > XLFD_MAX_FIELD_LEN - 1) + return NULL; + strncpy (buffer, t1, len); + buffer[len] = 0; + /* Convert to lower case. */ + g_strdown (buffer); + } + else + strcpy(buffer, "(nil)"); + + return buffer; +} + +/* This inserts the given fontname into the FontInfo table. + If a FontInfo already exists with the same family and foundry, then the + fontname is added to the FontInfos list of fontnames, else a new FontInfo + is created and inserted in alphabetical order in the table. */ +static void +pango_x_insert_font (PangoXFontMap *xfontmap, + char *fontname) +{ + PangoFontDescription description; + char family_buffer[XLFD_MAX_FIELD_LEN]; + char weight_buffer[XLFD_MAX_FIELD_LEN]; + char slant_buffer[XLFD_MAX_FIELD_LEN]; + char set_width_buffer[XLFD_MAX_FIELD_LEN]; + GSList *tmp_list; + PangoXFamilyEntry *family_entry; + PangoXFontEntry *font_entry; + int i; + + /* Convert the XLFD into a PangoFontDescription */ + + description.family_name = pango_x_get_xlfd_field (fontname, XLFD_FAMILY, family_buffer); + g_strdown (description.family_name); + + if (!description.family_name) + return; + + description.style = PANGO_STYLE_NORMAL; + if (pango_x_get_xlfd_field (fontname, XLFD_SLANT, slant_buffer)) + { + for (i=0; i<G_N_ELEMENTS(styles_map); i++) + { + if (!strcmp (styles_map[i].text, slant_buffer)) + { + description.style = styles_map[i].value; + break; + } + } + } + else + strcpy (slant_buffer, "*"); + + description.variant = PANGO_VARIANT_NORMAL; + + description.weight = PANGO_WEIGHT_NORMAL; + if (pango_x_get_xlfd_field (fontname, XLFD_WEIGHT, weight_buffer)) + { + for (i=0; i<G_N_ELEMENTS(weights_map); i++) + { + if (!strcmp (weights_map[i].text, weight_buffer)) + { + description.weight = weights_map[i].value; + break; + } + } + } + else + strcpy (weight_buffer, "*"); + + description.stretch = PANGO_STRETCH_NORMAL; + if (pango_x_get_xlfd_field (fontname, XLFD_SET_WIDTH, set_width_buffer)) + { + for (i=0; i<G_N_ELEMENTS(stretches_map); i++) + { + if (!strcmp (stretches_map[i].text, set_width_buffer)) + { + description.stretch = stretches_map[i].value; + break; + } + } + } + else + strcpy (set_width_buffer, "*"); + + family_entry = g_hash_table_lookup (xfontmap->families, description.family_name); + if (!family_entry) + { + family_entry = g_new (PangoXFamilyEntry, 1); + family_entry->family_name = g_strdup (description.family_name); + family_entry->font_entries = NULL; + + g_hash_table_insert (xfontmap->families, family_entry->family_name, family_entry); + } + + tmp_list = family_entry->font_entries; + while (tmp_list) + { + font_entry = tmp_list->data; + + if (font_entry->description.style == description.style && + font_entry->description.variant == description.variant && + font_entry->description.weight == description.weight && + font_entry->description.stretch == description.stretch) + return; + + tmp_list = tmp_list->next; + } + + font_entry = g_new (PangoXFontEntry, 1); + font_entry->description = description; + font_entry->description.family_name = family_entry->family_name; + + font_entry->xlfd_prefix = g_strconcat ("-*-", + family_buffer, + "-", + weight_buffer, + "-", + slant_buffer, + "-", + set_width_buffer, + "--", + NULL); + + family_entry->font_entries = g_slist_append (family_entry->font_entries, font_entry); + xfontmap->n_fonts++; +} + + +PangoContext * +pango_x_get_context (Display *display) +{ + PangoContext *result; + + result = pango_context_new (); + pango_context_add_font_map (result, pango_x_font_map_for_display (display)); + + return result; +} + /** * pango_x_load_font: * @display: the X display @@ -80,7 +557,7 @@ PangoFontClass pango_x_font_class = { */ PangoFont * pango_x_load_font (Display *display, - gchar *spec) + char *spec) { PangoXFont *result; @@ -126,8 +603,8 @@ pango_x_render (Display *display, GC gc, PangoFont *font, PangoGlyphString *glyphs, - gint x, - gint y) + int x, + int y) { /* Slow initial implementation. For speed, it should really * collect the characters into runs, and draw multiple @@ -193,13 +670,13 @@ pango_x_render (Display *display, void pango_x_glyph_extents (PangoFont *font, PangoGlyph glyph, - gint *lbearing, - gint *rbearing, - gint *width, - gint *ascent, - gint *descent, - gint *logical_ascent, - gint *logical_descent) + int *lbearing, + int *rbearing, + int *width, + int *ascent, + int *descent, + int *logical_ascent, + int *logical_descent) { XCharStruct *cs; PangoXSubfontInfo *subfont; @@ -261,13 +738,13 @@ pango_x_glyph_extents (PangoFont *font, void pango_x_extents (PangoFont *font, PangoGlyphString *glyphs, - gint *lbearing, - gint *rbearing, - gint *width, - gint *ascent, - gint *descent, - gint *logical_ascent, - gint *logical_descent) + int *lbearing, + int *rbearing, + int *width, + int *ascent, + int *descent, + int *logical_ascent, + int *logical_descent) { PangoXSubfontInfo *subfont; XCharStruct *cs; @@ -350,13 +827,13 @@ match_end (char *a, char *b) * (g_malloc'd) new name, or NULL if the XLFD cannot * match the charset */ -static gchar * +static char * name_for_charset (char *xlfd, char *charset) { char *p; char *dash_charset = g_strconcat ("-", charset, NULL); char *result = NULL; - gint ndashes = 0; + int ndashes = 0; for (p = xlfd; *p; p++) if (*p == '-') @@ -522,8 +999,6 @@ pango_x_font_destroy (PangoFont *font) PangoXFont *xfont = (PangoXFont *)font; int i; - g_hash_table_destroy (xfont->subfonts_by_charset); - for (i=0; i<xfont->n_subfonts; i++) { PangoXSubfontInfo *info = xfont->subfonts[i]; @@ -538,6 +1013,7 @@ pango_x_font_destroy (PangoFont *font) g_free (xfont->subfonts); g_hash_table_foreach (xfont->subfonts_by_charset, subfonts_foreach, NULL); + g_hash_table_destroy (xfont->subfonts_by_charset); g_strfreev (xfont->fonts); g_free (font); diff --git a/pango/pangox.h b/pango/pangox.h index 6cde06bc..b567aa46 100644 --- a/pango/pangox.h +++ b/pango/pangox.h @@ -35,6 +35,8 @@ extern "C" { /* Calls for applications */ +PangoContext *pango_x_get_context (Display *display); + PangoFont *pango_x_load_font (Display *display, gchar *spec); void pango_x_render (Display *display, |