10 Replies Latest reply on Mar 28, 2017 9:19 AM by levi23

    Get selection Bounds (text bounds (be outline))

    levi23 Level 1

      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[i];
                      // do a test here for the path type (ignore it, break to next object)
                      /*if( (obj[i].guides) ){
                      continue; 
                      }*/
                      // do a test here for the guides type (ignore it, break to next object)
                      if ((obj[i].guides == true)) {
                          // do nothing
                      } else {
                          if (obj[i].typename == 'TextFrame') {
                              //alert("1 - obj.typename=TextFrame")
                              objcopy = obj[i].duplicate().createOutline();
                              vgb2 = objcopy.visibleBounds;
                              objcopy.remove();
                          }
                          // layer clipping mask case
                          else if ((obj[i].typename == 'PathItem') && (obj[i].clipping)) {
                              clipObj = obj[i].geometricBounds;
                              vgb2 = clipObj;
                              return vgb2;
                          }
                          if ((obj[i].typename == 'GroupItem') && obj[i].clipped && (obj[i].pageItems.length > 1)) {
                              vgb2 = obj[i].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.

        • 1. Re: Get selection Bounds (text bounds (be outline))
          o-marat Level 3

          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 [j];
                // 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[i].clipping) {
                      if (bnds == '') {
                        bnds = _getElemBnds(groupPaths[i]);
                        continue;
                      }
                      bnds = _cmprBnds(groupPaths[i], 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;
            }
          }
          
          • 2. Re: Get selection Bounds (text bounds (be outline))
            Silly-V Adobe Community Professional

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

             

             

            1 person found this helpful
            • 4. Re: Get selection Bounds (text bounds (be outline))
              levi23 Level 1

              Many thanks. The code is perfect

              • 5. Re: Get selection Bounds (text bounds (be outline))
                levi23 Level 1

                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

                1 person found this helpful
                • 6. Re: Get selection Bounds (text bounds (be outline))
                  o-marat Level 3

                  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 [j];
                        // 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[i].clipping) {
                              if (bnds == '') {
                                bnds = _getElemBnds(groupPaths[i]);
                                continue;
                              }
                              bnds = _cmprBnds(groupPaths[i], 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;
                    }
                  }
                  
                  • 7. Re: Get selection Bounds (text bounds (be outline))
                    levi23 Level 1

                    It works. Thank you very much for your help.

                     

                     

                    Greetings.

                    • 8. Re: Get selection Bounds (text bounds (be outline))
                      o-marat Level 3

                      Thank you for helping to find a bug! 

                      • 9. Re: Get selection Bounds (text bounds (be outline))
                        levi23 Level 1

                        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.

                        • 10. Re: Get selection Bounds (text bounds (be outline))
                          levi23 Level 1

                          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 [j];  
                                // 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[i].clipping) {  
                                      if (bnds == '') {  
                                        bnds = _getElemBnds(groupPaths[i]);  
                                        continue;  
                                      }  
                                      bnds = _cmprBnds(groupPaths[i], 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[s]
                              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