ImageGear for C and C++ on Windows v19.10 - Updated May 25, 2021
Edit PDF Content and Fonts
User Guide > How to Work with... > Formats with Additional Functionality > PDF > How to... > Manage PDF Content > Edit PDF Content and Fonts

Before working with a PDF document, make sure to initialize the PDF component (see Getting Started with PDF).

The ImageGear API provides content editing functionality for creating, accessing, and editing PDF page content objects. With this API you can work with a page's content as a list of objects, such as images, text, forms. You can retain, modify, and save their data and properties.  

Document font support includes:

The code snippet below adds a text element to the content of a PDF. This example demonstrates creating a font, using the content in a PDF, and creating a text element.

C
Copy Code
#include <windows.h>

#include "gear.h"
#include "i_PDF.h"

// This function returns a new font to use for the text element.
HIG_PDE_FONT CreateNewFont( )
{
    // Declare variables.
    AT_PDE_FONTATTRS fontAttrs;
    HIG_PDE_FONT hFont = NULL;
    HIG_PDF_SYSFONT hSysFont = NULL;

    // Initialize font attributes.
    memset(&fontAttrs, 0, sizeof(fontAttrs));
    // Set font name attribute.
    IG_PDF_atom_from_string("Times-Roman", &(fontAttrs.name));
    // Set font type attribute.
    IG_PDF_atom_from_string("Type1", &(fontAttrs.type));

    // Create from sysfont.
    IG_PDF_sysfont_find(&fontAttrs, 0, &hSysFont);
    IG_PDE_font_create_from_sysfont(hSysFont, 0, IG_PDF_ATOM_NULL, NULL, &hFont);
    IG_PDF_sysfont_release(hSysFont);

    return hFont;
}

// This function will add a text element into the content of the PDF document.
void AddTextToFirstPDFPage( HMIGEAR document)
{
    // Declare variables.
    HIGEAR page = NULL;
    HIG_PDF_PAGE hPDFPage = NULL;
    HIG_PDE_CONTENT hContent = NULL;
    HIG_PDE_FONT hFont = NULL;
    HIG_PDF_ATOM hCSName = IG_PDF_ATOM_NULL;
    HIG_PDE_COLORSPACE hColorSpace = NULL;
    AT_PDE_GRAPHICSTATE graphicState;
    HIG_PDE_TEXT hText = NULL;
    AT_PDF_FIXEDMATRIX textMatrix;
    AT_PDF_FIXEDRECT cropBox;
    LPSTR textToAdd;
    int textLength = 0;
    LONG horizontalCenter, verticalCenter, textWidthEM, scaledTextWidth,
        textXPosition, textYPosition = 0;
    SHORT fontWidthScale, fontHeightScale = 0;

    // Get first page.
    IG_mpi_page_get(document, 0, &page);

    // Obtain PDF page.
    IG_vector_data_get(page, (LPVOID*)&hPDFPage);

    // Get page content.
    IG_PDF_page_get_content(hPDFPage, &hContent);

    // Create a font to use with the text element.
    hFont = CreateNewFont();

    // Set the color space to DeviceRGB.
    IG_PDF_atom_from_string("DeviceRGB", &hCSName);
    IG_PDE_colorspace_create(hCSName, NULL, &hColorSpace);

    // Set the attributes for the graphic state.
    memset(&graphicState, 0, sizeof(graphicState));
    graphicState.strokeColorSpec.space = graphicState.fillColorSpec.space = hColorSpace;

    // Create a blue text (for example).
    // Note: Color values are expressed as real numbers.
        // Set R componet.
    graphicState.fillColorSpec.value.color[0] = 0;
    // Set G componet.
    graphicState.fillColorSpec.value.color[1] = 0;
    // Set B componet.
    graphicState.fillColorSpec.value.color[2] = AM_PDF_DOUBLE_TO_FIXED(255./255);

    graphicState.miterLimit = IG_PDF_FIXED_TEN;
    graphicState.flatness = IG_PDF_FIXED_ONE;
    graphicState.lineWidth = IG_PDF_FIXED_ONE;

    // Create a string of text.
    textToAdd = "This is the string of text that will be added";

    // Set the length of the text.
    textLength = strlen(textToAdd);

    // Get page box.
    IG_PDF_page_get_crop_box(hPDFPage, &cropBox);

    // Calculate the center of the page.
    horizontalCenter = (cropBox.right - cropBox.left)/2;
    verticalCenter = (cropBox.top - cropBox.bottom)/2;

    // Get the width of the text in EM space.
    // Note: One EM in a 16-point typeface is 16 points.
    IG_PDE_font_sum_widths(hFont, (LPBYTE)textToAdd, textLength, &textWidthEM);
        
    fontWidthScale = 20;
    fontHeightScale = 20;

    // Get the width of the text considering font size.
    // Note: Convert from thousandths of a point to points and adjusts by the width scale factor.
    scaledTextWidth = (textWidthEM/1000) * fontWidthScale;

    // Set coordinates to center the text.
    textXPosition = horizontalCenter - AM_PDF_LONG_TO_FIXED(scaledTextWidth/ 2);
    textYPosition = verticalCenter;

    // Create a matrix to draw text with font size 20pt at the center of the page.
    // Note: The text matrix is a 3x3 affine transform matrix, depicted in its
    // abbreviated form: [ a b c d h v ]
    // * Set matrix values a and d to the font size in pt.
    // * Set matrix values h and v to move glyphs from user space origin to a place on the page.
    memset(&textMatrix, 0, sizeof(textMatrix));
    textMatrix.a = AM_PDF_SHORT_TO_FIXED(fontWidthScale);
    textMatrix.d = AM_PDF_SHORT_TO_FIXED(fontHeightScale);
    textMatrix.h = textXPosition;
    textMatrix.v = textYPosition;

    // Create new text run.
    IG_PDE_text_create(&hText);

    // Add the textToAdd into the element using the settings from above.
    IG_PDE_text_add(hText, IG_PDE_TEXT_RUN, 0, (LPBYTE)textToAdd, textLength, hFont,
            &graphicState, NULL, &textMatrix, NULL);
    // Add the text element into the content.
    IG_PDE_content_add_element(hContent, IG_PDE_AFTER_LAST, hText);

    // Set the page's PDE content back into the page object.
    IG_PDF_page_set_content(hPDFPage);

    // Release the objects created.
    IG_PDE_element_release(hText);
    IG_PDE_colorspace_release(hColorSpace);
    IG_PDF_page_release_content( hPDFPage );
}