jasper reports - Border Artifacts in JasperReport PDF Designed with iReport 5.1.0 -
when generating report jasperreports, seeing weird borders drawn reporting engine. borders drawn lines jut out @ 100% zoom level, seen in image. means when attempt draw square textbox, not square unless zoom in 150% more. here image showing issue.
am doing wrong when setting border settings in ireport? how can fix problem?
i had same problem. when exporting tables pdf , using thin table borders, lines of cell borders seem overstrike borders of table 1 pixel. visual artifacts visible in pdf viewers (they visible in adobe reader) , @ zoom levels. appearance of artifacts changes when line art smoothing turned on or off in pdf viewer. if zoom on overstrike @ maximal level, see lines drawn correctly - artifacts made pdf viewer when scaling document.
when checking jasperreports code, i've found pdf export draws table border 4 single lines. drawn no caps (the line cut off @ end). when drawing square border way, corners not connect completely, each line drawn longer border compensate missing cap. algorithm seems correct me, there going on in adobe reader, rounding , image "improvements" cause image artifacts appear.
i able come solution fixes issue in case. have subclassed jrpdfexporter , modified code draws borders. usage simple, use class instead of jrpdfexporter. use jasperreports 5.0.0.
package cz.jwa.jasper; import java.awt.color; import net.sf.jasperreports.engine.jrlinebox; import net.sf.jasperreports.engine.jrpen; import net.sf.jasperreports.engine.jrprintelement; import net.sf.jasperreports.engine.export.jrpdfexporter; import net.sf.jasperreports.engine.export.legacy.borderoffset; import net.sf.jasperreports.engine.type.linestyleenum; import com.lowagie.text.rectangle; import com.lowagie.text.pdf.pdfcontentbyte; public class jwapdfexporter extends jrpdfexporter { protected void exportbox(jrlinebox box, jrprintelement element) { if(!isboxvisible(box)) return; pdfcontentbyte.setlinecap(pdfcontentbyte.line_cap_projecting_square); float x1 = element.getx() + getoffsetx(); float y1 = jasperprint.getpageheight() - element.gety() - getoffsety(); float x2 = element.getx() + getoffsetx() + element.getwidth(); float y2 = jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight(); rectangle r = new rectangle(x1, y2, x2, y1); int borderflag = 0; boolean same = true; float linewidth = 0; color linecolor = null; if(box.getleftpen().getlinewidth().floatvalue() > 0f) { borderflag |= rectangle.left; linewidth = box.getleftpen().getlinewidth().floatvalue(); linecolor = box.getleftpen().getlinecolor(); } if(box.gettoppen().getlinewidth().floatvalue() > 0f) { borderflag |= rectangle.top; if(linewidth == 0) { linewidth = box.gettoppen().getlinewidth().floatvalue(); linecolor = box.gettoppen().getlinecolor(); } else if(linewidth != box.gettoppen().getlinewidth().floatvalue() || !linecolor.equals(box.gettoppen().getlinecolor())) { same = false; } } if(box.getrightpen().getlinewidth().floatvalue() > 0f) { borderflag |= rectangle.right; if(linewidth == 0) { linewidth = box.getrightpen().getlinewidth().floatvalue(); linecolor = box.getrightpen().getlinecolor(); } else if(linewidth != box.getrightpen().getlinewidth().floatvalue() || !linecolor.equals(box.getrightpen().getlinecolor())) { same = false; } } if(box.getbottompen().getlinewidth().floatvalue() > 0f) { borderflag |= rectangle.bottom; if(linewidth == 0) { linewidth = box.getbottompen().getlinewidth().floatvalue(); linecolor = box.getbottompen().getlinecolor(); } else if(linewidth != box.getbottompen().getlinewidth().floatvalue() || !linecolor.equals(box.getbottompen().getlinecolor())) { same = false; } } if(same) { r.setborder(borderflag); r.setbordercolor(linecolor); r.setborderwidth(linewidth); pdfcontentbyte.rectangle(r); pdfcontentbyte.stroke(); pdfcontentbyte.setlinedash(0.0f); pdfcontentbyte.setlinecap(pdfcontentbyte.line_cap_projecting_square); } else { super.exportbox(box, element); } } private boolean isboxvisible(jrlinebox box) { return box.getleftpen().getlinewidth().floatvalue() > 0f || box.gettoppen().getlinewidth().floatvalue() > 0f || box.getrightpen().getlinewidth().floatvalue() > 0f || box.getbottompen().getlinewidth().floatvalue() > 0f ; } protected void exporttoppen( jrpen toppen, jrpen leftpen, jrpen rightpen, jrprintelement element) { if (toppen.getlinewidth().floatvalue() > 0f) { float leftoffset = 0; //leftpen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(leftpen); float rightoffset = 0; //rightpen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(rightpen); preparepen(pdfcontentbyte, toppen, pdfcontentbyte.line_cap_butt); if (toppen.getlinestylevalue() == linestyleenum.double) { float topoffset = toppen.getlinewidth().floatvalue(); pdfcontentbyte.moveto( element.getx() + getoffsetx() - leftoffset, jasperprint.getpageheight() - element.gety() - getoffsety() + topoffset / 3 ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() + rightoffset, jasperprint.getpageheight() - element.gety() - getoffsety() + topoffset / 3 ); pdfcontentbyte.stroke(); pdfcontentbyte.moveto( element.getx() + getoffsetx() + leftoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - topoffset / 3 ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() - rightoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - topoffset / 3 ); pdfcontentbyte.stroke(); } else { float topoffset = borderoffset.getoffset(toppen); pdfcontentbyte.moveto( element.getx() + getoffsetx() - leftoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - topoffset ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() + rightoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - topoffset ); pdfcontentbyte.stroke(); } } } protected void exportleftpen(jrpen toppen, jrpen leftpen, jrpen bottompen, jrprintelement element) { if (leftpen.getlinewidth().floatvalue() > 0f) { float topoffset = 0; //toppen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(toppen); float bottomoffset = 0; //bottompen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(bottompen); preparepen(pdfcontentbyte, leftpen, pdfcontentbyte.line_cap_butt); if (leftpen.getlinestylevalue() == linestyleenum.double) { float leftoffset = leftpen.getlinewidth().floatvalue(); pdfcontentbyte.moveto( element.getx() + getoffsetx() - leftoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() + topoffset ); pdfcontentbyte.lineto( element.getx() + getoffsetx() - leftoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() - bottomoffset ); pdfcontentbyte.stroke(); pdfcontentbyte.moveto( element.getx() + getoffsetx() + leftoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - topoffset / 3 ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + leftoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() + bottomoffset / 3 ); pdfcontentbyte.stroke(); } else { float leftoffset = borderoffset.getoffset(leftpen); pdfcontentbyte.moveto( element.getx() + getoffsetx() + leftoffset, jasperprint.getpageheight() - element.gety() - getoffsety() + topoffset ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + leftoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() - bottomoffset ); pdfcontentbyte.stroke(); } } } /** * */ protected void exportbottompen(jrpen leftpen, jrpen bottompen, jrpen rightpen, jrprintelement element) { if (bottompen.getlinewidth().floatvalue() > 0f) { float leftoffset = 0; //leftpen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(leftpen); float rightoffset = 0; //rightpen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(rightpen); preparepen(pdfcontentbyte, bottompen, pdfcontentbyte.line_cap_butt); if (bottompen.getlinestylevalue() == linestyleenum.double) { float bottomoffset = bottompen.getlinewidth().floatvalue(); pdfcontentbyte.moveto( element.getx() + getoffsetx() - leftoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() - bottomoffset / 3 ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() + rightoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() - bottomoffset / 3 ); pdfcontentbyte.stroke(); pdfcontentbyte.moveto( element.getx() + getoffsetx() + leftoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() + bottomoffset / 3 ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() - rightoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() + bottomoffset / 3 ); pdfcontentbyte.stroke(); } else { float bottomoffset = borderoffset.getoffset(bottompen); pdfcontentbyte.moveto( element.getx() + getoffsetx() - leftoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() + bottomoffset ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() + rightoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() + bottomoffset ); pdfcontentbyte.stroke(); } } } /** * */ protected void exportrightpen(jrpen toppen, jrpen bottompen, jrpen rightpen, jrprintelement element) { if (rightpen.getlinewidth().floatvalue() > 0f) { float topoffset = 0; //toppen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(toppen); float bottomoffset = 0; //bottompen.getlinewidth().floatvalue() / 2 - borderoffset.getoffset(bottompen); preparepen(pdfcontentbyte, rightpen, pdfcontentbyte.line_cap_butt); if (rightpen.getlinestylevalue() == linestyleenum.double) { float rightoffset = rightpen.getlinewidth().floatvalue(); pdfcontentbyte.moveto( element.getx() + getoffsetx() + element.getwidth() + rightoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() + topoffset ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() + rightoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() - bottomoffset ); pdfcontentbyte.stroke(); pdfcontentbyte.moveto( element.getx() + getoffsetx() + element.getwidth() - rightoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - topoffset / 3 ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() - rightoffset / 3, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() + bottomoffset / 3 ); pdfcontentbyte.stroke(); } else { float rightoffset = borderoffset.getoffset(rightpen); pdfcontentbyte.moveto( element.getx() + getoffsetx() + element.getwidth() - rightoffset, jasperprint.getpageheight() - element.gety() - getoffsety() + topoffset ); pdfcontentbyte.lineto( element.getx() + getoffsetx() + element.getwidth() - rightoffset, jasperprint.getpageheight() - element.gety() - getoffsety() - element.getheight() - bottomoffset ); pdfcontentbyte.stroke(); } } } private static void preparepen(pdfcontentbyte pdfcontentbyte, jrpen pen, int linecap) { float linewidth = pen.getlinewidth().floatvalue(); if (linewidth <= 0) { return; } pdfcontentbyte.setlinewidth(linewidth); pdfcontentbyte.setlinecap(linecap); color color = pen.getlinecolor(); pdfcontentbyte.setrgbcolorstroke(color.getred(), color.getgreen(), color.getblue()); switch (pen.getlinestylevalue()) { case double: { pdfcontentbyte.setlinewidth(linewidth / 3); pdfcontentbyte.setlinedash(0f); break; } case dotted: { switch (linecap) { case pdfcontentbyte.line_cap_butt: { pdfcontentbyte.setlinedash(linewidth, linewidth, 0f); break; } case pdfcontentbyte.line_cap_projecting_square: { pdfcontentbyte.setlinedash(0, 2 * linewidth, 0f); break; } } break; } case dashed: { switch (linecap) { case pdfcontentbyte.line_cap_butt: { pdfcontentbyte.setlinedash(5 * linewidth, 3 * linewidth, 0f); break; } case pdfcontentbyte.line_cap_projecting_square: { pdfcontentbyte.setlinedash(4 * linewidth, 4 * linewidth, 0f); break; } } break; } case solid: default: { pdfcontentbyte.setlinedash(0f); break; } } } }
Comments
Post a Comment