Source

xkcd1110-ios / XKCD1110 / IVXkcdTiledLayer.m

Full commit
//
//  IVXkcdTiledLayer.m
//  XKCD1110
//
//  Created by Ivan Vučica on 29.9.2012..
//  Copyright (c) 2012. Ivan Vučica. All rights reserved.
//

#import "IVXkcdTiledLayer.h"
#import "UIImage+HNCaching.h"

#define ZOOM_SUPPORT 1

@implementation IVXkcdTiledLayer

- (void)drawInContext:(CGContextRef)context
{
	// Fetch clip box in *world* space; context's CTM is preconfigured for world space->tile pixel space transform
	CGRect box = CGContextGetClipBoundingBox(context);
    
	// Calculate tile index
	CGFloat contentsScale = [self respondsToSelector:@selector(contentsScale)]?[self contentsScale]:1.0;
	CGSize tileSize = [(CATiledLayer*)self tileSize];
    CGFloat scaling = box.size.width / tileSize.width;
#if !(ZOOM_SUPPORT)
	CGFloat x = box.origin.x * contentsScale / tileSize.width;
	CGFloat y = box.origin.y * contentsScale / tileSize.height;
#else
    CGRect tbox = CGRectApplyAffineTransform(CGRectMake(0, 0, tileSize.width, tileSize.height),
                                             CGAffineTransformInvert(CGContextGetCTM(context)));
    CGFloat x = box.origin.x / tbox.size.width;
    CGFloat y = box.origin.y / tbox.size.height;
#endif
	CGPoint tile = CGPointMake(x, y);
    
	// Clear background
	CGContextSetFillColorWithColor(context, [[UIColor grayColor] CGColor]);
	CGContextFillRect(context, box);
    
	// Rendering the contents
	CGContextSaveGState(context);
	CGContextConcatCTM(context, [self transformForTile:tile]);

    int zoomLevel = -log(scaling)/log(2);
    UIImage * img = [self imageForTile:tile atZoomLevel:zoomLevel];
    CGContextTranslateCTM(context, 0, box.size.height);
    CGContextScaleCTM(context, 1, -1);
    CGContextDrawImage(context, CGContextGetClipBoundingBox(context), [img CGImage]);
    
    CGContextRestoreGState(context);
    
#if 0
	// Render label (Setup)
	UIFont* font = [UIFont fontWithName:@"CourierNewPS-BoldMT" size:12 * scaling * 2];
	CGContextSelectFont(context, [[font fontName] cStringUsingEncoding:NSASCIIStringEncoding], [font pointSize], kCGEncodingMacRoman);
	CGContextSetTextDrawingMode(context, kCGTextFill);
	CGContextSetTextMatrix(context, CGAffineTransformMakeScale(1, -1));
	CGContextSetFillColorWithColor(context, [[UIColor greenColor] CGColor]);
    
	// Draw label
	NSString* s = [NSString stringWithFormat:@"(%.1f, %.1f) %g",x,y,log(scaling)/log(2)];
	CGContextShowTextAtPoint(context,
                             box.origin.x,
                             box.origin.y + [font pointSize],
                             [s cStringUsingEncoding:NSMacOSRomanStringEncoding],
                             [s lengthOfBytesUsingEncoding:NSMacOSRomanStringEncoding]);
#endif
}

- (CGAffineTransform)transformForTile:(CGPoint)tile
{
	return CGAffineTransformIdentity;
}

- (UIImage*)imageForTile:(CGPoint)tile atZoomLevel:(int)zoomLevel
{
    NSString * urlString = [NSString stringWithFormat:@"http://xkcd1.rent-a-geek.de/converted/%d-%d-%d.png", zoomLevel, (int)tile.x, (int)tile.y];
    NSURL * url = [NSURL URLWithString:urlString];
    
    return [UIImage imageWithContentsOfURLAndCaching:url];
}

@end