1

ビューで塗りつぶしパターンをテクスチャとして使用しようとしています。CGPatternCreate への呼び出しを設定しましたが、変換として何を渡すか正確にはわかりません。現在の行列を渡そうとしましたが、回転すると奇妙な結果が生じます。

形状は時計回りに回転し、パターンは反時計回りに回転するビューの例を作成しました。回転の方向を変更するために、さまざまな方法で y 軸をスケーリングしてみました。

//
//  TestView.m
//  test
//
//  Created by Blake Hegerle on 8/15/12.
//  Copyright (c) 2012 Blake Hegerle. All rights reserved.
//

#import "TestView.h"

const float RATE = (float)1/60;

void drawPattern(void *info, CGContextRef ctx) {
    CGImageRef img = (CGImageRef)info;

    CGRect bounds = CGRectMake(0, 0, CGImageGetWidth(img), CGImageGetHeight(img));
    CGContextDrawImage(ctx, bounds, img);
}

void releasePattern(void *info) {
    CGImageRef img = (CGImageRef)info;
    CFRelease(img);
}

@implementation TestView

-(void)awakeFromNib
{
    clock = 0;

    [NSTimer scheduledTimerWithTimeInterval:RATE
                                     target:self
                                   selector:@selector(tick:)
                                   userInfo:nil
                                    repeats:YES];
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx = UIGraphicsGetCurrentContext();

    // set transform
    CGContextTranslateCTM(ctx, rect.size.width/2, rect.size.height/2);
    CGContextRotateCTM(ctx, clock*RATE/5);

    // get the image
    CGImageRef img = [UIImage imageNamed:@"zebra.jpeg"].CGImage;
    double w = CGImageGetWidth(img), h = CGImageGetHeight(img);
    CFRetain(img);

    // set the pattern transform
    CGAffineTransform t0 = CGContextGetCTM(ctx);
    CGAffineTransform t1 = CGAffineTransformMakeScale(1, -1);
    CGAffineTransform t2 = CGAffineTransformMakeTranslation(0, rect.size.height);
    CGAffineTransform t = CGAffineTransformConcat(t2, CGAffineTransformConcat(t1, t0));

    // create the pattern
    CGPatternCallbacks cb = { 0, &drawPattern, &releasePattern };
    CGPatternRef pat = CGPatternCreate(img, rect, t, w, h, kCGPatternTilingConstantSpacing, true, &cb);

    // change to pattern colorspace
    CGColorSpaceRef pcs = CGColorSpaceCreatePattern(nil);
    CGContextSetFillColorSpace(ctx, pcs);
    CGColorSpaceRelease(pcs);

    // apply the pattern
    float alpha[] = { 1 };
    CGContextSetFillPattern(ctx, pat, alpha);
    CFRelease(pat);

    // fill a rect
    double sz = rect.size.width / 5;
    CGContextFillRect(ctx, CGRectMake(0, 0, sz, sz));
}

-(void)tick:(NSTimer *)t
{
    clock++;
    [self setNeedsDisplay];
}

@end
4

0 に答える 0