Seite 1 von 2

"Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 02:27
von c4s
Folgender Code beschreibt meine Frage wohl am Besten:

Code: Alles auswählen

Text.s = "Hello World!"

NBoxX = 50 : NBoxY = 50
GBoxX = 50 : GBoxY = 150  ;

CreateImage(0, 200, 200)
StartDrawing(ImageOutput(0))
	; Normal:
	DrawingMode(#PB_2DDrawing_Transparent)
	DrawText(NBoxX, NBoxY, Text, $FF00FF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(NBoxX, NBoxY, TextWidth(Text), TextHeight(Text), $FF00FF)
	Circle(NBoxX, NBoxY, 3, $FF00FF)

	; Gedreht:
	DrawingMode(#PB_2DDrawing_Transparent)
	DrawRotatedText(GBoxX, GBoxY, Text, 45, $FFFFFF)
	DrawingMode(#PB_2DDrawing_Outlined)
	Box(50, 90, 73, 73, $FFFFFF)  ; <- Geschätzte Koordinaten zur Veranschaulichung
	Circle(50, 90, 3, $FFFFFF)
StopDrawing() 


If OpenWindow(0, 0, 0, 200, 200, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ImageGadget(0, 0, 0, 200, 200, ImageID(0))

	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Ich möchte bei DrawRotatedText() die "Bounding-Box"-Koordinaten herausfinden und die Funktion am liebsten auch darüber steuern, sodass nicht um X/Y herum gedreht wird, sondern innerhalb der "Bounding-Box".

Kann mir jemand dabei auf die Sprünge helfen?

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 02:45
von STARGÅTE
Ist nicht ganz auf den Pixel (weil DrawText die Font irgendwie dicker macht bei Rotate) genau aber funktioniert:

Code: Alles auswählen

Text.s = "Hello World!"

NBoxX = 50 : NBoxY = 50
GBoxX = 150 : GBoxY = 250  ;

Procedure.i RotatedTextX(Text.s, Angle.f)
  Protected x
  If Cos(Radian(Angle)) < 0
    x + Cos(Radian(Angle))*TextWidth(Text)
  EndIf
  If Sin(Radian(Angle)) < 0
    x + Sin(Radian(Angle))*TextHeight(Text)
  EndIf
  ProcedureReturn x
EndProcedure
Procedure.i RotatedTextY(Text.s, Angle.f)
  Protected y
  If Sin(Radian(Angle)) > 0
    y - Sin(Radian(Angle))*TextWidth(Text)
  EndIf
  If Cos(Radian(Angle)) < 0
    y + Cos(Radian(Angle))*TextHeight(Text)
  EndIf
 ProcedureReturn y
EndProcedure
Procedure.i RotatedTextWidth(Text.s, Angle.f)
  ProcedureReturn Abs(Cos(Radian(Angle))*TextWidth(Text))+Abs(Sin(Radian(Angle))*TextHeight(Text))
EndProcedure
Procedure.i RotatedTextHeight(Text.s, Angle.f)
  ProcedureReturn Abs(Sin(Radian(Angle))*TextWidth(Text))+Abs(Cos(Radian(Angle))*TextHeight(Text))
EndProcedure


CreateImage(0, 400, 400)
StartDrawing(ImageOutput(0))
   ; Normal:
   DrawingMode(#PB_2DDrawing_Transparent)
   DrawText(NBoxX, NBoxY, Text, $FF00FF)
   DrawingMode(#PB_2DDrawing_Outlined)
   Box(NBoxX, NBoxY, TextWidth(Text), TextHeight(Text), $FF00FF)
   Circle(NBoxX, NBoxY, 3, $FF00FF)

   angle = 45
   ; Gedreht:
   DrawingMode(#PB_2DDrawing_Transparent)
   DrawRotatedText(GBoxX, GBoxY, Text, angle, $FFFFFF)
   DrawingMode(#PB_2DDrawing_Outlined)
   GBoxX + RotatedTextX(Text, angle)
   GBoxY + RotatedTextY(Text, angle)
   Box(GBoxX, GBoxY, RotatedTextWidth(Text, angle), RotatedTextHeight(Text, angle), $FFFFFF)  ; <- Geschätzte Koordinaten zur Veranschaulichung
   Circle(GBoxX, GBoxY, 3, $FFFFFF)
StopDrawing() 


If OpenWindow(0, 0, 0, 400, 400, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ImageGadget(0, 0, 0, 400, 400, ImageID(0))

   Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf 
RotatedTextX und RotatedTextY geben die (mögliche) Verschiebung an, wo die linke obere Ecke wäre
und RotatedTextWidth und RotatedTextHeight die gesamt ausdehnung.

Wie gesagt, die Darstellung von DrawText ist irgendwie ungenau, deswgene passt es nicht ganz.
Die Breite eines Textes ist nicht gleich der Höhe wenn er um 90° gedreht ist.

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 12:49
von c4s
Danke, ich werde mich damit mal auseinandersetzen und in mein kleines Projekt einbauen, dass ich demnächst hier veröffentlichen will.

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 14:41
von c4s
Leider verstehe ich das immer noch nicht so ganz... Wie kann ich das Beispiel so abändern, dass der rechte Text innerhalb der Box gezeichnet wird?
Ich möchte erreichen, dass DrawRotatedText() nicht um die X/Y-Koordinaten herum zeichnet, sondern wie bei DrawText() (bzw. Winkel=0) immer rechts unten von der gewünschten Position ist.

Ich habe das Beispiel etwas verbessert:

Code: Alles auswählen

EnableExplicit

Enumeration 
	#Window
	#ImageGadget
	#Image
	#Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
	Protected Result

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Sin(Radian(Angle)) < 0
		Result + (Sin(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
	Protected Result

	If Sin(Radian(Angle)) > 0
		Result - (Sin(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
	ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
	ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
	Protected X, Y, W, H

	CreateImage(#Image, Width, Height)


	StartDrawing(ImageOutput(#Image))
		DrawingFont(TextFontID)

		Box(0, 0, Width, Height, $000000)

		; Normal:
		X = NBoxX
		Y = NBoxY
		W = TextWidth(Text)
		H = TextHeight(Text)
		DrawingMode(#PB_2DDrawing_Transparent)
		DrawText(X, Y, Text, $FF00FF)
		DrawingMode(#PB_2DDrawing_Outlined)
		Box(X - 1, Y - 1, W + 2, H + 2, $800080)
		Circle(X, Y, 3, $800080)

		; Gedreht:
		X = GBoxX ;+ RotatedTextX(Text, GAngle)
		Y = GBoxY ;+ RotatedTextY(Text, GAngle)
		W = RotatedTextWidth(Text, GAngle)
		H = RotatedTextHeight(Text, GAngle)
		DrawingMode(#PB_2DDrawing_Transparent)
		DrawRotatedText(GBoxX, GBoxY, Text, GAngle, $FFFFFF) ;DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)
		DrawingMode(#PB_2DDrawing_Outlined)
		Box(X - 1, Y - 1, W + 2, H + 2, $808080)
		Circle(X, Y, 3, $808080)
	StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 100
GBoxX = 300 : GBoxY = 100 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

	AddWindowTimer(#Window, #Timer, 50)

	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Timer
				If EventTimer() = #Timer
					GAngle + 4  ; Text drehen
					CreateTestImage()
					SetGadgetState(#ImageGadget, ImageID(#Image))
				EndIf
			Case #PB_Event_CloseWindow
				Break
		EndSelect
	ForEver
EndIf

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 15:14
von STARGÅTE
Ist ja fast richtig, aber du hast in der Prozedur X und GBoxX verdreht:

Denn die Box soll ja immer bei GBoxX sein, und der Text dann verschoben um meine Prozedur.

Code: Alles auswählen

EnableExplicit

Enumeration 
   #Window
   #ImageGadget
   #Image
   #Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
   Protected Result

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Sin(Radian(Angle)) < 0
      Result + (Sin(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
   Protected Result

   If Sin(Radian(Angle)) > 0
      Result - (Sin(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
   ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
   ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
   Protected X, Y, W, H

   CreateImage(#Image, Width, Height)


   StartDrawing(ImageOutput(#Image))
      DrawingFont(TextFontID)

      Box(0, 0, Width, Height, $000000)

      ; Normal:
      X = NBoxX
      Y = NBoxY
      W = TextWidth(Text)
      H = TextHeight(Text)
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawText(X, Y, Text, $FF00FF)
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(X - 1, Y - 1, W + 2, H + 2, $800080)
      Circle(X, Y, 3, $800080)

      ; Gedreht:
      X = GBoxX - RotatedTextX(Text, GAngle)
      Y = GBoxY - RotatedTextY(Text, GAngle)
      W = RotatedTextWidth(Text, GAngle)
      H = RotatedTextHeight(Text, GAngle)
      DrawingMode(#PB_2DDrawing_Transparent)
      DrawRotatedText(X, Y, Text, GAngle, $FFFFFF) ;DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)
      DrawingMode(#PB_2DDrawing_Outlined)
      Box(GBoxX - 1, GBoxY - 1, W + 2, H + 2, $808080)
      Circle(GBoxX, GBoxY, 3, $808080)
   StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 100
GBoxX = 300 : GBoxY = 100 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

   AddWindowTimer(#Window, #Timer, 50)

   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_Timer
            If EventTimer() = #Timer
               GAngle + 4  ; Text drehen
               CreateTestImage()
               SetGadgetState(#ImageGadget, ImageID(#Image))
            EndIf
         Case #PB_Event_CloseWindow
            Break
      EndSelect
   ForEver
EndIf


Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 16:17
von c4s
Danke STARGÅTE!
Du kennst das sicherlich: Manchmal ist die Lösung so offensichtlich und einfach, dass man sie einfach nicht bemerkt - Passiert mir leider viel zu häufig. :cry:

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 19:10
von c4s
Leider komme ich mit der Materie überhaupt nicht zurecht. Langes probieren hat nicht geholfen:
Ziel sind zwei (oder mehrere) Zeilen gedrehter Text, die immer untereinander sind. Ich habe dabei X1/Y1 des ersten Textes und X2/Y2 des Zweiten. Nun möchte ich diese beiden Positionen in das "DrawRotatedText()-System" umwandeln, sodass bei Winkel=0 dasselbe wie bei DrawText() herauskommen würde und im anderen Fall eben die korrekte Drehung gezeigt wird.

Ich hoffe es ist verständlich was ich meine. Kann mir jemand helfen?

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 19:38
von STARGÅTE
Es läuft eigentlich immer aufs selbe hinaus:
RotationsMatrix:

Code: Alles auswählen

NeuX = Cos(Winkel)*x - Sin(Winkel)*y
NeuY = Sin(Winkel)*x + Cos(Winkel)*y
Du übergibst also dort dein x,y (also die Differenz zwischen den beiden Texten) an diese Gleichung
und bekommst die neuen relativkoordinaten.


Im Beispiel habe ich das Vorzeichen von Sin() verändert, da DrawRotatedText() anscheind "andersrum" dreht, (als zB RotateSprite3D)

Code: Alles auswählen

CreateImage(0, 400, 400)
StartDrawing(ImageOutput(0))
  X = 200
  Y = 200
  Angle = 15
  dx = 0
  dy = 0
  Winkel.f = Radian(Angle)
  For Zeile = 1 To 10
    Neudx = Cos(Winkel)*dx + Sin(Winkel)*dy
    Neudy = -Sin(Winkel)*dx + Cos(Winkel)*dy
    DrawRotatedText(X+Neudx, Y+Neudy, "Zeile "+Str(Zeile), Angle, $FFFFFF)
    dx + 0;TextWidth("Z")
    dy + TextHeight("Z")
  Next  
StopDrawing() 

If OpenWindow(0, 0, 0, 400, 400, "2DDrawing Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ImageGadget(0, 0, 0, 400, 400, ImageID(0))
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf 

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 22:43
von c4s
Entschuldigung, wenn ich mich zu doof anstelle, aber bitte nochmal erklären. :wink:

Beide (oder auch mehrere) gedrehte Textzeilen sollen sich in dem Rechteck drehen. Momentan ist es so, dass nur die erste mit Sicherheit immer im Rechteck ist. (Was müsste ich außerdem machen, wenn ich bereits feste Werte für die einzelnen Zeilen habe?)
Zur Veranschaulichung habe ich es nochmal in mein Beispiel eingefügt:

Code: Alles auswählen

;EnableExplicit

Enumeration
	#Window
	#ImageGadget
	#Image
	#Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
	Protected Result

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Sin(Radian(Angle)) < 0
		Result + (Sin(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
	Protected Result

	If Sin(Radian(Angle)) > 0
		Result - (Sin(Radian(Angle)) * TextWidth(Text))
	EndIf

	If Cos(Radian(Angle)) < 0
		Result + (Cos(Radian(Angle)) * TextHeight(Text))
	EndIf

	ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
	ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
	ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
	Protected X, Y, W, H
	Protected X2, Y2
	Protected RadSin.f, RadCos.f

	CreateImage(#Image, Width, Height)


	StartDrawing(ImageOutput(#Image))
		DrawingFont(TextFontID)

		Box(0, 0, Width, Height, $000000)

		DrawingMode(#PB_2DDrawing_Transparent | #PB_2DDrawing_Outlined)
	
		; Normal Gedreht:
		X = NBoxX - RotatedTextX(Text, GAngle)
		Y = NBoxY - RotatedTextY(Text, GAngle)
		W = RotatedTextWidth(Text, GAngle)
		H = RotatedTextHeight(Text, GAngle)

		DrawRotatedText(X, Y, Text, GAngle, $FF00FF)
		Box(NBoxX - 1, NBoxY - 1, W + 2, H + 2, $800080)
		Circle(NBoxX, NBoxY, 3, $800080)


		RadSin = Sin(Radian(GAngle))
		RadCos = Cos(Radian(GAngle))

		; Gedreht Kombi:
		X = GBoxX
		Y = GBoxY
		W = Abs(RadCos * TextWidth(Text)) + Abs(RadSin * (TextHeight(Text)+40))
		H = Abs(RadSin * TextWidth(Text)) + Abs(RadCos * (TextHeight(Text)+40))

		DrawRotatedText(X - RotatedTextX(Text, GAngle), Y - RotatedTextY(Text, GAngle), Text, GAngle, $FFFFFF)

		; Gedreht Kombi Nr. 2:
		X2 = GBoxX + (RadCos*0 + RadSin*40)
		Y2 = GBoxY + (-RadSin*0 + RadCos*40)
		DrawRotatedText(X2 - RotatedTextX(Text, GAngle), Y2 - RotatedTextY(Text, GAngle), Text, GAngle, $FFFFFF)

		Box(GBoxX - 1, GBoxY - 1, W + 2, H + 2, $808080)
		Circle(GBoxX, GBoxY, 3, $808080)
	StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 50
GBoxX = 300 : GBoxY = 50 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

	AddWindowTimer(#Window, #Timer, 50)

	Repeat
		Select WaitWindowEvent()
			Case #PB_Event_Timer
				If EventTimer() = #Timer
					GAngle + 4  ; Text drehen
					CreateTestImage()
					SetGadgetState(#ImageGadget, ImageID(#Image))
				EndIf
			Case #PB_Event_CloseWindow
				Break
		EndSelect
	ForEver
EndIf

Re: "Bounding-Box" von DrawRotatedText() ?

Verfasst: 26.01.2011 22:58
von STARGÅTE
Jo dann brauchst du für den Fall n abänderung meiner Prozeduren:

Ohne siehts dann so aus:

Code: Alles auswählen

;EnableExplicit

Enumeration
   #Window
   #ImageGadget
   #Image
   #Timer
EndEnumeration

Global Width, Height
Global Text.s, TextFontID
Global NBoxX, NBoxY, GBoxX, GBoxY, GAngle.f


Procedure RotatedTextX(Text.s, Angle.f)
   Protected Result

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Sin(Radian(Angle)) < 0
      Result + (Sin(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextY(Text.s, Angle.f)
   Protected Result

   If Sin(Radian(Angle)) > 0
      Result - (Sin(Radian(Angle)) * TextWidth(Text))
   EndIf

   If Cos(Radian(Angle)) < 0
      Result + (Cos(Radian(Angle)) * TextHeight(Text))
   EndIf

   ProcedureReturn Result
EndProcedure

Procedure RotatedTextWidth(Text.s, Angle.f)
   ProcedureReturn Abs(Cos(Radian(Angle)) * TextWidth(Text)) + Abs(Sin(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure RotatedTextHeight(Text.s, Angle.f)
   ProcedureReturn Abs(Sin(Radian(Angle)) * TextWidth(Text)) + Abs(Cos(Radian(Angle)) * TextHeight(Text))
EndProcedure

Procedure CreateTestImage()
   Protected X, Y, W, H
   Protected X2, Y2
   Protected RadSin.f, RadCos.f

   CreateImage(#Image, Width, Height)


   StartDrawing(ImageOutput(#Image))
      DrawingFont(TextFontID)

      Box(0, 0, Width, Height, $000000)

      DrawingMode(#PB_2DDrawing_Transparent | #PB_2DDrawing_Outlined)
   
      ; Normal Gedreht:
      X = NBoxX - RotatedTextX(Text, GAngle)
      Y = NBoxY - RotatedTextY(Text, GAngle)
      W = RotatedTextWidth(Text, GAngle)
      H = RotatedTextHeight(Text, GAngle)

      DrawRotatedText(X, Y, Text, GAngle, $FF00FF)
      Box(NBoxX - 1, NBoxY - 1, W + 2, H + 2, $800080)
      Circle(NBoxX, NBoxY, 3, $800080)


      RadSin = Sin(Radian(GAngle))
      RadCos = Cos(Radian(GAngle))

      ; Gedreht Kombi:
      X = GBoxX
      Y = GBoxY
      W = Abs(RadCos * TextWidth(Text)) + Abs(RadSin * (TextHeight(Text)+40))
      H = Abs(RadSin * TextWidth(Text)) + Abs(RadCos * (TextHeight(Text)+40))

      If RadCos < 0
        X - RadCos * TextWidth(Text)
      EndIf
      If RadSin < 0
        X - RadSin * (TextHeight(Text)+40)
      EndIf
      If RadSin > 0
        Y + RadSin * TextWidth(Text)
      EndIf
      If RadCos < 0
        Y - RadCos * (TextHeight(Text)+40)
      EndIf

      DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)

      ; Gedreht Kombi Nr. 2:
      X + (RadCos*0 + RadSin*40)
      Y + (-RadSin*0 + RadCos*40)
      DrawRotatedText(X, Y, Text, GAngle, $FFFFFF)

      Box(GBoxX - 1, GBoxY - 1, W + 2, H + 2, $808080)
      Circle(GBoxX, GBoxY, 3, $808080)
   StopDrawing()
EndProcedure



Width = 500 : Height = 200

Text = "| test |"
TextFontID = FontID(LoadFont(#PB_Any, "Arial", 20, #PB_Font_Bold | #PB_Font_HighQuality | #PB_Font_Italic | #PB_Font_StrikeOut))

NBoxX = 50 : NBoxY = 50
GBoxX = 300 : GBoxY = 50 : GAngle = 45


If OpenWindow(#Window, 0, 0, Width + 20, Height + 20, "DrawRotatedText Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   ImageGadget(#ImageGadget, 10, 10, Width, Height, 0)

   AddWindowTimer(#Window, #Timer, 50)

   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_Timer
            If EventTimer() = #Timer
               GAngle + 4  ; Text drehen
               CreateTestImage()
               SetGadgetState(#ImageGadget, ImageID(#Image))
            EndIf
         Case #PB_Event_CloseWindow
            Break
      EndSelect
   ForEver
EndIf 
Breite und Höhe der Box ergeben sich, wie du richtig erkannt hast eben aus der neuen Mehrzeiligen Höhe.
Das gilt dnan auch für die Verschiebungen.