Skip to main content
Known Participant
June 6, 2018
Question

Resize Text Size based on Canvas Size

  • June 6, 2018
  • 3 replies
  • 4397 views

Hi

We have code which changes the text in a layer.

We have an issue in that sometimes the text exceeds the size of the canvas ie its to long and needs to be reduced.

We are looking for some code which will:

1. Reduce the spacing between digits in that layer from -20 to -50 to fit.

2. Then reduce size of that layer if still needed until it fits within the canvas.

Thanks

This topic has been closed for replies.

3 replies

Legend
June 9, 2018

Try this script

var old_units = app.preferences.rulerUnits;

app.preferences.rulerUnits = Units.PIXELS;

var text_size = Number(activeDocument.activeLayer.bounds[2].value) - Number(activeDocument.activeLayer.bounds[0].value);

if (Number(activeDocument.activeLayer.bounds[0].value) < 0 || Number(activeDocument.activeLayer.bounds[2].value) > Number(activeDocument.width.value))

    activeDocument.activeLayer.translate(Number(activeDocument.width.value)/2 - (Number(activeDocument.activeLayer.bounds[2].value) + Number(activeDocument.activeLayer.bounds[0].value))/2)

if (text_size > Number(activeDocument.width.value) || Number(activeDocument.activeLayer.bounds[0].value) < 0 || Number(activeDocument.activeLayer.bounds[2].value) > Number(activeDocument.width.value))

    {

    var s = activeDocument.activeLayer.textItem.contents;

    var size = activeDocument.activeLayer.textItem.size.value;

    var prev_is_digit = false;

    var pos;

    var len;

   

    var x = new Array();

    for (var i = 0; i < s.length; i++)

        {

        var c = s.charAt(i);

   

        if (c >= "0" && c <= "9")

            {

            if (!prev_is_digit)

                {

                pos = i;

                len = 1;

                prev_is_digit = true;

                }

            else

                {          

                ++len;

                }

            }

        else

            {

            if (prev_is_digit)

                {

                x.push([pos, len]);

                prev_is_digit = false;

                }

   

            }       

        }

   

    if (prev_is_digit)

        {

        x.push([pos, len]);

        prev_is_digit = false;

        }

    for (var i = 0; i < x.length; i++)

        set_text_style(x[0], x[1]-1, size, -50); 

    text_size = Number(activeDocument.activeLayer.bounds[2].value) - Number(activeDocument.activeLayer.bounds[0].value);

    if (text_size > Number(activeDocument.width.value) || Number(activeDocument.activeLayer.bounds[0].value) < 0 || Number(activeDocument.activeLayer.bounds[2].value) > Number(activeDocument.width.value))

        {           

        activeDocument.activeLayer.translate(-activeDocument.activeLayer.bounds[0].value)

        activeDocument.activeLayer.resize(Number(activeDocument.width.value)/text_size*100, undefined, AnchorPosition.MIDDLELEFT);

        }

    }

app.preferences.rulerUnits = old_units;

 

function set_text_style(from, len, size, tracking) 

    { 

    try { 

        if (len <= 0) return;

       

        var d = new ActionDescriptor(); 

        var r = new ActionReference(); 

        r.putEnumerated(stringIDToTypeID("textLayer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum")); 

        d.putReference(stringIDToTypeID("null"), r); 

        var d1 = new ActionDescriptor(); 

 

        var list1 = new ActionList(); 

        var d2 = new ActionDescriptor(); 

        d2.putInteger(stringIDToTypeID("from"), from); 

        d2.putInteger(stringIDToTypeID("to"), from+len); 

 

        var d3 = new ActionDescriptor(); 

        d3.putUnitDouble(stringIDToTypeID("size"), stringIDToTypeID("pointsUnit"), size); 

        d3.putInteger(stringIDToTypeID("tracking"), tracking); 

 

        d2.putObject(stringIDToTypeID("textStyle"), stringIDToTypeID("textStyle"), d3); 

 

        list1.putObject(stringIDToTypeID("textStyleRange"), d2); 

        d1.putList(stringIDToTypeID("textStyleRange"), list1); 

 

        d.putObject(stringIDToTypeID("to"), stringIDToTypeID("textLayer"), d1); 

        executeAction(stringIDToTypeID("set"), d, DialogModes.NO); 

        } 

    catch (e) { throw(e); }  

    } 

web2000Author
Known Participant
June 11, 2018

Hi

Thanks for that script.

I tested and it works well.

It doesnt seem to reduce the font size though, does it just resize font width?

Ideally i was looking for it to resize the actual font size or spacing between digits to fit within canvas.

Thank you.

web2000Author
Known Participant
June 11, 2018

The script changes the distance between digits.

If you want to change the font size, you can do it in two ways.

Replace

activeDocument.activeLayer.resize(Number(activeDocument.width.value)/text_size*100, undefined, AnchorPosition.MIDDLELEFT);  

to

activeDocument.activeLayer.resize(Number(activeDocument.width.value)/text_size*100, Number(activeDocument.width.value)/text_size*100, AnchorPosition.MIDDLELEFT);  

or to

activeDocument.activeLayer.textItem.size *= (Number(activeDocument.width.value)/text_size);


Thanks for that, this worked best:

activeDocument.activeLayer.resize(Number(activeDocument.width.value)/text_size*100, Number(activeDocument.width.value)/text_size*100, AnchorPosition.MIDDLELEFT);   

A couple of questions if i may:

1. we adjusted the text_size*100 to text_size*95 just to give a slight margin around the edge of the document. This works well but then the text layer is positioned to the left. So we adjusted AnchorPosition.MIDDLELEFT to AnchorPosition.MIDDLECENTER but it moved to the right somewhat? We are guessing that it is centring based on the original text size perhaps before it was resized rather than centring based on the canvas size or the current new text size? Is there a way to centre correctly?

2. Is there a way to change the inbetween spacing ie 0 or -20 -50 etc first. For example if the text is larger than canvas, first try adjusting the inbetween spacing then reduce font if needed.

Thanks

JJMack
Community Expert
Community Expert
June 9, 2018

If you know the total number of characters  the longest text line will have you most likely could come up with the font size that should be used so the length of the text layer will not exceed the width of the canvas. You may need to change the Documents resolution to 72DPI  without resampling calculate the font size to use add the text layer then restore the document ti its original dip resolution.    I believe I had to doe something like that to come up with a font size to use.  But I just hack at scripting and doe not know much about how Adobe text tool works.

JJMack
JJMack
Community Expert
Community Expert
June 6, 2018

Text is quite complex resolution, size, and number of text characters and which characters most fonts support proportional charter sizes all play a part.

You may be able to transform the text layer to fit within some area  by using the areas selection bounds and the text layer bounds to resize the text layer for the area.  However, I do not know if you do that, that the text will always be readable at the new transformed scaled size.

You can not put todays headline in a icon size image file and be able to read it.

JJMack
web2000Author
Known Participant
June 9, 2018

Thanks for your reply.

Is there a way to work out the width of a text layer?

As i am thinking with the canvas size, and the text layer size we can then reduce if the text layer is bigger?