Recently we encountered a bug with one of our converted HTML5 files that was specific to Google Chrome, specifically to do with the bezierCurveTo function for canvas.
The HTML file contains a rectangular box with two rounded corners, below is it’s appearance in most web browsers and Chrome:
Upon inspection we found the problem code to be one specific bezierCurveTo function call. So in an effort to understand the problem I made a small test page to replicate it which you can see here.
The following is a snippet of that code showing how the image is drawn:
var height = 400; var width = 150; var curvature = 8; pdf.beginPath(); pdf.moveTo(0, 0); pdf.lineTo(0, height); pdf.lineTo(width - curvature, height); pdf.bezierCurveTo(width - curvature, height, width, height, width, height - curvature); pdf.lineTo(width, 0 + curvature); pdf.bezierCurveTo(width, curvature, width, 0, width - curvature, 0); pdf.fillStyle = 'rgb(0,0,0)'; pdf.fill();
For convenience sake I hard coded the values as variables so it was easier to modify. The variables height and width are self explanatory; curvature denotes how curved the two corners should be, lower values will create a smaller curve.
The lines begin at the top left hand side of the canvas and travel anticlockwise using normal lineTo commands until it reaches the bottom right hand side, whereupon we use a bézier curve to create a smooth corner.
This first bézier curve behaves normally and appearance stays consistent across all html5 supporting browsers we have tested on. After this bézier curve we use another simple lineTo command to traverse to the top right hand corner of the shape and then call a final bézier curve to finish the shape.
This is when the error in Chrome becomes apparent, up until this point all the browsers display the same. If the height is greater than the width (i.e. the box is a rectangle) the error occurs. In fact this can also happen with the first bezierCurveTo function if the width is greater than the height.
From a quick search I was able to find out that this issue was not present in previous version of Chrome and can also effect square shapes using bezier curves for all four corners.
One solution, as noted in that link, is to use the quadraticCurveTo function instead, however this affords less accuracy as it only takes one control point instead of two and because we are converting PDF files to HTML we cannot use quadratic curves as PDF files use bézier curves.
Another solution I found is to offset the bézier curves first control points y by a fractional amount: the smallest I have used is 0.000001
pdf.bezierCurveTo(width, 0.000001 + curvature, width, 0, width - curvature, 0);
Until there is a fix for the issue, offsetting the Y value seems like the likely workaround we will use in our PDF to HTML5 converter.
This post is part of our “HTML5 Article index” in these articles, we aim to help you understand the world of HTML5.
IDRsolutions develop a Java PDF library, a PDF forms to HTML5 converter, a PDF to HTML5 or SVG converter and a Java Image Library that doubles as an ImageIO replacement. On the blog our team post about anything interesting they learn about.