• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /macosx-10.10.1/pyobjc-45/2.5/pyobjc/pyobjc-framework-Quartz/Examples/Programming with Quartz/BasicDrawing/
1from Quartz import *
2import Quartz
3
4import Utilities
5
6import sys
7
8def drawQuartzRomanText(context):
9    text = "Quartz"
10    textlen = len(text)
11    fontSize = 60
12
13    opaqueBlack = [0.0, 0.0, 0.0, 1.0]
14    opaqueRed   = [0.663, 0.0, 0.031, 1.0]
15
16    # Set the fill color space. This sets the
17    # fill painting color to opaque black.
18    CGContextSetFillColorSpace(context,
19        Utilities.getTheCalibratedRGBColorSpace())
20
21    # The Cocoa framework calls the draw method with an undefined
22    # value of the text matrix. It's best to set it to what is needed by
23    # this code: the identity transform.
24    CGContextSetTextMatrix(context, CGAffineTransformIdentity)
25
26    # Set the font with the PostScript name "Times-Roman", at
27    # fontSize points, with the MacRoman encoding.
28    CGContextSelectFont(context, "Times-Roman", fontSize, kCGEncodingMacRoman)
29
30    # The default text drawing mode is fill. Draw the text at (70, 400).
31    CGContextShowTextAtPoint(context, 70, 400, text, textlen)
32
33    # Set the fill color to red.
34    CGContextSetFillColor(context, opaqueRed)
35
36    # Draw the next piece of text where the previous one left off.
37    CGContextShowText(context, text, textlen)
38
39    for i in range(3):
40        # Get the current text pen position.
41        p = CGContextGetTextPosition(context)
42        # Translate to the current text pen position.
43        CGContextTranslateCTM(context, p.x, p.y)
44
45        # Rotate clockwise by 90 degrees for the next
46        # piece of text.
47        CGContextRotateCTM(context, Utilities.DEGREES_TO_RADIANS(-90))
48        # Draw the next piece of text in blac at the origin.
49        CGContextSetFillColor(context, opaqueBlack)
50        CGContextShowTextAtPoint(context, 0, 0, text, textlen)
51        # Draw the next piece of text where the previous piece
52        # left off and paint it with red.
53        CGContextSetFillColor(context, opaqueRed)
54        CGContextShowText(context, text, textlen)
55
56
57def myCGContextStrokeLineSegments(context, s, count):
58    # CGContextStrokeLineSegments is available only on Tiger and later
59    # so if it isn't available, use an emulation of
60    # CGContextStrokeLineSegments. It is better to use the
61    # built-in CGContextStrokeLineSegments since it has significant
62    # performance optimizations on some hardware.
63    if hasattr(Quartz, 'CGContextStrokeLineSegments'):
64        CGContextStrokeLineSegments(context, s, count)
65    else:
66        CGContextBeginPath(context)
67        for k in xrange(0, count, 2):
68            CGContextMoveToPoint(context, s[k].x, s[k].y)
69            CGContextAddLineToPoint(context, s[k+1].x, s[k+1].y)
70        CGContextStrokePath(context)
71
72_gridLines = []
73def drawGridLines(context):
74    numlines = 60
75
76    if not _gridLines:
77        stepsize = 4.0
78        val = 0
79        for i in xrange(0, 2*numlines, 2):
80            _gridLines.append(CGPointMake(val, -60))
81            _gridLines.append(CGPointMake(val, 200))
82            val += stepsize
83
84        val = -20
85        for i in xrange(2*numlines, 4*numlines, 2):
86            _gridLines.append(CGPointMake(0, val))
87            _gridLines.append(CGPointMake(400, val))
88            val += stepsize
89
90    myCGContextStrokeLineSegments(context, _gridLines,  len(_gridLines))
91
92def drawQuartzTextWithTextModes(context):
93    fillText = "Fill "
94    strokeText = "Stroke "
95    fillAndStrokeText = "FillStroke "
96    invisibleText = "Invisible "
97    clipText = "ClipText "
98    fillStrokeClipText = "FillStrokeClip "
99    fontSize = 40.0
100    extraLeading = 5.0
101    dash = (1,1)
102    opaqueRed = (1.0, 0.0, 0.0, 1.0)
103
104    # Set the fill and stroke color space. This sets the
105    # fill and stroke painting color to opaque black.
106    CGContextSetFillColorSpace(context,
107            Utilities.getTheCalibratedRGBColorSpace())
108    CGContextSetStrokeColorSpace(context,
109            Utilities.getTheCalibratedRGBColorSpace())
110
111    # The Cocoa framework calls the draw method with an undefined
112    # value of the text matrix. It's best to set it to what is needed by
113    # this code: the identity transform.
114    CGContextSetTextMatrix(context, CGAffineTransformIdentity)
115
116    # Set the font with the PostScript name "Times-Roman", at
117    # fontSize points, with the MacRoman encoding.
118    CGContextSelectFont(context, "Times-Roman", fontSize, kCGEncodingMacRoman)
119
120    # ----  Text Line 1 ----
121
122    # Default text drawing mode is fill. Draw the text at (10, 400).
123    CGContextShowTextAtPoint(context, 10, 400, fillText, len(fillText))
124
125    # Set the fill color to red.
126    CGContextSetFillColor(context, opaqueRed)
127
128    CGContextSetTextPosition(context, 180, 400)
129    CGContextShowText(context, fillText, len(fillText))
130
131    # Translate down for the next line of text.
132    CGContextTranslateCTM(context, 0, -(fontSize + extraLeading))
133
134    # ----  Text Line 2 ----
135
136    # Now stroke the text by setting the text drawing mode
137    # to kCGTextStroke. When stroking text, Quartz uses the stroke
138    # color in the graphics state.
139    CGContextSetTextDrawingMode(context, kCGTextStroke)
140    CGContextShowTextAtPoint(context, 10, 400, strokeText, len(strokeText))
141
142    # When stroking text, the line width and other gstate parameters
143    # that affect stroking affect text stroking as well.
144    CGContextSetLineWidth(context, 2)
145    CGContextSetLineDash(context, 0, dash, 2)
146
147    CGContextSetTextPosition(context, 180, 400)
148    CGContextShowText(context, strokeText, len(strokeText))
149
150    # Reset the line dash and line width to their defaults.
151    CGContextSetLineDash(context, 0, None, 0)
152    CGContextSetLineWidth(context, 1)
153
154    # Translate down for the next line of text.
155    CGContextTranslateCTM(context, 0, -(fontSize + extraLeading))
156
157    # ----  Text Line 3 ----
158
159    # Set the text drawing mode so that text is both filled and
160    # stroked. This produces text that is filled with the fill
161    # color and stroked with the stroke color.
162    CGContextSetTextDrawingMode(context, kCGTextFillStroke)
163    CGContextShowTextAtPoint(context, 10, 400,
164            fillAndStrokeText, len(fillAndStrokeText))
165
166    # Now draw again with a thicker stroke width.
167    CGContextSetLineWidth(context, 2)
168    CGContextSetTextPosition(context, 180, 400)
169    CGContextShowText(context, fillAndStrokeText, len(fillAndStrokeText))
170
171    CGContextSetLineWidth(context, 1)
172    CGContextTranslateCTM(context, 0, -(fontSize + extraLeading))
173
174    # ----  Text Line 4 ----
175
176    # Set the text drawing mode to invisible so that the next piece of
177    # text does not appear. Quartz updates the text position as
178    # if it had been drawn.
179    CGContextSetTextDrawingMode(context, kCGTextInvisible)
180    CGContextShowTextAtPoint(context, 10, 400,
181            invisibleText, len(invisibleText))
182
183    CGContextSetTextDrawingMode(context, kCGTextFill)
184
185    CGContextSetTextPosition(context, 180, 400)
186    CGContextShowText(context, fillText, len(fillText))
187
188    CGContextTranslateCTM(context, 0, -(fontSize + extraLeading))
189
190    # ----  Text Line 5 ----
191    CGContextSaveGState(context)
192    if 1:
193        # Use the text as a clipping path.
194        CGContextSetTextDrawingMode(context, kCGTextClip)
195        CGContextShowTextAtPoint(context, 10, 400, clipText, len(clipText))
196
197        # Position and draw a grid of lines.
198        CGContextTranslateCTM(context, 10, 400)
199        drawGridLines(context)
200    CGContextRestoreGState(context)
201
202    CGContextSaveGState(context)
203    if 1:
204        # The current text position is that after the last piece
205        # of text has been drawn. Since CGContextSaveGState/
206        # CGContextRestoreGState do not affect the text position or
207        # the text matrix, the text position is that after the last
208        # text was "drawn", that drawn with the kCGTextClip mode
209        # above. This is where the next text drawn will go if it
210        # isn't explicitly positioned.
211        nextTextPosition = CGContextGetTextPosition(context)
212
213        # Draw so that the text is filled, stroked, and then used
214        # the clip subsequent drawing.
215        CGContextSetTextDrawingMode(context, kCGTextFillStrokeClip)
216
217        # Explicitly set the text position.
218        CGContextSetTextPosition(context, 180, 400)
219        nextTextPosition = CGContextGetTextPosition(context)
220
221        CGContextShowText(context, fillStrokeClipText, len(fillStrokeClipText))
222        # Adjust the location of the grid lines so that they overlap the
223        # text just drawn.
224        CGContextTranslateCTM(context, nextTextPosition.x, nextTextPosition.y)
225        # Draw the grid lines clipped by the text.
226        drawGridLines(context)
227    CGContextRestoreGState(context)
228
229# showFlippedTextAtPoint is a cover routine for CGContextShowText
230# that is useful for drawing text in a coordinate system where the y axis
231# is flipped relative to the default Quartz coordinate system.
232#
233# This code assumes that the text matrix is only used to
234# flip the text, not to perform scaling or any other
235# possible use of the text matrix.
236#
237# This function preserves the a, b, c, and d components of
238# the text matrix across its execution but updates the
239# tx, ty components (the text position) to reflect the
240# text just drawn. If all the text you draw is flipped, it
241# isn't necessary to continually set the text matrix. Instead
242# you could simply call CGContextSetTextMatrix once with
243# the flipped matrix each time your drawing
244# code is called.
245def showFlippedTextAtPoint(c, x, y, text, textLen):
246    t = CGAffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)
247    # Get the existing text matrix.
248    s = CGContextGetTextMatrix(c)
249    # Set the text matrix to the one that flips in y.
250    CGContextSetTextMatrix(c, t)
251    # Draw the text at the point.
252    CGContextShowTextAtPoint(c, x, y, text, textLen)
253    # Get the updated text position.
254    p = CGContextGetTextPosition(c)
255    # Update the saved text matrix to reflect the updated
256    # text position.
257    s.tx = p.x ; s.ty = p.y
258    # Reset to the text matrix in effect when this
259    # routine was called but with the text position updated.
260    CGContextSetTextMatrix(c, s)
261
262
263def drawQuartzTextWithTextMatrix(context):
264    fontSize = 60.0
265    extraLeading = 10.0
266    text = "Quartz "
267    textlen = len(text)
268
269    # The Cocoa framework calls the draw method with an undefined
270    # value of the text matrix. It's best to set it to what is needed by
271    # this code. Initially that is the identity transform.
272    CGContextSetTextMatrix(context, CGAffineTransformIdentity)
273
274    # Set the font with the PostScript name "Times-Roman", at
275    # fontSize points, with the MacRoman encoding.
276    CGContextSelectFont(context, "Times-Roman", fontSize, kCGEncodingMacRoman)
277
278    # ----  Text Line 1 ----
279
280    # Draw the text at (10, 600).
281    CGContextShowTextAtPoint(context, 10, 600, text, textlen)
282
283    # Get the current text position. The text pen is at the trailing
284    # point from the text just drawn.
285    textPosition = CGContextGetTextPosition(context)
286
287    # Set the text matrix to one that flips text in y and sets
288    # the text position to the user space coordinate (0,0).
289    t = CGAffineTransformMake(1, 0, 0, -1, 0, 0)
290    CGContextSetTextMatrix(context, t)
291
292    # Set the text position to the point where the previous text ended.
293    CGContextSetTextPosition(context, textPosition.x, textPosition.y)
294
295    # Draw the text at the current text position. It will be drawn
296    # flipped in y, relative to the text drawn previously.
297    CGContextShowText(context, text, textlen)
298
299    # ----  Text Line 2 ----
300
301    # Translate down for the next piece of text.
302    CGContextTranslateCTM(context, 0, -(3*fontSize + extraLeading))
303
304    CGContextSaveGState(context)
305    if 1:
306	# Change the text matrix to {1, 0, 0, 3, 0, 0}, which
307	# scales text by a factor of 1 in x and 3 in y.
308	# This scaling doesn't affect any drawing other than text
309	# drawing since only text drawing is transformed by
310	# the text matrix.
311	t = CGAffineTransformMake(1, 0, 0, 3, 0, 0)
312	CGContextSetTextMatrix(context, t)
313
314	# This text is scaled relative to the previous text
315	# because of the text matrix scaling.
316	CGContextShowTextAtPoint(context, 10, 600, text, textlen)
317
318    # This restores the graphics state to what it was at the time
319    # of the last CGContextSaveGState, but since the text matrix
320    # isn't part of the Quartz graphics state, it isn't affected.
321    CGContextRestoreGState(context)
322
323    # The text matrix isn't affected by CGContextSaveGState and
324    # CGContextRestoreGState. You can see this by observing that
325    # the next text piece appears immediately after the first piece
326    # and with the same text scaling as that text drawn with the
327    # text matrix established before we did CGContextRestoreGState.
328    CGContextShowText(context, text, textlen)
329
330    # ----  Text Line 3 ----
331    # Translate down for the next piece of text.
332    CGContextTranslateCTM(context, 0, -(fontSize + extraLeading))
333
334    # Reset the text matrix to the identity matrix.
335    CGContextSetTextMatrix(context, CGAffineTransformIdentity)
336
337    # Now draw text in a flipped coordinate system.
338    CGContextSaveGState(context)
339    if 1:
340	# Flip the coordinate system to mimic a coordinate system with the origin
341	# at the top-left corner of a window. The new origin is at 600 units in
342	# +y from the old origin and the y axis now increases with positive y
343	# going down the window.
344	CGContextConcatCTM(context, CGAffineTransformMake(1, 0, 0, -1, 0, 600))
345	# This text will be flipped along with the CTM.
346 	CGContextShowTextAtPoint(context, 10, 10, text, textlen)
347	# Obtain the user space coordinates of the current text position.
348	textPosition = CGContextGetTextPosition(context)
349	# Draw text at that point but flipped in y.
350	showFlippedTextAtPoint(context, textPosition.x, textPosition.y, text, textlen)
351    CGContextRestoreGState(context)
352