You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@pdfbox.apache.org by Kévin Sailly <ke...@gmail.com> on 2012/04/10 22:13:47 UTC
glyph width is wrong
Hello,
I have got some problems to render the word "Cœur" (that means "heart" in
French) because of the "œ" character, the glyph width is not the good value.
I am using FreeSerif truetype font downloadable from here :
http://packages.debian.org/squeeze/all/ttf-freefont
Generated PDFs can be accesed here:
http://www.4shared.com/office/mOkLEPGd/out2.html
http://www.4shared.com/office/kngqxy7X/out1.html
I am using version 1.6 of PDFBOX
First I try :
String message = "Cœur";
PDDocument doc = null;
try
{
doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
PDTrueTypeFont font = PDTrueTypeFont.loadTTF(doc,
"/usr/share/fonts/truetype/
freefont/FreeSerif.ttf");
Encoding e = EncodingManager.INSTANCE.getEncoding(
COSName.WIN_ANSI_ENCODING);
PDPageContentStream contentStream = new PDPageContentStream(doc,
page);
contentStream.beginText();
contentStream.setFont(font, 24);
contentStream.moveTextPositionByAmount(100, 700);
contentStream.drawString(message);
contentStream.endText();
contentStream.close();
doc.save("out1.pdf");
} catch (IOException e) {
e.printStackTrace();
} catch (COSVisitorException e) {
e.printStackTrace();
}
finally
{
if (doc != null)
{
try {
doc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
But the result out1.pdf facin the bug PDFBOX-1242 (
https://issues.apache.org/jira/browse/PDFBOX-1242)
So I am using code points to render the pdf:
String message = "Cœur";
PDDocument doc = null;
try
{
doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
PDTrueTypeFont font = PDTrueTypeFont.loadTTF(doc,
"/usr/share/fonts/truetype/freefont/FreeSerif.ttf");
Encoding e = EncodingManager.INSTANCE.getEncoding(
COSName.WIN_ANSI_ENCODING);
PDPageContentStream contentStream = new PDPageContentStream(doc,
page);
contentStream.beginText();
contentStream.setFont(font, 24);
contentStream.moveTextPositionByAmount(100, 700);
char[] mechars = message.toCharArray();
StringBuilder codesstring = new StringBuilder();
Map<String, Integer> m = e.getNameToCodeMap();
for (int i = 0; i < mechars.length; i++) {
char c = mechars[i];
String name = e.getNameFromCharacter(c);
int code = e.getCode(name);
codesstring.appendCodePoint(code);
}
contentStream.drawString(codesstring.toString());
contentStream.endText();
contentStream.close();
doc.save("out2.pdf");
} catch (IOException e) {
e.printStackTrace();
} catch (COSVisitorException e) {
e.printStackTrace();
}
finally
{
if (doc != null)
{
try {
doc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The glyph "œ" is correct now but the next letter partially recovert it (see
out2.pdf).
The character "EM DASH" have the same problem.
I looked at the PDTrueTypeFont class and the width looks correctly parsed
by PDFBOX:
339 : œ : 709 : 709.0
(inserting this in the class:
for( int i=0; i<widthValues.length ; i++ )
{
if(glyphToCCode[i]-firstChar < widths.size() &&
glyphToCCode[i]-firstChar >= 0
&& widths.get( glyphToCCode[i]-firstChar) == zero )
{
System.out.println(glyphToCCode[i] + " : " +(new
StringBuilder()).appendCodePoint(glyphToCCode[i]) + " : " + widthValues[i]
+ " : " + widthValues[i]*scaling);
widths.set( glyphToCCode[i]-firstChar,
widthValues[i]*scaling );
}
}
)
I also notice that the width used to render the glyph is the "zero" value :
float zero = 250;
defined in the method loadDescriptorDictionary of class PDTrueTypeFont.
I have no more clue to investigate as the glyph have is width correctly
defined, so help will be greatly appreciated!
Regards,
Kévin
Re: glyph width is wrong
Posted by Kévin Sailly <ke...@gmail.com>.
Hello,
I finally raped your code to achieve my end!
Into PDTrueTypeFont.java I have force the mapping of width to use the
choosen encoding:
Encoding e =
EncodingManager.INSTANCE.getEncoding(COSName.WIN_ANSI_ENCODING);
for( int i=0; i<widthValues.length ; i++ )
{
if(glyphToCCode[i]-firstChar < widths.size() &&
glyphToCCode[i]-firstChar >= 0
&& widths.get( glyphToCCode[i]-firstChar) == zero )
{
try {
widths.set( e.getCode(e.getNameFromCharacter(
(new StringBuilder()).appendCodePoint(
glyphToCCode[i]).toString().toCharArray()[0])),
widthValues[i]*scaling );
} catch (IOException x) {
widths.set( glyphToCCode[i]-firstChar,
widthValues[i]*scaling );
}
}
}
Then widths seems correct now.
Just notice that firstChar is hard coded to 0 in the original code, so I
think that you can remove it from.
Regards,
Kévin
2012/4/11 Kévin Sailly <ke...@gmail.com>
> Hello,
>
> I have found the reason (maybe).
> Using the code map to characters name here:
>
> Map<String, Integer> m = e.getNameToCodeMap();
> for (int i = 0; i < mechars.length; i++) {
> char c = mechars[i];
> String name = e.getNameFromCharacter(c);
> int code = e.getCode(name);
> codesstring.appendCodePoint(
> code);
> }
>
> Makes the method "getFontWidth(int charCode)" mapping to width of another
> character.
>
> What is the best method to correct this? map the widths with encoded
> codes, or changing method the getFontWidth(char charCode) using the correct
> char, not the code?
>
> Thanks,
> Kevin
>
>
> 2012/4/10 Kévin Sailly <ke...@gmail.com>
>
>> Hello,
>>
>> I have got some problems to render the word "Cœur" (that means "heart" in
>> French) because of the "œ" character, the glyph width is not the good value.
>>
>> I am using FreeSerif truetype font downloadable from here :
>> http://packages.debian.org/squeeze/all/ttf-freefont
>> Generated PDFs can be accesed here:
>> http://www.4shared.com/office/mOkLEPGd/out2.html
>> http://www.4shared.com/office/kngqxy7X/out1.html
>>
>> I am using version 1.6 of PDFBOX
>>
>>
>> First I try :
>> String message = "Cœur";
>> PDDocument doc = null;
>> try
>> {
>> doc = new PDDocument();
>> PDPage page = new PDPage();
>> doc.addPage(page);
>> PDTrueTypeFont font = PDTrueTypeFont.loadTTF(doc,
>> "/usr/share/fonts/truetype/
>> freefont/FreeSerif.ttf");
>>
>> Encoding e = EncodingManager.INSTANCE.getEncoding(
>> COSName.WIN_ANSI_ENCODING);
>> PDPageContentStream contentStream = new
>> PDPageContentStream(doc,
>> page);
>> contentStream.beginText();
>> contentStream.setFont(font, 24);
>> contentStream.moveTextPositionByAmount(100, 700);
>> contentStream.drawString(message);
>> contentStream.endText();
>> contentStream.close();
>> doc.save("out1.pdf");
>> } catch (IOException e) {
>> e.printStackTrace();
>> } catch (COSVisitorException e) {
>> e.printStackTrace();
>> }
>> finally
>> {
>> if (doc != null)
>> {
>> try {
>> doc.close();
>> } catch (IOException e) {
>> e.printStackTrace();
>> }
>> }
>> }
>>
>> But the result out1.pdf facin the bug PDFBOX-1242 (
>> https://issues.apache.org/jira/browse/PDFBOX-1242)
>>
>> So I am using code points to render the pdf:
>>
>> String message = "Cœur";
>> PDDocument doc = null;
>> try
>> {
>> doc = new PDDocument();
>> PDPage page = new PDPage();
>> doc.addPage(page);
>> PDTrueTypeFont font = PDTrueTypeFont.loadTTF(doc,
>> "/usr/share/fonts/truetype/freefont/FreeSerif.ttf");
>>
>> Encoding e = EncodingManager.INSTANCE.getEncoding(
>> COSName.WIN_ANSI_ENCODING);
>> PDPageContentStream contentStream = new
>> PDPageContentStream(doc,
>> page);
>> contentStream.beginText();
>> contentStream.setFont(font, 24);
>> contentStream.moveTextPositionByAmount(100, 700);
>> char[] mechars = message.toCharArray();
>> StringBuilder codesstring = new StringBuilder();
>> Map<String, Integer> m = e.getNameToCodeMap();
>> for (int i = 0; i < mechars.length; i++) {
>> char c = mechars[i];
>> String name = e.getNameFromCharacter(c);
>> int code = e.getCode(name);
>> codesstring.appendCodePoint(code);
>> }
>> contentStream.drawString(codesstring.toString());
>> contentStream.endText();
>> contentStream.close();
>> doc.save("out2.pdf");
>> } catch (IOException e) {
>> e.printStackTrace();
>> } catch (COSVisitorException e) {
>> e.printStackTrace();
>> }
>> finally
>> {
>> if (doc != null)
>> {
>> try {
>> doc.close();
>> } catch (IOException e) {
>> e.printStackTrace();
>> }
>> }
>> }
>>
>> The glyph "œ" is correct now but the next letter partially recovert it
>> (see out2.pdf).
>>
>> The character "EM DASH" have the same problem.
>>
>> I looked at the PDTrueTypeFont class and the width looks correctly parsed
>> by PDFBOX:
>>
>> 339 : œ : 709 : 709.0
>>
>> (inserting this in the class:
>> for( int i=0; i<widthValues.length ; i++ )
>> {
>> if(glyphToCCode[i]-firstChar < widths.size() &&
>> glyphToCCode[i]-firstChar >= 0
>> && widths.get( glyphToCCode[i]-firstChar) == zero
>> )
>> {
>> System.out.println(glyphToCCode[i] + " : " +(new
>> StringBuilder()).appendCodePoint(glyphToCCode[i]) + " : " + widthValues[i]
>> + " : " + widthValues[i]*scaling);
>> widths.set( glyphToCCode[i]-firstChar,
>> widthValues[i]*scaling );
>> }
>> }
>> )
>>
>> I also notice that the width used to render the glyph is the "zero" value
>> :
>> float zero = 250;
>> defined in the method loadDescriptorDictionary of class PDTrueTypeFont.
>>
>> I have no more clue to investigate as the glyph have is width correctly
>> defined, so help will be greatly appreciated!
>>
>> Regards,
>> Kévin
>>
>>
>
Re: glyph width is wrong
Posted by Kévin Sailly <ke...@gmail.com>.
Hello,
I have found the reason (maybe).
Using the code map to characters name here:
Map<String, Integer> m = e.getNameToCodeMap();
for (int i = 0; i < mechars.length; i++) {
char c = mechars[i];
String name = e.getNameFromCharacter(c);
int code = e.getCode(name);
codesstring.appendCodePoint(
code);
}
Makes the method "getFontWidth(int charCode)" mapping to width of another
character.
What is the best method to correct this? map the widths with encoded codes,
or changing method the getFontWidth(char charCode) using the correct char,
not the code?
Thanks,
Kevin
2012/4/10 Kévin Sailly <ke...@gmail.com>
> Hello,
>
> I have got some problems to render the word "Cœur" (that means "heart" in
> French) because of the "œ" character, the glyph width is not the good value.
>
> I am using FreeSerif truetype font downloadable from here :
> http://packages.debian.org/squeeze/all/ttf-freefont
> Generated PDFs can be accesed here:
> http://www.4shared.com/office/mOkLEPGd/out2.html
> http://www.4shared.com/office/kngqxy7X/out1.html
>
> I am using version 1.6 of PDFBOX
>
>
> First I try :
> String message = "Cœur";
> PDDocument doc = null;
> try
> {
> doc = new PDDocument();
> PDPage page = new PDPage();
> doc.addPage(page);
> PDTrueTypeFont font = PDTrueTypeFont.loadTTF(doc,
> "/usr/share/fonts/truetype/
> freefont/FreeSerif.ttf");
>
> Encoding e = EncodingManager.INSTANCE.getEncoding(
> COSName.WIN_ANSI_ENCODING);
> PDPageContentStream contentStream = new
> PDPageContentStream(doc,
> page);
> contentStream.beginText();
> contentStream.setFont(font, 24);
> contentStream.moveTextPositionByAmount(100, 700);
> contentStream.drawString(message);
> contentStream.endText();
> contentStream.close();
> doc.save("out1.pdf");
> } catch (IOException e) {
> e.printStackTrace();
> } catch (COSVisitorException e) {
> e.printStackTrace();
> }
> finally
> {
> if (doc != null)
> {
> try {
> doc.close();
> } catch (IOException e) {
> e.printStackTrace();
> }
> }
> }
>
> But the result out1.pdf facin the bug PDFBOX-1242 (
> https://issues.apache.org/jira/browse/PDFBOX-1242)
>
> So I am using code points to render the pdf:
>
> String message = "Cœur";
> PDDocument doc = null;
> try
> {
> doc = new PDDocument();
> PDPage page = new PDPage();
> doc.addPage(page);
> PDTrueTypeFont font = PDTrueTypeFont.loadTTF(doc,
> "/usr/share/fonts/truetype/freefont/FreeSerif.ttf");
>
> Encoding e = EncodingManager.INSTANCE.getEncoding(
> COSName.WIN_ANSI_ENCODING);
> PDPageContentStream contentStream = new
> PDPageContentStream(doc,
> page);
> contentStream.beginText();
> contentStream.setFont(font, 24);
> contentStream.moveTextPositionByAmount(100, 700);
> char[] mechars = message.toCharArray();
> StringBuilder codesstring = new StringBuilder();
> Map<String, Integer> m = e.getNameToCodeMap();
> for (int i = 0; i < mechars.length; i++) {
> char c = mechars[i];
> String name = e.getNameFromCharacter(c);
> int code = e.getCode(name);
> codesstring.appendCodePoint(code);
> }
> contentStream.drawString(codesstring.toString());
> contentStream.endText();
> contentStream.close();
> doc.save("out2.pdf");
> } catch (IOException e) {
> e.printStackTrace();
> } catch (COSVisitorException e) {
> e.printStackTrace();
> }
> finally
> {
> if (doc != null)
> {
> try {
> doc.close();
> } catch (IOException e) {
> e.printStackTrace();
> }
> }
> }
>
> The glyph "œ" is correct now but the next letter partially recovert it
> (see out2.pdf).
>
> The character "EM DASH" have the same problem.
>
> I looked at the PDTrueTypeFont class and the width looks correctly parsed
> by PDFBOX:
>
> 339 : œ : 709 : 709.0
>
> (inserting this in the class:
> for( int i=0; i<widthValues.length ; i++ )
> {
> if(glyphToCCode[i]-firstChar < widths.size() &&
> glyphToCCode[i]-firstChar >= 0
> && widths.get( glyphToCCode[i]-firstChar) == zero )
> {
> System.out.println(glyphToCCode[i] + " : " +(new
> StringBuilder()).appendCodePoint(glyphToCCode[i]) + " : " + widthValues[i]
> + " : " + widthValues[i]*scaling);
> widths.set( glyphToCCode[i]-firstChar,
> widthValues[i]*scaling );
> }
> }
> )
>
> I also notice that the width used to render the glyph is the "zero" value :
> float zero = 250;
> defined in the method loadDescriptorDictionary of class PDTrueTypeFont.
>
> I have no more clue to investigate as the glyph have is width correctly
> defined, so help will be greatly appreciated!
>
> Regards,
> Kévin
>
>