Search in sources :

Example 1 with PDType1Font

use of org.apache.pdfbox.pdmodel.font.PDType1Font in project pdfbox by apache.

the class HelloWorldType1 method main.

public static void main(String[] args) throws IOException {
    if (args.length != 3) {
        System.err.println("usage: " + HelloWorldType1.class.getName() + " <output-file> <Message> <pfb-file>");
        System.exit(1);
    }
    String file = args[0];
    String message = args[1];
    String pfbPath = args[2];
    try (PDDocument doc = new PDDocument()) {
        PDPage page = new PDPage();
        doc.addPage(page);
        PDFont font = new PDType1Font(doc, new FileInputStream(pfbPath));
        PDPageContentStream contents = new PDPageContentStream(doc, page);
        contents.beginText();
        contents.setFont(font, 12);
        contents.newLineAtOffset(100, 700);
        contents.showText(message);
        contents.endText();
        contents.close();
        doc.save(file);
        System.out.println(file + " created!");
    }
}
Also used : PDFont(org.apache.pdfbox.pdmodel.font.PDFont) PDType1Font(org.apache.pdfbox.pdmodel.font.PDType1Font) PDPage(org.apache.pdfbox.pdmodel.PDPage) PDDocument(org.apache.pdfbox.pdmodel.PDDocument) PDPageContentStream(org.apache.pdfbox.pdmodel.PDPageContentStream) FileInputStream(java.io.FileInputStream)

Example 2 with PDType1Font

use of org.apache.pdfbox.pdmodel.font.PDType1Font in project pdfbox-graphics2d by rototor.

the class PdfBoxGraphics2DFontTextDrawer method drawText.

@Override
public void drawText(AttributedCharacterIterator iterator, IFontTextDrawerEnv env) throws IOException, FontFormatException {
    PDPageContentStream contentStream = env.getContentStream();
    contentStream.beginText();
    Matrix textMatrix = new Matrix();
    textMatrix.scale(1, -1);
    contentStream.setTextMatrix(textMatrix);
    StringBuilder sb = new StringBuilder();
    boolean run = true;
    while (run) {
        Font attributeFont = (Font) iterator.getAttribute(TextAttribute.FONT);
        if (attributeFont == null)
            attributeFont = env.getFont();
        Number fontSize = ((Number) iterator.getAttribute(TextAttribute.SIZE));
        if (fontSize != null)
            attributeFont = attributeFont.deriveFont(fontSize.floatValue());
        PDFont font = applyFont(attributeFont, env);
        Paint paint = (Paint) iterator.getAttribute(TextAttribute.FOREGROUND);
        if (paint == null)
            paint = env.getPaint();
        /*
			 * Apply the paint
			 */
        env.applyPaint(paint);
        boolean isStrikeThrough = TextAttribute.STRIKETHROUGH_ON.equals(iterator.getAttribute(TextAttribute.STRIKETHROUGH));
        boolean isUnderline = TextAttribute.UNDERLINE_ON.equals(iterator.getAttribute(TextAttribute.UNDERLINE));
        boolean isLigatures = TextAttribute.LIGATURES_ON.equals(iterator.getAttribute(TextAttribute.LIGATURES));
        run = iterateRun(iterator, sb);
        String text = sb.toString();
        /*
			 * If we force the text write we may encounter situations where the font can not
			 * display the characters. PDFBox will throw an exception in this case. We will
			 * just silently ignore the text and not display it instead.
			 */
        try {
            showTextOnStream(env, contentStream, attributeFont, font, isStrikeThrough, isUnderline, isLigatures, text);
        } catch (IllegalArgumentException e) {
            if (font instanceof PDType1Font && !font.isEmbedded()) {
                /*
					 * We tried to use a builtin default font, but it does not have the needed
					 * characters. So we use a embedded font as fallback.
					 */
                try {
                    if (fallbackFontUnknownEncodings == null)
                        fallbackFontUnknownEncodings = findFallbackFont(env);
                    if (fallbackFontUnknownEncodings != null) {
                        env.getContentStream().setFont(fallbackFontUnknownEncodings, attributeFont.getSize2D());
                        showTextOnStream(env, contentStream, attributeFont, fallbackFontUnknownEncodings, isStrikeThrough, isUnderline, isLigatures, text);
                        e = null;
                    }
                } catch (IllegalArgumentException ignored) {
                    e = ignored;
                }
            }
            if (e != null)
                System.err.println("PDFBoxGraphics: Can not map text " + text + " with font " + attributeFont.getFontName() + ": " + e.getMessage());
        }
    }
    contentStream.endText();
}
Also used : PDFont(org.apache.pdfbox.pdmodel.font.PDFont) PDType1Font(org.apache.pdfbox.pdmodel.font.PDType1Font) Matrix(org.apache.pdfbox.util.Matrix) PDPageContentStream(org.apache.pdfbox.pdmodel.PDPageContentStream) PDType1Font(org.apache.pdfbox.pdmodel.font.PDType1Font) PDFont(org.apache.pdfbox.pdmodel.font.PDFont) TrueTypeFont(org.apache.fontbox.ttf.TrueTypeFont) PDType0Font(org.apache.pdfbox.pdmodel.font.PDType0Font)

Example 3 with PDType1Font

use of org.apache.pdfbox.pdmodel.font.PDType1Font in project pdfbox by apache.

the class PDLineAppearanceHandler method generateNormalAppearance.

@Override
public void generateNormalAppearance() {
    PDAnnotationLine annotation = (PDAnnotationLine) getAnnotation();
    PDRectangle rect = annotation.getRectangle();
    float[] pathsArray = annotation.getLine();
    if (pathsArray == null) {
        return;
    }
    AnnotationBorder ab = AnnotationBorder.getAnnotationBorder(annotation, annotation.getBorderStyle());
    PDColor color = annotation.getColor();
    if (color == null || color.getComponents().length == 0) {
        return;
    }
    float ll = annotation.getLeaderLineLength();
    float lle = annotation.getLeaderLineExtensionLength();
    float llo = annotation.getLeaderLineOffsetLength();
    // Adjust rectangle even if not empty, see PLPDF.com-MarkupAnnotations.pdf
    float minX = Float.MAX_VALUE;
    float minY = Float.MAX_VALUE;
    float maxX = Float.MIN_VALUE;
    float maxY = Float.MIN_VALUE;
    for (int i = 0; i < pathsArray.length / 2; ++i) {
        float x = pathsArray[i * 2];
        float y = pathsArray[i * 2 + 1];
        minX = Math.min(minX, x);
        minY = Math.min(minY, y);
        maxX = Math.max(maxX, x);
        maxY = Math.max(maxY, y);
    }
    // Leader lines
    if (ll < 0) {
        // /LLO and /LLE go in the same direction as /LL
        llo = -llo;
        lle = -lle;
    }
    // add/substract with, font height, and arrows
    // arrow length is 9 * width at about 30° => 10 * width seems to be enough
    // but need to consider /LL, /LLE and /LLO too
    // TODO find better way to calculate padding
    rect.setLowerLeftX(Math.min(minX - Math.max(ab.width * 10, Math.abs(llo + ll + lle)), rect.getLowerLeftX()));
    rect.setLowerLeftY(Math.min(minY - Math.max(ab.width * 10, Math.abs(llo + ll + lle)), rect.getLowerLeftY()));
    rect.setUpperRightX(Math.max(maxX + Math.max(ab.width * 10, Math.abs(llo + ll + lle)), rect.getUpperRightX()));
    rect.setUpperRightY(Math.max(maxY + Math.max(ab.width * 10, Math.abs(llo + ll + lle)), rect.getUpperRightY()));
    annotation.setRectangle(rect);
    try {
        try (PDAppearanceContentStream cs = getNormalAppearanceAsContentStream()) {
            handleOpacity(annotation.getConstantOpacity());
            // Tested with Adobe Reader:
            // text is written first (TODO)
            // width 0 is used by Adobe as such (but results in a visible line in rendering)
            // empty color array results in an invisible line ("n" operator) but the rest is visible
            // empty content is like no caption
            boolean hasStroke = cs.setStrokingColorOnDemand(color);
            if (ab.dashArray != null) {
                cs.setLineDashPattern(ab.dashArray, 0);
            }
            cs.setLineWidth(ab.width);
            float x1 = pathsArray[0];
            float y1 = pathsArray[1];
            float x2 = pathsArray[2];
            float y2 = pathsArray[3];
            // if there are leader lines, then the /L coordinates represent
            // the endpoints of the leader lines rather than the endpoints of the line itself.
            // so for us, llo + ll is the vertical offset for the line.
            float y = llo + ll;
            String contents = annotation.getContents();
            if (contents == null) {
                contents = "";
            }
            double angle = Math.atan2(y2 - y1, x2 - x1);
            cs.transform(Matrix.getRotateInstance(angle, x1, y1));
            float lineLength = (float) Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
            if (annotation.hasCaption() && !contents.isEmpty()) {
                PDType1Font font = PDType1Font.HELVETICA;
                // TODO: support newlines!!!!!
                // see https://www.pdfill.com/example/pdf_commenting_new.pdf
                float contentLength = 0;
                try {
                    contentLength = font.getStringWidth(annotation.getContents()) / 1000 * FONT_SIZE;
                // TODO How to decide the size of the font?
                // 9 seems to be standard, but if the text doesn't fit, a scaling is done
                // see AnnotationSample.Standard.pdf, diagonal line
                } catch (IllegalArgumentException ex) {
                    // Adobe Reader displays placeholders instead
                    LOG.error("line text '" + annotation.getContents() + "' can't be shown", ex);
                }
                float xOffset = (lineLength - contentLength) / 2;
                float yOffset;
                // Leader lines
                cs.moveTo(0, llo);
                cs.lineTo(0, llo + ll + lle);
                cs.moveTo(lineLength, llo);
                cs.lineTo(lineLength, llo + ll + lle);
                String captionPositioning = annotation.getCaptionPositioning();
                // that's the easiest way to calculate the positions for the line before and after inline caption
                if (SHORT_STYLES.contains(annotation.getStartPointEndingStyle())) {
                    cs.moveTo(ab.width, y);
                } else {
                    cs.moveTo(0, y);
                }
                if ("Top".equals(captionPositioning)) {
                    // this arbitrary number is from Adobe
                    yOffset = 1.908f;
                } else {
                    // Inline
                    // this arbitrary number is from Adobe
                    yOffset = -2.6f;
                    cs.lineTo(xOffset - ab.width, y);
                    cs.moveTo(lineLength - xOffset + ab.width, y);
                }
                if (SHORT_STYLES.contains(annotation.getEndPointEndingStyle())) {
                    cs.lineTo(lineLength - ab.width, y);
                } else {
                    cs.lineTo(lineLength, y);
                }
                cs.drawShape(ab.width, hasStroke, false);
                // /CO entry (caption offset)
                float captionHorizontalOffset = annotation.getCaptionHorizontalOffset();
                float captionVerticalOffset = annotation.getCaptionVerticalOffset();
                // check contentLength so we don't show if there was trouble before
                if (contentLength > 0) {
                    prepareResources();
                    cs.beginText();
                    cs.setFont(font, FONT_SIZE);
                    cs.newLineAtOffset(xOffset + captionHorizontalOffset, y + yOffset + captionVerticalOffset);
                    cs.showText(annotation.getContents());
                    cs.endText();
                }
                if (Float.compare(captionVerticalOffset, 0) != 0) {
                    // Adobe paints vertical bar to the caption
                    cs.moveTo(0 + lineLength / 2, y);
                    cs.lineTo(0 + lineLength / 2, y + captionVerticalOffset);
                    cs.drawShape(ab.width, hasStroke, false);
                }
            } else {
                if (SHORT_STYLES.contains(annotation.getStartPointEndingStyle())) {
                    cs.moveTo(ab.width, y);
                } else {
                    cs.moveTo(0, y);
                }
                if (SHORT_STYLES.contains(annotation.getEndPointEndingStyle())) {
                    cs.lineTo(lineLength - ab.width, y);
                } else {
                    cs.lineTo(lineLength, y);
                }
                cs.drawShape(ab.width, hasStroke, false);
            }
            // do this here and not before showing the text, or the text would appear in the
            // interior color
            boolean hasBackground = cs.setNonStrokingColorOnDemand(annotation.getInteriorColor());
            switch(annotation.getStartPointEndingStyle()) {
                case PDAnnotationLine.LE_OPEN_ARROW:
                case PDAnnotationLine.LE_CLOSED_ARROW:
                    drawArrow(cs, ab.width, y, ab.width * 9);
                    if (PDAnnotationLine.LE_CLOSED_ARROW.equals(annotation.getStartPointEndingStyle())) {
                        cs.closePath();
                    }
                    break;
                case PDAnnotationLine.LE_BUTT:
                    cs.moveTo(0, y - ab.width * 3);
                    cs.lineTo(0, y + ab.width * 3);
                    break;
                case PDAnnotationLine.LE_DIAMOND:
                    drawDiamond(cs, 0, y, ab.width * 3);
                    break;
                case PDAnnotationLine.LE_SQUARE:
                    cs.addRect(0 - ab.width * 3, y - ab.width * 3, ab.width * 6, ab.width * 6);
                    break;
                case PDAnnotationLine.LE_CIRCLE:
                    addCircle(cs, 0, y, ab.width * 3);
                    break;
                case PDAnnotationLine.LE_R_OPEN_ARROW:
                case PDAnnotationLine.LE_R_CLOSED_ARROW:
                    drawArrow(cs, -ab.width, y, -ab.width * 9);
                    if (PDAnnotationLine.LE_R_CLOSED_ARROW.equals(annotation.getStartPointEndingStyle())) {
                        cs.closePath();
                    }
                    break;
                case PDAnnotationLine.LE_SLASH:
                    // the line is 18 x linewidth at an angle of 60°
                    cs.moveTo((float) (Math.cos(Math.toRadians(60)) * ab.width * 9), y + (float) (Math.sin(Math.toRadians(60)) * ab.width * 9));
                    cs.lineTo((float) (Math.cos(Math.toRadians(240)) * ab.width * 9), y + (float) (Math.sin(Math.toRadians(240)) * ab.width * 9));
                    break;
                default:
                    break;
            }
            if (INTERIOR_COLOR_STYLES.contains(annotation.getStartPointEndingStyle())) {
                cs.drawShape(ab.width, hasStroke, hasBackground);
            } else if (!PDAnnotationLine.LE_NONE.equals(annotation.getStartPointEndingStyle())) {
                // need to do this separately, because sometimes /IC is set anyway
                cs.drawShape(ab.width, hasStroke, false);
            }
            switch(annotation.getEndPointEndingStyle()) {
                case PDAnnotationLine.LE_OPEN_ARROW:
                case PDAnnotationLine.LE_CLOSED_ARROW:
                    drawArrow(cs, lineLength - ab.width, y, -ab.width * 9);
                    if (PDAnnotationLine.LE_CLOSED_ARROW.equals(annotation.getEndPointEndingStyle())) {
                        cs.closePath();
                    }
                    break;
                case PDAnnotationLine.LE_BUTT:
                    cs.moveTo(lineLength, y - ab.width * 3);
                    cs.lineTo(lineLength, y + ab.width * 3);
                    break;
                case PDAnnotationLine.LE_DIAMOND:
                    drawDiamond(cs, lineLength, y, ab.width * 3);
                    break;
                case PDAnnotationLine.LE_SQUARE:
                    cs.addRect(lineLength - ab.width * 3, y - ab.width * 3, ab.width * 6, ab.width * 6);
                    break;
                case PDAnnotationLine.LE_CIRCLE:
                    addCircle(cs, lineLength, y, ab.width * 3);
                    break;
                case PDAnnotationLine.LE_R_OPEN_ARROW:
                case PDAnnotationLine.LE_R_CLOSED_ARROW:
                    drawArrow(cs, lineLength + ab.width, y, ab.width * 9);
                    if (PDAnnotationLine.LE_R_CLOSED_ARROW.equals(annotation.getEndPointEndingStyle())) {
                        cs.closePath();
                    }
                    break;
                case PDAnnotationLine.LE_SLASH:
                    // the line is 18 x linewidth at an angle of 60°
                    cs.moveTo(lineLength + (float) (Math.cos(Math.toRadians(60)) * ab.width * 9), y + (float) (Math.sin(Math.toRadians(60)) * ab.width * 9));
                    cs.lineTo(lineLength + (float) (Math.cos(Math.toRadians(240)) * ab.width * 9), y + (float) (Math.sin(Math.toRadians(240)) * ab.width * 9));
                    break;
                default:
                    break;
            }
            if (INTERIOR_COLOR_STYLES.contains(annotation.getEndPointEndingStyle())) {
                cs.drawShape(ab.width, hasStroke, hasBackground);
            } else if (!PDAnnotationLine.LE_NONE.equals(annotation.getEndPointEndingStyle())) {
                // need to do this separately, because sometimes /IC is set anyway
                cs.drawShape(ab.width, hasStroke, false);
            }
        }
    } catch (IOException ex) {
        LOG.error(ex);
    }
}
Also used : IOException(java.io.IOException) PDColor(org.apache.pdfbox.pdmodel.graphics.color.PDColor) PDType1Font(org.apache.pdfbox.pdmodel.font.PDType1Font) PDAnnotationLine(org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLine) PDAppearanceContentStream(org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceContentStream) PDRectangle(org.apache.pdfbox.pdmodel.common.PDRectangle)

Aggregations

PDType1Font (org.apache.pdfbox.pdmodel.font.PDType1Font)3 PDPageContentStream (org.apache.pdfbox.pdmodel.PDPageContentStream)2 PDFont (org.apache.pdfbox.pdmodel.font.PDFont)2 FileInputStream (java.io.FileInputStream)1 IOException (java.io.IOException)1 TrueTypeFont (org.apache.fontbox.ttf.TrueTypeFont)1 PDDocument (org.apache.pdfbox.pdmodel.PDDocument)1 PDPage (org.apache.pdfbox.pdmodel.PDPage)1 PDRectangle (org.apache.pdfbox.pdmodel.common.PDRectangle)1 PDType0Font (org.apache.pdfbox.pdmodel.font.PDType0Font)1 PDColor (org.apache.pdfbox.pdmodel.graphics.color.PDColor)1 PDAnnotationLine (org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLine)1 PDAppearanceContentStream (org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceContentStream)1 Matrix (org.apache.pdfbox.util.Matrix)1