Jump to content

Change Text size based on string length to stay on 1 line


Recommended Posts

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

Link to comment

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);

 

Link to comment
Posted (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 by MullinRJ
  • Like 3
Link to comment

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

Link to comment

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)

 

  • Like 2
Link to comment

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...