Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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?
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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); }
}
Copy link to clipboard
Copied
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..
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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);
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
If you looked at the logic of the script, you would notice that the script first changes the tracking for digits to -50. After that, checks the text size and only if it is more than necessary, it changes the actual size of the text.
In order for your text to center on the center at 95% and AnchorPosition.MIDDLECENTER, change the code at the end like this.
Instead
activeDocument.activeLayer.translate(-activeDocument.activeLayer.bounds[0].value)
Replace
activeDocument.activeLayer.translate(Number(activeDocument.width.value)/2 - (Number(activeDocument.activeLayer.bounds[2].value) + Number(activeDocument.activeLayer.bounds[0].value))/2)
Copy link to clipboard
Copied
Thank you. This now resizes the text perfectly. The only one issue is the code isnt first reducing the text -50 where possible, and then if it still doesnt fit then resizing the text size. It seems to be resizing where a -50 resize would bring it back in to canvas vs having to change text size. This is the final code i am working with. Thank you.
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(Number(activeDocument.width.value)/2 - (Number(activeDocument.activeLayer.bounds[2].value) + Number(activeDocument.activeLayer.bounds[0].value))/2)
activeDocument.activeLayer.resize(Number(activeDocument.width.value)/text_size*95, Number(activeDocument.width.value)/text_size*95, AnchorPosition.MIDDLECENTER);
}
}
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); }
}
Copy link to clipboard
Copied
So where can I use this script in Photoshop? Would love to have and action set to put signatures in my pictures changing the font size depending on the picture size
Copy link to clipboard
Copied