[gthumb] rotate image: pass a cairo_surface to the rotate function, instead of a GdkPixbuf
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb] rotate image: pass a cairo_surface to the rotate function, instead of a GdkPixbuf
- Date: Tue, 17 May 2011 22:10:32 +0000 (UTC)
commit 6316026c38e5187681b738bed9a54cc664f679cc
Author: Paolo Bacchilega <paobac src gnome org>
Date: Mon May 16 16:01:27 2011 +0200
rotate image: pass a cairo_surface to the rotate function, instead of a GdkPixbuf
extensions/file_tools/Makefile.am | 4 +-
.../{gdk-pixbuf-rotate.c => cairo-rotate.c} | 281 +++++++++-----------
extensions/file_tools/cairo-rotate.h | 50 ++++
extensions/file_tools/gdk-pixbuf-rotate.h | 56 ----
extensions/file_tools/gth-file-tool-rotate.c | 135 ++++++----
5 files changed, 261 insertions(+), 265 deletions(-)
---
diff --git a/extensions/file_tools/Makefile.am b/extensions/file_tools/Makefile.am
index d8ea6dc..74a619a 100644
--- a/extensions/file_tools/Makefile.am
+++ b/extensions/file_tools/Makefile.am
@@ -9,7 +9,7 @@ ENUM_TYPES = \
HEADER_FILES = \
cairo-blur.h \
- gdk-pixbuf-rotate.h \
+ cairo-rotate.h \
gth-file-tool-adjust-colors.h \
gth-file-tool-crop.h \
gth-file-tool-desaturate.h \
@@ -58,7 +58,7 @@ libfile_tools_la_SOURCES = \
callbacks.c \
callbacks.h \
cairo-blur.c \
- gdk-pixbuf-rotate.c \
+ cairo-rotate.c \
gth-file-tool-adjust-colors.c \
gth-file-tool-crop.c \
gth-file-tool-desaturate.c \
diff --git a/extensions/file_tools/gdk-pixbuf-rotate.c b/extensions/file_tools/cairo-rotate.c
similarity index 55%
rename from extensions/file_tools/gdk-pixbuf-rotate.c
rename to extensions/file_tools/cairo-rotate.c
index 38a2984..7848548 100644
--- a/extensions/file_tools/gdk-pixbuf-rotate.c
+++ b/extensions/file_tools/cairo-rotate.c
@@ -21,22 +21,20 @@
#include <math.h>
#include <gthumb.h>
-#include "gdk-pixbuf-rotate.h"
+#include "cairo-rotate.h"
-#define PI 3.1415926535
-
#define ROUND(x) ((int) floor ((x) + 0.5))
#define INTERPOLATE(v00, v10, v01, v11, fx, fy) ((v00) + ((v10) - (v00)) * (fx) + ((v01) - (v00)) * (fy) + ((v00) - (v10) - (v01) + (v11)) * (fx) * (fy))
#define GET_VALUES(r, g, b, a, x, y) \
if (x >= 0 && x < src_width && y >= 0 && y < src_height) { \
- p_src2 = p_src + src_rowstride * y + n_channels * x; \
- r = p_src2[RED_PIX]; \
- g = p_src2[GREEN_PIX]; \
- b = p_src2[BLUE_PIX]; \
- a = (n_channels == 4) ? p_src2[ALPHA_PIX] : a0; \
+ p_src2 = p_src + src_rowstride * y + 4 * x; \
+ r = p_src2[CAIRO_RED]; \
+ g = p_src2[CAIRO_GREEN]; \
+ b = p_src2[CAIRO_BLUE]; \
+ a = p_src2[CAIRO_ALPHA]; \
} \
else { \
r = r0; \
@@ -47,10 +45,10 @@
void
-_gdk_pixbuf_rotate_get_cropping_parameters (GdkPixbuf *src_pixbuf,
- double angle,
- double *p1_plus_p2,
- double *p_min)
+_cairo_image_surface_rotate_get_cropping_parameters (cairo_surface_t *image,
+ double angle,
+ double *p1_plus_p2,
+ double *p_min)
{
double angle_rad;
double cos_angle, sin_angle;
@@ -59,20 +57,20 @@ _gdk_pixbuf_rotate_get_cropping_parameters (GdkPixbuf *src_pixbuf,
angle = CLAMP (angle, -90.0, 90.0);
- angle_rad = fabs (angle) / 180.0 * PI;
+ angle_rad = fabs (angle) / 180.0 * G_PI;
cos_angle = cos (angle_rad);
sin_angle = sin (angle_rad);
- src_width = gdk_pixbuf_get_width (src_pixbuf) - 1;
- src_height = gdk_pixbuf_get_height (src_pixbuf) - 1;
+ src_width = cairo_image_surface_get_width (image) - 1.0;
+ src_height = cairo_image_surface_get_height (image) - 1.0;
if (src_width > src_height) {
t1 = cos_angle * src_width - sin_angle * src_height;
t2 = sin_angle * src_width + cos_angle * src_height;
*p1_plus_p2 = 1.0 + (t1 * src_height) / (t2 * src_width);
-
+
*p_min = src_height / src_width * sin_angle * cos_angle + (*p1_plus_p2 - 1) * cos_angle * cos_angle;
}
else {
@@ -80,37 +78,35 @@ _gdk_pixbuf_rotate_get_cropping_parameters (GdkPixbuf *src_pixbuf,
t2 = sin_angle * src_height + cos_angle * src_width;
*p1_plus_p2 = 1.0 + (t1 * src_width) / (t2 * src_height);
-
+
*p_min = src_width / src_height * sin_angle * cos_angle + (*p1_plus_p2 - 1) * cos_angle * cos_angle;
}
}
void
-_gdk_pixbuf_rotate_get_cropping_region (GdkPixbuf *src_pixbuf,
- double angle,
- double p1,
- double p2,
- GdkRectangle *region)
+_cairo_image_surface_rotate_get_cropping_region (cairo_surface_t *image,
+ double angle,
+ double p1,
+ double p2,
+ GdkRectangle *region)
{
double angle_rad;
double cos_angle, sin_angle;
double src_width, src_height;
double new_width;
-
double xx1, yy1, xx2, yy2;
angle = CLAMP (angle, -90.0, 90.0);
p1 = CLAMP (p1, 0.0, 1.0);
p2 = CLAMP (p2, 0.0, 1.0);
- angle_rad = fabs (angle) / 180.0 * PI;
-
+ angle_rad = fabs (angle) / 180.0 * G_PI;
cos_angle = cos (angle_rad);
sin_angle = sin (angle_rad);
- src_width = gdk_pixbuf_get_width (src_pixbuf) - 1;
- src_height = gdk_pixbuf_get_height (src_pixbuf) - 1;
+ src_width = cairo_image_surface_get_width (image) - 1.0;
+ src_height = cairo_image_surface_get_height (image) - 1.0;
if (angle < 0) {
@@ -124,25 +120,20 @@ _gdk_pixbuf_rotate_get_cropping_region (GdkPixbuf *src_pixbuf,
}
if (src_width > src_height) {
-
xx1 = p1 * src_width * cos_angle + src_height * sin_angle;
yy1 = p1 * src_width * sin_angle;
-
xx2 = (1 - p2) * src_width * cos_angle;
yy2 = (1 - p2) * src_width * sin_angle + src_height * cos_angle;
}
else {
xx1 = p1 * src_height * sin_angle;
yy1 = (1 - p1) * src_height * cos_angle;
-
xx2 = (1 - p2) * src_height * sin_angle + src_width * cos_angle;
yy2 = p2 * src_height * cos_angle + src_width * sin_angle;
}
if (angle < 0) {
-
- new_width = cos_angle * src_width + sin_angle * src_height;
-
+ new_width = (cos_angle * src_width) + (sin_angle * src_height);
xx1 = new_width - xx1;
xx2 = new_width - xx2;
}
@@ -155,66 +146,88 @@ _gdk_pixbuf_rotate_get_cropping_region (GdkPixbuf *src_pixbuf,
}
-static GdkPixbuf*
-rotate (GdkPixbuf *src_pixbuf,
- double angle,
- gboolean high_quality,
- guchar r0,
- guchar g0,
- guchar b0,
- guchar a0)
+double
+_cairo_image_surface_rotate_get_align_angle (gboolean vertical,
+ GdkPoint p1,
+ GdkPoint p2)
{
- GdkPixbuf *new_pixbuf;
-
- double angle_rad;
- double cos_angle, sin_angle;
- double src_width, src_height;
- int new_width, new_height;
- int src_rowstride, new_rowstride;
- int n_channels;
- int xi, yi;
- double x, y;
- double x2, y2;
- int x2min, y2min;
- int x2max, y2max;
- double fx, fy;
- guchar *p_src, *p_new;
- guchar *p_src2, *p_new2;
-
- guchar r00, r01, r10, r11;
- guchar g00, g01, g10, g11;
- guchar b00, b01, b10, b11;
- guchar a00, a01, a10, a11;
+ double angle;
- angle = CLAMP (angle, -90.0, 90.0);
+ if (! vertical) {
+ if (p1.y == p2.y)
+ return 0.0;
- angle_rad = angle / 180.0 * PI;
+ if (p2.x > p1.x)
+ angle = -atan2 (p2.y - p1.y, p2.x - p1.x);
+ else
+ angle = -atan2 (p1.y - p2.y, p1.x - p2.x);
+ }
+ else {
+ if (p1.x == p2.x)
+ return 0.0;
- cos_angle = cos (angle_rad);
- sin_angle = sin (angle_rad);
+ if (p2.y > p1.y)
+ angle = atan2 (p2.x - p1.x, p2.y - p1.y);
+ else
+ angle = atan2 (p1.x - p2.x, p1.y - p2.y);
+ }
+
+ angle = angle * 180.0 / G_PI;
+ angle = ROUND (angle * 10.0) / 10.0;
- src_width = gdk_pixbuf_get_width (src_pixbuf) - 1;
- src_height = gdk_pixbuf_get_height (src_pixbuf) - 1;
+ return angle;
+}
+
+static cairo_surface_t*
+rotate (cairo_surface_t *image,
+ double angle,
+ gboolean high_quality,
+ guchar r0,
+ guchar g0,
+ guchar b0,
+ guchar a0)
+{
+ cairo_surface_t *rotated;
+ double angle_rad;
+ double cos_angle, sin_angle;
+ double src_width, src_height;
+ int new_width, new_height;
+ int src_rowstride, new_rowstride;
+ int xi, yi;
+ double x, y;
+ double x2, y2;
+ int x2min, y2min;
+ int x2max, y2max;
+ double fx, fy;
+ guchar *p_src, *p_new;
+ guchar *p_src2, *p_new2;
+ guchar r00, r01, r10, r11;
+ guchar g00, g01, g10, g11;
+ guchar b00, b01, b10, b11;
+ guchar a00, a01, a10, a11;
+ guchar r, g, b, a;
+ guint32 pixel;
+
+ angle = CLAMP (angle, -90.0, 90.0);
+ angle_rad = angle / 180.0 * G_PI;
+ cos_angle = cos (angle_rad);
+ sin_angle = sin (angle_rad);
+ src_width = cairo_image_surface_get_width (image) - 1;
+ src_height = cairo_image_surface_get_height (image) - 1;
new_width = ROUND ( cos_angle * src_width + fabs(sin_angle) * src_height);
new_height = ROUND (fabs (sin_angle) * src_width + cos_angle * src_height);
- new_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src_pixbuf),
- gdk_pixbuf_get_has_alpha (src_pixbuf),
- gdk_pixbuf_get_bits_per_sample (src_pixbuf),
- new_width,
- new_height);
-
- p_src = gdk_pixbuf_get_pixels (src_pixbuf);
- p_new = gdk_pixbuf_get_pixels (new_pixbuf);
+ rotated = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, new_width, new_height);
- src_rowstride = gdk_pixbuf_get_rowstride (src_pixbuf);
- new_rowstride = gdk_pixbuf_get_rowstride (new_pixbuf);
+ p_src = cairo_image_surface_get_data (image);
+ p_new = cairo_image_surface_get_data (rotated);
+ src_rowstride = cairo_image_surface_get_stride (image);
+ new_rowstride = cairo_image_surface_get_stride (rotated);
- n_channels = gdk_pixbuf_get_n_channels (src_pixbuf);
+ cairo_surface_flush (rotated);
for (yi = 0; yi < new_height; yi++) {
-
p_new2 = p_new;
y = yi - new_height / 2.0;
@@ -227,8 +240,7 @@ rotate (GdkPixbuf *src_pixbuf,
y2 = sin_angle * x + cos_angle * y + src_height / 2.0;
if (high_quality) {
-
- /* Bilinear interpolation */
+ /* Bilinear interpolation. FIXME: use a gaussian interpolation here */
x2min = (int) floor (x2);
y2min = (int) floor (y2);
@@ -244,12 +256,13 @@ rotate (GdkPixbuf *src_pixbuf,
GET_VALUES (r10, g10, b10, a10, x2min, y2max);
GET_VALUES (r11, g11, b11, a11, x2max, y2max);
- p_new2[RED_PIX] = CLAMP (INTERPOLATE (r00, r01, r10, r11, fx, fy), 0, 255);
- p_new2[GREEN_PIX] = CLAMP (INTERPOLATE (g00, g01, g10, g11, fx, fy), 0, 255);
- p_new2[BLUE_PIX] = CLAMP (INTERPOLATE (b00, b01, b10, b11, fx, fy), 0, 255);
+ r = CLAMP (INTERPOLATE (r00, r01, r10, r11, fx, fy), 0, 255);
+ g = CLAMP (INTERPOLATE (g00, g01, g10, g11, fx, fy), 0, 255);
+ b = CLAMP (INTERPOLATE (b00, b01, b10, b11, fx, fy), 0, 255);
+ a = CLAMP (INTERPOLATE (a00, a01, a10, a11, fx, fy), 0, 255);
- if (n_channels == 4)
- p_new2[ALPHA_PIX] = CLAMP (INTERPOLATE (a00, a01, a10, a11, fx, fy), 0, 255);
+ pixel = CAIRO_RGBA_TO_UINT32 (r, g, b, a);
+ memcpy (p_new2, &pixel, sizeof (guint32));
}
else {
/* Nearest neighbor */
@@ -257,84 +270,52 @@ rotate (GdkPixbuf *src_pixbuf,
x2min = ROUND (x2);
y2min = ROUND (y2);
- if (n_channels == 4) {
- GET_VALUES (p_new2[RED_PIX], p_new2[GREEN_PIX], p_new2[BLUE_PIX], p_new2[ALPHA_PIX], x2min, y2min);
- }
- else {
- guchar t;
- GET_VALUES (p_new2[RED_PIX], p_new2[GREEN_PIX], p_new2[BLUE_PIX], t, x2min, y2min);
- }
+ GET_VALUES (p_new2[RED_PIX], p_new2[GREEN_PIX], p_new2[BLUE_PIX], p_new2[ALPHA_PIX], x2min, y2min);
}
- p_new2 += n_channels;
+ p_new2 += 4;
}
p_new += new_rowstride;
}
- return new_pixbuf;
-}
-
-
-double
-_gdk_pixbuf_rotate_get_align_angle (gboolean vertical,
- GdkPoint p1,
- GdkPoint p2)
-{
- double angle;
-
- if (! vertical) {
-
- if (p1.y == p2.y)
- return 0.0;
-
- if (p2.x > p1.x)
- angle = -atan2 (p2.y - p1.y, p2.x - p1.x);
- else
- angle = -atan2 (p1.y - p2.y, p1.x - p2.x);
- }
- else {
-
- if (p1.x == p2.x)
- return 0.0;
+ cairo_surface_mark_dirty (rotated);
- if (p2.y > p1.y)
- angle = atan2 (p2.x - p1.x, p2.y - p1.y);
- else
- angle = atan2 (p1.x - p2.x, p1.y - p2.y);
- }
-
- angle = angle * 180.0 / PI;
- angle = ROUND (angle * 10.0) / 10.0;
-
- return angle;
+ return rotated;
}
-GdkPixbuf*
-_gdk_pixbuf_rotate (GdkPixbuf *src_pixbuf,
- double angle,
- gboolean high_quality,
- guchar r0,
- guchar g0,
- guchar b0,
- guchar a0)
+cairo_surface_t *
+_cairo_image_surface_rotate (cairo_surface_t *image,
+ double angle,
+ gboolean high_quality,
+ cairo_color_255_t *background_color)
{
- GdkPixbuf *new_pixbuf;
+ cairo_surface_t *rotated;
+ cairo_surface_t *tmp = NULL;
- if (angle == 0.0) {
- new_pixbuf = src_pixbuf;
- g_object_ref (new_pixbuf);
- }
- else if (angle >= 90.0) {
- new_pixbuf = gdk_pixbuf_rotate_simple (src_pixbuf, GDK_PIXBUF_ROTATE_CLOCKWISE);
+ if (angle >= 90.0) {
+ image = tmp = _cairo_image_surface_transform (image, GTH_TRANSFORM_ROTATE_90);
+ angle -= 90.0;
}
else if (angle <= -90.0) {
- new_pixbuf = gdk_pixbuf_rotate_simple (src_pixbuf, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE);
- }
- else {
- new_pixbuf = rotate (src_pixbuf, -angle, high_quality, r0, g0, b0, a0);
+ image = tmp = _cairo_image_surface_transform (image, GTH_TRANSFORM_ROTATE_270);
+ angle += 90.0;
}
- return new_pixbuf;
+ if (angle != 0.0)
+ rotated = rotate (image,
+ -angle,
+ high_quality,
+ background_color->r,
+ background_color->g,
+ background_color->b,
+ background_color->a);
+ else
+ rotated = cairo_surface_reference (image);
+
+ if (tmp != NULL)
+ cairo_surface_destroy (tmp);
+
+ return rotated;
}
diff --git a/extensions/file_tools/cairo-rotate.h b/extensions/file_tools/cairo-rotate.h
new file mode 100644
index 0000000..dbf2030
--- /dev/null
+++ b/extensions/file_tools/cairo-rotate.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2011 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef CAIRO_ROTATE_H
+#define CAIRO_ROTATE_H
+
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+G_BEGIN_DECLS
+
+void _cairo_image_surface_rotate_get_cropping_parameters (cairo_surface_t *image,
+ double angle,
+ double *p1_plus_p2,
+ double *p_min);
+void _cairo_image_surface_rotate_get_cropping_region (cairo_surface_t *image,
+ double angle,
+ double p1,
+ double p2,
+ GdkRectangle *region);
+double _cairo_image_surface_rotate_get_align_angle (gboolean vertical,
+ GdkPoint p1,
+ GdkPoint p2);
+cairo_surface_t * _cairo_image_surface_rotate (cairo_surface_t *image,
+ double angle,
+ gboolean high_quality,
+ cairo_color_255_t *background_color);
+
+G_END_DECLS
+
+#endif /* CAIRO_ROTATE_H */
diff --git a/extensions/file_tools/gth-file-tool-rotate.c b/extensions/file_tools/gth-file-tool-rotate.c
index 4e6c756..c94a676 100644
--- a/extensions/file_tools/gth-file-tool-rotate.c
+++ b/extensions/file_tools/gth-file-tool-rotate.c
@@ -24,7 +24,7 @@
#include <gthumb.h>
#include <extensions/image_viewer/gth-image-viewer-page.h>
#include "enum-types.h"
-#include "gdk-pixbuf-rotate.h"
+#include "cairo-rotate.h"
#include "gth-file-tool-rotate.h"
#include "gth-image-rotator.h"
@@ -37,29 +37,28 @@ static gpointer parent_class = NULL;
struct _GthFileToolRotatePrivate {
- GdkPixbuf *src_pixbuf;
- GdkPixbuf *rotate_pixbuf;
- gboolean has_alpha;
- GtkBuilder *builder;
- GtkWidget *options;
- GtkAdjustment *rotation_angle_adj;
- GtkWidget *background_colorbutton;
- GtkWidget *background_transparent;
- gboolean crop_enabled;
- GtkWidget *show_grid;
- GtkWidget *keep_aspect_ratio;
- GtkAdjustment *crop_p1_adj;
- GtkAdjustment *crop_p2_adj;
- double crop_p1_plus_p2;
- GtkWidget *crop_grid;
- GdkRectangle crop_region;
- GthImageSelector *selector_crop;
- GthImageSelector *selector_align;
+ cairo_surface_t *image;
+ gboolean has_alpha;
+ GtkBuilder *builder;
+ GtkWidget *options;
+ GtkAdjustment *rotation_angle_adj;
+ GtkWidget *background_colorbutton;
+ GtkWidget *background_transparent;
+ gboolean crop_enabled;
+ GtkWidget *show_grid;
+ GtkWidget *keep_aspect_ratio;
+ GtkAdjustment *crop_p1_adj;
+ GtkAdjustment *crop_p2_adj;
+ double crop_p1_plus_p2;
+ GtkWidget *crop_grid;
+ GdkRectangle crop_region;
+ GthImageSelector *selector_crop;
+ GthImageSelector *selector_align;
GthImageViewerTool *rotator;
- guint selector_align_direction;
- guint selector_align_point;
- GdkPoint align_points[2];
- guint apply_event;
+ guint selector_align_direction;
+ guint selector_align_point;
+ GdkPoint align_points[2];
+ guint apply_event;
};
@@ -85,10 +84,10 @@ update_crop_parameters (GthFileToolRotate *self)
gtk_widget_set_sensitive (GET_WIDGET ("crop_p2_label"), FALSE);
gtk_widget_set_sensitive (GET_WIDGET ("crop_p2_hbox"), FALSE);
- _gdk_pixbuf_rotate_get_cropping_parameters (self->priv->src_pixbuf,
- rotation_angle,
- &self->priv->crop_p1_plus_p2,
- &crop_p_min);
+ _cairo_image_surface_rotate_get_cropping_parameters (self->priv->image,
+ rotation_angle,
+ &self->priv->crop_p1_plus_p2,
+ &crop_p_min);
/* This centers the cropping region in the middle of the rotated image */
@@ -133,11 +132,11 @@ update_crop_region (GthFileToolRotate *self)
rotation_angle = gtk_adjustment_get_value (self->priv->rotation_angle_adj);
crop_p1 = gtk_adjustment_get_value (self->priv->crop_p1_adj);
crop_p2 = gtk_adjustment_get_value (self->priv->crop_p2_adj);
- _gdk_pixbuf_rotate_get_cropping_region (self->priv->src_pixbuf,
- rotation_angle,
- crop_p1,
- crop_p2,
- &self->priv->crop_region);
+ _cairo_image_surface_rotate_get_cropping_region (self->priv->image,
+ rotation_angle,
+ crop_p1,
+ crop_p2,
+ &self->priv->crop_region);
gth_image_rotator_set_crop_region (GTH_IMAGE_ROTATOR (self->priv->rotator), &self->priv->crop_region);
}
else
@@ -167,7 +166,8 @@ align_begin (GthFileToolRotate *self)
gtk_widget_set_sensitive (self->priv->options, FALSE);
- gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->src_pixbuf, FALSE);
+ /* FIXME
+ gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->src_pixbuf, FALSE); */
gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), (GthImageViewerTool *) self->priv->selector_align);
}
@@ -178,16 +178,14 @@ align_end (GthFileToolRotate *self)
{
GtkWidget *window;
GtkWidget *viewer_page;
- GtkWidget *viewer;
double angle;
window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
- viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
- angle = _gdk_pixbuf_rotate_get_align_angle (self->priv->selector_align_direction == 1,
- self->priv->align_points[0],
- self->priv->align_points[1]),
+ angle = _cairo_image_surface_rotate_get_align_angle (self->priv->selector_align_direction == 1,
+ self->priv->align_points[0],
+ self->priv->align_points[1]),
self->priv->selector_align_direction = 0;
self->priv->selector_align_point = 0;
@@ -198,7 +196,9 @@ align_end (GthFileToolRotate *self)
/* We already have the pixmap ready */
+ /* FIXME
gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), self->priv->rotate_pixbuf, FALSE);
+ */
update_crop_parameters (self);
update_crop_region (self);
@@ -313,9 +313,13 @@ static void
apply_button_clicked_cb (GtkButton *button,
GthFileToolRotate *self)
{
- GtkWidget *window;
- GtkWidget *viewer_page;
- cairo_surface_t *image;
+ GtkWidget *window;
+ GtkWidget *viewer_page;
+ double rotation_angle;
+ GdkColor color;
+ cairo_color_255_t background_color;
+ cairo_surface_t *rotated;
+ cairo_surface_t *image;
#if 0
if (self->priv->rotate_pixbuf != self->priv->src_pixbuf) {
@@ -347,12 +351,31 @@ apply_button_clicked_cb (GtkButton *button,
}
#endif
+ rotation_angle = gtk_adjustment_get_value (self->priv->rotation_angle_adj);
+
+ gtk_color_button_get_color (GTK_COLOR_BUTTON (self->priv->background_colorbutton), &color);
+ background_color.r = color.red;
+ background_color.g = color.green;
+ background_color.b = color.blue;
+ background_color.a = gtk_color_button_get_alpha (GTK_COLOR_BUTTON (self->priv->background_colorbutton));
+
+ rotated = _cairo_image_surface_rotate (self->priv->image, rotation_angle, TRUE, &background_color);
+ if (self->priv->crop_enabled)
+ image = _cairo_image_surface_copy_subsurface (rotated,
+ self->priv->crop_region.x,
+ self->priv->crop_region.y,
+ self->priv->crop_region.width,
+ self->priv->crop_region.height);
+ else
+ image = cairo_surface_reference (rotated);
+ /*image = gth_image_rotator_get_result (GTH_IMAGE_ROTATOR (self->priv->rotator)); FIXME*/
+
window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
-
- image = gth_image_rotator_get_result (GTH_IMAGE_ROTATOR (self->priv->rotator));
gth_image_viewer_page_set_image (GTH_IMAGE_VIEWER_PAGE (viewer_page), image, TRUE);
+
cairo_surface_destroy (image);
+ cairo_surface_destroy (rotated);
gth_file_tool_hide_options (GTH_FILE_TOOL (self));
}
@@ -475,15 +498,14 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
return NULL;
- _g_clear_object (&self->priv->src_pixbuf);
- _g_clear_object (&self->priv->rotate_pixbuf);
+ cairo_surface_destroy (self->priv->image);
viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
- self->priv->src_pixbuf = gth_image_viewer_get_current_pixbuf (GTH_IMAGE_VIEWER (viewer));
- if (self->priv->src_pixbuf == NULL)
+ self->priv->image = gth_image_viewer_get_current_image (GTH_IMAGE_VIEWER (viewer));
+ if (self->priv->image == NULL)
return NULL;
- self->priv->rotate_pixbuf = g_object_ref (self->priv->src_pixbuf);
+ cairo_surface_reference (self->priv->image);
self->priv->builder = _gtk_builder_new_from_file ("rotate-options.ui", "file_tools");
@@ -496,7 +518,7 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
self->priv->background_colorbutton = _gtk_builder_get_widget (self->priv->builder, "background_colorbutton");
self->priv->background_transparent = _gtk_builder_get_widget (self->priv->builder, "background_transparent_checkbutton");
- self->priv->has_alpha = gdk_pixbuf_get_n_channels (self->priv->src_pixbuf) == 4;
+ self->priv->has_alpha = _cairo_image_surface_get_has_alpha (self->priv->image);
if (self->priv->has_alpha) {
gtk_color_button_set_use_alpha (GTK_COLOR_BUTTON (self->priv->background_colorbutton), TRUE);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self->priv->background_transparent), TRUE);
@@ -537,8 +559,8 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
self->priv->rotator = gth_image_rotator_new (GTH_IMAGE_VIEWER (viewer));
gth_image_rotator_set_center (GTH_IMAGE_ROTATOR (self->priv->rotator),
- gdk_pixbuf_get_width (self->priv->src_pixbuf) / 2,
- gdk_pixbuf_get_height (self->priv->src_pixbuf) / 2);
+ cairo_image_surface_get_width (self->priv->image) / 2,
+ cairo_image_surface_get_height (self->priv->image) / 2);
gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), self->priv->rotator);
gth_image_viewer_set_zoom_enabled (GTH_IMAGE_VIEWER (viewer), FALSE);
gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (viewer_page));
@@ -549,8 +571,8 @@ gth_file_tool_rotate_get_options (GthFileTool *base)
self->priv->crop_enabled = TRUE;
self->priv->crop_region.x = 0;
self->priv->crop_region.y = 0;
- self->priv->crop_region.width = gdk_pixbuf_get_width (self->priv->src_pixbuf);
- self->priv->crop_region.height = gdk_pixbuf_get_height (self->priv->src_pixbuf);
+ self->priv->crop_region.width = cairo_image_surface_get_width (self->priv->image);
+ self->priv->crop_region.height = cairo_image_surface_get_height (self->priv->image);
g_signal_connect (GET_WIDGET ("apply_button"),
"clicked",
@@ -639,8 +661,8 @@ gth_file_tool_rotate_destroy_options (GthFileTool *base)
gth_image_viewer_set_zoom_enabled (GTH_IMAGE_VIEWER (viewer), TRUE);
gth_viewer_page_update_sensitivity (GTH_VIEWER_PAGE (viewer_page));
- _g_clear_object (&self->priv->src_pixbuf);
- _g_clear_object (&self->priv->rotate_pixbuf);
+ cairo_surface_destroy (self->priv->image);
+ self->priv->image = NULL;
_g_clear_object (&self->priv->builder);
_g_clear_object (&self->priv->selector_crop);
_g_clear_object (&self->priv->selector_align);
@@ -676,8 +698,7 @@ gth_file_tool_rotate_finalize (GObject *object)
self = (GthFileToolRotate *) object;
- _g_object_unref (self->priv->src_pixbuf);
- _g_object_unref (self->priv->rotate_pixbuf);
+ cairo_surface_destroy (self->priv->image);
_g_object_unref (self->priv->builder);
/* Chain up */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]