Images

1. Loading a graphic from a file
2. Referring to images
3. How to insert images into an fo file
4. Graphics in xsl-fo
5. Image in a table, with padding
6. Images and XSL FO
7. Text wrap round image
8. Scaling images
9. Keeping an image with associated text
10. Image sizing
11. fo:external-graphic syntax
12. Anchor an image to the bottom of a page
13. Full page images
14. Image overlay, e.g. to mark an image as 'draft'.
15. Overlaid graphics
16. Text wrap round image
17. Image scaling
18. SVG Image to fill full screen
19. Image scaling
20. Wrapping text round an image
21. Align graphic with top of text

1.

Loading a graphic from a file

Eliot Kimber

There is no simple single solution to this problem because it depends entirely on the relative locations of the FO instance (if you are generating an instance) and the graphic *at the time you render them*, not at the time you generate the FO.

Therefore, for different processing environments, it might be most appropriate to generate an absolute path and in others you have to generate a relative path relative to some pre-defined location.

In addition, doing path processing is generally easier in a language like Java than in XSLT (although you can do it in XSLT, of course). For example, we have utility Java libraries that do things like compare two paths and return the shortest relative path. We then expose these through Saxon extension functions so that in the XSLT we can easily generate relative paths to graphics given some base path (normally passed in as a parameter to the XSLT process).

For one customer we have to provide an FO-generation-time option of whether graphic paths are relative or absolute because different users of the code have different business rules.

Finally, remember that relative paths will be relative to the location of the FO instance, not the original XML document (unless you set the xml:base attribute in the FO instance to be the location of the orignal XML document), which can be a problem, especially if you generate the FO instance and then move it somewhere else before rendering it.

This is all presuming that your graphics are not managed in some URL-accessible content store that would allow you to specify location-independent absolute URIs. In essence, all the W3C specifications assume that this is the case, even though for most users it is never the case.

2.

Referring to images

David Carlisle



   > <fo:external-graphic  
    src="file:../graphics/page.gif" content-height="200%"
   > content-width="200"/>

Also, (unfortunately) XSL for no particularly good reason insists that the URI is surrounded by url( ... ) so that should be src="url(file:///......)"

(note that you can not put a relative uri like ../graphics/page.gif after file: (or any other URI-scheme prefix) Either you should have a relative URI with no prefix, or an absolute URI, this is a URI syntax issue, nothing to do with XSL).

Note that the WG shuold be clarifying this in the version 1 errata very soon (July 2002)

3.

How to insert images into an fo file

??

This is the xsl for images <!-- IMAGES --> <xsl:template match="imagedata"> <fo:block> <fo:inline-graphic content-height="auto" content-width="auto" href="file:{@fileref}"/> </fo:block> </xsl:template>

4.

Graphics in xsl-fo

David Tolpin




  > I have a question concerning XSL-FO. It's about 
  > <fo:external-graphic>. I
  > have a JPEG of unknown size and want to place it in the 
  > horizontal middle of
  > the page (align="center"). But neither I get the correct 
  > scaling nor the
  > JPEG centered. I found the attribute "display-align", but that's not
  > implemented in FOP. With XEP I don't get any picture.
  
  <fo:block 
        align="center"><fo:external-graphic src="1.jpg"/>
</fo:block>
  

  
> I tried <fo:external-graphic src="1.jpg" width="22.7cm" 
  height="12.4cm"/>
  > and the not implemented attributes content-width="scale-to-fit",
  > content-height="scale-to-fit" and scaling="uniform".

Try

  <fo:external-graphic src="1.jpg" content-width="22.7cm" 
 content-height="12.4cm" scaling="uniform"/>

5.

Image in a table, with padding

Nikolai Grigoriev



> <fo:table-cell padding-left="7cm"><fo:block><fo:inline-graphic height="3cm"
> width="3cm"
>          href="<xsl:value-of select="header/headerimage/url"
> />"/></fo:block></fo:table-cell>
>
> But this does not seem to be legal syntax. Does somebody know how to do
> this?

Assumptions:

1. You're writing a stylesheet, and the URL to the image is contained in the XML document to be processed, enclosed in an <url> element which is contained in a <headerimage> element which is contained in a <header> element which is a child of the current node, and all these elements have no siblings of the same name. (;-)).

2. You're using an old XSL FO version (1999-04-21) - either FOP version 13.0 or earlier, or XEP.

Then, the syntax would be:

<fo:table-cell padding-left="7cm">
  <fo:block>
    <fo:inline-graphic height="3cm" width="3cm"
                 href="{header/headerimage/url}"/>
  </fo:block>
</fo:table-cell>

By the way: in XSL FO 1999-04-21, you could use a fo:display-image (which is a block-level element), inserting it directly into an fo:table cell without an intercalary fo:block:

<fo:table-cell padding-left="7cm">
    <fo:display-graphic height="3cm" width="3cm"
                 href="{header/headerimage/url}"/>
</fo:table-cell>

6.

Images and XSL FO

David Tolpin


> > The pdf-file has to look as followed:
> > 		_________________
> > 	text 1	|	image	     |
> > 	text 2	|		     |
> > 	text 2	|		     |
> > 	text 2	|________________|
> > 	text 2 text2 text 2
> 
> I've tried, and failed, to get text to wrap round an image.
	

Floats (fo:float), floating horizontally are for that. Unfortunately, in most implementations I'm aware of floats either do not float at all, or float in the natural vertical direction.

Other implementation do support horizontal floating, but lack other significant features.

And no, RenderX XEP does not handle fo:float yet. (01 2001)

Sebastian Queries

>taking that as a challenge (:-}), I looked again at the spec. am I
>right in the following crude view?
>
> <fo:float float="none">...      stays exactly where it is
> <fo:float float="left">...      sits on the left side of the
>                                paragraph,  and text floats around it
> <fo:float float="right">...     sits on the right side of the
>                                paragraph,  and text floats around it
> <fo:float float="before">...    goes to top of this, or subsequent pages
>

Paul Grosso answers:

Yes, you are basically correct. So when fo:float's float property is "before", you get what TeX would call a topfloat.

>this appears to exclude floats going to the *bottom* of the page, if I
>understand it right. surely this is unnaturely restrictive??? what if
>the float looked better at the bottom of the page?

Correct. The theory of floats is complex (anyone familiar with the details of TeX's inserts and such, as I know Sebastian is, can appreciate this, and what TeX does with floats is less than half of the actual complexity), and the XSL WG decided we'd never get the XSL spec out if we didn't make some simplifying assumptions in this area (the other alternative was to leave vertical floats out of XSL 1.0 altogether, and we didn't want to do that). So we allowed for top floats only (and footnotes, but via the fo:footnote FO) in XSL 1.0.

>its also odd that "<fo:float>" defaults to float="none", and so does
>not float at all.....

The CSS default is none, and we just copied it. Furthermore, since the value of the float property could make for either a vertical float (aka insert) or a horizontal "float" (aka wrap-around text) which are very different things, it would be hard to have a default that was useful and intuitive in the majority of cases. Making the default none just means that, when you explicitly insert an fo:float, you also have to explicitly set the float property to something.

7.

Text wrap round image

Ken Holman



>    But I want, let say if the attribute"align" in my image tag
>is left, then first it should place the image on the left and leave
>2mm space and start the writing the content on the right side.
>once the content height reached the height of the image then from
>next line content should start from the beginning of the pagelike a
>full line. i should be like a flow.
>   Am I clear?

Now you are ... and you just need to use side-floats for that.

>   I think even this happens with list-block also because we are
>creating two blocks . I want a block which contains both content and
>image not two separate blocks.

Now I can tell from your wording what you want.


<block xmlns="http://www.w3.org/1999/XSL/Format">
  <float float="start"><external-graphic src="image"/></float>
  Text goes here.
</block>

The following illustrates this in both Antenna House and XEP using just text in the float instead of a graphic:

<fo:block>
   <fo:float float="start">
     <fo:block background-color="silver">F111</fo:block>
     <fo:block background-color="silver">F111</fo:block>
   </fo:float>
  B222 B222 B222 B222 B222 B222 B222 B222 B222 B222 B222 B222 B222
</fo:block>

8.

Scaling images

Max Froumentin



> I am using fo:external-graphic to display images.I have a requirement
> to show the same image in different sizes.Is there any way to scale
> images in XSL:FO??

Yes, the propreties "content-height" and "content-width" apply to fo:external-graphic. The scaling is controlled by the scaling and the scaling-method properties. See 6.6.5 fo:external-graphic for more details.

9.

Keeping an image with associated text

Ken Holman



>Does anybody know how to prevent an external-graphic and its following
>text from breaking a line ?

Use keep-with-next= on the graphic or keep-with-previous= on the text, or keep-together= on the pair.

The following illustrates this to me on Antenna House (your margins may vary, play with the length of the XX prefix to cause the first one to break the line between the graphic and the subsequent text:

   <block>XXXXX: This is a test with a graphic followed by text 
<external-graphic src="url('smflags.bmp')"/><inline>hello 
world</inline></block>
   <block>XXXXX: This is a test with a graphic followed by text 
<external-graphic src="url('smflags.bmp')" 
keep-with-next="always"/><inline>hello world</inline></block>
   <block>XXXXX: This is a test with a graphic followed by text 
<external-graphic src="url('smflags.bmp')"/><inline 
keep-with-previous="always">hello world</inline></block>
   <block>XXXXX: This is a test with a graphic followed by text <inline 
keep-together="always"><external-graphic src="url('smflags.bmp')"/>hello 
world</inline></block>

10.

Image sizing

Ken Holman


>I want te get the width of an image, and if the image has a width greater as
>144 pixels, I want to scale the image, else if the size <= 144 pixels then
>I'd like to display the image at the normal size.

Because the XSL-FO interpretation is arms-length from the XSLT transformation, one must always express the desired conditional processing in the stylesheet before the XSL-FO processor acts on the resulting transformation. An example of such conditional processing is the set of "keep" properties.

These needs in particular cannot be expressed in the conditional processing facilities in XSL-FO, so you must resort to a scheme outside of the Recommendation.

If I had a program that read the dimensions of an image and wrote out a small XML instance capturing these measurements, then I would read those XML instances at transformation time using the document() function when processing the figures and determine in my XSLT stylesheet which strategy to follow for the presentation of each image.

11.

fo:external-graphic syntax

Ken Holman



>The src attribute is defined as containing a <uri-specification>
>which has the format 'url(' followed by a URI reference in single
>or double quotes, followed by ')'. So your code should be
>
><xsl:element name="fo:external-graphic">
>   <xsl:attribute name="src">url('<xsl:value-of 
> select="imgurl"/>/zenith.gif')</xsl:attribute>

A nuance is that the use of the single quote as the literal in the url() syntax may not be the "safest" when you are dealing with arbitrary URL values from your XML authors.

The single quote is a valid character in the URL syntax according to the second last paragraph of section 2.2 of RFC1738 ... so I figured that if you used url('{@url}') there was a risk that the single quote of the URL would get confused with the single quote of the opening literal. Perhaps I am wrong about this risk, since it isn't mentioned in the Recommendation.

The safest is to use url("{@url}") to ensure there would be no confusion with any valid URL value resolved from the author's data.

Note that for those who quote their attributes, it would be:

    src="url(&quot;{@url}&quot;)"

12.

Anchor an image to the bottom of a page

David Tolpin


>          <fo:flow flow-name="xsl-region-body">

>              <fo:block>
>               ...
>              </fo:block>
>              ...
>              <fo:block> <fo:external-graphic src='url(foo.jpg)'/>
</fo:block>
>         ...
>              <fo:block>
>               ...
>              </fo:block>

>          <fo:flow>


> The fo:flow element contains material for several pages, and I want the 
> image to be shifted (or anchored) to the bottom of its current page (the 
> current page is the page where the image would appear without special
>action).

  <fo:block>
    <fo:footnote>
      <fo:footnote-body>
      <fo:inline/>
        <fo:external-graphic src="url(foo.jpg)"/>
      </fo:footnote-body>
    </fo:footnote>
  </fo:block>

13.

Full page images

David Tolpin



> I have several figures/external-graphics that I need
> to render at full page size.  
> However, I do not want to create a page-break at
> the point in the document flow where the image appears.  
> Rather, I want to place
> the external-graphic on its own page which immediately follows 
> the point in the
> document flow where the fo:external-graphic element appears. 
> The text before
> and after the fo:external-graphic should flow together, 
> uninterrupted by any page breaks.

You are talking about before-floats. Just take your images into <fo:float float="before"> and you will get what you are describing in a compliant processor

14.

Image overlay, e.g. to mark an image as 'draft'.

W. Eliot Kimber


>>
>>You can try a block as overlay, using relative positioning.

> Could you please give me further more information? - What do you mean 
> with relative positioning?

You need to use block-container or inline-container. For block-container, the basic pattern is:

<fo:block-container>
   <fo:block-container position="absolute">
     <fo:block>This is the first block</fo:block>
   </fo:block-container>
   <fo:block-container position="absolute">
     <fo:block>This is the second block. It should overprint the
first</fo:block>
   </fo:block-container>
</fo:block-container>

The reason this works is that the outer block-container establishes a new "reference area", that is, an area within which other areas are positioned.

The two inner block-containers use position="absolute" to indicate that they are absolutely positioned relative to the boundaries of their containing reference area. Because both inner block containers are positioned at the same place (the default position is aligned with the top and left of the containing reference areas) they overlay each other.

By default, the Z-order (vertical stacking) is determined by source order, so the second inner block-container has a higher Z-order than the first block container.

The same basic approach works with inline-container, the difference being that the outer inline-container will be positioned within a sequence of inline areas rather than as a block, as in the example above. Here is a sample that works with XSL Formatter 2.5 (in my data set, the graphic is a little icon about 10pt square):

     <fo:block space-before="12pt"
         font-size="12pt"
     >this is before the inline graphic
     <fo:inline-container
         alignment-adjust="10pt"
         inline-progression-dimension="12pt"
     >
       <fo:block-container position="absolute">
         <fo:block>
           <fo:external-graphic src="url(graphics/menu-icon.eps)"/>
         </fo:block>
       </fo:block-container>
       <fo:block-container position="absolute">
         <fo:block>
           <fo:leader
               color="red"
               alignment-adjust="middle"
               rule-thickness="1pt"
               leader-length="12pt"
               leader-alignment="reference-area"
               leader-pattern="rule"/>
         </fo:block>
       </fo:block-container>
     </fo:inline-container>
     this is after the inline graphic.
     </fo:block>

[It may not work with XEP--I believe XEP implements all absolutely-positioned blocks relative to the page's reference area. I would be very surprised if it works with FOP.]

15.

Overlaid graphics

Eliot Kimber



> The first of these is that I want to be able to use over-layed text / 
> graphics within the PDF.  For example, lets say I create multi-page 
> PDF customer order confirmations, once the customer confirms they have 
> received the goods, I want to overlay the words "Fulfilled" diagonally 
> across the entire document.

If FOP supports block-container you can use an absolutely-positioned block container to overlay the text. If you want it to be diagonal, you will need to use a graphic for the text (easy to do with EPS or SVG).

The one limitation may be support for Z-order--if your FO implementation doesn't support Z-order or doesn't default to the behavior you want you may not be able to force the text to overlay the region-body content.

Z-order is the property that determines the vertical stacking over overlapping areas--a higher Z-order value should be rendered above (on top of) areas with lower Z-orders.

Since the overlay would need to be static content (so it could apply to each page) you'd have to put in into one of the edge regions with the region's extent set so that it overlaps the region-body. Different FO implementations may vary in how they place the areas involved, so it will require some testing to determine if what you want will work with a particular implementation.

This problem can also be addressed using a PDF post-process using a tool. Adding an overlay to every page of a PDF is a pretty simple operation. See www.pdfzone.com or www.planetpdf.com for a list of likely candidate tools.

16.

Text wrap round image

Ken Holman



>    But I want, let say if the attribute"align" in my image tag
>is left, then first it should place the image on the left and leave
>2mm space and start the writing the content on the right side.
>once the content height reached the height of the image then from
>next line content should start from the beginning of the pagelike a
>full line. i should be like a flow.
>   Am I clear?

Now you are ... and you just need to use side-floats for that.


>   I think even this happens with list-block also because we are
>creating two blocks . I want a block which contains both content and
>image not two separate blocks.

Now I can tell from your wording what you want.

>   IS there any way to do it in xsl-fo?

<block xmlns="http://www.w3.org/1999/XSL/Format">
  <float float="start"><external-graphic src="image"/></float>
  Text goes here.
</block>

The following illustrates this in both Antenna House and XEP using just text in the float instead of a graphic:

<fo:block>
   <fo:float float="start">
     <fo:block background-color="silver">F111</fo:block>
     <fo:block background-color="silver">F111</fo:block>
   </fo:float>
  B222 B222 B222 B222 B222 B222 B222 B222 B222 B222 B222 B222 B222
</fo:block>

17.

Image scaling

G. Ken Holman



>Is it possible to scale images so that images that would run off the
>page are scaled to fit, while smaller images retain their existing
>size.

The pattern I've seen used is:

  <external-graphic url="......."
   width="100%" content-width="scale-to-fit"
   scaling="uniform"
   content-height="100%"/>

or, if you want to limit by height instead of by width:

  <external-graphic url="......."
   height="100%" content-height="scale-to-fit"
   scaling="uniform"
   content-width="100%"/>

When images are smaller than the dimension changing specification of the content dimension using "scale-to-fit", the image is considered to already fit. If the image is larger than the given dimension, that dimension is reduced to fit to the viewport (defined by height= or width=, in the above examples, the use of 100% specifies the viewport to be the full dimension available, you have to choose one of height or width to be the governing dimension since specifying both won't result in proper scaling).

The scaling="uniform" ensures that the other image dimension is relatively scaled so as to not disturb the aspect ratio.

Finally, the explicit specification of the other image dimension to 100% ensures that the governing content dimension specification does not distort the content's other dimension ... so images that are smaller than the governing dimension do not get stretched to 100% of that dimension's available size.

I hope the explanation can be understood, and I would welcome anyone else's wording of what I've tried to say above ... all I know is that I learned the pattern from somewhere and I understand what it is doing and it has worked for me ... but I have to wave my arms to convey my thoughts on this.

18.

SVG Image to fill full screen

Jirka Kosek


> You are correct, this 'half leading' resulted in a small white line above my SVG. 
> With line-height="1.0" this line vanished and I could make the SVG image 1mm higher.
> But, there is still a tine white line below the SVG, 
> it is still not possible to make it as high as the page.
>
> I just want the SVG to be rendered even if it has 
> the same size (or is bigger) than the page! Is this possible with XEP?

You can put your image into block-container and then use absolute positioning to fine tune placement of image, e.g.:


<fo:block-container absolute-position="absolute"
                  left="-1.5cm"
                  top="-1cm" >
  ...
</fo:block-container> 

19.

Image scaling

Angela Williams



>I have tried playing with the margins and set them to
>0.5in for both the page and region-body. Then I set
>the content-height and content-width values to
>"scale-to-fit".

>This  says "no space for element to recover".

Your image is 212.09mm x 190.5mm but the available space inside your region-body is only 200.4mm x 189.9mm.=20

page_height - page_top - page_bottom - body_top - body_bottom max-height of region-body content area. (279.4mm (11in) - 5mm - 5mm - 39mm - 30mm =200.4mm

page_width - page_left - page_right - body_left - body_right = max-width of region-body content area (215.9mm (8.5in) - 5mm - 5mm - 8mm - 8mm = 189.9mm)

<fo:external-graphic content-height="scale-to-fit" height="200.4mm"
content-width="scale-to-fit" width=3D"189.9mm" src="url({@href})"/> =
works.

I have found http://www.onlineconversion.com/length_common.htm useful to convert between mm and inches to determine dimensions - I recommend using the same standard of measurement.

20.

Wrapping text round an image

Ken Holman



>I have an image, and I want to have text to flow
>around it like this pattern:
>
>   text1   image___
>   text1   |       |
>   text2   |       |
>   text2   |_______|
>text2 text2 text2....
>
>my code is:
>
><fo:float float="left">
>  <fo:block>text1  text1
>    <fo:external-graphic src="url(blomma.jpg)"/>
>text2 text2 text2 text2.....
>  </fo:block>
></fo:float>
>but it seems that it doesn't work as I expected.

You are looking at it backwards. You should be floating the image so that the text flow wraps around the floated image.

>Can somebody help me please?
>Does xep support float and floats attributes?

Indeed it does. Consider the example below. The float is marked to go at the end of the line (using start/end is better than using left/right for internationalized stylesheets), the text is then just part of the regular flow and flows around the floated image.


<?xml version="1.0" encoding="US-ASCII"?>
<root xmlns="http://www.w3.org/1999/XSL/Format"
      font-family="Times" font-size="20pt">

  <layout-master-set>
    <simple-page-master master-name="frame"
                        page-height="297mm" page-width="210mm"
                        margin-top="15mm" margin-bottom="15mm"
                        margin-left="15mm" margin-right="15mm">
      <region-body region-name="frame-body"/>
    </simple-page-master>
  </layout-master-set>

  <page-sequence master-reference="frame">
    <flow flow-name="frame-body">
      <float float="end">
        <block>
          <external-graphic alignment-baseline="after-edge"
                            width="5cm" content-width="5cm"
                            src='url("AnImage.jpg")'/>
        </block>
      </float>
      <block>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi est
eros, auctor quis, rutrum a, bibendum vitae, enim. Suspendisse dolor
elit, dapibus non, tincidunt quis, sodales vitae, magna. Maecenas
odio ipsum, bibendum id, feugiat luctus, aliquet sed, mauris.
Suspendisse ut sem suscipit lectus volutpat nonummy. Nam at ipsum ut
est luctus scelerisque. Duis id nulla eu pede interdum elementum.
Suspendisse lacinia, ante ut lobortis rhoncus, dolor purus tempor
pede, ut accumsan risus ante eu tellus. Mauris in nisl a ligula
fringilla pretium. Nunc et lacus in orci fringilla sodales. Aenean
feugiat justo. In hac habitasse platea dictumst. Nam ac urna sit amet
augue facilisis sodales. Integer lacinia vulputate wisi. Nullam
posuere magna eu ante. Integer in nisl. Sed enim tellus, nonummy
vitae, scelerisque a, viverra id, tortor.
      </block>
    </flow>
  </page-sequence>
</root>

21.

Align graphic with top of text

Ken Holman



>What I want for inline image alignment is this, :
>
>  +-+  Blahhhh, Blahhh, Blahhh, Blahhh, Blahhh,
>   |  |
>  + +

That is an incorrect default ... the default is that the base of the image sits on top of the text baseline.

>In XEP, I get this:
>
>  +-+
>   | |
>  +-+  Blahhhh, Blahhh, Blahhh, Blahhh, Blahhh,

Yep!

>
Basically, I want the image to output from the top down, aligned
>with the top of the text with XEP. Is this possible?

Absolutely it is: in XSL-FO the alignment-adjust= specifies which point of the object is to be used for alignment, while the alignment-baseline= specifies the point of the line to which the object is aligned.

So you want to align the before-edge of your image with the before-edge of the line. Seems to work fine in XEP.

I hope the example below helps. Just plug in the name of your image in place of "star.gif".

<?xml version="1.0" encoding="US-ASCII"?><!--align2.fo-->
<root xmlns="http://www.w3.org/1999/XSL/Format"
      font-family="Times" font-size="20pt">

  <layout-master-set>
    <simple-page-master master-name="frame"
                        page-height="297mm" page-width="210mm"
                        margin-top="15mm" margin-bottom="15mm"
                        margin-left="15mm" margin-right="15mm">
      <region-body region-name="frame-body"/>
    </simple-page-master>
  </layout-master-set>

  <page-sequence master-reference="frame">
    <flow flow-name="frame-body" xmlns="http://www.w3.org/1999/XSL/Format">
      <block>
        This is a test of image alignment; "Xy" is used
        to show the location of the top, baseline, and
        bottom of the character box.</block>
      <block>
        Default: image sits on baseline
        Xy<external-graphic src='url("star.gif")'/>yX
      </block>
      <block>
        Aligning the base to the bottom of the line:
        Xy<external-graphic src='url("star.gif")'
                            alignment-baseline="after-edge"/>yX
      </block>
      <block>
        Aligning the top to the top of the line:
        Xy<external-graphic src='url("star.gif")'
                            alignment-adjust="before-edge"
                            alignment-baseline="before-edge"/>yX
      </block>
      <block>End of test</block>
    </flow>
  </page-sequence>
</root>