- added NSColor private method to generate a CGColorRef

- NSShadow set now does the proper CG calls instead of raise exception, but the underlying CG to draw shadows is not present
- added CGColorSpaceCreateDeviceGray(), CGColorSpaceCreateDeviceCMYK() functions
- Gaussian blur work for shadows
This commit is contained in:
Christopher Lloyd 2008-09-05 19:17:18 +00:00
parent 9567075ce6
commit b8ef1a6601
26 changed files with 355 additions and 165 deletions

View File

@ -722,6 +722,7 @@
FEDF95200CAF43E7009DC96F /* KGPDFContext.m in Sources */ = {isa = PBXBuildFile; fileRef = FEDF951C0CAF43E7009DC96F /* KGPDFContext.m */; }; FEDF95200CAF43E7009DC96F /* KGPDFContext.m in Sources */ = {isa = PBXBuildFile; fileRef = FEDF951C0CAF43E7009DC96F /* KGPDFContext.m */; };
FEF2EC350C891E7C001FC5A8 /* NSOpenGLDrawable_gdiView.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF2EC330C891E7C001FC5A8 /* NSOpenGLDrawable_gdiView.h */; settings = {ATTRIBUTES = (Private, ); }; }; FEF2EC350C891E7C001FC5A8 /* NSOpenGLDrawable_gdiView.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF2EC330C891E7C001FC5A8 /* NSOpenGLDrawable_gdiView.h */; settings = {ATTRIBUTES = (Private, ); }; };
FEF2EC7B0C8A03CC001FC5A8 /* NSOpenGLDrawable_gdiView.m in Sources */ = {isa = PBXBuildFile; fileRef = FEF2EC790C8A03CC001FC5A8 /* NSOpenGLDrawable_gdiView.m */; }; FEF2EC7B0C8A03CC001FC5A8 /* NSOpenGLDrawable_gdiView.m in Sources */ = {isa = PBXBuildFile; fileRef = FEF2EC790C8A03CC001FC5A8 /* NSOpenGLDrawable_gdiView.m */; };
FEF35E270E6DC186000BD639 /* NSColor-Private.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF35E260E6DC186000BD639 /* NSColor-Private.h */; settings = {ATTRIBUTES = (Private, ); }; };
FEF9CAE90E133FF2003502ED /* KGSurface_DIBSection.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF9CAE70E133FF2003502ED /* KGSurface_DIBSection.h */; }; FEF9CAE90E133FF2003502ED /* KGSurface_DIBSection.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF9CAE70E133FF2003502ED /* KGSurface_DIBSection.h */; };
FEF9CAEA0E133FF2003502ED /* KGSurface_DIBSection.m in Sources */ = {isa = PBXBuildFile; fileRef = FEF9CAE80E133FF2003502ED /* KGSurface_DIBSection.m */; }; FEF9CAEA0E133FF2003502ED /* KGSurface_DIBSection.m in Sources */ = {isa = PBXBuildFile; fileRef = FEF9CAE80E133FF2003502ED /* KGSurface_DIBSection.m */; };
FEF9CB9F0E13EB8E003502ED /* KGColorSpace+PDF.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF9CB780E13EB8E003502ED /* KGColorSpace+PDF.h */; }; FEF9CB9F0E13EB8E003502ED /* KGColorSpace+PDF.h in Headers */ = {isa = PBXBuildFile; fileRef = FEF9CB780E13EB8E003502ED /* KGColorSpace+PDF.h */; };
@ -1529,6 +1530,7 @@
FEF2EC790C8A03CC001FC5A8 /* NSOpenGLDrawable_gdiView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NSOpenGLDrawable_gdiView.m; sourceTree = "<group>"; }; FEF2EC790C8A03CC001FC5A8 /* NSOpenGLDrawable_gdiView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = NSOpenGLDrawable_gdiView.m; sourceTree = "<group>"; };
FEF33BFF0B93543C00DC0B6F /* KGMutablePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KGMutablePath.h; sourceTree = "<group>"; }; FEF33BFF0B93543C00DC0B6F /* KGMutablePath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KGMutablePath.h; sourceTree = "<group>"; };
FEF33C000B93543C00DC0B6F /* KGMutablePath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KGMutablePath.m; sourceTree = "<group>"; }; FEF33C000B93543C00DC0B6F /* KGMutablePath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KGMutablePath.m; sourceTree = "<group>"; };
FEF35E260E6DC186000BD639 /* NSColor-Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor-Private.h"; sourceTree = "<group>"; };
FEF9CAE70E133FF2003502ED /* KGSurface_DIBSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KGSurface_DIBSection.h; sourceTree = "<group>"; }; FEF9CAE70E133FF2003502ED /* KGSurface_DIBSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KGSurface_DIBSection.h; sourceTree = "<group>"; };
FEF9CAE80E133FF2003502ED /* KGSurface_DIBSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KGSurface_DIBSection.m; sourceTree = "<group>"; }; FEF9CAE80E133FF2003502ED /* KGSurface_DIBSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KGSurface_DIBSection.m; sourceTree = "<group>"; };
FEF9CB780E13EB8E003502ED /* KGColorSpace+PDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KGColorSpace+PDF.h"; sourceTree = "<group>"; }; FEF9CB780E13EB8E003502ED /* KGColorSpace+PDF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KGColorSpace+PDF.h"; sourceTree = "<group>"; };
@ -1956,6 +1958,7 @@
6E2B55430976075300DA0954 /* NSColor */ = { 6E2B55430976075300DA0954 /* NSColor */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
FEF35E260E6DC186000BD639 /* NSColor-Private.h */,
FE08C3210DDF299800B3169A /* NSColor_CGColor.h */, FE08C3210DDF299800B3169A /* NSColor_CGColor.h */,
FE08C3220DDF299800B3169A /* NSColor_CGColor.m */, FE08C3220DDF299800B3169A /* NSColor_CGColor.m */,
6E2B55620976075300DA0954 /* conversions.h */, 6E2B55620976075300DA0954 /* conversions.h */,
@ -2950,6 +2953,7 @@
FEF9CBC20E13EB8E003502ED /* KGImage+PDF.h in Headers */, FEF9CBC20E13EB8E003502ED /* KGImage+PDF.h in Headers */,
FEF9CBC40E13EB8E003502ED /* KGShading+PDF.h in Headers */, FEF9CBC40E13EB8E003502ED /* KGShading+PDF.h in Headers */,
FEF9CCC30E1416C4003502ED /* KGContext_builtin_gdi.h in Headers */, FEF9CCC30E1416C4003502ED /* KGContext_builtin_gdi.h in Headers */,
FEF35E270E6DC186000BD639 /* NSColor-Private.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -16,3 +16,11 @@ void CGColorSpaceRelease(CGColorSpaceRef colorSpace) {
CGColorSpaceRef CGColorSpaceCreateDeviceRGB() { CGColorSpaceRef CGColorSpaceCreateDeviceRGB() {
return [[KGColorSpace alloc] initWithDeviceRGB]; return [[KGColorSpace alloc] initWithDeviceRGB];
} }
CGColorSpaceRef CGColorSpaceCreateDeviceGray() {
return [[KGColorSpace alloc] initWithDeviceGray];
}
CGColorSpaceRef CGColorSpaceCreateDeviceCMYK() {
return [[KGColorSpace alloc] initWithDeviceCMYK];
}

View File

@ -59,20 +59,23 @@ typedef struct Edge {
typedef void (*KGBlendSpan_RGBA8888)(KGRGBA8888 *src,KGRGBA8888 *dst,int length); typedef void (*KGBlendSpan_RGBA8888)(KGRGBA8888 *src,KGRGBA8888 *dst,int length);
typedef void (*KGBlendSpan_RGBAffff)(KGRGBAffff *src,KGRGBAffff *dst,int length); typedef void (*KGBlendSpan_RGBAffff)(KGRGBAffff *src,KGRGBAffff *dst,int length);
typedef void (*KGWriteCoverage_RGBA8888)(KGSurface *surface,KGSurface *mask,KGPaint *paint,int x, int y,int coverage,int length,KGBlendSpan_RGBA8888 blendFunction);
@class KGSurface,KGContext_builtin; @class KGSurface,KGContext_builtin;
#define KGRasterizer KGContext_builtin #define KGRasterizer KGContext_builtin
@interface KGContext_builtin : KGBitmapContext { @interface KGContext_builtin : KGBitmapContext {
KGSurface *m_mask; KGSurface *m_mask;
KGPaint *m_paint; KGPaint *m_paint;
BOOL _useRGBA8888; KGBlendSpan_RGBA8888 _blend_lRGBA8888_PRE;
CGBlendMode _blendMode; KGBlendSpan_RGBAffff _blend_lRGBAffff_PRE;
KGBlendSpan_RGBA8888 _blend_lRGBA8888_PRE; KGWriteCoverage_RGBA8888 _writeCoverage_lRGBA8888_PRE;
KGBlendSpan_RGBAffff _blend_lRGBAffff_PRE; void (*_blendFunction)();
void (*_writeCoverageFunction)();
int _vpx,_vpy,_vpwidth,_vpheight; int _vpx,_vpy,_vpwidth,_vpheight;
int _edgeCount; int _edgeCount;
@ -98,7 +101,7 @@ void KGRasterizerSetViewport(KGRasterizer *self,int x,int y,int vpwidth,int vphe
void KGRasterizerClear(KGRasterizer *self); void KGRasterizerClear(KGRasterizer *self);
void KGRasterizerAddEdge(KGRasterizer *self,const CGPoint v0, const CGPoint v1); void KGRasterizerAddEdge(KGRasterizer *self,const CGPoint v0, const CGPoint v1);
void KGRasterizerSetShouldAntialias(KGRasterizer *self,BOOL antialias,int quality); void KGRasterizerSetShouldAntialias(KGRasterizer *self,BOOL antialias,int quality);
void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRule); void KGRasterizerFill(KGRasterizer *self,int fillRule);
void KGRasterizeSetBlendMode(KGRasterizer *self,CGBlendMode blendMode); void KGRasterizeSetBlendMode(KGRasterizer *self,CGBlendMode blendMode);
void KGRasterizeSetMask(KGRasterizer *self,KGSurface* mask); void KGRasterizeSetMask(KGRasterizer *self,KGSurface* mask);

View File

@ -623,17 +623,25 @@ static void KGApplyCoverageAndMaskToSpan_lRGBA8888_PRE(KGRGBA8888 *dst,int icove
static void KGApplyCoverageToSpan_lRGBA8888_PRE(KGRGBA8888 *dst,int coverage,KGRGBA8888 *src,int length){ static void KGApplyCoverageToSpan_lRGBA8888_PRE(KGRGBA8888 *dst,int coverage,KGRGBA8888 *src,int length){
int i; int i;
int oneMinusCoverage=inverseCoverage(coverage);
for(i=0;i<length;i++,src++,dst++){ if(coverage==256){
KGRGBA8888 r=*src; for(i=0;i<length;i++,src++,dst++){
KGRGBA8888 d=*dst; *dst=*src;
}
}
else {
int oneMinusCoverage=inverseCoverage(coverage);
for(i=0;i<length;i++,src++,dst++){
KGRGBA8888 r=*src;
KGRGBA8888 d=*dst;
*dst=KGRGBA8888Add(KGRGBA8888MultiplyByCoverage(r , coverage) , KGRGBA8888MultiplyByCoverage(d , oneMinusCoverage)); *dst=KGRGBA8888Add(KGRGBA8888MultiplyByCoverage(r , coverage) , KGRGBA8888MultiplyByCoverage(d , oneMinusCoverage));
}
} }
} }
static void KGBlendSpanNormal_8888_coverage(KGRGBA8888 *src,KGRGBA8888 *dst,int coverage,int length){ static inline void KGBlendSpanNormal_8888_coverage(KGRGBA8888 *src,KGRGBA8888 *dst,int coverage,int length){
// Passes Visual Test // Passes Visual Test
int i; int i;
@ -646,10 +654,12 @@ static void KGBlendSpanNormal_8888_coverage(KGRGBA8888 *src,KGRGBA8888 *dst,int
if(s.a==255) if(s.a==255)
r=*src; r=*src;
else { else {
r.r=RI_INT_MIN((int)s.r+((int)d.r*(255-s.a))/255,255); int sa=255-s.a;
r.g=RI_INT_MIN((int)s.g+((int)d.g*(255-s.a))/255,255);
r.b=RI_INT_MIN((int)s.b+((int)d.b*(255-s.a))/255,255); r.r=RI_INT_MIN((int)s.r+((int)d.r*sa)/255,255);
r.a=RI_INT_MIN((int)s.a+((int)d.a*(255-s.a))/255,255); r.g=RI_INT_MIN((int)s.g+((int)d.g*sa)/255,255);
r.b=RI_INT_MIN((int)s.b+((int)d.b*sa)/255,255);
r.a=RI_INT_MIN((int)s.a+((int)d.a*sa)/255,255);
} }
*dst=r; *dst=r;
} }
@ -692,8 +702,8 @@ static void KGBlendSpanCopy_8888_coverage(KGRGBA8888 *src,KGRGBA8888 *dst,int co
int i; int i;
if(coverage==256){ if(coverage==256){
for(i=0;i<length;i++,src++,dst++) for(i=0;i<length;i++)
*dst=*src; *dst++=*src++;
} }
else { else {
int oneMinusCoverage=256-coverage; int oneMinusCoverage=256-coverage;
@ -723,77 +733,102 @@ static void KGBlendSpanCopy_8888_coverage(KGRGBA8888 *src,KGRGBA8888 *dst,int co
} }
} }
static inline void KGRasterizeWriteCoverageSpan(KGRasterizer *self,int x, int y,int coverage,int length) { static inline void KGRasterizeWriteCoverageSpan8888_Normal(KGSurface *surface,KGSurface *mask,KGPaint *paint,int x, int y,int coverage,int length,KGBlendSpan_RGBA8888 blendFunction) {
if(self->_useRGBA8888){
KGRGBA8888 *dst=__builtin_alloca(length*sizeof(KGRGBA8888)); KGRGBA8888 *dst=__builtin_alloca(length*sizeof(KGRGBA8888));
KGRGBA8888 *direct=self->_surface->_read_lRGBA8888_PRE(self->_surface,x,y,dst,length); KGRGBA8888 *direct=surface->_read_lRGBA8888_PRE(surface,x,y,dst,length);
if(direct!=NULL) if(direct!=NULL)
dst=direct; dst=direct;
KGRGBA8888 src[length]; KGRGBA8888 src[length];
KGPaintReadSpan_lRGBA8888_PRE(self->m_paint,x,y,src,length); KGPaintReadSpan_lRGBA8888_PRE(paint,x,y,src,length);
switch(self->_blendMode){ KGBlendSpanNormal_8888_coverage(src,dst,coverage,length);
// FIXME: doesnt handle mask if present
case kCGBlendModeNormal:
KGBlendSpanNormal_8888_coverage(src,dst,coverage,length);
break;
case kCGBlendModeCopy:
KGBlendSpanCopy_8888_coverage(src,dst,coverage,length);
break;
default:
self->_blend_lRGBA8888_PRE(src,dst,length);
//apply masking
if(!self->m_mask)
KGApplyCoverageToSpan_lRGBA8888_PRE(dst,coverage,src,length);
else {
uint8_t maskSpan[length];
KGImageReadSpan_A8_MASK(self->m_mask,x,y,maskSpan,length);
KGApplyCoverageAndMaskToSpan_lRGBA8888_PRE(dst,coverage,maskSpan,src,length);
}
break;
}
if(direct==NULL){ if(direct==NULL){
//write result to the destination surface //write result to the destination surface
KGSurfaceWriteSpan_lRGBA8888_PRE(self->_surface,x,y,dst,length); KGSurfaceWriteSpan_lRGBA8888_PRE(surface,x,y,dst,length);
} }
} }
static inline void KGRasterizeWriteCoverageSpan8888_Copy(KGSurface *surface,KGSurface *mask,KGPaint *paint,int x, int y,int coverage,int length,KGBlendSpan_RGBA8888 blendFunction) {
KGRGBA8888 *dst=__builtin_alloca(length*sizeof(KGRGBA8888));
KGRGBA8888 *direct=surface->_read_lRGBA8888_PRE(surface,x,y,dst,length);
if(direct!=NULL)
dst=direct;
KGRGBA8888 src[length];
KGPaintReadSpan_lRGBA8888_PRE(paint,x,y,src,length);
KGBlendSpanCopy_8888_coverage(src,dst,coverage,length);
// FIXME: doesnt handle mask if present
if(direct==NULL){
//write result to the destination surface
KGSurfaceWriteSpan_lRGBA8888_PRE(surface,x,y,dst,length);
}
}
static inline void KGRasterizeWriteCoverageSpan8888(KGSurface *surface,KGSurface *mask,KGPaint *paint,int x, int y,int coverage,int length,KGBlendSpan_RGBA8888 blendFunction) {
KGRGBA8888 *dst=__builtin_alloca(length*sizeof(KGRGBA8888));
KGRGBA8888 *direct=surface->_read_lRGBA8888_PRE(surface,x,y,dst,length);
if(direct!=NULL)
dst=direct;
KGRGBA8888 src[length];
KGPaintReadSpan_lRGBA8888_PRE(paint,x,y,src,length);
blendFunction(src,dst,length);
//apply masking
if(mask==NULL)
KGApplyCoverageToSpan_lRGBA8888_PRE(dst,coverage,src,length);
else { else {
uint8_t maskSpan[length];
KGImageReadSpan_A8_MASK(mask,x,y,maskSpan,length);
KGApplyCoverageAndMaskToSpan_lRGBA8888_PRE(dst,coverage,maskSpan,src,length);
}
if(direct==NULL){
//write result to the destination surface
KGSurfaceWriteSpan_lRGBA8888_PRE(surface,x,y,dst,length);
}
}
static inline void KGRasterizeWriteCoverageSpanffff(KGSurface *surface,KGSurface *mask,KGPaint *paint,int x, int y,int coverage,int length,KGBlendSpan_RGBAffff blendFunction) {
KGRGBAffff *dst=__builtin_alloca(length*sizeof(KGRGBAffff)); KGRGBAffff *dst=__builtin_alloca(length*sizeof(KGRGBAffff));
KGRGBAffff *direct=KGImageReadSpan_lRGBAffff_PRE(self->_surface,x,y,dst,length); KGRGBAffff *direct=KGImageReadSpan_lRGBAffff_PRE(surface,x,y,dst,length);
if(direct!=NULL) if(direct!=NULL)
dst=direct; dst=direct;
KGRGBAffff src[length]; KGRGBAffff src[length];
KGPaintReadSpan_lRGBAffff_PRE(self->m_paint,x,y,src,length); KGPaintReadSpan_lRGBAffff_PRE(paint,x,y,src,length);
self->_blend_lRGBAffff_PRE(src,dst,length); blendFunction(src,dst,length);
//apply masking //apply masking
if(!self->m_mask) if(mask==NULL)
KGApplyCoverageToSpan_lRGBAffff_PRE(dst,coverage,src,length); KGApplyCoverageToSpan_lRGBAffff_PRE(dst,coverage,src,length);
else { else {
CGFloat maskSpan[length]; CGFloat maskSpan[length];
KGImageReadSpan_Af_MASK(self->m_mask,x,y,maskSpan,length); KGImageReadSpan_Af_MASK(mask,x,y,maskSpan,length);
KGApplyCoverageAndMaskToSpan_lRGBAffff_PRE(dst,coverage,maskSpan,src,length); KGApplyCoverageAndMaskToSpan_lRGBAffff_PRE(dst,coverage,maskSpan,src,length);
} }
if(direct==NULL){ if(direct==NULL){
//write result to the destination surface //write result to the destination surface
KGSurfaceWriteSpan_lRGBAffff_PRE(self->_surface,x,y,dst,length); KGSurfaceWriteSpan_lRGBAffff_PRE(surface,x,y,dst,length);
} }
}
} }
void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRuleMask) { void KGRasterizerFill(KGRasterizer *self,int fillRuleMask) {
int edgeCount=self->_edgeCount; int edgeCount=self->_edgeCount;
Edge **edges=self->_edges; Edge **edges=self->_edges;
@ -812,7 +847,7 @@ void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRuleMask) {
int *increase=self->_increase; int *increase=self->_increase;
int numberOfSamples=self->numSamples; int numberOfSamples=self->numSamples;
int shiftNumberOfSamples=self->sampleSizeShift; int shiftNumberOfSamples=self->sampleSizeShift;
CGFloat sidePre[numberOfSamples]; CGFloat sidePre[numberOfSamples];
for(scany=self->_vpy;scany<ylimit;scany++){ for(scany=self->_vpy;scany<ylimit;scany++){
Edge *edge,*previous=NULL; Edge *edge,*previous=NULL;
@ -851,7 +886,7 @@ void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRuleMask) {
CGFloat normalY=edge->normal.y; CGFloat normalY=edge->normal.y;
int belowY=0; int belowY=0;
int aboveY; int aboveY;
for(;sampleY<v0y && pre<preEnd;sampleY+=sampleDeltaY,samplesX++){ for(;sampleY<v0y && pre<preEnd;sampleY+=sampleDeltaY,samplesX++){
pre++; pre++;
belowY++; belowY++;
@ -902,8 +937,8 @@ void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRuleMask) {
if(pcxnormal<=*pre++) if(pcxnormal<=*pre++)
*windptr+++=direction; *windptr+++=direction;
else { else {
leftOfEdge++;
windptr++; windptr++;
leftOfEdge++;
} }
} }
@ -951,7 +986,10 @@ void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRuleMask) {
for(;windptr<windend;) { for(;windptr<windend;) {
// using ? with 0 is faster than not // using ? with 0 is faster than not
coverage +=((*windptr+++accum) & fillRuleMask)?weight:0;
coverage +=(((*windptr+accum) & fillRuleMask)?weight:0);
windptr++;
} }
accum+=increase[scanx]; accum+=increase[scanx];
@ -964,7 +1002,7 @@ void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRuleMask) {
} }
if(coverage>0){ if(coverage>0){
KGRasterizeWriteCoverageSpan(self,scanx,scany,coverage,(advance-scanx)); self->_writeCoverageFunction(self->_surface,self->m_mask,self->m_paint,scanx,scany,coverage,(advance-scanx),self->_blendFunction);
coverage=0; coverage=0;
} }
@ -976,15 +1014,15 @@ void KGRasterizerFill(KGRasterizer *self,VGFillRuleMask fillRuleMask) {
void KGRasterizeSetBlendMode(KGRasterizer *self,CGBlendMode blendMode) { void KGRasterizeSetBlendMode(KGRasterizer *self,CGBlendMode blendMode) {
RI_ASSERT(blendMode >= kCGBlendModeNormal && blendMode <= kCGBlendModePlusLighter); RI_ASSERT(blendMode >= kCGBlendModeNormal && blendMode <= kCGBlendModePlusLighter);
self->_blendMode=blendMode; self->_blend_lRGBA8888_PRE=NULL;
self->_useRGBA8888=NO; self->_writeCoverage_lRGBA8888_PRE=NULL;
switch(blendMode){ switch(blendMode){
case kCGBlendModeNormal: case kCGBlendModeNormal:
self->_useRGBA8888=YES;
self->_blend_lRGBA8888_PRE=KGBlendSpanNormal_8888; self->_blend_lRGBA8888_PRE=KGBlendSpanNormal_8888;
self->_blend_lRGBAffff_PRE=KGBlendSpanNormal_ffff; self->_blend_lRGBAffff_PRE=KGBlendSpanNormal_ffff;
self->_writeCoverage_lRGBA8888_PRE=KGRasterizeWriteCoverageSpan8888_Normal;
break; break;
case kCGBlendModeMultiply: case kCGBlendModeMultiply:
@ -1048,19 +1086,17 @@ void KGRasterizeSetBlendMode(KGRasterizer *self,CGBlendMode blendMode) {
break; break;
case kCGBlendModeClear: case kCGBlendModeClear:
self->_useRGBA8888=YES;
self->_blend_lRGBA8888_PRE=KGBlendSpanClear_8888; self->_blend_lRGBA8888_PRE=KGBlendSpanClear_8888;
self->_blend_lRGBAffff_PRE=KGBlendSpanClear_ffff; self->_blend_lRGBAffff_PRE=KGBlendSpanClear_ffff;
break; break;
case kCGBlendModeCopy: case kCGBlendModeCopy:
self->_useRGBA8888=YES;
self->_blend_lRGBA8888_PRE=KGBlendSpanCopy_8888; self->_blend_lRGBA8888_PRE=KGBlendSpanCopy_8888;
self->_blend_lRGBAffff_PRE=KGBlendSpanCopy_ffff; self->_blend_lRGBAffff_PRE=KGBlendSpanCopy_ffff;
self->_writeCoverage_lRGBA8888_PRE=KGRasterizeWriteCoverageSpan8888_Copy;
break; break;
case kCGBlendModeSourceIn: case kCGBlendModeSourceIn:
self->_useRGBA8888=YES;
self->_blend_lRGBA8888_PRE=KGBlendSpanSourceIn_8888; self->_blend_lRGBA8888_PRE=KGBlendSpanSourceIn_8888;
self->_blend_lRGBAffff_PRE=KGBlendSpanSourceIn_ffff; self->_blend_lRGBAffff_PRE=KGBlendSpanSourceIn_ffff;
break; break;
@ -1090,7 +1126,6 @@ void KGRasterizeSetBlendMode(KGRasterizer *self,CGBlendMode blendMode) {
break; break;
case kCGBlendModeXOR: case kCGBlendModeXOR:
self->_useRGBA8888=YES;
self->_blend_lRGBA8888_PRE=KGBlendSpanXOR_8888; self->_blend_lRGBA8888_PRE=KGBlendSpanXOR_8888;
self->_blend_lRGBAffff_PRE=KGBlendSpanXOR_ffff; self->_blend_lRGBAffff_PRE=KGBlendSpanXOR_ffff;
break; break;
@ -1100,11 +1135,25 @@ void KGRasterizeSetBlendMode(KGRasterizer *self,CGBlendMode blendMode) {
break; break;
case kCGBlendModePlusLighter: case kCGBlendModePlusLighter:
self->_useRGBA8888=YES;
self->_blend_lRGBA8888_PRE=KGBlendSpanPlusLighter_8888; self->_blend_lRGBA8888_PRE=KGBlendSpanPlusLighter_8888;
self->_blend_lRGBAffff_PRE=KGBlendSpanPlusLighter_ffff; self->_blend_lRGBAffff_PRE=KGBlendSpanPlusLighter_ffff;
break; break;
} }
if(self->_writeCoverage_lRGBA8888_PRE!=NULL){
self->_blendFunction=NULL;
self->_writeCoverageFunction=self->_writeCoverage_lRGBA8888_PRE;
}
else {
if(self->_blend_lRGBA8888_PRE!=NULL){
self->_blendFunction=self->_blend_lRGBA8888_PRE;
self->_writeCoverageFunction=KGRasterizeWriteCoverageSpan8888;
}
else {
self->_blendFunction=self->_blend_lRGBAffff_PRE;
self->_writeCoverageFunction=KGRasterizeWriteCoverageSpanffff;
}
}
} }
void KGRasterizeSetMask(KGRasterizer *self,KGSurface* mask) { void KGRasterizeSetMask(KGRasterizer *self,KGSurface* mask) {

View File

@ -39,6 +39,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
CGSize _shadowOffset; CGSize _shadowOffset;
float _shadowBlur; float _shadowBlur;
KGColor *_shadowColor; KGColor *_shadowColor;
void *_shadowKernel;
BOOL _shouldAntialias; BOOL _shouldAntialias;
int _antialiasingQuality; int _antialiasingQuality;

View File

@ -16,6 +16,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#import "KGClipPhase.h" #import "KGClipPhase.h"
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import "KGExceptions.h" #import "KGExceptions.h"
#import "KGSurface.h"
@implementation KGGraphicsState @implementation KGGraphicsState
@ -49,6 +50,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
if(_dashLengths!=NULL) if(_dashLengths!=NULL)
NSZoneFree(NULL,_dashLengths); NSZoneFree(NULL,_dashLengths);
[_shadowColor release]; [_shadowColor release];
KGGaussianKernelRelease(_shadowKernel);
[super dealloc]; [super dealloc];
} }
@ -69,6 +71,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
copy->_shadowColor=[_shadowColor copyWithZone:zone]; copy->_shadowColor=[_shadowColor copyWithZone:zone];
copy->_shadowKernel=KGGaussianKernelRetain(_shadowKernel);
return copy; return copy;
} }
@ -283,16 +287,17 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
[color retain]; [color retain];
[_shadowColor release]; [_shadowColor release];
_shadowColor=color; _shadowColor=color;
KGGaussianKernelRelease(_shadowKernel);
_shadowKernel=(_shadowColor==nil)?NULL:KGCreateGaussianKernelWithDeviation(blur);
} }
-(void)setShadowOffset:(CGSize)offset blur:(float)blur { -(void)setShadowOffset:(CGSize)offset blur:(float)blur {
KGColorSpace *colorSpace=[[KGColorSpace alloc] initWithDeviceRGB]; KGColorSpace *colorSpace=[[KGColorSpace alloc] initWithDeviceRGB];
float components[4]={0,0,0,1.0/3.0}; float components[4]={0,0,0,1.0/3.0};
KGColor *color=[[KGColor alloc] initWithColorSpace:colorSpace components:components];
_shadowOffset=offset; [self setShadowOffset:offset blur:blur color:color];
_shadowBlur=blur; [color release];
[_shadowColor release];
_shadowColor=[[KGColor alloc] initWithColorSpace:colorSpace components:components];
[colorSpace release]; [colorSpace release];
} }

View File

@ -253,11 +253,17 @@ void KGSurfaceWriteFilteredPixel(KGSurface *self,int x, int y, VGColor c, VGbitf
void KGSurfaceWriteMaskPixel(KGSurface *self,int x, int y, CGFloat m); //can write only to VG_A_8 void KGSurfaceWriteMaskPixel(KGSurface *self,int x, int y, CGFloat m); //can write only to VG_A_8
typedef struct KGGaussianKernel *KGGaussianKernelRef;
KGGaussianKernelRef KGCreateGaussianKernelWithDeviation(CGFloat stdDeviation);
KGGaussianKernelRef KGGaussianKernelRetain(KGGaussianKernelRef kernel);
void KGGaussianKernelRelease(KGGaussianKernelRef kernel);
void KGSurfaceColorMatrix(KGSurface *self,KGSurface * src, const CGFloat* matrix, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask); void KGSurfaceColorMatrix(KGSurface *self,KGSurface * src, const CGFloat* matrix, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void KGSurfaceConvolve(KGSurface *self,KGSurface * src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernel, CGFloat scale, CGFloat bias, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask); void KGSurfaceConvolve(KGSurface *self,KGSurface * src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernel, CGFloat scale, CGFloat bias, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void KGSurfaceSeparableConvolve(KGSurface *self,KGSurface * src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernelX, const RIint16* kernelY, CGFloat scale, CGFloat bias, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask); void KGSurfaceSeparableConvolve(KGSurface *self,KGSurface * src, int kernelWidth, int kernelHeight, int shiftX, int shiftY, const RIint16* kernelX, const RIint16* kernelY, CGFloat scale, CGFloat bias, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void KGSurfaceGaussianBlur(KGSurface *self,KGSurface * src, CGFloat stdDeviationX, CGFloat stdDeviationY, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask); void KGSurfaceGaussianBlur(KGSurface *self,KGImage * src, KGGaussianKernelRef kernel);
void KGSurfaceLookup(KGSurface *self,KGSurface * src, const RIuint8 * redLUT, const RIuint8 * greenLUT, const RIuint8 * blueLUT, const RIuint8 * alphaLUT, BOOL outputLinear, BOOL outputPremultiplied, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask); void KGSurfaceLookup(KGSurface *self,KGSurface * src, const RIuint8 * redLUT, const RIuint8 * greenLUT, const RIuint8 * blueLUT, const RIuint8 * alphaLUT, BOOL outputLinear, BOOL outputPremultiplied, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);
void KGSurfaceLookupSingle(KGSurface *self,KGSurface * src, const RIuint32 * lookupTable, KGSurfaceChannel sourceChannel, BOOL outputLinear, BOOL outputPremultiplied, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask); void KGSurfaceLookupSingle(KGSurface *self,KGSurface * src, const RIuint32 * lookupTable, KGSurfaceChannel sourceChannel, BOOL outputLinear, BOOL outputPremultiplied, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask);

View File

@ -1310,39 +1310,42 @@ void KGSurfaceSeparableConvolve(KGSurface *self,KGSurface * src, int kernelWidth
* \note * \note
*//*-------------------------------------------------------------------*/ *//*-------------------------------------------------------------------*/
void KGSurfaceGaussianBlur(KGSurface *self,KGSurface * src, CGFloat stdDeviationX, CGFloat stdDeviationY, VGTilingMode tilingMode, VGColor edgeFillColor, BOOL filterFormatLinear, BOOL filterFormatPremultiplied, VGbitfield channelMask){ static KGRGBAffff gaussianReadPixel(int x, int y, int w, int h,KGRGBAffff *image)
RI_ASSERT(src->_pixelBytes); //source exists {
RI_ASSERT(self->_pixelBytes); //destination exists if(x < 0 || x >= w || y < 0 || y >= h) { //apply tiling mode
return KGRGBAffffInit(0,0,0,0);
}
else
{
RI_ASSERT(x >= 0 && x < w && y >= 0 && y < h);
return image[y*w+x];
}
}
typedef struct KGGaussianKernel {
int refCount;
int xSize;
int xShift;
CGFloat xScale;
CGFloat *xValues;
int ySize;
int yShift;
CGFloat yScale;
CGFloat *yValues;
} KGGaussianKernel;
KGGaussianKernel *KGCreateGaussianKernelWithDeviation(CGFloat stdDeviation){
KGGaussianKernel *kernel=NSZoneMalloc(NULL,sizeof(KGGaussianKernel));
kernel->refCount=1;
CGFloat stdDeviationX=stdDeviation;
CGFloat stdDeviationY=stdDeviation;
RI_ASSERT(stdDeviationX > 0.0f && stdDeviationY > 0.0f); RI_ASSERT(stdDeviationX > 0.0f && stdDeviationY > 0.0f);
RI_ASSERT(stdDeviationX <= RI_MAX_GAUSSIAN_STD_DEVIATION && stdDeviationY <= RI_MAX_GAUSSIAN_STD_DEVIATION); RI_ASSERT(stdDeviationX <= RI_MAX_GAUSSIAN_STD_DEVIATION && stdDeviationY <= RI_MAX_GAUSSIAN_STD_DEVIATION);
//the area to be written is an intersection of source and destination image areas.
//lower-left corners of the images are aligned.
int w = RI_INT_MIN(self->_width, src->_width);
int h = RI_INT_MIN(self->_height, src->_height);
RI_ASSERT(w > 0 && h > 0);
VGColorInternalFormat procFormat = getProcessingFormat(src->_colorFormat, filterFormatLinear, filterFormatPremultiplied);
VGColor edge = edgeFillColor;
edge=VGColorClamp(edge);
edge=VGColorConvert(edge,procFormat);
VGColor *tmp=(VGColor *)NSZoneMalloc(NULL,src->_width*src->_height*sizeof(VGColor));
//copy source region to tmp and do conversion
int j;
for(j=0;j<src->_height;j++)
{
int i;
for(i=0;i<src->_width;i++)
{
VGColor s = KGSurfaceReadPixel(src,i, j);
s=VGColorConvert(s,procFormat);
tmp[j*src->_width+i] = s;
}
}
//find a size for the kernel //find a size for the kernel
CGFloat totalWeightX = stdDeviationX*(CGFloat)sqrt(2.0f*M_PI); CGFloat totalWeightX = stdDeviationX*(CGFloat)sqrt(2.0f*M_PI);
CGFloat totalWeightY = stdDeviationY*(CGFloat)sqrt(2.0f*M_PI); CGFloat totalWeightY = stdDeviationY*(CGFloat)sqrt(2.0f*M_PI);
@ -1354,81 +1357,117 @@ void KGSurfaceGaussianBlur(KGSurface *self,KGSurface * src, CGFloat stdDeviation
int kernelWidth = 0; int kernelWidth = 0;
CGFloat e = 0.0f; CGFloat e = 0.0f;
CGFloat sumX = 1.0f; //the weight of the middle entry counted already CGFloat sumX = 1.0f; //the weight of the middle entry counted already
do do{
{
kernelWidth++; kernelWidth++;
e = (CGFloat)exp((CGFloat)(kernelWidth * kernelWidth) * expScaleX); e = (CGFloat)exp((CGFloat)(kernelWidth * kernelWidth) * expScaleX);
sumX += e*2.0f; //count left&right lobes sumX += e*2.0f; //count left&right lobes
} }while(sumX < tolerance*totalWeightX);
while(sumX < tolerance*totalWeightX);
int kernelHeight = 0; int kernelHeight = 0;
e = 0.0f; e = 0.0f;
CGFloat sumY = 1.0f; //the weight of the middle entry counted already CGFloat sumY = 1.0f; //the weight of the middle entry counted already
do do{
{
kernelHeight++; kernelHeight++;
e = (CGFloat)exp((CGFloat)(kernelHeight * kernelHeight) * expScaleY); e = (CGFloat)exp((CGFloat)(kernelHeight * kernelHeight) * expScaleY);
sumY += e*2.0f; //count left&right lobes sumY += e*2.0f; //count left&right lobes
} }while(sumY < tolerance*totalWeightY);
while(sumY < tolerance*totalWeightY);
//make a separable kernel //make a separable kernel
int kernelXSize=kernelWidth*2+1; kernel->xSize=kernelWidth*2+1;
CGFloat kernelX[kernelXSize]; kernel->xValues=NSZoneMalloc(NULL,sizeof(CGFloat)*kernel->xSize);
int shiftX = kernelWidth; kernel->xShift = kernelWidth;
CGFloat scaleX = 0.0f; kernel->xScale = 0.0f;
int i; int i;
for(i=0;i<kernelXSize;i++) for(i=0;i<kernel->xSize;i++){
{ int x = i-kernel->xShift;
int x = i-shiftX; kernel->xValues[i] = (CGFloat)exp((CGFloat)x*(CGFloat)x * expScaleX);
kernelX[i] = (CGFloat)exp((CGFloat)x*(CGFloat)x * expScaleX); kernel->xScale += kernel->xValues[i];
scaleX += kernelX[i];
} }
scaleX = 1.0f / scaleX; //NOTE: using the mathematical definition of the scaling term doesn't work since we cut the filter support early for performance kernel->xScale = 1.0f / kernel->xScale; //NOTE: using the mathematical definition of the scaling term doesn't work since we cut the filter support early for performance
int kernelYSize=kernelHeight*2+1; kernel->ySize=kernelHeight*2+1;
CGFloat kernelY[kernelYSize]; kernel->yValues=NSZoneMalloc(NULL,sizeof(CGFloat)*kernel->ySize);
int shiftY = kernelHeight; kernel->yShift = kernelHeight;
CGFloat scaleY = 0.0f; kernel->yScale = 0.0f;
for(i=0;i<kernelYSize;i++) for(i=0;i<kernel->ySize;i++)
{ {
int y = i-shiftY; int y = i-kernel->yShift;
kernelY[i] = (CGFloat)exp((CGFloat)y*(CGFloat)y * expScaleY); kernel->yValues[i] = (CGFloat)exp((CGFloat)y*(CGFloat)y * expScaleY);
scaleY += kernelY[i]; kernel->yScale += kernel->yValues[i];
} }
scaleY = 1.0f / scaleY; //NOTE: using the mathematical definition of the scaling term doesn't work since we cut the filter support early for performance kernel->yScale = 1.0f / kernel->yScale; //NOTE: using the mathematical definition of the scaling term doesn't work since we cut the filter support early for performance
return kernel;
}
VGColor *tmp2=(VGColor *)NSZoneMalloc(NULL,w*src->_height*sizeof(VGColor)); KGGaussianKernelRef KGGaussianKernelRetain(KGGaussianKernelRef kernel) {
if(kernel!=NULL)
kernel->refCount++;
return kernel;
}
void KGGaussianKernelRelease(KGGaussianKernelRef kernel) {
if(kernel!=NULL){
kernel->refCount--;
if(kernel->refCount<=0){
NSZoneFree(NULL,kernel->xValues);
NSZoneFree(NULL,kernel->yValues);
NSZoneFree(NULL,kernel);
}
}
}
void KGSurfaceGaussianBlur(KGSurface *self,KGImage * src, KGGaussianKernel *kernel){
RI_ASSERT(src->_pixelBytes); //source exists
RI_ASSERT(self->_pixelBytes); //destination exists
//the area to be written is an intersection of source and destination image areas.
//lower-left corners of the images are aligned.
int w = RI_INT_MIN(self->_width, src->_width);
int h = RI_INT_MIN(self->_height, src->_height);
RI_ASSERT(w > 0 && h > 0);
KGRGBAffff *tmp=NSZoneMalloc(NULL,src->_width*src->_height*sizeof(KGRGBAffff));
//copy source region to tmp and do conversion
int i,j;
for(j=0;j<src->_height;j++){
KGRGBAffff *tmpRow=tmp+j*src->_width;
int i,width=src->_width;
KGRGBAffff *direct=KGImageReadSpan_lRGBAffff_PRE(src,0,j,tmpRow,width);
if(direct!=NULL){
for(i=0;i<width;i++)
tmpRow[i]=direct[i];
}
}
KGRGBAffff *tmp2=NSZoneMalloc(NULL,w*src->_height*sizeof(KGRGBAffff));
//horizontal pass //horizontal pass
for(j=0;j<src->_height;j++) for(j=0;j<src->_height;j++){
{ for(i=0;i<w;i++){
for(i=0;i<w;i++) KGRGBAffff sum=KGRGBAffffInit(0,0,0,0);
{
VGColor sum=VGColorRGBA(0,0,0,0,procFormat);
int ki; int ki;
for(ki=0;ki<kernelXSize;ki++) for(ki=0;ki<kernel->xSize;ki++){
{ int x = i+ki-kernel->xShift;
int x = i+ki-shiftX; sum=KGRGBAffffAdd(sum, KGRGBAffffMultiplyByFloat(gaussianReadPixel(x, j, src->_width, src->_height, tmp),kernel->xValues[ki]));
sum=VGColorAdd(sum, VGColorMultiplyByFloat(readTiledPixel(x, j, src->_width, src->_height, tilingMode, tmp, edge),kernelX[ki]));
} }
tmp2[j*w+i] = VGColorMultiplyByFloat(sum, scaleX); tmp2[j*w+i] = KGRGBAffffMultiplyByFloat(sum, kernel->xScale);
} }
} }
//vertical pass //vertical pass
for(j=0;j<h;j++) for(j=0;j<h;j++){
{ for(i=0;i<w;i++){
for(i=0;i<w;i++) KGRGBAffff sum=KGRGBAffffInit(0,0,0,0);
{
VGColor sum=VGColorRGBA(0,0,0,0,procFormat);
int kj; int kj;
for(kj=0;kj<kernelYSize;kj++) for(kj=0;kj<kernel->ySize;kj++){
{ int y = j+kj-kernel->yShift;
int y = j+kj-shiftY; sum=KGRGBAffffAdd(sum, KGRGBAffffMultiplyByFloat(gaussianReadPixel(i, y, w, src->_height, tmp2), kernel->yValues[kj]));
sum=VGColorAdd(sum, VGColorMultiplyByFloat(readTiledPixel(i, y, w, src->_height, tilingMode, tmp2, edge), kernelY[kj]));
} }
KGSurfaceWriteFilteredPixel(self,i, j, VGColorMultiplyByFloat(sum, scaleY), channelMask); sum=KGRGBAffffMultiplyByFloat(sum, kernel->yScale);
KGSurfaceWriteSpan_lRGBAffff_PRE(self,i, j, &sum,1);
} }
} }
NSZoneFree(NULL,tmp); NSZoneFree(NULL,tmp);

View File

@ -9,7 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#import "NSTIFFImageFileDirectory.h" #import "NSTIFFImageFileDirectory.h"
#import "NSTIFFReader.h" #import "NSTIFFReader.h"
#import "KGPDFFilter.h" #import "KGPDFFilter.h"
#import <ApplicationServices/CoreGraphics.h> #import <ApplicationServices/ApplicationServices.h>
@implementation NSTIFFImageFileDirectory @implementation NSTIFFImageFileDirectory

View File

@ -0,0 +1,6 @@
#import <AppKit/NSColor.h>
#import <ApplicationServices/ApplicationServices.h>
@interface NSColor(NSAppKitPrivate)
-(CGColorRef)createCGColorRef;
@end

View File

@ -67,6 +67,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return nil; return nil;
} }
-(CGColorRef)createCGColorRef {
return CGColorRetain(_colorRef);
}
-(void)setStroke { -(void)setStroke {
CGContextSetStrokeColorWithColor(NSCurrentGraphicsPort(),_colorRef); CGContextSetStrokeColorWithColor(NSCurrentGraphicsPort(),_colorRef);
} }

View File

@ -9,6 +9,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#import <AppKit/NSColor_catalog.h> #import <AppKit/NSColor_catalog.h>
#import <AppKit/NSGraphics.h> #import <AppKit/NSGraphics.h>
#import <AppKit/NSDisplay.h> #import <AppKit/NSDisplay.h>
#import <AppKit/NSColor-Private.h>
@implementation NSColor_catalog @implementation NSColor_catalog
@ -71,6 +72,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return result; return result;
} }
-(CGColorRef)createCGColorRef {
return [[[NSDisplay currentDisplay] colorWithName:_colorName] createCGColorRef];
}
-(void)setFill { -(void)setFill {
NSColor *color=[[NSDisplay currentDisplay] colorWithName:_colorName]; NSColor *color=[[NSDisplay currentDisplay] colorWithName:_colorName];

View File

@ -97,6 +97,16 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return [super colorUsingColorSpaceName:colorSpace device:device]; return [super colorUsingColorSpaceName:colorSpace device:device];
} }
-(CGColorRef)createCGColorRef {
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceCMYK();
float components[5]={_cyan,_magenta,_yellow,_black,_alpha};
KGColor *color=CGColorCreate(colorSpace,components);
CGColorSpaceRelease(colorSpace);
return color;
}
-(void)setFill { -(void)setFill {
CGContextSetCMYKFillColor(NSCurrentGraphicsPort(),_cyan,_magenta,_yellow,_black, _alpha); CGContextSetCMYKFillColor(NSCurrentGraphicsPort(),_cyan,_magenta,_yellow,_black, _alpha);
} }

View File

@ -105,6 +105,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return [super colorUsingColorSpaceName:colorSpace device:device]; return [super colorUsingColorSpaceName:colorSpace device:device];
} }
-(CGColorRef)createCGColorRef {
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
float components[4]={_red,_green,_blue,_alpha};
KGColor *color=CGColorCreate(colorSpace,components);
CGColorSpaceRelease(colorSpace);
return color;
}
-(void)setFill { -(void)setFill {
CGContextSetRGBFillColor(NSCurrentGraphicsPort(),_red,_green,_blue,_alpha); CGContextSetRGBFillColor(NSCurrentGraphicsPort(),_red,_green,_blue,_alpha);
} }

View File

@ -111,6 +111,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return NSDeviceRGBColorSpace; return NSDeviceRGBColorSpace;
} }
-(CGColorRef)createCGColorRef {
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
float components[4]={_red,_green,_blue,_alpha};
KGColor *color=CGColorCreate(colorSpace,components);
CGColorSpaceRelease(colorSpace);
return color;
}
-(void)setStroke { -(void)setStroke {
CGContextSetRGBStrokeColor(NSCurrentGraphicsPort(),_red,_green,_blue,_alpha); CGContextSetRGBStrokeColor(NSCurrentGraphicsPort(),_red,_green,_blue,_alpha);
} }

View File

@ -124,6 +124,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return [super colorUsingColorSpaceName:colorSpace device:device]; return [super colorUsingColorSpaceName:colorSpace device:device];
} }
-(CGColorRef)createCGColorRef {
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceGray();
float components[2]={_white,_alpha};
KGColor *color=CGColorCreate(colorSpace,components);
CGColorSpaceRelease(colorSpace);
return color;
}
-(void)setStroke { -(void)setStroke {
CGContextSetGrayStrokeColor(NSCurrentGraphicsPort(),_white,_alpha); CGContextSetGrayStrokeColor(NSCurrentGraphicsPort(),_white,_alpha);
} }

View File

@ -66,6 +66,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
return [[[[self class] alloc] initWithGray:_white alpha:alpha] autorelease]; return [[[[self class] alloc] initWithGray:_white alpha:alpha] autorelease];
} }
-(CGColorRef)createCGColorRef {
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceGray();
float components[2]={_white,_alpha};
KGColor *color=CGColorCreate(colorSpace,components);
CGColorSpaceRelease(colorSpace);
return color;
}
-(void)setStroke { -(void)setStroke {
CGContextSetGrayStrokeColor(NSCurrentGraphicsPort(),_white,_alpha); CGContextSetGrayStrokeColor(NSCurrentGraphicsPort(),_white,_alpha);
} }

View File

@ -130,9 +130,10 @@ void evaluate(void *info,const float *in, float *output) {
function=CGFunctionCreate(self,1,domain,4,range,&callbacks); function=CGFunctionCreate(self,1,domain,4,range,&callbacks);
float radius=[self bounds].size.width/2; float radius=[self bounds].size.width/2;
CGColorSpaceRef colorSpace=CGColorSpaceCreateDeviceRGB();
shading=CGShadingCreateRadial(CGColorSpaceCreateDeviceRGB(),CGPointMake(0,0),1, shading=CGShadingCreateRadial(CGColorSpaceCreateDeviceRGB(),CGPointMake(0,0),1,
CGPointMake(radius *2,radius*2),radius,function,YES,NO); CGPointMake(radius *2,radius*2),radius,function,YES,NO);
CGColorSpaceRelease(colorSpace);
CGContextDrawShading(graphicsPort,shading); CGContextDrawShading(graphicsPort,shading);
CGContextRotateCTM(graphicsPort,M_PI*(120)/180.0); CGContextRotateCTM(graphicsPort,M_PI*(120)/180.0);
CGContextDrawShading(graphicsPort,shading); CGContextDrawShading(graphicsPort,shading);

View File

@ -7,9 +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. */ 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 <AppKit/NSShadow.h> #import <AppKit/NSShadow.h>
#import <AppKit/NSColor.h> #import <AppKit/NSColor-Private.h>
#import <AppKit/NSGraphicsContext.h> #import <AppKit/NSGraphicsContext.h>
#import <ApplicationServices/CGContext.h> #import <ApplicationServices/ApplicationServices.h>
#import <Foundation/NSRaise.h> #import <Foundation/NSRaise.h>
@implementation NSShadow @implementation NSShadow
@ -71,10 +71,11 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
-(void)set { -(void)set {
CGContextRef context=[[NSGraphicsContext currentContext] graphicsPort]; CGContextRef context=[[NSGraphicsContext currentContext] graphicsPort];
CGColorRef color=[_color createCGColorRef];
CGContextSetShadowWithColor(context,_offset,_blurRadius,color);
// need NSColor->CGColor CGColorRelease(color);
// CGContextSetShadowWithColor(context,_offset,_blurRadius,[color _cgColor]);
NSUnimplementedMethod();
} }
@end @end

View File

@ -25,3 +25,5 @@ typedef enum {
COREGRAPHICS_EXPORT void CGColorSpaceRelease(CGColorSpaceRef colorSpace); COREGRAPHICS_EXPORT void CGColorSpaceRelease(CGColorSpaceRef colorSpace);
COREGRAPHICS_EXPORT CGColorSpaceRef CGColorSpaceCreateDeviceRGB(); COREGRAPHICS_EXPORT CGColorSpaceRef CGColorSpaceCreateDeviceRGB();
COREGRAPHICS_EXPORT CGColorSpaceRef CGColorSpaceCreateDeviceGray();
COREGRAPHICS_EXPORT CGColorSpaceRef CGColorSpaceCreateDeviceCMYK();

View File

@ -180,8 +180,8 @@
[context setFlatness:flatness] [context setFlatness:flatness]
#define CGContextSetInterpolationQuality(context,quality) \ #define CGContextSetInterpolationQuality(context,quality) \
[context setInterpolationQuality:quality] [context setInterpolationQuality:quality]
#define CGContextSetShadowWithColor(context,offset,blur,color) \ #define CGContextSetShadowWithColor(context,o,b,c) \
[context setShadowOffset:offset blur:blur color:color] [context setShadowOffset:o blur:b color:c]
#define CGContextSetShadow(context,offset,blur) \ #define CGContextSetShadow(context,offset,blur) \
[context setShadowOffset:offset blur:blur] [context setShadowOffset:offset blur:blur]
#define CGContextSetShouldAntialias(context,yesOrNo) \ #define CGContextSetShouldAntialias(context,yesOrNo) \

View File

@ -79,7 +79,7 @@ static CGColorRef cgColorFromColor(NSColor *color){
_dashLengthsCount=0; _dashLengthsCount=0;
_dashLengths=NSZoneMalloc([self zone],sizeof(float)*4); _dashLengths=NSZoneMalloc([self zone],sizeof(float)*4);
NSString *path=[[NSBundle bundleForClass:[self class]] pathForResource:@"overlay" ofType:@"jpg"]; NSString *path=[[NSBundle bundleForClass:[self class]] pathForResource:@"overlay" ofType:@"png"];
NSData *data=[NSData dataWithContentsOfFile:path]; NSData *data=[NSData dataWithContentsOfFile:path];
CGImageSourceRef source=CGImageSourceCreateWithData((CFDataRef)data,nil); CGImageSourceRef source=CGImageSourceCreateWithData((CFDataRef)data,nil);
_resamplingImage=CGImageSourceCreateImageAtIndex(source,0,nil); _resamplingImage=CGImageSourceCreateImageAtIndex(source,0,nil);
@ -282,6 +282,16 @@ static void addSliceToPath(CGMutablePathRef path,float innerRadius,float outerRa
[self establishContextState]; [self establishContextState];
#if 0
CGColorRef color=CGColorCreateGenericRGB(1,0,0,1);
CGContextSetShadowWithColor(_context,CGSizeMake(-5,-5),5,color);
CGColorRelease(color);
#endif
#if 0
CGContextAddEllipseInRect(_context,CGRectMake(0,0,CGImageGetWidth(_resamplingImage),CGImageGetHeight(_resamplingImage)));
CGContextClip(_context);
#endif
CGContextDrawImage(_context,CGRectMake(0,0,CGImageGetWidth(_resamplingImage),CGImageGetHeight(_resamplingImage)),_resamplingImage); CGContextDrawImage(_context,CGRectMake(0,0,CGImageGetWidth(_resamplingImage),CGImageGetHeight(_resamplingImage)),_resamplingImage);
CGContextRestoreGState(_context); CGContextRestoreGState(_context);

View File

@ -10,11 +10,11 @@
<integer>5</integer> <integer>5</integer>
<key>IBOpenObjects</key> <key>IBOpenObjects</key>
<array> <array>
<integer>2</integer>
<integer>29</integer> <integer>29</integer>
<integer>2</integer>
</array> </array>
<key>IBSystem Version</key> <key>IBSystem Version</key>
<string>9D34</string> <string>9E17</string>
<key>targetFramework</key> <key>targetFramework</key>
<string>IBCocoaFramework</string> <string>IBCocoaFramework</string>
</dict> </dict>

View File

@ -649,7 +649,7 @@
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO; GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = NO;
GCC_MODEL_TUNING = ""; GCC_MODEL_TUNING = "";
GCC_OPTIMIZATION_LEVEL = 3; GCC_OPTIMIZATION_LEVEL = 3;
GCC_UNROLL_LOOPS = YES; GCC_UNROLL_LOOPS = NO;
GCC_VERSION = 4.2; GCC_VERSION = 4.2;
GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GCC_WARN_SHADOW = NO; GCC_WARN_SHADOW = NO;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 36 KiB