トップ «前の日記(2012-03-15) 最新 次の日記(2012-03-17)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|

2012-03-16 [iOS]座標と描画(その5)

実は、まだ、理解できていない箇所があるので、再挑戦だ!

Core Graphics (Quartz)のデフォルト座標系は、左下が原点で、X軸は右方向、Y軸は上方向が正だ。

LLO

一方、UIKitのデフォルト座標系は、左上が原点で、X軸は右方向、Y軸は下方向が正となる。

ULO

おそらく、UIKitでは、UIGraphicsBeginImageContextWithOptions()を使った操作に近い手順でコンテキストを用意していると思われる。この関数で得られるコンテキストは、左上が原点で、X軸は右報告、Y軸は下方向が正となる。

ここからが、ややこしい部分だ。

UIKitを使っていれば、慣れた左上が原点の座標系となり、何も悩む事はない、と考えると失敗する。

例えば、CoreGraphicsの関数で文字列を描画する場合。

- (void)drawRect:(CGRect)rect
{
    CGContextRef    context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    CGContextSetFillColorSpace(context, cs);
    CGColorSpaceRelease(cs);
    
    CGContextSetTextDrawingMode(context, kCGTextFill);
    CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
    
    CGContextSelectFont(context, "Helvetica", 48.0, kCGEncodingMacRoman);
    CGContextShowTextAtPoint(context, 10.0, 10.0, "Quartz", strlen("Quartz"));
    
    CGContextFlush(context);
    CGContextRestoreGState(context);
}

文字が反転してしまう。

反転

その為、上記の例では、文字列を描画する際に、座標系をCoreGraphicsのデフォルトの座標系に戻す必要がある。

- (void)drawRect:(CGRect)rect
{
    CGContextRef    context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    
    CGFloat height = self.bounds.size.height;
    CGContextTranslateCTM(context, 0.0, height);
    CGContextScaleCTM(context, 1.0, - 1.0);
    
    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    CGContextSetFillColorSpace(context, cs);
    CGColorSpaceRelease(cs);
    
    CGContextSetTextDrawingMode(context, kCGTextFill);
    CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
    
    CGContextSelectFont(context, "Helvetica", 48.0, kCGEncodingMacRoman);
    CGContextShowTextAtPoint(context, 10.0, 10.0, "Quartz", strlen("Quartz"));
    
    CGContextFlush(context);
    CGContextRestoreGState(context);
}
描画

だたし、この場合は、描画する位置を計算し直さないといけなくなる。そうでないと、上記の例のように上段に文字列を描画したかったのに、下段となってしまった。


トップ «前の日記(2012-03-15) 最新 次の日記(2012-03-17)» 編集