Q: We are looking for a PDF SDK that will allow us to get a virtual
Device Context that we can specify its resolution and paper dimension.
We want to be able to use our C++ software to use WIN32 calls to write
into the DC to create PDF documents whether there are any printer
drivers installed on the system or not. Will any of your software
packages provide us with these options?
----------
A: We are about to release a new version of PDFNet SDK (v.5.
http://www.pdftron.com/pdfnet) and PDFDC (PDF Device Context) will be
one of the new features.
PDFDC will enable you to write into the DC to create PDF documents
whether there are any printer drivers installed on the system or not.
DotNet developers will also be able to create .NET PDF Graphics object
and use it for PDF generation without having to learn more advanced
PDF creation APIs available in PDFNet.
Attached is the header and some sample code illustrating the use of
the new class. Pre-release version is available to existing clinets.
//-----------------------------------------
/**
* PDFDC can be used to create a PDF compatible GDI Display Context.
*/
class PDFDC
{
public:
PDFDC();
~PDFDC();
/**
* Create an empty EMF and returns a the GDI Display Context.
*
* @param in_doc pointer to the document which will hold the
converted
* data including embedded fonts and objects.
* @return a GDI Handle to Display Context.
*/
HDC Begin( PDFDoc & in_doc, double dpi = 72);
/**
* Closes the EMF Display Context, converts to PDF and returns the
resulting Form
* XObject. The XObject can be placed on a PDF page or any content
stream.
*/
SDF::Obj End();
private:
TRN_PDFDC m_pdfdc;
};
//-------------------
#include <windows.h>
#include <math.h>
#include <assert.h>
#include <tchar.h>
#include <strsafe.h>
#include <iostream>
#include <PDF/PDFNet.h>
#include <PDF/PDFDoc.h>
#include <PDF/PDFDC.h>
#include <PDF/ElementBuilder.h>
#include <PDF/ElementWriter.h>
#include <SDF/Obj.h>
#include <iostream>
using namespace pdftron;
using namespace SDF;
using namespace PDF;
using namespace std;
// Relative path to the folder containing test files.
string input_path = "../../TestFiles/";
string outputPath = "../../TestFiles/Output/";
// lfHeight; lfWidth; lfEscapement; lfOrientation; lfWeight; lfItalic;
lfUnderline; lfStrikeOut; lfCharSet;
// lfOutPrecision; lfClipPrecision; lfQuality; lfPitchAndFamily;
// lfFaceName[LF_FACESIZE];
static const LOGFONTW ArialFont =
{
24,
0,
200,
200,
FW_NORMAL,
FALSE,
FALSE,
FALSE,
ANSI_CHARSET,
0,
0,
DEFAULT_QUALITY,
VARIABLE_PITCH | FF_SWISS,
L"Arial"
};
void OnDraw(HDC hDC)
{
LONG xMin = 0;
LONG yMin = 0;
LONG xMax = 500;
LONG yMax = 500;
SetGraphicsMode( hDC, GM_ADVANCED );
SetMapMode( hDC, MM_ANISOTROPIC );
SetViewportExtEx( hDC, xMax, yMax, NULL );
SetWindowOrgEx( hDC, 0, 0, NULL );
SetWindowExtEx( hDC, xMax, yMax, NULL );
SelectObject(hDC, GetStockObject( WHITE_BRUSH ) );
Rectangle( hDC, 0, 0, xMax, yMax );
SetBkMode(hDC, TRANSPARENT);
HBRUSH hBrush = CreateSolidBrush( RGB(128,0,0) );
SelectObject( hDC, hBrush );
Ellipse(hDC, xMin, yMin, xMax, yMax);
SetTextColor( hDC, RGB(255,255,0) );
HFONT hArialFont;
hArialFont = CreateFontIndirectW( &ArialFont );
assert( hArialFont );
LONG x1_org, y1_org;
LPCWSTR label;
x1_org = xMax / 2;
y1_org = yMax / 2;
SelectObject(hDC, hArialFont );
SetTextAlign( hDC, TA_CENTER | TA_TOP );
label = L"EMF 2000 - The Future is Now";
ExtTextOutW( hDC, x1_org, y1_org, ETO_OPAQUE, NULL, label, wcslen
(label), NULL );
DeleteObject( hArialFont );
DeleteObject( hBrush );
}
int main()
{
int ret = 0;
HDC currentHdc;
PDFNet::Initialize();
try
{
PDFDoc pdfdoc;
PDFDC pdfDc;
Page page = pdfdoc.PageCreate();
ElementWriter writer;
writer.Begin(page);
ElementBuilder eb;
currentHdc = pdfDc.Begin( pdfdoc );
OnDraw(currentHdc);
SDF::Obj obj = pdfDc.End();
Element element = eb.CreateForm(obj);
Rect cropBox = page.GetCropBox();
// TODO: assume that the page is in portrait, scale up the FormX
object and center it vertically
element.GetGState().SetTransform(cropBox.x2, 0.0, 0.0, cropBox.x2,
0, (cropBox.y2 - cropBox.x2) / 2.0);
writer.WriteElement(element);
writer.End();
pdfdoc.PagePushBack(page);
string outputFile = outputPath + "Emf2PdfTest.pdf";
pdfdoc.Save(outputFile.c_str(), SDFDoc::e_remove_unused, NULL);
// An example of using the high-level PDFNet API to read existing
annotations,
// to edit existing annotations, and to create new annotation from
scratch.
cout << "Saved " << outputPath.c_str() << "\nDone. " << endl;
}
catch(Common::Exception& e)
{
cout << e << endl;
ret = 1;
}
catch(...)
{
cout << "Unknown Exception" << endl;
ret = 1;
}
PDFNet::Terminate();
return ret;
}