[
https://issues.apache.org/jira/browse/PDFBOX-1296?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13675800#comment-13675800
]
Tilman Hausherr commented on PDFBOX-1296:
-----------------------------------------
Sigh... Its now a year later and nothing has happened. Anyway, here's an
updated the fix for the current trunk, which I checked out with svn yesterday.
The changes are in canDisplayUpTo() and in the parts with //TH in drawString().
/**
*
* Font.canDisplayUpTo() is buggy:
* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6623219
*
http://stackoverflow.com/questions/1754697/displaying-chinese-text-in-an-applet
*
* @param font
* @param s
* @return -1 when all is good
*
* This method returns an offset into the String s which is the first
* character this Font cannot display without using the missing glyph code.
* If the Font can display all characters, -1 is returned.
*/
int canDisplayUpTo(Font font, String s)
{
if (!font.canDisplay(' ') || !font.canDisplay('a') ||
!font.canDisplay('A'))
{
return 0; //TH font.canDisplay does not always tell the truth
}
int len = s.length();
int index = 0;
while (index < len)
{
int codePoint = s.codePointAt(index);
if (!font.canDisplay(codePoint))
{
return index;
}
index += Character.charCount(codePoint);
}
return -1;
}
/**
* {@inheritDoc}
*/
public void drawString(String string, int[] codePoints, Graphics g, float
fontSize,
AffineTransform at, float x, float y) throws IOException
{
Font awtFont = getawtFont();
FontRenderContext frc = new FontRenderContext(new AffineTransform(),
true, true);
GlyphVector glyphs = null;
boolean useCodepoints = codePoints != null && isType0Font();
PDFont descendantFont = useCodepoints ? ((PDType0Font)
this).getDescendantFont() : null;
// symbolic fonts may trigger the same fontmanager.so/dll error as
described below
if (useCodepoints && !descendantFont.getFontDescriptor().isSymbolic())
{
PDCIDFontType2Font cid2Font = null;
if (descendantFont instanceof PDCIDFontType2Font)
{
cid2Font = (PDCIDFontType2Font) descendantFont;
}
if ((cid2Font != null && cid2Font.hasCIDToGIDMap()) ||
isFontSubstituted)
{
// we still have to use the string if a CIDToGIDMap is used
glyphs = awtFont.createGlyphVector(frc, string);
}
else
{
glyphs = awtFont.createGlyphVector(frc, codePoints);
}
}
else
{
// mdavis - fix fontmanager.so/dll on
sun.font.FileFont.getGlyphImage
// for font with bad cmaps?
// Type1 fonts are not affected as they don't have cmaps
//TH
/*
if (!isType1Font() && awtFont.canDisplayUpTo(string) != -1)
{
LOG.warn("Changing font on <" + string + "> from <"
+ awtFont.getName() + "> to the default font");
awtFont = Font.decode(null).deriveFont(1f);
}
*/
//TH
if (!isType1Font() && canDisplayUpTo(awtFont, string) != -1)
{
Font awtFontOld = awtFont;
String name = null;
String style;
String defText = "";
if (awtFont.getName().indexOf('+') > 0)
{
name =
awtFont.getName().substring(awtFont.getName().indexOf('+') + 1);
}
else if (awtFont.getName().startsWith("DejaVu") ||
awtFont.getName().startsWith("Liberation"))
{
if (awtFont.getName().startsWith("DejaVu Sans"))
{
name = "Lucida Sans";
}
else if (awtFont.getName().startsWith("Liberation Serif"))
{
name = "Times New Roman";
}
else if (awtFont.getName().startsWith("Liberation Sans"))
{
name = "Arial";
}
else if (awtFont.getName().startsWith("Liberation Mono"))
{
name = "Courier New";
}
else
{
name = "Lucida Sans";
}
}
if (name == null)
{
awtFont = Font.decode(null).deriveFont(1f);
defText = " (default font)";
}
else
{
switch (awtFont.getStyle())
{
case Font.BOLD:
style = "BOLD";
break;
case Font.ITALIC:
style = "ITALIC";
break;
case Font.PLAIN:
style = "PLAIN";
break;
default:
if (awtFont.getStyle() == (Font.BOLD | Font.ITALIC))
{
style = "BOLDITALIC";
}
else
{
style = "PLAIN";
}
}
if (awtFont.getName().endsWith("Bold"))
{
style = "BOLD";
}
else if (awtFont.getName().endsWith("Bold Italic"))
{
style = "BOLDITALIC";
}
else if (awtFont.getName().endsWith("Italic"))
{
style = "ITALIC";
}
awtFont = Font.decode(name + "-" + style + "-" +
Integer.toString(awtFont.getSize()));
}
LOG.warn("Changing font on <" + string + "> from <" +
awtFontOld + "> to <" + awtFont + ">" + defText);
}
glyphs = awtFont.createGlyphVector(frc, string);
if (isType1Font())
{
glyphs = remapGlyphs(glyphs, string);
}
}
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
writeFont(g2d, at, x, y, glyphs);
}
However the real problem is deeper. One of my test files (confidential, thus
not attached) is PDF/A, the font is included in the PDF itself, so my fallfack
solution shouldn't be used at all.
> Warnung: Changing font on < > from <AMAKEA+TimesNewRoman> to the default font
> -----------------------------------------------------------------------------
>
> Key: PDFBOX-1296
> URL: https://issues.apache.org/jira/browse/PDFBOX-1296
> Project: PDFBox
> Issue Type: Bug
> Components: PDModel
> Affects Versions: 1.6.0
> Environment: XP, JDK 1.7
> Reporter: Tilman Hausherr
> Attachments: outside-in-01.png, outside-in.pdf, shortcuts-01.png,
> shortcuts.pdf
>
>
> Pdfbox does not produce the correct fonts in the PNG file created with the
> following code and I get a lot of warnings:
> PDDocument document = null;
> try
> {
> document = PDDocument.load(pdfFile);
> List pages = document.getDocumentCatalog().getAllPages();
> int p = 0;
> for (Object pobj : pages)
> {
> PDPage page = (PDPage) pobj;
> ++p;
> BufferedImage bim = page.convertToImage();
> // Test with output in memory, to see the size
> ByteArrayOutputStream memout = new
> ByteArrayOutputStream();
> boolean memoutok = ImageIO.write(bim, "png", memout);
> if (!memoutok)
> System.err.println ("mem write failed for " + p);
> memout.reset();
> memout.close();
> // Test with output to png file
> String fname = String.format("%s-%02d.png", prefix, p);
> boolean foutok = ImageIO.write(bim, "png", new
> File(fname));
> if (!foutok)
> System.err.println ("file write failed for " + p);
> ....
> Apr 26, 2012 2:41:11 PM org.apache.pdfbox.util.PDFStreamEngine processOperator
> Information: unsupported/disabled operation: i
> Apr 26, 2012 2:41:12 PM org.apache.pdfbox.util.PDFStreamEngine processOperator
> Information: unsupported/disabled operation: ri
> Apr 26, 2012 2:41:12 PM org.apache.pdfbox.pdmodel.font.PDSimpleFont drawString
> Warnung: Changing font on < > from <AMAKEA+TimesNewRoman> to the default font
> Apr 26, 2012 2:41:13 PM org.apache.pdfbox.pdmodel.font.PDSimpleFont drawString
> Warnung: Changing font on < > from <AMAKEA+TimesNewRoman> to the default font
> Apr 26, 2012 2:41:13 PM org.apache.pdfbox.pdmodel.font.PDSimpleFont drawString
> Warnung: Changing font on <O> from <AMAKME+Arial,Bold> to the default font
> Apr 26, 2012 2:41:13 PM org.apache.pdfbox.pdmodel.font.PDSimpleFont drawString
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira