X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=libdocument%2Fev-document-misc.c;h=d597127f69251a426600798e1b76e60b1d09445d;hb=212d9a536bc60e711b779feb5e8aa33db654997d;hp=3dc4babef53a14198acedf20422c1586f5f4a4ba;hpb=4ce480dd80453275c10c3b99f988667c2f1bdfff;p=evince.git diff --git a/libdocument/ev-document-misc.c b/libdocument/ev-document-misc.c index 3dc4babe..d597127f 100644 --- a/libdocument/ev-document-misc.c +++ b/libdocument/ev-document-misc.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2009 Juanjo Marín * Copyright (c) 2007 Carlos Garcia Campos * Copyright (C) 2000-2003 Marco Pesenti Gritti * @@ -14,22 +15,28 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "ev-document-misc.h" +#include + #include +#include + #include +#include "ev-document-misc.h" + /* Returns a new GdkPixbuf that is suitable for placing in the thumbnail view. * It is four pixels wider and taller than the source. If source_pixbuf is not * NULL, then it will fill the return pixbuf with the contents of * source_pixbuf. */ -GdkPixbuf * -ev_document_misc_get_thumbnail_frame (int width, - int height, - GdkPixbuf *source_pixbuf) +static GdkPixbuf * +create_thumbnail_frame (int width, + int height, + GdkPixbuf *source_pixbuf, + gboolean fill_bg) { GdkPixbuf *retval; guchar *data; @@ -61,8 +68,10 @@ ev_document_misc_get_thumbnail_frame (int width, rowstride = gdk_pixbuf_get_rowstride (retval); gdk_pixbuf_fill (retval, 0x000000ff); - for (i = 1; i < height_r + 1; i++) - memset (data + (rowstride * i) + 4, 0xffffffff, width_r * 4); + if (fill_bg) { + for (i = 1; i < height_r + 1; i++) + memset (data + (rowstride * i) + 4, 0xffffffff, width_r * 4); + } /* copy the source pixbuf */ if (source_pixbuf) @@ -85,6 +94,22 @@ ev_document_misc_get_thumbnail_frame (int width, return retval; } +GdkPixbuf * +ev_document_misc_get_thumbnail_frame (int width, + int height, + GdkPixbuf *source_pixbuf) +{ + return create_thumbnail_frame (width, height, source_pixbuf, TRUE); +} + +GdkPixbuf * +ev_document_misc_get_loading_thumbnail (int width, + int height, + gboolean inverted_colors) +{ + return create_thumbnail_frame (width, height, NULL, !inverted_colors); +} + void ev_document_misc_get_page_border_size (gint page_width, gint page_height, @@ -108,42 +133,45 @@ ev_document_misc_get_page_border_size (gint page_width, void -ev_document_misc_paint_one_page (GdkDrawable *drawable, +ev_document_misc_paint_one_page (cairo_t *cr, GtkWidget *widget, GdkRectangle *area, GtkBorder *border, - gboolean highlight) + gboolean highlight, + gboolean inverted_colors) { - gdk_draw_rectangle (drawable, - highlight ? - widget->style->text_gc[widget->state] : widget->style->dark_gc[widget->state], - TRUE, - area->x, - area->y, - area->width, - area->height); - gdk_draw_rectangle (drawable, - widget->style->white_gc, - TRUE, - area->x + border->left, - area->y + border->top, - area->width - (border->left + border->right), - area->height - (border->top + border->bottom)); - gdk_draw_rectangle (drawable, - widget->style->mid_gc[widget->state], - TRUE, - area->x, - area->y + area->height - (border->bottom - border->top), - border->bottom - border->top, - border->bottom - border->top); - gdk_draw_rectangle (drawable, - widget->style->mid_gc[widget->state], - TRUE, - area->x + area->width - (border->right - border->left), - area->y, - border->right - border->left, - border->right - border->left); + GtkStyle *style = gtk_widget_get_style (widget); + GtkStateType state = gtk_widget_get_state (widget); + + gdk_cairo_set_source_color (cr, highlight ? &style->text[state] : &style->dark[state]); + gdk_cairo_rectangle (cr, area); + cairo_fill (cr); + if (inverted_colors) + cairo_set_source_rgb (cr, 0, 0, 0); + else + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_rectangle (cr, + area->x + border->left, + area->y + border->top, + area->width - (border->left + border->right), + area->height - (border->top + border->bottom)); + cairo_fill (cr); + + gdk_cairo_set_source_color (cr, &style->mid[state]); + cairo_rectangle (cr, + area->x, + area->y + area->height - (border->bottom - border->top), + border->bottom - border->top, + border->bottom - border->top); + cairo_fill (cr); + + cairo_rectangle (cr, + area->x + area->width - (border->right - border->left), + area->y, + border->right - border->left, + border->right - border->left); + cairo_fill (cr); } cairo_surface_t * @@ -151,8 +179,9 @@ ev_document_misc_surface_from_pixbuf (GdkPixbuf *pixbuf) { cairo_surface_t *surface; cairo_t *cr; - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + + surface = cairo_image_surface_create (gdk_pixbuf_get_has_alpha (pixbuf) ? + CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf)); cr = cairo_create (surface); @@ -218,10 +247,10 @@ ev_document_misc_pixbuf_from_surface (cairo_surface_t *surface) p[3] = (has_alpha) ? p[3] : 0xff; #else tmp = p[0]; - p[0] = (has_alpha) ? p[3] : 0xff; - p[3] = p[2]; - p[2] = p[1]; - p[1] = tmp; + p[0] = p[1]; + p[1] = p[2]; + p[2] = p[3]; + p[3] = (has_alpha) ? tmp : 0xff; #endif p += pixbuf_n_channels; } @@ -257,7 +286,7 @@ ev_document_misc_surface_rotate_and_scale (cairo_surface_t *surface, } new_surface = cairo_surface_create_similar (surface, - CAIRO_CONTENT_COLOR_ALPHA, + cairo_surface_get_content (surface), new_width, new_height); cr = cairo_create (new_surface); @@ -289,4 +318,83 @@ ev_document_misc_surface_rotate_and_scale (cairo_surface_t *surface, return new_surface; } - + +void +ev_document_misc_invert_surface (cairo_surface_t *surface) { + cairo_t *cr; + + cr = cairo_create (surface); + + /* white + DIFFERENCE -> invert */ + cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE); + cairo_set_source_rgb (cr, 1., 1., 1.); + cairo_paint(cr); + cairo_destroy (cr); +} + +void +ev_document_misc_invert_pixbuf (GdkPixbuf *pixbuf) +{ + guchar *data, *p; + guint width, height, x, y, rowstride, n_channels; + + n_channels = gdk_pixbuf_get_n_channels (pixbuf); + g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); + g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); + + /* First grab a pointer to the raw pixel data. */ + data = gdk_pixbuf_get_pixels (pixbuf); + + /* Find the number of bytes per row (could be padded). */ + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + for (x = 0; x < width; x++) { + for (y = 0; y < height; y++) { + /* Calculate pixel's offset into the data array. */ + p = data + x * n_channels + y * rowstride; + /* Change the RGB values*/ + p[0] = 255 - p[0]; + p[1] = 255 - p[1]; + p[2] = 255 - p[2]; + } + } +} + +gdouble +ev_document_misc_get_screen_dpi (GdkScreen *screen) +{ + gdouble dp, di; + + /*diagonal in pixels*/ + dp = hypot (gdk_screen_get_width (screen), gdk_screen_get_height (screen)); + + /*diagonal in inches*/ + di = hypot (gdk_screen_get_width_mm(screen), gdk_screen_get_height_mm (screen)) / 25.4; + + return (dp / di); +} + +/* Returns a locale specific date and time representation */ +gchar * +ev_document_misc_format_date (GTime utime) +{ + time_t time = (time_t) utime; + char s[256]; + const char fmt_hack[] = "%c"; + size_t len; +#ifdef HAVE_LOCALTIME_R + struct tm t; + if (time == 0 || !localtime_r (&time, &t)) return NULL; + len = strftime (s, sizeof (s), fmt_hack, &t); +#else + struct tm *t; + if (time == 0 || !(t = localtime (&time)) ) return NULL; + len = strftime (s, sizeof (s), fmt_hack, t); +#endif + + if (len == 0 || s[0] == '\0') return NULL; + + return g_locale_to_utf8 (s, -1, NULL, NULL, NULL); +}