• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /macosx-10.10/pyobjc-45/pyobjc/pyobjc-framework-Quartz-2.5.1/Examples/Programming with Quartz/BasicDrawing/
1import os, sys
2
3from Quartz import *
4import Quartz
5
6import objc
7
8def createDataProviderFromPathName (path):
9    # Create a CFURL for the supplied file system path.
10    url = CFURLCreateWithFileSystemPath(None, path, kCFURLPOSIXPathStyle, False)
11    if url is None:
12        print >>sys.stderr, "Couldn't create url!"
13        return None
14
15    # Create a Quartz data provider for the URL.
16    dataProvider = CGDataProviderCreateWithURL(url)
17    if dataProvider is None:
18        print >>sys.stderr, "Couldn't create data provider!"
19        return None
20
21    return dataProvider
22
23def createRGBRampDataProvider():
24    width = 256
25    height = 256
26    imageDataSize = width*height*3
27
28    dataP = objc.allocateBuffer(imageDataSize)
29
30    #    Build an image that is RGB 24 bits per sample. This is a ramp
31    #    where the red component value increases in red from left to
32    #    right and the green component increases from top to bottom.
33    #
34    idx=0
35    for g in xrange(height):
36        for r in xrange(width):
37            dataP[idx] = chr(r)
38            dataP[idx+1] = chr(g)
39            dataP[idx+2] = '\0'
40            idx += 3
41
42    # Once this data provider is created, the data associated
43    # with dataP MUST be available until Quartz calls the data
44    # releaser function 'rgbReleaseRampData'.
45    dataProvider = CGDataProviderCreateWithData(
46            None, dataP, imageDataSize, None)
47    return dataProvider
48
49class MyImageDataInfo (object):
50    fp = None
51    totalBytesRead = 0
52    skippedBytes = 0
53    numRewinds = 0
54
55def getBytesSequentialAccessDP(data, buffer, count):
56    buf = data.fp.read(count)
57    buffer[:len(buf)] = buf
58    data.totalBytesRead += len(buf)
59    return len(buf), buffer
60
61def skipBytesSequentialAccessDP(data, count):
62    try:
63        data.fp.seek(count, os.SEEK_CUR)
64        data.skippedBytes += count
65
66    except IOError, msg:
67        print >>sys.stderr, "Couldn't seek %d bytes because of %s"%(count, msg)
68
69
70def rewindSequentialAccessDP(data):
71    # Rewind the beginning of the data.
72    data.fp.seek(0, 0)
73    data.numRewinds += 1
74
75def releaseSequentialAccessDP(data):
76    if data is not None:
77        print >>sys.stderr, "read %d bytes, skipped %d bytes, rewind called %d times"%(
78                    data.totalBytesRead, data.skippedBytes,
79                    data.numRewinds)
80        data.fp.close()
81
82def createSequentialAccessDPForURL(url):
83    success, pathString = CFURLGetFileSystemRepresentation(url, True, None, 1024)
84    pathString = pathString.rstrip('\0')
85    if not success:
86        print >>sys.stderr, "Couldn't get the path name C string!"
87        return None
88
89    fp = open(pathString, "rb")
90    if fp is None:
91        print >>sys.stderr, "Couldn't open path to file %s!"%(pathString,)
92        return None
93
94    imageDataInfoP = MyImageDataInfo()
95    imageDataInfoP.fp = fp
96
97    provider = CGDataProviderCreate(imageDataInfoP, (
98        getBytesSequentialAccessDP,
99        skipBytesSequentialAccessDP,
100        rewindSequentialAccessDP,
101        releaseSequentialAccessDP))
102    if provider is None:
103        print >>sys.stderr, "Couldn't create data provider!"
104        # Release the info data and cleanup.
105        releaseSequentialAccessDP(imageDataInfoP)
106        return None
107
108    return provider
109
110
111def getBytesGrayRampDirectAccess(info, buffer, offset, count):
112        # This computes a linear gray ramp that is 256 samples wide and
113        # 1 sample high. The ith byte in the image is the sample
114        # value i. This produces a gray ramp that goes from 0 (black) to
115        # FF (white).
116    idx = 0
117
118    # This data provider provides 256 bytes total. If Quartz
119    # requests more data than is available, only return
120    # the available data.
121    if (offset + count) > 256:
122        count = 256 - offset
123
124    for i in range(offset, offset+count):
125        buffer[idx] = chr(i)
126        idx+=1
127
128    return count, buffer
129
130def  createGrayRampDirectAccessDP():
131    provider = CGDataProviderCreateDirectAccess(None, 256, (
132        None,
133        None,
134        getBytesGrayRampDirectAccess,
135        None))
136    if provider is None:
137        print >>sys.stderr, "Couldn't create data provider!"
138        return None
139
140    return provider
141
142# This only builds on Tiger and later.
143def myCGDataProviderCreateWithCFData(data):
144    # If the CFData object passed in is None, this code returns
145    # a None data provider.
146    if data is None:
147        return None
148
149    # Test to see if the Quartz version is available and if so, use it.
150
151    #XXX: force the replacment code to be used
152    #if hasattr(Quartz, 'CGDataProviderCreateWithCFData'):
153    #    return CGDataProviderCreateWithCFData(data)
154
155    dataSize = CFDataGetLength(data)
156    provider = CGDataProviderCreateWithData(data, buffer(data), dataSize, None)
157    return provider
158
159def createDataConsumerFromPathName(path):
160    # Create a CFURL for the supplied file system path.
161    url = CFURLCreateWithFileSystemPath (None, path, kCFURLPOSIXPathStyle, False)
162    if url is None:
163        print >>sys.stderr, "Couldn't create url!"
164        return None
165    # Create a Quartz data provider for the URL.
166    dataConsumer = CGDataConsumerCreateWithURL(url)
167    if dataConsumer is None:
168        print >>sys.stderr, "Couldn't create data consumer!"
169        return None
170
171    return dataConsumer
172
173def myCFDataConsumerPutBytes(data, buffer, count):
174    # Append 'count' bytes from 'buffer' to the CFData
175    # object 'data'.
176    CFDataAppendBytes(data, buffer, count)
177    return count
178
179# This only builds on Tiger and later.
180def myCGDataConsumerCreateWithCFData(data):
181    # If the CFData object passed in is None, this code returns
182    # a None data consumer.
183    if data is None:
184        return None
185
186    # Test to see if the Quartz version is available.
187
188    # XXX: force the replacement code to be used:
189    #if hasattr(Quartz, 'CGDataConsumerCreateWithCFData'):
190    #    return CGDataConsumerCreateWithCFData(data)
191
192    consumer = CGDataConsumerCreate(data, (
193        myCFDataConsumerPutBytes, None))
194    return consumer
195