4-Heights™ PDF Toolbox SDK – Bearbeiten, Zusammenfügen und Erstellen von PDF-Dateien in C# und Java

Das 4-Heights™ PDF Toolbox SDK ist eine professionelle Bibliothek für das automatisierte PDF Erstellen, Bearbeiten und Assemblieren. Das PDF/A konforme SDK ist Plattform-unabhängig und kann auf Windows, Linux und MacOS eingesetzt werden. Dank verschiedenen Schnittstellen kann das SDK sowohl mit Java, C/C++,  .NET Core und .NET Sprachen wie C# oder Visual Basic eingesetzt werden.

Formulare und Annotationen

Programmatisch Formulare erstellen, ausfüllen und extrahieren, Annotationen erstellen, ändern und extrahieren.

PDF Bearbeiten

Bilder oder Text auf PDF anbringen (Stempel/Wasserzeichen) oder vorhandener Text in PDF löschen

PDF Erstellen

PDF erstellen, von Grund auf neue Seiten mit beliebigen Inhalten erzeugen und mit vorhandenen Seiten kombinieren

Zeit sparen dank Cloud-basierter PDF Dienste

Mit wachsender Nutzeranzahl wurden zudem mehr und mehr neue Funktionalitäten von der Community verlangt. Dazu gehörte das Komprimieren von PDF Dateien oder Konvertieren von Office Dokumenten nach PDF.

Smallpdf bei der Komprimierung ganz gross

Die Grösse einer Datei in einem E-Mail Anhang kann dazu führen, dass die E-Mail nicht versendet oder empfangen werden kann. Um dieses Problem zu lösen suchte Smallpdf eine Möglichkeit, die Grösse dieser Dateien zu reduzieren.

PDF Toolbox - Funktionen

Dokumentenzusammenstellung

  • Kopieren von Seiten bestehender PDF Dokumente
  • Kopieren von Annotationen/Kommentaren, Formularfeldern, Links, Strukturinformationen, Lesezeichen, Sprungmarken
  • Auflösen von Annotationen, Formularfeldern, Signaturen
  • Ressourcenoptimierung
  • Seiten zuschneiden und drehen
  • Freies Zusammenstellen von Inhalten: Overlays, Underlays, Stempeln, Transformieren
  • Verschlüsselung: Benutzerpasswort, Eigentümerpasswort, Berechtigungen
  • Kopieren und Ändern von Dokument-Metadaten
  • Kopieren und Ändern von Seiten-Metadaten
  • Hinzufügen von eingebetteten Dateien und zugehörigen Dateien
  • OpenAction abrufen und festlegen

Generierung

  • Dokument Ebene
    • Seiten erstellen
    • Formularfelder erstellen
      • Allgemeine Textfelder und Kombi-Textfelder
      • Checkboxen
      • Radio Button Gruppe
      • Auswahllisten
      • Kombinationsfelder
    • Neue Gliederungspunkte anlegen und an beliebiger Stelle im Baum einfügen
    • Ziele: Benannte und direkte Ziele im gleichen Dokument
    • Viewer Einstellungen konfigurieren
  • Seiteninhaltsebene
    • Erstellen von neuen PDF Inhalten von Grund auf
    • Aufbringen von Inhalt auf existierende Seiten
  • Farben
    • RGB, CMYK und Graustufen
    • ICC Farbprofile
    • Transparenz: Alpha und Blend Modus
  • Pfade
    • Linien (Single and multi-segment)
    • Rechtecke, Kreise, Bézierkurven, Ellipsen
    • Füllen, zeichnen, clippen und Kombinationen davon
    • Linienbreite, -ende (cap), -verbindung (join), -strich (dash array, dash phase) und Gehrungsgrenze (miter limit)
    • Füllregel: Nonzero winding oder Even/odd
  • Text
    • Schriftgröße, Zeichenabstand, Wortabstand
    • Horizontale Skalierung, leading, hoch stellen
    • Einfaches Textlayout ermöglichen
    • Standard PDF Schriften, installierte Schriften
    • Fontmetriken: Italic angle, Ascent, Descent, Cap height, Character width
    • Unicode Zeichen
    • Textstrich: Linienbreite, Linienverbindung und Striche
    • Text Füllen und Markieren, unsichtbarer Text
    • Text als Beschneidungspfad verwenden
  • Bilder
    • Bi-Level: CCITT G3, G3 2D und G4, Flate, LZW, Packbits, unkomprimiert
    • 4 Bit und 8 Bit Graustufen: Flate, LZW, Packbits, JPEG und JPEG-6 (nur 8 Bit), unkomprimiert
    • RGB: Flate, JPEG und JPEG-6, LZW, Packbits, unkomprimiert
  • Transformationen
    • Übersetzung
    • Skalieren
    • Verzerren (Horizontal oder Vertikal)
    • Rotation
  • Annotationen
    • Web Link Annotation
    • Datei Anhang Annotation
    • Freitext Annotation
    • Sticky Note Annotation
    • Text Stempel Annotation
    • Individual Stempel Annotation
    • Kreis Annotation
    • Quadrat Annotation
    • Linien Annotation
    • Polyline Annotation
    • Polygon Annotation
    • Freihand (“Tinte”) Annotation

Modifikation

  • Seiteninhalt
    • Selektives Löschen von Inhaltselementen (ohne Markup)
    • Geometrische Transformation von Inhaltselementen (ohne Markup)
  • Annotationen
    • Ziel-URI von Weblink Annotation
    • Standort, Erstellungs- und Modifikations-Datum, Titel, Autor und Inhalt von Markup Annotationen
  • Fomularfelder
    • Löschen von Feldern und Ändern von Feldwerten für
      • allgemeine Textfelder und Kombi-Textfelder
      • Checkboxen
      • Radio Button Gruppe
      • Auswahllisten
      • Kombinationsfelder

Extrahieren

  • Dokument und Seiten
    • Dokumentinformationen: Titel, Autor, Betreff, Schlagwörter, Ersteller, Produzent, Erstellungsdatum, Änderungsdatum
    • Dokument XMP Metadaten
    • Einstellungen zur Verschlüsselung des Dokuments
    • Eingebettete Dateien
    • Seiten Bounding-Boxen: Media box, Crop box, Bleed box, Trim box, Art box
    • Seite XMP Metadaten
    • Outline Item Baum: Baum Struktur, Titel, auf-/zugeklappt
    • Destinationen: Named und direkte Destinationen im selben Dokument
    • Viewer Einstellungen
  • Inhalt
    • Inhaltselemente der Seiten und Group-Elemente, einschließlich der folgenden Attribute
      • Begrenzungsbox
      • Affine Transformation
    • Extrahierte Elementtypen:
      • Group-Element
      • Bildelement
        • Breite und Höhe in Pixel
        • Bits pro Farbkomponente
        • Farbraum
    • Bildmaskenelement
      • Breite und Höhe in Pixel
      • Farbe zum Füllen der Maske
    • Pfadelement
      • Ausrichtungsbox
      • Füllparameter einschließlich Farbe und Füllregel
      • Strichparameter einschließlich Linienfarbe und Linienstil
    • Shading-Element
    • Textelement
      • Textfragmente
        • Begrenzungsbox
        • Affine Transformation
        • Unicode String
        • Füllparameter einschließlich Farbe und Füllregel
        • Strichparameter einschließlich Linienfarbe und Linienstil
  • Annotationen
    • Annotationen: Standort
    • Markup Annotationen: Typ, Ort, Erstellungs- und Modifikationsdatum, Titel, Autor, Inhalt
    • Individuelle Stempel Annotation: Darstellung
    • Link Annotation: Standort, Ziel Destination oder URI
    • Signaturfelder: Name, Standort, Grund, Kontaktinformationen, Datum, Sichtbarkeit
  • AcroForm Formularfelder
    • Formularfeldbezeichner, Exportnamen und Benutzernamen, einschließlich Formularfeldhierarchie
    • Formularfeld-Export und Anzeige des Inhalts von:
      • Drucktasten
      • Checkboxen
      • Radio Button Gruppe
      • Allgemeine Textfelder und Kombi-Textfelder
      • Auswahllisten
      • Kombinationsfelder

Conformance

  • ISO 32000-1 (PDF 1.7)
  • ISO 32000-2 (PDF 2.0)
  • ISO 19005-1 (PDF/A-1)
  • ISO 19005-2 (PDF/A-2)
  • ISO 19005-3 (PDF/A-3)

Unterstützte Formate

Unterstützte PDF-Formate

  • PDF 1.0 bis 1.7
  • PDF 2.0
  • PDF/A-1, PDF/A-2, PDF/A-3

Unterstützte Bildformate

  • BMP
  • DIB
  • JPEG
  • JPEG2000
  • JBIG2
  • PNG
  • GIF
  • TIFF

Unterstützte Schriftformate

  • Type1
  • TrueType
  • OpenType
  • OpenType (CFF)

Einsatzgebiete - Bearbeiten und zusammenstellen von PDF Dokumenten

PDF Erstellen und Bearbeiten

Nutzen Sie die 3-Heights™ PDF Toolbox zum PDF Dateien in Ihrer Programmiersprache (Java, C#, Visual Basic, C/C++) erstellen, editieren und assemblieren. Bewahren Sie die PDF/A Konformität und erstellen Sie PDF Dokumente in Massenverarbeitung, wobei die Inhalte aus beliebigen Quellen stammen können, wie z. B. einer Datenbank oder einem Webseitenformular.

Personalisierung

PDF Dokumente werden für den Vertrieb von E-Books verwendet sowie für das Erstellen von Rechnungen, Verträgen und Bedingungen u. a. in Versicherungsanträgen. Diese Dokumente haben alle eine gemeinsame Anforderung: Sie müssen um empfängerspezifische Informationen ergänzt werden.

Automatisierte Berichterstellung

Grosse Informationsmengen werden auf Datenbank- und DMS-Systemen gespeichert. Die PDF Toolbox eignet sich, um diese Informationen entgegen zu nehmen und daraus verteilbare und standardisierte PDF Dokumente zu erstellen. Somit wird auch die Distribution über Infrastrukturen mit verschiedensten Technologien und Betriebssystemen ermöglicht.

Weitere Einsatzgebiete

  • Erzeugung von benutzerdefinierten Dokumenten wie Angebote, Policendossiers etc.
  • Massenerzeugung von Rechnungen, Berichten usw.
  • PDF Erzeugung „on-the-fly“ in Webserveranwendungen
  • „Save as PDF/A“ Funktion in Anwenderprogrammen
  • Importieren von Bildern und Texten in PDF/A Dokumente

Stempel zu PDF hinzufügen

Füge jeder Seite eines PDF Dokuments einen halb-transparenten Stempeltext hinzu. Optional können die Farbe und die Deckkraft des Stempels festgelegt werden.

C# Beispiel: Download
// Open input document
using (Stream inStream = new FileStream(inPath, FileMode.Open, FileAccess.Read))
using (Document inDoc = Document.Open(inStream, null))

// Create output document
using (Stream outStream = new FileStream(outPath, FileMode.Create, FileAccess.ReadWrite))
using (Document outDoc = Document.Create(outStream, inDoc.Conformance, null))
{
    // Copy document-wide data
    CopyDocumentData(inDoc, outDoc);

    font = Font.CreateFromSystem(outDoc, "Arial", "Italic", true);

    // Get the color space
    ColorSpace colorSpace = ColorSpace.CreateProcessColorSpace(outDoc, ProcessColorSpaceType.Rgb);

    // Choose the RGB color value
    double[] color = { 1.0, 0.0, 0.0 };
    Transparency transparency = new Transparency(alpha);

    // Create paint object with the choosen RGB color
    paint = Paint.Create(outDoc, colorSpace, color, transparency);

    // Define copy options
    PageCopyOptions copyOptions = new PageCopyOptions();

    // Copy all pages from input document
    foreach (Page inPage in inDoc.Pages)
    {
        // Copy page from input to output
        Page outPage = Page.Copy(outDoc, inPage, copyOptions);

        // Add text to page
        AddStamp(outDoc, outPage, stampString);

        // Add page to document
        outDoc.Pages.Add(outPage);
    }
}
private static void CopyDocumentData(Document inDoc, Document outDoc)
{
    // Copy document-wide data

    // Output intent
    if (inDoc.OutputIntent != null)
        outDoc.OutputIntent = IccBasedColorSpace.Copy(outDoc, inDoc.OutputIntent);

    // Metadata
    outDoc.Metadata = Metadata.Copy(outDoc, inDoc.Metadata);

    // Viewer settings
    outDoc.ViewerSettings = ViewerSettings.Copy(outDoc, inDoc.ViewerSettings);

    // Associated files (for PDF/A-3 and PDF 2.0 only)
    FileReferenceList outAssociatedFiles = outDoc.AssociatedFiles;
    foreach (FileReference inFileRef in inDoc.AssociatedFiles)
        outAssociatedFiles.Add(FileReference.Copy(outDoc, inFileRef));

    // Plain embedded files
    FileReferenceList outEmbeddedFiles = outDoc.PlainEmbeddedFiles;
    foreach (FileReference inFileRef in inDoc.PlainEmbeddedFiles)
        outEmbeddedFiles.Add(FileReference.Copy(outDoc, inFileRef));
}
private static void AddStamp(Document outputDoc, Page outPage, string stampString)
{
    // Create content generator and text object
    using ContentGenerator gen = new ContentGenerator(outPage.Content, false);
    Text text = Text.Create(outputDoc);

    // Create text generator
    using (TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null))
    {
        // Calculate point and angle of rotation
        Point rotationCenter = new Point
        {
            X = outPage.Size.Width / 2.0,
            Y = outPage.Size.Height / 2.0
        };
        double rotationAngle = Math.Atan2(outPage.Size.Height,
            outPage.Size.Width) / Math.PI * 180.0;

        // Rotate textinput around the calculated position
        AffineTransform trans = AffineTransform.Identity;
        trans.Rotate(rotationAngle, rotationCenter);
        gen.Transform(trans);

        // Calculate position
        Point position = new Point
        {
            X = (outPage.Size.Width - textgenerator.GetWidth(stampString)) / 2.0,
            Y = (outPage.Size.Height - font.Ascent * fontSize) / 2.0
        };

        // Move to position
        textgenerator.MoveTo(position);

        // Set text paint
        textgenerator.Fill = paint;

        // Add given stamp string
        textgenerator.ShowLine(stampString);
    }
    // Paint the positioned text
    gen.PaintText(text);
}
Java Beispiel: Download
try (// Open input document
    FileStream inStream = new FileStream(inPath, "r");
    Document inDoc = Document.open(inStream, null);
    FileStream outStream = new FileStream(outPath, "rw")) {
    outStream.setLength(0);
    try (// Create output document
        Document outDoc = Document.create(outStream, inDoc.getConformance(), null)) {
        // Copy document-wide data
        copyDocumentData(inDoc, outDoc);

        // Create embedded font in output document
        font = Font.createFromSystem(outDoc, "Arial", "Italic", true);

        // Get the color space
        ColorSpace colorSpace = ColorSpace.createProcessColorSpace(outDoc, ProcessColorSpaceType.RGB);

        // Choose the RGB color value
        double[] color = { 1.0, 0.0, 0.0 };
        Transparency transparency = new Transparency(alpha);

        // Create paint object
        paint = Paint.create(outDoc, colorSpace, color, transparency);

        // Define page copy options
        PageCopyOptions copyOptions = new PageCopyOptions();

        // Loop throw all pages of input
        for (Page inPage : inDoc.getPages()) {
            // Copy page from input to output
            Page outPage = Page.copy(outDoc, inPage, copyOptions);

            // Add text to page
            addStamp(outDoc, outPage, stampString);

            // Add page to document
            outDoc.getPages().add(outPage);
        }
    }
}
private static void copyDocumentData(Document inDoc, Document outDoc) throws PdfToolboxException, IOException {
    // Copy document-wide data

    // Output intent
    if (inDoc.getOutputIntent() != null)
        outDoc.setOutputIntent(IccBasedColorSpace.copy(outDoc, inDoc.getOutputIntent()));

    // Metadata
    outDoc.setMetadata(Metadata.copy(outDoc, inDoc.getMetadata()));

    // Viewer settings
    outDoc.setViewerSettings(ViewerSettings.copy(outDoc, inDoc.getViewerSettings()));

    // Associated files (for PDF/A-3 and PDF 2.0 only)
    FileReferenceList outAssociatedFiles = outDoc.getAssociatedFiles();
    for (FileReference inFileRef : inDoc.getAssociatedFiles())
        outAssociatedFiles.add(FileReference.copy(outDoc, inFileRef));

    // Plain embedded files
    FileReferenceList outEmbeddedFiles = outDoc.getPlainEmbeddedFiles();
    for (FileReference inFileRef : inDoc.getPlainEmbeddedFiles())
        outEmbeddedFiles.add(FileReference.copy(outDoc, inFileRef));
}
private static void addStamp(Document outputDoc, Page outPage, String stampString)
        throws PdfToolboxException, IOException {
    try (// Create content generator
        ContentGenerator generator = new ContentGenerator(outPage.getContent(), false)) {
        // Create text object
        Text text = Text.create(outputDoc);
        try (// Create text generator
            TextGenerator textgenerator = new TextGenerator(text, font, fontSize, null)) {
            // Calculate point and angle of rotation
            Point rotationCenter = new Point(outPage.getSize().width / 2.0, outPage.getSize().height / 2.0);

            // Calculate rotation angle
            double rotationAngle = Math.atan2(outPage.getSize().height, outPage.getSize().width) / Math.PI * 180.0;

            // Rotate text input around the calculated position
            AffineTransform trans = AffineTransform.getIdentity();
            trans.rotate(rotationAngle, rotationCenter);
            generator.transform(trans);

            // Calculate position
            Point position = new Point((outPage.getSize().width - textgenerator.getWidth(stampString)) / 2.0,
                    (outPage.getSize().height - font.getAscent() * fontSize) / 2.0);

            // Move to position
            textgenerator.moveTo(position);

            // Set text paint
            textgenerator.setFill(paint);

            // Add given stamp string
            textgenerator.showLine(stampString);
        }

        // Paint the positioned text
        generator.paintText(text);
    }
}
C Beispiel: Download
// Open input document
pInStream = _tfopen(szInPath, _T("rb"));
GOTO_CLEANUP_IF_NULL(pInStream, _T("Failed to open input file \"%s\".\n"), szInPath);
PtxSysCreateFILEStreamDescriptor(&inDescriptor, pInStream, FALSE);
pInDoc = PtxPdf_Document_Open(&inDescriptor, _T(""));
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInDoc, _T("Input file \"%s\" cannot be opened. %s (ErrorCode: 0x%08x).\n"), szInPath, szErrorBuff, Ptx_GetLastError());

// Create output document
pOutStream = _tfopen(szOutPath, _T("wb+"));
GOTO_CLEANUP_IF_NULL(pOutStream, _T("Failed to open output file %s.\n"), szOutPath);
PtxSysCreateFILEStreamDescriptor(&outDescriptor, pOutStream, 0);
iConformance = PtxPdf_Document_GetConformance(pInDoc);
pOutDoc = PtxPdf_Document_Create(&outDescriptor, &iConformance, NULL);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutDoc, _T("Output file %s cannot be closed. %s (ErrorCode: 0x%08x).\n"), szOutPath, szErrorBuff, Ptx_GetLastError());

// Create embedded font in output document
pFont = PtxPdfContent_Font_CreateFromSystem(pOutDoc, _T("Arial"), _T("Italic"), TRUE);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pFont, _T("Embedded font cannot be created. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

// Copy document-wide data
GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(copyDocumentData(pInDoc, pOutDoc), _T("Failed to copy document-wide data. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

// Get the color space
TPtxPdfContent_ColorSpace* pColorSpace = PtxPdfContent_ColorSpace_CreateProcessColorSpace(pOutDoc, ePtxPdfContent_ProcessColorSpaceType_Rgb);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pColorSpace, _T("Failed to get the color space. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

// Chose the RGB color values
double color[] = { 1.0, 0.0, 0.0 };
size_t nColor = sizeof(color) / sizeof(double);
pTransparency = PtxPdfContent_Transparency_New(dAlpha);

// Create paint object
pPaint = PtxPdfContent_Paint_Create(pOutDoc, pColorSpace, color, nColor, pTransparency);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pPaint, _T("Failed to create a transparent paint. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

// Configure copy options
pCopyOptions = PtxPdf_PageCopyOptions_New();

// Loop through all pages of input
pInPageList = PtxPdf_Document_GetPages(pInDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pInPageList, _T("Failed to get the pages of the input document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
pOutPageList = PtxPdf_Document_GetPages(pOutDoc);
GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPageList, _T("Failed to get the pages of the output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
for (int i = 0; i < PtxPdf_PageList_GetCount(pInPageList); i++)
{
    // Get a list of pages
    pInPage = PtxPdf_PageList_Get(pInPageList, i);

    // Copy page from input to output
    pOutPage = PtxPdf_Page_Copy(pOutDoc, pInPage, pCopyOptions);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pOutPage, _T("Failed to copy pages from input to output. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    // Add stamp to page
    if (addStamp(pOutDoc, pOutPage, szStampString, pFont, 50) == 1)
    {
        goto cleanup;
    }

    // Add page to output document
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_PageList_Add(pOutPageList, pOutPage), _T("Failed to add page to output document. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    if (pOutPage != NULL)
    {
        Ptx_Release(pOutPage);
        pOutPage = NULL;
    }

    if (pInPage != NULL)
    {
        Ptx_Release(pInPage);
        pInPage = NULL;
    }
}
int copyDocumentData(TPtxPdf_Document * pInDoc, TPtxPdf_Document * pOutDoc)
{
    TPtxPdf_FileReferenceList* pInFileRefList;
    TPtxPdf_FileReferenceList* pOutFileRefList;

    // Output intent
    if (PtxPdf_Document_GetOutputIntent(pInDoc) != NULL)
        if (PtxPdf_Document_SetOutputIntent(pOutDoc, PtxPdfContent_IccBasedColorSpace_Copy(pOutDoc, PtxPdf_Document_GetOutputIntent(pInDoc))) == FALSE)
            return FALSE;

    // Metadata
    if (PtxPdf_Document_SetMetadata(pOutDoc, PtxPdf_Metadata_Copy(pOutDoc, PtxPdf_Document_GetMetadata(pInDoc))) == FALSE)
        return FALSE;

    // Viewer settings
    if (PtxPdf_Document_SetViewerSettings(pOutDoc, PtxPdfNav_ViewerSettings_Copy(pOutDoc, PtxPdf_Document_GetViewerSettings(pInDoc))) == FALSE)
        return FALSE;

    // Associated files (for PDF/A-3 and PDF 2.0 only)
    pInFileRefList = PtxPdf_Document_GetAssociatedFiles(pInDoc);
    pOutFileRefList = PtxPdf_Document_GetAssociatedFiles(pOutDoc);
    if (pInFileRefList == NULL || pOutFileRefList == NULL)
        return FALSE;
    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
        if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
            return FALSE;

    // Plain embedded files
    pInFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pInDoc);
    pOutFileRefList = PtxPdf_Document_GetPlainEmbeddedFiles(pOutDoc);
    if (pInFileRefList == NULL || pOutFileRefList == NULL)
        return FALSE;
    for (int iFileRef = 0; iFileRef < PtxPdf_FileReferenceList_GetCount(pInFileRefList); iFileRef++)
        if (PtxPdf_FileReferenceList_Add(pOutFileRefList, PtxPdf_FileReference_Copy(pOutDoc, PtxPdf_FileReferenceList_Get(pInFileRefList, iFileRef))) == FALSE)
            return FALSE;

    return TRUE;
}
int addStamp(TPtxPdf_Document* pOutDoc, TPtxPdf_Page* pOutPage, TCHAR* szStampString, TPtxPdfContent_Font* pFont, double dFontSize)
{
    TPtxPdfContent_ContentGenerator* pGenerator = NULL;
    TPtxPdfContent_Text* pText = NULL;
    TPtxPdfContent_TextGenerator* pTextGenerator = NULL;
    TPtxGeomReal_AffineTransform trans;
    TPtxGeomReal_Point rotationCenter;
    double dTextWidth;
    double dFontAscent;

    TPtxPdfContent_Content* pContent = PtxPdf_Page_GetContent(pOutPage);

    // Create content generator
    pGenerator = PtxPdfContent_ContentGenerator_New(pContent, FALSE);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pGenerator, _T("Failed to create a content generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    // Create text object
    pText = PtxPdfContent_Text_Create(pOutDoc);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pText, _T("Failed to create a text object. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    // Create a text generator 
    pTextGenerator = PtxPdfContent_TextGenerator_New(pText, pFont, dFontSize, NULL);
    GOTO_CLEANUP_IF_NULL_PRINT_ERROR(pTextGenerator, _T("Failed to create a text generator. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    // Get output page size
    TPtxGeomReal_Size size;
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdf_Page_GetSize(pOutPage, &size), _T("Failed to read page size. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    // Calculate point and angle of rotation
    rotationCenter.dX = size.dWidth / 2.0;
    rotationCenter.dY = size.dHeight / 2.0;
    double dRotationAngle = atan2(size.dHeight, size.dWidth) / M_PI * 180.0;

    // Rotate textinput around the calculated position
    PtxGeomReal_AffineTransform_GetIdentity(&trans);
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxGeomReal_AffineTransform_Rotate(&trans, dRotationAngle, &rotationCenter), _T("Failed to rotate textinput around the calculated position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_Transform(pGenerator, &trans), _T("Failed to modify the current transformation. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    // Calculate position
    TPtxGeomReal_Point position;
    dTextWidth = PtxPdfContent_TextGenerator_GetWidth(pTextGenerator, szStampString);
    GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dTextWidth, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
    dFontAscent = PtxPdfContent_Font_GetAscent(pFont);
    GOTO_CLEANUP_IF_ZERO_PRINT_ERROR(dFontAscent, _T("%s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
    position.dX = (size.dWidth - dTextWidth) / 2.0;
    position.dY = (size.dHeight - dFontAscent * dFontSize) / 2.0;

    // Move to position
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_MoveTo(pTextGenerator, &position), _T("Failed to move to position. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
    // Set text rendering
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_SetFill(pTextGenerator, pPaint), _T("Failed to set fill paint. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());
    // Add given stamp string
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_TextGenerator_ShowLine(pTextGenerator, szStampString), _T("Failed to add stamp. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

    // Close text generator
    if (pTextGenerator != NULL)
    {
        PtxPdfContent_TextGenerator_Close(pTextGenerator);
        pTextGenerator = NULL;
    }

    // Paint the positioned text
    GOTO_CLEANUP_IF_FALSE_PRINT_ERROR(PtxPdfContent_ContentGenerator_PaintText(pGenerator, pText), _T("Failed to paint the positioned text. %s (ErrorCode: 0x%08x).\n"), szErrorBuff, Ptx_GetLastError());

cleanup:
    if (pTextGenerator != NULL)
        PtxPdfContent_TextGenerator_Close(pTextGenerator);
    if (pText != NULL)
        Ptx_Release(pText);
    if (pGenerator != NULL)
        PtxPdfContent_ContentGenerator_Close(pGenerator);
    if (pContent != NULL)
        Ptx_Release(pContent);

    return iReturnValue;
}
PDF Expert blog - the caveats of assembling PDF/A documents

The caveats of assembling PDF/A documents

Assembling PDF documents from various sources is a crucial part of an output management system. And, as the document needs to be archived in most cases, it should conform to the PDF/A standard. Is there a way to assemble a document and accomplish PDF/A conformance in one step?


PDF Expert Blog - embedded fonts and PDF mass printing application

The problem with embedded fonts in PDF mass printing applications

PDF is more and more finding its way into mass printing applications. However, PDF spool files often ask too much from a print engine resulting in aborts or, even worse, incomplete prints which may not be noticed. What is special about PDF mass printing...