• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Get selection Bounds (text bounds (be outline))

Explorer ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

Please, could you help me build a code?

I am trying to get bounds from the selection (visiblebounds) but with the peculiarity of that of the text bounds (be outlines).

This code works only in groups that are not masked. Could you help correct it please?

Or do you know a better code?

function getBounds(obj) {

    var selObj1 = new Array();

    var selObj2 = new Array();

    var vgb1 = new Array();

    var vgb2 = new Array();

    var n = obj.length;

    if (n > 0) {

        // ignore worst case of (1) type on path or (2) guide items

        if ((obj[0].guides == true)) {

            // do nothing

        } else {

            if (obj[0].typename == 'TextFrame') {

                //alert("1 - obj.typename=TextFrame")

                objcopy = obj[0].duplicate().createOutline();

                vgb1 = objcopy.visibleBounds;

                objcopy.remove();

            }

            // group items that are masked case

            else if ((obj[0].typename == 'GroupItem') && obj[0].clipped && (obj[0].pageItems.length > 1)) {

                clipObj = obj[0].pathItems[0].visibleBounds;

                vgb1 = clipObj;

            } else {

                selObj1 = obj[0];

                vgb1 = selObj1.visibleBounds;

            }

            /* } else {

            vgb1 = new Array;

            vgb1[0] = vgb1[1] = vgb1[2] = vgb1[3] = null;

            */

        }

        // loose page items case

        if (n > 1) {

            for (i = 1; i < n; i++) {

                selObj2 = obj;

                // do a test here for the path type (ignore it, break to next object)

                /*if( (obj.guides) ){

                continue;

                }*/

                // do a test here for the guides type (ignore it, break to next object)

                if ((obj.guides == true)) {

                    // do nothing

                } else {

                    if (obj.typename == 'TextFrame') {

                        //alert("1 - obj.typename=TextFrame")

                        objcopy = obj.duplicate().createOutline();

                        vgb2 = objcopy.visibleBounds;

                        objcopy.remove();

                    }

                    // layer clipping mask case

                    else if ((obj.typename == 'PathItem') && (obj.clipping)) {

                        clipObj = obj.geometricBounds;

                        vgb2 = clipObj;

                        return vgb2;

                    }

                    if ((obj.typename == 'GroupItem') && obj.clipped && (obj.pageItems.length > 1)) {

                        vgb2 = obj.pathItems[0].visibleBounds;

                    } else {

                        vgb2 = selObj2.visibleBounds;

                    }

                    if (vgb1[0] > vgb2[0]) vgb1[0] = vgb2[0];

                    if (vgb1[1] < vgb2[1]) vgb1[1] = vgb2[1];

                    if (vgb1[2] < vgb2[2]) vgb1[2] = vgb2[2];

                    if (vgb1[3] > vgb2[3]) vgb1[3] = vgb2[3];

                }

            }

        }

    }

    return vgb1;

}

Thank you very much.

Greetings.

TOPICS
Scripting

Views

1.7K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Engaged ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

Hi, levi23​!

Here it seems to be what you need:

//@target illustrator

getMaxCollectionBnds(selection, 'geometricBounds');

/**

* get maximum bounds of the collection of the elements or one element

*

* @param {Array/PageItem} collection

* @param {String} boundsType - geometricBounds or visibleBounds

* @return {Array} bounds - array af the maximal bounds of the entire colleciton or element

* */

function getMaxCollectionBnds(collection, boundsType) {

  var bndsType = boundsType || 'geometricBounds';

  var bounds   = _getMaxBnds(collection, []);

  return bounds;

  /**

   * recursive search maximum bounds

   *

   * @param {Object} collection - selection, PageItems or PageItem

   * @param {Array} bounds - last maximal bounds

   * @return {Array} bounds - maximal bound

   * */

  function _getMaxBnds(collection, bounds) {

    var bnds = bounds;

    // case then passed one item rather then true collection

    if (collection.typename == 'PathItem' ||

      collection.typename == 'CompoundPathItem' ||

      collection.typename == 'TextFrame') {

      return _cmprBnds(collection, bnds);

    }

    for (var j = 0; j < collection.length; j++) {

      var el = collection ;

      // anything PageItem exclude GroupItem

      if (el.typename != 'GroupItem') {

        if (bnds == '') {

          bnds = _getElemBnds(el);

          continue;

        }

        bnds = _cmprBnds(el, bnds);

      }

      // group contains a mask -> search this mask

      if (el.typename == 'GroupItem' && el.clipped) {

        var groupPaths = el.pathItems;

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

          if (groupPaths.clipping) {

            if (bnds == '') {

              bnds = _getElemBnds(groupPaths);

              continue;

            }

            bnds = _cmprBnds(groupPaths, bnds);

          }

        }

      }

      // group contains no a mask and a groups

      if (el.typename == 'GroupItem' && !el.clipped && !el.groupItems) {

        if (bnds == '') {

          bnds = _getElemBnds(el);

          continue;

        }

        bnds = _cmprBnds(el[bndsType], bnds);

      }

      // group contains no a mask, but contains a groups -> recurse

      if (el.typename == 'GroupItem' && !el.clipped && el.groupItems) {

        bnds = _getMaxBnds(el.pageItems, bnds);

        continue;

      }

    }

    return bnds;

  }

  /**

   * comparing the geometricBounds of two PageItems

   *

   * @param {PageItem} elem - the object of Illustrator DOM PageItem class

   * @param {Array} boundsToCompare

   * @return {Array} [left, top, right, bottom]

   * */

  function _cmprBnds(elem, bndsToCompare) {

    var elemBnds = _getElemBnds(elem);

    return [

      Math.min(elemBnds[0], bndsToCompare[0]),

      Math.max(elemBnds[1], bndsToCompare[1]),

      Math.max(elemBnds[2], bndsToCompare[2]),

      Math.min(elemBnds[3], bndsToCompare[3])

    ]

  }

  /**

   * get the bounds of one element

   *

   * @param {PageItem} elem - object of PageItem of Illustrator DOM class

   * @return {Array} elemBnds - element bounds

   * */

  function _getElemBnds(elem) {

    var elemBnds;

    if (elem.typename == 'TextFrame') {

      var elemCurvedCopy = elem.duplicate().createOutline();

      elemBnds           = elemCurvedCopy[bndsType];

      elemCurvedCopy.remove();

    } else {

      elemBnds = elem[bndsType];

    }

    return elemBnds;

  }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

This is great code, and for smart, intelligent, individuals it will be a great method to get the bounds of clipped text objects.

However, for those who want to take the easy way out and 'cheat' (provided, CS6+ is used), the following will suffice after a grouped copy has been made of all the items needed:

app.executeMenuCommand("outline");

app.executeMenuCommand("Live Pathfinder Trim");

app.executeMenuCommand("expandStyle");

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 18, 2016 Nov 18, 2016

Copy link to clipboard

Copied

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 30, 2016 Nov 30, 2016

Copy link to clipboard

Copied

Excuse a question. How does the code work without selections?

  * @param {Object} collection - selection, PageItems or PageItem

With selection it works perfectly, but if concrete an PathItem  returns

NaN, NaN, NaN, NaN

sel = activeDocument.selection;

getMaxCollectionBnds(sel[0], 'geometricBounds');//retun  NaN, NaN, NaN, NaN

Any help please?

Supposedly it works with ...  *  PageItems or PageItem

How?

Thanks in advance.

Regards

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Nov 30, 2016 Nov 30, 2016

Copy link to clipboard

Copied

fixed:

getMaxCollectionBnds(selection[0], 'geometricBounds');

function getMaxCollectionBnds(collection, boundsType) {

  var bndsType = boundsType || 'geometricBounds';

  var bounds   = _getMaxBnds(collection, []);

  return bounds;

  function _getMaxBnds(collection, bounds) {

    var bnds = bounds;

    // case then passed one item rather then true collection

    try {

      var oneElemBnds = collection[boundsType];

      if (oneElemBnds[0]) {

        return oneElemBnds;

      }

    } catch (e) {

    }

    for (var j = 0; j < collection.length; j++) {

      var el = collection ;

      // anything PageItem exclude GroupItem

      if (el.typename != 'GroupItem') {

        if (bnds == '') {

          bnds = _getElemBnds(el);

          continue;

        }

        bnds = _cmprBnds(el, bnds);

      }

      // group contains a mask -> search this mask

      if (el.typename == 'GroupItem' && el.clipped) {

        var groupPaths = el.pathItems;

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

          if (groupPaths.clipping) {

            if (bnds == '') {

              bnds = _getElemBnds(groupPaths);

              continue;

            }

            bnds = _cmprBnds(groupPaths, bnds);

          }

        }

      }

      // group contains no a mask and a groups

      if (el.typename == 'GroupItem' && !el.clipped && !el.groupItems) {

        if (bnds == '') {

          bnds = _getElemBnds(el);

          continue;

        }

        bnds = _cmprBnds(el[bndsType], bnds);

      }

      // group contains no a mask, but contains a groups -> recurse

      if (el.typename == 'GroupItem' && !el.clipped && el.groupItems) {

        bnds = _getMaxBnds(el.pageItems, bnds);

        continue;

      }

    }

    return bnds;

  }

  function _cmprBnds(elem, bndsToCompare) {

    var elemBnds = _getElemBnds(elem);

    return [

      Math.min(elemBnds[0], bndsToCompare[0]),

      Math.max(elemBnds[1], bndsToCompare[1]),

      Math.max(elemBnds[2], bndsToCompare[2]),

      Math.min(elemBnds[3], bndsToCompare[3])

    ]

  }

  function _getElemBnds(elem) {

    var elemBnds;

    if (elem.typename == 'TextFrame') {

      var elemCurvedCopy = elem.duplicate().createOutline();

      elemBnds           = elemCurvedCopy[bndsType];

      elemCurvedCopy.remove();

    } else {

      elemBnds = elem[bndsType];

    }

    return elemBnds;

  }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Dec 01, 2016 Dec 01, 2016

Copy link to clipboard

Copied

It works. Thank you very much for your help.

Greetings.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Dec 01, 2016 Dec 01, 2016

Copy link to clipboard

Copied

Thank you for helping to find a bug! 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 27, 2017 Mar 27, 2017

Copy link to clipboard

Copied

Sorry again but I found another bug.

When the code is applied on a clipmask, and the content is larger than the mask. The resulting bounds (visibleBounds) do not return the measures of the mask. (Include parts of clipped paths)

Someone help me to solve it ?. Many thanks.

Sorry for bothering you.

A greeting.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Nov 19, 2016 Nov 19, 2016

Copy link to clipboard

Copied

Many thanks. The code is perfect

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Mar 28, 2017 Mar 28, 2017

Copy link to clipboard

Copied

LATEST

I show you the Bug that I detected

If you try the code on a clipmask in which the content is greater than the mask you can verify that the code is malfunctioning.

function getMaxCollectionBnds(collection, boundsType) { 

  var bndsType = boundsType || 'geometricBounds'; 

  var bounds   = _getMaxBnds(collection, []); 

  return bounds; 

  function _getMaxBnds(collection, bounds) { 

    var bnds = bounds; 

    // case then passed one item rather then true collection 

    try { 

      var oneElemBnds = collection[boundsType]; 

      if (oneElemBnds[0]) { 

        return oneElemBnds; 

      } 

    } catch (e) { 

    } 

    for (var j = 0; j < collection.length; j++) { 

      var el = collection

      // anything PageItem exclude GroupItem 

      if (el.typename != 'GroupItem') { 

        if (bnds == '') { 

          bnds = _getElemBnds(el); 

          continue; 

        } 

        bnds = _cmprBnds(el, bnds); 

      } 

      // group contains a mask -> search this mask 

      if (el.typename == 'GroupItem' && el.clipped) { 

        var groupPaths = el.pathItems; 

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

          if (groupPaths.clipping) { 

            if (bnds == '') { 

              bnds = _getElemBnds(groupPaths); 

              continue; 

            } 

            bnds = _cmprBnds(groupPaths, bnds); 

          } 

        } 

      } 

      // group contains no a mask and a groups 

      if (el.typename == 'GroupItem' && !el.clipped && !el.groupItems) { 

        if (bnds == '') { 

          bnds = _getElemBnds(el); 

          continue; 

        } 

        bnds = _cmprBnds(el[bndsType], bnds); 

      } 

      // group contains no a mask, but contains a groups -> recurse 

      if (el.typename == 'GroupItem' && !el.clipped && el.groupItems) { 

        bnds = _getMaxBnds(el.pageItems, bnds); 

        continue; 

      } 

    } 

    return bnds; 

  } 

  function _cmprBnds(elem, bndsToCompare) { 

    var elemBnds = _getElemBnds(elem); 

    return [ 

      Math.min(elemBnds[0], bndsToCompare[0]), 

      Math.max(elemBnds[1], bndsToCompare[1]), 

      Math.max(elemBnds[2], bndsToCompare[2]), 

      Math.min(elemBnds[3], bndsToCompare[3]) 

    ] 

  } 

  function _getElemBnds(elem) { 

    var elemBnds; 

    if (elem.typename == 'TextFrame') { 

      var elemCurvedCopy = elem.duplicate().createOutline(); 

      elemBnds           = elemCurvedCopy[bndsType]; 

      elemCurvedCopy.remove(); 

    } else { 

      elemBnds = elem[bndsType]; 

    } 

    return elemBnds; 

  } 

var doc = app.activeDocument;

sel = activeDocument.selection;

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

    IntersectArtboardIndx = []

    obj = sel

    Bounds=getMaxCollectionBnds(obj, 'visibleBounds')

    var rect = doc.pathItems.rectangle(Bounds[1], Bounds[0], (Bounds[2] - Bounds[0]), (Bounds[1] - Bounds[3]));

}

If we change this line: [obj] instead of obj

Bounds = getMaxCollectionBnds ([obj], 'visibleBounds')

The code seems to work correctly.

Could you please help me correct it?

Thank you very much in advance

Regards

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines