Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tab character is not visible in the PDF generated as glyph substitution not working #454

Closed
PallaviSaini opened this issue Nov 12, 2020 · 2 comments · Fixed by #519
Closed

Comments

@PallaviSaini
Copy link

Bug
Tab character is not visible in the PDF generated.
This is due to glyph substitutions are not done for tab character as per the TTF file.
Below is link to typography specs:
https://docs.microsoft.com/en-us/typography/opentype/spec/gsub

Below is code to Reproduce
package test;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.converter.pdf.PdfConverter;
import org.apache.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
/**
*

*/
public class OpenPdf {

public static void main(String[] args) throws XDocReportException, IOException {
	PdfOptions options = PdfOptions.create();
	String templatePath = "D:\\Workspace\\ThankYouNote_Template.docx";
	URL url = new File(templatePath).toURI().toURL();
	InputStream inputStream = url.openStream();
	IXDocReport xdocReport = XDocReportRegistry.getRegistry().loadReport(inputStream, null,
            TemplateEngineKind.Freemarker, false);
	FieldsMetadata metadata = xdocReport.createFieldsMetadata();
    metadata.setTemplateEngineKind("Freemarker");
    xdocReport.setFieldsMetadata(metadata);
	IContext context = xdocReport.createContext();
	context.put("name", "RAJ\tVIHAR");
	ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
	xdocReport.process(context, outputStream);

	XWPFDocument document = new XWPFDocument(new ByteArrayInputStream(outputStream.toByteArray()));
	ByteArrayOutputStream out = new ByteArrayOutputStream();
	PdfConverter.getInstance().convert(document, out, options);
	writeToPdfFile(out.toByteArray(), "D:\\Workspace\\ThankYouNote_Template.pdf");

}

private static void writeToPdfFile(byte[] fileContent, String path) {

	BufferedOutputStream bs = null;
	FileOutputStream fs = null;
	try {

		fs = new FileOutputStream(new File(path));
		bs = new BufferedOutputStream(fs);
		bs.write(fileContent);
		bs.close();
		bs = null;
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		IOUtils.closeQuietly(fs);
	}

}

}

Expected behavior
The text should be visible as "Raj Vihar" instead of "RajVihar". The rendered text in PDF should have a tab character in it.

Screenshot of current behaviour

image

System:

  • OS: Windows
  • Used Font: Times New Roman
@Wugengxian
Copy link

Wugengxian commented Apr 20, 2021

@asturio @PallaviSaini This issue is caused by that when we use \t, PdfChunk will change font to font-fallback/LiberationSans-Regular.ttf. But this font can not support \t, when it meet \t in bytesArray it will ignore it and don't encode it. So my solution is that when we use \t, use default font which actually support \t.
related code:

// Check if the chunk content is text
if (chunk.getContent().chars().allMatch(c -> (c >= 0x20 && c <= 0xFF))) {
// translation of the font-family to a PDF font-family
baseFont = f.getCalculatedBaseFont(false);
} else {
// translation to the embeddable free font
try {
baseFont = BaseFont.createFont("font-fallback/LiberationSans-Regular.ttf",
BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

\t not in the matrix:
if (metrics == null){
textLength--;
continue;
}

I have fix it solution. In the futher, I will study how to let other fonts to encode \t and give a better solution.
Test Code:

public class TabTest {
    public static void main(String[] args) throws FileNotFoundException, DocumentException {
        Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
        Document.compress = false;
        try {
            PdfWriter.getInstance(document,
                    new FileOutputStream("TabsTable.pdf"));
            document.open();
            Chunk a = new Chunk("data\\ttable");
            a.setFont(new Font(BaseFont.createFont("font-fallback/LiberationSans-Regular.ttf",
                    BaseFont.IDENTITY_H, BaseFont.EMBEDDED)));
            document.add(a);
        } catch (Exception de) {
            de.printStackTrace();
        }
        document.close();
    }
}

@asturio asturio mentioned this issue Apr 22, 2021
1 task
@asturio asturio linked a pull request Apr 22, 2021 that will close this issue
1 task
@asturio
Copy link
Member

asturio commented Apr 22, 2021

Thanks for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants