[ 
https://issues.apache.org/jira/browse/PDFBOX-3099?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

David KELLER updated PDFBOX-3099:
---------------------------------
    Description: 
What is the best way to find a suitable font ?

I assume that PDFont cannot load directly a java.awt.Font.

But I want to parse a PDF and find a text occurrence using "TextPosition 
textStart;"

A this moment I can retrieve the good font using  :
                float fontSize = textStart.getFontSize();
                PDFont font = textStart.getFont();

But in the PDF, the font is not complete (partial incorporated font).
So If I want to replace "#date#" by  "10 Novembre 2015", i can have this result 
 "1? Novembre 2?1?". Because "0" is not present in the "partial incorporated 
font"

So I need to determine the font used and find on the server the TTF font 
source, and then load it using .

I found on forums this thread 
http://stackoverflow.com/questions/13077611/how-to-retrieve-the-native-font-name-in-java

Then I wrote this source code to "do the job"

{code}

        public static PDFont findSuitableFont(PDDocument pdDocument, PDFont 
font) {
                
                String fontName = font.getFontDescriptor().getFontName();
                fontName = fontName.replace("+", "");
                fontName = fontName.replace("ABCDEE", "");
                
                GraphicsEnvironment graphicsEnvironment = 
GraphicsEnvironment.getLocalGraphicsEnvironment();
            Font[] fonts = graphicsEnvironment.getAllFonts(); // Get the fonts
            for (Font existingFont : fonts) {
                    if (existingFont.getFontName().equals(fontName)) {
                              try {

                                      return getPDFont(existingFont, 
pdDocument);

                              } catch (Exception e) {
                                  e.printStackTrace();
                              }
                    }
            }
            
            return null;
        }


        public static PDFont getPDFont(Font font, PDDocument pdDocument)
        throws NoSuchFieldException, SecurityException, 
IllegalArgumentException, IllegalAccessException, 
        InvocationTargetException, NoSuchMethodException, IOException
        {
                Method method = font.getClass().getDeclaredMethod("getFont2D");
                method.setAccessible(true);
                Font2D f = (Font2D) method.invoke(font);

                return getPDFont(f, pdDocument);
        }

        public static PDFont getPDFont(Font2D font, PDDocument pdDocument) 
        throws NoSuchFieldException, SecurityException, 
IllegalArgumentException, IllegalAccessException, IOException {
                if (font instanceof CompositeFont) {
                        System.out.println("Font '" + 
font.getFontName(Locale.getDefault()) + "' is composed of:");

                        CompositeFont cf = (CompositeFont) font;
                        PDFont pdFont = null;
                        for (int i = 0; i < cf.getNumSlots(); i++) {
                                PhysicalFont pf = cf.getSlotFont(i);
                                pdFont = getPDFont(pf, pdDocument);
                                
                                if (pdFont != null) {
                                        return pdFont;
                                }
                        }
                } else {
                        Field platName = 
PhysicalFont.class.getDeclaredField("platName");
                        platName.setAccessible(true);
                        String fontPath = (String)platName.get(font);
                        platName.setAccessible(false);
                        System.out.println("-> " + font);
                        System.out.println("fontPath: " + fontPath);
                        return PDTrueTypeFont.loadTTF(pdDocument, fontPath);
                }
                
                return null;
        }


        protected void findSuitableFont(TextPosition textStart) {
                float fontSize = textStart.getFontSize();
                PDFont font = textStart.getFont();
                logger.info("fontSize: " + fontSize);
                logger.info("font: " + font.getBaseFont());

                PDFont pdFont = findSuitableFont(document, font);
                logger.info("suitable font: " + pdFont.getBaseFont());
     }

{code}

Is it a best way to do it ?


  was:
What is the best way to find a suitable font ?

I assume that PDFont cannot load directly a java.awt.Font.

But I want to parse a PDF and find a text occurrence using "TextPosition 
textStart;"

A this moment I can retrieve the good font using  :
                float fontSize = textStart.getFontSize();
                PDFont font = textStart.getFont();

But in the PDF, the font is not complete (partial incorporated font).
So If I want to replace "#date#" by  "10 Novembre 2015", i can have this result 
 "1? Novembre 2?1?". Because "0" is not present in the "partial incorporated 
font"

So I need to determine the font used and find on the server the TTF font 
source, and then load it using .

I found on forums this thread 
http://stackoverflow.com/questions/13077611/how-to-retrieve-the-native-font-name-in-java

Then I wrote this source code to "do the job"


        public static PDFont findSuitableFont(PDDocument pdDocument, PDFont 
font) {
                
                String fontName = font.getFontDescriptor().getFontName();
                fontName = fontName.replace("+", "");
                fontName = fontName.replace("ABCDEE", "");
                
                GraphicsEnvironment graphicsEnvironment = 
GraphicsEnvironment.getLocalGraphicsEnvironment();
            Font[] fonts = graphicsEnvironment.getAllFonts(); // Get the fonts
            for (Font existingFont : fonts) {
                    if (existingFont.getFontName().equals(fontName)) {
                              try {
                                      return getPDFont(existingFont, 
pdDocument);
                              } catch (Exception e) {
                                  e.printStackTrace();
                              }
                    }
            }
            
            return null;
        }

        public static PDFont getPDFont(Font font, PDDocument pdDocument)
        throws NoSuchFieldException, SecurityException, 
IllegalArgumentException, IllegalAccessException, 
        InvocationTargetException, NoSuchMethodException, IOException
        {
                Method method = font.getClass().getDeclaredMethod("getFont2D");
                method.setAccessible(true);
                Font2D f = (Font2D) method.invoke(font);

                return getPDFont(f, pdDocument);
        }

        public static PDFont getPDFont(Font2D font, PDDocument pdDocument) 
        throws NoSuchFieldException, SecurityException, 
IllegalArgumentException, IllegalAccessException, IOException {
                if (font instanceof CompositeFont) {
                        System.out.println("Font '" + 
font.getFontName(Locale.getDefault()) + "' is composed of:");

                        CompositeFont cf = (CompositeFont) font;
                        PDFont pdFont = null;
                        for (int i = 0; i < cf.getNumSlots(); i++) {
                                PhysicalFont pf = cf.getSlotFont(i);
                                pdFont = getPDFont(pf, pdDocument);
                                
                                if (pdFont != null) {
                                        return pdFont;
                                }
                        }
                } else {
                        Field platName = 
PhysicalFont.class.getDeclaredField("platName");
                        platName.setAccessible(true);
                        String fontPath = (String)platName.get(font);
                        platName.setAccessible(false);
                        System.out.println("-> " + font);
                        System.out.println("fontPath: " + fontPath);
                        return PDTrueTypeFont.loadTTF(pdDocument, fontPath);
                }
                
                return null;
        }


        protected void findSuitableFont(TextPosition textStart) {
                float fontSize = textStart.getFontSize();
                PDFont font = textStart.getFont();
                logger.info("fontSize: " + fontSize);
                logger.info("font: " + font.getBaseFont());

                PDFont pdFont = findSuitableFont(document, font);
                logger.info("suitable font: " + pdFont.getBaseFont());
     }


Is it a best way to do it ?



> Find suitable PDFont
> --------------------
>
>                 Key: PDFBOX-3099
>                 URL: https://issues.apache.org/jira/browse/PDFBOX-3099
>             Project: PDFBox
>          Issue Type: Improvement
>          Components: PDModel
>    Affects Versions: 1.8.8
>         Environment: Windows / Linux
>            Reporter: David KELLER
>
> What is the best way to find a suitable font ?
> I assume that PDFont cannot load directly a java.awt.Font.
> But I want to parse a PDF and find a text occurrence using "TextPosition 
> textStart;"
> A this moment I can retrieve the good font using  :
>               float fontSize = textStart.getFontSize();
>               PDFont font = textStart.getFont();
> But in the PDF, the font is not complete (partial incorporated font).
> So If I want to replace "#date#" by  "10 Novembre 2015", i can have this 
> result  "1? Novembre 2?1?". Because "0" is not present in the "partial 
> incorporated font"
> So I need to determine the font used and find on the server the TTF font 
> source, and then load it using .
> I found on forums this thread 
> http://stackoverflow.com/questions/13077611/how-to-retrieve-the-native-font-name-in-java
> Then I wrote this source code to "do the job"
> {code}
>       public static PDFont findSuitableFont(PDDocument pdDocument, PDFont 
> font) {
>               
>               String fontName = font.getFontDescriptor().getFontName();
>               fontName = fontName.replace("+", "");
>               fontName = fontName.replace("ABCDEE", "");
>               
>               GraphicsEnvironment graphicsEnvironment = 
> GraphicsEnvironment.getLocalGraphicsEnvironment();
>           Font[] fonts = graphicsEnvironment.getAllFonts(); // Get the fonts
>           for (Font existingFont : fonts) {
>                   if (existingFont.getFontName().equals(fontName)) {
>                             try {
>                                     return getPDFont(existingFont, 
> pdDocument);
>                             } catch (Exception e) {
>                                 e.printStackTrace();
>                             }
>                   }
>           }
>           
>           return null;
>       }
>       public static PDFont getPDFont(Font font, PDDocument pdDocument)
>       throws NoSuchFieldException, SecurityException, 
> IllegalArgumentException, IllegalAccessException, 
>       InvocationTargetException, NoSuchMethodException, IOException
>       {
>               Method method = font.getClass().getDeclaredMethod("getFont2D");
>               method.setAccessible(true);
>               Font2D f = (Font2D) method.invoke(font);
>               return getPDFont(f, pdDocument);
>       }
>       public static PDFont getPDFont(Font2D font, PDDocument pdDocument) 
>       throws NoSuchFieldException, SecurityException, 
> IllegalArgumentException, IllegalAccessException, IOException {
>               if (font instanceof CompositeFont) {
>                       System.out.println("Font '" + 
> font.getFontName(Locale.getDefault()) + "' is composed of:");
>                       CompositeFont cf = (CompositeFont) font;
>                       PDFont pdFont = null;
>                       for (int i = 0; i < cf.getNumSlots(); i++) {
>                               PhysicalFont pf = cf.getSlotFont(i);
>                               pdFont = getPDFont(pf, pdDocument);
>                               
>                               if (pdFont != null) {
>                                       return pdFont;
>                               }
>                       }
>               } else {
>                       Field platName = 
> PhysicalFont.class.getDeclaredField("platName");
>                       platName.setAccessible(true);
>                       String fontPath = (String)platName.get(font);
>                       platName.setAccessible(false);
>                       System.out.println("-> " + font);
>                       System.out.println("fontPath: " + fontPath);
>                       return PDTrueTypeFont.loadTTF(pdDocument, fontPath);
>               }
>               
>               return null;
>       }
>       protected void findSuitableFont(TextPosition textStart) {
>               float fontSize = textStart.getFontSize();
>               PDFont font = textStart.getFont();
>               logger.info("fontSize: " + fontSize);
>               logger.info("font: " + font.getBaseFont());
>               PDFont pdFont = findSuitableFont(document, font);
>               logger.info("suitable font: " + pdFont.getBaseFont());
>      }
> {code}
> Is it a best way to do it ?



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to