Sign In  Sign Up Live-Chat

Disadvantage of drawGlyphVector()

Last post 10-08-2007, 6:29 AM by tashiro. 6 replies.
Sort Posts: Previous Next
  •  09-06-2007, 6:59 AM 93750

    Disadvantage of drawGlyphVector()

    Hi,

    I use Metafiles for example to create PDFs with itext. I noticed that in some cases characters
    doesn't appear in the PDFs. Those characters are mostly characters of the Symbol font, which is not directly available on Unix machines.
    Normally itext has a facility to map fonts to solve the problem. But this can't be used because Metafile use drawGlyphVector() to draw all texts in the graphic. The produced glyphs have no information about the characters anymore and can't converted correctly. So itext convert them to Shapes.

    And this is the second drawback. Because all glyphs are rendered as Shapes, you can't select the text in the PDFs.

    Is it possible to use something different than drawGlyphVector() or allow to use a font factory at least?

    If you are interested then I could sponsor a little demo on how to convert a metafile to PDF.

    Thank you, Stephan.
     
  •  09-06-2007, 11:51 AM 93810 in reply to 93750

    Re: Disadvantage of drawGlyphVector()

    Dear Stephan,

    I don't really understand how Aspose.Metafiles can help with
    converting metafiles to pdf using iText. Could you explain it please.

    Alexey Zhilin
    Lead Developer
    Aspose Tyumen Team
    About Us
    Contact Us
     
  •  09-07-2007, 12:54 AM 93887 in reply to 93810

    Re: Disadvantage of drawGlyphVector()

    Unfortunately I can't attach a file, so I will paste an example here:

    import java.awt.*;
    import java.awt.geom.*;
    import java.io.*;

    import com.aspose.metafiles.*;
    import com.lowagie.text.*;
    import com.lowagie.text.Image;
    import com.lowagie.text.Rectangle;
    import com.lowagie.text.pdf.*;

    public class PdfConvert {

      public static void main(String[] args) throws IOException, MetafilesException, DocumentException {
        if (args.length != 1) {
          System.out.println("Usage PDFConvert [file.emf]");
          System.exit(1);
        }
        InputStream in = new FileInputStream(args[0]);

        EmfMetafile metaFile = new EmfMetafile(in);

        Rectangle2D bounds = new Rectangle2D.Float(metaFile.getMinX(), metaFile.getMinY(), metaFile.getWidth(), metaFile.getHeight());

        int width = (int) Math.ceil(bounds.getWidth());
        int height = (int) Math.ceil(bounds.getHeight());

        Document document = new Document(new Rectangle(width, height), 0f, 0f, 0f, 0f);
        OutputStream out = new FileOutputStream(args[0].replaceFirst("\\.\\w+$", ".pdf"));
        PdfWriter writer = PdfWriter.getInstance(document, out);
        document.open();

        PdfContentByte cb = writer.getDirectContent();
        Image image = getImage(cb, metaFile, bounds);
        document.add(image);

        document.close();
      }

      public static Image getImage(PdfContentByte cb, EmfMetafile metaFile, Rectangle2D bounds) throws BadElementException, MetafilesException {
        int width = (int) Math.ceil(bounds.getWidth());
        int height = (int) Math.ceil(bounds.getHeight());

        PdfTemplate template = cb.createTemplate(width, height);

        DefaultFontMapper mapper = new DefaultFontMapper();
        FontFactory.registerDirectories();
        // mapper.insertDirectory("c:\\windows\\fonts");

        Graphics2D g = template.createGraphics(width, height, mapper);

        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

        g.setTransform(AffineTransform.getTranslateInstance(-bounds.getMinX(), -bounds.getMinY()));

        metaFile.playMetafile(g);

        g.dispose();

        return new ImgTemplate(template);
      }

    }
     
  •  09-07-2007, 7:10 AM 93936 in reply to 93887

    Re: Disadvantage of drawGlyphVector()

    I think the best way is install Symbol.ttf and map it in the java's fontconfig.
    Aspose.Metafiles also uses drawGlyphVector, that is normal.
    You won't get characters in the PDF anyway, because metafile converted to an image.

    Alexey Zhilin
    Lead Developer
    Aspose Tyumen Team
    About Us
    Contact Us
     
  •  09-10-2007, 1:47 AM 94133 in reply to 93936

    Re: Disadvantage of drawGlyphVector()

    > I think the best way is install Symbol.ttf and map it in the java's fontconfig.

    Yes, that is the only solution ATM, which I know :-/

    > You won't get characters in the PDF anyway, because metafile converted to an image.

    No, that not true if you use itext. itext is able to create a mixture of text and graphic elements.
    The advantage is that the size of the generated PDF is much smaller and the rendering speed is higher for most of the PDF viewers. And you are also able to copy&paste texts from the graphics.

    Nevertheless if you use TextLayout, which uses implicit
    drawGlyphVector(), then you can't do much. I was just asking if it is easy for you to switch to something different than drawGlyphVector(). Unfortunately I can't fix itext instead of Metafiles, because I don't have enough information of the characters, which should be drawn in drawGlyphVector().

    Stephan.
     
  •  09-10-2007, 10:48 AM 94233 in reply to 94133

    Re: Disadvantage of drawGlyphVector()

    Stephan,

    So you offer create special fonts rendering for iText output?

    Btw, there is something wrong in your code. Why you create ImgTemplate?
    If I'm not mistaken it converts everything to Image and all shapes and glyphs will be lost.

    Alexey Zhilin
    Lead Developer
    Aspose Tyumen Team
    About Us
    Contact Us
     
  •  10-08-2007, 6:29 AM 97720 in reply to 94233

    Re: Disadvantage of drawGlyphVector()

    Sorry for the long delay. Some other stuff went in-between like always.

    1. No, itext can handle fonts even if they are not available through the AWT toolkit. The load mechanismen of AWT for fonts is sub-optimal. And through itext I'm able to map fonts on different fonts, which are not available for the AWT toolkit.

    2. I use ImgTemplate, because I have to create a raster graphic for every other implementation of com.lowagie.text.Image. And no, ImgTemplate doesn't create an AWT image.

    The biggest problem, which I have currently, is that the generated PDFs are much bigger and lower in their rendering speed.
     And that you can't copy&paste text from the PDFs made it even worse.

    I wrote a little demo to show the difference. This demo create two PDFs "test-drawstring.pdf" (1.4Kb) and "test-drawglyphvector.pdf"(215Kb!!).

    BTW, the problem doesn't occur not only with itext. I have the same problem if I convert the Metafile images to SVG or PS.

    I would appreciate it very much if you can help me with it,
    Stephan.

    TestDrawGlyphVector.java:
    import java.awt.Graphics2D;
    import java.awt.font.TextLayout;
    import java.io.*;

    import com.lowagie.text.*;
    import com.lowagie.text.pdf.*;

    public class TestDrawGlyphVector {
      private final static float WIDTH = 500f;
      private final static float HEIGHT = 500f;

      public static void main(String[] args) throws FileNotFoundException, DocumentException {
        for (int i = 1; i <= 2; i++) {
         
          Document document = new Document(new Rectangle(WIDTH, HEIGHT), 0f, 0f, 0f, 0f);
          String fileName = "test-" + (i == 1 ? "drawstring" : "drawglyphvector") + ".pdf";
          OutputStream out = new FileOutputStream(fileName);
          PdfWriter writer = PdfWriter.getInstance(document, out);
          document.open();

          PdfContentByte cb = writer.getDirectContent();
          PdfTemplate template = cb.createTemplate(WIDTH, HEIGHT);
          Graphics2D g = template.createGraphics(WIDTH, HEIGHT, new DefaultFontMapper());

          for (int y = 0; y < 500; y += 10) {
            if (i == 1) {
              g.drawString("Test Test Test Test Test Test Test Test Test Test Test Test Test Test", 0, y);
            } else {
              new TextLayout("Test Test Test Test Test Test Test Test Test Test Test Test Test Test", g.getFont(), g.getFontRenderContext()).draw(
                      g, 0, y);
            }
          }
         
          g.dispose();
          document.add(new ImgTemplate(template));

          document.close();
        }
      }
    }


     
View as RSS news feed in XML