1 2import math 3 4from Quartz import * 5import Quartz 6from CoreFoundation import * 7 8class ExportInfo (object): 9 command = None 10 fileType = None 11 useQTForExport = False 12 dpi = 1 13 14def DEGREES_TO_RADIANS(degrees): 15 return degrees * math.pi / 180 16 17 18gScalingFactor = 1.0 19 20# These routines are used for getting the correct results when 21# drawing shadows and patterns with Quartz and exporting the 22# results as bits. This is a hack; in principle the scaling 23# factor should be passed to the draw proc. 24def setScalingFactor(scalingFactor): 25 if scalingFactor > 0: 26 gScalingFactor = scalingFactor 27 28def getScalingFactor(): 29 return gScalingFactor 30 31_appBundle = None 32def getAppBundle(): 33 global _appBundle 34 35 if _appBundle is None: 36 _appBundle = CFBundleGetMainBundle() 37 38 return _appBundle 39 40 41# 42# This version of getTheRGBColorSpace returns 43# the DeviceRGB color space. 44# 45_deviceRGB = None 46def getTheRGBColorSpace(): 47 global _deviceRGB 48 49 # Set once, the first time this function is called. 50 if _deviceRGB is None: 51 _deviceRGB = CGColorSpaceCreateDeviceRGB() 52 53 return _deviceRGB 54 55 56_genericRGBColorSpace = None 57def getTheCalibratedRGBColorSpace(): 58 global _genericRGBColorSpace 59 60 if _genericRGBColorSpace is None: 61 _genericRGBColorSpace = CGColorSpaceCreateWithName( 62 kCGColorSpaceGenericRGB) 63 64 return _genericRGBColorSpace 65 66_genericGrayColorSpace = None 67def getTheCalibratedGrayColorSpace(): 68 global _genericGrayColorSpace 69 70 if _genericGrayColorSpace is None: 71 _genericGrayColorSpace = CGColorSpaceCreateWithName( 72 kCGColorSpaceGenericGray) 73 return _genericGrayColorSpace 74 75 76_genericSRGBColorSpace = None 77def getTheSRGBColorSpace(): 78 # This only works on 10.5 or later 79 global _genericSRGBColorSpace 80 81 if _genericSRGBColorSpace is None: 82 _genericSRGBColorSpace = CGColorSpaceCreateWithName( 83 kCGColorSpaceGenericRGB) # XXX: should be GenericSRGB 84 return _genericSRGBColorSpace 85 86def getTheDisplayColorSpace(): 87 # This is a hack, basicly here because the C implementation uses APIs that 88 # aren't wrapped yet. 89 return getTheRGBColorSpace() 90 91 92_rgbWhite = None 93def getRGBOpaqueWhiteColor(): 94 global _rgbWhite 95 96 if _rgbWhite is None: 97 opaqueWhite = (1.0, 1.0, 1.0, 1.0) 98 _rgbWhite = CGColorCreate(getTheCalibratedRGBColorSpace(), opaqueWhite) 99 return _rgbWhite 100 101_rgbBlack = None 102def getRGBOpaqueBlackColor(): 103 global _rgbBlack 104 if _rgbBlack is None: 105 opaqueBlack = (0, 0, 0, 1) 106 _rgbBlack = CGColorCreate( 107 getTheCalibratedRGBColorSpace(), opaqueBlack) 108 return _rgbBlack 109 110_rgbGray = None 111def getRGBOpaqueGrayColor(): 112 global _rgbGray 113 if _rgbGray is None: 114 opaqueGray = (0.9, 0.9, 0.9, 1) 115 _rgbGray = CGColorCreate( 116 getTheCalibratedRGBColorSpace(), opaqueGray) 117 return _rgbGray 118 119_rgbRed = None 120def getRGBOpaqueRedColor(): 121 global _rgbRed 122 if _rgbRed is None: 123 opaqueRed = (0.663, 0, 0.031, 1) 124 _rgbRed = CGColorCreate( 125 getTheCalibratedRGBColorSpace(), opaqueRed) 126 return _rgbRed 127 128_rgbBlue = None 129def getRGBOpaqueBlueColor(): 130 global _rgbBlue 131 if _rgbBlue is None: 132 opaqueBlue = (0.482, 0.62, 0.871, 1) 133 _rgbBlue = CGColorCreate( 134 getTheCalibratedRGBColorSpace(), opaqueBlue) 135 return _rgbBlue 136 137_rgbPurple = None 138def getRGBOpaquePurpleColor(): 139 global _rgbPurple 140 if _rgbPurple is None: 141 opaquePurple = (0.69, 0.486, 0.722, 1) 142 _rgbPurple = CGColorCreate( 143 getTheCalibratedRGBColorSpace(), opaquePurple) 144 return _rgbPurple 145 146_rgbDarkBlue = None 147def getRGBOpaqueDarkBlueColor(): 148 global _rgbDarkBlue 149 if _rgbDarkBlue is None: 150 opaqueDarkBlue = (0.11, 0.208, 0.451, 1) 151 _rgbDarkBlue = CGColorCreate( 152 getTheCalibratedRGBColorSpace(), opaqueDarkBlue) 153 return _rgbDarkBlue 154 155_rgbBrown = None 156def getRGBOpaqueBrownColor(): 157 global _rgbBrown 158 if _rgbBrown is None: 159 opaqueBrown = (0.325, 0.208, 0.157, 1) 160 _rgbBrown = CGColorCreate( 161 getTheCalibratedRGBColorSpace(), opaqueBrown) 162 return _rgbBrown 163 164_rgbOrange = None 165def getRGBOpaqueOrangeColor(): 166 global _rgbOrange 167 if _rgbOrange is None: 168 opaqueOrange = (0.965, 0.584, 0.059, 1) 169 _rgbOrange = CGColorCreate( 170 getTheCalibratedRGBColorSpace(), opaqueOrange) 171 return _rgbOrange 172 173_rgbYellow = None 174def getRGBOpaqueYellowColor(): 175 global _rgbYellow 176 if _rgbYellow is None: 177 opaqueYellow = (1, 0.816, 0, 1) 178 _rgbYellow = CGColorCreate( 179 getTheCalibratedRGBColorSpace(), opaqueYellow) 180 return _rgbYellow 181 182_rgbGreen = None 183def getRGBOpaqueGreenColor(): 184 global _rgbGreen 185 if _rgbGreen is None: 186 opaqueGreen = (0.584, 0.871, 0.318, 1) 187 _rgbGreen = CGColorCreate( 188 getTheCalibratedRGBColorSpace(), opaqueGreen) 189 return _rgbGreen 190 191_rgbDarkGreen = None 192def getRGBOpaqueDarkGreenColor(): 193 global _rgbDarkGreen 194 if _rgbDarkGreen is None: 195 opaqueDarkGreen = (0.404, 0.808, 0.239, 1) 196 _rgbDarkGreen = CGColorCreate( 197 getTheCalibratedRGBColorSpace(), opaqueDarkGreen) 198 return _rgbDarkGreen 199 200def myCGContextAddEllipseInRect(context, r): 201 if hasattr(Quartz, 'CGContextAddEllipseInRect'): 202 CGContextAddEllipseInRect(context, r) 203 204 else: 205 # This is not a perfect emulation but is correct as long as there is 206 # not an open subpath already in the current path. In that case the 207 # CGContextClosePath here would not necessarily produce the desired 208 # result. 209 CGContextSaveGState(context) 210 if 1: 211 # Translate to the center of the ellipse. 212 CGContextTranslateCTM(context, 213 CGRectGetMidX(r), 214 CGRectGetMidY(r)) 215 # Scale by half the width and height of the rectangle 216 # bounding the ellipse. 217 CGContextScaleCTM(context, r.size.width/2, r.size.height/2) 218 # Establish a current point at the first point 219 # on the ellipse. This ensures that there 220 # is no line segment connecting the previous 221 # current point to the first point on the subpath. 222 CGContextMoveToPoint(context, 1, 0) 223 # Circular arc around the ellipse center with 224 # a radius that, when scaled by the CTM, produces 225 # the major and minor axes of the ellipse. Since 226 # CGContextAddEllipseInRect defines the direction 227 # of the path as clockwise, this routine will 228 # draw the arc clockwise also. 229 CGContextAddArc(context, 0, 0, 1, 0, 2*math.pi, 1) 230 CGContextClosePath(context) 231 CGContextRestoreGState(context) 232 233# Routines that are useful for debugging. 234 235def drawPoint(context, p): 236 CGContextSaveGState(context) 237 if 1: 238 # Opaque black. 239 CGContextSetRGBStrokeColor(context, 0, 0, 0, 1) 240 CGContextSetLineWidth(context, 5) 241 CGContextSetLineCap(context, kCGLineCapRound) 242 CGContextMoveToPoint(context, p.x, p.y) 243 CGContextAddLineToPoint(context, p.x, p.y) 244 CGContextStrokePath(context) 245 CGContextRestoreGState(context) 246 247 248def printCTM(context): 249 t = CGContextGetCTM(context) 250 print >>sys.stderr, "CurrentCTM is %r"%(t,) 251 252kTickLength = 5 253kTickDistance = 72 254kAxesLength = (20*kTickDistance) 255 256def drawCoordinateAxes(context): 257 tickLength = kTickLength 258 259 CGContextSaveGState(context) 260 if 1: 261 CGContextBeginPath(context) 262 # Paint the x-axis in red. 263 CGContextSetRGBStrokeColor(context, 1, 0, 0, 1) 264 CGContextMoveToPoint(context, -kTickLength, 0.) 265 CGContextAddLineToPoint(context, kAxesLength, 0.) 266 CGContextDrawPath(context, kCGPathStroke) 267 268 # Paint the y-axis in blue. 269 CGContextSetRGBStrokeColor(context, 0, 0, 1, 1) 270 CGContextMoveToPoint(context, 0, -kTickLength) 271 CGContextAddLineToPoint(context, 0, kAxesLength) 272 CGContextDrawPath(context, kCGPathStroke) 273 274 # Paint the x-axis tick marks in red. 275 CGContextSetRGBStrokeColor(context, 1, 0, 0, 1) 276 for i in range(2): 277 for t in range(0, kAxesLength, kTickDistance): 278 CGContextMoveToPoint(context, t, -tickLength) 279 CGContextAddLineToPoint(context, t, tickLength) 280 281 CGContextDrawPath(context, kCGPathStroke) 282 CGContextRotateCTM(context, math.pi/2.) 283 # Paint the y-axis tick marks in blue. 284 CGContextSetRGBStrokeColor(context, 0, 0, 1, 1) 285 286 drawPoint(context, CGPointZero) 287 CGContextRestoreGState(context) 288 289def drawDebuggingRect(context, rect): 290 CGContextSaveGState(context) 291 if 1: 292 CGContextSetLineWidth(context, 4.) 293 # Draw opaque red from top-left to bottom-right. 294 CGContextSetRGBStrokeColor(context, 1, 0, 0, 1.0) 295 CGContextMoveToPoint(context, rect.origin.x, 296 rect.origin.y + rect.size.height) 297 CGContextAddLineToPoint(context, 298 rect.origin.x + rect.size.width, 299 rect.origin.y) 300 CGContextStrokePath(context) 301 # Draw opaque blue from top-right to bottom-left. 302 CGContextSetRGBStrokeColor(context, 0, 0, 1, 1.0) 303 CGContextMoveToPoint(context, rect.origin.x + rect.size.width, 304 rect.origin.y + rect.size.height) 305 CGContextAddLineToPoint(context, rect.origin.x, rect.origin.y) 306 CGContextStrokePath(context) 307 # Opaque black. 308 CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.) 309 CGContextStrokeRect(context, rect) 310 CGContextRestoreGState(context) 311