Bug #8374
openPDFJet unicode
0%
Description
public class WPdfImage extends WResource implements WPaintDevice {
private static final Logger logger = LoggerFactory.getLogger(WPdfImage.class);
private static Constructor<?> fontConstructor;
static {
for (Constructor<?> c : Font.class.getConstructors()) {
Class<?>[] paramTypes = c.getParameterTypes();
if (paramTypes.length == 4 &&
paramTypes[0] == PDF.class &&
paramTypes[1] == java.io.InputStream.class &&
paramTypes[2].isPrimitive() && paramTypes[2].equals(java.lang.Integer.TYPE) &&
paramTypes[3].isPrimitive() && paramTypes[3].equals(java.lang.Boolean.TYPE)) {
fontConstructor = c;
break;
}
}
}
PDFJet Font has no such constructor at all.
As a result custom font collection does not work:
private Font createFont(WFont font) {
if (fontConstructor != null) {
FontMatch fm = trueTypeFonts.matchFont(font);
Updated by Korneel Dumon over 3 years ago
Hi,
can you provide a code example that illustrates the problem?
Updated by Vladimir Savchik over 3 years ago
Korneel Dumon wrote in #note-1:
Hi,
can you provide a code example that illustrates the problem?
@Override
protected void handleRequest( WebRequest request , WebResponse response) throws IOException {
response.setContentType( "application/pdf" );
try {
PDF pdf = new PDF( response.getOutputStream() );
renderReport( pdf );
Page page = new Page( pdf , A4.PORTRAIT );
WPdfRenderer renderer = new WPdfRenderer( pdf , page );
ActionBase action = view.main.getAction();
renderer.addFontCollection( action.getLocalPath( Common.getPath( action.execrc.installPath , "fonts" ) ) );
renderer.setMargin( 2.54 );
renderer.setDpi( 96 );
String filePath = action.getWorkFilePath( "pdf.html" );
Common.createFileFromString( action.execrc , filePath , html );
action.trace( "pdf html copied to " + filePath );
renderer.render( html );
...
full at http://usvn.ahuman.org/svn/urmweb/trunk/src/org/urm/web/view/system/ReleaseNotesPDF.java
practically I forced jwt working by changing your code here:
private Font createFont(WFont font) {
/*
if (fontConstructor != null) {
FontMatch fm = trueTypeFonts.matchFont(font);
if (fm.isMatched()) {
try {
FileInputStream fis = new FileInputStream(fm.getFileName());
Font f = (Font)fontConstructor.newInstance(pdf, fis, CodePage.UNICODE, Embed.YES);
f.setSize(font.getSizeLength().toPixels());
return f;
} catch (IllegalArgumentException e) {
logger.error("IllegalArgumentException while creating font {}", font.getCssText(), e);
} catch (InstantiationException e) {
logger.error("InstantiationException while creating font {}", font.getCssText(), e);
} catch (IllegalAccessException e) {
logger.error("IllegalAccessException while creating font {}", font.getCssText(), e);
} catch (InvocationTargetException e) {
logger.error("InvocationTargetException while creating font {}", font.getCssText(), e);
} catch (FileNotFoundException e) {
logger.info("FileNotFoundException while creating font {}", font.getCssText(), e);
}
}
}
*/
FontMatch fm = trueTypeFonts.matchFont(font);
if (fm.isMatched()) {
try {
FileInputStream fis = new FileInputStream(fm.getFileName());
Font f = new Font(pdf, fis, Font.STREAM);
f.setSize(font.getSizeLength().toPixels());
return f;
} catch (Exception e) {
logger.info("Exception while creating font {}", font.getCssText(), e);
}
}
String name = PdfUtils.toBase14Font(font);
try {
Font f = new Font(pdf, name);
f.setSize(font.getSizeLength().toPixels());
return f;
} catch (Exception e) {
logger.info("Error creating font {}", font.getCssText(), e);
return null;
}
}
btw, added code to split long strings w/o whitespace, e.g. urls
@Override
public WTextItem measureText(CharSequence text, double maxWidth, boolean wordWrap) {
processChangeFlags();
if (wordWrap) {
if (maxWidth == -1) {
return new WTextItem(text, font.stringWidth(text.toString()));
} else {
String previousWord = null;
double previousWordWidth = 0;
int len = text.length();
for (int i = 0; i < len; ++i) {
double w;
if (Character.isWhitespace(text.charAt(i)))
w = font.stringWidth(text.subSequence(0, i).toString());
else if (i == len - 1)
w = font.stringWidth(text.subSequence(0, i + 1).toString());
else
continue;
String s = text.subSequence(0, i + 1).toString();
if (w > maxWidth) {
if (previousWord == null)
return measureTextExact(text, maxWidth);
/*return new WTextItem(s, w);*/
else
return new WTextItem(previousWord, previousWordWidth);
} else {
previousWord = s;
previousWordWidth = w;
}
}
return new WTextItem(text, font.stringWidth(text.toString()));
}
} else {
return new WTextItem(text, font.stringWidth(text.toString()));
}
}
private WTextItem measureTextExact(CharSequence text, double maxWidth) {
int len = text.length();
double width = 0;
for (int i = 0; i < len; ++i) {
double w = font.stringWidth(text.subSequence(0, i + 1).toString());
if (w > maxWidth)
return new WTextItem(text.subSequence(0, i).toString(), width);
width = w;
}
return new WTextItem(text, width);
}
Updated by Vladimir Savchik over 3 years ago
Problem finally - that default font is chosen, which has no cyrillic chars, and pdf is garbage there.
Updated by Roel Standaert over 3 years ago
I believe this is a limitation of the open source version of PDFJet. I think it simply does not support font embedding.
Updated by Vladimir Savchik over 3 years ago
Roel Standaert wrote in #note-4:
I believe this is a limitation of the open source version of PDFJet. I think it simply does not support font embedding.
maybe, but
- Trial version from PDFJet site does not contain 4-args constructor.
- I believe font matching and font embedding are different features.
Updated by Roel Standaert over 3 years ago
Yeah, things may have changed in the meantime. I think you still needed the font embedding feature (or just TTF font support) in PDFJet in order to actually do proper font matching, which was not in the open source version.