[cairo-commit] [cairo-www] src/cookbook.mdwn src/sharplinescale.mdwn

Carl Worth cworth at freedesktop.org
Sun Aug 19 13:07:42 PDT 2007


 src/cookbook.mdwn       |    3 -
 src/sharplinescale.mdwn |  111 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+), 1 deletion(-)

New commits:
commit aa70efde623b9b3fc2040814c7330ae4feba1976
Author: Carl Worth <cworth at annarchy.freedesktop.org>
Date:   Sun Aug 19 13:07:42 2007 -0700

    web commit by frob: basic info about matrix transformation and some transforms for everyday transformations

diff --git a/src/cookbook.mdwn b/src/cookbook.mdwn
index 427d1b7..c9322f2 100644
--- a/src/cookbook.mdwn
+++ b/src/cookbook.mdwn
@@ -7,4 +7,5 @@
 * [[Rendering_SVG_using_librsvg_in_Python|librsvgpython]]
 * [[Converting_cairo_code_from_Python_to_C_and_back|ConvertCtoPyAndBack]]
 * [[Load_jpg/png/gif/bmp/etc_into_CairoContext_with_help_from_gdk-pixbuf_in_Pycairo/Pygtk|gdkpixbufpycairo]] 
-* [[Keep lines sharp while scale up (python)|sharplinescale]]
\ No newline at end of file
+* [[Keep_lines_sharp_while_scale_up_(in_Pycairo)|sharplinescale]]
+* [[Basic matrix transformation reminder|//cookbook/matrix_transform]]
\ No newline at end of file
diff --git a/src/sharplinescale.mdwn b/src/sharplinescale.mdwn
new file mode 100644
index 0000000..12178d4
--- /dev/null
+++ b/src/sharplinescale.mdwn
@@ -0,0 +1,111 @@
+In the [FAQ](http://cairographics.org/FAQ/#sharp_lines) there is a question 'how to draw a sharp, single-pixel-wide line'.
+Static coords and scale are used in the answer.
+In a real life we have variable coords and scale.
+So below is a simple pygtk program, that create a window with small black '+' and red 'x'.
+Left mouse click scale drawing area up by 1.4, right click scale it down.
+Black '+' lines stay sharp, red 'x' lines scales up and down.
+
+This method works fine for sharp lines, but fails for not-so-sharp ones.
+Feel free to fix it or comment in [my blog](http://blogs.gnome.org/frob/)
+
+    #!/usr/bin/env python
+    import gtk
+    import cairo
+    
+    def shift(x,sz):
+      return  0.5-(x*sz)%1
+    
+    def lineshift(x1,y1,x2,y2,sz):
+      dx1 = shift(x1,sz)
+      dy1 = shift(y1,sz)
+      dx2 = shift(x2,sz)
+      dy2 = shift(y2,sz)
+      dx = max(dx1,dx2)
+      dy = max(dy1,dy2)
+      return dx,dy
+
+    class MainWindow(gtk.Window):
+      def __init__(self, parent=None):
+        gtk.Window.__init__(self)
+        try:
+          self.set_screen(parent.get_screen())
+        except AttributeError:
+            self.connect('destroy', lambda *w: gtk.main_quit())
+        self.zoom = 1
+        self.set_title("pycairo test")
+        self.set_default_size(400, 300)
+        self.da = gtk.DrawingArea()
+        self.da.connect("button_press_event",self.on_button_press)
+        self.da.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+        self.add(self.da)
+        self.da.connect('expose_event', self.expose)
+        self.show_all()
+    
+      def expose (self,da,event):
+        ctx = da.window.cairo_create()
+        sz = self.zoom
+        ctx.set_line_width(1)
+
+        ## red 'x' starts here
+        ctx.save()
+        ## coords of the 1st stem
+        x1,y1,x2,y2 = 30,10,50,30 
+        ctx.set_source_rgb(1,0,0)
+        m = cairo.Matrix(self.zoom,0,0,self.zoom,0,0)
+        ctx.transform(m)
+        ctx.move_to(x1,y1)
+        ctx.line_to(x2,y2)
+        ctx.stroke()
+        ctx.restore()
+
+        ctx.save()
+        x1,y1,x2,y2 = 50,10,30,30
+        ## coords of the 2nd stem
+        ctx.set_source_rgb(1,0,0)
+        m = cairo.Matrix(self.zoom,0,0,self.zoom,0,0)
+        ctx.transform(m)
+        ctx.move_to(x1,y1)
+        ctx.line_to(x2,y2)
+        ctx.stroke()
+        ctx.restore()
+        
+        ## black '+' starts here
+        ctx.save()
+        x1,y1,x2,y2 = 10,20,20,20
+        ## calculate 0.5 shift
+        dx,dy = lineshift(x1,y1,x2,y2,sz)
+        m = cairo.Matrix(self.zoom,0,0,self.zoom,dx,dy)
+        ctx.transform(m)
+        ctx.move_to(x1,y1)
+        ctx.line_to(x2,y2)
+        ## do not stroke it inside of save()/restore()
+        ctx.restore()
+
+        ctx.save()
+        x1,y1,x2,y2  = 15,15,15,25
+        ## calculate 0.5 shift
+        dx,dy = lineshift(x1,y1,x2,y2,sz)
+        m = cairo.Matrix(self.zoom,0,0,self.zoom,dx,dy)
+        ctx.transform(m)
+        ctx.move_to(x1,y1)
+        ctx.line_to(x2,y2)
+        ## do not stroke it inside of save()/restore()
+        ctx.restore()
+        ## now stroke both black '+' stems
+        ctx.stroke()
+
+      def on_button_press(self,da,event):
+        if event.button == 1:
+          self.zoom*=1.4
+        if event.button == 3:
+          self.zoom/=1.4
+        ## I'm lazy to send 'expose' signal, so I just hide/show drawing area here
+        da.hide()
+        da.show()
+
+    def main():
+      MainWindow()
+      gtk.main()
+    
+    if __name__ == '__main__':
+      main()
\ No newline at end of file


More information about the cairo-commit mailing list