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

    } 

JJMack
Community Expert
Community Expert
June 9, 2018

The script does resize the active layer to fit within the canvas width as I wrote can be done in my first append.  However that does not mean the text will be readable.  There is a point where the resize text may be to small to be readable there needs to some number of pixel to form readable characters.  To few pixels will cause  characters to be unrecognizable shapes..

JJMack
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?