[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