• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSAttributedString in NSAffineTransform
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSAttributedString in NSAffineTransform


  • Subject: Re: NSAttributedString in NSAffineTransform
  • From: Graham Cox <email@hidden>
  • Date: Mon, 10 Nov 2008 01:46:47 +1100


On 10 Nov 2008, at 1:01 am, Joseph Ayers wrote:

I am having a tremendous problem getting the vertical text in the y Axis of a graph. If i try to rotate text specified as
NSAttributedString it appears to get translated in nonlinear ways: I would assume that in the below, the text would
rotate around NSMinX(rect) and NSMinY(rect) but it doesn't.


Consider:
- (void)drawYLabel:(NSRect)rect
{

	NSPoint labelHere;
	int xOffSet;
	if(drawYLabelFlag == YES)
		{
			NSAffineTransform *transform = [NSAffineTransform transform];
			NSGraphicsContext *context   = [NSGraphicsContext currentContext];

//			[transform translateXBy:NSMinY(gRect) yBy:0.0];
			[transform rotateByDegrees:90.0];

[context saveGraphicsState];
[transform concat];

xOffSet =NSMinY(rect) + ((gHeight/2.0) - [ylabel size].width/2.0);
labelHere = NSMakePoint( xOffSet, NSMinY(rect) +[ylabel size].height) ;
[ylabel drawAtPoint:labelHere];

[context restoreGraphicsState];
}
}
yLabel is a NSAttributed String
gHeight is the height of rect.
rect is a bounding rect for the graph that is smaller than the frame of the NSView.


yLabel doesn't appear in the NSView

What am I doing wrong here


Any rotation is with respect to the origin of the coordinate system. Thus, to rotate about a given point, you need to make that point the origin, perform the rotation, then translate back to the actual position you want to draw.

Thus (typed into mail):

NSAffineTransform* transform = [NSAffineTransform transform];

[transform translateXBy:myPoint.x yBy:myPoint.y];
[transform rotateByDegrees:90];
[transform translateXBy:-myPoint.x yBy:-myPoint.y];
[transform concat];

[myAttributedString drawAtPoint:myPoint];


Note that the translation to the origin and back is apparently back-to- front. Transforms are like that - I find it sometimes helps to read the series of translate/scale/rotate operations in reverse order to get an idea of what it does as if in a series of steps.


Anyway, in your code you need to figure the origin of your drawing rect and do the above. Your code refers to 'gRect' but uses 'rect' - not clear if that's intentional or what it means. But if your label is drawn in the rect 'rect' then you should be able to use that information alone to handle the rotation, so I'm not sure what gRect is or how it's being used.

Anyhoo, hope that helps.

Here's some code I have in my current app that does something similar, labelling the axes of a grid. It refers to other methods and so on not shown here, but will give you an idea of how I do the rotation. One thing to note is that I do all of the positioning calculations ahead of doing the rotation/drawing. Also, <aRect> is the updateRect that originates in the view's -drawRect: method, not the box in which I draw the text. This also handles both X and Y axes, hence the added complication ;-)



- (void) drawAnnotationElement:(unsigned) indx maxElement:(unsigned) max inRect:(NSRect) aRect atEdge:(DKOGridEdge) edge
{
//<indx> is the ordinal item to draw, starting from 0. The actual drawn element factors in the offset and increment. <edge> specifies which edge(s) the annotation
// should be drawn at. It will be left or right. For vertical annotation left == top, right == bottom.

if( edge == 0 )
return; // nothing to do

NSString* str = [self annotationStringForElement:indx maxElement:max];
NSAttributedString* std = [[NSAttributedString alloc] initWithString:str attributes:[self textAttributes]];
NSRect bbox, ir;

// get the bounding box for the string


bbox.size = [std size];
ir = [mGridRef borderRect];

// swap the box width/height if rotated

if([self isRotated])
{
float temp = bbox.size.width;
bbox.size.width = bbox.size.height;
bbox.size.height = temp;
}

// position the box

float textOffset = [mGridRef borderAllowance] + mOffset;

float sd = [mGridRef spanLength];

if([self orientationIsVertical])
{
if( edge == kDKOLeftEdge )
bbox.origin.x = NSMinX( ir ) - bbox.size.width - textOffset;
else
bbox.origin.x = NSMaxX( ir ) + textOffset;

bbox.origin.y = ( NSMinY( ir ) + ( sd * indx )) - (bbox.size.height * 0.5);

if([self placement] == kDKOPlaceAnnotationBetweenGrid )
bbox.origin.y += sd * 0.5;

// don't draw if beyond end of interior

if( bbox.origin.y > NSMaxY( ir ))
return;
}
else
{
if( edge == kDKOLeftEdge )
bbox.origin.y = NSMinY( ir ) - bbox.size.height - ( textOffset * 0.7);
else
bbox.origin.y = NSMaxY( ir ) + ( textOffset * 0.7 );

bbox.origin.x = ( NSMinX( ir ) + ( sd * indx )) - (bbox.size.width * 0.5);

if([self placement] == kDKOPlaceAnnotationBetweenGrid )
bbox.origin.x += sd * 0.5;

if( bbox.origin.x > NSMaxX( ir ))
return;
}

// draw the text in the box

if( NSIntersectsRect( bbox, aRect ))
{
NSPoint origin = bbox.origin;

[NSGraphicsContext saveGraphicsState];

if([self isRotated])
{
NSAffineTransform* tfm = [NSAffineTransform transform];

if([self orientationIsVertical])
{
origin.x = NSMaxX( bbox );
[tfm translateXBy:origin.x yBy:origin.y];
[tfm rotateByDegrees:90];
[tfm translateXBy:-origin.x yBy:-origin.y];
}
else
{
origin.y = NSMaxY( bbox );
[tfm translateXBy:origin.x yBy:origin.y];
[tfm rotateByDegrees:-90];
[tfm translateXBy:-origin.x yBy:-origin.y];
}
[tfm concat];
}

[std drawAtPoint:origin];
[NSGraphicsContext restoreGraphicsState];
}
}




Graham
_______________________________________________

Cocoa-dev mailing list (email@hidden)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


References: 
 >NSAttributedString in NSAffineTransform (From: Joseph Ayers <email@hidden>)

  • Prev by Date: NSAttributedString in NSAffineTransform
  • Next by Date: Re: CoreAudio — AudioUnit and AudioUnitExternalBuffer
  • Previous by thread: NSAttributedString in NSAffineTransform
  • Next by thread: How to manage (My)SQL data in Cocoa
  • Index(es):
    • Date
    • Thread