Problem with CircleView Example and NSLayoutManager angles...
Problem with CircleView Example and NSLayoutManager angles...
- Subject: Problem with CircleView Example and NSLayoutManager angles...
- From: Steve Mykytyn <email@hidden>
- Date: Thu, 29 Jan 2004 14:29:59 -0800
CircleView is a great example program for learning how to lay out text
along a curve.
It does have a very small bug, which you can see if you make the font
used for the text larger, say 36 point. It makes it easier to see if
you draw a circle just interior to the text.
The bug is: the angle calculated to determine where each glyph should
start drawing is assumed to be the same angle that should be used to
rotate the glyph. This is not the case, as you can see when you make
the Font large.
A reasonable solution is to calculate the appropriate angle to the
midpoint of each glyph and use that to rotate the coordinates, as in
the sample code below taken from a modified version of CircleView:
[transform translateXBy:viewLocation.x yBy:viewLocation.y];
// new stuff here to compute angle2
if ( glyphIndex < NSMaxRange(glyphRange)-1 ) {
NSRect lineFragmentRect2 = [layoutManager
lineFragmentRectForGlyphAtIndex:glyphIndex+1 effectiveRange:NULL];
NSPoint layoutLocation2 = [layoutManager
locationForGlyphAtIndex:glyphIndex+1];
layoutLocation2.x += lineFragmentRect2.origin.x;
angle2 = startingAngle + ((layoutLocation.x+layoutLocation2.x) /
(2*distance));
NSLog(@"glyphIndex=%d Angle = %f Angle2 = %f",glyphIndex,angle,
angle2);
}
else {
NSRect lineFragmentRect2 = [layoutManager
lineFragmentRectForGlyphAtIndex:glyphIndex-1 effectiveRange:NULL];
NSPoint layoutLocation2 = [layoutManager
locationForGlyphAtIndex:glyphIndex-1];
layoutLocation2.x += lineFragmentRect2.origin.x;
angle2 = startingAngle + ((2*layoutLocation.x-layoutLocation2.x) /
(distance));
}
[transform rotateByRadians:-angle2];
This works well EXCEPT for the "else" clause - I'm having trouble
getting the last glyph to lay out correctly. Up until the last glyph,
you can basically take the starting position of the current and next
glyph, average them, and use that angle. This of course does not work
for the last glyph.
I've tried a number of different approaches to get the angle right on
the last glyph, but the only one that reliably works for me is
appending a blank to the string being drawn, so that the last visible
glyph is not the last glyph. This seems inelegant. In the code above,
I use the distance back to the next to last glyph as an estimate of the
width of the current glyph - which of course only works if they are the
same glyph.
As I think I understand it, there's no easy way to get the width of an
individual glyph. Suggestions other than appending that blank to the
end of the string?
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.