#import "SkView.h" #import "SkMatrix.h" #import "SkCanvas.h" #import class SkNSContainerView : public SkView { public: SkNSContainerView(NSView* parent){ fParent = parent; fMatrix.reset(); } void setBeforeChildMatrix(const SkMatrix& m) {fMatrix = m;} protected: virtual bool handleInval(const SkRect*) { [fParent setNeedsDisplay:YES]; return true; } virtual void beforeChild(SkView* child, SkCanvas* canvas) { canvas->concat(fMatrix); } virtual void onSizeChange() { this->INHERITED::onSizeChange(); SkView::F2BIter iter(this); SkView* view = iter.next(); while (view) { view->setSize(this->width(), this->height()); view = iter.next(); } } private: NSView* fParent; SkMatrix fMatrix; typedef SkView INHERITED; }; //////////////////////////////////////////////////////////////////////////////// #import "SkCGUtils.h" #import "SkNSView.h" @implementation SkNSView @synthesize fOffset, fCenter, fScale, fRotation; -(id) initWithFrame:(NSRect)frame { self = [super initWithFrame:frame]; if (self) { fView = new SkNSContainerView(self); fView->setVisibleP(true); NSSize viewSize = [self bounds].size; fView->setSize(viewSize.width, viewSize.height); [self resetTransformations]; } return self; } -(void) dealloc { delete fView; [super dealloc]; } -(void) addSkView:(SkView*)aView { fView->attachChildToFront(aView); } -(BOOL) isFlipped { return YES; } -(BOOL) inLiveResize { if (fView != nil) { NSSize s = [self bounds].size; fView->setSize(s.width, s.height); [self setNeedsDisplay:YES]; } return [super inLiveResize]; } -(void) resetTransformations { fOffset = NSMakePoint(0, 0); fCenter = NSMakePoint(fView->width() / 2.0, fView->height() / 2.0); fRotation = 0; fScale = 1.0; } -(void) drawRect:(NSRect)dirtyRect { //TODO -- check if our NSView is backed by a CALayer, and possibly use //skia's gpu backend if (fView != nil) { SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, fView->width(), fView->height()); bitmap.allocPixels(); SkCanvas canvas(bitmap); //Apply view transformations so they can be applied to individual //child views without affecting the parent's clip/matrix SkMatrix matrix; matrix.setTranslate(fOffset.x + fCenter.x, fOffset.y + fCenter.y); matrix.preRotate(fRotation); matrix.preScale(fScale, fScale); matrix.preTranslate(-fCenter.x, -fCenter.y); fView->setBeforeChildMatrix(matrix); fView->draw(&canvas); //Draw bitmap NSImage * image = [[NSImage alloc] init]; CGImageRef cgimage = SkCreateCGImageRef(bitmap); NSBitmapImageRep * bitmapRep = [[NSBitmapImageRep alloc] initWithCGImage:cgimage]; [image addRepresentation:bitmapRep]; [image setSize:NSMakeSize(fView->width(), fView->height())]; [image setFlipped:TRUE]; [image drawAtPoint:NSMakePoint(0, 0) fromRect: NSZeroRect operation: NSCompositeSourceOver fraction: 1.0]; [image release]; CGImageRelease(cgimage); [bitmapRep release]; } } @end