[Drawkit] DKTextShape rotation
Graham Cox
graham.cox at bigpond.com
Thu Feb 12 15:39:31 PST 2009
On 13 Feb 2009, at 4:57 am, Allan wrote:
> Hi Graham,
>
> I'm still working on implementing the TEXT entity import from the
> DXF format into DK. It has been a tougher nut to crack than I
> expected. Here's my current issue that I wonder if you could comment
> on.
>
> In AutoCAD (and the resulting DXF) when TEXT is rotated it is not
> necessarily rotated around the center point. AutoCAD uses the
> concept of an "insertion point" which is the origin or base point of
> the TEXT object. If you rotate text, it gets rotated with respect to
> this insertion point.
>
> I think that in DK all DrawableObject rotations happen around the
> object center/middle point. Is that correct? If so, for me to place
> a rotated text object correctly would require me to do some math
> where I would use the AutoCAD insertion point and the rotation angle
> with some sines and cosines to figure out the correct DK origin and
> then apply the rotation.
>
> Is that right? All DK objects are rotated around the center/middle?
> Or is there a clever DK method to modify the rotation point for an
> object that I could use to more directly get the TEXT object located
> correctly?
>
> Thanks for any help you can send.
Hi Allan,
All shapes (including text shapes) allow you to set the 'point of
rotation' anywhere within the bounds of the shape. By default it's the
middle, but you can move it anywhere.
In the UI an ordinary shape uses a centre target cross to show where
this is, and you can click and drag this to set the centre. In a text
shape, this knob is turned off so that it doesn't get in the way of
reading the text, and as a result it's not draggable. That doesn't
prevent you from setting it programatically, and/or you can turn the
visibility of that knob back on if you want to make it interactive.
To set it programmatically, use -setOffset:
This accepts a NSSize argument that is the relative amount of
displacement from the centre to the unrotated bounds edge. That sounds
complicated but it's easy to understand with an example. An offset of
{0,0} is the centre. An offset of {-0.5, -0.5} is the top, left (or
bottom, left in unflipped coordinates) of the object, and offset =
{0.5, 0.5} is the bottom right. Specifying the offset this way makes
it always proportional to the current size of the object so rotation
does the expected thing.
If you want to make the knob for this visible in a text object, in the
current version you'll need to change the mask returned by +knobMask,
which is hardcoding the clearing of the kDKDrawableShapeOriginTarget
flag. I need to change that to use the more recent approach of using
+setKnobMask so you can simply set it as you wish.
When you're placing text objects programmatically, if you set the
offset prior to setting the location and angle of the object, you
should be able to simply place the object without having to do any
maths - the offset also sets the position that the object considers
its location to be measured from, so for example if you set the offset
to the bottom, left of the text, and that's where the DXF file
considers its text labels to be located, then you can just call -
setLocation: with the same value (and angle). When the offset is
changed interactively the location is compensated so the object
doesn't move within the drawing, but the actual value of -location is
changing. Hope that makes sense. Rather than 'point of rotation' think
of the offset as setting the object's datum. The location and rotation
are relative to this datum point.
Also, while we're on this topic, here's a handy debugging or
introspection technique that can sometimes be useful to "see" what's
happening to certain values as you interact with objects, such as
dragging them or their control knobs. Create a text adornment style
and set its identifier to '$<keypath>', where <keypath> is some
property of interest, let's say 'offset'. Then the object that has
this style attached will display the value of that property right
there in the object, and it will be updated live whenever it changes.
The '$' prefix is there to tell the adornment to look up the value as
a property not as a metadata key. After that it's just using KVC.
--Graham
More information about the Drawkit
mailing list