Copy link to clipboard
Copied
Hi, I have some code here that I'm using to replace a paragraph text item.
We're doing some funky stuff to get the text size and angle because it needs to handle broken or tranformed items. Also normalizing some values like text scaling and baseline.
But I've been trying to figure out why this results in an inaccurate width and height, since I'm grabbing the original height and width and applying those to the end result. Any help would be greatly appreciated!
var log = []
ProcessUserText( activeDocument.activeLayer )
alert( log.join('\n') )
function ProcessUserText( lyr ) { try {
var prev_units = SetUnits( 'pixels' )
var txt = lyr.textItem
txt.kind = TextType.PARAGRAPHTEXT
var txtPos = txt.position
// var resFix = activeDocument.resolution / 72
// var bW = BdsW( lyr.bounds )
// var bH = BdsH( lyr.bounds )
var w = txt.width, h = txt.height
log.push( 'starting w & h: ' + [w,h] )
// fixes some broken textItem issues
txt.kind = TextType.POINTTEXT
var lyr2 = lyr.parent.artLayers.add()
lyr2.kind = LayerKind.TEXT
txt2 = lyr2.textItem
txt2.contents = txt.contents
txt2.font = txt.font
var ang = TextAngle( lyr )
RotateLayer( -ang, lyr )
// ps bug: https://community.adobe.com/t5/photoshop-ecosystem-discussions/read-font-size-with-script/td-p/10697934
txt2.size = txt.size
TextSizeWorkaround( lyr2, lyr )
RotateLayer( ang, lyr2 )
// try { txt2.color = txt.color }
// catch(e) { txt2.color = TextColorFromSample( txt ) }
// var rgb = RoundTextRgb( txt2 )
// if( ! RgbInList( rgb ) ) LogWarn( 'text color '+ rgb +' not found in list' )
txt2.useAutoLeading = true
txt2.autoKerning = AutoKernType.MANUAL
txt2.tracking = 0
txt2.verticalScale = 100
txt2.horizontalScale = 100
txt2.baselineShift = 0
txt2.justification = txt.justification
txt2.kind = TextType.PARAGRAPHTEXT
SetUnits( 'pixels' )
txt2.position = txtPos
log.push( 'txt2.kind: '+ txt2.kind )
// var bdsFix = BdsW( lyr2.bounds ) / bW
// LogDev( 'bounds new-over-old : '+ bdsFix )
txt2.width = w
txt2.height = h
log.push( 'final w & h: ' + [txt2.width, txt2.height] )
var n = lyr.name
lyr2.move( lyr, ElementPlacement.PLACEBEFORE )
lyr.remove()
lyr2.name = n
log.push( 'xy:'+ Number( txt2.position[0] ).toFixed(0)
+','+ Number( txt2.position[1] ).toFixed(0) )
log.push( 'deg:'+ ang )
log.push( 'pt:'+Number( txt2.size ).toFixed(1) )
log.push( 'font:'+ txt2.font )
log.push( 'encoded:'+ encodeURI( txt2.contents ) )
SetUnits( prev_units ) }
catch(e) { log.push( 'ProcessUserText '+ e ) }
return lyr2 } // ProcessUserText
function SetUnits( input ) { try {
var rUnit, tUnit
if( input instanceof Object ) {
rUnit = input.ruler
tUnit = input.type }
else if( IsString( input ) )
rUnit = tUnit = input
var prev_units = { ruler: preferences.rulerUnits,
type: preferences.typeUnits }
switch( rUnit ) {
case 'points': case 'pt':
preferences.rulerUnits = Units.POINTS
break;
case 'inches': case 'in':
preferences.rulerUnits = Units.INCHES
break;
case 'centimeters': case 'cm':
preferences.rulerUnits = Units.CENTIMETERS
break;
default:
preferences.rulerUnits = Units.PIXELS
break }
switch( tUnit ) {
case 'pixels': case 'px':
preferences.typeUnits = TypeUnits.PIXELS
break;
case 'inches': case 'in':
preferences.typeUnits = TypeUnits.INCHES
break;
case 'centimeters': case 'cm':
preferences.typeUnits = TypeUnits.CENTIMETERS
break;
default:
preferences.typeUnits = TypeUnits.POINTS
break }
log.push( 'units set: '+ preferences.rulerUnits +', '+ preferences.typeUnits )
return prev_units }
catch(e) { log.push( 'SetUnits '+ e ) }
} // SetUnits
function IsString( input ) {
return typeof input === 'string' || input instanceof String
} // IsString
function EditAsSmartObject( lyr ) {
ConvertSmartLayer( lyr )
runMenuItem( stID( 'placedLayerEditContents' ) )
return activeDocument.activeLayer
} // EditAsSmartObject
function ConvertSmartLayer( lyr ) { try {
SelectLayer( lyr )
if( IsSmartObj( lyr )) return lyr
var desc = new ActionDescriptor()
desc.putInteger( chID( "DocI" ), 219 )
desc.putInteger( chID( "Idnt" ), 230 )
desc.putString( chID( "Nm " ), """Convert to Smart Object""" )
desc.putBoolean( stID( "hasEnglish" ), true )
desc.putInteger( chID( "ItmI" ), 3 )
executeAction( stID( "newPlacedLayer" ), undefined, DialogModes.NO )
lyr = activeDocument.activeLayer // layer is now a different object
log.push( lyr.name +' converted to smart object' )
return lyr }
catch(e) { log.push( 'ConvertSmaartLayer '+ e ) }
} // ConvertSmartLayer
function TextAngle( lyr ) { try {
// Normalizes text copy to a period(.) and
// uses baselineShift to create a vector
var doc = activeDocument
var prev_state = doc.activeHistoryState
var angLyr = lyr.duplicate()
var angTxt = angLyr.textItem
angTxt.contents = '.'
angTxt.font = 'MyriadPro-Regular'
angTxt.size = 3
angTxt.baselineShift = 0
var soLyr1 = EditAsSmartObject( angLyr )
var soDoc = soLyr1.parent
soDoc.resizeCanvas( 250, 250, AnchorPosition.MIDDLECENTER )
var soLyr2 = soLyr1.duplicate()
soLyr2.textItem.baselineShift = 100
var ang = GetAngle(
RoundEach( BdsMid( soLyr1 ) ),
RoundEach( BdsMid( soLyr2 ) ) )
soDoc.close( SaveOptions.DONOTSAVECHANGES )
doc.activeHistoryState = prev_state
log.push( lyr.name +' angle: '+ ang )
return ang }
catch(e) { log.push( 'TextAngle '+ e ) }
} // TextAngle
function GetAngle( xy1, xy2 ) {
var ang = 0 - Math.atan( ( xy1[0] - xy2[0] ) / ( xy1[1] - xy2[1] ) ) * 180.0 / Math.PI
log.push( [xy1,xy2] +' angle: '+ ang )
return ang
} // GetAngle
function RoundEach( nums ) {
var it = []
for( var i=0; i<nums.length; i++ ) {
it[i] = Math.round( nums[i] ) }
return it
} // RoundEach
function BdsMid( lyr ) {
var b = lyr.bounds
var mid = Midpoint( [ b[0], b[1] ], [ b[2], b[3] ] )
log.push( lyr.name +' midpoint: '+ mid )
return mid
} // BdsMid
function Midpoint( xy1, xy2 ) {
return [ ( xy1[0] + xy2[0] ) / 2, ( xy1[1] + xy2[1] ) / 2 ]
} // Midpoint
function RotateLayer( deg, lyr ) { try {
lyr = lyr || activeDocument.activeLayer
if( deg && deg !== 0 ) {
lyr.rotate( deg )
log.push( lyr.name +' rotated '+ deg ) } }
catch(e) { log.push( 'RotateLayer '+ e ) }
} // RotateLayer
function TextSizeWorkaround( resizeLayer, targetLayer ) { try {
var prev_units = SetUnits( 'points' )
var resizeTxt = resizeLayer.textItem
var startSize = resizeTxt.size
log.push( 'startSize: '+ startSize )
var delta0 = BdsH( targetLayer ) - BdsH( resizeLayer )
var limit = 5
while( limit-- && Math.abs( delta0 ) >= 1 ) {
if( resizeTxt.size < 6 ) return resizeTxt.size = 6
var upDown = 1
if( delta0 < 0 ) {
resizeTxt.size--
upDown = -1
delta0 = Math.abs( delta0 ) }
else resizeTxt.size++
log.push( 'delta0: '+ delta0 )
log.push( 'upDown: '+ upDown )
var delta1 = Math.abs( BdsH( targetLayer ) - BdsH( resizeLayer ) )
log.push( 'delta1: '+ delta1 )
var remainingDelta = upDown * delta1 /( delta0 - delta1 )
log.push( 'remainingDelta: '+ remainingDelta )
resizeTxt.size = Math.round( resizeTxt.size + remainingDelta )
log.push( 'resizeTxt.size: '+ resizeTxt.size )
delta0 = BdsH( targetLayer ) - BdsH( resizeLayer ) }
SetUnits( prev_units )
return resizeTxt.size }
catch(e) { log.push( 'TextSizeWorkaround '+ e ) }
} // TextSizeWorkaround
function BdsH( bdsOrLyr ) {
if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds
return Math.abs( bdsOrLyr[1] - bdsOrLyr[3] )
} // BdsH
function BdsW( bdsOrLyr ) {
if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds
return Math.abs( bdsOrLyr[0] - bdsOrLyr[2] )
} // BdsW
function chID( a ) { return charIDToTypeID( a )}
function stID( a ) { return stringIDToTypeID( a )}
function SelectLayer( lyr ) { try {
if( typeof lyr === 'string' || lyr instanceof String ) lyr = GetLayer( lyr )
activeDocument.activeLayer = lyr
return activeDocument.activeLayer }
catch(e) { LogErr( 'SelectLayer: '+ e ) }
} // SelectLayer
function GetLayer( ptn ) { try {
if( ptn instanceof ArtLayer ) return ptn
var lyrs = activeDocument.layers
var l, len = lyrs.length || 0
for( l=0; l<len; l++ ) {
if( RegExp( ptn ).test( lyrs[l].name )) return lyrs[l] } }
catch(e) { LogErr( 'GetLayer: '+ e ) }
} // GetLayer
function IsSmartObj( lyr ) { return lyr.kind == LayerKind.SMARTOBJECT }
Following up on my earlier comment, I have implemented a solution that fills the textItem with characters so that the layer.bounds will match what the textItem width and height properties should be returning. We're using a lot of very small characters to keep it accurate, but there is a trade-off in performance, expecially when large textItem boxes with small fonts are encountered. So I implemented a loop to hopefully prevent too many characters being added in these cases, at the cost of a littl
...Copy link to clipboard
Copied
Okay, it looks like the textItem width & height properties are off based on existing transformations. I've done some digging on accessing the layer transformation data, and just to confirm... it's not actually available? If that's the case, the only workaround I can think of is to try and fill the box with characters and retrieve the bounds.
Copy link to clipboard
Copied
I posted a solution, but it has been flagged as spam (probably done automatically because it involves a large string of repeated characters). Hopefully we can get that reviewed and reinstated so that people can see the working code, but I'm not sure who to appeal to for this request.
Copy link to clipboard
Copied
Try again...
Copy link to clipboard
Copied
Deja vu
Copy link to clipboard
Copied
Let's see if I can post the content of your post (I recieved for my E-Mail):
"Here is a diffchecker composite of a textItem before and after being processed by the script. Magenta indicates pixels that changed. You can see the layer edges in blue did not move at all in this case. In larger text boxes, you might see it shift by a few pixels.
I should also note that I've commented out the call to RgbInList() because that relies on a swatches.csv file that I won't be sharing here."
var log = [] displayDialogs = DialogModes.NO ProcessUserText( activeDocument.activeLayer ) displayDialogs = DialogModes.ERROR alert( log.join('\n') ) function ProcessUserText( lyr ) { try { log.push( lyr.name ) var prev_units = SetUnits( 'pixels' ) var txt = lyr.textItem try { var jstn = txt.justification } catch(e) { throw lyr.name +': unable to access text justification' } txt.kind = TextType.PARAGRAPHTEXT var ang = TextAngle( lyr ) RotateLayer( -ang, lyr ) var box = TextBoxDimsWorkaround( lyr ) // fixes some broken textItem issues txt.kind = TextType.POINTTEXT var lyr2 = lyr.parent.artLayers.add() lyr2.kind = LayerKind.TEXT txt2 = lyr2.textItem txt2.contents = txt.contents txt2.font = txt.font // ps bug: https://community.adobe.com/t5/photoshop-ecosystem-discussions/read-font-size-with-script/td-p/10697934 txt2.size = txt.size TextSizeWorkaround( lyr2, lyr ) try { txt2.color = txt.color } catch(e) { txt2.color = TextColorFromSample( txt ) } var rgb = RoundTextRgb( txt2 ) // if( ! RgbInList( rgb ) ) log.push( 'text color '+ rgb +' not found in list' ) // else log.push( 'rgb found: '+ rgb ) txt2.useAutoLeading = true txt2.autoKerning = AutoKernType.MANUAL txt2.tracking = 0 txt2.verticalScale = 100 txt2.horizontalScale = 100 txt2.baselineShift = 0 txt2.justification = txt.justification log.push( 'jstn: '+ jstn ) txt2.kind = TextType.PARAGRAPHTEXT SetUnits( 'pixels' ) txt2.position = box.position var resFix = activeDocument.resolution / 72 txt2.width = box.width / resFix txt2.height = box.height / resFix var adjX = lyr.bounds[0] - lyr2.bounds[0] var adjY = lyr.bounds[1] - lyr2.bounds[1] log.push( 'adjustments: '+ [adjX,adjY] ) txt2.width += adjX / resFix txt2.height += adjY / resFix log.push( 'final w & h: ' + [txt2.width, txt2.height] ) RotateLayer( ang, lyr2 ) var n = lyr.name lyr2.move( lyr, ElementPlacement.PLACEBEFORE ) lyr.remove() lyr2.name = n var tstats = [ 'xy:'+ Number( txt2.position[0] ).toFixed(0) +','+ Number( txt2.position[1] ).toFixed(0), 'deg:'+ang, 'pt:'+Number( txt2.size ).toFixed(1), 'font:'+ txt2.font, 'rgb:'+ rgb, 'encoded:'+ encodeURI( txt2.contents ) ].join(' ') log.push( lyr2.name +' rebuilt ' + tstats ) SetUnits( prev_units ) return lyr2 } catch(e) { log.push( 'ProcessUserText '+ e ) } } // ProcessUserText function IsString( input ) { return typeof input === 'string' || input instanceof String } // IsString function EditAsSmartObject( lyr ) { ConvertSmartLayer( lyr ) runMenuItem( stID( 'placedLayerEditContents' ) ) return activeDocument.activeLayer } // EditAsSmartObject function ConvertSmartLayer( lyr ) { try { SelectLayer( lyr ) if( IsSmartObj( lyr )) return lyr var desc = new ActionDescriptor() desc.putInteger( chID( "DocI" ), 219 ) desc.putInteger( chID( "Idnt" ), 230 ) desc.putString( chID( "Nm " ), """Convert to Smart Object""" ) desc.putBoolean( stID( "hasEnglish" ), true ) desc.putInteger( chID( "ItmI" ), 3 ) executeAction( stID( "newPlacedLayer" ), undefined, DialogModes.NO ) lyr = activeDocument.activeLayer // layer is now a different object log.push( lyr.name +' converted to smart object' ) return lyr } catch(e) { log.push( 'ConvertSmaartLayer '+ e ) } } // ConvertSmartLayer function TextAngle( lyr ) { try { // Normalizes text copy to a period(.) and // uses baselineShift to create a vector var doc = activeDocument var prev_state = doc.activeHistoryState var angLyr = lyr.duplicate() var angTxt = angLyr.textItem angTxt.contents = '.' angTxt.font = 'MyriadPro-Regular' angTxt.size = 3 angTxt.baselineShift = 0 var soLyr1 = EditAsSmartObject( angLyr ) var soDoc = soLyr1.parent soDoc.resizeCanvas( 250, 250, AnchorPosition.MIDDLECENTER ) var soLyr2 = soLyr1.duplicate() soLyr2.textItem.baselineShift = 100 var ang = GetAngle( RoundEach( BdsMid( soLyr1 ) ), RoundEach( BdsMid( soLyr2 ) ) ) soDoc.close( SaveOptions.DONOTSAVECHANGES ) doc.activeHistoryState = prev_state log.push( lyr.name +' angle: '+ ang ) return ang } catch(e) { log.push( 'TextAngle '+ e ) } } // TextAngle function GetAngle( xy1, xy2 ) { var ang = 0 - Math.atan( ( xy1[0] - xy2[0] ) / ( xy1[1] - xy2[1] ) ) * 180.0 / Math.PI log.push( [xy1,xy2] +' angle: '+ ang ) return ang } // GetAngle function RoundEach( nums ) { var it = [] for( var i=0; i<nums.length; i++ ) { it[i] = Math.round( nums[i] ) } return it } // RoundEach function BdsMid( lyr ) { var b = lyr.bounds var mid = Midpoint( [ b[0], b[1] ], [ b[2], b[3] ] ) log.push( lyr.name +' midpoint: '+ mid ) return mid } // BdsMid function Midpoint( xy1, xy2 ) { return [ ( xy1[0] + xy2[0] ) / 2, ( xy1[1] + xy2[1] ) / 2 ] } // Midpoint function RotateLayer( deg, lyr ) { try { lyr = lyr || activeDocument.activeLayer if( deg && deg !== 0 ) { lyr.rotate( deg ) log.push( lyr.name +' rotated '+ deg ) } } catch(e) { log.push( 'RotateLayer '+ e ) } } // RotateLayer function TextSizeWorkaround( resizeLayer, targetLayer ) { try { var prev_units = SetUnits( 'points' ) var resizeTxt = resizeLayer.textItem var startSize = resizeTxt.size log.push( 'startSize: '+ startSize ) var delta0 = BdsH( targetLayer ) - BdsH( resizeLayer ) var limit = 5 while( limit-- && Math.abs( delta0 ) >= 1 ) { if( resizeTxt.size < 6 ) return resizeTxt.size = 6 var upDown = 1 if( delta0 < 0 ) { resizeTxt.size-- upDown = -1 delta0 = Math.abs( delta0 ) } else resizeTxt.size++ log.push( 'delta0: '+ delta0 ) log.push( 'upDown: '+ upDown ) var delta1 = Math.abs( BdsH( targetLayer ) - BdsH( resizeLayer ) ) log.push( 'delta1: '+ delta1 ) var remainingDelta = upDown * delta1 /( delta0 - delta1 ) log.push( 'remainingDelta: '+ remainingDelta ) resizeTxt.size = Math.round( resizeTxt.size + remainingDelta ) log.push( 'resizeTxt.size: '+ resizeTxt.size ) delta0 = BdsH( targetLayer ) - BdsH( resizeLayer ) } SetUnits( prev_units ) return resizeTxt.size } catch(e) { log.push( 'TextSizeWorkaround '+ e ) } } // TextSizeWorkaround function BdsTL( bdsOrLyr ) { if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds return [ bdsOrLyr[0], bdsOrLyr[1] ] } // BdsTL function BdsH( bdsOrLyr ) { if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds return Math.abs( bdsOrLyr[1] - bdsOrLyr[3] ) } // BdsH function BdsW( bdsOrLyr ) { if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds return Math.abs( bdsOrLyr[0] - bdsOrLyr[2] ) } // BdsW function chID( a ) { return charIDToTypeID( a )} function stID( a ) { return stringIDToTypeID( a )} function SelectLayer( lyr ) { try { if( typeof lyr === 'string' || lyr instanceof String ) lyr = GetLayer( lyr ) activeDocument.activeLayer = lyr return activeDocument.activeLayer } catch(e) { log.push( 'SelectLayer: '+ e ) } } // SelectLayer function GetLayer( ptn ) { try { if( ptn instanceof ArtLayer ) return ptn var lyrs = activeDocument.layers var l, len = lyrs.length || 0 for( l=0; l<len; l++ ) { if( RegExp( ptn ).test( lyrs[l].name )) return lyrs[l] } } catch(e) { log.push( 'GetLayer: '+ e ) } } // GetLayer function IsSmartObj( lyr ) { return lyr.kind == LayerKind.SMARTOBJECT } function TextBoxDimsWorkaround( lyr ) { try { // ps bug: textItem width & height distorted by previous transformations // workaround fills area with text so that layer bounds matches textbox w & h var prev_state = activeDocument.activeHistoryState SetUnits( 'pixels' ) lyr.textItem.kind = TextType.PARAGRAPHTEXT var dup = lyr.duplicate() var duptxt = dup.textItem // set font size to 10% of capital character height // 1 pt would be the most accurate, but it's very cpu intensive // converting for resolution because txt.width & height are always in pts var dup2 = lyr.duplicate() dup2.textItem.contents = 'X' var bH = BdsH( dup2 ) * 72 / activeDocument.resolution duptxt.size = UnitValue( Math.max( 3, bH / 10 ), 'pt' ) log.push( 'size: '+ duptxt.size ) duptxt.useAutoLeading = true duptxt.autoLeadingAmount = 100 duptxt.font = 'MyriadPro-Regular' duptxt.baselineShift = 0 duptxt.fauxBold = false duptxt.fauxItalic = false duptxt.firstLineIndent = 0 duptxt.horizontalScale = 100 duptxt.verticalScale = 100 duptxt.contents = TextFiller() // for large textboxes that need more fill, we double it until it overflows // limit to 3 times because more can cause processing issues // we also 2x font size to lower cycles, at slight cost of accuracy var i = 0 while( i < 3 && TextOverflow( dup ) < 1 ) { if( i++ ) duptxt.size = UnitValue( duptxt.size.value * 2, 'pt' ) log.push( 'size: '+ duptxt.size ) duptxt.kind = TextType.PARAGRAPHTEXT duptxt.contents = duptxt.contents + duptxt.contents } // we can now use bounds as height & width because the box is filled // position is the text baseline origin var dims = { position: lyr.textItem.position, width: dup.bounds[2] - dup.bounds[0] - 1, height: dup.bounds[3] - dup.bounds[1] } // undo the mess we made because we now have our data activeDocument.activeHistoryState = prev_state log.push( 'dims.position: '+ dims.position ) log.push( 'dims.width: '+ dims.width ) log.push( 'dims.height: '+ dims.height ) return dims } catch(e) { log.push( 'TextBoxDimsWorkaround '+ e ) } } // TextBoxDimsWorkaround function TextOverflow( lyr ) { try { var prev_state = activeDocument.activeHistoryState var dup = lyr.duplicate() dup.textItem.kind = TextType.POINTTEXT var overlen = lyr.textItem.contents.length - dup.textItem.contents.length activeDocument.activeHistoryState = prev_state return overlen } catch(e) { log.push( 'TextOverflow '+ e ) } } // TextOverflow function SetUnits( input ) { try { var rUnit, tUnit if( input instanceof Object ) { rUnit = input.ruler tUnit = input.type } else if( IsString( input ) ) rUnit = tUnit = input var prev_units = { ruler: preferences.rulerUnits, type: preferences.typeUnits } switch( rUnit ) { case 'points': case 'pt': preferences.rulerUnits = Units.POINTS break; case 'inches': case 'in': preferences.rulerUnits = Units.INCHES break; case 'centimeters': case 'cm': preferences.rulerUnits = Units.CENTIMETERS break; default: preferences.rulerUnits = Units.PIXELS break } switch( tUnit ) { case 'pixels': case 'px': preferences.typeUnits = TypeUnits.PIXELS break; case 'inches': case 'in': preferences.typeUnits = TypeUnits.INCHES break; case 'centimeters': case 'cm': preferences.typeUnits = TypeUnits.CENTIMETERS break; default: preferences.typeUnits = TypeUnits.POINTS break } log.push( 'SetUnits: '+ preferences.rulerUnits +', '+ preferences.typeUnits ) return prev_units } catch(e) { log.push( 'SetUnits '+ e ) } } // SetUnits function RoundTextRgb( text ) { try { var rgb = text.color.rgb rgb.red = Math.round( Number( rgb.red ) ) rgb.green = Math.round( Number( rgb.green ) ) rgb.blue = Math.round( Number( rgb.blue ) ) return [ rgb.red, rgb.green, rgb.blue ] } catch(e) { log.push( 'RoundTextRgb '+ e ) } } // RoundTextRgb function RgbInList( rgb ) { var inList = false var r = rgb[0], g = rgb[1], b = rgb[2] var limit = 5000, loop = 0, freq = 1000, start = new Date() // csv is sorted ascending by R, then G, then B var csv = File( File($.fileName).parent +'/swatches.csv' ) csv.open( 'r' ); try { var ln = csv.readln() ln = csv.readln() // skip header while( ln != 'end' && ! csv.eof && loop < limit ) { if( ++loop % freq == 0 && new Date() - start >= limit ) throw 'timed out' var rgb2 = ln.split( ',' ) ln = csv.readln() var r2 = Number( rgb2[0] ) if( r < r2 ) break; if( r > r2 ) continue; if( r == r2 ) { var g2 = Number( rgb2[1] ) if( g < g2 ) break; if( g > g2 ) continue; if( g == g2 ) { var b2 = Number( rgb2[2] ) if( b < b2 ) break; if( b > b2 ) continue; if( b == b2 ) inList = true; break; } } } } catch(e) {log.push( 'RgbInList '+ e )} csv.close() return inList } // RgbInList function FormatColor( color ) { try { switch( color.model ) { case ColorModel.GRAYSCALE: return color.gray.gray.toFixed(0) +'% gray' case ColorModel.RGB: return 'rgb '+ [ color.rgb.red.toFixed(0), color.rgb.green.toFixed(0), color.rgb.blue.toFixed(0) ] +' #'+ color.rgb.hexValue case ColorModel.NONE: case undefined: return 'none (full transparency)' default: return color.model +' needs support' } } catch(e) { log.push( 'FormatColor '+ e ) } } // FormatColor function TextFiller() { // can't believe we have to do this for TextBoxDimsWorkaround // performance is better with large fill and fewer cycles return '||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||' } // TextFiller
Copy link to clipboard
Copied
Following up on my earlier comment, I have implemented a solution that fills the textItem with characters so that the layer.bounds will match what the textItem width and height properties should be returning. We're using a lot of very small characters to keep it accurate, but there is a trade-off in performance, expecially when large textItem boxes with small fonts are encountered. So I implemented a loop to hopefully prevent too many characters being added in these cases, at the cost of a little bit of accuracy.
Here is a diffchecker composite of a textItem before and after being processed by the script. Magenta indicates pixels that changed. You can see the layer edges in blue did not move at all in this case. In larger text boxes, you might see it shift by a few pixels.
I should also note that I've commented out the call to RgbInList() because that relies on a swatches.csv file that I won't be sharing here.
var log = []
displayDialogs = DialogModes.NO
ProcessUserText( activeDocument.activeLayer )
displayDialogs = DialogModes.ERROR
alert( log.join('\n') )
function ProcessUserText( lyr ) { try {
log.push( lyr.name )
var prev_units = SetUnits( 'pixels' )
var txt = lyr.textItem
try { var jstn = txt.justification }
catch(e) { throw lyr.name +': unable to access text justification' }
txt.kind = TextType.PARAGRAPHTEXT
var ang = TextAngle( lyr )
RotateLayer( -ang, lyr )
var box = TextBoxDimsWorkaround( lyr )
// fixes some broken textItem issues
txt.kind = TextType.POINTTEXT
var lyr2 = lyr.parent.artLayers.add()
lyr2.kind = LayerKind.TEXT
txt2 = lyr2.textItem
txt2.contents = txt.contents
txt2.font = txt.font
// ps bug: https://community.adobe.com/t5/photoshop-ecosystem-discussions/read-font-size-with-script/td-p/10697934
txt2.size = txt.size
TextSizeWorkaround( lyr2, lyr )
try { txt2.color = txt.color }
catch(e) { txt2.color = TextColorFromSample( txt ) }
var rgb = RoundTextRgb( txt2 )
// if( ! RgbInList( rgb ) ) log.push( 'text color '+ rgb +' not found in list' )
// else log.push( 'rgb found: '+ rgb )
txt2.useAutoLeading = true
txt2.autoKerning = AutoKernType.MANUAL
txt2.tracking = 0
txt2.verticalScale = 100
txt2.horizontalScale = 100
txt2.baselineShift = 0
txt2.justification = txt.justification
log.push( 'jstn: '+ jstn )
txt2.kind = TextType.PARAGRAPHTEXT
SetUnits( 'pixels' )
txt2.position = box.position
var resFix = activeDocument.resolution / 72
txt2.width = box.width / resFix
txt2.height = box.height / resFix
var adjX = lyr.bounds[0] - lyr2.bounds[0]
var adjY = lyr.bounds[1] - lyr2.bounds[1]
log.push( 'adjustments: '+ [adjX,adjY] )
txt2.width += adjX / resFix
txt2.height += adjY / resFix
log.push( 'final w & h: ' + [txt2.width, txt2.height] )
RotateLayer( ang, lyr2 )
var n = lyr.name
lyr2.move( lyr, ElementPlacement.PLACEBEFORE )
lyr.remove()
lyr2.name = n
var tstats = [
'xy:'+ Number( txt2.position[0] ).toFixed(0)
+','+ Number( txt2.position[1] ).toFixed(0),
'deg:'+ang,
'pt:'+Number( txt2.size ).toFixed(1),
'font:'+ txt2.font,
'rgb:'+ rgb,
'encoded:'+ encodeURI( txt2.contents )
].join(' ')
log.push( lyr2.name +' rebuilt ' + tstats )
SetUnits( prev_units )
return lyr2
}
catch(e) { log.push( 'ProcessUserText '+ e ) }
} // ProcessUserText
function IsString( input ) {
return typeof input === 'string' || input instanceof String
} // IsString
function EditAsSmartObject( lyr ) {
ConvertSmartLayer( lyr )
runMenuItem( stID( 'placedLayerEditContents' ) )
return activeDocument.activeLayer
} // EditAsSmartObject
function ConvertSmartLayer( lyr ) { try {
SelectLayer( lyr )
if( IsSmartObj( lyr )) return lyr
var desc = new ActionDescriptor()
desc.putInteger( chID( "DocI" ), 219 )
desc.putInteger( chID( "Idnt" ), 230 )
desc.putString( chID( "Nm " ), """Convert to Smart Object""" )
desc.putBoolean( stID( "hasEnglish" ), true )
desc.putInteger( chID( "ItmI" ), 3 )
executeAction( stID( "newPlacedLayer" ), undefined, DialogModes.NO )
lyr = activeDocument.activeLayer // layer is now a different object
log.push( lyr.name +' converted to smart object' )
return lyr }
catch(e) { log.push( 'ConvertSmaartLayer '+ e ) }
} // ConvertSmartLayer
function TextAngle( lyr ) { try {
// Normalizes text copy to a period(.) and
// uses baselineShift to create a vector
var doc = activeDocument
var prev_state = doc.activeHistoryState
var angLyr = lyr.duplicate()
var angTxt = angLyr.textItem
angTxt.contents = '.'
angTxt.font = 'MyriadPro-Regular'
angTxt.size = 3
angTxt.baselineShift = 0
var soLyr1 = EditAsSmartObject( angLyr )
var soDoc = soLyr1.parent
soDoc.resizeCanvas( 250, 250, AnchorPosition.MIDDLECENTER )
var soLyr2 = soLyr1.duplicate()
soLyr2.textItem.baselineShift = 100
var ang = GetAngle(
RoundEach( BdsMid( soLyr1 ) ),
RoundEach( BdsMid( soLyr2 ) ) )
soDoc.close( SaveOptions.DONOTSAVECHANGES )
doc.activeHistoryState = prev_state
log.push( lyr.name +' angle: '+ ang )
return ang }
catch(e) { log.push( 'TextAngle '+ e ) }
} // TextAngle
function GetAngle( xy1, xy2 ) {
var ang = 0 - Math.atan( ( xy1[0] - xy2[0] ) / ( xy1[1] - xy2[1] ) ) * 180.0 / Math.PI
log.push( [xy1,xy2] +' angle: '+ ang )
return ang
} // GetAngle
function RoundEach( nums ) {
var it = []
for( var i=0; i<nums.length; i++ ) {
it[i] = Math.round( nums[i] ) }
return it
} // RoundEach
function BdsMid( lyr ) {
var b = lyr.bounds
var mid = Midpoint( [ b[0], b[1] ], [ b[2], b[3] ] )
log.push( lyr.name +' midpoint: '+ mid )
return mid
} // BdsMid
function Midpoint( xy1, xy2 ) {
return [ ( xy1[0] + xy2[0] ) / 2, ( xy1[1] + xy2[1] ) / 2 ]
} // Midpoint
function RotateLayer( deg, lyr ) { try {
lyr = lyr || activeDocument.activeLayer
if( deg && deg !== 0 ) {
lyr.rotate( deg )
log.push( lyr.name +' rotated '+ deg ) } }
catch(e) { log.push( 'RotateLayer '+ e ) }
} // RotateLayer
function TextSizeWorkaround( resizeLayer, targetLayer ) { try {
var prev_units = SetUnits( 'points' )
var resizeTxt = resizeLayer.textItem
var startSize = resizeTxt.size
log.push( 'startSize: '+ startSize )
var delta0 = BdsH( targetLayer ) - BdsH( resizeLayer )
var limit = 5
while( limit-- && Math.abs( delta0 ) >= 1 ) {
if( resizeTxt.size < 6 ) return resizeTxt.size = 6
var upDown = 1
if( delta0 < 0 ) {
resizeTxt.size--
upDown = -1
delta0 = Math.abs( delta0 ) }
else resizeTxt.size++
log.push( 'delta0: '+ delta0 )
log.push( 'upDown: '+ upDown )
var delta1 = Math.abs( BdsH( targetLayer ) - BdsH( resizeLayer ) )
log.push( 'delta1: '+ delta1 )
var remainingDelta = upDown * delta1 /( delta0 - delta1 )
log.push( 'remainingDelta: '+ remainingDelta )
resizeTxt.size = Math.round( resizeTxt.size + remainingDelta )
log.push( 'resizeTxt.size: '+ resizeTxt.size )
delta0 = BdsH( targetLayer ) - BdsH( resizeLayer ) }
SetUnits( prev_units )
return resizeTxt.size }
catch(e) { log.push( 'TextSizeWorkaround '+ e ) }
} // TextSizeWorkaround
function BdsTL( bdsOrLyr ) {
if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds
return [ bdsOrLyr[0], bdsOrLyr[1] ]
} // BdsTL
function BdsH( bdsOrLyr ) {
if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds
return Math.abs( bdsOrLyr[1] - bdsOrLyr[3] )
} // BdsH
function BdsW( bdsOrLyr ) {
if( bdsOrLyr instanceof ArtLayer ) bdsOrLyr = bdsOrLyr.bounds
return Math.abs( bdsOrLyr[0] - bdsOrLyr[2] )
} // BdsW
function chID( a ) { return charIDToTypeID( a )}
function stID( a ) { return stringIDToTypeID( a )}
function SelectLayer( lyr ) { try {
if( typeof lyr === 'string' || lyr instanceof String ) lyr = GetLayer( lyr )
activeDocument.activeLayer = lyr
return activeDocument.activeLayer }
catch(e) { log.push( 'SelectLayer: '+ e ) }
} // SelectLayer
function GetLayer( ptn ) { try {
if( ptn instanceof ArtLayer ) return ptn
var lyrs = activeDocument.layers
var l, len = lyrs.length || 0
for( l=0; l<len; l++ ) {
if( RegExp( ptn ).test( lyrs[l].name )) return lyrs[l] } }
catch(e) { log.push( 'GetLayer: '+ e ) }
} // GetLayer
function IsSmartObj( lyr ) { return lyr.kind == LayerKind.SMARTOBJECT }
function TextBoxDimsWorkaround( lyr ) { try {
// ps bug: textItem width & height distorted by previous transformations
// workaround fills area with text so that layer bounds matches textbox w & h
var prev_state = activeDocument.activeHistoryState
SetUnits( 'pixels' )
lyr.textItem.kind = TextType.PARAGRAPHTEXT
var dup = lyr.duplicate()
var duptxt = dup.textItem
// set font size to 10% of capital character height
// 1 pt would be the most accurate, but it's very cpu intensive
// converting for resolution because txt.width & height are always in pts
var dup2 = lyr.duplicate()
dup2.textItem.contents = 'X'
var bH = BdsH( dup2 ) * 72 / activeDocument.resolution
duptxt.size = UnitValue( Math.max( 3, bH / 10 ), 'pt' )
log.push( 'size: '+ duptxt.size )
duptxt.useAutoLeading = true
duptxt.autoLeadingAmount = 100
duptxt.font = 'MyriadPro-Regular'
duptxt.baselineShift = 0
duptxt.fauxBold = false
duptxt.fauxItalic = false
duptxt.firstLineIndent = 0
duptxt.horizontalScale = 100
duptxt.verticalScale = 100
duptxt.contents = TextFiller()
// for large textboxes that need more fill, we double it until it overflows
// limit to 3 times because more can cause processing issues
// we also 2x font size to lower cycles, at slight cost of accuracy
var i = 0
while( i < 3 && TextOverflow( dup ) < 1 ) {
if( i++ ) duptxt.size = UnitValue( duptxt.size.value * 2, 'pt' )
log.push( 'size: '+ duptxt.size )
duptxt.kind = TextType.PARAGRAPHTEXT
duptxt.contents = duptxt.contents + duptxt.contents }
// we can now use bounds as height & width because the box is filled
// position is the text baseline origin
var dims = { position: lyr.textItem.position,
width: dup.bounds[2] - dup.bounds[0] - 1,
height: dup.bounds[3] - dup.bounds[1] }
// undo the mess we made because we now have our data
activeDocument.activeHistoryState = prev_state
log.push( 'dims.position: '+ dims.position )
log.push( 'dims.width: '+ dims.width )
log.push( 'dims.height: '+ dims.height )
return dims }
catch(e) { log.push( 'TextBoxDimsWorkaround '+ e ) }
} // TextBoxDimsWorkaround
function TextOverflow( lyr ) { try {
var prev_state = activeDocument.activeHistoryState
var dup = lyr.duplicate()
dup.textItem.kind = TextType.POINTTEXT
var overlen = lyr.textItem.contents.length - dup.textItem.contents.length
activeDocument.activeHistoryState = prev_state
return overlen }
catch(e) { log.push( 'TextOverflow '+ e ) }
} // TextOverflow
function SetUnits( input ) { try {
var rUnit, tUnit
if( input instanceof Object ) {
rUnit = input.ruler
tUnit = input.type }
else if( IsString( input ) )
rUnit = tUnit = input
var prev_units = { ruler: preferences.rulerUnits,
type: preferences.typeUnits }
switch( rUnit ) {
case 'points': case 'pt':
preferences.rulerUnits = Units.POINTS
break;
case 'inches': case 'in':
preferences.rulerUnits = Units.INCHES
break;
case 'centimeters': case 'cm':
preferences.rulerUnits = Units.CENTIMETERS
break;
default:
preferences.rulerUnits = Units.PIXELS
break }
switch( tUnit ) {
case 'pixels': case 'px':
preferences.typeUnits = TypeUnits.PIXELS
break;
case 'inches': case 'in':
preferences.typeUnits = TypeUnits.INCHES
break;
case 'centimeters': case 'cm':
preferences.typeUnits = TypeUnits.CENTIMETERS
break;
default:
preferences.typeUnits = TypeUnits.POINTS
break }
log.push( 'SetUnits: '+ preferences.rulerUnits +', '+ preferences.typeUnits )
return prev_units }
catch(e) { log.push( 'SetUnits '+ e ) }
} // SetUnits
function RoundTextRgb( text ) { try {
var rgb = text.color.rgb
rgb.red = Math.round( Number( rgb.red ) )
rgb.green = Math.round( Number( rgb.green ) )
rgb.blue = Math.round( Number( rgb.blue ) )
return [ rgb.red, rgb.green, rgb.blue ] }
catch(e) { log.push( 'RoundTextRgb '+ e ) }
} // RoundTextRgb
function RgbInList( rgb ) {
var inList = false
var r = rgb[0], g = rgb[1], b = rgb[2]
var limit = 5000, loop = 0, freq = 1000, start = new Date()
// csv is sorted ascending by R, then G, then B
var csv = File( File($.fileName).parent +'/swatches.csv' )
csv.open( 'r' ); try {
var ln = csv.readln()
ln = csv.readln() // skip header
while( ln != 'end' && ! csv.eof && loop < limit ) {
if( ++loop % freq == 0 && new Date() - start >= limit )
throw 'timed out'
var rgb2 = ln.split( ',' )
ln = csv.readln()
var r2 = Number( rgb2[0] )
if( r < r2 ) break;
if( r > r2 ) continue;
if( r == r2 ) {
var g2 = Number( rgb2[1] )
if( g < g2 ) break;
if( g > g2 ) continue;
if( g == g2 ) {
var b2 = Number( rgb2[2] )
if( b < b2 ) break;
if( b > b2 ) continue;
if( b == b2 ) inList = true; break; } } } }
catch(e) {log.push( 'RgbInList '+ e )}
csv.close()
return inList
} // RgbInList
function FormatColor( color ) { try {
switch( color.model ) {
case ColorModel.GRAYSCALE:
return color.gray.gray.toFixed(0) +'% gray'
case ColorModel.RGB:
return 'rgb '+ [
color.rgb.red.toFixed(0),
color.rgb.green.toFixed(0),
color.rgb.blue.toFixed(0) ]
+' #'+ color.rgb.hexValue
case ColorModel.NONE:
case undefined:
return 'none (full transparency)'
default:
return color.model +' needs support' } }
catch(e) { log.push( 'FormatColor '+ e ) }
} // FormatColor
function TextFiller() {
// can't believe we have to do this for TextBoxDimsWorkaround
// performance is better with large fill and fewer cycles
return '||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||'
} // TextFiller