Stringshape rotation

Given a string of font size FS, drawn at x,y

Is there a reliable method for turning that into a stringshape which, when drawn, rotates the string clockwise around the bottom left corner of the string?

I’m struggling to do this because stringshapes rotate around their centre point.
And if I get the position correct for one value of FS, as soon as I use another font size, the Y position is incorrect.
I’ve spent days on it and cannot get it to be reliable

Im happy with the rotation angle for 90 degrees, and eventually wouldnt mind using other angles. But right now its the starting location that is eluding me.

To avoid doing the math yourself, you could try making it part of a Group2D and then rotate the Group2D.


I hear you.
But that would rotate ‘everything’ and my needs are
99% normal drawing commands, plus a few rotated text items.

I can rotate the text. I just cannot predict where it will end up on the page.

I do this (g is the target graphics instance):

'Note this code is an excerpt, the actual code is part of a class which determines the rotation and scaling

Dim Ss As New StringShape
Dim TempX1 As Double
Dim TempY1 As Double
Dim WidHere As Double
Dim WidNew As Double

Ss.FillColor = g.DrawingColor
Ss.TextFont = g.TextFont
Ss.TextSize = g.TextSize
Ss.Bold = g.Bold
Ss.Underline = g.Underline
Ss.Italic = g.Italic

Ss.HorizontalAlignment = StringShape.Alignment.Center
Ss.VerticalAlignment = StringShape.Alignment.Center

Ss.Text = Astr 'The string I'm drawing

Ss.Rotation=Rotation * -.0174533 'Rotate 270 degrees to the left 

Select Case Self.TxtAlignment
Case kJustLeft
  If Rotation=0 Then 'Upright
  ElseIf Rotation=90 Then 'Rotated Left
  ElseIf Rotation=270 Then 'Rotated Right
  End If
Case kJustCtr
Case kJustRight
  If Rotation=0 Then 'Upright
    If WidNew>0 Then
    End If
  ElseIf Rotation=90 Then 'Rotated Left
  ElseIf Rotation=270 Then 'Rotated right
  End If
End Select


Just noticed that my snippet left out a crucial part:


If WidHere=0 Then
End If

Interesting… What are AvailWid and Availhere doing/coming from?

centre justification is the default, isnt it?
If so,

does rotate the text but places it ‘somewhere’ rather than ‘rotated about the corner’

This is what I am after: (the red dot shows my assumed point of centre for rotating)

I’ll experiment with your code (thank you), but at first glance I’m not sure we are there yet…

Not done much with string shape but the following code i’ve just hacked together might help.
NOTE. mAngle_ is an Integer containing the angle in degrees

  Const kPi = 3.14159265358979323846264338327950288
  'the draw x & y position
  Const kX = 150
  Const kY = 150
  'create a dummy shape
  Dim s As New StringShape
  s.Text = "Hello"
  s.TextFont = "System"
  s.TextSize = 50
  'create a picture so that we can measure the text
  Dim p As New Picture(1, 1, 32)
  p.Graphics.TextFont = s.TextFont
  p.Graphics.TextSize = s.TextSize
  'calculate half the width as string shape rotates from the centre
  Dim halfWidth As Double
  halfWidth = p.Graphics.StringWidth(s.Text) / 2
  'offset the string shape so that it draws the same way as Graphics.DrawString
  'not needed but i used this for testing
  s.Y = p.Graphics.TextAscent
  s.X = halfWidth
  'draw the string shape at 0 degrees
  s.FillColor = RGB(0, 0,  0)
  g.DrawObject(s, kX, kY)
  'draw the text using DrawString at the same position
  'not needed but i used this for testing
  g.TextFont = s.TextFont
  g.TextSize = s.TextSize
  g.ForeColor = RGB(255, 0,  0)
  g.DrawString(s.Text, kX, kY + p.Graphics.TextAscent)
  'calculate the rotation offset
  Dim offsetX, offsetY As Double
  Dim theRadians As Double
  Dim theCosine, theSine As Double
  Dim rotatedX, rotatedY As Double
  theRadians = (2 * kPi * Self.mAngle_) / 360
  theCosine = Cos(theRadians)
  theSine = Sin(theRadians)
  offsetX = halfWidth 'move the horizontal rotation point from the centre to the left (* -1 should move it to the right)
  offsetY = 0 'don't move the vertical rotation point (p.Graphics.TextAscent should move it to the top)
  rotatedX = (offsetX * theCosine) - (offsetY * theSine)
  rotatedY = (offsetX * theSine) + (offsetY * theCosine)
  'draw the rotated string shape
  s.Rotation = theRadians
  s.FillColor = RGB(192, 192, 192)

  g.DrawObject(s, kX - offsetX + rotatedX, kY - offsetY + rotatedY)

I’m drawing on Avery labels on a page, so AvailWid is g.width of the whole page, WidHere is the space available within each label.

For what you’re doing, you probably want to use the Rotation=270 code.

This does require some mind-twisting gymnastics. I worked it out by drawing a letter on a 3x5 index card set on top of a piece of paper, writing down the coordinates of the card, then rotated the card the direction I wanted and figured out its new coordinates. Compared the “before” and “after” to see what the difference was, then wrote code to match.

1 Like