12 Replies Latest reply on Dec 14, 2015 3:27 AM by billy8015

    Converting a rotated text from IDML to HTML5

    love2code94 Level 1

      I am trying to convert IDML into HTML5 thru script. I have used ItemTransform matrix and IDML geometry (from IDML specs) to get the values for left and top. Left value for css is coming out ok, but top value is not coming out correctly. When a text is rotated, how do I correctly calculate the values for css coordinates (left, top, etc)?

       

      I have used http://www.adobe.com/products/postscript/pdfs/PLRM.pdf (page 187) to get the idea for co-ordinate transformation. Thanks.

        • 1. Re: Converting a rotated text from IDML to HTML5
          Marc Autret Level 4

          I do not know if this has anything to do with your problem, but in InDesign there is a crucial distinction between the inner geometry of a page item and the coordinate space-related bounding box(es). Especially, transformed objects won't see their inner-space bounding box no longer coincides with their parent-space bounding box, as illustrated by the following examples:

           

          http://indiscripts.com/blog/public/BBox_01.png

          http://indiscripts.com/blog/public/BBox_02.png

           

          http://indiscripts.com/blog/public/BBox_03.png

           

          http://indiscripts.com/blog/public/BBox_04.png

           

          In your example, maybe you have to provide the top-left corner location of the textframe inner bounding box in the spread coordinate space, which is not the top-left corner location of the spread-related bounding box. I suppose that IDML uses the same logic as the DOM, describing object locations through a tree of hierarchical transformation matrices. In the scripting environment, you can directly convert a location from a coordinate space to another using the PageItem.resolve() method. You can also provide a location relative to a bounding box system, and then convert it into any coordinate space. If IDML only returns the matrix values, then maybe you need to apply the transformations' chain to get the desired result in the target coordinate space (?)

           

          @+

          Marc

          1 person found this helpful
          • 2. Re: Converting a rotated text from IDML to HTML5
            love2code94 Level 1

            Thanks Marc. I don't think IDML uses the same logic as DOM. I am not sure. Following is the sample XML code (spreads/spread_uc6.xml) for the text frame defined in the IDML.

             

            <TextFrame Self="uda" ParentStory="udc" PreviousTextFrame="n" NextTextFrame="n" ContentType="TextType" ParentInterfaceChangeCount="" TargetInterfaceChangeCount="" LastUpdatedInterfaceChangeCount="" OverriddenPageItemProps="" HorizontalLayoutConstraints="FlexibleDimension FixedDimension FlexibleDimension" VerticalLayoutConstraints="FlexibleDimension FixedDimension FlexibleDimension" GradientFillStart="0 0" GradientFillLength="0" GradientFillAngle="0" GradientStrokeStart="0 0" GradientStrokeLength="0" GradientStrokeAngle="0" ItemLayer="uc3" Locked="false" LocalDisplaySetting="Default" GradientFillHiliteLength="0" GradientFillHiliteAngle="0" GradientStrokeHiliteLength="0" GradientStrokeHiliteAngle="0" AppliedObjectStyle="ObjectStyle/$ID/[Normal Graphics Frame]" Visible="true" Name="$ID/" ItemTransform="0.9702957262759965 -0.24192189559966773 0.24192189559966773 0.9702957262759965 98.8904199390546 85.39783839154677">

             

            ItemTransform attribute basically tells how to transform the text frame. Six values defined in ItemTransform correspond to a, b, c, d, Tx and Ty defined in page 187 of postscript lang reference manual (http://www.adobe.com/products/postscript/pdfs/PLRM.pdf). These coordinates defined by ItemTransform attribute are all for bounding box -- basically for the entire text frame. As I mentioned, I followed the matrix transformation logic formula (transforming coordinates x,y to x' and y') defined in the manual. It doesnt seem to work for both left and top coordinates. If I fix left, top messs up and vice versa.

            • 3. Re: Converting a rotated text from IDML to HTML5
              Harbs. Level 6

              Transformation matrices can be quite complex.

              I find this web page to be very helpful when working on matrix math (it's written for Flash, but it applies equally to all  languages):

              http://www.senocular.com/flash/tutorials/transformmatrix/

              • 4. Re: Converting a rotated text from IDML to HTML5
                Marc Autret Level 4

                Hi again,

                 

                Let's be practical.

                 

                Considering the ItemTransform of your IDML fragment, you can set the transformation parameters as follows:

                 

                a = .9702957262759965;
                b = -.24192189559966773;
                c = .24192189559966773;
                d = .9702957262759965;
                tx = 98.8904199390546;
                ty = 85.39783839154677;
                

                 

                Those values describe the transformation that translates the page item INNER coordinate space into its parent coordinate space, i.e. the SPREAD coordinate space—assuming the pageitem is not nested.

                 

                Now, you need to browse the PathGeometry element of your TextFrame to retrieve the desired path point location. Provided a rectangular geometry is used, you should have four PathPointType elements in the PathPointArray, and the first path point should reflect the TOP-LEFT anchor. Here you have an Anchor attribute, say Anchor="-150 50". This means that the location of this pathpoint is [-150,50] in the INNER coordinate space:

                 

                xInner = -150;
                yInner = 50;
                

                 

                Note: the Anchor attribute always gives the [x,y] location of a PathGeometry point relative to the INNER coordinate space. This may be confusing as the ORIGIN of the inner space is in some way 'arbitrary.' Indeed, that origin does not only result from the intrinsic location of the object. It also depends on translations (moves) that have been manually applied by the user since the creation of the object—such translations have an effect on the tx and ty values of the ItemTransform element (see above). Thus, two identical page items which exactly share the same place in the layout can have both their pathpoints' locations AND their (tx,ty) pair different. Anyway, you can still translate the location of any pathpoint into the spread coordinate space, because this is the role of the transformation matrix to convert the INNER coordinate system into the parent coordinate system with respect to the origin of each one. (By the way, [tx, ty] is the location of the INNER space origin expressed in the SPREAD space system.)

                 

                From that point, we can compute the coordinates of the TOP-LEFT anchor in the SPREAD system. We just have to apply the transformation:

                 

                xInSpread = xInner*a + yInner*b + tx;
                yInSpread = xInner*c + yInner*d + ty;
                

                 

                In my example, this gives the following coordinates: [-58.75, 97.62]  (after rounding). These are the location of the anchor, in POINTS, relative to the SPREAD origin (which is always the center point of the spread). If you need to have this location relative to a PAGE, then you have to also consider the ItemTransform element of that page—which usually describes a simple translation (unless the page itself is scaled/rotated/skewed…).

                 

                If the above method does not work, then your TextFrame is probably not the direct child of a Spread, so you must consider each parent's ItemTransform and compose the corresponding transformations.

                 

                @+

                Marc

                • 5. Re: Converting a rotated text from IDML to HTML5
                  love2code94 Level 1

                  Hi Marc,

                   

                  Thanks again for taking time to write the details.

                   

                  The formula is

                   

                  xInSpread = xInner*a + yInner*c + Tx;

                  yInSpread = xInner*b + yInner*d + Ty;

                   

                  This is what I have been using before. Your answers helped me to understand the origin of the spread. I kept my code as it is and added webkit-transform-origin: top left to the css. It came out well. I ran couple of tests. For most of the tests, the rotated text is properly aligned or very closely aligned to the original IDML.

                   

                  Thanks!

                  Ram

                  • 6. Re: Converting a rotated text from IDML to HTML5
                    Marc Autret Level 4

                    love2code94 wrote:

                     

                    The formula is

                     

                    xInSpread = xInner*a + yInner*c + Tx;

                    yInSpread = xInner*b + yInner*d + Ty;

                     

                     

                    Yes! Indeed I switched b and c by mistake (threfore the result is wrong in my example).

                    Sorry for my carelessness.

                     

                    @+

                    Marc

                    • 7. Re: Converting a rotated text from IDML to HTML5
                      love2code94 Level 1

                      Hi Marc, no problem. Actually, I was able to solve this issue only because of the pointers you provided.

                       

                      Thank you very much,

                      Ram

                      • 8. Re: Converting a rotated text from IDML to HTML5
                        wMan Level 1

                        Hi everybody,

                         

                        I just came across this entry it it was so far very helpful and calculation of x and y for rotated textfields works so far with the given formulas.

                         

                        But now I came across an issue, if I have three pages in one spread.

                         

                        Just have a look at the following image. Top image is InDesign and how everything should be. Bottom is my flash application.

                        template.jpg

                        As you can see, my textfields aren't  positionend correctly. Right now I use the follwing approach which works fine for a spread with two pages:

                         

                        xInSpread= xInner*a + yInner*c + Tx;

                        yInSpread= xInner*b + yInner*d + ty;

                        xPos = spreadWidth*.5 + xInSpread;

                        yPos = spreadHeight*.5 + yInSpread;

                         

                        My guess is that I maybe need to calculate positions relative to the page as Marc stated in the "marked as correct answer". But if so, how?

                         

                        Any help would be realy appreciated.

                         

                        Regards,

                        wMan

                        • 9. Re: Converting a rotated text from IDML to HTML5
                          Marc Autret Level 4

                          Hi wMan,

                           

                          Considering your code for xPos and yPos I suppose that those coordinates are expected relative to the top-left corner of your imageable area.

                           

                          At first sight, translating (xInSpread, yInSpread) by (spreadWidth/2, spreadHeight/2)—as you do—should do the job since the spread origin is (almost) always the center point of the spread. But there is a special case which is not so special: facing-page layouts. If your document has "facing pages" enabled, then the x-coordinate of the spread origin is not necessary centered relative to the imageable area. Facing pages lead to a global axis among all spreads, which determines the side of a page. The origin of any spread is on that axis, whatever the disposition of pages. So given three pages, they might be all left-sided, or all right-sided, or you can have one page to the left side and two pages to the right side, and so on.

                           

                          Therefore, xInSpread (which is the x-coordinate of your object relative to the spread origin) must be translated with respect to the actual location of the top-left corner of the area relative to the spread origin. spreadWidth/2 is valid only if the origin of the spread fits the center point of the area. But in a general case (with facing pages!) you have to get the origin of the first page relative to the spread origin. (Note: the origin of the first page matches the top-left corner we are looking after.)

                           

                           

                          xOffset = {x-location of the 1st page relative to the spread origin}

                          xPos = xInSpread - xOffset

                           

                           

                          I think you'll easily find xOffset considering the ItemTransform element of the page.

                           

                          @+

                          Marc

                          • 10. Re: Converting a rotated text from IDML to HTML5
                            wMan Level 1

                            Hi Marc,

                             

                            thank you very much for your detailed and very well explained answer. You guessed right. Facing Pages were enabled for the specific indesign file. I disabled it and it worked as expected.

                             

                            Because disabling it within the indesign file is not an option for me I just got a few more questions according facing pages and the xOffset.

                             

                            My current workflow for my flash application is something like this that I rename the idml file to zip, extract its content and parse that content to a xls-fo file.

                             

                            1.) Because I need to handle both ways (indesign files with facing pages and without) how do I figure out if the idml or the contents of the zip uses facing pages? While having a look at the xml's of the zip I couldn't find something like a flag or hint for facing pages.

                             

                            2.) How do I find the correct page for each Textframe to get the correct xOffset? While having a look at the xml's of the zip I couldn't find something that tells me which textframe belongs to which page.

                             

                            3.) For the given example I have one Spread with three pages. So the idml/xml's define three page nodes. Which node should I use get the itemTransform element? And next if I have the itemTransform how do I excactly calculate the xOffset? For example this is the first page node within my spreads xml:

                             

                            <Page Self="u14f" AppliedAlternateLayout="uab" LayoutRule="Off" SnapshotBlendingMode="IgnoreLayoutSnapshots" OptionalPage="false" GeometricBounds="0 0 297.6377952755906 405.35433070866145" ItemTransform="1 0 0 1 -405.35433070866145 -148.8188976377953" Name="1" AppliedTrapPreset="TrapPreset/$ID/kDefaultTrapStyleName" OverrideList="" AppliedMaster="u136" MasterPageTransform="1 0 0 1 0 0" TabOrder="" GridStartingPoint="TopOutside" UseMasterGrid="false">


                             

                            Regards,

                            wMan

                            • 11. Re: Converting a rotated text from IDML to HTML5
                              wMan Level 1

                              Hi Marc,

                               

                              actually I was able to solve my problems/questions with your help.

                               

                              1.) I was able to find a attribute FacingPages="true" within Resources/Preferences.xml file.

                              2.) As you said I don't need to find the correct page for each textframe because we always take the first page to calculate the xOffset

                              3.) As you mentioned I simple use the ItemTransform and the GeometricBounds of the 1st page to calculate my xOffset.

                               

                              For example considering the following ItemTransform and GeometricBound

                              ItemTransform="1 0 0 1 -405.35433070866145 -148.8188976377953"

                              GeometricBounds="0 0 297.6377952755906 405.35433070866145"

                               

                              I calulate my xOffset like:

                              xInner = 0

                              yInner = 0

                              a = 1

                              c = 0

                              tx = -405.35433070866145


                              var xOffset:Number = xInner * a + yInner * c + tx; = 0*1 + 0*0 - 405.35433070866145 = -405.35433070866145

                               

                              Thank you for your help.

                               

                              Regards,

                              wMan

                               

                               

                               

                               

                               

                               


                               

                              • 12. Re: Converting a rotated text from IDML to HTML5
                                billy8015 Level 1

                                hello wMan,

                                   can you please describe how to calculate xpos and ypos relative to the page in html5.  

                                I calculate page height and width from Preferences.xml

                                 

                                <DocumentPreference PageHeight="850.3937007874016" PageWidth="340.15748031496065" CreatePrimaryTextFrame="false" PagesPerDocument="1" FacingPages="false" DocumentBleedTopOffset="0" DocumentBleedBottomOffset="0" DocumentBleedInsideOrLeftOffset="0" DocumentBleedOutsideOrRightOffset="0" DocumentBleedUniformSize="true" SlugTopOffset="0" SlugBottomOffset="0" SlugInsideOrLeftOffset="0" SlugRightOrOutsideOffset="0" DocumentSlugUniformSize="false" PreserveLayoutWhenShuffling="true" AllowPageShuffle="true" OverprintBlack="true" ColumnGuideLocked="true" Intent="PrintIntent" PageBinding="LeftToRight" ColumnDirection="Horizontal" MasterTextFrame="false" SnippetImportUsesOriginalLocation="false">

                                 

                                $width = (340.15748031496065 / 2.83464) * 3.779528= 453.543307 px;

                                $height = (850.3937007874016 / 2.83464) * 3.779528= 1133.858268 px;


                                that width and height i used for the canvas height and width.


                                now I have a rectangul. on the page. I am able to calculate the height and width of the rectangular but i am not able to calculate the xpos and ypos relative to the top-left corner so that i can use in html ctx.rect(xpos,ypos, 377.95355590711, 502.67822935646);


                                I have page information in spread.xml


                                <Page Self="ucb" AppliedAlternateLayout="ucc" LayoutRule="UseMaster" SnapshotBlendingMode="IgnoreLayoutSnapshots" OptionalPage="false" GeometricBounds="-382.6771653543307 28.346456692913414 467.7165354330707 368.5039370078741" ItemTransform="1 0 0 1 -198.42519685039372 -42.51968503937011" Name="1" AppliedTrapPreset="TrapPreset/$ID/kDefaultTrapStyleName" OverrideList="" AppliedMaster="ucd" MasterPageTransform="1 0 0 1 0 0" TabOrder="" GridStartingPoint="TopOutside" UseMasterGrid="false">

                                  <Properties>

                                  </GridDataInformation>

                                  </Page>


                                and rantangulor information is given below.


                                <Rectangle Self="ue6" ContentType="GraphicType" StoryTitle="$ID/" ParentInterfaceChangeCount="" TargetInterfaceChangeCount="" LastUpdatedInterfaceChangeCount="" OverriddenPageItemProps="" HorizontalLayoutConstraints="FlexibleDimension FixedDimension FlexibleDimension" VerticalLayoutConstraints="FlexibleDimension FixedDimension FlexibleDimension" GradientFillStart="0 0" GradientFillLength="0" GradientFillAngle="0" GradientStrokeStart="0 0" GradientStrokeLength="0" GradientStrokeAngle="0" ItemLayer="u1e7" Locked="false" LocalDisplaySetting="Default" GradientFillHiliteLength="0" GradientFillHiliteAngle="0" GradientStrokeHiliteLength="0" GradientStrokeHiliteAngle="0" AppliedObjectStyle="ObjectStyle/$ID/[None]" Visible="true" Name="bildbox1" ItemTransform="1 0 0 1 56.74938201842281 -24.13408680238939">

                                  <Properties>

                                  <PathGeometry>

                                  <GeometryPathType PathOpen="false">

                                  <PathPointArray>

                                 

                                <PathPointType Anchor="-198.48040380941532 -42.48008642595708" LeftDirection="-198.48040380941532 -42.48008642595708"                                    ghtDirection="-198.48040380941532 -42.48008642595708" />

                                 

                                  <PathPointType Anchor="-198.48040380941532 334.52778758979093" LeftDirection="-198.48040380941532 334.52778758979093"                     RightDirection="-198.48040380941532 334.52778758979093" />

                                 

                                <PathPointType Anchor="84.98416311971849 334.52778758979093" LeftDirection="84.98416311971849 334.52778758979093"                RightDirection="84.98416311971849 334.52778758979093" />

                                 

                                <PathPointType Anchor="84.98416311971849 -42.48008642595708" LeftDirection="84.98416311971849 -42.48008642595708"           RightDirection="84.98416311971849 -42.48008642595708" />

                                 

                                </PathPointArray>

                                  </GeometryPathType>

                                  </PathGeometry>

                                  </Properties>

                                 

                                I have calculate the  width,height( 377.95355590711, 502.67822935646) in pixel for rectangular. but know the problem is xpos and ypos relative to the top .left corner. to proper place the rectangular on the canvas.

                                 

                                thank you in advance.