5
5
#import " CSVDocument.h"
6
6
#import " CSVRowObject.h"
7
7
8
+ #define MIN_WIDTH 40.0
9
+
10
+ static CGContextRef createRGBABitmapContext (CGSize pixelSize);
11
+
8
12
9
13
/* -----------------------------------------------------------------------------
10
14
Generate a thumbnail for file
@@ -52,21 +56,16 @@ OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thum
52
56
53
57
54
58
// Draw an icon if still interested in the thumbnail
55
- if (false == QLThumbnailRequestIsCancelled (thumbnail)) {
56
- CGFloat startY = 0.0 ;
57
- if (gotRows < numRows) {
58
- startY = thumbnailSize - gotRows * rowHeight;
59
- }
60
- CGRect myBounds = CGRectMake (0.0 , startY, thumbnailSize, thumbnailSize);
61
- CGContextRef context = QLThumbnailRequestCreateContext (thumbnail, myBounds.size , false , NULL );
59
+ if ((gotRows > 0 ) && (false == QLThumbnailRequestIsCancelled (thumbnail))) {
60
+ CGRect maxBounds = CGRectMake (0.0 , 0.0 , thumbnailSize, thumbnailSize);
61
+ CGRect usedBounds = CGRectMake (0.0 , 0.0 , thumbnailSize, thumbnailSize);
62
62
63
- // Draw a mini table
63
+ CGContextRef context = createRGBABitmapContext (maxBounds. size );
64
64
if (context) {
65
- CGContextSaveGState (context);
66
65
67
66
// Flip CoreGraphics coordinate system
68
67
CGContextScaleCTM (context, 1.0 , -1.0 );
69
- CGContextTranslateCTM (context, 0 , -myBounds .size .height );
68
+ CGContextTranslateCTM (context, 0 , -maxBounds .size .height );
70
69
71
70
// Create colors
72
71
CGColorRef borderColor = CGColorCreateGenericRGB (0.67 , 0.67 , 0.67 , 1.0 );
@@ -90,20 +89,26 @@ OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thum
90
89
91
90
// We loop each cell, row by row for each column
92
91
for (NSString *colKey in csvDoc.columnKeys ) {
93
- if (cellX > myBounds .size .width ) {
92
+ if (cellX > maxBounds .size .width ) {
94
93
break ;
95
94
}
96
95
97
- CGRect rowRect = CGRectMake (cellX, 0.0 , myBounds .size .width - cellX, rowHeight);
96
+ CGRect rowRect = CGRectMake (cellX, 0.0 , maxBounds .size .width - cellX, rowHeight);
98
97
maxCellStringWidth = 0.0 ;
99
98
BOOL altRow = NO ;
99
+ BOOL isFirstColumn = [csvDoc isFirstColumn: colKey];
100
100
101
101
// loop rows
102
102
for (CSVRowObject *row in csvDoc.rows ) {
103
- CGContextSetFillColorWithColor (context, altRow ? altRowBG : rowBG);
104
- CGContextFillRect (context, rowRect);
105
103
106
- if (![csvDoc isFirstColumn: colKey]) {
104
+ // Draw background
105
+ if (isFirstColumn) {
106
+ CGContextSetFillColorWithColor (context, altRow ? altRowBG : rowBG);
107
+ CGContextFillRect (context, rowRect);
108
+ }
109
+
110
+ // Draw border
111
+ else {
107
112
CGContextMoveToPoint (context, cellX + borderWidth / 2 , rowRect.origin .y );
108
113
CGContextAddLineToPoint (context, cellX + borderWidth / 2 , rowRect.origin .y + rowRect.size .height );
109
114
CGContextSetStrokeColorWithColor (context, borderColor);
@@ -128,24 +133,38 @@ OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thum
128
133
cellX += maxCellStringWidth + 2 * textXPadding;
129
134
}
130
135
131
- // Crop the thumbnail if we didn't use the whole width
132
- if (cellX < myBounds.size .width ) {
133
- myBounds.size .width -= cellX;
134
- CGRect clearRect = CGRectMake (cellX, 0.0 , myBounds.size .width , myBounds.size .height );
135
- CGContextClearRect (context, clearRect);
136
-
137
- // we should now center the thumbnail in our context or crop the context somehow...
136
+ // adjust usedBounds.size.width...
137
+ if (cellX < maxBounds.size .width ) {
138
+ usedBounds.size .width = (cellX < MIN_WIDTH) ? MIN_WIDTH : cellX;
139
+ }
140
+
141
+ // ...and usedBounds.size.height
142
+ if (gotRows < numRows) {
143
+ usedBounds.size .height = gotRows * rowHeight;
138
144
}
139
145
}
140
146
141
147
CGColorRelease (borderColor);
142
148
CGColorRelease (rowBG);
143
149
CGColorRelease (altRowBG);
144
150
145
- // Clean up
146
- CGContextRestoreGState (context);
147
- QLThumbnailRequestFlushContext (thumbnail, context);
151
+ // Draw the image to the thumbnail request
152
+ CGContextRef thumbContext = QLThumbnailRequestCreateContext (thumbnail, usedBounds.size , false , NULL );
153
+
154
+ CGImageRef fullImage = CGBitmapContextCreateImage (context);
155
+ CGImageRef usedImage = CGImageCreateWithImageInRect (fullImage, usedBounds);
156
+ CGImageRelease (fullImage);
157
+ CGContextDrawImage (thumbContext, usedBounds, usedImage);
158
+ CGImageRelease (usedImage);
159
+
160
+ // we no longer need the bitmap data; free
161
+ char *bitmapData = CGBitmapContextGetData (context);
162
+ if (bitmapData) {
163
+ free (bitmapData);
164
+ }
148
165
CFRelease (context);
166
+
167
+ QLThumbnailRequestFlushContext (thumbnail, thumbContext);
149
168
}
150
169
}
151
170
}
@@ -158,4 +177,37 @@ OSStatus GenerateThumbnailForURL(void *thisInterface, QLThumbnailRequestRef thum
158
177
void CancelThumbnailGeneration (void * thisInterface, QLThumbnailRequestRef thumbnail)
159
178
{
160
179
}
180
+ #pragma mark -
181
+
182
+
183
+
184
+ #pragma mark Creating a bitmap context
185
+ static CGContextRef createRGBABitmapContext (CGSize pixelSize)
186
+ {
187
+ NSUInteger width = pixelSize.width ;
188
+ NSUInteger height = pixelSize.height ;
189
+ NSUInteger bitmapBytesPerRow = width * 4 ; // 1 byte per component r g b a
190
+ NSUInteger bitmapBytes = bitmapBytesPerRow * height;
191
+
192
+ // allocate needed bytes
193
+ void *bitmapData = malloc (bitmapBytes);
194
+ if (NULL == bitmapData) {
195
+ fprintf (stderr, " Oops, could not allocate bitmap data!" );
196
+ return NULL ;
197
+ }
198
+
199
+ // create the context
200
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName (kCGColorSpaceGenericRGB );
201
+ CGContextRef context = CGBitmapContextCreate (bitmapData, width, height, 8 , bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast );
202
+ CGColorSpaceRelease (colorSpace);
203
+
204
+ // context creation fail
205
+ if (NULL == context) {
206
+ free (bitmapData);
207
+ fprintf (stderr, " Oops, could not create the context!" );
208
+ return NULL ;
209
+ }
210
+
211
+ return context;
212
+ }
161
213
0 commit comments