[cairo-commit] [cairo-www] src/cairomm.mdwn src/cookbook src/pycairo src/win32quickstart.mdwn
Carl Worth
cworth at freedesktop.org
Wed Jul 4 09:49:00 PDT 2007
src/cairomm.mdwn | 10 +-
src/cookbook/convertctopyandback.mdwn | 17 +++
src/cookbook/librsvgpython.mdwn | 85 +++++++++++++++++
src/cookbook/roundedrectangles.mdwn | 109 +++++++++++++++++++++
src/pycairo/ressources.mdwn | 37 +++++++
src/win32quickstart.mdwn | 169 ++++++++++++++++++++++++++++++++++
6 files changed, 423 insertions(+), 4 deletions(-)
New commits:
commit b0a55cbd6e62c5a0ecbe0ff44f983747603fb74e
Author: JonathonJongsma <jonathon.jongsma at gmail.com>
Date: Wed Jul 4 09:49:00 2007 -0700
add link to drawing area documentation of the gtkmm manual
diff --git a/src/cairomm.mdwn b/src/cairomm.mdwn
index 7ffea94..ac69b30 100644
--- a/src/cairomm.mdwn
+++ b/src/cairomm.mdwn
@@ -8,15 +8,15 @@ Standard Template Library where it makes sense.
# Status
cairomm wraps all relevant parts of the cairo API and is
-API/ABI-stable. cairomm is used by [gtkmm][] since 2.10.
+API/ABI-stable. cairomm is used by [gtkmm](http://gtkmm.org/) since 2.10.
# Download
There have been several releases, which you can download from the
[cairo release area](/releases/). If you want bleeding-edge code, (or
if you want to help out with development or cairomm), you can also
-check out cairomm from CVS. Freedesktop.org has some instructions on
-[using CVS][cvs]. You can also view the code online with [viewcvs][].
+check out cairomm from git. Freedesktop.org has some instructions on
+[using git](http://www.freedesktop.org/wiki/Infrastructure/git). You can also view the code online with [gitweb](http://gitweb.cairographics.org/?p=cairomm.git;a=summary).
# Documentation
@@ -28,7 +28,9 @@ documentation](/manual/) as well.
In addition to the API documentation, there are several small example
programs which ship with cairomm and demonstrate some of the basic
functionality. These examples are in the examples/ directory of the
-release tarball or can be [browsed online][examples].
+release tarball or can be [browsed online](http://gitweb.cairographics.org/?p=cairomm.git;a=tree;f=examples).
+
+There is also some tutorial-like documentation available in the gtkmm manual. The [Drawing Area chapter](http://gtkmm.org/docs/gtkmm-2.4/docs/tutorial/html/ch15.html) introduces some basic cairomm drawing concepts. Although the documentation is about using cairomm with gtkmm, most of the concepts apply whether you're using gtkmm or not.
# License
diff --git a/src/cookbook/convertctopyandback.mdwn b/src/cookbook/convertctopyandback.mdwn
new file mode 100644
index 0000000..0c24532
--- /dev/null
+++ b/src/cookbook/convertctopyandback.mdwn
@@ -0,0 +1,17 @@
+
+Converting cairo code between languages is very easy.
+
+##C to Python
+
+the following C code:
+ cairo_new_path (cr);
+ cairo_move_to (cr, x + radius_x, y);
+to Python:
+ cr.new_path()
+ cr.move_to ( x + radius_x, y)
+
+* replace cairo_ with cr
+* remove cr as first argument
+
+Note that in some instances the python bindings will try to simplify, and then a direct translation is not possible. In such a case refer to the source code of [[pycairo]], it is relatively easy to read.
+
diff --git a/src/cookbook/librsvgpython.mdwn b/src/cookbook/librsvgpython.mdwn
new file mode 100644
index 0000000..4c5cc8d
--- /dev/null
+++ b/src/cookbook/librsvgpython.mdwn
@@ -0,0 +1,85 @@
+[[meta title="Rendering SVG with libRSVG,Python and c-types"]]
+Back to [[cookbook]]
+
+
+ # Very primitive librsvg bindings for win32
+ # no error checking, etc.
+ # but hey it works!
+
+ from ctypes import *
+ import cairo
+
+ l=CDLL('librsvg-2-2.dll')
+ g=CDLL('libgobject-2.0-0.dll')
+ g.g_type_init()
+
+
+ class PycairoContext(Structure):
+ _fields_ = [("PyObject_HEAD", c_byte * object.__basicsize__),
+ ("ctx", c_void_p),
+ ("base", c_void_p)]
+
+
+
+ class RsvgDimensionData(Structure):
+ _fields_ = [("width", c_int),
+ ("height", c_int),
+ ("em",c_double),
+ ("ex",c_double)]
+
+
+ svghandlecache = {}
+
+
+ def renderSVG(ctx,filename,x,y):
+
+ if not filename in svghandlecache:
+ error=''
+ handle1 = l.rsvg_handle_new_from_file(filename,error)
+ svghandlecache[filename] = handle1
+ else:
+ handle1 = svghandlecache[filename]
+ #print error
+ #print handle1
+
+ #svgDim = RsvgDimensionData()
+
+ #l.rsvg_handle_get_dimensions(handle1,byref(svgDim))
+
+ #print 'SVG Dimensions: ',svgDim.width,'x',svgDim.height
+
+ #scaleX = float(WIDTH) / float(svgDim.width)
+ #scaleY = float(HEIGHT) / float(svgDim.height)
+ #scaleY = scaleX
+ #scaleX = 1
+ #scaleY = 1
+
+ #print scaleY
+
+ ctx.save()
+ #ctx.scale(scaleX, scaleY)
+ ctx.translate(x,y)
+
+ z = PycairoContext.from_address(id(ctx))
+ #print z.ctx
+
+ #print '>>',l.rsvg_handle_render_cairo(handle1, z.ctx)
+ l.rsvg_handle_render_cairo(handle1, z.ctx)
+ ctx.restore()
+
+
+
+ WIDTH, HEIGHT = 400, 400
+
+ # Setup Cairo
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
+ ctx = cairo.Context(surface)
+
+ #bg
+ bg = WebColour('#FFFFFF')
+ ctx.set_source_rgb(bg[0],bg[1],bg[2])
+ ctx.paint()
+
+ renderSVG(ctx,'ball.svg',0,0)
+
+ surface.write_to_png("test.png")
diff --git a/src/cookbook/roundedrectangles.mdwn b/src/cookbook/roundedrectangles.mdwn
new file mode 100644
index 0000000..036a25e
--- /dev/null
+++ b/src/cookbook/roundedrectangles.mdwn
@@ -0,0 +1,109 @@
+##Method A
+
+From the cairo samples, modified. Gives a very nice shape but takes width and height only as guides.
+
+ def roundedrecA(self,cr,x,y,width,height,radius=5):
+ #/* a custom shape, that could be wrapped in a function */
+ #radius = 5 #/*< and an approximate curvature radius */
+ x0 = radius/2.0 #/*< parameters like cairo_rectangle */
+ y0 = radius/2.0
+ rect_width = width - radius
+ rect_height = height - radius
+
+ cr.save()
+ #cr.set_line_width (0.04)
+ #self.snippet_normalize (cr, width, height)
+
+ x1=x0+rect_width
+ y1=y0+rect_height
+ #if (!rect_width || !rect_height)
+ # return
+ if rect_width/2<radius:
+ if rect_height/2<radius:
+ cr.move_to (x0, (y0 + y1)/2)
+ cr.curve_to (x0 ,y0, x0, y0, (x0 + x1)/2, y0)
+ cr.curve_to (x1, y0, x1, y0, x1, (y0 + y1)/2)
+ cr.curve_to (x1, y1, x1, y1, (x1 + x0)/2, y1)
+ cr.curve_to (x0, y1, x0, y1, x0, (y0 + y1)/2)
+ else:
+ cr.move_to (x0, y0 + radius)
+ cr.curve_to (x0 ,y0, x0, y0, (x0 + x1)/2, y0)
+ cr.curve_to (x1, y0, x1, y0, x1, y0 + radius)
+ cr.line_to (x1 , y1 - radius)
+ cr.curve_to (x1, y1, x1, y1, (x1 + x0)/2, y1)
+ cr.curve_to (x0, y1, x0, y1, x0, y1- radius)
+
+ else:
+ if rect_height/2<radius:
+ cr.move_to (x0, (y0 + y1)/2)
+ cr.curve_to (x0 , y0, x0 , y0, x0 + radius, y0)
+ cr.line_to (x1 - radius, y0)
+ cr.curve_to (x1, y0, x1, y0, x1, (y0 + y1)/2)
+ cr.curve_to (x1, y1, x1, y1, x1 - radius, y1)
+ cr.line_to (x0 + radius, y1)
+ cr.curve_to (x0, y1, x0, y1, x0, (y0 + y1)/2)
+ else:
+ cr.move_to (x0, y0 + radius)
+ cr.curve_to (x0 , y0, x0 , y0, x0 + radius, y0)
+ cr.line_to (x1 - radius, y0)
+ cr.curve_to (x1, y0, x1, y0, x1, y0 + radius)
+ cr.line_to (x1 , y1 - radius)
+ cr.curve_to (x1, y1, x1, y1, x1 - radius, y1)
+ cr.line_to (x0 + radius, y1)
+ cr.curve_to (x0, y1, x0, y1, x0, y1- radius)
+
+ cr.close_path ()
+
+ cr.restore()
+
+##Method B
+From mono moonlight aka mono silverlight. Works very well on larger shapes.
+
+ def roundedrecMoonlight(self,cr,x,y,w,h,radius_x=5,radius_y=5):
+ #from mono moonlight aka mono silverlight
+ #test limits (without using multiplications)
+ # http://graphics.stanford.edu/courses/cs248-98-fall/Final/q1.html
+ ARC_TO_BEZIER = 0.55228475
+ if radius_x > w - radius_x:
+ radius_x = w / 2
+ if radius_y > h - radius_y:
+ radius_y = h / 2
+
+ #approximate (quite close) the arc using a bezier curve
+ c1 = ARC_TO_BEZIER * radius_x
+ c2 = ARC_TO_BEZIER * radius_y
+
+ cr.new_path();
+ cr.move_to ( x + radius_x, y)
+ cr.rel_line_to ( w - 2 * radius_x, 0.0)
+ cr.rel_curve_to ( c1, 0.0, radius_x, c2, radius_x, radius_y)
+ cr.rel_line_to ( 0, h - 2 * radius_y)
+ cr.rel_curve_to ( 0.0, c2, c1 - radius_x, radius_y, -radius_x, radius_y)
+ cr.rel_line_to ( -w + 2 * radius_x, 0)
+ cr.rel_curve_to ( -c1, 0, -radius_x, -c2, -radius_x, -radius_y)
+ cr.rel_line_to (0, -h + 2 * radius_y)
+ cr.rel_curve_to (0.0, -c2, radius_x - c1, -radius_y, radius_x, -radius_y)
+ cr.close_path ()
+
+##Method C
+I can't remember where I got this. If you are the author please add your name. Works well on smaller shapes.
+
+ def roundedrec(self,context,x,y,w,h,r = 10):
+ "Draw a rounded rectangle"
+ # A****BQ
+ # H C
+ # * *
+ # G D
+ # F****E
+
+ context.move_to(x+r,y) # Move to A
+ context.line_to(x+w-r,y) # Straight line to B
+ context.curve_to(x+w,y,x+w,y,x+w,y+r) # Curve to C, Control points are both at Q
+ context.line_to(x+w,y+h-r) # Move to D
+ context.curve_to(x+w,y+h,x+w,y+h,x+w-r,y+h) # Curve to E
+ context.line_to(x+r,y+h) # Line to F
+ context.curve_to(x,y+h,x,y+h,x,y+h-r) # Curve to G
+ context.line_to(x,y+r) # Line to H
+ context.curve_to(x,y,x,y,x+r,y) # Curve to A
+ return
+
diff --git a/src/pycairo/ressources.mdwn b/src/pycairo/ressources.mdwn
new file mode 100644
index 0000000..ba6f1c4
--- /dev/null
+++ b/src/pycairo/ressources.mdwn
@@ -0,0 +1,37 @@
+[[meta title="Pycairo ressources"]]
+
+Various useful ressources about [python cairo bindings](/pycairo).
+
+# API Reference and Documentation
+
+Currently there is no Python specific cairo API documentation. However there is the [cairo C documentation](/manual) which can be useful.
+
+# Tutorials
+
+ * [Cairo Tutorial for Python (and other) Programmers][1]: Generic introduction to cairo concepts oriented to python.
+ * [Cairo Tutorial for PyGTK Programmers][2]: Tutorial about how to use cairo for drawing in [PyGTK](http://www.pygtk.org).
+ * _Writing a widget using cairo and PyGTK 2.8_ [Part 1][3], [Part 2][4]: A translation of the GNOME Journal tutorial by Davyd Madeley from C to Python.
+
+# Cairo-based canvas
+ * [GooCanvas python bindings][5] - python API reference available. (Report bugs [here](https://launchpad.net/pygoocanvas))
+ * [Libccc][6] python bindings - not documented at all.
+ * [HippoCanvas][7] - part of the [OLPC](http://www.laptop.org) project.
+
+# Demos
+
+ * [A Basic Cairo-clock in Python][8] using XShape.
+ * [A simple clock implemented in pygtk and cairo][9].
+ * [A Shogiban for Gnushogi][10].
+
+ [1]: http://www.tortall.net/mu/wiki/CairoTutorial
+ [2]: http://www.tortall.net/mu/wiki/PyGTKCairoTutorial
+ [3]: http://www.pygtk.org/articles/cairo-pygtk-widgets/cairo-pygtk-widgets.htm
+ [4]: http://www.pygtk.org/articles/cairo-pygtk-widgets/cairo-pygtk-widgets2.htm
+
+ [5]: https://developer.berlios.de/projects/pygoocanvas/
+ [6]: http://live.gnome.org/Criawips/CriaCanvas
+ [7]: http://wiki.laptop.org/go/HippoCanvas
+
+ [8]: http://blog.eikke.com/index.php/ikke/2007/02/17/python_cairo_xshape_and_clocks
+ [9]: http://ralph-glass.homepage.t-online.de/clock/readme.html
+ [10]: http://ralph-glass.homepage.t-online.de/shogi/readme.html
\ No newline at end of file
diff --git a/src/win32quickstart.mdwn b/src/win32quickstart.mdwn
new file mode 100644
index 0000000..c5ab8c1
--- /dev/null
+++ b/src/win32quickstart.mdwn
@@ -0,0 +1,169 @@
+[[meta title="Win32 Quickstart"]]
+Back to [[cookbook]]
+
+##Python
+The following is a minimal windows application that uses cairo. It has double buffering and uses the PyWin32 library.
+
+ from win32api import *
+ try:
+ from winxpgui import *
+ except ImportError:
+ from win32gui import *
+
+ import win32con
+ import sys, os
+ import cairo
+
+ def WebColour(sCol):
+ #print sCol
+ ic = [int(sCol[i:i+2], 16)/255.0 for i in range(1, 7, 2)]
+ #print ic
+ return ic
+
+ def roundedRectangle(cr,x,y,w,h,radius_x=5,radius_y=5):
+ #from mono moonlight aka mono silverlight
+ #test limits (without using multiplications)
+ # http://graphics.stanford.edu/courses/cs248-98-fall/Final/q1.html
+ ARC_TO_BEZIER = 0.55228475
+ if radius_x > w - radius_x:
+ radius_x = w / 2
+ if radius_y > h - radius_y:
+ radius_y = h / 2
+
+ #approximate (quite close) the arc using a bezier curve
+ c1 = ARC_TO_BEZIER * radius_x
+ c2 = ARC_TO_BEZIER * radius_y
+
+ cr.new_path();
+ cr.move_to ( x + radius_x, y)
+ cr.rel_line_to ( w - 2 * radius_x, 0.0)
+ cr.rel_curve_to ( c1, 0.0, radius_x, c2, radius_x, radius_y)
+ cr.rel_line_to ( 0, h - 2 * radius_y)
+ cr.rel_curve_to ( 0.0, c2, c1 - radius_x, radius_y, -radius_x, radius_y)
+ cr.rel_line_to ( -w + 2 * radius_x, 0)
+ cr.rel_curve_to ( -c1, 0, -radius_x, -c2, -radius_x, -radius_y)
+ cr.rel_line_to (0, -h + 2 * radius_y)
+ cr.rel_curve_to (0.0, -c2, radius_x - c1, -radius_y, radius_x, -radius_y)
+ cr.close_path ()
+
+
+ class MainWindow(object):
+ def __init__(self):
+ message_map = {
+ win32con.WM_DESTROY: self.OnDestroy,
+ win32con.WM_PAINT: self.OnPaint,
+ win32con.WM_SETCURSOR: self.OnCursor,
+ win32con.WM_ERASEBKGND: self.OnBackgroundErase,
+ win32con.WM_LBUTTONDOWN: self.OnClick,
+ win32con.WM_KEYUP: self.OnKey,
+ #win32con.WM_COMMAND: self.OnCommand,
+ #win32con.WM_USER+20 : self.OnTaskbarNotify,
+ # owner-draw related handlers.
+ #win32con.WM_MEASUREITEM: self.OnMeasureItem,
+ #win32con.WM_DRAWITEM: self.OnDrawItem,
+ }
+ # Register the Window class.
+ wc = WNDCLASS()
+ hinst = wc.hInstance = GetModuleHandle(None)
+ self.hinst = hinst
+ wc.lpszClassName = "CairoWindow"
+ wc.lpfnWndProc = message_map # could also specify a wndproc.
+ classAtom = RegisterClass(wc)
+ # Create the Window.
+ style = win32con.WS_THICKFRAME | win32con.WS_MAXIMIZEBOX | win32con.WS_MINIMIZEBOX | win32con.WS_SYSMENU | win32con.WS_VISIBLE
+ self.hwnd = CreateWindow( classAtom, "Cairo is the greatest thing!", style, \
+ 0, 0, 550, 350, \
+ 0, 0, hinst, None)
+ UpdateWindow(self.hwnd)
+
+
+ def OnKey(self, hWnd, msg, wParam, lparam):
+ if wParam == 38: #up
+ print "up"
+ elif wParam == 40: #down
+ print "down"
+
+ def OnClick(self, hWnd, msg, wparam, lparam):
+ x = LOWORD(lparam)
+ y = HIWORD(lparam)
+
+ def Render(self):
+ try:
+ InvalidateRect(self.hwnd, None, True)
+ return True
+ except:
+ print "That didn't work"
+ return False
+
+ def OnPaint(self, hWnd, msg, wparam, lparam):
+ hdc, ps = BeginPaint(hWnd)
+ rc = GetClientRect(hWnd)
+ left, top, right, bottom = rc
+
+ width = right - left
+ height = bottom - top
+ x = left
+ y = top
+
+ _buffer = CreateCompatibleDC(hdc)
+ #Double Buffer Stage 1
+ hBitmap = CreateCompatibleBitmap(hdc,width,height)
+ hOldBitmap = SelectObject(_buffer, hBitmap )
+
+
+ surf = cairo.Win32Surface(_buffer)
+ ctx = cairo.Context(surf)
+
+ ctx.set_source_rgb(1,1,1)
+ ctx.paint()
+
+
+ roundedRectangle(ctx, 50, 50, 250, 250, 10, 10)
+ clr = WebColour("#F0FEE9")
+ ctx.set_source_rgb(clr[0],clr[1],clr[2])
+ ctx.fill_preserve()
+ clr = WebColour("#B3FF8D")
+ ctx.set_source_rgb(clr[0],clr[1],clr[2])
+ ctx.stroke()
+
+ ctx.set_source_rgb(0,0,0)
+ ctx.select_font_face("Arial",cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
+ ctx.set_font_size(10)
+
+ txt = "Cairo is the greatest thing!"
+
+ ctx.move_to(5,10)
+ ctx.show_text(txt)
+
+ surf.finish()
+
+ BitBlt(hdc,0, 0, width, height,
+ _buffer, x, y, win32con.SRCCOPY)
+
+ SelectObject( _buffer, hOldBitmap )
+ DeleteObject( hBitmap )
+ DeleteDC( _buffer )
+
+ EndPaint(hWnd,ps)
+
+ def OnCursor(self, hwnd, msg, wparam, lparam):
+ #IDC_HAND = 32649
+ #IDC_ARROW
+ cur_normal = LoadCursor(0, win32con.IDC_ARROW)
+ SetCursor(cur_normal)
+
+ def OnBackgroundErase(self, hwnd, msg, wparam, lparam):
+ return False
+
+
+ def OnDestroy(self, hwnd, msg, wparam, lparam):
+ #nid = (self.hwnd, 0)
+ #Shell_NotifyIcon(NIM_DELETE, nid)
+ PostQuitMessage(0) # Terminate the app.
+ print "Exited."
+
+
+ w=MainWindow()
+ PumpMessages()
+
+##Other?
\ No newline at end of file
More information about the cairo-commit
mailing list