У меня есть подкласс NSView, и в этом я рисую NSImage. Я использую NSAffineTransforms, чтобы вращать, переводить и масштабировать изображение.
Большая часть работает нормально. Однако иногда преобразования просто не активируются.
Например, когда я изменяю размер окна, преобразование поворота не происходит.
Когда я увеличиваю изображение, оно помещает нижний левый угол изображения в правильное место, но не увеличивает его, но увеличивает масштаб той части изображения, которая будет справа от исходного размера образ. Если я поверну это, он увеличится правильно, но переводится неправильно. (Перевод может быть ошибка расчета с моей стороны)
Вот код моего drawRect: (простите за длинный код)
- (void)drawRect:(NSRect)rect
{
// Drawing code here.
double rotateDeg = -90* rotation;
NSAffineTransform *afTrans = [[NSAffineTransform alloc] init];
NSGraphicsContext *context = [NSGraphicsContext currentContext];
NSSize sz;
NSRect windowFrame = [[self window] frame];
float deltaX, deltaY;
NSSize superSize = [[self superview] frame].size;
float height, width, sHeight, sWidth;
NSRect imageRect;
if(image)
{
sz = [ image size];
imageRect.size = sz;
imageRect.origin = NSZeroPoint;
imageRect.size.width *= zoom;
imageRect.size.height *= zoom;
height = sz.height * zoom ;
width = sz.width *zoom ;
sHeight = superSize.height;
sWidth = superSize.width;
}
Мне нужно заранее взять размеры всего, чтобы я мог использовать их позже, когда поверну. Я не уверен, что мне нужно защищать что-либо из этого, но я параноик от многолетнего К ...
[context saveGraphicsState];
// rotate
[afTrans rotateByDegrees:rotateDeg];
// translate to account for window size;
deltaX = 0;
deltaY = 0;
// translate to account for rotation
// in 1 and 3, X and Y are reversed because the entire FRAME
// (inculding axes) is rotated!
switch (rotation)
{
case 0:
// NSLog(@"No rotation ");
break;
case 1:
deltaY -= (sHeight - height);
deltaX -= sHeight ;
break;
case 2:
deltaX -= width;
deltaY -= ( 2*sHeight - height);
// it's rotating around the lower left of the FRAME, so,
// we need to move it up two frame hights, and then down
// the hieght of the image
break;
case 3:
deltaX += (sHeight - width);
deltaY -= sHeight;
break;
}
Поскольку я вращаюсь вокруг нижнего левого угла и хочу, чтобы изображение было зафиксировано в верхнем левом углу, мне нужно переместить изображение вокруг. Когда я поворачиваюсь один раз, изображение находится в квадранте + -, поэтому мне нужно сместить его на одну высоту просмотра, а влево - на высоту просмотра за вычетом высоты изображения. и т.д.
[afTrans translateXBy:deltaX yBy:deltaY];
// for putting image in upper left
// zoom
[afTrans scaleBy: zoom];
printMatrix([afTrans transformStruct]);
NSLog(@"zoom %f", zoom);
[afTrans concat];
if(image)
{
NSRect drawingRect = imageRect;
NSRect frame = imageRect;
frame.size.height = MAX(superSize.height, imageRect.size.height) ;
[self setFrame:frame];
deltaY = superSize.height - imageRect.size.height;
drawingRect.origin.y += deltaY;
Это делает кадр правильного размера, чтобы изображение находилось в верхнем левом углу кадра.
Если изображение больше окна, я хочу, чтобы рамка была достаточно большой, чтобы появлялись полосы прокрутки. Если это не так, я хочу, чтобы рамка была достаточно большой, чтобы она доходила до верхней части окна.
[image drawInRect:drawingRect
fromRect:imageRect
operation:NSCompositeSourceOver
fraction:1];
if((rotation %2) )
{
float tmp;
tmp = drawingRect.size.width;
drawingRect.size.width = drawingRect.size.height;
drawingRect.size.height = tmp;
}
Этот код может быть полностью историческим, теперь, когда я смотрю на него ... идея состояла в том, чтобы поменять высоту и ширину, если я повернул на 90 или 270 градусов.
}
else
NSLog(@"no image");
[afTrans release];
[context restoreGraphicsState];
}