Forum How do I...?

What forms does Prince support css clip-path

daneren2005
I have a document with some dynamically created svg that I define like this:

<div style="width: 254.98px; height: 298.894px; clip-path: url("#Mask-1"); -webkit-clip-path: url("#Mask-1");">
  <img src="src">
</div>

<svg id="globalMaskDefinitions" height="0" width="0">
  <defs>
    <clipPath clipPathUnits="objectBoundingBox" id="Mask-1">
      <rect rx=".2px" ry=".15px" height="1" width="1" y="0" x="0"/>
    </clipPath>
  </defs>
</svg>


This works in Chrome and FF, but not in Prince. I'm guessing that Prince does not support svg embedded in the html document. What form does Prince accept it? If I put getSvg.php?type=1 in the url (and obviously make a getSvg.php function which returns the same thing I embedded in the DOM), will it work. If not, how else am I supposed to get clip-path working?
mikeday
Prince does not support the clip-path URL on <div> elements. Actually, I didn't realise browsers support that, either. :)
daneren2005
Does Prince support clip-path url's pointing to a embedded svg element if it is on the img? That's an easy enough fix if so.
mikeday
Prince only supports clip-paths within SVG, so the clip-path can't be applied to an <img> element, but it can be applied inside an <svg> element.
daneren2005
Is there any plan to add support for clip-path's on an <img> element?
mikeday
Well there wasn't, but now that you've asked for it, maybe? :)

In the meantime you can get the same effect by replacing the <img> with <svg><image/></svg>, although you might find that less convenient.

Actually, specifying a border-radius will also apply a clip path, but only the kind of circular clipping that border-radius can provide.
daneren2005
I am trying to switch out every img with <svg><image></svg> right now. True it's less convenient, but if it works I will be happy. In the future you will probably see more people trying to apply svg to <img> now that browsers support it, so it might not be a bad idea ;)
mikeday
There is also the filter property which has snuck into CSS. Over time, SVG might eat up the rest of the document, if it can figure out a proper model for text at least. :)
daneren2005
That still does not seem to work. Here is a fiddle with what I am trying to do. I tried applying the clip-path to both the svg element and the underlining image element. Can you tell me what I am doing wrong with this?
mikeday
Sorry, references to clip paths and other SVG defs only work when they are in the same SVG "island". It means in this case the clip path would need to be repeated inside each separate <svg> element. This is a limitation of Prince we hope to fix in a future release.
daneren2005
Ok good news is that worked. Bad news is that polygon clip paths do not seem to work. In fact it removes the image altogether.

Works:
<clipPath clipPathUnits="objectBoundingBox">
  <rect x="0" y="0" width="1" height="1" ry=".15px" rx=".2px"/>
</clipPath>

<clipPath clipPathUnits="objectBoundingBox">
  <circle x="0" y="0" width="1" height="1" cx=".5px" cy=".5px" r=".5px" />
</clipPath>


Does not work:
<clipPath clipPathUnits="objectBoundingBox">
  <polygon points=".5 0, .7 .3, 1 .38, .75 .65, .82 1, .49 .84, .18 1, .25 .65, 0 .38, .30 .30"/>
</clipPath>


Is that something I am doing wrong, or a limitation of Prince? Notice that I am doing fractions in there, not absolute points.

PS: Here is the code to replace <img> with a working <svg> in case it helps anyone else:
var width = $(this).width();
var height = $(this).height();
var url = this.src;
				
// Get the svg we are trying to apply
var clipPath = this.style['clip-path'];
clipPath = clipPath.slice(5, -2);
var svg = $(clipPath);
svg = svg[0].outerHTML;
				
// Replace this img with a <svg><image><def></svg>
var image = $('<svg width="' + width + '" height="' + height + '"><image xlink:href="' + url + '" width="' + width + '" height="' + height + '" style="clip-path: ' + this.style['clip-path'].replace(/"/ig, "'") + ';" />' + svg + '</svg>');
$(this).replaceWith(image);

Edited by daneren2005

mikeday
It looks like we have trouble with clipPathUnits="objectBoundingBox" on the clip path. We are investigating the issue.
daneren2005
Alright, let me know. clipPathUnits="objectBoundingBox" was the only way I was able to find which did percentages instead of absolutes. If Prince supports another way I would be find moving to it, I just need the masks to stay generalized for any size images.
mikeday
Right, hopefully we should have an updated alpha version ready in the next couple of days. Which platform are you running Prince on?

Edited by mikeday

daneren2005
Ubuntu 14.04
mikeday
We have an updated alpha version for 64-bit Ubuntu 14.04 available now, and the 32-bit packages will be available tomorrow. This should fix the clip path units issue, and some other SVG issues.

Edited by mikeday

daneren2005
Ah yes, I forgot about the issues that I was getting with the last alpha you guys uploaded for me. I still can't install them because it crashes and refuses to run and I can't figure out why.

Fri Jan 30 10:27:17 2015: /usr/lib/prince/license/license.dat: error: can't open input file: No such file or directory
Fri Jan 30 10:27:17 2015: warning: failed to load external entity "/usr/lib/prince/license/license.dat"
Fri Jan 30 10:27:17 2015: /usr/lib/prince/license/license.dat: warning: could not load license
Fri Jan 30 10:27:18 2015: /usr/lib/prince/style/common.css: warning: can't open input file: No such file or directory
Fri Jan 30 10:27:18 2015: /usr/lib/prince/style/xhtml-ns.css: warning: can't open input file: No such file or directory
Fri Jan 30 10:27:26 2015: internal error: no available fonts
daneren2005
Did you guys change the format for fonts so something like:

src: url("/app/private/PlicCanvas/prince/fonts/msttcorefonts/Trebuchet_MS_Bold_Italic.ttf")
doesn't work anymore?
mikeday
No, that should be fine, assuming that /app is an actual path. But all those errors above seem to suggest that Prince is not installed in /usr/lib/prince, is this the case? Did you install the .deb package or the .tar.gz?
daneren2005
I installed the .deb and copied it from /usr/lib/prince to another location. I have verified that that location exists a few times. Sorry the first error log was from me trying to execute against the /usr/lib/prince version to see if I got the same errors and I did. What's strange is that the older version works fine still when I revert back to it. It's probably something stupid that I just need to hunt down :/
mikeday
Prince finds its data files relative to its binary location, eg. if the binary is in /path/to/bin/prince, then the style sheets files will be in /path/to/style/ and so on.

So if you add it to your PATH and just run "prince" it cannot find its files unless you explicitly add --prefix=/path/to on the command-line.

We normally workaround that by having a one line shell script in /usr/bin/prince that calls the binary with a full absolute path.
daneren2005
Edit: Removed

Edited by daneren2005

daneren2005
Nevermind, I think I figured out the difference. In the latest builds of Prince, supplying a fileroot seems to break things.

This works:
prince example.html -o test.pdf -v


This breaks:
prince example.html -o test.pdf -v --fileroot=/var/elements

with
prince: Converting document...
prince: internal error: no available fonts


This worked before.

Edited by daneren2005

daneren2005
I am happy to report that using the latest alpha all the masks that I have tried seem to work great. Thank you for your great support in this.
mikeday
Great. Regarding the --fileroot issue, it should be applied more consistent in latest builds, which could cause issues if you have some @font-face rules with absolute file paths that do not take the --fileroot settings into account.