From a570c48944e0a45ddf21c81683c22ffb38a984ee Mon Sep 17 00:00:00 2001 From: Christopher Lloyd Date: Thu, 1 May 2008 03:39:59 +0000 Subject: [PATCH] - SWRender, added PDF draw test - PDF drawing related cleanup --- AppKit/AppKit.xcodeproj/project.pbxproj | 4 + AppKit/CoreGraphics.subproj/CGPDFPage.m | 8 ++ .../CoreGraphics.subproj/KGContext_builtin.m | 10 +- AppKit/CoreGraphics.subproj/KGDataProvider.h | 1 + AppKit/CoreGraphics.subproj/KGImage.h | 1 + AppKit/CoreGraphics.subproj/KGImage.m | 4 + .../CoreGraphics.subproj/KGImageSource_JPEG.m | 2 +- .../CoreGraphics.subproj/KGImageSource_PNG.m | 2 +- AppKit/CoreGraphics.subproj/KGPDFDocument.h | 3 +- AppKit/CoreGraphics.subproj/KGPDFDocument.m | 6 +- AppKit/CoreGraphics.subproj/KGPDFPage.h | 12 +-- AppKit/CoreGraphics.subproj/KGPDFPage.m | 14 +-- AppKit/CoreGraphics.subproj/KGPixelPipe.m | 4 +- AppKit/CoreGraphics.subproj/KGRasterizer.h | 4 +- AppKit/CoreGraphics.subproj/KGRasterizer.m | 87 +++++++----------- AppKit/CoreGraphics.subproj/KGSurface.m | 2 +- AppKit/NSBezierPath.h | 2 +- AppKit/NSBezierPath.m | 8 +- AppKit/NSBitmapImageRep.h | 3 +- AppKit/NSBitmapImageRep.m | 7 +- AppKit/NSPDFImageRep.m | 21 +++-- .../project.pbxproj | 18 ++-- ApplicationServices/CGImageSource.h | 8 ++ ApplicationServices/CGPDFPage.h | 12 +++ ApplicationServices/CoreGraphics.h | 2 + testing/SWRender/CoreGraphics_KG.h | 32 +++++++ testing/SWRender/DemoContext.h | 3 +- testing/SWRender/DemosTemplate.m | 79 +++++++++------- .../English.lproj/MainMenu.nib/classes.nib | 2 + .../English.lproj/MainMenu.nib/info.nib | 2 +- .../MainMenu.nib/keyedobjects.nib | Bin 37106 -> 38590 bytes testing/SWRender/KGRenderController.h | 2 + testing/SWRender/KGRenderController.m | 39 +++++++- 33 files changed, 259 insertions(+), 145 deletions(-) diff --git a/AppKit/AppKit.xcodeproj/project.pbxproj b/AppKit/AppKit.xcodeproj/project.pbxproj index 27591c54..15375fee 100644 --- a/AppKit/AppKit.xcodeproj/project.pbxproj +++ b/AppKit/AppKit.xcodeproj/project.pbxproj @@ -688,6 +688,7 @@ FE6EE2E20DB92B05005503A1 /* KGRasterizer.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE2DE0DB92B05005503A1 /* KGRasterizer.m */; }; FE6EE2E50DB92B11005503A1 /* VGPath.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6EE2E30DB92B11005503A1 /* VGPath.h */; }; FE6EE2E60DB92B11005503A1 /* VGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE2E40DB92B11005503A1 /* VGPath.m */; }; + FE7ABEBE0DC2C9BA0060D15B /* CGPDFDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = FE7ABEBD0DC2C9BA0060D15B /* CGPDFDocument.m */; }; FE82867F0D34727900F7489F /* NSApplicationIcon.tiff in Resources */ = {isa = PBXBuildFile; fileRef = FE8286770D34727900F7489F /* NSApplicationIcon.tiff */; }; FE8286800D34727900F7489F /* NSSystemInfoPanel.h in Headers */ = {isa = PBXBuildFile; fileRef = FE8286780D34727900F7489F /* NSSystemInfoPanel.h */; settings = {ATTRIBUTES = (Private, ); }; }; FE8286810D34727900F7489F /* NSSystemInfoPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = FE8286790D34727900F7489F /* NSSystemInfoPanel.m */; }; @@ -1437,6 +1438,7 @@ FE7247A50C0622F2007CBC51 /* NSTextAttachmentCell.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NSTextAttachmentCell.m; sourceTree = ""; }; FE72484F0C0676AA007CBC51 /* NSTypesetter_concrete.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NSTypesetter_concrete.h; sourceTree = ""; }; FE7248500C0676AA007CBC51 /* NSTypesetter_concrete.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NSTypesetter_concrete.m; sourceTree = ""; }; + FE7ABEBD0DC2C9BA0060D15B /* CGPDFDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGPDFDocument.m; sourceTree = ""; }; FE8286770D34727900F7489F /* NSApplicationIcon.tiff */ = {isa = PBXFileReference; lastKnownFileType = image.tiff; path = NSApplicationIcon.tiff; sourceTree = ""; }; FE8286780D34727900F7489F /* NSSystemInfoPanel.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NSSystemInfoPanel.h; sourceTree = ""; }; FE8286790D34727900F7489F /* NSSystemInfoPanel.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NSSystemInfoPanel.m; sourceTree = ""; }; @@ -1972,6 +1974,7 @@ 6E2B55B20976075300DA0954 /* CoreGraphics */ = { isa = PBXGroup; children = ( + FE7ABEBD0DC2C9BA0060D15B /* CGPDFDocument.m */, FE45EDCB0DC2407E00F49290 /* CGImageSource.m */, FE3395570DB930F4009AB3E0 /* KGContext_builtin.h */, FE3395580DB930F4009AB3E0 /* KGContext_builtin.m */, @@ -3349,6 +3352,7 @@ FE6EE2E60DB92B11005503A1 /* VGPath.m in Sources */, FE33955A0DB930F4009AB3E0 /* KGContext_builtin.m in Sources */, FE45EDCC0DC2407E00F49290 /* CGImageSource.m in Sources */, + FE7ABEBE0DC2C9BA0060D15B /* CGPDFDocument.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/AppKit/CoreGraphics.subproj/CGPDFPage.m b/AppKit/CoreGraphics.subproj/CGPDFPage.m index e7b02591..9c85f487 100644 --- a/AppKit/CoreGraphics.subproj/CGPDFPage.m +++ b/AppKit/CoreGraphics.subproj/CGPDFPage.m @@ -7,3 +7,11 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #import + +CGPDFPageRef CGPDFPageRetain(CGPDFPageRef self) { + return [self retain]; +} + +void CGPDFPageRelease(CGPDFPageRef self) { + [self release]; +} diff --git a/AppKit/CoreGraphics.subproj/KGContext_builtin.m b/AppKit/CoreGraphics.subproj/KGContext_builtin.m index e03b1784..2b28e6e6 100644 --- a/AppKit/CoreGraphics.subproj/KGContext_builtin.m +++ b/AppKit/CoreGraphics.subproj/KGContext_builtin.m @@ -79,7 +79,7 @@ BOOL _isAvailable=NO; case kCGImageAlphaNoneSkipFirst: break; } - + _surface=KGSurfaceInitWithBytes(KGSurfaceAlloc(),_width,_height,bitsPerComponent,bitsPerPixel,bytesPerRow,colorSpace,bitmapInfo,VG_lRGBA_8888_PRE,_bytes); _rasterizer=KGRasterizerInit(KGRasterizerAlloc()); _pixelPipe=KGPixelPipeInit(KGPixelPipeAlloc()); @@ -223,11 +223,13 @@ xform=CGAffineTransformConcat(xform,u2d); } -(void)showGlyphs:(const CGGlyph *)glyphs count:(unsigned)count { - KGInvalidAbstractInvocation(); + // KGInvalidAbstractInvocation(); } -(void)drawShading:(KGShading *)shading { - KGInvalidAbstractInvocation(); + + + //KGInvalidAbstractInvocation(); } -(void)drawImage:(KGImage *)image inRect:(CGRect)rect { @@ -302,7 +304,7 @@ xform=CGAffineTransformConcat(xform,u2d); } -(void)drawLayer:(KGLayer *)layer inRect:(CGRect)rect { - KGInvalidAbstractInvocation(); + //KGInvalidAbstractInvocation(); } diff --git a/AppKit/CoreGraphics.subproj/KGDataProvider.h b/AppKit/CoreGraphics.subproj/KGDataProvider.h index ebf1a2af..3061034f 100644 --- a/AppKit/CoreGraphics.subproj/KGDataProvider.h +++ b/AppKit/CoreGraphics.subproj/KGDataProvider.h @@ -19,6 +19,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -initWithData:(NSData *)data; -initWithBytes:(const void *)bytes length:(size_t)length; +-(NSData *)data; -(const void *)bytes; -(size_t)length; diff --git a/AppKit/CoreGraphics.subproj/KGImage.h b/AppKit/CoreGraphics.subproj/KGImage.h index 4d3f9979..858a6e28 100644 --- a/AppKit/CoreGraphics.subproj/KGImage.h +++ b/AppKit/CoreGraphics.subproj/KGImage.h @@ -243,6 +243,7 @@ const char *KGImageNameWithIntent(CGColorRenderingIntent intent); size_t KGImageGetWidth(KGImage *self); size_t KGImageGetHeight(KGImage *self); +VGColorInternalFormat KGImageColorFormat(KGImage *self); KGRGBAffff KGRGBAffffUnpack(unsigned int inputData,KGImage *img); diff --git a/AppKit/CoreGraphics.subproj/KGImage.m b/AppKit/CoreGraphics.subproj/KGImage.m index d7869218..704e2818 100644 --- a/AppKit/CoreGraphics.subproj/KGImage.m +++ b/AppKit/CoreGraphics.subproj/KGImage.m @@ -517,6 +517,10 @@ size_t KGImageGetHeight(KGImage *self) { return self->_height; } +VGColorInternalFormat KGImageColorFormat(KGImage *self) { + return self->_colorFormat; +} + static RIfloat byteToColor(unsigned char i){ return (RIfloat)(i) / (RIfloat)0xFF; } diff --git a/AppKit/CoreGraphics.subproj/KGImageSource_JPEG.m b/AppKit/CoreGraphics.subproj/KGImageSource_JPEG.m index 6cb37d08..a5a7b68c 100644 --- a/AppKit/CoreGraphics.subproj/KGImageSource_JPEG.m +++ b/AppKit/CoreGraphics.subproj/KGImageSource_JPEG.m @@ -1019,7 +1019,7 @@ static void stbi_jpeg_load_from_memory(KGImageSource_JPEG *self,const stbi_uc *b KGDataProvider *provider=[[KGDataProvider alloc] initWithData:bitmap]; KGColorSpace *colorSpace=[[KGColorSpace alloc] initWithGenericRGB]; KGImage *image=[[KGImage alloc] initWithWidth:width height:height bitsPerComponent:8 bitsPerPixel:bitsPerPixel bytesPerRow:bytesPerRow - colorSpace:colorSpace bitmapInfo:0/*kCGImageAlphaLast|kCGBitmapByteOrder32Little*/ provider:provider decode:NULL interpolate:NO renderingIntent:kCGRenderingIntentDefault]; + colorSpace:colorSpace bitmapInfo:kCGBitmapByteOrder32Big provider:provider decode:NULL interpolate:NO renderingIntent:kCGRenderingIntentDefault]; [colorSpace release]; [provider release]; diff --git a/AppKit/CoreGraphics.subproj/KGImageSource_PNG.m b/AppKit/CoreGraphics.subproj/KGImageSource_PNG.m index e7ccecdf..9d57c272 100644 --- a/AppKit/CoreGraphics.subproj/KGImageSource_PNG.m +++ b/AppKit/CoreGraphics.subproj/KGImageSource_PNG.m @@ -548,7 +548,7 @@ unsigned char *stbi_png_load_from_memory(const unsigned char *buffer, int len, i KGDataProvider *provider=[[KGDataProvider alloc] initWithData:bitmap]; KGColorSpace *colorSpace=[[KGColorSpace alloc] initWithGenericRGB]; KGImage *image=[[KGImage alloc] initWithWidth:width height:height bitsPerComponent:8 bitsPerPixel:bitsPerPixel bytesPerRow:bytesPerRow - colorSpace:colorSpace bitmapInfo:0/*kCGImageAlphaLast|kCGBitmapByteOrder32Little*/ provider:provider decode:NULL interpolate:NO renderingIntent:kCGRenderingIntentDefault]; + colorSpace:colorSpace bitmapInfo:kCGBitmapByteOrder32Big provider:provider decode:NULL interpolate:NO renderingIntent:kCGRenderingIntentDefault]; [colorSpace release]; [provider release]; diff --git a/AppKit/CoreGraphics.subproj/KGPDFDocument.h b/AppKit/CoreGraphics.subproj/KGPDFDocument.h index 8c37fb10..d27d1901 100755 --- a/AppKit/CoreGraphics.subproj/KGPDFDocument.h +++ b/AppKit/CoreGraphics.subproj/KGPDFDocument.h @@ -9,7 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import -@class KGPDFString,KGPDFxref,KGPDFDictionary,KGPDFPage; +@class KGPDFString,KGPDFxref,KGPDFDictionary,KGPDFPage,KGDataProvider; @interface KGPDFDocument : NSObject { KGPDFString *_version; @@ -17,6 +17,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI } -initWithData:(NSData *)data; +-initWithDataProvider:(KGDataProvider *)provider; -(KGPDFxref *)xref; diff --git a/AppKit/CoreGraphics.subproj/KGPDFDocument.m b/AppKit/CoreGraphics.subproj/KGPDFDocument.m index d269ea05..0ee8d5a2 100755 --- a/AppKit/CoreGraphics.subproj/KGPDFDocument.m +++ b/AppKit/CoreGraphics.subproj/KGPDFDocument.m @@ -35,6 +35,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI return self; } +-initWithDataProvider:(KGDataProvider *)provider { + return [self initWithData:[provider data]]; +} + -(void)dealloc{ [_xref release]; [super dealloc]; @@ -142,7 +146,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -(KGPDFPage *)pageAtNumber:(int)pageNumber { KGPDFDictionary *pages=[self pagesRoot]; - KGPDFPage *page=[self pageAtNumber:pageNumber pages:pages pagesOffset:0]; + KGPDFPage *page=[self pageAtNumber:pageNumber-1 pages:pages pagesOffset:0]; return page; } diff --git a/AppKit/CoreGraphics.subproj/KGPDFPage.h b/AppKit/CoreGraphics.subproj/KGPDFPage.h index ecd38522..db0e2396 100644 --- a/AppKit/CoreGraphics.subproj/KGPDFPage.h +++ b/AppKit/CoreGraphics.subproj/KGPDFPage.h @@ -12,14 +12,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI @class KGPDFDocument,KGPDFDictionary,KGContext; -typedef enum { - kKGPDFMediaBox, - kKGPDFCropBox, - kKGPDFBleedBox, - kKGPDFTrimBox, - kKGPDFArtBox -} KGPDFBox; - @interface KGPDFPage : NSObject { KGPDFDocument *_document; int _pageNumber; @@ -35,11 +27,11 @@ typedef enum { -(KGPDFDictionary *)dictionary; --(BOOL)getRect:(CGRect *)rect forBox:(KGPDFBox)box; +-(BOOL)getRect:(CGRect *)rect forBox:(CGPDFBox)box; -(int)rotationAngle; --(CGAffineTransform)drawingTransformForBox:(KGPDFBox)box inRect:(CGRect)rect rotate:(int)degrees preserveAspectRatio:(BOOL)preserveAspectRatio; +-(CGAffineTransform)drawingTransformForBox:(CGPDFBox)box inRect:(CGRect)rect rotate:(int)degrees preserveAspectRatio:(BOOL)preserveAspectRatio; -(void)drawInContext:(KGContext *)context; diff --git a/AppKit/CoreGraphics.subproj/KGPDFPage.m b/AppKit/CoreGraphics.subproj/KGPDFPage.m index 3201fafa..842705a6 100644 --- a/AppKit/CoreGraphics.subproj/KGPDFPage.m +++ b/AppKit/CoreGraphics.subproj/KGPDFPage.m @@ -70,18 +70,18 @@ BOOL KGPDFGetPageArrayForKey(KGPDFPage *page,const char *key,KGPDFArray **arrayp return [check checkForType:kKGPDFObjectTypeArray value:arrayp]; } --(BOOL)getRect:(CGRect *)rect forBox:(KGPDFBox)box { +-(BOOL)getRect:(CGRect *)rect forBox:(CGPDFBox)box { const char *string=NULL; KGPDFArray *array; KGPDFReal *numbers; unsigned count; switch(box){ - case kKGPDFMediaBox: string="MediaBox"; break; - case kKGPDFCropBox: string="CropBox"; break; - case kKGPDFBleedBox: string="BleedBox"; break; - case kKGPDFTrimBox: string="TrimBox"; break; - case kKGPDFArtBox: string="ArtBox"; break; + case kCGPDFMediaBox: string="MediaBox"; break; + case kCGPDFCropBox: string="CropBox"; break; + case kCGPDFBleedBox: string="BleedBox"; break; + case kCGPDFTrimBox: string="TrimBox"; break; + case kCGPDFArtBox: string="ArtBox"; break; } if(string==NULL) @@ -112,7 +112,7 @@ BOOL KGPDFGetPageArrayForKey(KGPDFPage *page,const char *key,KGPDFArray **arrayp } --(CGAffineTransform)drawingTransformForBox:(KGPDFBox)box inRect:(CGRect)rect rotate:(int)degrees preserveAspectRatio:(BOOL)preserveAspectRatio { +-(CGAffineTransform)drawingTransformForBox:(CGPDFBox)box inRect:(CGRect)rect rotate:(int)degrees preserveAspectRatio:(BOOL)preserveAspectRatio { CGAffineTransform result=CGAffineTransformIdentity; CGRect boxRect; diff --git a/AppKit/CoreGraphics.subproj/KGPixelPipe.m b/AppKit/CoreGraphics.subproj/KGPixelPipe.m index 16185929..e354fa13 100644 --- a/AppKit/CoreGraphics.subproj/KGPixelPipe.m +++ b/AppKit/CoreGraphics.subproj/KGPixelPipe.m @@ -494,12 +494,12 @@ static void KGPixelPipeReadPremultipliedSourceSpan(KGPixelPipe *self,int x,int y else { KGRGBAffff imageSpan[length]; - KGPixelPipeReadPremultipliedImageNormalSpan(self,x,y,imageSpan,length,self->m_image->_colorFormat|VGColorPREMULTIPLIED); + KGPixelPipeReadPremultipliedImageNormalSpan(self,x,y,imageSpan,length,KGImageColorFormat(self->m_image)|VGColorPREMULTIPLIED); for(i=0;im_image->_colorFormat); + VGColor im=VGColorFromKGRGBA_ffff(imageSpan[i],KGImageColorFormat(self->m_image)); //apply image (vgDrawImage only) //1. paint: convert paint to dst space diff --git a/AppKit/CoreGraphics.subproj/KGRasterizer.h b/AppKit/CoreGraphics.subproj/KGRasterizer.h index 60913ddc..9dddf750 100644 --- a/AppKit/CoreGraphics.subproj/KGRasterizer.h +++ b/AppKit/CoreGraphics.subproj/KGRasterizer.h @@ -35,7 +35,7 @@ typedef enum { VG_NON_ZERO } VGFillRule; -#define MAX_SAMPLES 32 +#define MAX_SAMPLES 256 typedef struct { Vector2 v0; @@ -74,7 +74,7 @@ typedef struct { int numSamples; RIfloat sumWeights; RIfloat fradius; //max offset of the sampling points from a pixel center - Sample samples[32]; + Sample samples[MAX_SAMPLES]; } KGRasterizer *KGRasterizerAlloc(); diff --git a/AppKit/CoreGraphics.subproj/KGRasterizer.m b/AppKit/CoreGraphics.subproj/KGRasterizer.m index 844af7ed..68228fc3 100644 --- a/AppKit/CoreGraphics.subproj/KGRasterizer.m +++ b/AppKit/CoreGraphics.subproj/KGRasterizer.m @@ -129,42 +129,32 @@ void KGRasterizerSetShouldAntialias(KGRasterizer *self,BOOL antialias) { self->_antialias=antialias; //make a sampling pattern self->sumWeights = 0.0f; - self->fradius = 0.0f; //max offset of the sampling points from a pixel center - if(NO && !antialias){ - self->numSamples = 1; - self->samples[0].x = 0.0f; - self->samples[0].y = 0.0f; - self->samples[0].weight = 1.0f; - self->fradius = 0.0f; - self->sumWeights = 1.0f; - } - else { - #if 1 - //box filter of diameter 1.0f, 8-queen sampling pattern - self->numSamples = 8; - self->samples[0].x = 3; - self->samples[1].x = 7; - self->samples[2].x = 0; - self->samples[3].x = 2; - self->samples[4].x = 5; - self->samples[5].x = 1; - self->samples[6].x = 6; - self->samples[7].x = 4; - int i; - for(i=0;inumSamples;i++) - { - self->samples[i].x = (self->samples[i].x + 0.5f) / (RIfloat)self->numSamples - 0.5f; - self->samples[i].y = ((RIfloat)i + 0.5f) / (RIfloat)self->numSamples - 0.5f; - self->samples[i].weight = 1.0f / (RIfloat)self->numSamples; - self->sumWeights += self->samples[i].weight; - } - self->fradius = 0.5f; - #else + if(NO && !self->_antialias){ + self->numSamples=1; + self->fradius=0.6; + self->sumWeights=1; + self->samples[0].x = 0; + self->samples[0].y = 0; + self->samples[0].weight = 1; + } + else { +/* + The exact specifications of the Quartz AA filter are unknown. We want something very close in quality. + + Visual comparisons indicate the Quartz filter quality is at least the quality of a 64 sample one. + 32 samples appears too low regardless of the function. More samples with an inferior weighting function + doesn't help and is more expensive. + + Visual comparisons indicate the Quartz filter radius is not large, 0.75 is too big and results + in extra pixels being drawn which Quartz does not generate. 0.6 is extremely close if not identical using + any reasonable weighting. + + */ // The Quartz AA filter is different than this // 8, 16 also work, but all of them generate misdrawing with the classic test & stroking, this might be a fill bug - self->numSamples = 32; - self->fradius = .75; + self->numSamples = 64; + self->fradius = 0.6; int i; for(i=0;inumSamples;i++) @@ -178,8 +168,8 @@ void KGRasterizerSetShouldAntialias(KGRasterizer *self,BOOL antialias) { RIfloat r = (RIfloat)sqrt(x) * self->fradius; x = r * (RIfloat)sin(y*2.0f*M_PI); y = r * (RIfloat)cos(y*2.0f*M_PI); - self->samples[i].weight = (RIfloat)exp(-0.5f * RI_SQR(r/self->fradius)); - + self->samples[i].weight = (RIfloat)exp(-0.5*RI_SQR(r)); +// self->samples[i].weight = (RIfloat)exp(-0.5*RI_SQR(r/self->fradius)); RI_ASSERT(x >= -1.5f && x <= 1.5f && y >= -1.5f && y <= 1.5f); //the specification restricts the filter radius to be less than or equal to 1.5 self->samples[i].x = x; @@ -187,9 +177,8 @@ void KGRasterizerSetShouldAntialias(KGRasterizer *self,BOOL antialias) { self->sumWeights += self->samples[i].weight; } - #endif - } + } } static void scanlineSort(Edge **edges,int count,Edge **B){ @@ -318,12 +307,6 @@ static void incrementEdgeForAET(Edge *edge,RIfloat cminy,RIfloat cmaxy,RIfloat f } /* - AA filter - - Apple's AA filter is unknown at this point, so the sampling loop remains unoptimally optimized. The box filter is decent but - is not as good. The Gaussian filter is closer, but it has a less uniform appearance than Apple's. The current Gaussian implementation - also has big artifacts in some case shown by the Classic test. I'm not sure if the original filter was broken or the fill optimizations - created a problem. When we figure out something closer/same as Apple's the sampling loops can be constant for the one filter. Aliased Drawing @@ -483,20 +466,20 @@ void KGRasterizerFill(KGRasterizer *self,VGFillRule fillRule, KGPixelPipe *pixel if(scanxdirection; + int direction=edge->direction; RIfloat *pre=edge->sidePre; + int *windptr=winding; RIfloat pcxnormal=scanx*edge->normal.x; - - s=self->numSamples; - while(--s>=0){ - if(pcxnormal>pre[s]) - rightOfLastEdge=NO; - else { - winding[s]+=direction; - rightOfLastEdge&=YES; + int rightOfThisEdge=0; + + for(s=0;snumSamples;s++,windptr++){ + if(pcxnormal<=*pre++) { + *windptr+=direction; + rightOfThisEdge+=direction; } } + rightOfLastEdge&=(ABS(rightOfThisEdge)==self->numSamples)?YES:NO; if(rightOfLastEdge){ rightOfLastEdge=YES; nextEdge=i+1; diff --git a/AppKit/CoreGraphics.subproj/KGSurface.m b/AppKit/CoreGraphics.subproj/KGSurface.m index ddda4d39..2074ae98 100644 --- a/AppKit/CoreGraphics.subproj/KGSurface.m +++ b/AppKit/CoreGraphics.subproj/KGSurface.m @@ -626,7 +626,7 @@ KGSurface *KGSurfaceInit(KGSurface *self,size_t width, size_t height,size_t bits self->_bitmapInfo=bitmapInfo; if(!initFunctionsForParameters(self,bitsPerComponent,bitsPerPixel,colorSpace,bitmapInfo)) - NSLog(@"error, return"); + NSLog(@"KGSurface error, return"); self->_imageFormat=imageFormat; size_t checkBPP; diff --git a/AppKit/NSBezierPath.h b/AppKit/NSBezierPath.h index 084e3323..220b9194 100644 --- a/AppKit/NSBezierPath.h +++ b/AppKit/NSBezierPath.h @@ -35,7 +35,7 @@ typedef enum { } NSWindingRule; @interface NSBezierPath : NSObject { - KGMutablePath *_path; + CGMutablePathRef _path; float _lineWidth; float _miterLimit; float _flatness; diff --git a/AppKit/NSBezierPath.m b/AppKit/NSBezierPath.m index bf5fdd38..607250dd 100644 --- a/AppKit/NSBezierPath.m +++ b/AppKit/NSBezierPath.m @@ -6,10 +6,10 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -// Original - Christopher Lloyd #import #import #import +#import #import #import #import @@ -24,7 +24,7 @@ static NSLineCapStyle _defaultLineCapStyle=NSButtLineCapStyle; static NSLineJoinStyle _defaultLineJoinStyle=NSMiterLineJoinStyle; -init { - _path=[[KGMutablePath alloc] init]; + _path=CGPathCreateMutable(); _lineWidth=_defaultLineWidth; _miterLimit=_defaultMiterLimit; _flatness=_defaultFlatness; @@ -45,7 +45,7 @@ static NSLineJoinStyle _defaultLineJoinStyle=NSMiterLineJoinStyle; } -(void)dealloc { - [_path release]; + CGPathRelease(_path); if(_dashes!=NULL) NSZoneFree(NULL,_dashes); [super dealloc]; @@ -54,7 +54,7 @@ static NSLineJoinStyle _defaultLineJoinStyle=NSMiterLineJoinStyle; -copyWithZone:(NSZone *)zone { NSBezierPath *copy=NSCopyObject(self,0,zone); - copy->_path=[_path mutableCopy]; + copy->_path=CGPathCreateMutableCopy(_path); if(_dashCount>0){ int i; diff --git a/AppKit/NSBitmapImageRep.h b/AppKit/NSBitmapImageRep.h index 7faf1b68..2a472d78 100755 --- a/AppKit/NSBitmapImageRep.h +++ b/AppKit/NSBitmapImageRep.h @@ -8,6 +8,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import #import +#import @class KGImage; @@ -49,7 +50,7 @@ typedef enum { unsigned char **_bitmapPlanes; NSMutableDictionary *_properties; - KGImage *_image; + CGImageRef _image; } +(void)getTIFFCompressionTypes:(const NSTIFFCompression **)types count:(int *)count; diff --git a/AppKit/NSBitmapImageRep.m b/AppKit/NSBitmapImageRep.m index 1f6253eb..eb3d8637 100755 --- a/AppKit/NSBitmapImageRep.m +++ b/AppKit/NSBitmapImageRep.m @@ -9,9 +9,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import #import #import -#import -#import -#import @implementation NSBitmapImageRep @@ -116,9 +113,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI } -initWithData:(NSData *)data { - KGImageSource *imageSource=[KGImageSource newImageSourceWithData:data options:nil]; + CGImageSourceRef imageSource=CGImageSourceCreateWithData(data,nil); - _image=[imageSource imageAtIndex:0 options:nil]; + _image=CGImageSourceCreateImageAtIndex(imageSource,0,nil); _size.width=CGImageGetWidth(_image); _size.height=CGImageGetHeight(_image); diff --git a/AppKit/NSPDFImageRep.m b/AppKit/NSPDFImageRep.m index 26b4a36e..d1bda42d 100644 --- a/AppKit/NSPDFImageRep.m +++ b/AppKit/NSPDFImageRep.m @@ -7,10 +7,9 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #import -#import -#import #import #import +#import @implementation NSPDFImageRep @@ -36,13 +35,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -initWithData:(NSData *)data { _pdf=[data retain]; _currentPage=0; - _document=[[KGPDFDocument alloc] initWithData:_pdf]; + CGDataProviderRef provider=CGDataProviderCreateWithCFData(_pdf); + _document=CGPDFDocumentCreateWithProvider(provider); + CGDataProviderRelease(provider); return self; } -(void)dealloc { [_pdf release]; - [_document release]; + CGPDFDocumentRelease(_document); [super dealloc]; } @@ -55,7 +56,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI } -(int)pageCount { - return [_document pageCount]; + return CGPDFDocumentGetNumberOfPages(_document); } -(int)currentPage { @@ -67,10 +68,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI } -(NSSize)size { - KGPDFPage *page=[_document pageAtNumber:_currentPage]; + CGPDFPageRef page=CGPDFDocumentGetPage(_document,_currentPage); NSRect mediaBox; - - if(![page getRect:&mediaBox forBox:kKGPDFMediaBox]) + + if(![page getRect:&mediaBox forBox:kCGPDFMediaBox]) return NSMakeSize(0,0); return mediaBox.size; @@ -78,13 +79,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI -(BOOL)drawInRect:(NSRect)rect { CGContextRef context=[[NSGraphicsContext currentContext] graphicsPort]; - KGPDFPage *page=[_document pageAtNumber:_currentPage]; + CGPDFPageRef page=CGPDFDocumentGetPage(_document,_currentPage); if(page==nil) return NO; CGContextSaveGState(context); - CGContextConcatCTM(context,[page drawingTransformForBox:kKGPDFMediaBox inRect:rect rotate:0 preserveAspectRatio:NO]); + CGContextConcatCTM(context,[page drawingTransformForBox:kCGPDFMediaBox inRect:rect rotate:0 preserveAspectRatio:NO]); CGContextDrawPDFPage(context,page); CGContextRestoreGState(context); return YES; diff --git a/ApplicationServices/ApplicationServices.xcodeproj/project.pbxproj b/ApplicationServices/ApplicationServices.xcodeproj/project.pbxproj index 96af232f..b61d2615 100644 --- a/ApplicationServices/ApplicationServices.xcodeproj/project.pbxproj +++ b/ApplicationServices/ApplicationServices.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ FE01AAE60C5D9BF900AEA51A /* ApplicationServices.h in Headers */ = {isa = PBXBuildFile; fileRef = FE32179C0BB41C65004F000A /* ApplicationServices.h */; settings = {ATTRIBUTES = (Public, ); }; }; FE45EDC30DC2400F00F49290 /* CGImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = FE45EDC20DC2400F00F49290 /* CGImageSource.h */; settings = {ATTRIBUTES = (Public, ); }; }; + FE7ABE640DC2C0290060D15B /* CGPDFDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = FE7ABE630DC2C0290060D15B /* CGPDFDocument.h */; settings = {ATTRIBUTES = (Public, ); }; }; FECAF4E90DB7110900BA2A8E /* CGAffineTransform.h in Headers */ = {isa = PBXBuildFile; fileRef = FECAF4DA0DB7110900BA2A8E /* CGAffineTransform.h */; settings = {ATTRIBUTES = (Public, ); }; }; FECAF4EA0DB7110900BA2A8E /* CGBitmapContext.h in Headers */ = {isa = PBXBuildFile; fileRef = FECAF4DB0DB7110900BA2A8E /* CGBitmapContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; FECAF4EB0DB7110900BA2A8E /* CGColor.h in Headers */ = {isa = PBXBuildFile; fileRef = FECAF4DC0DB7110900BA2A8E /* CGColor.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -84,6 +85,7 @@ FE01AAED0C5D9BF900AEA51A /* ApplicationServices.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ApplicationServices.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FE32179C0BB41C65004F000A /* ApplicationServices.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ApplicationServices.h; sourceTree = ""; }; FE45EDC20DC2400F00F49290 /* CGImageSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGImageSource.h; sourceTree = ""; }; + FE7ABE630DC2C0290060D15B /* CGPDFDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGPDFDocument.h; sourceTree = ""; }; FECAF4DA0DB7110900BA2A8E /* CGAffineTransform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGAffineTransform.h; sourceTree = ""; }; FECAF4DB0DB7110900BA2A8E /* CGBitmapContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGBitmapContext.h; sourceTree = ""; }; FECAF4DC0DB7110900BA2A8E /* CGColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGColor.h; sourceTree = ""; }; @@ -126,10 +128,6 @@ 0867D691FE84028FC02AAC07 /* ApplicationServices */ = { isa = PBXGroup; children = ( - FE45EDC20DC2400F00F49290 /* CGImageSource.h */, - FECAF52D0DB7134F00BA2A8E /* CGPDFPage.h */, - FECAF5150DB711BC00BA2A8E /* CoreGraphicsExport.h */, - FECAF5010DB7119B00BA2A8E /* Foundation.xcodeproj */, FECAF4DA0DB7110900BA2A8E /* CGAffineTransform.h */, FECAF4DB0DB7110900BA2A8E /* CGBitmapContext.h */, FECAF4DC0DB7110900BA2A8E /* CGColor.h */, @@ -140,16 +138,21 @@ FECAF4E10DB7110900BA2A8E /* CGFunction.h */, FECAF4E20DB7110900BA2A8E /* CGGeometry.h */, FECAF4E30DB7110900BA2A8E /* CGImage.h */, + FE45EDC20DC2400F00F49290 /* CGImageSource.h */, FECAF4E40DB7110900BA2A8E /* CGLayer.h */, FECAF4E50DB7110900BA2A8E /* CGPath.h */, FECAF4E60DB7110900BA2A8E /* CGPattern.h */, + FE7ABE630DC2C0290060D15B /* CGPDFDocument.h */, + FECAF52D0DB7134F00BA2A8E /* CGPDFPage.h */, FECAF4E70DB7110900BA2A8E /* CGShading.h */, - FECAF4E80DB7110900BA2A8E /* CoreGraphics.h */, 08FB77AEFE84172EC02AAC07 /* Classes */, - 32C88DFF0371C24200C91783 /* Other Sources */, - 089C1665FE841158C02AAC07 /* Resources */, + FECAF4E80DB7110900BA2A8E /* CoreGraphics.h */, + FECAF5150DB711BC00BA2A8E /* CoreGraphicsExport.h */, 0867D69AFE84028FC02AAC07 /* External Frameworks and Libraries */, + FECAF5010DB7119B00BA2A8E /* Foundation.xcodeproj */, + 32C88DFF0371C24200C91783 /* Other Sources */, 034768DFFF38A50411DB9C8B /* Products */, + 089C1665FE841158C02AAC07 /* Resources */, ); name = ApplicationServices; sourceTree = ""; @@ -240,6 +243,7 @@ FECAF5160DB711BC00BA2A8E /* CoreGraphicsExport.h in Headers */, FECAF52E0DB7134F00BA2A8E /* CGPDFPage.h in Headers */, FE45EDC30DC2400F00F49290 /* CGImageSource.h in Headers */, + FE7ABE640DC2C0290060D15B /* CGPDFDocument.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/ApplicationServices/CGImageSource.h b/ApplicationServices/CGImageSource.h index 902efd94..e39b1e50 100644 --- a/ApplicationServices/CGImageSource.h +++ b/ApplicationServices/CGImageSource.h @@ -1,3 +1,11 @@ +/* Copyright (c) 2008 Christopher J. W. Lloyd + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + #import "CoreGraphicsExport.h" @class KGImageSource; diff --git a/ApplicationServices/CGPDFPage.h b/ApplicationServices/CGPDFPage.h index 7621f991..24a2dcec 100644 --- a/ApplicationServices/CGPDFPage.h +++ b/ApplicationServices/CGPDFPage.h @@ -6,8 +6,20 @@ The above copyright notice and this permission notice shall be included in all c THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#import "CoreGraphicsExport.h" #import @class KGPDFPage; typedef KGPDFPage *CGPDFPageRef; + +typedef enum { + kCGPDFMediaBox, + kCGPDFCropBox, + kCGPDFBleedBox, + kCGPDFTrimBox, + kCGPDFArtBox, +} CGPDFBox; + +COREGRAPHICS_EXPORT CGPDFPageRef CGPDFPageRetain(CGPDFPageRef self); +COREGRAPHICS_EXPORT void CGPDFPageRelease(CGPDFPageRef self); diff --git a/ApplicationServices/CoreGraphics.h b/ApplicationServices/CoreGraphics.h index 266b4f71..b784fa88 100755 --- a/ApplicationServices/CoreGraphics.h +++ b/ApplicationServices/CoreGraphics.h @@ -18,8 +18,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #import #import #import +#import #import #import #import +#import #import #import diff --git a/testing/SWRender/CoreGraphics_KG.h b/testing/SWRender/CoreGraphics_KG.h index c612dbc2..1237ea21 100644 --- a/testing/SWRender/CoreGraphics_KG.h +++ b/testing/SWRender/CoreGraphics_KG.h @@ -6,6 +6,8 @@ #import "KGImage.h" #import "KGImageSource.h" #import "KGDataProvider.h" +#import "KGPDFDocument.h" +#import "KGPDFPage.h" #define CGContextRef KGContext * #define CGColorRef KGColor * @@ -15,6 +17,8 @@ #define CGDataProviderRef KGDataProvider * #define CGImageRef KGImage * #define CGImageSourceRef KGImageSource * +#define CGPDFDocumentRef KGPDFDocument * +#define CGPDFPageRef KGPDFPage * #define CGContextRetain(context) \ [context retain] @@ -503,6 +507,9 @@ #define CGDataProviderCreateWithData(info,data,size, releaseCallback) \ [[KGDataProvider alloc] initWithBytes:data length:size] + +#define CGDataProviderCreateWithCFData(data) \ + [[KGDataProvider alloc] initWithData:data] // image source @@ -513,3 +520,28 @@ [self imageAtIndex:index options:opts] +// pdf document + +#define CGPDFDocumentRetain(self) \ + [self retain] + +#define CGPDFDocumentRelease(self) \ + [self release] + +#define CGPDFDocumentCreateWithProvider(provider) \ + [[KGPDFDocument alloc] initWithDataProvider:provider] + +#define CGPDFDocumentGetNumberOfPages(self) \ + [self pageCount] + +#define CGPDFDocumentGetPage(self,pageNumber) \ + [self pageAtNumber:pageNumber] + +// pdf page + +#define CGPDFPageRetain(self) \ + [self retain] + +#define CGPDFPageRelease(self) \ + [self release] + diff --git a/testing/SWRender/DemoContext.h b/testing/SWRender/DemoContext.h index 649334b8..e44ad74b 100644 --- a/testing/SWRender/DemoContext.h +++ b/testing/SWRender/DemoContext.h @@ -32,9 +32,10 @@ -(void)setRotation:(float)value; -(void)setShouldAntialias:(BOOL)value; -(void)setInterpolationQuality:(CGInterpolationQuality)value; +-(void)setPDFData:(NSData *)data; -(void)drawClassic; -(void)drawBitmapImageRep; - +-(void)drawPDF; @end diff --git a/testing/SWRender/DemosTemplate.m b/testing/SWRender/DemosTemplate.m index 6dae559c..ce1ed97b 100644 --- a/testing/SWRender/DemosTemplate.m +++ b/testing/SWRender/DemosTemplate.m @@ -34,6 +34,7 @@ float _flatness; CGImageRef _resamplingImage; + CGPDFDocumentRef _pdfDocument; } @end @@ -60,6 +61,7 @@ static CGColorRef cgColorFromColor(NSColor *color){ _fillColor=cgColorFromColor([NSColor blueColor]); _strokeColor=cgColorFromColor([NSColor redColor]); + _pathDrawingMode=kCGPathStroke; _shouldAntialias=YES; _interpolationQuality=kCGInterpolationDefault; _scalex=1; @@ -198,6 +200,16 @@ static CGColorRef cgColorFromColor(NSColor *color){ _interpolationQuality=value; } +-(void)setPDFData:(NSData *)data { + if(_pdfDocument!=NULL) + CGPDFDocumentRelease(_pdfDocument); + + CGDataProviderRef provider=CGDataProviderCreateWithCFData(data); + + _pdfDocument=CGPDFDocumentCreateWithProvider(provider); + CGDataProviderRelease(provider); +} + -(CGAffineTransform)ctm { CGAffineTransform ctm=CGAffineTransformMakeTranslation(400/2,400/2); @@ -206,6 +218,19 @@ static CGColorRef cgColorFromColor(NSColor *color){ return CGAffineTransformRotate(ctm,M_PI*_rotation/180.0); } +-(void)establishContextState { + CGContextSetShouldAntialias(_context,_shouldAntialias); + CGContextSetBlendMode(_context,_blendMode); + CGContextSetFillColorWithColor(_context,_fillColor); + CGContextSetStrokeColorWithColor(_context,_strokeColor); + CGContextSetLineWidth(_context,_lineWidth); + CGContextSetLineCap(_context,_lineCap); + CGContextSetLineJoin(_context,_lineJoin); + CGContextSetMiterLimit(_context,_miterLimit); + CGContextSetLineDash(_context,_dashPhase,_dashLengths,_dashLengthsCount); + CGContextSetFlatness(_context,_flatness); +} + static void addSliceToPath(CGMutablePathRef path,float innerRadius,float outerRadius,float startAngle,float endAngle){ CGPoint point; @@ -232,16 +257,9 @@ static void addSliceToPath(CGMutablePathRef path,float innerRadius,float outerRa CGContextSaveGState(_context); CGContextClearRect(_context,CGRectMake(0,0,400,400)); CGContextConcatCTM(_context,xform); - CGContextSetShouldAntialias(_context,_shouldAntialias); - CGContextSetBlendMode(_context,_blendMode); - CGContextSetFillColorWithColor(_context,_fillColor); - CGContextSetStrokeColorWithColor(_context,_strokeColor); - CGContextSetLineWidth(_context,_lineWidth); - CGContextSetLineCap(_context,_lineCap); - CGContextSetLineJoin(_context,_lineJoin); - CGContextSetMiterLimit(_context,_miterLimit); - CGContextSetLineDash(_context,_dashPhase,_dashLengths,_dashLengthsCount); - CGContextSetFlatness(_context,_flatness); + + [self establishContextState]; + CGContextBeginPath(_context); CGContextAddPath(_context,path); @@ -260,9 +278,7 @@ static void addSliceToPath(CGMutablePathRef path,float innerRadius,float outerRa CGContextSaveGState(_context); CGContextClearRect(_context,CGRectMake(0,0,400,400)); CGContextConcatCTM(_context,ctm); - CGContextSetShouldAntialias(_context,_shouldAntialias); - CGContextSetInterpolationQuality(_context,_interpolationQuality); - CGContextSetBlendMode(_context,_blendMode); + [self establishContextState]; CGContextDrawImage(_context,CGRectMake(0,0,CGImageGetWidth(_resamplingImage),CGImageGetHeight(_resamplingImage)),_resamplingImage); @@ -290,16 +306,7 @@ static void addSliceToPath(CGMutablePathRef path,float innerRadius,float outerRa CGContextSaveGState(_context); CGContextClearRect(_context,CGRectMake(0,0,400,400)); CGContextConcatCTM(_context,xform); - CGContextSetShouldAntialias(_context,_shouldAntialias); - CGContextSetBlendMode(_context,_blendMode); - CGContextSetFillColorWithColor(_context,_fillColor); - CGContextSetStrokeColorWithColor(_context,_strokeColor); - CGContextSetLineWidth(_context,_lineWidth); - CGContextSetLineCap(_context,_lineCap); - CGContextSetLineJoin(_context,_lineJoin); - CGContextSetMiterLimit(_context,_miterLimit); - CGContextSetLineDash(_context,_dashPhase,_dashLengths,_dashLengthsCount); - CGContextSetFlatness(_context,_flatness); + [self establishContextState]; CGContextBeginPath(_context); CGContextAddPath(_context,path); @@ -320,15 +327,7 @@ static void addSliceToPath(CGMutablePathRef path,float innerRadius,float outerRa CGContextSaveGState(_context); CGContextClearRect(_context,CGRectMake(0,0,400,400)); CGContextConcatCTM(_context,ctm); - CGContextSetShouldAntialias(_context,_shouldAntialias); - CGContextSetFillColorWithColor(_context,_fillColor); - CGContextSetStrokeColorWithColor(_context,_strokeColor); - CGContextSetLineWidth(_context,_lineWidth); - CGContextSetLineCap(_context,_lineCap); - CGContextSetLineJoin(_context,_lineJoin); - CGContextSetMiterLimit(_context,_miterLimit); - CGContextSetLineDash(_context,_dashPhase,_dashLengths,_dashLengthsCount); - CGContextSetFlatness(_context,_flatness); + [self establishContextState]; for(i=0;iid selectLineWidth id + selectPDFPath + id selectPathDrawingMode id selectRotation diff --git a/testing/SWRender/English.lproj/MainMenu.nib/info.nib b/testing/SWRender/English.lproj/MainMenu.nib/info.nib index 806b4bd0..66b8b073 100644 --- a/testing/SWRender/English.lproj/MainMenu.nib/info.nib +++ b/testing/SWRender/English.lproj/MainMenu.nib/info.nib @@ -10,8 +10,8 @@ 5 IBOpenObjects + 2 29 - 21 IBSystem Version 9C31 diff --git a/testing/SWRender/English.lproj/MainMenu.nib/keyedobjects.nib b/testing/SWRender/English.lproj/MainMenu.nib/keyedobjects.nib index d6fc2f75bfde9668cade3630ce4dc56e411b5a35..6d9f8cf0786c9f675ad2b97737731c12f587d4d4 100644 GIT binary patch literal 38590 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