diff options
author | Ramiro Estrugo <ramiro@src.gnome.org> | 2001-02-22 14:33:58 +0000 |
---|---|---|
committer | Ramiro Estrugo <ramiro@src.gnome.org> | 2001-02-22 14:33:58 +0000 |
commit | f2453a7d8baa76a1aa97f3040261d778aacfac57 (patch) | |
tree | 17d23e45ec2d4ccf2c01f6f33abc82ccc6c73190 | |
parent | 2e9551e36205476ef592e80747e90bbc037b3bd3 (diff) | |
download | nautilus-f2453a7d8baa76a1aa97f3040261d778aacfac57.tar.gz |
reviewed by: Maciej Stachowiak <mjs@eazel.com>
* components/mozilla/nautilus-mozilla-encoding-tables.c:
No need to have 2 strings. Use an array of just one string.
* components/mozilla/nautilus-mozilla-content-view.c:
(mozilla_view_create_charset_encoding_submenu):
Replace assertion with a more robust check for NULL.
reviewed by: Seth Nickell <seth@eazel.com>
* applets/preferences-applet/nautilus-preferences-applet.c:
(quit_nautilus_button_clicked_callback),
(start_nautilus_button_clicked_callback),
(restart_nautilus_button_clicked_callback),
(exit_button_clicked_callback), (main):
Add a exit button for the applet itself. Renamed nautilus remote
callbacks to be clearer.
* libnautilus-extensions/nautilus-art-extensions.h:
* libnautilus-extensions/nautilus-art-extensions.c:
(nautilus_art_irect_is_valid),
(nautilus_self_check_art_extensions): New functions and tests for
checking whether a rectangle is valid.
* libnautilus-extensions/nautilus-glyph.h: Use int instead
of guint everywhere.
* libnautilus-extensions/nautilus-glyph.c: (nautilus_glyph_new),
(nautilus_glyph_free), (glyph_get_width_space_safe): New functions
to get dimensions that work with glyphs that are just empty space.
(glyph_get_height_space_safe), (nautilus_glyph_get_width),
(nautilus_glyph_get_height), (nautilus_glyph_get_dimensions): Make
these work with empty spaces.
(glyph_is_valid), (nautilus_glyph_draw_to_pixbuf): Use libart rgba
functions instead of doing our own alpha blending. Allow for
rendering glyphs with just blank spaces (noop). Remove debug code.
(nautilus_glyph_intersect): New function to intersect a glyph at
some coordinates with a rectangle.
* test/test-nautilus-glyph-simple.c: (main):
* test/test-nautilus-glyph.c: (glyph_new), (main):
* test/test.c: (test_pixbuf_draw_rectangle_tiled):
More glyph tests.
-rw-r--r-- | ChangeLog | 47 | ||||
-rw-r--r-- | applets/preferences-applet/nautilus-preferences-applet.c | 30 | ||||
-rw-r--r-- | components/mozilla/nautilus-mozilla-content-view.c | 4 | ||||
-rw-r--r-- | components/mozilla/nautilus-mozilla-encoding-tables.c | 186 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-art-extensions.c | 14 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-art-extensions.h | 1 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-glyph.c | 230 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-glyph.h | 8 | ||||
-rw-r--r-- | libnautilus-private/nautilus-art-extensions.c | 14 | ||||
-rw-r--r-- | libnautilus-private/nautilus-art-extensions.h | 1 | ||||
-rw-r--r-- | libnautilus-private/nautilus-glyph.c | 230 | ||||
-rw-r--r-- | libnautilus-private/nautilus-glyph.h | 8 | ||||
-rw-r--r-- | test/test-nautilus-glyph-simple.c | 17 | ||||
-rw-r--r-- | test/test-nautilus-glyph.c | 306 | ||||
-rw-r--r-- | test/test.c | 4 |
15 files changed, 711 insertions, 389 deletions
@@ -1,3 +1,50 @@ +2001-02-22 Ramiro Estrugo <ramiro@eazel.com> + + reviewed by: Maciej Stachowiak <mjs@eazel.com> + + * components/mozilla/nautilus-mozilla-encoding-tables.c: + No need to have 2 strings. Use an array of just one string. + + * components/mozilla/nautilus-mozilla-content-view.c: + (mozilla_view_create_charset_encoding_submenu): + Replace assertion with a more robust check for NULL. + + + reviewed by: Seth Nickell <seth@eazel.com> + + * applets/preferences-applet/nautilus-preferences-applet.c: + (quit_nautilus_button_clicked_callback), + (start_nautilus_button_clicked_callback), + (restart_nautilus_button_clicked_callback), + (exit_button_clicked_callback), (main): + Add a exit button for the applet itself. Renamed nautilus remote + callbacks to be clearer. + + * libnautilus-extensions/nautilus-art-extensions.h: + * libnautilus-extensions/nautilus-art-extensions.c: + (nautilus_art_irect_is_valid), + (nautilus_self_check_art_extensions): New functions and tests for + checking whether a rectangle is valid. + + * libnautilus-extensions/nautilus-glyph.h: Use int instead + of guint everywhere. + * libnautilus-extensions/nautilus-glyph.c: (nautilus_glyph_new), + (nautilus_glyph_free), (glyph_get_width_space_safe): New functions + to get dimensions that work with glyphs that are just empty space. + (glyph_get_height_space_safe), (nautilus_glyph_get_width), + (nautilus_glyph_get_height), (nautilus_glyph_get_dimensions): Make + these work with empty spaces. + (glyph_is_valid), (nautilus_glyph_draw_to_pixbuf): Use libart rgba + functions instead of doing our own alpha blending. Allow for + rendering glyphs with just blank spaces (noop). Remove debug code. + (nautilus_glyph_intersect): New function to intersect a glyph at + some coordinates with a rectangle. + + * test/test-nautilus-glyph-simple.c: (main): + * test/test-nautilus-glyph.c: (glyph_new), (main): + * test/test.c: (test_pixbuf_draw_rectangle_tiled): + More glyph tests. + 2001-02-22 Dan Mueth <dan@eazel.com> reviewed by: Ramiro Estrugo <ramiro@eazel.com> diff --git a/applets/preferences-applet/nautilus-preferences-applet.c b/applets/preferences-applet/nautilus-preferences-applet.c index f9a2d36dd..425e04ec2 100644 --- a/applets/preferences-applet/nautilus-preferences-applet.c +++ b/applets/preferences-applet/nautilus-preferences-applet.c @@ -131,7 +131,7 @@ boolean_toggle_button_new (const char *preference_name, } static void -quit_button_clicked_callback (GtkWidget *button, +quit_nautilus_button_clicked_callback (GtkWidget *button, gpointer callback_data) { g_return_if_fail (GTK_IS_BUTTON (button)); @@ -140,7 +140,7 @@ quit_button_clicked_callback (GtkWidget *button, } static void -start_button_clicked_callback (GtkWidget *button, +start_nautilus_button_clicked_callback (GtkWidget *button, gpointer callback_data) { g_return_if_fail (GTK_IS_BUTTON (button)); @@ -149,7 +149,7 @@ start_button_clicked_callback (GtkWidget *button, } static void -restart_button_clicked_callback (GtkWidget *button, +restart_nautilus_button_clicked_callback (GtkWidget *button, gpointer callback_data) { g_return_if_fail (GTK_IS_BUTTON (button)); @@ -158,6 +158,15 @@ restart_button_clicked_callback (GtkWidget *button, } static void +exit_button_clicked_callback (GtkWidget *button, + gpointer callback_data) +{ + g_return_if_fail (GTK_IS_BUTTON (button)); + + gtk_main_quit (); +} + +static void user_level_changed_callback (gpointer callback_data) { g_return_if_fail (GTK_IS_TOGGLE_BUTTON (callback_data)); @@ -178,6 +187,7 @@ main (int argc, char **argv) GtkWidget *quit_button; GtkWidget *start_button; GtkWidget *restart_button; + GtkWidget *exit_button; bindtextdomain (PACKAGE, GNOMELOCALEDIR); textdomain (PACKAGE); @@ -235,7 +245,7 @@ main (int argc, char **argv) gtk_box_pack_start (GTK_BOX (command_hbox), quit_button, TRUE, TRUE, 1); gtk_signal_connect (GTK_OBJECT (quit_button), "clicked", - GTK_SIGNAL_FUNC (quit_button_clicked_callback), + GTK_SIGNAL_FUNC (quit_nautilus_button_clicked_callback), NULL); start_button = gtk_button_new_with_label ("Start"); @@ -243,7 +253,7 @@ main (int argc, char **argv) gtk_box_pack_start (GTK_BOX (command_hbox), start_button, TRUE, TRUE, 1); gtk_signal_connect (GTK_OBJECT (start_button), "clicked", - GTK_SIGNAL_FUNC (start_button_clicked_callback), + GTK_SIGNAL_FUNC (start_nautilus_button_clicked_callback), NULL); restart_button = gtk_button_new_with_label ("Restart"); @@ -251,7 +261,15 @@ main (int argc, char **argv) gtk_box_pack_start (GTK_BOX (command_hbox), restart_button, TRUE, TRUE, 1); gtk_signal_connect (GTK_OBJECT (restart_button), "clicked", - GTK_SIGNAL_FUNC (restart_button_clicked_callback), + GTK_SIGNAL_FUNC (restart_nautilus_button_clicked_callback), + NULL); + + exit_button = gtk_button_new_with_label ("[x]"); + nautilus_gtk_label_make_smaller (GTK_LABEL (GTK_BIN (exit_button)->child), 4); + gtk_box_pack_start (GTK_BOX (command_hbox), exit_button, TRUE, TRUE, 1); + gtk_signal_connect (GTK_OBJECT (exit_button), + "clicked", + GTK_SIGNAL_FUNC (exit_button_clicked_callback), NULL); gtk_container_add (GTK_CONTAINER (applet), main_hbox); diff --git a/components/mozilla/nautilus-mozilla-content-view.c b/components/mozilla/nautilus-mozilla-content-view.c index 4a9421039..7b50d7471 100644 --- a/components/mozilla/nautilus-mozilla-content-view.c +++ b/components/mozilla/nautilus-mozilla-content-view.c @@ -582,7 +582,9 @@ mozilla_view_create_charset_encoding_submenu (NautilusMozillaContentView *mozill translated_encoding_group = mozilla_charset_encoding_group_get_translated (mozilla, encoding_group); - g_assert (translated_encoding_group != NULL); + if (translated_encoding_group == NULL) { + translated_encoding_group = g_strdup (encoding_group); + } escaped_encoding_group = bonobo_ui_util_encode_str (encoding_group); /* HACK: From now onwards we use the groups list to store indeces of items */ diff --git a/components/mozilla/nautilus-mozilla-encoding-tables.c b/components/mozilla/nautilus-mozilla-encoding-tables.c index a23c3eefa..7ffecacb6 100644 --- a/components/mozilla/nautilus-mozilla-encoding-tables.c +++ b/components/mozilla/nautilus-mozilla-encoding-tables.c @@ -33,102 +33,96 @@ #include <libgnome/gnome-i18n.h> #include <string.h> -typedef struct +static const char *encoding_groups_table[] = { - const char *string; - const char *translated_string; -} TranslatedString; - -static TranslatedString encoding_groups_table[] = -{ - { "Arabic", N_("Arabic") }, - { "Baltic", N_("Baltic") }, - { "Central European", N_("Central European") }, - { "Chinese", N_("Chinese") }, - { "Cyrillic", N_("Cyrillic") }, - { "Greek", N_("Greek") }, - { "Hebrew", N_("Hebrew") }, - { "Japanese", N_("Japanese"), }, - { "Turkish", N_("Turkish") }, - { "Unicode", N_("Unicode") }, - { "UTF", N_("UTF") }, - { "Vietnamese", N_("Vietnamese") }, - { "Western", N_("Western") } + N_("Arabic"), + N_("Baltic"), + N_("Central European"), + N_("Chinese"), + N_("Cyrillic"), + N_("Greek"), + N_("Hebrew"), + N_("Japanese"), + N_("Turkish"), + N_("Unicode"), + N_("UTF"), + N_("Vietnamese"), + N_("Western") }; -static TranslatedString encoding_table[] = +static const char *encoding_table[] = { - { "Arabic (IBM-864)", N_("Arabic (IBM-864)")}, - { "Arabic (ISO-8859-6)", N_("Arabic (ISO-8859-6)")}, - { "Arabic (ISO-8859-6-E)", N_("Arabic (ISO-8859-6-E)")}, - { "Arabic (ISO-8859-6-I)", N_("Arabic (ISO-8859-6-I)")}, - { "Arabic (Windows-1256)", N_("Arabic (Windows-1256)")}, - { "Armenian (ARMSCII-8)", N_("Armenian (ARMSCII-8)")}, - { "Baltic (ISO-8859-13)", N_("Baltic (ISO-8859-13)")}, - { "Baltic (ISO-8859-4)", N_("Baltic (ISO-8859-4)")}, - { "Baltic (Windows-1257)", N_("Baltic (Windows-1257)")}, - { "Celtic (ISO-8859-14)", N_("Celtic (ISO-8859-14)")}, - { "Central European (IBM-852)", N_("Central European (IBM-852)")}, - { "Central European (ISO-8859-2)", N_("Central European (ISO-8859-2)")}, - { "Central European (MacCE)", N_("Central European (MacCE)")}, - { "Central European (Windows-1250)", N_("Central European (Windows-1250)")}, - { "Chinese Simplified (GB2312)", N_("Chinese Simplified (GB2312)")}, - { "Chinese Simplified (GBK)", N_("Chinese Simplified (GBK)")}, - { "Chinese Simplified (HZ)", N_("Chinese Simplified (HZ)")}, - { "Chinese Traditional (Big5)", N_("Chinese Traditional (Big5)")}, - { "Chinese Traditional (EUC-TW)", N_("Chinese Traditional (EUC-TW)")}, - { "Croatian (MacCroatian)", N_("Croatian (MacCroatian)")}, - { "Cyrillic (IBM-855)", N_("Cyrillic (IBM-855)")}, - { "Cyrillic (ISO-8859-5)", N_("Cyrillic (ISO-8859-5)")}, - { "Cyrillic (ISO-IR-111)", N_("Cyrillic (ISO-IR-111)")}, - { "Cyrillic (KOI8-R)", N_("Cyrillic (KOI8-R)")}, - { "Cyrillic (MacCyrillic)", N_("Cyrillic (MacCyrillic)")}, - { "Cyrillic (Windows-1251)", N_("Cyrillic (Windows-1251)")}, - { "Cyrillic/Russian (IBM-866)", N_("Cyrillic/Russian (IBM-866)")}, - { "Cyrillic/Ukrainian (KOI8-U)", N_("Cyrillic/Ukrainian (KOI8-U)")}, - { "Cyrillic/Ukrainian (MacUkrainian)", N_("Cyrillic/Ukrainian (MacUkrainian)")}, - { "English (US-ASCII)", N_("English (US-ASCII)")}, - { "Greek (ISO-8859-7)", N_("Greek (ISO-8859-7)")}, - { "Greek (MacGreek)", N_("Greek (MacGreek)")}, - { "Greek (Windows-1253)", N_("Greek (Windows-1253)")}, - { "Hebrew (IBM-862)", N_("Hebrew (IBM-862)")}, - { "Hebrew (ISO-8859-8-E)", N_("Hebrew (ISO-8859-8-E)")}, - { "Hebrew (ISO-8859-8-I)", N_("Hebrew (ISO-8859-8-I)")}, - { "Hebrew (Windows-1255)", N_("Hebrew (Windows-1255)")}, - { "Icelandic (MacIcelandic)", N_("Icelandic (MacIcelandic)")}, - { "Japanese (EUC-JP)", N_("Japanese (EUC-JP)")}, - { "Japanese (ISO-2022-JP)", N_("Japanese (ISO-2022-JP)")}, - { "Japanese (Shift_JIS)", N_("Japanese (Shift_JIS)")}, - { "Korean (EUC-KR)", N_("Korean (EUC-KR)")}, - { "Nordic (ISO-8859-10)", N_("Nordic (ISO-8859-10)")}, - { "Romanian (MacRomanian)", N_("Romanian (MacRomanian)")}, - { "South European (ISO-8859-3)", N_("South European (ISO-8859-3)")}, - { "T.61-8bit", N_("T.61-8bit")}, - { "Thai (TIS-620)", N_("Thai (TIS-620)")}, - { "Turkish (IBM-857)", N_("Turkish (IBM-857)")}, - { "Turkish (ISO-8859-9)", N_("Turkish (ISO-8859-9)")}, - { "Turkish (MacTurkish)", N_("Turkish (MacTurkish)")}, - { "Turkish (Windows-1254)", N_("Turkish (Windows-1254)")}, - { "Unicode (UTF-7)", N_("Unicode (UTF-7)")}, - { "Unicode (UTF-8)", N_("Unicode (UTF-8)")}, - { "User Defined", N_("User Defined")}, - { "UTF-16BE", N_("UTF-16BE")}, - { "UTF-16LE", N_("UTF-16LE")}, - { "UTF-32BE", N_("UTF-32BE")}, - { "UTF-32LE", N_("UTF-32LE")}, - { "Vietnamese (TCVN)", N_("Vietnamese (TCVN)")}, - { "Vietnamese (VISCII)", N_("Vietnamese (VISCII)")}, - { "Vietnamese (VPS)", N_("Vietnamese (VPS)")}, - { "Vietnamese (Windows-1258)", N_("Vietnamese (Windows-1258)")}, - { "Visual Hebrew (ISO-8859-8)", N_("Visual Hebrew (ISO-8859-8)")}, - { "Western (IBM-850)", N_("Western (IBM-850)")}, - { "Western (ISO-8859-1)", N_("Western (ISO-8859-1)")}, - { "Western (ISO-8859-15)", N_("Western (ISO-8859-15)")}, - { "Western (MacRoman)", N_("Western (MacRoman)")}, - { "Western (Windows-1252)", N_("Western (Windows-1252)")}, - { "windows-936", N_("windows-936")}, - { "x-imap4-modified-utf7", N_("x-imap4-modified-utf7")}, - { "x-u-escaped", N_("x-u-escaped") } + N_("Arabic (IBM-864)"), + N_("Arabic (ISO-8859-6)"), + N_("Arabic (ISO-8859-6-E)"), + N_("Arabic (ISO-8859-6-I)"), + N_("Arabic (Windows-1256)"), + N_("Armenian (ARMSCII-8)"), + N_("Baltic (ISO-8859-13)"), + N_("Baltic (ISO-8859-4)"), + N_("Baltic (Windows-1257)"), + N_("Celtic (ISO-8859-14)"), + N_("Central European (IBM-852)"), + N_("Central European (ISO-8859-2)"), + N_("Central European (MacCE)"), + N_("Central European (Windows-1250)"), + N_("Chinese Simplified (GB2312)"), + N_("Chinese Simplified (GBK)"), + N_("Chinese Simplified (HZ)"), + N_("Chinese Traditional (Big5)"), + N_("Chinese Traditional (EUC-TW)"), + N_("Croatian (MacCroatian)"), + N_("Cyrillic (IBM-855)"), + N_("Cyrillic (ISO-8859-5)"), + N_("Cyrillic (ISO-IR-111)"), + N_("Cyrillic (KOI8-R)"), + N_("Cyrillic (MacCyrillic)"), + N_("Cyrillic (Windows-1251)"), + N_("Cyrillic/Russian (IBM-866)"), + N_("Cyrillic/Ukrainian (KOI8-U)"), + N_("Cyrillic/Ukrainian (MacUkrainian)"), + N_("English (US-ASCII)"), + N_("Greek (ISO-8859-7)"), + N_("Greek (MacGreek)"), + N_("Greek (Windows-1253)"), + N_("Hebrew (IBM-862)"), + N_("Hebrew (ISO-8859-8-E)"), + N_("Hebrew (ISO-8859-8-I)"), + N_("Hebrew (Windows-1255)"), + N_("Icelandic (MacIcelandic)"), + N_("Japanese (EUC-JP)"), + N_("Japanese (ISO-2022-JP)"), + N_("Japanese (Shift_JIS)"), + N_("Korean (EUC-KR)"), + N_("Nordic (ISO-8859-10)"), + N_("Romanian (MacRomanian)"), + N_("South European (ISO-8859-3)"), + N_("T.61-8bit"), + N_("Thai (TIS-620)"), + N_("Turkish (IBM-857)"), + N_("Turkish (ISO-8859-9)"), + N_("Turkish (MacTurkish)"), + N_("Turkish (Windows-1254)"), + N_("Unicode (UTF-7)"), + N_("Unicode (UTF-8)"), + N_("User Defined"), + N_("UTF-16BE"), + N_("UTF-16LE"), + N_("UTF-32BE"), + N_("UTF-32LE"), + N_("Vietnamese (TCVN)"), + N_("Vietnamese (VISCII)"), + N_("Vietnamese (VPS)"), + N_("Vietnamese (Windows-1258)"), + N_("Visual Hebrew (ISO-8859-8)"), + N_("Western (IBM-850)"), + N_("Western (ISO-8859-1)"), + N_("Western (ISO-8859-15)"), + N_("Western (MacRoman)"), + N_("Western (Windows-1252)"), + N_("windows-936"), + N_("x-imap4-modified-utf7"), + N_("x-u-escaped") }; guint @@ -142,7 +136,7 @@ mozilla_encoding_groups_table_peek_nth (guint n) { g_return_val_if_fail (n < mozilla_encoding_groups_table_get_count (), NULL); - return encoding_groups_table[n].string; + return encoding_groups_table[n]; } const char * @@ -150,7 +144,7 @@ mozilla_encoding_groups_table_peek_nth_translated (guint n) { g_return_val_if_fail (n < mozilla_encoding_groups_table_get_count (), NULL); - return gettext (encoding_groups_table[n].string); + return gettext (encoding_groups_table[n]); } const char * @@ -181,7 +175,7 @@ mozilla_encoding_table_peek_nth (guint n) { g_return_val_if_fail (n < mozilla_encoding_table_get_count (), NULL); - return encoding_table[n].string; + return encoding_table[n]; } const char * @@ -189,7 +183,7 @@ mozilla_encoding_table_peek_nth_translated (guint n) { g_return_val_if_fail (n < mozilla_encoding_table_get_count (), NULL); - return gettext (encoding_table[n].string); + return gettext (encoding_table[n]); } const char * diff --git a/libnautilus-extensions/nautilus-art-extensions.c b/libnautilus-extensions/nautilus-art-extensions.c index 41c975797..db938b5ff 100644 --- a/libnautilus-extensions/nautilus-art-extensions.c +++ b/libnautilus-extensions/nautilus-art-extensions.c @@ -109,6 +109,12 @@ nautilus_art_drect_equal (const ArtDRect *rect_a, && rect_a->y1 == rect_b->y1; } +gboolean +nautilus_art_irect_is_valid (const ArtIRect *rect) +{ + return rect && !art_irect_empty (rect); +} + void nautilus_art_irect_assign (ArtIRect *rect, int x, @@ -271,6 +277,14 @@ nautilus_self_check_art_extensions (void) NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_equal (&one, &two), TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_equal (&one, &empty_rect), FALSE); + /* nautilus_art_irect_is_valid */ + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (NULL), FALSE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&empty_rect), FALSE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&one), TRUE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&two), TRUE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&inside), TRUE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&outside), TRUE); + /* nautilus_art_irect_hits_irect */ NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_hits_irect (&one, &two), TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_hits_irect (&one, &inside), TRUE); diff --git a/libnautilus-extensions/nautilus-art-extensions.h b/libnautilus-extensions/nautilus-art-extensions.h index e5838e6fd..e5b27ad95 100644 --- a/libnautilus-extensions/nautilus-art-extensions.h +++ b/libnautilus-extensions/nautilus-art-extensions.h @@ -58,6 +58,7 @@ gboolean nautilus_art_irect_contains_irect (const ArtIRect *outer_r gboolean nautilus_art_irect_contains_point (const ArtIRect *outer_rect, int x, int y); +gboolean nautilus_art_irect_is_valid (const ArtIRect *rect); void nautilus_art_irect_assign (ArtIRect *rect, int x, int y, diff --git a/libnautilus-extensions/nautilus-glyph.c b/libnautilus-extensions/nautilus-glyph.c index b913a9c52..a3ea72a3b 100644 --- a/libnautilus-extensions/nautilus-glyph.c +++ b/libnautilus-extensions/nautilus-glyph.c @@ -33,9 +33,14 @@ #include <libart_lgpl/art_misc.h> #include <libart_lgpl/art_affine.h> - +#include <libart_lgpl/art_rgb.h> +#include <librsvg/art_rgba.h> #include <librsvg/rsvg-ft.h> +static gboolean glyph_is_valid (const NautilusGlyph *glyph); +static int glyph_get_width_space_safe (const NautilusGlyph *glyph); +static int glyph_get_height_space_safe (const NautilusGlyph *glyph); + /* Detail member struct */ struct NautilusGlyph { @@ -54,16 +59,17 @@ struct NautilusGlyph */ NautilusGlyph * nautilus_glyph_new (const NautilusScalableFont *font, - guint font_size, + int font_size, const char *text, - guint text_length) + int text_length) { NautilusGlyph *glyph; RsvgFTGlyph *rsvg_glyph; const double affine[6] = { 1, 0, 0, 1, 0, 0 }; int glyph_xy[2]; - + g_return_val_if_fail (NAUTILUS_IS_SCALABLE_FONT (font), NULL); + g_return_val_if_fail (font_size > 0, NULL); g_return_val_if_fail (text != NULL, NULL); g_return_val_if_fail (text[0] != '\0', NULL); @@ -75,11 +81,9 @@ nautilus_glyph_new (const NautilusScalableFont *font, font_size, affine, glyph_xy); - g_return_val_if_fail (rsvg_glyph != NULL, NULL); - - glyph = g_new0 (NautilusGlyph, 1); + glyph = g_new0 (NautilusGlyph, 1); glyph->rsvg_glyph = rsvg_glyph; glyph->glyph_xy[0] = glyph_xy[0]; glyph->glyph_xy[1] = glyph_xy[1]; @@ -102,6 +106,34 @@ nautilus_glyph_free (NautilusGlyph *glyph) g_free (glyph); } +static int +glyph_get_width_space_safe (const NautilusGlyph *glyph) +{ + g_return_val_if_fail (glyph != NULL, 0); + g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); + + /* Check for the case when we have only spaces. */ + if (glyph->rsvg_glyph->width == 0 && glyph->rsvg_glyph->xpen > 0.0) { + return (int) glyph->rsvg_glyph->xpen; + } + + return glyph->rsvg_glyph->width; +} + +static int +glyph_get_height_space_safe (const NautilusGlyph *glyph) +{ + g_return_val_if_fail (glyph != NULL, 0); + g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); + + /* Check for the case when we have only spaces. */ + if (glyph->rsvg_glyph->width == 0 && glyph->rsvg_glyph->xpen > 0.0) { + return 1; + } + + return glyph->rsvg_glyph->height; +} + /** * nautilus_glyph_get_width: * @glyph: A NautilusGlyph. @@ -111,10 +143,9 @@ nautilus_glyph_free (NautilusGlyph *glyph) int nautilus_glyph_get_width (const NautilusGlyph *glyph) { - g_return_val_if_fail (glyph != NULL, 0); - g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); - - return glyph->rsvg_glyph->width; + g_return_val_if_fail (glyph_is_valid (glyph), 0); + + return glyph_get_width_space_safe (glyph); } /** @@ -126,10 +157,9 @@ nautilus_glyph_get_width (const NautilusGlyph *glyph) int nautilus_glyph_get_height (const NautilusGlyph *glyph) { - g_return_val_if_fail (glyph != NULL, 0); - g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); + g_return_val_if_fail (glyph_is_valid (glyph), 0); - return glyph->rsvg_glyph->height; + return glyph_get_height_space_safe (glyph); } /** @@ -144,44 +174,22 @@ nautilus_glyph_get_dimensions (const NautilusGlyph *glyph) NautilusDimensions glyph_dimensions; g_return_val_if_fail (glyph != NULL, NAUTILUS_DIMENSIONS_EMPTY); - g_return_val_if_fail (glyph->rsvg_glyph != NULL, NAUTILUS_DIMENSIONS_EMPTY); + g_return_val_if_fail (glyph_is_valid (glyph), NAUTILUS_DIMENSIONS_EMPTY); - glyph_dimensions.width = glyph->rsvg_glyph->width; - glyph_dimensions.height = glyph->rsvg_glyph->height; + glyph_dimensions.width = glyph_get_width_space_safe (glyph); + glyph_dimensions.height = glyph_get_height_space_safe (glyph); return glyph_dimensions; } -/* FIXME bugzilla.eazel.com xxxx: We should really use libart - * over here to do the alpha compositing. The reason why - * im not doing so is because of the currently confusing - * location of libart stable/HEAD headers for some rgba functions. - * It not hard to figure that out, Ill do so soon. For now this - * code works, even if not super optimized like the libart blending - * code. - */ -static void -color_blend_with_opacity (guchar background_r, - guchar background_g, - guchar background_b, - guchar foreground_r, - guchar foreground_g, - guchar foreground_b, - int opacity, - guchar *blend_r_out, - guchar *blend_g_out, - guchar *blend_b_out) +/* A glyph is valid if IT and the RsvgGlyph it wraps area not NULL */ +static gboolean +glyph_is_valid (const NautilusGlyph *glyph) { - g_return_if_fail (opacity > NAUTILUS_OPACITY_FULLY_TRANSPARENT); - g_return_if_fail (opacity < NAUTILUS_OPACITY_FULLY_OPAQUE); - g_return_if_fail (blend_r_out != NULL); - g_return_if_fail (blend_g_out != NULL); - g_return_if_fail (blend_b_out != NULL); - - /* This blending operation is the same as that in libart */ - *blend_r_out = background_r + (((foreground_r - background_r) * opacity + 0x80) >> 8); - *blend_g_out = background_g + (((foreground_g - background_g) * opacity + 0x80) >> 8); - *blend_b_out = background_b + (((foreground_b - background_b) * opacity + 0x80) >> 8); + return glyph != NULL + && glyph->rsvg_glyph != NULL + && glyph_get_width_space_safe (glyph) > 0 + && glyph_get_height_space_safe (glyph) > 0; } /** @@ -229,26 +237,28 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, const guchar foreground_g = NAUTILUS_RGBA_COLOR_GET_G (color); const guchar foreground_b = NAUTILUS_RGBA_COLOR_GET_B (color); - g_return_if_fail (glyph != NULL); - g_return_if_fail (glyph->rsvg_glyph != NULL); - g_return_if_fail (glyph->rsvg_glyph->buf != NULL); - g_return_if_fail (glyph->rsvg_glyph->width > 0); - g_return_if_fail (glyph->rsvg_glyph->height > 0); - g_return_if_fail (glyph->rsvg_glyph->rowstride > 0); g_return_if_fail (nautilus_gdk_pixbuf_is_valid (pixbuf)); - g_return_if_fail (destination_x >= 0 && destination_x < gdk_pixbuf_get_width (pixbuf)); - g_return_if_fail (destination_y >= 0 && destination_y < gdk_pixbuf_get_height (pixbuf)); + g_return_if_fail (glyph_is_valid (glyph)); + /* FIXME bugzilla.eazel.com xxxx: We currently dont handle opacities * other than 0xFF. */ g_return_if_fail (opacity == NAUTILUS_OPACITY_FULLY_OPAQUE); + /* Check for just spaces */ + if (glyph->rsvg_glyph->buf == NULL || glyph->rsvg_glyph->rowstride <= 0) { + return; + } + /* Clip the pixbuf to the clip area; bail if no work */ target = nautilus_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area); if (art_irect_empty (&target)) { return; } - + + g_return_if_fail (glyph->rsvg_glyph->buf != NULL); + g_return_if_fail (glyph->rsvg_glyph->rowstride > 0); + glyph_dimensions = nautilus_glyph_get_dimensions (glyph); glyph_rowstride = glyph->rsvg_glyph->rowstride; glyph_buffer = glyph->rsvg_glyph->buf; @@ -275,37 +285,6 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, return; } - /* Debug code to be yanked real soon */ - if (0) nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, - FALSE, - target.x0, - target.y0, - target.x1, - target.y1, - NAUTILUS_RGBA_COLOR_OPAQUE_GREEN, - NAUTILUS_OPACITY_FULLY_OPAQUE, - 0); - - if (0) nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, - FALSE, - glyph_bounds.x0, - glyph_bounds.y0, - glyph_bounds.x1, - glyph_bounds.y1, - NAUTILUS_RGBA_COLOR_OPAQUE_BLUE, - NAUTILUS_OPACITY_FULLY_OPAQUE, - 0); - - if (0) nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, - FALSE, - render_area.x0, - render_area.y0, - render_area.x1, - render_area.y1, - NAUTILUS_RGBA_COLOR_OPAQUE_RED, - NAUTILUS_OPACITY_FULLY_OPAQUE, - -1); - /* Compute the offset into the pixbuf where we want to render. */ pixbuf_y_offset = pixbuf_pixels @@ -336,6 +315,7 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, + (glyph_top_skip * glyph_rowstride) + glyph_left_skip; + /* Thanks to the careful clipping above, the iterations below * should always be within the bounds of both the pixbuf's pixels * and the glyph's buffer. @@ -361,39 +341,21 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, /* If the opacity is not fully opaque or fully transparent, * we need to to alpha blending. */ - - /* FIXME bugzilla.eazel.com xxxx: We should really use libart - * over here to do the alpha compositing. The reason why - * im not doing so is because of the currently confusing - * location of libart stable/HEAD headers for some rgba functions. - * It not hard to figure that out, Ill do so soon. For now this - * code works, even if not super optimized like the libart blending - * code. - */ } else if (point_opacity != NAUTILUS_OPACITY_FULLY_TRANSPARENT) { - const guchar background_r = *(pixbuf_x_offset + 0); - const guchar background_g = *(pixbuf_x_offset + 1); - const guchar background_b = *(pixbuf_x_offset + 2); - guchar blend_r; - guchar blend_g; - guchar blend_b; - - color_blend_with_opacity (background_r, - background_g, - background_b, - foreground_r, - foreground_g, - foreground_b, - point_opacity, - &blend_r, - &blend_g, - &blend_b); - - *(pixbuf_x_offset + 0) = blend_r; - *(pixbuf_x_offset + 1) = blend_g; - *(pixbuf_x_offset + 2) = blend_b; if (pixbuf_has_alpha) { - *(pixbuf_x_offset + 3) = NAUTILUS_OPACITY_FULLY_OPAQUE; + art_rgba_run_alpha (pixbuf_x_offset, + foreground_r, + foreground_g, + foreground_b, + point_opacity, + 1); + } else { + art_rgb_run_alpha (pixbuf_x_offset, + foreground_r, + foreground_g, + foreground_b, + point_opacity, + 1); } } @@ -411,3 +373,37 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, glyph_y_offset += glyph_rowstride; } } + +ArtIRect +nautilus_glyph_intersect (const NautilusGlyph *glyph, + int glyph_x, + int glyph_y, + const ArtIRect *rectangle) +{ + ArtIRect intersection; + ArtIRect bounds; + NautilusDimensions dimensions; + + g_return_val_if_fail (glyph_is_valid (glyph), NAUTILUS_ART_IRECT_EMPTY); + + dimensions = nautilus_glyph_get_dimensions (glyph); + bounds = nautilus_art_irect_assign_dimensions (glyph_x, glyph_y, &dimensions); + + if (rectangle == NULL) { + return bounds; + } + + art_irect_intersect (&intersection, rectangle, &bounds); + + /* In theory, this is not needed because a rectangle is empty + * regardless of how MUCH negative the dimensions are. + * However, to make debugging and self checks simpler, we + * consistenly return a standard empty rectangle. + */ + if (art_irect_empty (&intersection)) { + return NAUTILUS_ART_IRECT_EMPTY; + } + + return intersection; +} + diff --git a/libnautilus-extensions/nautilus-glyph.h b/libnautilus-extensions/nautilus-glyph.h index ab942897b..c199a0e9d 100644 --- a/libnautilus-extensions/nautilus-glyph.h +++ b/libnautilus-extensions/nautilus-glyph.h @@ -36,9 +36,9 @@ BEGIN_GNOME_DECLS typedef struct NautilusGlyph NautilusGlyph; NautilusGlyph * nautilus_glyph_new (const NautilusScalableFont *font, - guint font_size, + int font_size, const char *text, - guint text_length); + int text_length); void nautilus_glyph_free (NautilusGlyph *glyph); int nautilus_glyph_get_width (const NautilusGlyph *glyph); int nautilus_glyph_get_height (const NautilusGlyph *glyph); @@ -50,6 +50,10 @@ void nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *gl const ArtIRect *clip_area, guint32 color, int opacity); +ArtIRect nautilus_glyph_intersect (const NautilusGlyph *glyph, + int glyph_x, + int glyph_y, + const ArtIRect *rectangle); END_GNOME_DECLS diff --git a/libnautilus-private/nautilus-art-extensions.c b/libnautilus-private/nautilus-art-extensions.c index 41c975797..db938b5ff 100644 --- a/libnautilus-private/nautilus-art-extensions.c +++ b/libnautilus-private/nautilus-art-extensions.c @@ -109,6 +109,12 @@ nautilus_art_drect_equal (const ArtDRect *rect_a, && rect_a->y1 == rect_b->y1; } +gboolean +nautilus_art_irect_is_valid (const ArtIRect *rect) +{ + return rect && !art_irect_empty (rect); +} + void nautilus_art_irect_assign (ArtIRect *rect, int x, @@ -271,6 +277,14 @@ nautilus_self_check_art_extensions (void) NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_equal (&one, &two), TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_equal (&one, &empty_rect), FALSE); + /* nautilus_art_irect_is_valid */ + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (NULL), FALSE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&empty_rect), FALSE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&one), TRUE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&two), TRUE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&inside), TRUE); + NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_is_valid (&outside), TRUE); + /* nautilus_art_irect_hits_irect */ NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_hits_irect (&one, &two), TRUE); NAUTILUS_CHECK_BOOLEAN_RESULT (nautilus_art_irect_hits_irect (&one, &inside), TRUE); diff --git a/libnautilus-private/nautilus-art-extensions.h b/libnautilus-private/nautilus-art-extensions.h index e5838e6fd..e5b27ad95 100644 --- a/libnautilus-private/nautilus-art-extensions.h +++ b/libnautilus-private/nautilus-art-extensions.h @@ -58,6 +58,7 @@ gboolean nautilus_art_irect_contains_irect (const ArtIRect *outer_r gboolean nautilus_art_irect_contains_point (const ArtIRect *outer_rect, int x, int y); +gboolean nautilus_art_irect_is_valid (const ArtIRect *rect); void nautilus_art_irect_assign (ArtIRect *rect, int x, int y, diff --git a/libnautilus-private/nautilus-glyph.c b/libnautilus-private/nautilus-glyph.c index b913a9c52..a3ea72a3b 100644 --- a/libnautilus-private/nautilus-glyph.c +++ b/libnautilus-private/nautilus-glyph.c @@ -33,9 +33,14 @@ #include <libart_lgpl/art_misc.h> #include <libart_lgpl/art_affine.h> - +#include <libart_lgpl/art_rgb.h> +#include <librsvg/art_rgba.h> #include <librsvg/rsvg-ft.h> +static gboolean glyph_is_valid (const NautilusGlyph *glyph); +static int glyph_get_width_space_safe (const NautilusGlyph *glyph); +static int glyph_get_height_space_safe (const NautilusGlyph *glyph); + /* Detail member struct */ struct NautilusGlyph { @@ -54,16 +59,17 @@ struct NautilusGlyph */ NautilusGlyph * nautilus_glyph_new (const NautilusScalableFont *font, - guint font_size, + int font_size, const char *text, - guint text_length) + int text_length) { NautilusGlyph *glyph; RsvgFTGlyph *rsvg_glyph; const double affine[6] = { 1, 0, 0, 1, 0, 0 }; int glyph_xy[2]; - + g_return_val_if_fail (NAUTILUS_IS_SCALABLE_FONT (font), NULL); + g_return_val_if_fail (font_size > 0, NULL); g_return_val_if_fail (text != NULL, NULL); g_return_val_if_fail (text[0] != '\0', NULL); @@ -75,11 +81,9 @@ nautilus_glyph_new (const NautilusScalableFont *font, font_size, affine, glyph_xy); - g_return_val_if_fail (rsvg_glyph != NULL, NULL); - - glyph = g_new0 (NautilusGlyph, 1); + glyph = g_new0 (NautilusGlyph, 1); glyph->rsvg_glyph = rsvg_glyph; glyph->glyph_xy[0] = glyph_xy[0]; glyph->glyph_xy[1] = glyph_xy[1]; @@ -102,6 +106,34 @@ nautilus_glyph_free (NautilusGlyph *glyph) g_free (glyph); } +static int +glyph_get_width_space_safe (const NautilusGlyph *glyph) +{ + g_return_val_if_fail (glyph != NULL, 0); + g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); + + /* Check for the case when we have only spaces. */ + if (glyph->rsvg_glyph->width == 0 && glyph->rsvg_glyph->xpen > 0.0) { + return (int) glyph->rsvg_glyph->xpen; + } + + return glyph->rsvg_glyph->width; +} + +static int +glyph_get_height_space_safe (const NautilusGlyph *glyph) +{ + g_return_val_if_fail (glyph != NULL, 0); + g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); + + /* Check for the case when we have only spaces. */ + if (glyph->rsvg_glyph->width == 0 && glyph->rsvg_glyph->xpen > 0.0) { + return 1; + } + + return glyph->rsvg_glyph->height; +} + /** * nautilus_glyph_get_width: * @glyph: A NautilusGlyph. @@ -111,10 +143,9 @@ nautilus_glyph_free (NautilusGlyph *glyph) int nautilus_glyph_get_width (const NautilusGlyph *glyph) { - g_return_val_if_fail (glyph != NULL, 0); - g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); - - return glyph->rsvg_glyph->width; + g_return_val_if_fail (glyph_is_valid (glyph), 0); + + return glyph_get_width_space_safe (glyph); } /** @@ -126,10 +157,9 @@ nautilus_glyph_get_width (const NautilusGlyph *glyph) int nautilus_glyph_get_height (const NautilusGlyph *glyph) { - g_return_val_if_fail (glyph != NULL, 0); - g_return_val_if_fail (glyph->rsvg_glyph != NULL, 0); + g_return_val_if_fail (glyph_is_valid (glyph), 0); - return glyph->rsvg_glyph->height; + return glyph_get_height_space_safe (glyph); } /** @@ -144,44 +174,22 @@ nautilus_glyph_get_dimensions (const NautilusGlyph *glyph) NautilusDimensions glyph_dimensions; g_return_val_if_fail (glyph != NULL, NAUTILUS_DIMENSIONS_EMPTY); - g_return_val_if_fail (glyph->rsvg_glyph != NULL, NAUTILUS_DIMENSIONS_EMPTY); + g_return_val_if_fail (glyph_is_valid (glyph), NAUTILUS_DIMENSIONS_EMPTY); - glyph_dimensions.width = glyph->rsvg_glyph->width; - glyph_dimensions.height = glyph->rsvg_glyph->height; + glyph_dimensions.width = glyph_get_width_space_safe (glyph); + glyph_dimensions.height = glyph_get_height_space_safe (glyph); return glyph_dimensions; } -/* FIXME bugzilla.eazel.com xxxx: We should really use libart - * over here to do the alpha compositing. The reason why - * im not doing so is because of the currently confusing - * location of libart stable/HEAD headers for some rgba functions. - * It not hard to figure that out, Ill do so soon. For now this - * code works, even if not super optimized like the libart blending - * code. - */ -static void -color_blend_with_opacity (guchar background_r, - guchar background_g, - guchar background_b, - guchar foreground_r, - guchar foreground_g, - guchar foreground_b, - int opacity, - guchar *blend_r_out, - guchar *blend_g_out, - guchar *blend_b_out) +/* A glyph is valid if IT and the RsvgGlyph it wraps area not NULL */ +static gboolean +glyph_is_valid (const NautilusGlyph *glyph) { - g_return_if_fail (opacity > NAUTILUS_OPACITY_FULLY_TRANSPARENT); - g_return_if_fail (opacity < NAUTILUS_OPACITY_FULLY_OPAQUE); - g_return_if_fail (blend_r_out != NULL); - g_return_if_fail (blend_g_out != NULL); - g_return_if_fail (blend_b_out != NULL); - - /* This blending operation is the same as that in libart */ - *blend_r_out = background_r + (((foreground_r - background_r) * opacity + 0x80) >> 8); - *blend_g_out = background_g + (((foreground_g - background_g) * opacity + 0x80) >> 8); - *blend_b_out = background_b + (((foreground_b - background_b) * opacity + 0x80) >> 8); + return glyph != NULL + && glyph->rsvg_glyph != NULL + && glyph_get_width_space_safe (glyph) > 0 + && glyph_get_height_space_safe (glyph) > 0; } /** @@ -229,26 +237,28 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, const guchar foreground_g = NAUTILUS_RGBA_COLOR_GET_G (color); const guchar foreground_b = NAUTILUS_RGBA_COLOR_GET_B (color); - g_return_if_fail (glyph != NULL); - g_return_if_fail (glyph->rsvg_glyph != NULL); - g_return_if_fail (glyph->rsvg_glyph->buf != NULL); - g_return_if_fail (glyph->rsvg_glyph->width > 0); - g_return_if_fail (glyph->rsvg_glyph->height > 0); - g_return_if_fail (glyph->rsvg_glyph->rowstride > 0); g_return_if_fail (nautilus_gdk_pixbuf_is_valid (pixbuf)); - g_return_if_fail (destination_x >= 0 && destination_x < gdk_pixbuf_get_width (pixbuf)); - g_return_if_fail (destination_y >= 0 && destination_y < gdk_pixbuf_get_height (pixbuf)); + g_return_if_fail (glyph_is_valid (glyph)); + /* FIXME bugzilla.eazel.com xxxx: We currently dont handle opacities * other than 0xFF. */ g_return_if_fail (opacity == NAUTILUS_OPACITY_FULLY_OPAQUE); + /* Check for just spaces */ + if (glyph->rsvg_glyph->buf == NULL || glyph->rsvg_glyph->rowstride <= 0) { + return; + } + /* Clip the pixbuf to the clip area; bail if no work */ target = nautilus_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area); if (art_irect_empty (&target)) { return; } - + + g_return_if_fail (glyph->rsvg_glyph->buf != NULL); + g_return_if_fail (glyph->rsvg_glyph->rowstride > 0); + glyph_dimensions = nautilus_glyph_get_dimensions (glyph); glyph_rowstride = glyph->rsvg_glyph->rowstride; glyph_buffer = glyph->rsvg_glyph->buf; @@ -275,37 +285,6 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, return; } - /* Debug code to be yanked real soon */ - if (0) nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, - FALSE, - target.x0, - target.y0, - target.x1, - target.y1, - NAUTILUS_RGBA_COLOR_OPAQUE_GREEN, - NAUTILUS_OPACITY_FULLY_OPAQUE, - 0); - - if (0) nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, - FALSE, - glyph_bounds.x0, - glyph_bounds.y0, - glyph_bounds.x1, - glyph_bounds.y1, - NAUTILUS_RGBA_COLOR_OPAQUE_BLUE, - NAUTILUS_OPACITY_FULLY_OPAQUE, - 0); - - if (0) nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, - FALSE, - render_area.x0, - render_area.y0, - render_area.x1, - render_area.y1, - NAUTILUS_RGBA_COLOR_OPAQUE_RED, - NAUTILUS_OPACITY_FULLY_OPAQUE, - -1); - /* Compute the offset into the pixbuf where we want to render. */ pixbuf_y_offset = pixbuf_pixels @@ -336,6 +315,7 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, + (glyph_top_skip * glyph_rowstride) + glyph_left_skip; + /* Thanks to the careful clipping above, the iterations below * should always be within the bounds of both the pixbuf's pixels * and the glyph's buffer. @@ -361,39 +341,21 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, /* If the opacity is not fully opaque or fully transparent, * we need to to alpha blending. */ - - /* FIXME bugzilla.eazel.com xxxx: We should really use libart - * over here to do the alpha compositing. The reason why - * im not doing so is because of the currently confusing - * location of libart stable/HEAD headers for some rgba functions. - * It not hard to figure that out, Ill do so soon. For now this - * code works, even if not super optimized like the libart blending - * code. - */ } else if (point_opacity != NAUTILUS_OPACITY_FULLY_TRANSPARENT) { - const guchar background_r = *(pixbuf_x_offset + 0); - const guchar background_g = *(pixbuf_x_offset + 1); - const guchar background_b = *(pixbuf_x_offset + 2); - guchar blend_r; - guchar blend_g; - guchar blend_b; - - color_blend_with_opacity (background_r, - background_g, - background_b, - foreground_r, - foreground_g, - foreground_b, - point_opacity, - &blend_r, - &blend_g, - &blend_b); - - *(pixbuf_x_offset + 0) = blend_r; - *(pixbuf_x_offset + 1) = blend_g; - *(pixbuf_x_offset + 2) = blend_b; if (pixbuf_has_alpha) { - *(pixbuf_x_offset + 3) = NAUTILUS_OPACITY_FULLY_OPAQUE; + art_rgba_run_alpha (pixbuf_x_offset, + foreground_r, + foreground_g, + foreground_b, + point_opacity, + 1); + } else { + art_rgb_run_alpha (pixbuf_x_offset, + foreground_r, + foreground_g, + foreground_b, + point_opacity, + 1); } } @@ -411,3 +373,37 @@ nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *glyph, glyph_y_offset += glyph_rowstride; } } + +ArtIRect +nautilus_glyph_intersect (const NautilusGlyph *glyph, + int glyph_x, + int glyph_y, + const ArtIRect *rectangle) +{ + ArtIRect intersection; + ArtIRect bounds; + NautilusDimensions dimensions; + + g_return_val_if_fail (glyph_is_valid (glyph), NAUTILUS_ART_IRECT_EMPTY); + + dimensions = nautilus_glyph_get_dimensions (glyph); + bounds = nautilus_art_irect_assign_dimensions (glyph_x, glyph_y, &dimensions); + + if (rectangle == NULL) { + return bounds; + } + + art_irect_intersect (&intersection, rectangle, &bounds); + + /* In theory, this is not needed because a rectangle is empty + * regardless of how MUCH negative the dimensions are. + * However, to make debugging and self checks simpler, we + * consistenly return a standard empty rectangle. + */ + if (art_irect_empty (&intersection)) { + return NAUTILUS_ART_IRECT_EMPTY; + } + + return intersection; +} + diff --git a/libnautilus-private/nautilus-glyph.h b/libnautilus-private/nautilus-glyph.h index ab942897b..c199a0e9d 100644 --- a/libnautilus-private/nautilus-glyph.h +++ b/libnautilus-private/nautilus-glyph.h @@ -36,9 +36,9 @@ BEGIN_GNOME_DECLS typedef struct NautilusGlyph NautilusGlyph; NautilusGlyph * nautilus_glyph_new (const NautilusScalableFont *font, - guint font_size, + int font_size, const char *text, - guint text_length); + int text_length); void nautilus_glyph_free (NautilusGlyph *glyph); int nautilus_glyph_get_width (const NautilusGlyph *glyph); int nautilus_glyph_get_height (const NautilusGlyph *glyph); @@ -50,6 +50,10 @@ void nautilus_glyph_draw_to_pixbuf (const NautilusGlyph *gl const ArtIRect *clip_area, guint32 color, int opacity); +ArtIRect nautilus_glyph_intersect (const NautilusGlyph *glyph, + int glyph_x, + int glyph_y, + const ArtIRect *rectangle); END_GNOME_DECLS diff --git a/test/test-nautilus-glyph-simple.c b/test/test-nautilus-glyph-simple.c index 3b00261fc..e32f2c12a 100644 --- a/test/test-nautilus-glyph-simple.c +++ b/test/test-nautilus-glyph-simple.c @@ -33,6 +33,7 @@ main (int argc, char* argv[]) GdkPixbuf *pixbuf; NautilusScalableFont *font; ArtIRect clip_area; + ArtIRect dest_area; NautilusGlyph *glyph; const guint font_size = 60; const int opacity = NAUTILUS_OPACITY_FULLY_OPAQUE; @@ -73,9 +74,23 @@ main (int argc, char* argv[]) NAUTILUS_OPACITY_FULLY_OPAQUE); glyph = glyph_new (text, font_size); - + + nautilus_art_irect_assign (&dest_area, + 50, + 200, + 1000, + 1000); + nautilus_glyph_draw_to_pixbuf (glyph, pixbuf, + 100, + 0, + &dest_area, + NAUTILUS_RGBA_COLOR_OPAQUE_BLUE, + opacity); + + if (0) nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, 30, 40, NULL, //&clip_area, diff --git a/test/test-nautilus-glyph.c b/test/test-nautilus-glyph.c index 4f159485d..c8016b4a9 100644 --- a/test/test-nautilus-glyph.c +++ b/test/test-nautilus-glyph.c @@ -6,7 +6,8 @@ #include <libnautilus-extensions/nautilus-glyph.h> static NautilusGlyph * -glyph_new (const char *text, int font_size) +glyph_new (const char *text, + int font_size) { NautilusScalableFont *font; NautilusGlyph *glyph; @@ -20,28 +21,31 @@ glyph_new (const char *text, int font_size) g_return_val_if_fail (font != NULL, NULL); glyph = nautilus_glyph_new (font, font_size, text, strlen (text)); - g_return_val_if_fail (glyph != NULL, NULL); - gtk_object_unref (GTK_OBJECT (font)); + g_return_val_if_fail (glyph != NULL, NULL); + return glyph; } int main (int argc, char* argv[]) { - GdkPixbuf *pixbuf; - NautilusScalableFont *font; - guint i; - int x; - int y; - const guint pixbuf_width = 640; const guint pixbuf_height = 480; - const guint num_glyphs = 1; - const gboolean has_alpha = TRUE; + const gboolean has_alpha = FALSE; const guint32 background_color = NAUTILUS_RGB_COLOR_WHITE; const char text[] = "Something"; + const gboolean solid_background = FALSE; + const guint font_size = 100; + const int opacity = NAUTILUS_OPACITY_FULLY_OPAQUE; + + GdkPixbuf *pixbuf; + NautilusScalableFont *font; + int x; + int y; + ArtIRect clip_area; + NautilusGlyph *glyph; test_init (&argc, &argv); @@ -51,7 +55,7 @@ main (int argc, char* argv[]) pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, pixbuf_width, pixbuf_height); g_assert (pixbuf != NULL); - if (0) { + if (solid_background) { nautilus_debug_pixbuf_draw_rectangle (pixbuf, TRUE, -1, -1, -1, -1, @@ -67,50 +71,262 @@ main (int argc, char* argv[]) x = 10; y = 50; - for (i = 0; i < num_glyphs; i++) { - ArtIRect clip_area; - NautilusGlyph *glyph; - - const guint font_size = 100; - const int opacity = NAUTILUS_OPACITY_FULLY_OPAQUE; - - nautilus_art_irect_assign (&clip_area, - 50, - 30, - 200, - 80); - + nautilus_art_irect_assign (&clip_area, + 50, + 30, + 200, + 80); + + glyph = glyph_new (text, font_size); + + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + x, + y, + NULL, + NAUTILUS_RGBA_COLOR_OPAQUE_BLUE, + opacity); + + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + -200, + y + 3 * font_size, + NULL, + NAUTILUS_RGBA_COLOR_OPAQUE_BLUE, + opacity); + + if (solid_background) { nautilus_debug_pixbuf_draw_rectangle (pixbuf, - FALSE, + TRUE, clip_area.x0, clip_area.y0, clip_area.x1, clip_area.y1, - NAUTILUS_RGBA_COLOR_OPAQUE_GREEN, + background_color, NAUTILUS_OPACITY_FULLY_OPAQUE); + } else { + test_pixbuf_draw_rectangle_tiled (pixbuf, + "patterns/brushed_metal.png", + clip_area.x0, + clip_area.y0, + clip_area.x1, + clip_area.y1, + NAUTILUS_OPACITY_FULLY_OPAQUE); + } + + if (1) nautilus_debug_pixbuf_draw_rectangle (pixbuf, + FALSE, + clip_area.x0 - 1, + clip_area.y0 - 1, + clip_area.x1 + 1, + clip_area.y1 + 1, + NAUTILUS_RGBA_COLOR_OPAQUE_GREEN, + NAUTILUS_OPACITY_FULLY_OPAQUE); + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + x, + y, + &clip_area, + NAUTILUS_RGBA_COLOR_OPAQUE_RED, + opacity); + + nautilus_glyph_free (glyph); + + nautilus_art_irect_assign (&clip_area, + 50, + 100 + font_size + 4, + 200, + 80); + + if (1) nautilus_scalable_font_draw_text (font, + pixbuf, + x, + y + font_size + 4, + NULL, + font_size, + text, + strlen (text), + NAUTILUS_RGBA_COLOR_OPAQUE_BLUE, + opacity); + + if (solid_background) { + nautilus_debug_pixbuf_draw_rectangle (pixbuf, + TRUE, + clip_area.x0, + clip_area.y0, + clip_area.x1, + clip_area.y1, + background_color, + NAUTILUS_OPACITY_FULLY_OPAQUE); + } else { + test_pixbuf_draw_rectangle_tiled (pixbuf, + "patterns/brushed_metal.png", + clip_area.x0, + clip_area.y0, + clip_area.x1, + clip_area.y1, + NAUTILUS_OPACITY_FULLY_OPAQUE); + } + + if (1) nautilus_debug_pixbuf_draw_rectangle (pixbuf, + FALSE, + clip_area.x0 - 1, + clip_area.y0 - 1, + clip_area.x1 + 1, + clip_area.y1 + 1, + NAUTILUS_RGBA_COLOR_OPAQUE_GREEN, + NAUTILUS_OPACITY_FULLY_OPAQUE); + if (1) nautilus_scalable_font_draw_text (font, + pixbuf, + x, + y + font_size + 4, + &clip_area, + font_size, + text, + strlen (text), + NAUTILUS_RGBA_COLOR_OPAQUE_RED, + opacity); + + { + const int glyph_x = 400; + const int glyph_y = 300; + ArtIRect glyph_rect; + glyph = glyph_new ("x", 50); - glyph = glyph_new (text, font_size); + glyph_rect = nautilus_glyph_intersect (glyph, glyph_x, glyph_y, NULL); + + nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, + FALSE, + glyph_rect.x0, + glyph_rect.y0, + glyph_rect.x1, + glyph_rect.y1, + 0xeebbaa, + 0xff, + -1); + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + glyph_x, + glyph_y, + NULL, + 0x0, + 0xff); + + nautilus_glyph_free (glyph); + } + + { + const int glyph_x = 400; + const int glyph_y = 350; + ArtIRect glyph_rect; + glyph = glyph_new ("x y", 50); - nautilus_glyph_draw_to_pixbuf (glyph, - pixbuf, - x, - y, - &clip_area,//NULL, - NAUTILUS_RGBA_COLOR_OPAQUE_RED, - opacity); + glyph_rect = nautilus_glyph_intersect (glyph, glyph_x, glyph_y, NULL); + + nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, + FALSE, + glyph_rect.x0, + glyph_rect.y0, + glyph_rect.x1, + glyph_rect.y1, + 0xeebbaa, + 0xff, + -1); + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + glyph_x, + glyph_y, + NULL, + 0x0, + 0xff); + + nautilus_glyph_free (glyph); + } + + { + const int glyph_x = 400; + const int glyph_y = 400; + ArtIRect glyph_rect; + glyph = glyph_new (" ", 50); + + glyph_rect = nautilus_glyph_intersect (glyph, glyph_x, glyph_y, NULL); + + nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, + FALSE, + glyph_rect.x0, + glyph_rect.y0, + glyph_rect.x1, + glyph_rect.y1, + 0xeebbaa, + 0xff, + -1); + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + glyph_x, + glyph_y, + NULL, + 0x0, + 0xff); + + nautilus_glyph_free (glyph); + } + + { + const int glyph_x = 400; + const int glyph_y = 420; + ArtIRect glyph_rect; + glyph = glyph_new (" ", 50); + glyph_rect = nautilus_glyph_intersect (glyph, glyph_x, glyph_y, NULL); + + nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, + FALSE, + glyph_rect.x0, + glyph_rect.y0, + glyph_rect.x1, + glyph_rect.y1, + 0xeebbaa, + 0xff, + -1); + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + glyph_x, + glyph_y, + NULL, + 0x0, + 0xff); + nautilus_glyph_free (glyph); + } + + + /* This should not work. A "" glyph is invalid */ + if (0) { + const int glyph_x = 400; + const int glyph_y = 450; + ArtIRect glyph_rect; + glyph = glyph_new ("", 50); - nautilus_scalable_font_draw_text (font, - pixbuf, - x, - y + font_size + 4, - NULL, - font_size, - text, - strlen (text), - NAUTILUS_RGBA_COLOR_OPAQUE_RED, - opacity); + glyph_rect = nautilus_glyph_intersect (glyph, glyph_x, glyph_y, NULL); + + nautilus_debug_pixbuf_draw_rectangle_inset (pixbuf, + FALSE, + glyph_rect.x0, + glyph_rect.y0, + glyph_rect.x1, + glyph_rect.y1, + 0xeebbaa, + 0xff, + -1); + nautilus_glyph_draw_to_pixbuf (glyph, + pixbuf, + glyph_x, + glyph_y, + NULL, + 0x0, + 0xff); + + nautilus_glyph_free (glyph); } nautilus_debug_show_pixbuf_in_eog (pixbuf); diff --git a/test/test.c b/test/test.c index 6b8e79d3e..8de4c1504 100644 --- a/test/test.c +++ b/test/test.c @@ -353,8 +353,8 @@ test_pixbuf_draw_rectangle_tiled (GdkPixbuf *pixbuf, &area, gdk_pixbuf_get_width (tile_pixbuf), gdk_pixbuf_get_height (tile_pixbuf), - x0, - y0, + 0, + 0, opacity, GDK_INTERP_NEAREST); |