1

In the creation of PDF document based on information of a specific system, using fop, i cannot show special characters, showing '#' instead of the character and giving me this WARNS when i create the pdf.

12:49:18,637 WARN  [org.apache.fop.apps.FOUserAgent] (default task-3) Glyph "?" (0x11f, gbreve) not available in font "Helvetica".
12:49:18,640 WARN  [org.apache.fop.apps.FOUserAgent] (default task-3) Glyph "?" (0x15e, Scedilla) not available in font "Helvetica".
12:49:19,041 INFO  [org.apache.fop.apps.FOUserAgent] (default task-3) Rendered page #1.
12:49:19,203 WARN  [org.apache.fop.apps.FOUserAgent] (default task-3) Glyph "?" (0x11f, gbreve) not available in font "Helvetica-Bold".
12:49:19,206 WARN  [org.apache.fop.apps.FOUserAgent] (default task-3) Glyph "?" (0x15e, Scedilla) not available in font "Helvetica-Bold".

I already changed font family in .xsl but no progress, now it sits like that, i think this uses fop.xconf, which has all the fonts and types.

 <!-- Helvetica -->
        <font>
          <afp-font name="Helvetica" type="raster" codepage="T1V10500" encoding="Cp500">
....
</font>

and .xsl:

<fo:block-container absolute-position="absolute" left="25mm" top="42mm" width="160mm" height="100mm"
                                        background-color="rgb(178,178,178)">
                        <fo:block color="white" font-size="29pt">
                            <fo:inline font-weight="bold">PDF</fo:inline> Report <xsl:value-of select="year"/>
                        </fo:block>
                        <fo:block color="white" font-size="16pt" margin-top="3mm">
                            <xsl:value-of select="name"/>
                        </fo:block>
                        <fo:block color="white" font-size="16pt">
                            <xsl:value-of select="address"/>
                        </fo:block>
                    </fo:block-container>

what can i do more? this is new to me, and already saw some similar threads in Stackoverflow, but none of them really helped.

EDIT: Quick update, maybe the xconf is not used at all? because i already removed all from there and there's no change, cause i am trying to add FreeSerif but none happened..

Bruno
  • 374
  • 3
  • 12
  • Are you telling FOP to use your xconf file (either with the `-c file.xconf` from the command line, or within your java code)? – lfurini Feb 19 '20 at 14:38
  • 1
    An old answer of mine about [font configuration](https://stackoverflow.com/a/28251945/4453460) could come in handy. – lfurini Feb 19 '20 at 14:40
  • Do i need to create the /conf/ folder and place xconf file there? because i don't have it.. and my fopFactory doesn't have setUserConfig method to place the path to the fop.xconf file.. i am very lost here.. please help me – Bruno Feb 25 '20 at 10:36
  • You can have the xconf file whereever you prefer, and use the appropriate path when referring to its location. In order to reach a solution incrementally, I would suggest to call fop from the command line to check if the configuration is ok, and then set it in in your code. – lfurini Feb 25 '20 at 11:41
  • i am debugging the application, so i can see that the uri in FopFactory.newInstance(uri) is pointing to where my fop.xconf file is.. shouldn't it be enough? Onde thing that i saw debugging is the "fop.foUserAgent = Cannot find local variable 'fop'" i don't know.. i am really lost here.. – Bruno Feb 27 '20 at 10:21

2 Answers2

1

lfurini, i saw your old answer and i'am stuck an step 2, because i don't have that 'conf' dir. I'am using it on a Java program, i got it in src/main/resources/pdf/fopfactorybasedir inside that dir i have one folder to display the images on my pdf and fop.xconf file ( that i can't find anywhere in the code.. so that's why i am saying that is not used at all.. ) here's my code..

FopFactoryWithUserAgentAndTransformerFactoryService

@ApplicationScoped
        public class FopFactoryWithUserAgentAndTransformerFactoryService {
            private static final Logger LOG = 
    LoggerFactory.getLogger(FopFactoryWithUserAgentAndTransformerFactoryService.class);
            private static final String ROOT_PATH = "/pdf/fopfactorybasedir/";
            private final FopFactory fopFactory;
            private final FOUserAgent foUserAgent;
            private final TransformerFactory transformerFactory;

            public FopFactoryWithUserAgentAndTransformerFactoryService() throws URISyntaxException {
                final URI uri = FopFactoryWithUserAgentAndTransformerFactoryService.class.getResource(ROOT_PATH).toURI();
                LOG.info("fopBaseUri={}", uri);
                fopFactory = FopFactory.newInstance(uri);
                foUserAgent = fopFactory.newFOUserAgent();
                transformerFactory = TransformerFactory.newInstance();
            }

            public FopFactory getFopFactory() {
                return fopFactory;
            }
        public Fop newFop(final String outputFormat, final OutputStream out) throws FOPException {
                return fopFactory.newFop(outputFormat, foUserAgent, out);
            }
            ...

PDFFactory:

@ApplicationScoped
public class PdfFactory {

@Inject
private FopFactoryWithUserAgentAndTransformerFactoryService fopFactoryEtAl;

public PdfFactory() {

}

public PdfFactory(final FopFactoryWithUserAgentAndTransformerFactoryService fopFactoryEtAl) {
    this.fopFactoryEtAl = fopFactoryEtAl;
}
public ByteArrayDto generatePdfFromModelObject(final Object model, final String xslFileName)
....

The question is, how can i use my fop.xconf file? maybe if i use it, the will be enough... ?

Bruno
  • 374
  • 3
  • 12
1

Ok i figure it out. It was my fop.xconf file that was being ignored, i mean, i was with the default values when creating the pdf. So to fix it just edited the following files:

fop.xconf

...
<fonts>
<auto-detect/>
</fonts>
...

file.xsl

<fo:root font-family="Arial">
    <!-- rest of document -->
</fo:root

FopFactoryWithUserAgentAndTransformerFactoryService.java

//get the fop.xconf file to be read by the app
  final URL uri = getClass()
            .getClassLoader()
            .getResource("/pdf/fopfactorybasedir/fop.xconf");
   try{
        if(uri != null){
            fopFactory = FopFactory.newInstance(new File(uri.getFile()));
            foUserAgent = fopFactory.newFOUserAgent();
            transformerFactory = TransformerFactory.newInstance();
        }
    }catch (SAXException | IOException e)
    {
        e.printStackTrace();
    }

With this i got the xconf file injected! so remember, always check if the xconf file is being read by the app!

Bruno
  • 374
  • 3
  • 12