diff options
| author | pinky <> | 2007-01-07 21:41:39 +0000 |
|---|---|---|
| committer | pinky <> | 2007-01-07 21:41:39 +0000 |
| commit | 05bb5d58295cd959c34f1fbcd5b605cd6dafaacc (patch) | |
| tree | 3b3651037037c1617a54ef3d216e8c11ea8cdddf /bin/reportlab/docs/graphguide/ch3_shapes.py | |
| parent | 62524af2f41454a2302efb21f15a95318d257a76 (diff) | |
Repotrlab 2.0
bzr revid: pinky-b8333ccaab5dad8ff965b6c380fadadf30d5212a
Diffstat (limited to 'bin/reportlab/docs/graphguide/ch3_shapes.py')
| -rw-r--r-- | bin/reportlab/docs/graphguide/ch3_shapes.py | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/bin/reportlab/docs/graphguide/ch3_shapes.py b/bin/reportlab/docs/graphguide/ch3_shapes.py new file mode 100644 index 00000000000..375513a037e --- /dev/null +++ b/bin/reportlab/docs/graphguide/ch3_shapes.py @@ -0,0 +1,416 @@ +#Copyright ReportLab Europe Ltd. 2000-2004 +#see license.txt for license details +#history http://www.reportlab.co.uk/cgi-bin/viewcvs.cgi/public/reportlab/trunk/reportlab/docs/graphguide/ch3_shapes.py + +from reportlab.tools.docco.rl_doc_utils import * +from reportlab.graphics.shapes import * + +heading1("Shapes") + +disc(""" +This chapter describes the concept of shapes and their importance +as building blocks for all output generated by the graphics library. +Some properties of existing shapes and their relationship to +diagrams are presented and the notion of having different renderers +for different output formats is briefly introduced. +""") + +heading2("Available Shapes") + +disc(""" +Drawings are made up of Shapes. +Absolutely anything can be built up by combining the same set of +primitive shapes. +The module $shapes.py$ supplies a number of primitive shapes and +constructs which can be added to a drawing. +They are: +""") + +bullet("Rect") +bullet("Circle") +bullet("Ellipse") +bullet("Wedge (a pie slice)") +bullet("Polygon") +bullet("Line") +bullet("PolyLine") +bullet("String") +bullet("Group") +bullet("Path (<i>not implemented yet, but will be added in the future</i>)") + +disc(""" +The following drawing, taken from our test suite, shows most of the +basic shapes (except for groups). +Those with a filled green surface are also called <i>solid shapes</i> +(these are $Rect$, $Circle$, $Ellipse$, $Wedge$ and $Polygon$). +""") + +from reportlab.graphics import testshapes + +t = testshapes.getDrawing06() +draw(t, "Basic shapes") + + +heading2("Shape Properties") + +disc(""" +Shapes have two kinds of properties - some to define their geometry +and some to define their style. +Let's create a red rectangle with 3-point thick green borders: +""") + +eg(""" +>>> from reportlab.graphics.shapes import Rect +>>> from reportlab.lib.colors import red, green +>>> r = Rect(5, 5, 200, 100) +>>> r.fillColor = red +>>> r.strokeColor = green +>>> r.strokeWidth = 3 +>>> +""") + +from reportlab.graphics.shapes import Rect +from reportlab.lib.colors import red, green +d = Drawing(220, 120) +r = Rect(5, 5, 200, 100) +r.fillColor = red +r.strokeColor = green +r.strokeWidth = 3 +d.add(r) +draw(d, "red rectangle with green border") + +disc(""" +<i>Note: In future examples we will omit the import statements.</i> +""") + +disc(""" +All shapes have a number of properties which can be set. +At an interactive prompt, we can use their <i>dumpProperties()</i> +method to list these. +Here's what you can use to configure a Rect: +""") + +eg(""" +>>> r.dumpProperties() +fillColor = Color(1.00,0.00,0.00) +height = 100 +rx = 0 +ry = 0 +strokeColor = Color(0.00,0.50,0.00) +strokeDashArray = None +strokeLineCap = 0 +strokeLineJoin = 0 +strokeMiterLimit = 0 +strokeWidth = 3 +width = 200 +x = 5 +y = 5 +>>> +""") + +disc(""" +Shapes generally have <i>style properties</i> and <i>geometry +properties</i>. +$x$, $y$, $width$ and $height$ are part of the geometry and must +be provided when creating the rectangle, since it does not make +much sense without those properties. +The others are optional and come with sensible defaults. +""") + +disc(""" +You may set other properties on subsequent lines, or by passing them +as optional arguments to the constructor. +We could also have created our rectangle this way: +""") + +eg(""" +>>> r = Rect(5, 5, 200, 100, + fillColor=red, + strokeColor=green, + strokeWidth=3) +""") + +disc(""" +Let's run through the style properties. $fillColor$ is obvious. +$stroke$ is publishing terminology for the edge of a shape; +the stroke has a color, width, possibly a dash pattern, and +some (rarely used) features for what happens when a line turns +a corner. +$rx$ and $ry$ are optional geometric properties and are used to +define the corner radius for a rounded rectangle. +""") + +disc("All the other solid shapes share the same style properties.") + + +heading2("Lines") + +disc(""" +We provide single straight lines, PolyLines and curves. +Lines have all the $stroke*$ properties, but no $fillColor$. +Here are a few Line and PolyLine examples and the corresponding +graphics output: +""") + +eg(""" + Line(50,50, 300,100, + strokeColor=colors.blue, strokeWidth=5) + Line(50,100, 300,50, + strokeColor=colors.red, + strokeWidth=10, + strokeDashArray=[10, 20]) + PolyLine([120,110, 130,150, 140,110, 150,150, 160,110, + 170,150, 180,110, 190,150, 200,110], + strokeWidth=2, + strokeColor=colors.purple) +""") + +d = Drawing(400, 200) +d.add(Line(50,50, 300,100,strokeColor=colors.blue, strokeWidth=5)) +d.add(Line(50,100, 300,50, + strokeColor=colors.red, + strokeWidth=10, + strokeDashArray=[10, 20])) +d.add(PolyLine([120,110, 130,150, 140,110, 150,150, 160,110, + 170,150, 180,110, 190,150, 200,110], + strokeWidth=2, + strokeColor=colors.purple)) +draw(d, "Line and PolyLine examples") + + +heading2("Strings") + +disc(""" +The ReportLab Graphics package is not designed for fancy text +layout, but it can place strings at desired locations and with +left/right/center alignment. +Let's specify a $String$ object and look at its properties: +""") + +eg(""" +>>> s = String(10, 50, 'Hello World') +>>> s.dumpProperties() +fillColor = Color(0.00,0.00,0.00) +fontName = Times-Roman +fontSize = 10 +text = Hello World +textAnchor = start +x = 10 +y = 50 +>>> +""") + +disc(""" +Strings have a textAnchor property, which may have one of the +values 'start', 'middle', 'end'. +If this is set to 'start', x and y relate to the start of the +string, and so on. +This provides an easy way to align text. +""") + +disc(""" +Strings use a common font standard: the Type 1 Postscript fonts +present in Acrobat Reader. +We can thus use the basic 14 fonts in ReportLab and get accurate +metrics for them. +We have recently also added support for extra Type 1 fonts +and the renderers all know how to render Type 1 fonts. +""") + +##Until now we have worked with bitmap renderers which have to use +##TrueType fonts and which make some substitutions; this could lead +##to differences in text wrapping or even the number of labels on +##a chart between renderers. + +disc(""" +Here is a more fancy example using the code snippet below. +Please consult the ReportLab User Guide to see how non-standard +like 'LettErrorRobot-Chrome' fonts are being registered! +""") + +eg(""" + d = Drawing(400, 200) + for size in range(12, 36, 4): + d.add(String(10+size*2, 10+size*2, 'Hello World', + fontName='Times-Roman', + fontSize=size)) + + d.add(String(130, 120, 'Hello World', + fontName='Courier', + fontSize=36)) + + d.add(String(150, 160, 'Hello World', + fontName='LettErrorRobot-Chrome', + fontSize=36)) +""") + +from reportlab.pdfbase import pdfmetrics +from reportlab import rl_config +rl_config.warnOnMissingFontGlyphs = 0 +afmFile, pfbFile = getJustFontPaths() +T1face = pdfmetrics.EmbeddedType1Face(afmFile, pfbFile) +T1faceName = 'LettErrorRobot-Chrome' +pdfmetrics.registerTypeFace(T1face) +T1font = pdfmetrics.Font(T1faceName, T1faceName, 'WinAnsiEncoding') +pdfmetrics.registerFont(T1font) + +d = Drawing(400, 200) +for size in range(12, 36, 4): + d.add(String(10+size*2, 10+size*2, 'Hello World', + fontName='Times-Roman', + fontSize=size)) + +d.add(String(130, 120, 'Hello World', + fontName='Courier', + fontSize=36)) + +d.add(String(150, 160, 'Hello World', + fontName='LettErrorRobot-Chrome', + fontSize=36)) + +draw(d, 'fancy font example') + + +heading2("""Paths""") + +disc(""" +Postscript paths are a widely understood concept in graphics. +They are not implemented in $reportlab/graphics$ as yet, but they +will be, soon. +""") + +# NB This commented out section is for 'future compatibility' - paths haven't +# been implemented yet, but when they are we can uncomment this back in. + + ##disc("""Postscript paths are a widely understood concept in graphics. A Path + ## is a way of defining a region in space. You put an imaginary pen down, + ## draw straight and curved segments, and even pick the pen up and move + ## it. At the end of this you have described a region, which may consist + ## of several distinct close shapes or unclosed lines. At the end, this + ## 'path' is 'stroked and filled' according to its properties. A Path has + ## the same style properties as a solid shape. It can be used to create + ## any irregular shape.""") + ## + ##disc("""In Postscript-based imaging models such as PDF, Postscript and SVG, + ## everything is done with paths. All the specific shapes covered above + ## are instances of paths; even text strings (which are shapes in which + ## each character is an outline to be filled). Here we begin creating a + ## path with a straight line and a bezier curve:""") + ## + ##eg(""" + ##>>> P = Path(0,0, strokeWidth=3, strokeColor=red) + ##>>> P.lineTo(0, 50) + ##>>> P.curveTo(10,50,80,80,100,30) + ##>>> + ##""") + + ##disc("""As well as being the only way to draw complex shapes, paths offer some + ## performance advantages in renderers which support them. If you want to + ## create a scatter plot with 5000 blue circles of different sizes, you + ## can create 5000 circles, or one path object. With the latter, you only + ## need to set the color and line width once. PINGO just remembers the + ## drawing sequence, and writes it out into the file. In renderers which + ## do not support paths, the renderer will still have to decompose it + ## into 5000 circles so you won't save anything.""") + ## + ##disc("""<b>Note that our current path implementation is an approximation; it + ## should be finished off accurately for PDF and PS.</b>""") + + +heading2("Groups") + +disc(""" +Finally, we have Group objects. +A group has a list of contents, which are other nodes. +It can also apply a transformation - its contents can be rotated, +scaled or shifted. +If you know the math, you can set the transform directly. +Otherwise it provides methods to rotate, scale and so on. +Here we make a group which is rotated and translated: +""") + +eg(""" +>>> g =Group(shape1, shape2, shape3) +>>> g.rotate(30) +>>> g.translate(50, 200) +""") + +disc(""" +Groups provide a tool for reuse. +You can make a bunch of shapes to represent some component - say, +a coordinate system - and put them in one group called "Axis". +You can then put that group into other groups, each with a different +translation and rotation, and you get a bunch of axis. +It is still the same group, being drawn in different places. +""") + +disc("""Let's do this with some only slightly more code:""") + +eg(""" + d = Drawing(400, 200) + + Axis = Group( + Line(0,0,100,0), # x axis + Line(0,0,0,50), # y axis + Line(0,10,10,10), # ticks on y axis + Line(0,20,10,20), + Line(0,30,10,30), + Line(0,40,10,40), + Line(10,0,10,10), # ticks on x axis + Line(20,0,20,10), + Line(30,0,30,10), + Line(40,0,40,10), + Line(50,0,50,10), + Line(60,0,60,10), + Line(70,0,70,10), + Line(80,0,80,10), + Line(90,0,90,10), + String(20, 35, 'Axes', fill=colors.black) + ) + + firstAxisGroup = Group(Axis) + firstAxisGroup.translate(10,10) + d.add(firstAxisGroup) + + secondAxisGroup = Group(Axis) + secondAxisGroup.translate(150,10) + secondAxisGroup.rotate(15) + + d.add(secondAxisGroup) + + thirdAxisGroup = Group(Axis, + transform=mmult(translate(300,10), + rotate(30))) + d.add(thirdAxisGroup) +""") + +d = Drawing(400, 200) +Axis = Group( + Line(0,0,100,0), # x axis + Line(0,0,0,50), # y axis + Line(0,10,10,10), # ticks on y axis + Line(0,20,10,20), + Line(0,30,10,30), + Line(0,40,10,40), + Line(10,0,10,10), # ticks on x axis + Line(20,0,20,10), + Line(30,0,30,10), + Line(40,0,40,10), + Line(50,0,50,10), + Line(60,0,60,10), + Line(70,0,70,10), + Line(80,0,80,10), + Line(90,0,90,10), + String(20, 35, 'Axes', fill=colors.black) + ) +firstAxisGroup = Group(Axis) +firstAxisGroup.translate(10,10) +d.add(firstAxisGroup) +secondAxisGroup = Group(Axis) +secondAxisGroup.translate(150,10) +secondAxisGroup.rotate(15) +d.add(secondAxisGroup) +thirdAxisGroup = Group(Axis, + transform=mmult(translate(300,10), + rotate(30))) +d.add(thirdAxisGroup) +draw(d, "Groups examples")
\ No newline at end of file |
