7 Replies Latest reply on Aug 24, 2015 1:45 PM by Silly-V

    Get position and width of each line of textFrame

    kcBZOR

      hello!

       

      I have a file from a designer with a text layout that has a block of centered copy with lots of kerning adjustments and line breaks. I'd like to loop over the lines and find the center,, left and top position (in pixels) of each line of the textFrame. Is there a way to do this in JS?

       

      thanks!

      -kc

        • 1. Re: Get position and width of each line of textFrame
          Silly-V Adobe Community Professional

          Why don't you post a screenshot of your typical file, maybe this could be made possible.

          • 2. Re: Get position and width of each line of textFrame
            kcBZOR Level 1

            sure here's one of the simpler ones:

             

            layout.png

             

            The text is one textFrame, and I need to find the center position and upper left position of each line..

             

            thanks!

            • 3. Re: Get position and width of each line of textFrame
              Silly-V Adobe Community Professional

              Hmm, try this script out, and let's see if it works.

               

              #target illustrator
              
              function test(){
                function newCMYKColor(arr){
                    var c = new CMYKColor();
                    c.cyan = arr[0];
                    c.magenta = arr[1];
                    c.yellow = arr[2];
                    c.black = arr[3];
                    return c;
                }
                function marker(xy, clr){
                    var doc = app.activeDocument;
                    var p = doc.pathItems.ellipse(xy[1] + 2, xy[0] - 2, 4, 4);
                    p.stroked = false;
                    p.filled = true;
                    p.fillColor = clr || newCMYKColor([0,100,100,0]);
                    return p;
                }
                function gridize(pageItems, buffer){
                    var tempArr;
                    tempArr = pageItems.slice(0).sort(function(a,b){return b.top - a.top;});
                    var buffer = buffer || 10;
                    /* buffer is the max variance expected between separate rows */
                    var vBnds = [];
                    for(var i=0; i<pageItems.length; i++){
                        var thisItem = pageItems[i];
                        var p = thisItem.geometricBounds;
                        vBnds.push(p.concat([thisItem]));
                    }
                    var sortedVBnds = [];
                    var currentRowYMarker;
                    var currentRowY = [];
                    var temp = vBnds.slice(0);
                    for(var i=0; i<vBnds.length; i++){
                        currentRowYMarker = vBnds[i];
                        currentRowY = [];
                        for(var j=temp.length-1; j>-1; j--){
                            if(temp[j][1] + buffer >= currentRowYMarker[1] && temp[j][1] - buffer <= currentRowYMarker[1]){
                                currentRowY.push(temp[j]);
                                temp.splice(j,1);
                            }
                        }
                        if(currentRowY.length > 0){
                            sortedVBnds.push(currentRowY.sort(function(a,b){return a[0] - b[0];}));
                        }
                    }
                    sortedVBnds.sort(function(a,b){return b[0][1] - a[0][1];});
                    return sortedVBnds;
                }
                function getRowTop(row){
                    var num = 0;
                    for (var i = 0; i < row.length; i++) {
                        var vb = row[i];
                        var top = vb[1];
                        if(top > num){
                            num = top;
                        }
                    };
                    return num;
                }
                function getRowBottom(row){
                    var num = row[0][3];
                    for (var i = 0; i < row.length; i++) {
                        var vb = row[i];
                        var btm = vb[3];
                        if(btm < num){
                            num = btm;
                        }
                    };
                    return num;
                }
                function getRowRight(row){
                    var num = row[0][2];
                    for (var i = 0; i < row.length; i++) {
                        var vb = row[i];
                        var right = vb[2];
                        if(right > num){
                            num = right;
                        }
                    };
                    return num;
                }
                function getRowBounds(row){
                    var arr = [];
                    var left = row[0][0];
                    var right = getRowRight(row);
                    var top = getRowTop(row);
                    var bottom = getRowBottom(row);
              
              
                    return [left, top, right, bottom];
                }
                function getRowCenter(rowBounds){
                var r = rowBounds;
                return [r[0] + ((r[2] - r[0]) / 2) , r[3] - ((r[3] - r[1]) / 2)];
                }
              
              
              //================================================== MAIN =================================================//
                if(app.documents.length > 0){
                var doc = app.activeDocument;
                doc.rulerOrigin = [0,0];
                if(doc.selection.length > 0 && doc.selection[0].typename == "TextFrame"){
                var s = doc.selection[0];
                var dupeText = s.duplicate(s, ElementPlacement.PLACEAFTER);
                var dupeTextOutlines = dupeText.createOutline();
                dupeText = null;
                var myArray = [];
                for (var i = 0; i < dupeTextOutlines.compoundPathItems.length; i++) {
                var thisComp = dupeTextOutlines.compoundPathItems[i];
                myArray.push(thisComp);
                };
                var allLines = gridize(myArray);
                for(var i=0; i<allLines.length; i++){
                var thisLine = allLines[i];
                var thisLineBounds = getRowBounds(thisLine);
                var topLeftMarker = marker([thisLineBounds[0], thisLineBounds[1]]);
                topLeftMarker.name = "Top Left";
                var thisLineCenter = getRowCenter(thisLineBounds);
                var centerMarker = marker([thisLineCenter[0], thisLineCenter[1]]);
                centerMarker.name = "Center";
                }
                dupeTextOutlines.remove();
                dupeTextOutlines = null;
                } else {
                alert("Please select a text box.");
                }
                } else {
                alert("No document present.")
                }
              }
              
              
              test();
              
              • 4. Re: Get position and width of each line of textFrame
                Silly-V Adobe Community Professional

                Hey kcBZOR I slaved away for hours and hours, neglecting my own nutritional intake and ostracized my entire social community to make this happen for you, now aren't you going to let us know if it worked?

                • 5. Re: Get position and width of each line of textFrame
                  kcBZOR Level 1

                  lol! totally missed that reply, I'll give this a go when I get into work tomorrow.. even if it doesn't work, at a glance it's giving me lots to go on. this is great.

                   

                  THANK YOU

                  • 6. Re: Get position and width of each line of textFrame
                    kcBZOR Level 1

                    works great, this is exactly what I needed to get started.. thanks so much, really really appreciate it!