Espejado vertical y horizontal de los objetos
authordanigm <danigm>
Fri, 26 Feb 2010 19:07:25 +0000 (19:07 +0000)
committerdanigm <danigm@aa302d1f-72b1-406a-902b-8593ca2b2744>
Fri, 26 Feb 2010 19:07:25 +0000 (19:07 +0000)
git-svn-id: https://forja.rediris.es/svn/cusl4-tbo@67 aa302d1f-72b1-406a-902b-8593ca2b2744

src/Makefile.am
src/selector-tool.c
src/svgimage.c
src/tbo-object.c [new file with mode: 0644]
src/tbo-object.h [new file with mode: 0644]
src/textobj.c
test/ejemplo_2.py

index 9f7a1c3..dcf2761 100644 (file)
@@ -27,6 +27,7 @@ tbo_SOURCES = \
        textobj.c \
        svgimage.c \
        dnd.c \
+       tbo-object.c \
        tbo-window.h \
        comic.h \
        comic-new-dialog.h \
@@ -44,6 +45,7 @@ tbo_SOURCES = \
        svgimage.h \
        textobj.h \
        dnd.h \
+       tbo-object.h \
        custom-stock.h
 
 tbo_CFLAGS = @GTK_CFLAGS@ \
index 0a42a00..31fd362 100644 (file)
@@ -5,6 +5,7 @@
 #include "selector-tool.h"
 #include "tbo-window.h"
 #include "tbo-types.h"
+#include "tbo-object.h"
 #include "page.h"
 #include "frame.h"
 #include "comic.h"
@@ -411,10 +412,23 @@ frame_view_on_key (GtkWidget *widget, GdkEventKey *event, TboWindow *tbo)
         set_frame_view (NULL);
     }
 
-    if (OBJ != NULL && event->keyval == GDK_Delete)
+    if (OBJ != NULL)
     {
-        tbo_frame_del_obj (SELECTED, OBJ);
-        set_selected_obj (NULL, tbo);
+        switch (event->keyval)
+        {
+            case GDK_Delete:
+                tbo_frame_del_obj (SELECTED, OBJ);
+                set_selected_obj (NULL, tbo);
+                break;
+            case GDK_v:
+                tbo_object_flipv (OBJ);
+                break;
+            case GDK_h:
+                tbo_object_fliph (OBJ);
+                break;
+            default:
+                break;
+        }
     }
 }
 
index f36577f..94b0bbf 100644 (file)
@@ -17,6 +17,8 @@ tbo_svgimage_new ()
     image->free =tbo_svg_image_free;
     image->draw =tbo_svg_image_draw;
     image->type = SVGOBJ;
+    image->flipv = FALSE;
+    image->fliph = FALSE;
     return image;
 }
 
@@ -35,6 +37,8 @@ tbo_svgimage_new_width_params (int x,
     image->height = height;
     snprintf (image->data, 255, "%s", path);
     image->type = SVGOBJ;
+    image->flipv = FALSE;
+    image->fliph = FALSE;
     return image;
 }
 
@@ -69,14 +73,20 @@ tbo_svg_image_draw (SVGImage *self, Frame *frame, cairo_t *cr)
         float factorw = (float)self->width / (float)w;
         float factorh = (float)self->height / (float)h;
 
+        // Fliping
+        cairo_matrix_t mx = {1, 0, 0, 1, 0, 0};
+        tbo_object_get_flip_matrix (self, &mx);
+
         cairo_rectangle(cr, frame->x+2, frame->y+2, frame->width-4, frame->height-4);
         cairo_clip (cr);
         cairo_translate (cr, frame->x+self->x, frame->y+self->y);
         cairo_rotate (cr, self->angle);
         cairo_scale (cr, factorw, factorh);
+        cairo_transform (cr, &mx);
 
         rsvg_handle_render_cairo (rsvg_handle, cr);
 
+        cairo_transform (cr, &mx);
         cairo_scale (cr, 1/factorw, 1/factorh);
         cairo_rotate (cr, -self->angle);
         cairo_translate (cr, -(frame->x+self->x), -(frame->y+self->y));
diff --git a/src/tbo-object.c b/src/tbo-object.c
new file mode 100644 (file)
index 0000000..6a35a01
--- /dev/null
@@ -0,0 +1,42 @@
+#include <gtk/gtk.h>
+#include <cairo.h>
+#include "tbo-types.h"
+#include "tbo-object.h"
+
+void
+tbo_object_flipv (tbo_object *self)
+{
+    if (self->flipv)
+        self->flipv = FALSE;
+    else
+        self->flipv = TRUE;
+}
+
+void
+tbo_object_fliph (tbo_object *self)
+{
+    if (self->fliph)
+        self->fliph = FALSE;
+    else
+        self->fliph = TRUE;
+}
+
+void
+tbo_object_get_flip_matrix (tbo_object *self, cairo_matrix_t *mx)
+{
+    cairo_matrix_t flipv = {1, 0, 0, -1, 0, 0};
+    cairo_matrix_t fliph = {-1, 0, 0, 1, 0, 0};
+
+    if (self->flipv)
+    {
+        mx->xx = flipv.xx; mx->yx = flipv.yx; mx->yy = flipv.yy;
+        mx->x0 = 0;
+        mx->y0 = self->height;
+    }
+    else if (self->fliph)
+    {
+        mx->xx = fliph.xx; mx->yx = fliph.yx; mx->yy = fliph.yy;
+        mx->x0 = self->width;
+        mx->y0 = 0;
+    }
+}
diff --git a/src/tbo-object.h b/src/tbo-object.h
new file mode 100644 (file)
index 0000000..0c44725
--- /dev/null
@@ -0,0 +1,7 @@
+#include <gtk/gtk.h>
+#include <cairo.h>
+#include "tbo-types.h"
+
+void tbo_object_flipv (tbo_object *self);
+void tbo_object_fliph (tbo_object *self);
+void tbo_object_get_flip_matrix (tbo_object *self, cairo_matrix_t *mx);
index 0000af8..7388cd6 100644 (file)
@@ -69,6 +69,8 @@ tbo_text_new ()
     text->free = tbo_text_free;
     text->draw = tbo_text_draw;
     text->type = TEXTOBJ;
+    text->flipv = FALSE;
+    text->fliph = FALSE;
     return text;
 }
 
@@ -89,6 +91,8 @@ tbo_text_new_width_params (int x,
     textobj->height = height;
     textobj->data = text_data_new (text, font, r, g, b);
     textobj->type = TEXTOBJ;
+    textobj->flipv = FALSE;
+    textobj->fliph = FALSE;
     return textobj;
 }
 
@@ -132,14 +136,20 @@ tbo_text_draw (TextObj *self, Frame *frame, cairo_t *cr)
         self->height = self->height * factorw;
     }
 
+    // Fliping
+    cairo_matrix_t mx = {1, 0, 0, 1, 0, 0};
+    tbo_object_get_flip_matrix (self, &mx);
+
     cairo_rectangle(cr, frame->x+2, frame->y+2, frame->width-4, frame->height-4);
     cairo_clip (cr);
     cairo_translate (cr, frame->x+self->x, frame->y+self->y);
     cairo_rotate (cr, self->angle);
     cairo_scale (cr, factorw, factorh);
+    cairo_transform (cr, &mx);
 
     pango_cairo_show_layout (cr, layout);
 
+    cairo_transform (cr, &mx);
     cairo_scale (cr, 1/factorw, 1/factorh);
     cairo_rotate (cr, -self->angle);
     cairo_translate (cr, -(frame->x+self->x), -(frame->y+self->y));
index a77048d..c51f1d9 100644 (file)
@@ -1,62 +1,67 @@
 # -*- coding: utf-8 -*-
 import gtk
 import gtk.gdk
+import cairo
 import math
 
 class SemiCirculo(gtk.DrawingArea):
-       def __init__(self):
-               gtk.DrawingArea.__init__(self)
-               self.connect("expose-event", self.expose)
-       
-       def expose(self, widget, event):
-               #Creamos un contexto de dibujo cairo
-               self.context = widget.window.cairo_create()
-               
-               #Ajustamos el tamaño del contexto al del widget
-               self.context.rectangle(event.area.x, event.area.y,
-                               event.area.width, event.area.height)
-               self.context.clip()
-       
-               #Llamamos a la función de dibujado
-               self.draw(self.context)
-               return False    
-
-       def draw(self, context):
-               #Adquirimos las coordenadas de origen
-               #y el tamaño del rectangulo del widget,
-               #situando en las variable x e y
-               #el centro del rectangulo.
-               rect = self.get_allocation()
-               x = rect.x + rect.width / 2
-               y = rect.y + rect.height / 2
-
-               #hallamos el radio
-               radius = min(rect.width / 2, rect.height / 2) - 5
-
-               #Dibujamos un arco
-               context.arc(x, y, radius, 0,(1 * math.pi))
-
-               #Elegimos el color de relleno y lo vertemos
-               context.set_source_rgb(0.7, 0.8, 0.1)
-               context.fill_preserve()
-
-               #Elegimos el color del borde y lo dibujamos
-               context.set_source_rgb(0, 0, 0)
-               context.stroke()
+    def __init__(self):
+        gtk.DrawingArea.__init__(self)
+        self.connect("expose-event", self.expose)
+    
+    def expose(self, widget, event):
+        #Creamos un contexto de dibujo cairo
+        self.context = widget.window.cairo_create()
+        
+        #Ajustamos el tamaño del contexto al del widget
+        self.context.rectangle(event.area.x, event.area.y,
+                event.area.width, event.area.height)
+        self.context.clip()
+    
+        #Llamamos a la función de dibujado
+        self.draw(self.context)
+        return False    
+
+    def draw(self, context):
+        #Adquirimos las coordenadas de origen
+        #y el tamaño del rectangulo del widget,
+        #situando en las variable x e y
+        #el centro del rectangulo.
+        rect = self.get_allocation()
+        x = rect.x + rect.width / 2
+        y = rect.y + rect.height / 2
+
+        #hallamos el radio
+        radius = min(rect.width / 2, rect.height / 2) - 5
+
+        #Dibujamos un arco
+        mx = cairo.Matrix(-1,0,0,-1,0,0)
+        context.translate(x, y)
+        context.transform(mx)
+        context.arc(0, 0, radius/2, 0,(1 * math.pi))
+        context.arc(0, 0, radius/10, 0,(2 * math.pi))
+
+        #Elegimos el color de relleno y lo vertemos
+        context.set_source_rgb(0.7, 0.8, 0.1)
+        context.fill_preserve()
+
+        #Elegimos el color del borde y lo dibujamos
+        context.set_source_rgb(0, 0, 0)
+        context.stroke()
 
 def main():
-       window = gtk.Window()
-       semicirculo = SemiCirculo()
+    window = gtk.Window()
+    semicirculo = SemiCirculo()
 
-       # Añadimos nuestro widget a la ventana
-       window.add(semicirculo)         
-       # Conectamos el evento destroy con la salida del bucle de eventos
-       window.connect("destroy", gtk.main_quit)
-       # Dibujamos toda la ventana
-       window.show_all()
+    # Añadimos nuestro widget a la ventana
+    window.add(semicirculo)     
+    # Conectamos el evento destroy con la salida del bucle de eventos
+    window.connect("destroy", gtk.main_quit)
+    # Dibujamos toda la ventana
+    window.show_all()
 
-       # Comenzamos el bucle de eventos
-       gtk.main()
+    # Comenzamos el bucle de eventos
+    gtk.main()
 
 if __name__ == "__main__":
-       main()
+    main()