Jayme McColgan Posted June 3, 2022 Share Posted June 3, 2022 lets say i make a text box that is 3" long but i want whatever text i type to dynamically size itself to always be on 1 line. using vs.SetTextSize() how would i go from deciding the point size based on the text length and the text box size. Quote Link to comment
Jayme McColgan Posted June 3, 2022 Author Share Posted June 3, 2022 Oh my... I've started doing some research into how pts compare to inches and they math hurts my head... Lol I've got a good working formula if all the characters are the same size but that's never gonna happen... Quote Link to comment
MullinRJ Posted June 3, 2022 Share Posted June 3, 2022 If the point size is uniform through the entire block, the scaling formula is quite easy to achieve a known length. If you have mixed character sizes throughout the block, and potentially mixed font faces, you will have to build a dynamic array of each character and store its size and fontID, calculate the scale factor needed to change the block length to the desired size, then scale each character individually to achieve the overall desired length. Doable, but tedious. And who said HS algebra class was a waste of time? Raymond Quote Link to comment
Pat Stanford Posted June 3, 2022 Share Posted June 3, 2022 How about calculating the ratio of the existing size of the bounding box to the desired size and using that ratio to scale the text size. It seems to work both up and down on my quick test. This script is intended to be run on a selected text block on the active layer. It will work best on a layer at 1:1 scale. Sorry, Vectorscript, not Python. Procedure Test; Var X1,Y1,X2,Y2, W1, R1, T1, T2 :Real; H1 :Handle; BEGIN H1:=FSActLayer; GetBBox(H1,X1,Y1, X2,Y2); W1:=(X2-X1); R1:=(3"/W1); T1:=GetTextSize(H1,1); T2:=(T1*R1); SetTextSize(H1, 0, Len(GetText(H1)), T2); ResetObject(H1); End; Run(Test); Quote Link to comment
Pat Stanford Posted June 3, 2022 Share Posted June 3, 2022 And yes, the above script does assume that the entire block is the same font. Thats edge case @MullinRJ to you and me. 😉 Good catch Raymond. Quote Link to comment
MullinRJ Posted June 3, 2022 Share Posted June 3, 2022 (edited) OK, not as hard as I originally imagined. You just have to scale each character's size by the same amount, and the scale factor is the (existing text length) / (unwrapped text length). Then use a loop to get each characters's size and scale each one to a new size. The secret sauce is knowing how to set the TextWrap and TightFill attributes. The rest is easy peasy. PROCEDURE xxx; { Scale a wrapped text block to fit in the same box on one line. } { 2 Jun 2022 - Raymond Mullin } VAR H :Handle; I :Integer; TxtBoxW, TxtWid, SF, ChSz :Real; BEGIN H := FSActLayer; TxtBoxW := GetTextWidth(H); { target size } SetTextWrap(H, False); { clear Text Wrap } SetObjectVariableBoo(H, 684, False); { clear Tight Fill } TxtWid := GetTextWidth(H); { full length of text } SF := TxtBoxW / TxtWid; { scale factor } for I := 0 to GetTextLength(H) do begin ChSz := GetTextSize(H, I); { individual character size } SetTextSize(H, I, 1, ChSz * SF); { new character size } end; { for } SysBeep; END; Run(xxx); Like Pat, I leave it to you to Pythonize it. Raymond Edited June 3, 2022 by MullinRJ 3 Quote Link to comment
MullinRJ Posted June 3, 2022 Share Posted June 3, 2022 For some unknown reason, to me at least, when processing a text block with 3 or more point sizes, the above procedure gets very close to achieving the proper text length after scaling, but not the exact length. It's slightly long. I did achieve acceptable perfection by repeating the process of scaling a second time. If you need more input on how to do this, write back. Raymond Quote Link to comment
Jayme McColgan Posted June 3, 2022 Author Share Posted June 3, 2022 Here is the Python Version! i also added a check so it doesn't go larger then the vertical box i want the text to be in. might a little messy but it works for my specific scenario thanks for the help @MullinRJ and @Pat Stanford max_size = 1 ### points (determed by trial and error lol) text_box_width = 2.8 ### inches string1 = "Super Long Fixture Name" vs.CreateText(str(f"{string1}")) last = vs.LNewObj() vs.SetTextJust(last, 1) vs.SetTextWidth(last, text_box_width) vs.HMove(last, 1.01, -0.2) textwidth = vs.GetTextWidth(last) vs.SetTextWrap(last, False) vs.SetObjectVariableBoolean(last, 684, False) textwidth_new = vs.GetTextWidth(last) sf = textwidth / textwidth_new for i in range(vs.GetTextLength(last)): ChSz = vs.GetTextSize(last, i) if ChSz * sf > max_size: vs.SetTextSize(last, i, 1, max_size) else: vs.SetTextSize(last, i, 1, ChSz * sf) 2 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.