Some test text!

Discord Logo

Chat with us

PDFTron is now Apryse, learn more here.

PDF device context in C++

More languages

More languages

Sample C++ code for using PDFTron SDK to create and use PDFDC (i.e. a PDF Device Context). Windows developers can use standard GDI or GDI+ API-s to write on PDFDC and to generate PDF documents based on their existing drawing functions. PDFDC can also be used to implement file conversion from any printable file format to PDF. Learn more about our C++ PDF Library and Windows PDF Library.

Get Started Samples Download

To run this sample, get started with a free trial of Apryse SDK.

// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
// Consult legal.txt regarding legal and license information.

#include <iostream>
#include <sstream>
#include <PDF/PDFNet.h>
#include <PDF/PDFDC.h>
#include <PDF/PDFDCEX.h>
#include "../../LicenseKey/CPP/LicenseKey.h"

// This sample shows how to create and use the PDFDCEX which allows 
// printer-like multipage translations with GDI resources used across pages.
// PDFDCEX allows you to create page after page of GDI to PDF conversion using existing 
// printing functions.

using namespace pdftron;
using namespace PDF;

// Relative path to the folder containing test files.
std::string inputPath =  "../../TestFiles/";
std::string outputPath = "../../TestFiles/Output/";

// Define a font
static const LOGFONTW ArialFont =
	12,							// height (points)
	0,							// width (use default)
	0,							// rotation of baseline for text strings
	0,							// rotation of each character
	FW_NORMAL,					// weight
	FALSE,						// italic
	FALSE,						// underline
	FALSE,						// strike out
	ANSI_CHARSET,				// character set
	OUT_DEFAULT_PRECIS,			// output precision
	CLIP_DEFAULT_PRECIS,		// clip precision
	DEFAULT_QUALITY,			// quality
	VARIABLE_PITCH | FF_SWISS,	// pitch and family
	L"Arial"					// font name

int main()
	int ret = 0;
#if defined(_WIN32) && !defined(WINCE)


		// Add two pages to a new PDFDoc.
		// Fonts and resources are shared across pages.  No need to work with each PDFPage.
		// We work in page coordinates which are page dimensions (inches) times
		// DPI. Origin is at upper left corner of the page, positive down and to right.

		// Start with a PDFDoc to put the translation into, and a PDFDCEX to translate GDI to PDF
		PDFDoc pdfdoc2;
		PDFDCEX pdfDcEx;
		HDC hDC2;
		HFONT hArialFont2;
		HGDIOBJ hOldFont2;
		HGDIOBJ hPen2, hOldPen2;

		// Begin the translation from GDI to PDF -- provide the PDFDoc to append to.
		// Get back a GDI Device Context, we've added "::" the start of all of the
		// GDI calls to emphasize that we only use the PDFDCEX at the beginning and end.
		PDF::Point paperDimensions(8.5, 11);
		hDC2 = pdfDcEx.Begin( pdfdoc2, paperDimensions );

		UInt32 dpi = pdfDcEx.GetDPI(); 
		PDF::Point paperSize( paperDimensions.x * dpi, paperDimensions.y * dpi);


		// We like to think of font height in "points" -- convert this to page pixels
		LOGFONTW tmpFont = ArialFont;
		tmpFont.lfHeight *= dpi / 72;
		hArialFont2 = ::CreateFontIndirectW( &tmpFont );
		hOldFont2 = ::SelectObject(hDC2, hArialFont2 );

		hPen2 = ::CreatePen(PS_SOLID, 1, RGB(0,0,0));
		hOldPen2 = ::SelectObject(hDC2, hPen2);
		::SetBkMode(hDC2, TRANSPARENT);
		::Ellipse(hDC2, (int)(paperSize.x/2 - dpi), (int)(paperSize.y/2 - dpi), (int)(paperSize.x/2 + dpi), (int)(paperSize.y/2 + dpi));
		::SetTextAlign(hDC2, TA_CENTER | TA_BOTTOM);
		::TextOutW(hDC2, (int)(paperSize.x/2), (int)(paperSize.y/2 + tmpFont.lfHeight / 2), L"Hello World", 11);
		::SelectObject(hDC2, hOldPen2);

		// Page two
		// Reuse existing font and DC.
		::Ellipse(hDC2, -20, -20, 20, 20);
		::SetTextAlign(hDC2, TA_CENTER | TA_BOTTOM);
		::TextOutW(hDC2, (int)(paperSize.x/2), (int)(paperSize.y/2 + ArialFont.lfHeight / 2), L"Page 2", 6);
		::SelectObject(hDC2, hOldFont2);

		// Complete the translation

		// Save the PDF document
		pdfdoc2.Save(outputPath + "PDFDCEXTest.pdf", SDF::SDFDoc::e_remove_unused, NULL);
		std::cout << "Saved PDFDCEXTest.pdf\nDone.\n";
	catch(Common::Exception& e)
		std::cout << e << std::endl;
		ret = 1;
		std::cout << "Unknown Exception" << std::endl;
		ret = 1;

#endif // defined(_WIN32) && !defined(WINCE)
	return ret;