mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-11-27 22:10:23 +00:00
- Issue #183 fix, KGImageSource_TIFF, KGImageSource_PNG clamps color channel for premultiplied alpha
-[NSPopUpButtonCell insertItemWithTitle: atIndex:] implemented -[NSResponder validRequestorForSendType: returnType:] implemented - VGPath cleanup and changed to just tessellation info and references the path instead having to be rebuild the path too. Removal of VGmath.m - cleanup
This commit is contained in:
parent
dbd854cab8
commit
e1b0f2f114
@ -651,7 +651,6 @@
|
||||
C88976BF0EA0BF3100D0A0A2 /* NSMultipleValueBinder.m in Sources */ = {isa = PBXBuildFile; fileRef = FE8D951F0CE4057300AFB060 /* NSMultipleValueBinder.m */; };
|
||||
C88976C00EA0BF3100D0A0A2 /* NSSystemInfoPanel.m in Sources */ = {isa = PBXBuildFile; fileRef = FE8286790D34727900F7489F /* NSSystemInfoPanel.m */; };
|
||||
C88976C10EA0BF3100D0A0A2 /* KGClipPhase.m in Sources */ = {isa = PBXBuildFile; fileRef = FE34FBC70D6F24A5008D2C1A /* KGClipPhase.m */; };
|
||||
C88976C30EA0BF3100D0A0A2 /* VGmath.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE27D0DB91EA8005503A1 /* VGmath.m */; };
|
||||
C88976C40EA0BF3100D0A0A2 /* KGSurface.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE28D0DB91FDF005503A1 /* KGSurface.m */; };
|
||||
C88976C50EA0BF3100D0A0A2 /* VGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE2E40DB92B11005503A1 /* VGPath.m */; };
|
||||
C88976C60EA0BF3100D0A0A2 /* KGContext_builtin.m in Sources */ = {isa = PBXBuildFile; fileRef = FE3395580DB930F4009AB3E0 /* KGContext_builtin.m */; };
|
||||
@ -1390,7 +1389,6 @@
|
||||
FE66F0060E513AE8006C5796 /* CGImageProperties.m in Sources */ = {isa = PBXBuildFile; fileRef = FE66F0050E513AE8006C5796 /* CGImageProperties.m */; };
|
||||
FE6EDE340DB797D9005503A1 /* KGExceptions.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6EDE330DB797D9005503A1 /* KGExceptions.h */; };
|
||||
FE6EE27E0DB91EA8005503A1 /* VGmath.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6EE27C0DB91EA8005503A1 /* VGmath.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
FE6EE27F0DB91EA8005503A1 /* VGmath.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE27D0DB91EA8005503A1 /* VGmath.m */; };
|
||||
FE6EE28E0DB91FDF005503A1 /* KGSurface.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6EE28C0DB91FDF005503A1 /* KGSurface.h */; settings = {ATTRIBUTES = (Private, ); }; };
|
||||
FE6EE28F0DB91FDF005503A1 /* KGSurface.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE28D0DB91FDF005503A1 /* KGSurface.m */; };
|
||||
FE6EE2E50DB92B11005503A1 /* VGPath.h in Headers */ = {isa = PBXBuildFile; fileRef = FE6EE2E30DB92B11005503A1 /* VGPath.h */; };
|
||||
@ -2214,7 +2212,6 @@
|
||||
FE6DC3EF0BA9A7100082AC66 /* NSDatePickerCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDatePickerCell.m; sourceTree = "<group>"; };
|
||||
FE6EDE330DB797D9005503A1 /* KGExceptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KGExceptions.h; sourceTree = "<group>"; };
|
||||
FE6EE27C0DB91EA8005503A1 /* VGmath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGmath.h; sourceTree = "<group>"; };
|
||||
FE6EE27D0DB91EA8005503A1 /* VGmath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGmath.m; sourceTree = "<group>"; };
|
||||
FE6EE28C0DB91FDF005503A1 /* KGSurface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KGSurface.h; sourceTree = "<group>"; };
|
||||
FE6EE28D0DB91FDF005503A1 /* KGSurface.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KGSurface.m; sourceTree = "<group>"; };
|
||||
FE6EE2E30DB92B11005503A1 /* VGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGPath.h; sourceTree = "<group>"; };
|
||||
@ -2844,7 +2841,6 @@
|
||||
FE6EE28C0DB91FDF005503A1 /* KGSurface.h */,
|
||||
FE6EE28D0DB91FDF005503A1 /* KGSurface.m */,
|
||||
FE6EE27C0DB91EA8005503A1 /* VGmath.h */,
|
||||
FE6EE27D0DB91EA8005503A1 /* VGmath.m */,
|
||||
FE6EDE330DB797D9005503A1 /* KGExceptions.h */,
|
||||
FE34FBC60D6F24A5008D2C1A /* KGClipPhase.h */,
|
||||
FE34FBC70D6F24A5008D2C1A /* KGClipPhase.m */,
|
||||
@ -4641,7 +4637,6 @@
|
||||
C88976BF0EA0BF3100D0A0A2 /* NSMultipleValueBinder.m in Sources */,
|
||||
C88976C00EA0BF3100D0A0A2 /* NSSystemInfoPanel.m in Sources */,
|
||||
C88976C10EA0BF3100D0A0A2 /* KGClipPhase.m in Sources */,
|
||||
C88976C30EA0BF3100D0A0A2 /* VGmath.m in Sources */,
|
||||
C88976C40EA0BF3100D0A0A2 /* KGSurface.m in Sources */,
|
||||
C88976C50EA0BF3100D0A0A2 /* VGPath.m in Sources */,
|
||||
C88976C60EA0BF3100D0A0A2 /* KGContext_builtin.m in Sources */,
|
||||
@ -5002,7 +4997,6 @@
|
||||
FE8286810D34727900F7489F /* NSSystemInfoPanel.m in Sources */,
|
||||
FE34FBC90D6F24A5008D2C1A /* KGClipPhase.m in Sources */,
|
||||
FE5C69A20D76039F00098551 /* KGDeviceContext_gdiDIBSection.m in Sources */,
|
||||
FE6EE27F0DB91EA8005503A1 /* VGmath.m in Sources */,
|
||||
FE6EE28F0DB91FDF005503A1 /* KGSurface.m in Sources */,
|
||||
FE6EE2E60DB92B11005503A1 /* VGPath.m in Sources */,
|
||||
FE33955A0DB930F4009AB3E0 /* KGContext_builtin.m in Sources */,
|
||||
|
@ -142,59 +142,6 @@ BOOL _isAvailable=NO;
|
||||
[[self currentState] setDeviceSpaceCTM:flip];
|
||||
}
|
||||
|
||||
static void applyPath(void *info,const CGPathElement *element) {
|
||||
VGPath *vgPath=( VGPath *)info;
|
||||
CGPoint *points=element->points;
|
||||
|
||||
switch(element->type){
|
||||
|
||||
case kCGPathElementMoveToPoint:{
|
||||
RIuint8 segment[1]={kCGPathElementMoveToPoint};
|
||||
|
||||
|
||||
VGPathAppendData(vgPath,segment,1,points);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGPathElementAddLineToPoint:{
|
||||
RIuint8 segment[1]={kCGPathElementAddLineToPoint};
|
||||
|
||||
VGPathAppendData(vgPath,segment,1,points);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGPathElementAddCurveToPoint:{
|
||||
RIuint8 segment[1]={kCGPathElementAddCurveToPoint};
|
||||
|
||||
VGPathAppendData(vgPath,segment,1,points);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGPathElementAddQuadCurveToPoint:{
|
||||
RIuint8 segment[1]={kCGPathElementAddQuadCurveToPoint};
|
||||
|
||||
VGPathAppendData(vgPath,segment,1,points);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGPathElementCloseSubpath:{
|
||||
RIuint8 segment[1]={kCGPathElementCloseSubpath};
|
||||
|
||||
VGPathAppendData(vgPath,segment,1,points);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
-(VGPath *)buildDeviceSpacePath:(KGPath *)path {
|
||||
|
||||
VGPath *vgPath=VGPathInit(VGPathAlloc(),1,1);
|
||||
|
||||
[path applyWithInfo:vgPath function:applyPath];
|
||||
|
||||
return vgPath;
|
||||
}
|
||||
|
||||
-(void)deviceClipReset {
|
||||
KGRasterizerSetViewport(self,0,0,KGImageGetWidth(_surface),KGImageGetHeight(_surface));
|
||||
}
|
||||
@ -227,7 +174,6 @@ static KGPaint *paintFromColor(KGColor *color){
|
||||
}
|
||||
|
||||
-(void)drawPath:(CGPathDrawingMode)drawingMode {
|
||||
VGPath *vgPath=[self buildDeviceSpacePath:_path];
|
||||
KGGraphicsState *gState=[self currentState];
|
||||
|
||||
// KGRasterizeSetMask(context->m_masking ? context->getMask() : NULL);
|
||||
@ -240,8 +186,8 @@ static KGPaint *paintFromColor(KGColor *color){
|
||||
|
||||
CGAffineTransform userToSurfaceMatrix=gState->_deviceSpaceTransform;
|
||||
|
||||
VGPathTransform(vgPath,CGAffineTransformInvert(gState->_userSpaceTransform));
|
||||
|
||||
[_path applyTransform:CGAffineTransformInvert(gState->_userSpaceTransform)];
|
||||
VGPath *vgPath=[[VGPath alloc] initWithKGPath:_path];
|
||||
|
||||
if(drawingMode!=kCGPathStroke){
|
||||
KGPaint *paint=paintFromColor(gState->_fillColor);
|
||||
@ -249,7 +195,8 @@ static KGPaint *paintFromColor(KGColor *color){
|
||||
[paint release];
|
||||
|
||||
CGAffineTransform surfaceToPaintMatrix =userToSurfaceMatrix;//context->m_pathUserToSurface * context->m_fillPaintToUser;
|
||||
if(CGAffineTransformInplaceInvert(&surfaceToPaintMatrix)){
|
||||
|
||||
surfaceToPaintMatrix=CGAffineTransformInvert(surfaceToPaintMatrix);
|
||||
KGPaintSetSurfaceToPaintMatrix(paint,surfaceToPaintMatrix);
|
||||
|
||||
VGPathFill(vgPath,userToSurfaceMatrix,self);
|
||||
@ -257,7 +204,6 @@ static KGPaint *paintFromColor(KGColor *color){
|
||||
VGFillRuleMask fillRule=(drawingMode==kCGPathFill || drawingMode==kCGPathFillStroke)?VG_NON_ZERO:VG_EVEN_ODD;
|
||||
|
||||
KGRasterizerFill(self,fillRule);
|
||||
}
|
||||
}
|
||||
|
||||
if(drawingMode>=kCGPathStroke){
|
||||
@ -267,7 +213,8 @@ static KGPaint *paintFromColor(KGColor *color){
|
||||
[paint release];
|
||||
|
||||
CGAffineTransform surfaceToPaintMatrix=userToSurfaceMatrix;// = context->m_pathUserToSurface * context->m_strokePaintToUser;
|
||||
if(CGAffineTransformInplaceInvert(&surfaceToPaintMatrix)){
|
||||
|
||||
surfaceToPaintMatrix=CGAffineTransformInvert(surfaceToPaintMatrix);
|
||||
KGPaintSetSurfaceToPaintMatrix(paint,surfaceToPaintMatrix);
|
||||
|
||||
KGRasterizerClear(self);
|
||||
@ -275,11 +222,10 @@ static KGPaint *paintFromColor(KGColor *color){
|
||||
VGPathStroke(vgPath,userToSurfaceMatrix, self, gState->_dashLengths,gState->_dashLengthsCount, gState->_dashPhase, YES /* context->m_strokeDashPhaseReset ? YES : NO*/,
|
||||
gState->_lineWidth, gState->_lineCap, gState->_lineJoin, RI_MAX(gState->_miterLimit, 1.0f));
|
||||
KGRasterizerFill(self,VG_NON_ZERO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VGPathDealloc(vgPath);
|
||||
[vgPath release];
|
||||
KGRasterizerClear(self);
|
||||
[_path reset];
|
||||
}
|
||||
@ -366,7 +312,9 @@ xform=CGAffineTransformConcat(i2u,xform);
|
||||
|
||||
CGAffineTransform surfaceToImageMatrix = imageUserToSurface;
|
||||
CGAffineTransform surfaceToPaintMatrix = CGAffineTransformConcat(imageUserToSurface,fillPaintToUser);
|
||||
if(CGAffineTransformInplaceInvert(&surfaceToImageMatrix) && CGAffineTransformInplaceInvert(&surfaceToPaintMatrix)){
|
||||
|
||||
surfaceToImageMatrix=CGAffineTransformInvert(surfaceToImageMatrix);
|
||||
surfaceToPaintMatrix=CGAffineTransformInvert(surfaceToPaintMatrix);
|
||||
KGPaintSetSurfaceToPaintMatrix(paint,surfaceToPaintMatrix);
|
||||
KGPaintSetSurfaceToPaintMatrix(imagePaint,surfaceToImageMatrix);
|
||||
|
||||
@ -375,7 +323,7 @@ xform=CGAffineTransformConcat(i2u,xform);
|
||||
KGRasterizerAddEdge(self,p2, p3);
|
||||
KGRasterizerAddEdge(self,p3, p0);
|
||||
KGRasterizerFill(self,VG_EVEN_ODD);
|
||||
}
|
||||
|
||||
KGRasterizeSetPaint(self,nil);
|
||||
[paint release];
|
||||
[imagePaint release];
|
||||
@ -995,7 +943,7 @@ void KGRasterizerFill(KGRasterizer *self,int fillRuleMask) {
|
||||
|
||||
windptr++;
|
||||
}
|
||||
|
||||
|
||||
accum+=increase[scanx];
|
||||
increase[scanx]=INT_MAX;
|
||||
|
||||
|
@ -543,6 +543,14 @@ unsigned char *stbi_png_load_from_memory(const unsigned char *buffer, int len, i
|
||||
int bytesPerRow=(bitsPerPixel/(sizeof(char)*8))*width;
|
||||
NSData *bitmap;
|
||||
|
||||
// clamp premultiplied data, this should probably be moved into the KGImage init
|
||||
int i;
|
||||
for(i=0;i<bytesPerRow*height;i+=4){
|
||||
pixels[i]=MIN(pixels[i],pixels[i+3]);
|
||||
pixels[i+1]=MIN(pixels[i+1],pixels[i+3]);
|
||||
pixels[i+2]=MIN(pixels[i+2],pixels[i+3]);
|
||||
}
|
||||
|
||||
bitmap=[[NSData alloc] initWithBytesNoCopy:pixels length:bytesPerRow*height];
|
||||
|
||||
KGDataProvider *provider=[[KGDataProvider alloc] initWithData:bitmap];
|
||||
|
@ -95,6 +95,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
return nil;
|
||||
}
|
||||
|
||||
// clamp premultiplied data, this should probably be moved into the KGImage init
|
||||
int i;
|
||||
for(i=0;i<bytesPerRow*height;i+=4){
|
||||
bytes[i]=MIN(bytes[i],bytes[i+3]);
|
||||
bytes[i+1]=MIN(bytes[i+1],bytes[i+3]);
|
||||
bytes[i+2]=MIN(bytes[i+2],bytes[i+3]);
|
||||
}
|
||||
|
||||
bitmap=[[NSData alloc] initWithBytesNoCopy:bytes length:bytesPerRow*height];
|
||||
|
||||
KGDataProvider *provider=[[KGDataProvider alloc] initWithData:bitmap];
|
||||
|
@ -77,6 +77,10 @@ static inline KGIntRect KGIntRectInit(int x,int y,int width,int height) {
|
||||
return result;
|
||||
}
|
||||
|
||||
#define RI_INT32_MAX (0x7fffffff)
|
||||
#define RI_INT32_MIN (-0x7fffffff-1)
|
||||
static inline int RI_INT_ADDSATURATE(int a, int b) { RI_ASSERT(b >= 0); int r = a + b; return (r >= a) ? r : RI_INT32_MAX; }
|
||||
|
||||
static inline KGIntRect KGIntRectIntersect(KGIntRect self,KGIntRect other) {
|
||||
if(self.width >= 0 && other.width >= 0 && self.height >= 0 && other.height >= 0)
|
||||
{
|
||||
|
@ -30,53 +30,14 @@
|
||||
#import "KGPath.h"
|
||||
#import "KGContext_builtin.h"
|
||||
|
||||
typedef struct {
|
||||
CGPoint userPosition;
|
||||
CGPoint userTangent;
|
||||
CGFloat pathLength;
|
||||
unsigned int flags;
|
||||
} Vertex;
|
||||
|
||||
typedef struct {
|
||||
CGPoint p;
|
||||
CGPoint t;
|
||||
CGPoint ccw;
|
||||
CGPoint cw;
|
||||
CGFloat pathLength;
|
||||
unsigned int flags;
|
||||
BOOL inDash;
|
||||
} StrokeVertex;
|
||||
|
||||
static inline StrokeVertex StrokeVertexInit(){
|
||||
StrokeVertex result;
|
||||
|
||||
result.p=CGPointMake(0,0);
|
||||
result.t=CGPointMake(0,0);
|
||||
result.ccw=CGPointMake(0,0);
|
||||
result.cw=CGPointMake(0,0);
|
||||
result.pathLength=0;
|
||||
result.flags=0;
|
||||
result.inDash=NO;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//data produced by tessellation
|
||||
typedef struct {
|
||||
int start;
|
||||
int end;
|
||||
} VertexIndex;
|
||||
|
||||
@interface VGPath : KGPath {
|
||||
int _capacityOfElements;
|
||||
int _capacityOfPoints;
|
||||
|
||||
@interface VGPath : NSObject {
|
||||
KGPath *_path;
|
||||
int _vertexCount;
|
||||
int _vertexCapacity;
|
||||
Vertex *_vertices;
|
||||
struct Vertex *_vertices;
|
||||
|
||||
int _segmentToVertexCapacity;
|
||||
VertexIndex *_segmentToVertex;
|
||||
struct VertexIndex *_segmentToVertex;
|
||||
|
||||
CGFloat m_userMinx;
|
||||
CGFloat m_userMiny;
|
||||
@ -84,37 +45,16 @@ typedef struct {
|
||||
CGFloat m_userMaxy;
|
||||
}
|
||||
|
||||
VGPath *VGPathAlloc();
|
||||
VGPath *VGPathInit(VGPath *self,int segmentCapacityHint, int coordCapacityHint);
|
||||
void VGPathDealloc(VGPath *self);
|
||||
-initWithKGPath:(KGPath *)path;
|
||||
|
||||
void VGPathAppendData(VGPath *self,const RIuint8* segments, int numSegments, const CGPoint *data);
|
||||
void VGPathAppend(VGPath *self,VGPath* srcPath);
|
||||
void VGPathTransform(VGPath *self,CGAffineTransform matrix);
|
||||
//returns YES if interpolation succeeds, NO if start and end paths are not compatible
|
||||
void VGPathFill(VGPath *self,CGAffineTransform pathToSurface, KGRasterizer *rasterizer);
|
||||
void VGPathStroke(VGPath *self,CGAffineTransform pathToSurface, KGRasterizer *rasterizer, const CGFloat* dashPattern,int dashPatternSize, CGFloat dashPhase, BOOL dashPhaseReset, CGFloat strokeWidth, CGLineCap capStyle, CGLineJoin joinStyle, CGFloat miterLimit);
|
||||
|
||||
void VGPathGetPointAlong(VGPath *self,int startIndex, int numSegments, CGFloat distance, CGPoint *p, CGPoint *t);
|
||||
CGFloat getPathLength(VGPath *self,int startIndex, int numSegments);
|
||||
void VGPathGetPathBounds(VGPath *self,CGFloat *minx, CGFloat *miny, CGFloat *maxx, CGFloat *maxy);
|
||||
void VGPathGetPathTransformedBounds(VGPath *self,CGAffineTransform pathToSurface, CGFloat *minx, CGFloat *miny, CGFloat *maxx, CGFloat *maxy);
|
||||
|
||||
int CGPathElementTypeToNumCoordinates(CGPathElementType segment);
|
||||
int VGPathCountNumCoordinates(const RIuint8* segments, int numSegments);
|
||||
|
||||
void VGPathAddVertex(VGPath *self,CGPoint p, CGPoint t, CGFloat pathLength, unsigned int flags);
|
||||
void VGPathAddEdge(VGPath *self,CGPoint p0, CGPoint p1, CGPoint t0, CGPoint t1, unsigned int startFlags, unsigned int endFlags);
|
||||
|
||||
void VGPathAddEndPath(VGPath *self,CGPoint p0, CGPoint p1, BOOL subpathHasGeometry, unsigned int flags);
|
||||
BOOL VGPathAddLineTo(VGPath *self,CGPoint p0, CGPoint p1, BOOL subpathHasGeometry);
|
||||
BOOL VGPathAddQuadTo(VGPath *self,CGPoint p0, CGPoint p1, CGPoint p2, BOOL subpathHasGeometry);
|
||||
BOOL VGPathAddCubicTo(VGPath *self,CGPoint p0, CGPoint p1, CGPoint p2, CGPoint p3, BOOL subpathHasGeometry);
|
||||
void VGPathGetPathTransformedBounds(VGPath *self,CGAffineTransform pathToSurface, CGFloat *minx, CGFloat *miny, CGFloat *maxx, CGFloat *maxy);
|
||||
|
||||
void VGPathTessellate(VGPath *self);
|
||||
|
||||
void VGPathInterpolateStroke(CGAffineTransform pathToSurface, KGRasterizer *rasterizer,StrokeVertex v0,StrokeVertex v1, CGFloat strokeWidth);
|
||||
void VGPathDoCap(CGAffineTransform pathToSurface, KGRasterizer *rasterizer,StrokeVertex v, CGFloat strokeWidth, CGLineCap capStyle);
|
||||
void VGPathDoJoin(CGAffineTransform pathToSurface, KGRasterizer *rasterizer,StrokeVertex v0,StrokeVertex v1, CGFloat strokeWidth, CGLineJoin joinStyle, CGFloat miterLimit);
|
||||
|
||||
@end
|
||||
|
@ -29,6 +29,59 @@
|
||||
#import "VGPath.h"
|
||||
#import "VGmath.h"
|
||||
|
||||
static inline void RI_SWAP(CGFloat *a, CGFloat *b) { CGFloat tmp = *a; *a = *b; *b = tmp; }
|
||||
static inline CGFloat RI_RAD_TO_DEG(CGFloat a) { return (CGFloat)(a * 180.0f/ M_PI); }
|
||||
|
||||
static inline CGPoint Vector2Negate(CGPoint result){
|
||||
return CGPointMake(-result.x,-result.y);
|
||||
}
|
||||
|
||||
static inline CGFloat Vector2Length(CGPoint v){
|
||||
return sqrt((double)v.x*(double)v.x+(double)v.y*(double)v.y);
|
||||
}
|
||||
|
||||
static inline BOOL Vector2IsEqual(CGPoint v1,CGPoint v2 ){
|
||||
return (v1.x == v2.x) && (v1.y == v2.y);
|
||||
}
|
||||
|
||||
static inline BOOL Vector2IsZero(CGPoint v){
|
||||
return (v.x == 0.0f) && (v.y == 0.0f);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2MultiplyByFloat(CGPoint v,CGFloat f){
|
||||
return CGPointMake(v.x*f,v.y*f);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2Add(CGPoint v1,CGPoint v2 ){
|
||||
return CGPointMake(v1.x+v2.x, v1.y+v2.y);
|
||||
}
|
||||
|
||||
//if v is a zero vector, returns a zero vector
|
||||
static inline CGPoint Vector2Normalize(CGPoint v){
|
||||
double l = (double)v.x*(double)v.x+(double)v.y*(double)v.y;
|
||||
|
||||
if( l != 0.0 )
|
||||
l = 1.0 / sqrt(l);
|
||||
|
||||
return CGPointMake((CGFloat)((double)v.x * l), (CGFloat)((double)v.y * l));
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2PerpendicularCW(CGPoint v){
|
||||
return CGPointMake(v.y, -v.x);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2PerpendicularCCW(CGPoint v){
|
||||
return CGPointMake(-v.y, v.x);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2Perpendicular(CGPoint v, BOOL cw){
|
||||
if(cw)
|
||||
return CGPointMake(v.y, -v.x);
|
||||
|
||||
return CGPointMake(-v.y, v.x);
|
||||
}
|
||||
|
||||
|
||||
enum VertexFlags
|
||||
{
|
||||
START_SUBPATH = (1<<0),
|
||||
@ -39,14 +92,45 @@
|
||||
IMPLICIT_CLOSE_SUBPATH = (1<<5)
|
||||
};
|
||||
|
||||
#define RI_FLOAT_MAX FLT_MAX
|
||||
typedef struct Vertex {
|
||||
CGPoint userPosition;
|
||||
CGPoint userTangent;
|
||||
CGFloat pathLength;
|
||||
unsigned int flags;
|
||||
} Vertex;
|
||||
|
||||
//data produced by tessellation
|
||||
typedef struct VertexIndex {
|
||||
int start;
|
||||
int end;
|
||||
} VertexIndex;
|
||||
|
||||
static inline CGFloat inputFloat(CGFloat f) {
|
||||
//this function is used for all floating point input values
|
||||
if(RI_ISNAN(f)) return 0.0f; //convert NaN to zero
|
||||
return RI_CLAMP(f, -RI_FLOAT_MAX, RI_FLOAT_MAX); //clamp +-inf to +-CGFloat max
|
||||
typedef struct {
|
||||
CGPoint p;
|
||||
CGPoint t;
|
||||
CGPoint ccw;
|
||||
CGPoint cw;
|
||||
CGFloat pathLength;
|
||||
unsigned int flags;
|
||||
BOOL inDash;
|
||||
} StrokeVertex;
|
||||
|
||||
static inline StrokeVertex StrokeVertexInit(){
|
||||
StrokeVertex result;
|
||||
|
||||
result.p=CGPointMake(0,0);
|
||||
result.t=CGPointMake(0,0);
|
||||
result.ccw=CGPointMake(0,0);
|
||||
result.cw=CGPointMake(0,0);
|
||||
result.pathLength=0;
|
||||
result.flags=0;
|
||||
result.inDash=NO;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define RI_FLOAT_MAX FLT_MAX
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Form a reliable normalized average of the two unit input vectors.
|
||||
* The average always lies to the given direction from the first
|
||||
@ -168,25 +252,12 @@ static CGPoint circularLerp(CGPoint t0, CGPoint t1, CGFloat ratio)
|
||||
|
||||
@implementation VGPath
|
||||
|
||||
static inline int VGPathGetNumCoordinates(VGPath *self){
|
||||
return self->_numberOfPoints;
|
||||
}
|
||||
|
||||
VGPath *VGPathAlloc(){
|
||||
return (VGPath *)NSZoneCalloc(NULL,1,sizeof(VGPath));
|
||||
}
|
||||
|
||||
VGPath *VGPathInit(VGPath *self,int segmentCapacityHint, int coordCapacityHint){
|
||||
-initWithKGPath:(KGPath *)path {
|
||||
_path=[path retain];
|
||||
self->m_userMinx=0.0f;
|
||||
self->m_userMiny=0.0f;
|
||||
self->m_userMaxx=0.0f;
|
||||
self->m_userMaxy=0.0f;
|
||||
self->_numberOfElements=0;
|
||||
self->_capacityOfElements=(segmentCapacityHint>0)?RI_INT_MIN(segmentCapacityHint,65536):2;
|
||||
self->_elements=NSZoneMalloc(NULL,self->_capacityOfElements*sizeof(unsigned char));
|
||||
self->_numberOfPoints=0;
|
||||
self->_capacityOfPoints=(coordCapacityHint>0)?RI_INT_MIN(coordCapacityHint, 65536):2;
|
||||
self->_points=NSZoneMalloc(NULL,self->_capacityOfPoints*sizeof(CGPoint));
|
||||
self->_vertexCount=0;
|
||||
self->_vertexCapacity=2;
|
||||
self->_vertices=NSZoneMalloc(NULL,self->_vertexCapacity*sizeof(Vertex));
|
||||
@ -195,45 +266,10 @@ VGPath *VGPathInit(VGPath *self,int segmentCapacityHint, int coordCapacityHint){
|
||||
return self;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief VGPath destructor.
|
||||
* \param
|
||||
* \return
|
||||
* \note
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
void VGPathDealloc(VGPath *self){
|
||||
NSZoneFree(NULL,self->_elements);
|
||||
NSZoneFree(NULL,self->_points);
|
||||
-(void)dealloc {
|
||||
NSZoneFree(NULL,self->_vertices);
|
||||
NSZoneFree(NULL,self->_segmentToVertex);
|
||||
NSZoneFree(NULL,self);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Reads a coordinate and applies scale and bias.
|
||||
* \param
|
||||
* \return
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
CGPoint VGPathGetCoordinate(VGPath *self,int i){
|
||||
RI_ASSERT(i >= 0 && i < self->_numberOfPoints);
|
||||
|
||||
return self->_points[i];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Writes a coordinate, subtracting bias and dividing out scale.
|
||||
* \param
|
||||
* \return
|
||||
* \note If the coordinates do not fit into path datatype range, they
|
||||
* will overflow silently.
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
void VGPathSetCoordinate(VGPath *self,int i, CGPoint c){
|
||||
RI_ASSERT(i >= 0);
|
||||
|
||||
self->_points[i]=c;
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
@ -269,160 +305,6 @@ int VGPathCountNumCoordinates(const RIuint8* segments, int numSegments)
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Appends user segments and data.
|
||||
* \param
|
||||
* \return
|
||||
* \note if runs out of memory, throws bad_alloc and leaves the path as it was
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
void VGPathAppendData(VGPath *self,const RIuint8* segments, int numSegments, const CGPoint* data){
|
||||
RI_ASSERT(numSegments > 0);
|
||||
RI_ASSERT(segments && data);
|
||||
|
||||
//allocate new arrays
|
||||
RIuint8 *newSegments=NULL;
|
||||
int newSegmentCapacity=self->_numberOfElements+numSegments;
|
||||
|
||||
if(newSegmentCapacity>self->_capacityOfElements)
|
||||
newSegments=NSZoneMalloc(NULL,newSegmentCapacity*sizeof(unsigned char));
|
||||
|
||||
CGPoint *newCoordinates=NULL;
|
||||
int newCoordinateCount=VGPathCountNumCoordinates(segments,numSegments);
|
||||
int newCoordinateCapacity=self->_numberOfPoints+newCoordinateCount;
|
||||
|
||||
if(newCoordinateCapacity>self->_capacityOfPoints)
|
||||
newCoordinates=NSZoneMalloc(NULL,newCoordinateCapacity*sizeof(CGPoint));
|
||||
|
||||
//if we get here, the memory allocations have succeeded
|
||||
|
||||
//copy old segments and append new ones
|
||||
int i;
|
||||
|
||||
if(newSegments!=NULL){
|
||||
RIuint8 *tmp;
|
||||
|
||||
for(i=0;i<self->_numberOfElements;i++)
|
||||
newSegments[i]=self->_elements[i];
|
||||
|
||||
tmp=self->_elements;
|
||||
self->_elements=newSegments;
|
||||
self->_capacityOfElements=newSegmentCapacity;
|
||||
newSegments=tmp;
|
||||
}
|
||||
for(i=0;i<numSegments;i++)
|
||||
self->_elements[self->_numberOfElements++]=segments[i];
|
||||
|
||||
if(newCoordinates!=NULL){
|
||||
CGPoint *tmp;
|
||||
|
||||
for(i=0;i<self->_numberOfPoints;i++)
|
||||
newCoordinates[i]=self->_points[i];
|
||||
|
||||
tmp=self->_points;
|
||||
self->_points=newCoordinates;
|
||||
self->_capacityOfPoints=newCoordinateCapacity;
|
||||
newCoordinates=tmp;
|
||||
}
|
||||
for(i=0;i<newCoordinateCount;i++)
|
||||
self->_points[self->_numberOfPoints++]=CGPointMake(inputFloat(data[i].x),inputFloat(data[i].y));
|
||||
|
||||
RI_ASSERT(self->_numberOfPoints == VGPathCountNumCoordinates(self->_elements,self->_numberOfElements));
|
||||
|
||||
if(newSegments!=NULL)
|
||||
NSZoneFree(NULL,newSegments);
|
||||
if(newCoordinates!=NULL)
|
||||
NSZoneFree(NULL,newCoordinates);
|
||||
|
||||
//clear tessellated path
|
||||
self-> _vertexCount=0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Appends a path.
|
||||
* \param
|
||||
* \return
|
||||
* \note if runs out of memory, throws bad_alloc and leaves the path as it was
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
void VGPathAppend(VGPath *self,VGPath* srcPath){
|
||||
RI_ASSERT(srcPath);
|
||||
|
||||
if(srcPath->_numberOfElements>0)
|
||||
{
|
||||
//allocate new arrays
|
||||
RIuint8 *newSegments=NULL;
|
||||
int newSegmentCapacity=self->_numberOfElements+srcPath->_numberOfElements;
|
||||
|
||||
if(newSegmentCapacity>self->_capacityOfElements)
|
||||
newSegments=NSZoneMalloc(NULL,newSegmentCapacity*sizeof(unsigned char));
|
||||
|
||||
CGPoint *newCoordinates=NULL;
|
||||
int newCoordinateCapacity=self->_numberOfPoints+VGPathGetNumCoordinates(srcPath);
|
||||
|
||||
if(newCoordinateCapacity>self->_capacityOfPoints)
|
||||
newCoordinates=NSZoneMalloc(NULL,newCoordinateCapacity*sizeof(CGPoint));
|
||||
|
||||
//if we get here, the memory allocations have succeeded
|
||||
|
||||
//copy old segments and append new ones
|
||||
int i;
|
||||
|
||||
if(newSegments!=NULL){
|
||||
RIuint8 *tmp;
|
||||
|
||||
for(i=0;i<self->_numberOfElements;i++)
|
||||
newSegments[i]=self->_elements[i];
|
||||
|
||||
tmp=self->_elements;
|
||||
self->_elements=newSegments;
|
||||
self->_capacityOfElements=newSegmentCapacity;
|
||||
newSegments=tmp;
|
||||
}
|
||||
for(i=0;i<srcPath->_numberOfElements;i++)
|
||||
self->_elements[self->_numberOfElements++]=srcPath->_elements[i];
|
||||
|
||||
if(newCoordinates!=NULL){
|
||||
CGPoint *tmp;
|
||||
|
||||
for(i=0;i<self->_numberOfPoints;i++)
|
||||
newCoordinates[i]=self->_points[i];
|
||||
|
||||
tmp=self->_points;
|
||||
self->_points=newCoordinates;
|
||||
self->_capacityOfPoints=newCoordinateCapacity;
|
||||
newCoordinates=tmp;
|
||||
}
|
||||
for(i=0;i<VGPathGetNumCoordinates(srcPath);i++){
|
||||
VGPathSetCoordinate(self,self->_numberOfPoints++, VGPathGetCoordinate(srcPath,i));
|
||||
}
|
||||
RI_ASSERT(self->_numberOfPoints == VGPathCountNumCoordinates(self->_elements,self->_numberOfElements) );
|
||||
|
||||
if(newSegments!=NULL)
|
||||
NSZoneFree(NULL,newSegments);
|
||||
if(newCoordinates!=NULL)
|
||||
NSZoneFree(NULL,newCoordinates);
|
||||
}
|
||||
|
||||
//clear tessellated path
|
||||
self->_vertexCount=0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Appends a transformed copy of the source path.
|
||||
* \param
|
||||
* \return
|
||||
* \note if runs out of memory, throws bad_alloc and leaves the path as it was
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
void VGPathTransform(VGPath *self,CGAffineTransform matrix){
|
||||
int i;
|
||||
|
||||
for(i=0;i<self->_numberOfPoints;i++)
|
||||
self->_points[i]=CGPointApplyAffineTransform(self->_points[i],matrix);
|
||||
self->_vertexCount=0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Tessellates a path for filling and appends resulting edges
|
||||
* to a rasterizer.
|
||||
@ -435,7 +317,6 @@ void VGPathFill(VGPath *self,CGAffineTransform pathToSurface, KGRasterizer *rast
|
||||
|
||||
VGPathTessellate(self);
|
||||
|
||||
// try
|
||||
{
|
||||
CGPoint p0=CGPointMake(0,0), p1=CGPointMake(0,0);
|
||||
int i;
|
||||
@ -451,13 +332,6 @@ void VGPathFill(VGPath *self,CGAffineTransform pathToSurface, KGRasterizer *rast
|
||||
p0 = p1;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
catch(std::bad_alloc)
|
||||
{
|
||||
KGRasterizerClear(rasterizer); //remove the unfinished path
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
@ -750,7 +624,6 @@ void VGPathStroke(VGPath *self,CGAffineTransform pathToSurface, KGRasterizer *ra
|
||||
//inDash keeps track whether the last point was in dash or not
|
||||
|
||||
//loop vertex events
|
||||
// try
|
||||
{
|
||||
CGFloat nextDash = 0.0f;
|
||||
int d = 0;
|
||||
@ -926,13 +799,7 @@ void VGPathStroke(VGPath *self,CGAffineTransform pathToSurface, KGRasterizer *ra
|
||||
v0 = v1;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
catch(std::bad_alloc)
|
||||
{
|
||||
KGRasterizerClear(rasterizer); //remove the unfinished path
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
@ -1412,8 +1279,9 @@ void VGPathTessellate(VGPath *self){
|
||||
|
||||
// try
|
||||
{
|
||||
if(self->_segmentToVertexCapacity<self->_numberOfElements){
|
||||
self->_segmentToVertexCapacity=self->_numberOfElements;
|
||||
unsigned numberOfElements=[self->_path numberOfElements];
|
||||
if(self->_segmentToVertexCapacity<numberOfElements){
|
||||
self->_segmentToVertexCapacity=numberOfElements;
|
||||
self->_segmentToVertex=NSZoneRealloc(NULL,self->_segmentToVertex,self->_segmentToVertexCapacity*sizeof(VertexIndex));
|
||||
}
|
||||
|
||||
@ -1430,9 +1298,12 @@ void VGPathTessellate(VGPath *self){
|
||||
BOOL subpathHasGeometry = NO;
|
||||
CGPathElementType prevSegment = kCGPathElementMoveToPoint;
|
||||
int i;
|
||||
for(i=0;i<self->_numberOfElements;i++)
|
||||
const unsigned char *elements=[self->_path elements];
|
||||
const CGPoint *points=[self->_path points];
|
||||
|
||||
for(i=0;i<numberOfElements;i++)
|
||||
{
|
||||
CGPathElementType segment = (CGPathElementType)self->_elements[i];
|
||||
CGPathElementType segment = elements[i];
|
||||
int coords = CGPathElementTypeToNumCoordinates(segment);
|
||||
self->_segmentToVertex[i].start = self->_vertexCount;
|
||||
|
||||
@ -1451,7 +1322,7 @@ void VGPathTessellate(VGPath *self){
|
||||
case kCGPathElementMoveToPoint:
|
||||
{
|
||||
RI_ASSERT(coords == 1);
|
||||
CGPoint c=VGPathGetCoordinate(self,coordIndex);
|
||||
CGPoint c=points[coordIndex];
|
||||
if(prevSegment != kCGPathElementMoveToPoint && prevSegment != kCGPathElementCloseSubpath)
|
||||
VGPathAddEndPath(self,o, s, subpathHasGeometry, IMPLICIT_CLOSE_SUBPATH);
|
||||
s = c;
|
||||
@ -1464,7 +1335,7 @@ void VGPathTessellate(VGPath *self){
|
||||
case kCGPathElementAddLineToPoint:
|
||||
{
|
||||
RI_ASSERT(coords == 1);
|
||||
CGPoint c=VGPathGetCoordinate(self,coordIndex);
|
||||
CGPoint c=points[coordIndex];
|
||||
if(VGPathAddLineTo(self,o, c, subpathHasGeometry))
|
||||
subpathHasGeometry = YES;
|
||||
p = c;
|
||||
@ -1475,8 +1346,8 @@ void VGPathTessellate(VGPath *self){
|
||||
case kCGPathElementAddQuadCurveToPoint:
|
||||
{
|
||||
RI_ASSERT(coords == 2);
|
||||
CGPoint c0=VGPathGetCoordinate(self,coordIndex);
|
||||
CGPoint c1=VGPathGetCoordinate(self,coordIndex+1);
|
||||
CGPoint c0=points[coordIndex];
|
||||
CGPoint c1=points[coordIndex+1];
|
||||
if(VGPathAddQuadTo(self,o, c0, c1, subpathHasGeometry))
|
||||
subpathHasGeometry = YES;
|
||||
p = c0;
|
||||
@ -1487,9 +1358,9 @@ void VGPathTessellate(VGPath *self){
|
||||
case kCGPathElementAddCurveToPoint:
|
||||
{
|
||||
RI_ASSERT(coords == 3);
|
||||
CGPoint c0=VGPathGetCoordinate(self,coordIndex+0);
|
||||
CGPoint c1=VGPathGetCoordinate(self,coordIndex+1);
|
||||
CGPoint c2=VGPathGetCoordinate(self,coordIndex+2);
|
||||
CGPoint c0=points[coordIndex+0];
|
||||
CGPoint c1=points[coordIndex+1];
|
||||
CGPoint c2=points[coordIndex+2];
|
||||
if(VGPathAddCubicTo(self,o, c0, c1, c2, subpathHasGeometry))
|
||||
subpathHasGeometry = YES;
|
||||
p = c1;
|
||||
|
@ -35,9 +35,6 @@ typedef unsigned char RIuint8;
|
||||
//#define RI_ASSERT(_) NSCParameterAssert(_)
|
||||
#define RI_ASSERT(_)
|
||||
|
||||
#define RI_INT32_MAX (0x7fffffff)
|
||||
#define RI_INT32_MIN (-0x7fffffff-1)
|
||||
|
||||
static inline int RI_ISNAN(float a) {
|
||||
return (a!=a)?1:0;
|
||||
}
|
||||
@ -45,11 +42,8 @@ static inline int RI_ISNAN(float a) {
|
||||
static inline CGFloat RI_MAX(CGFloat a, CGFloat b) { return (a > b) ? a : b; }
|
||||
static inline CGFloat RI_MIN(CGFloat a, CGFloat b) { return (a < b) ? a : b; }
|
||||
static inline CGFloat RI_CLAMP(CGFloat a, CGFloat l, CGFloat h) { if(RI_ISNAN(a)) return l; RI_ASSERT(l <= h); return (a < l) ? l : (a > h) ? h : a; }
|
||||
static inline void RI_SWAP(CGFloat *a, CGFloat *b) { CGFloat tmp = *a; *a = *b; *b = tmp; }
|
||||
static inline CGFloat RI_ABS(CGFloat a) { return (a < 0.0f) ? -a : a; }
|
||||
static inline CGFloat RI_SQR(CGFloat a) { return a * a; }
|
||||
static inline CGFloat RI_DEG_TO_RAD(CGFloat a) { return (CGFloat)(a * M_PI / 180.0f); }
|
||||
static inline CGFloat RI_RAD_TO_DEG(CGFloat a) { return (CGFloat)(a * 180.0f/ M_PI); }
|
||||
static inline CGFloat RI_MOD(CGFloat a, CGFloat b){
|
||||
if(RI_ISNAN(a) || RI_ISNAN(b))
|
||||
return 0.0f;
|
||||
@ -70,7 +64,6 @@ static inline CGFloat RI_MOD(CGFloat a, CGFloat b){
|
||||
static inline int RI_INT_MAX(int a, int b) { return (a > b) ? a : b; }
|
||||
static inline int RI_INT_MIN(int a, int b) { return (a < b) ? a : b; }
|
||||
static inline int RI_INT_MOD(int a, int b) { RI_ASSERT(b >= 0); if(!b) return 0; int i = a % b; if(i < 0) i += b; RI_ASSERT(i >= 0 && i < b); return i; }
|
||||
static inline int RI_INT_ADDSATURATE(int a, int b) { RI_ASSERT(b >= 0); int r = a + b; return (r >= a) ? r : RI_INT32_MAX; }
|
||||
static inline int RI_INT_CLAMP(int a, int l, int h) { RI_ASSERT(l <= h); return (a < l) ? l : (a > h) ? h : a; }
|
||||
|
||||
static inline int RI_FLOOR_TO_INT(CGFloat value){
|
||||
@ -80,30 +73,6 @@ static inline int RI_FLOOR_TO_INT(CGFloat value){
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2Negate(CGPoint result){
|
||||
return CGPointMake(-result.x,-result.y);
|
||||
}
|
||||
|
||||
static inline CGFloat Vector2Length(CGPoint v){
|
||||
return (CGFloat)sqrt((double)v.x*(double)v.x+(double)v.y*(double)v.y);
|
||||
}
|
||||
|
||||
static inline BOOL Vector2IsEqual(CGPoint v1,CGPoint v2 ){
|
||||
return (v1.x == v2.x) && (v1.y == v2.y);
|
||||
}
|
||||
|
||||
static inline BOOL Vector2IsZero(CGPoint v){
|
||||
return (v.x == 0.0f) && (v.y == 0.0f);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2MultiplyByFloat(CGPoint v,CGFloat f){
|
||||
return CGPointMake(v.x*f,v.y*f);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2Add(CGPoint v1,CGPoint v2 ){
|
||||
return CGPointMake(v1.x+v2.x, v1.y+v2.y);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2Subtract(CGPoint v1,CGPoint v2){
|
||||
return CGPointMake(v1.x-v2.x, v1.y-v2.y);
|
||||
}
|
||||
@ -112,34 +81,6 @@ static inline CGFloat Vector2Dot(CGPoint v1,CGPoint v2){
|
||||
return v1.x*v2.x+v1.y*v2.y;
|
||||
}
|
||||
|
||||
//if v is a zero vector, returns a zero vector
|
||||
static inline CGPoint Vector2Normalize(CGPoint v){
|
||||
double l = (double)v.x*(double)v.x+(double)v.y*(double)v.y;
|
||||
|
||||
if( l != 0.0 )
|
||||
l = 1.0 / sqrt(l);
|
||||
|
||||
return CGPointMake((CGFloat)((double)v.x * l), (CGFloat)((double)v.y * l));
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2PerpendicularCW(CGPoint v){
|
||||
return CGPointMake(v.y, -v.x);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2PerpendicularCCW(CGPoint v){
|
||||
return CGPointMake(-v.y, v.x);
|
||||
}
|
||||
|
||||
static inline CGPoint Vector2Perpendicular(CGPoint v, BOOL cw){
|
||||
if(cw)
|
||||
return CGPointMake(v.y, -v.x);
|
||||
|
||||
return CGPointMake(-v.y, v.x);
|
||||
}
|
||||
|
||||
|
||||
BOOL CGAffineTransformInplaceInvert(CGAffineTransform *m);
|
||||
|
||||
//matrix * column vector.
|
||||
|
||||
static inline CGPoint CGAffineTransformTransformVector2(CGAffineTransform m,CGPoint v){
|
||||
|
@ -1,59 +0,0 @@
|
||||
/*------------------------------------------------------------------------
|
||||
*
|
||||
* Derivative of the OpenVG 1.0.1 Reference Implementation
|
||||
* -------------------------------------
|
||||
*
|
||||
* Copyright (c) 2007 The Khronos Group Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and /or associated documentation files
|
||||
* (the "Materials "), to deal in the Materials without restriction,
|
||||
* including without limitation the rights to use, copy, modify, merge,
|
||||
* publish, distribute, sublicense, and/or sell copies of the Materials,
|
||||
* and to permit persons to whom the Materials are 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 Materials.
|
||||
*
|
||||
* THE MATERIALS ARE 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 MATERIALS OR
|
||||
* THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*
|
||||
*//**
|
||||
* \file
|
||||
* \brief Implementation of non-inline matrix functions.
|
||||
* \note
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
#import "VGmath.h"
|
||||
|
||||
/*-------------------------------------------------------------------*//*!
|
||||
* \brief Inverts a 3x3 m->mat. Returns NO if the matrix is singular.
|
||||
* \param
|
||||
* \return
|
||||
* \note
|
||||
*//*-------------------------------------------------------------------*/
|
||||
|
||||
BOOL CGAffineTransformInplaceInvert(CGAffineTransform *m)
|
||||
{
|
||||
CGFloat det00 = m->d ;
|
||||
CGFloat det01 = - m->b;
|
||||
|
||||
CGFloat d = m->a*det00 + m->c*det01 ;
|
||||
if( d == 0.0f ) return NO; //singular, leave the m->mat unmodified and return NO
|
||||
|
||||
CGAffineTransform t;
|
||||
t.a = det00/d;
|
||||
t.b = det01/d;
|
||||
t.c = ( - m->c)/d;
|
||||
t.d = (m->a )/d;
|
||||
t.tx = (m->c*m->ty - m->d*m->tx)/d;
|
||||
t.ty = (m->b*m->tx - m->a*m->ty)/d;
|
||||
*m = t;
|
||||
return YES;
|
||||
}
|
@ -402,12 +402,16 @@ static int numberOfPointsForOperator(int op){
|
||||
CGPathAddArcToPoint(_path,NULL,point.x,point.y,toPoint.x,toPoint.y,radius);
|
||||
}
|
||||
|
||||
static inline CGFloat degreesToRadians(CGFloat degrees){
|
||||
return degrees*M_PI/180.0;
|
||||
}
|
||||
|
||||
-(void)appendBezierPathWithArcWithCenter:(NSPoint)center radius:(float)radius startAngle:(float)startAngle endAngle:(float)endAngle {
|
||||
CGPathAddArc(_path,NULL,center.x,center.y,radius,RI_DEG_TO_RAD(startAngle),RI_DEG_TO_RAD(endAngle),YES);
|
||||
CGPathAddArc(_path,NULL,center.x,center.y,radius,degreesToRadians(startAngle),degreesToRadians(endAngle),YES);
|
||||
}
|
||||
|
||||
-(void)appendBezierPathWithArcWithCenter:(NSPoint)center radius:(float)radius startAngle:(float)startAngle endAngle:(float)endAngle clockwise:(BOOL)clockwise {
|
||||
CGPathAddArc(_path,NULL,center.x,center.y,radius,RI_DEG_TO_RAD(startAngle),RI_DEG_TO_RAD(endAngle),clockwise);
|
||||
CGPathAddArc(_path,NULL,center.x,center.y,radius,degreesToRadians(startAngle),degreesToRadians(endAngle),clockwise);
|
||||
}
|
||||
|
||||
-(void)appendBezierPathWithGlyph:(NSGlyph)glyph inFont:(NSFont *)font {
|
||||
|
@ -18,7 +18,7 @@ typedef enum {
|
||||
NSImageCacheNever,
|
||||
} NSImageCacheMode;
|
||||
|
||||
@interface NSImage : NSObject <NSCopying> {
|
||||
@interface NSImage : NSObject <NSCopying,NSCoding> {
|
||||
NSString *_name;
|
||||
NSSize _size;
|
||||
NSColor *_backgroundColor;
|
||||
|
@ -6,7 +6,6 @@ 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 <cjwl@objc.net>, David Young <daver@geeks.org>
|
||||
#import <AppKit/NSPopUpButtonCell.h>
|
||||
#import <AppKit/NSMenu.h>
|
||||
#import <AppKit/NSEvent.h>
|
||||
@ -144,7 +143,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
}
|
||||
|
||||
-(void)insertItemWithTitle:(NSString *)title atIndex:(int)index {
|
||||
NSUnimplementedMethod();
|
||||
[_menu insertItemWithTitle:title action:NULL keyEquivalent:nil atIndex:index];
|
||||
}
|
||||
|
||||
-(NSImage *)image {
|
||||
|
@ -51,8 +51,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
}
|
||||
|
||||
-validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType {
|
||||
NSUnimplementedMethod();
|
||||
return nil;
|
||||
return [_nextResponder validRequestorForSendType:sendType returnType:returnType];
|
||||
}
|
||||
|
||||
-(void)doCommandBySelector:(SEL)selector {
|
||||
|
@ -797,7 +797,6 @@ static void sourceOverImage(KGImage *image,KGRGBA8888 *resultBGRX,int width,int
|
||||
for(x=0;x<width;x++)
|
||||
span[x]=direct[x];
|
||||
}
|
||||
|
||||
KGBlendSpanNormal_8888_coverage(span,combine,coverage,width);
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,10 @@ static NSImageRep *imageRepForIcon(SHFILEINFO * fileInfo) {
|
||||
if(SHGetFileInfo(pathCString,0,&fileInfo,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_LARGEICON))
|
||||
[icon addRepresentation:imageRepForIcon(&fileInfo)];
|
||||
|
||||
return ([[icon representations] count]?icon:nil);
|
||||
if([[icon representations] count]==0)
|
||||
return nil;
|
||||
|
||||
return icon;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -7,12 +7,12 @@ 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 <Foundation/NSObject.h>
|
||||
|
||||
@class NSPort,NSArray,NSDate;
|
||||
@class NSPort,NSArray,NSMutableArray,NSDate;
|
||||
|
||||
@interface NSPortMessage : NSObject {
|
||||
NSPort *_sendPort;
|
||||
NSPort *_receivePort;
|
||||
NSArray *_components;
|
||||
NSMutableArray *_components;
|
||||
unsigned _msgid;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
-initWithSendPort:(NSPort *)sendPort receivePort:(NSPort *)receivePort components:(NSArray *)components {
|
||||
_sendPort=[sendPort retain];
|
||||
_receivePort=[receivePort retain];
|
||||
_components=[components retain];
|
||||
_components=[[NSMutableArray alloc] initWithArray:components];
|
||||
_msgid=0;
|
||||
return self;
|
||||
}
|
||||
@ -48,8 +48,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
}
|
||||
|
||||
-(BOOL)sendBeforeDate:(NSDate *)date {
|
||||
NSUnimplementedMethod();
|
||||
return NO;
|
||||
return [_sendPort sendBeforeDate:date msgid:_msgid components:_components from:_receivePort reserved:0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -7,11 +7,15 @@ 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 <Foundation/NSPort.h>
|
||||
@class NSInputStream,NSOutputStream;
|
||||
|
||||
typedef int NSSocketNativeHandle;
|
||||
|
||||
@interface NSSocketPort : NSPort {
|
||||
|
||||
id _delegate;
|
||||
BOOL _isValid;
|
||||
NSInputStream *_inputStream;
|
||||
NSOutputStream *_outputStream;
|
||||
}
|
||||
|
||||
-init;
|
||||
|
@ -8,6 +8,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
#import <Foundation/NSSocketPort.h>
|
||||
#import <Foundation/NSRaise.h>
|
||||
#import <Foundation/NSStream.h>
|
||||
|
||||
@implementation NSSocketPort
|
||||
|
||||
@ -61,4 +62,9 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
return 0;
|
||||
}
|
||||
|
||||
-(void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)streamEvent {
|
||||
NSUnimplementedMethod();
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
@ -73,7 +73,6 @@
|
||||
FE6EDD410DB78EA1005503A1 /* KGzlib.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EDD280DB78EA1005503A1 /* KGzlib.m */; };
|
||||
FE6EE00B0DB7CE0B005503A1 /* KGContext_builtin.m in Sources */ = {isa = PBXBuildFile; fileRef = FE6EE00A0DB7CE0B005503A1 /* KGContext_builtin.m */; };
|
||||
FE9552810D77CA67009B765B /* KGSurface.m in Sources */ = {isa = PBXBuildFile; fileRef = FE9552780D77CA67009B765B /* KGSurface.m */; };
|
||||
FE9552820D77CA67009B765B /* VGmath.m in Sources */ = {isa = PBXBuildFile; fileRef = FE95527A0D77CA67009B765B /* VGmath.m */; };
|
||||
FE9552830D77CA67009B765B /* VGPath.m in Sources */ = {isa = PBXBuildFile; fileRef = FE95527C0D77CA67009B765B /* VGPath.m */; };
|
||||
FEBF55B90DCA0DE500CE5A1C /* KGPaint.m in Sources */ = {isa = PBXBuildFile; fileRef = FEBF55B80DCA0DE500CE5A1C /* KGPaint.m */; };
|
||||
FEBF575B0DCA60CD00CE5A1C /* KGPaint_image.m in Sources */ = {isa = PBXBuildFile; fileRef = FEBF575A0DCA60CD00CE5A1C /* KGPaint_image.m */; };
|
||||
@ -229,7 +228,6 @@
|
||||
FE9552770D77CA67009B765B /* KGSurface.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = KGSurface.h; path = ../../AppKit/CoreGraphics.subproj/KGSurface.h; sourceTree = "<group>"; };
|
||||
FE9552780D77CA67009B765B /* KGSurface.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = KGSurface.m; path = ../../AppKit/CoreGraphics.subproj/KGSurface.m; sourceTree = "<group>"; };
|
||||
FE9552790D77CA67009B765B /* VGmath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VGmath.h; path = ../../AppKit/CoreGraphics.subproj/VGmath.h; sourceTree = "<group>"; };
|
||||
FE95527A0D77CA67009B765B /* VGmath.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = VGmath.m; path = ../../AppKit/CoreGraphics.subproj/VGmath.m; sourceTree = "<group>"; };
|
||||
FE95527B0D77CA67009B765B /* VGPath.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = VGPath.h; path = ../../AppKit/CoreGraphics.subproj/VGPath.h; sourceTree = "<group>"; };
|
||||
FE95527C0D77CA67009B765B /* VGPath.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; name = VGPath.m; path = ../../AppKit/CoreGraphics.subproj/VGPath.m; sourceTree = "<group>"; };
|
||||
FEBF55B70DCA0DE500CE5A1C /* KGPaint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KGPaint.h; path = ../../AppKit/CoreGraphics.subproj/KGPaint.h; sourceTree = "<group>"; };
|
||||
@ -396,7 +394,6 @@
|
||||
FE9552770D77CA67009B765B /* KGSurface.h */,
|
||||
FE9552780D77CA67009B765B /* KGSurface.m */,
|
||||
FE9552790D77CA67009B765B /* VGmath.h */,
|
||||
FE95527A0D77CA67009B765B /* VGmath.m */,
|
||||
FE6EDE380DB797FA005503A1 /* KGExceptions.h */,
|
||||
FE6EDCF70DB78EA1005503A1 /* KGPDFArray.h */,
|
||||
FE6EDCF80DB78EA1005503A1 /* KGPDFArray.m */,
|
||||
@ -542,7 +539,6 @@
|
||||
files = (
|
||||
8D11072D0486CEB800E47090 /* main.m in Sources */,
|
||||
FE9552810D77CA67009B765B /* KGSurface.m in Sources */,
|
||||
FE9552820D77CA67009B765B /* VGmath.m in Sources */,
|
||||
FE9552830D77CA67009B765B /* VGPath.m in Sources */,
|
||||
FE1F93630D7EF19900969491 /* KGImageView.m in Sources */,
|
||||
FE1F937A0D7EF1F800969491 /* KGRenderController.m in Sources */,
|
||||
|
Loading…
Reference in New Issue
Block a user