2009-07-08 60 views
1

我有一個NSView的子類,並且我正在繪製一個NSImage。我正在解開NSAffineTransforms旋轉,翻譯和縮放圖像。NSAffineTransforms沒有被使用?

大部分工作正常。但是,有時候,轉換似乎不會被激活。

例如,當我調整窗口大小時,旋轉變換不會發生。

當我放大圖像時,它會將圖像的左下角放在正確的位置,但不會縮放圖像,但會縮放圖像中位於原圖右側的部分大小的圖像。如果我旋轉它,它會正確放大,但翻譯錯誤。 (該TRANSATION可能是我的一個計算錯誤)

這裏是我的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; 
    } 

我要抓住一切的大小初使我可以稍後在旋轉時使用它們。我不知道,我需要保護任何的,但我是偏執狂,從多年的C ...

[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; 
     } 

該代碼可以是完全的歷史,現在,我看它......當時的想法是換高度andwidth如果我旋轉90名或270度的視角。

} 
    else 
     NSLog(@"no image"); 

    [afTrans release]; 
    [context restoreGraphicsState]; 

} 
+0

你可以將大代碼塊拆分成更小的部分,並試圖解釋你在每個代碼塊中要做什麼(特別是switch語句和兩個if(image)塊)。我已經在一個項目中嘲笑了你的代碼,但是我在嘗試遵循你正在做的事情時遇到了麻煩。 – Peter 2009-07-10 01:28:49

+0

好的,沒問題! – 2009-07-10 13:52:01

回答

0

爲什麼使用superview的大小?這是你應該幾乎不需要擔心的事情。您應該讓視圖獨立工作,而不依賴於嵌入任何特定視圖。

縮放imageRect的大小可能不是正確的方法。通常,在調用-drawImage時,您希望源矩形是圖像的邊界,並縮放目標矩形以將其縮放。

您報告的問題有點像您在更改轉換後不重繪整個視圖。你打電話給--setNeedsDisplay:YES?

此視圖如何嵌入窗口中?它在NSScrollView中嗎?你確定滾動視圖與窗口一起調整大小嗎?