PdfFont* PdfFontFactory::CreateFontObject( PdfFontMetrics* pMetrics, int nFlags, const PdfEncoding* const pEncoding, PdfVecObjects* pParent ) { PdfFont* pFont = NULL; EPdfFontType eType = pMetrics->GetFontType(); bool bEmbed = nFlags & ePdfFont_Embedded; bool bSubsetting = (nFlags & ePdfFont_Subsetting) != 0; try { pFont = PdfFontFactory::CreateFontForType( eType, pMetrics, pEncoding, bEmbed, bSubsetting, pParent ); if( pFont ) { pFont->SetBold( nFlags & ePdfFont_Bold ? true : false ); pFont->SetItalic( nFlags & ePdfFont_Italic ? true : false ); } else { // something went wrong, so we have to delete // the font metrics delete pMetrics; // make sure this will be done before the catch block // as the encoding might be deleted already // afterwars, but we cannot set the pointer to NULL if( pEncoding && pEncoding->IsAutoDelete() ) delete pEncoding; } } catch( PdfError & e ) { // we have to delete the pMetrics object in case of error if( pFont ) { // The font will delete encoding and metrics delete pFont; pFont = NULL; } else { // something went wrong, so we have to delete // the font metrics (and if auto-delete, also the encoding) delete pMetrics; pMetrics = NULL; if( pEncoding && pEncoding->IsAutoDelete() ) delete pEncoding; } e.AddToCallstack( __FILE__, __LINE__, "Font creation failed." ); throw e; } return pFont; }
PdfFont* PdfFontCache::GetDuplicateFontType1( PdfFont * pFont, const char* pszSuffix ) { TCISortedFontList it = m_vecFonts.begin(); std::string id = pFont->GetIdentifier().GetName(); id += pszSuffix; // Search if the object is a cached normal font while( it != m_vecFonts.end() ) { if( (*it).m_pFont->GetIdentifier() == id ) return (*it).m_pFont; ++it; } // Search if the object is a cached font subset it = m_vecFontSubsets.begin(); while( it != m_vecFontSubsets.end() ) { if( (*it).m_pFont->GetIdentifier() == id ) return (*it).m_pFont; ++it; } // Create a copy of the font PODOFO_ASSERT( pFont->GetFontMetrics()->GetFontType() == ePdfFontType_Type1Pfb ); PdfFontMetrics *pMetrics = new PdfFontMetrics( &m_ftLibrary, pFont->GetFontMetrics()->GetFilename() ); PdfFont* newFont = new PdfFontType1( static_cast<PdfFontType1 *>(pFont), pMetrics, pszSuffix, m_pParent ); if( newFont ) { std::string name = newFont->GetFontMetrics()->GetFontname(); name += pszSuffix; TFontCacheElement element; element.m_pFont = newFont; element.m_bBold = newFont->IsBold(); element.m_bItalic = newFont->IsItalic(); element.m_sFontName = name; element.m_pEncoding = newFont->GetEncoding(); m_vecFonts .push_back( element ); // Now sort the font list std::sort( m_vecFonts.begin(), m_vecFonts.end() ); } return newFont; }
void draw( char* pszBuffer, PdfDocument* pDocument ) { PdfPage* pPage; PdfPainter painter; PdfFont* pFont; PdfRect size; double dX = BORDER_LEFT; double dY = BORDER_TOP; char* pszStart = pszBuffer; size = PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ); pFont = pDocument->CreateFont( "Arial" ); pPage = pDocument->CreatePage( size ); if( !pFont ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pFont->SetFontSize( FONT_SIZE ); painter.SetPage( pPage ); painter.SetFont( pFont ); while( *pszBuffer ) { if( *pszBuffer == '\n' ) { painter.DrawText( dX, dY, pszStart, pszBuffer-pszStart ); pszStart = (++pszBuffer); dY += pFont->GetFontMetrics()->GetLineSpacing(); if( dY > (size.GetHeight() - BORDER_TOP) ) { pPage = pDocument->CreatePage( size ); painter.SetPage( pPage ); dY = BORDER_TOP; } } else ++pszBuffer; } painter.FinishPage(); }
PdfFont* PdfFontCache::GetFont( PdfObject* pObject ) { TCISortedFontList it = m_vecFonts.begin(); const PdfReference & ref = pObject->Reference(); // Search if the object is a cached normal font while( it != m_vecFonts.end() ) { if( (*it).m_pFont->GetObject()->Reference() == ref ) return (*it).m_pFont; ++it; } // Search if the object is a cached font subset it = m_vecFontSubsets.begin(); while( it != m_vecFontSubsets.end() ) { if( (*it).m_pFont->GetObject()->Reference() == ref ) return (*it).m_pFont; ++it; } // Create a new font PdfFont* pFont = PdfFontFactory::CreateFont( &m_ftLibrary, pObject ); if( pFont ) { TFontCacheElement element; element.m_pFont = pFont; element.m_bBold = pFont->IsBold(); element.m_bItalic = pFont->IsItalic(); element.m_sFontName = pFont->GetFontMetrics()->GetFontname(); element.m_pEncoding = NULL; m_vecFonts .push_back( element ); // Now sort the font list std::sort( m_vecFonts.begin(), m_vecFonts.end() ); } return pFont; }
PdfFont* PdfFontCache::CreateFontObject( TISortedFontList itSorted, TSortedFontList & rvecContainer, PdfFontMetrics* pMetrics, bool bEmbedd, bool bBold, bool bItalic, const char* pszFontName, const PdfEncoding * const pEncoding ) { PdfFont* pFont; try { int nFlags = ePdfFont_Normal; if( bEmbedd ) nFlags |= ePdfFont_Embedded; if( bBold ) nFlags |= ePdfFont_Bold; if( bItalic ) nFlags |= ePdfFont_Italic; pFont = PdfFontFactory::CreateFontObject( pMetrics, nFlags, pEncoding, m_pParent ); if( pFont ) { TFontCacheElement element; element.m_pFont = pFont; element.m_bBold = pFont->IsBold(); element.m_bItalic = pFont->IsItalic(); element.m_sFontName = pszFontName; element.m_pEncoding = pEncoding; // Do a sorted insert, so no need to sort again rvecContainer.insert( itSorted, element ); } } catch( PdfError & e ) { e.AddToCallstack( __FILE__, __LINE__ ); e.PrintErrorMsg(); PdfError::LogMessage( eLogSeverity_Error, "Cannot initialize font: %s\n", pszFontName ? pszFontName : "" ); return NULL; } return pFont; }
void PagesTreeTest::testCreateDelete() { PdfMemDocument writer; PdfPage* pPage; PdfPainter painter; PdfFont * pFont; // create font pFont = writer.CreateFont( "Arial" ); if( !pFont ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pFont->SetFontSize( 16.0 ); // write 1. page pPage = writer.CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) ); painter.SetPage( pPage ); painter.SetFont( pFont ); painter.DrawText( 200, 200, "Page 1" ); painter.FinishPage(); CPPUNIT_ASSERT_EQUAL( writer.GetPageCount(), 1 ); // write 2. page pPage = writer.CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) ); painter.SetPage( pPage ); painter.DrawText( 200, 200, "Page 2" ); painter.FinishPage(); CPPUNIT_ASSERT_EQUAL( writer.GetPageCount(), 2 ); // try to delete second page, index is 0 based writer.DeletePages( 1, 1 ); CPPUNIT_ASSERT_EQUAL( writer.GetPageCount(), 1 ); // write 3. page pPage = writer.CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) ); painter.SetPage( pPage ); painter.DrawText( 200, 200, "Page 3" ); painter.FinishPage(); CPPUNIT_ASSERT_EQUAL( writer.GetPageCount(), 2 ); }
void EncryptTest::CreatedEncrypedPdf( const char* pszFilename ) { PdfMemDocument writer; PdfPage* pPage = writer.CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) ); PdfPainter painter; painter.SetPage( pPage ); PdfFont* pFont = writer.CreateFont( "Arial", PdfEncodingFactory::GlobalWinAnsiEncodingInstance(), false ); if( !pFont ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pFont->SetFontSize( 16.0 ); painter.SetFont( pFont ); painter.DrawText( 100, 100, "Hello World" ); painter.FinishPage(); writer.SetEncrypted( "user", "owner" ); writer.Write( pszFilename ); printf( "Wrote: %s\n", pszFilename ); }
void PdfAcroForm::Init( EPdfAcroFormDefaulAppearance eDefaultAppearance ) { // Add default appearance: black text, 12pt times // -> only if we do not have a DA key yet // Peter Petrov 27 April 2008 //this->GetObject()->GetDictionary().AddKey( PdfName("NeedAppearances"), PdfVariant(true) ); if( !this->GetObject()->GetDictionary().HasKey("DA") && eDefaultAppearance == ePdfAcroFormDefaultAppearance_BlackText12pt ) { //PdfFont* pFont = pParent->GetDocument()->CreateFont( "Helvetica", false ); // TODO: It is no good idea to always embedd arial // but handling of non embedded helvetica is currently broken PdfFont* pFont = m_pDocument->CreateFont( "Arial" ); // embedd is default true PdfObject* pResource; PdfObject* pFontDict; // Create DR key if( !this->GetObject()->GetDictionary().HasKey( PdfName("DR") ) ) this->GetObject()->GetDictionary().AddKey( PdfName("DR"), PdfDictionary() ); pResource = this->GetObject()->GetDictionary().GetKey( PdfName("DR") ); if( !pResource->GetDictionary().HasKey( PdfName("Font") ) ) pResource->GetDictionary().AddKey( PdfName("Font"), PdfDictionary() ); pFontDict = pResource->GetDictionary().GetKey( PdfName("Font") ); pFontDict->GetDictionary().AddKey( pFont->GetIdentifier(), pFont->GetObject()->Reference() ); // Create DA key std::ostringstream oss; PdfLocaleImbue(oss); oss << "0 0 0 rg /" << pFont->GetIdentifier().GetName() << " 12 Tf"; this->GetObject()->GetDictionary().AddKey( PdfName("DA"), PdfString( oss.str() ) ); } }
void draw( char* pszBuffer, PdfDocument* pDocument, bool bUtf8, const char* pszFontName ) { PdfPage* pPage; PdfPainter painter; PdfFont* pFont; PdfRect size; const PdfEncoding* pEncoding; double dX = BORDER_LEFT; double dY = BORDER_TOP; char* pszStart = pszBuffer; if( bUtf8 ) { pEncoding = new PdfIdentityEncoding(); } else { pEncoding = PdfEncodingFactory::GlobalWinAnsiEncodingInstance(); } size = PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ); pFont = pDocument->CreateFont( pszFontName, pEncoding ); pPage = pDocument->CreatePage( size ); dY = size.GetHeight() - dY; if( !pFont ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pFont->SetFontSize( FONT_SIZE ); painter.SetPage( pPage ); painter.SetFont( pFont ); while( *pszBuffer ) { if( *pszBuffer == '\n' ) { if( bUtf8 ) { painter.DrawText( dX, dY, PdfString( reinterpret_cast<const pdf_utf8*>(pszStart), pszBuffer-pszStart ) ); } else { painter.DrawText( dX, dY, pszStart, pszBuffer-pszStart ); } pszStart = (++pszBuffer); dY -= pFont->GetFontMetrics()->GetLineSpacing(); if( dY < BORDER_TOP ) { pPage = pDocument->CreatePage( size ); painter.SetPage( pPage ); dY = size.GetHeight() - dY; } } else ++pszBuffer; } painter.FinishPage(); }
void HelloWorld( const char* pszFilename ) { /* * PdfStreamedDocument is the class that can actually write a PDF file. * PdfStreamedDocument is much faster than PdfDocument, but it is only * suitable for creating/drawing PDF files and cannot modify existing * PDF documents. * * The document is written directly to pszFilename while being created. */ PdfStreamedDocument document( pszFilename ); /* * PdfPainter is the class which is able to draw text and graphics * directly on a PdfPage object. */ PdfPainter painter; /* * This pointer will hold the page object later. * PdfSimpleWriter can write several PdfPage's to a PDF file. */ PdfPage* pPage; /* * A PdfFont object is required to draw text on a PdfPage using a PdfPainter. * PoDoFo will find the font using fontconfig on your system and embedd truetype * fonts automatically in the PDF file. */ PdfFont* pFont; try { /* * The PdfDocument object can be used to create new PdfPage objects. * The PdfPage object is owned by the PdfDocument will also be deleted automatically * by the PdfDocument object. * * You have to pass only one argument, i.e. the page size of the page to create. * There are predefined enums for some common page sizes. */ pPage = document.CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) ); /* * If the page cannot be created because of an error (e.g. ePdfError_OutOfMemory ) * a NULL pointer is returned. * We check for a NULL pointer here and throw an exception using the RAISE_ERROR macro. * The raise error macro initializes a PdfError object with a given error code and * the location in the file in which the error ocurred and throws it as an exception. */ if( !pPage ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } /* * Set the page as drawing target for the PdfPainter. * Before the painter can draw, a page has to be set first. */ painter.SetPage( pPage ); /* * Create a PdfFont object using the font "Arial". * The font is found on the system using fontconfig and embedded into the * PDF file. If Arial is not available, a default font will be used. * * The created PdfFont will be deleted by the PdfDocument. */ pFont = document.CreateFont( "Arial" ); /* * If the PdfFont object cannot be allocated return an error. */ if( !pFont ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } /* * Set the font size */ pFont->SetFontSize( 18.0 ); /* * Set the font as default font for drawing. * A font has to be set before you can draw text on * a PdfPainter. */ painter.SetFont( pFont ); /* * You could set a different color than black to draw * the text. * * SAFE_OP( painter.SetColor( 1.0, 0.0, 0.0 ) ); */ /* * Actually draw the line "Hello World!" on to the PdfPage at * the position 2cm,2cm from the top left corner. * Please remember that PDF files have their origin at the * bottom left corner. Therefore we substract the y coordinate * from the page height. * * The position specifies the start of the baseline of the text. * * All coordinates in PoDoFo are in PDF units. * You can also use PdfPainterMM which takes coordinates in 1/1000th mm. * */ painter.DrawText( 56.69, pPage->GetPageSize().GetHeight() - 56.69, "Hello World!" ); /* * Tell PoDoFo that the page has been drawn completely. * This required to optimize drawing operations inside in PoDoFo * and has to be done whenever you are done with drawing a page. */ painter.FinishPage(); /* * Set some additional information on the PDF file. */ document.GetInfo()->SetCreator ( PdfString("examplahelloworld - A PoDoFo test application") ); document.GetInfo()->SetAuthor ( PdfString("Dominik Seichter") ); document.GetInfo()->SetTitle ( PdfString("Hello World") ); document.GetInfo()->SetSubject ( PdfString("Testing the PoDoFo PDF Library") ); document.GetInfo()->SetKeywords( PdfString("Test;PDF;Hello World;") ); /* * The last step is to close the document. */ document.Close(); } catch ( const PdfError & e ) { /* * All PoDoFo methods may throw exceptions * make sure that painter.FinishPage() is called * or who will get an assert in its destructor */ try { painter.FinishPage(); } catch( ... ) { /* * Ignore errors this time */ } throw e; } }
void PdfTable::Draw( double dX, double dY, PdfPainter* pPainter, const PdfRect & rClipRect, double* pdLastX, double* pdLastY ) { if( !pPainter ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } //RG: TODO Should dCurY variable be initialised with 0? (line 257 may fall through without initialisation!) int i = 0; int j = 0; double dCurX = 0.0; double dCurY = 0.0; double dWidth = 0.0; double dHeight = 0.0; double dVertical = 0.0; double* pdColWidths = new double[this->GetCols()]; double* pdRowHeights = new double[this->GetRows()]; bool bBorders = !m_pModel || (m_pModel && m_pModel->HasBorders() ); // Calculate all necessary sizes this->CalculateTableSize( dX, dY, pPainter->GetPage(), pdColWidths, pdRowHeights, &dWidth, &dHeight ); if( !(!static_cast<int>(rClipRect.GetBottom()) && !static_cast<int>(rClipRect.GetLeft()) && !static_cast<int>(rClipRect.GetWidth()) && !static_cast<int>(rClipRect.GetWidth())) ) m_curClipRect = rClipRect; else { m_curClipRect = PdfRect( 0.0, dX, pPainter->GetPage()->GetPageSize().GetWidth() - dX, dY ); } // Draw the table pPainter->Save(); PdfFont* pDefaultFont = pPainter->GetFont(); // get the default font PdfFont* pFont; // draw contents if( m_pModel ) { pPainter->SetStrokeWidth( m_pModel->GetBorderWidth() ); if( bBorders ) // draw top border this->DrawHorizontalBorders( 0, dX, dY, pPainter, pdColWidths ); for( j=0;j<m_nRows;j++ ) { if( this->CheckForNewPage( &dY, &dCurY, pdRowHeights[j], pPainter ) && bBorders ) // draw top border on new page this->DrawHorizontalBorders( j, dX, dY, pPainter, pdColWidths ); dCurX = 0.0; dCurY += pdRowHeights[j]; for( i=0;i<m_nCols;i++ ) { // set a clipping rectangle pPainter->Save(); pPainter->SetClipRect( dX + dCurX, dY - dCurY, pdColWidths[i], pdRowHeights[j] ); // Draw background double dBorder = bBorders ? m_pModel->GetBorderWidth()/2.0 : 0.0; if( m_pModel->HasBackgroundColor( i, j ) ) { pPainter->Save(); pPainter->SetColor( m_pModel->GetBackgroundColor( i, j ) ); // Make sure that FillRect only fills inside the border // rectangle and not over the border. This is necessary // because we draw the border first and than the contents. pPainter->FillRect( dX + dCurX + dBorder, dY - dCurY + dBorder, pdColWidths[i] - 2.0 * dBorder, pdRowHeights[j] - 2.0 * dBorder ); pPainter->Restore(); } // draw an image PdfImage* pImage = m_pModel->GetImage( i, j ); double dImageWidth = 0.0; if( m_pModel->HasImage( i, j ) && pImage ) { double dScaleX = (pdColWidths[i]) / pImage->GetPageSize().GetWidth(); double dScaleY = (pdRowHeights[j] - 2.0 * dBorder) / pImage->GetPageSize().GetHeight(); double dScale = PDF_MIN( dScaleX, dScaleY ); dImageWidth = pImage->GetPageSize().GetWidth() * dScale; pPainter->DrawImage( dX + dCurX, dY - dCurY + dBorder, pImage, dScale, dScale ); } // Set the correct font pFont = m_pModel->GetFont( i, j ); pFont = pFont ? pFont : pDefaultFont; pPainter->SetFont( pFont ); pPainter->SetColor( m_pModel->GetForegroundColor( i, j ) ); // draw text if( m_pModel->HasWordWrap( i, j ) ) { // Make sure we have at least 1 dot free space at each side of the rectangle pPainter->DrawMultiLineText( dX + dCurX + 1.0 + dImageWidth, dY - dCurY, pdColWidths[i] - 2.0 - dImageWidth, pdRowHeights[j], m_pModel->GetText( i, j ), m_pModel->GetAlignment( i, j ), m_pModel->GetVerticalAlignment( i, j ) ); } else { // calculate vertical alignment switch( m_pModel->GetVerticalAlignment( i, j ) ) { default: case ePdfVerticalAlignment_Top: dVertical = 0.0; break; case ePdfVerticalAlignment_Center: dVertical = (pdRowHeights[j] - pFont->GetFontMetrics()->GetLineSpacing()) / 2.0; break; case ePdfVerticalAlignment_Bottom: dVertical = (pdRowHeights[j] - pFont->GetFontMetrics()->GetLineSpacing()); break; } // Make sure we have at least 1 dot free space at each side of the rectangle pPainter->DrawTextAligned( dX + dCurX + 1 + dImageWidth, dY - dCurY + dVertical, pdColWidths[i] - 2.0 - dImageWidth, m_pModel->GetText( i, j ), m_pModel->GetAlignment( i, j ) ); } pPainter->Restore(); if( bBorders ) // draw left x border { // use always the border color of the left to the current cell pPainter->SetStrokingColor( m_pModel->GetBorderColor( i>0 ? i-1 : i, j ) ); pPainter->DrawLine( dX + dCurX, dY - dCurY, dX + dCurX, dY - dCurY + pdRowHeights[j] ); } dCurX += pdColWidths[i]; } if( bBorders ) { // Draw last X border if( i > 0 ) { pPainter->SetStrokingColor( m_pModel->GetBorderColor( i-1, j ) ); pPainter->DrawLine( dX + dCurX, dY - dCurY, dX + dCurX, dY - dCurY + pdRowHeights[j] ); } // draw border below row this->DrawHorizontalBorders( j, dX, dY - dCurY, pPainter, pdColWidths ); } } } pPainter->Restore(); if( pdLastX ) *pdLastX = dX + dWidth; if( pdLastY ) *pdLastY = dY - dCurY; // Free allocated memory delete [] pdColWidths; delete [] pdRowHeights; }
err_info *Pdfwrite::create (void) { try { qDebug () << _fname; _doc = new PdfMemDocument (); _doc->GetInfo()->SetCreator ( PdfString("examplahelloworld - A PoDoFo test application") ); _doc->GetInfo()->SetAuthor ( PdfString("Dominik Seichter") ); _doc->GetInfo()->SetTitle ( PdfString("Hello World") ); _doc->GetInfo()->SetSubject ( PdfString("Testing the PoDoFo PDF Library") ); _doc->GetInfo()->SetKeywords( PdfString("Test;PDF;Hello World;") ); } catch (const PdfError &eCode) { return err_make (ERRFN, E_pdf_creation_error1, eCode.ErrorMessage (eCode.GetError())); } #if 0 try { _doc = new PdfStreamedDocument (_fname.latin1 ()); PdfPage* pPage; PdfPainter painter; PdfFont* pFont; pPage = _doc->CreatePage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ) ); if( !pPage ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } painter.SetPage( pPage ); pFont = _doc->CreateFont( "Arial" ); if( !pFont ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pFont->SetFontSize( 18.0 ); painter.SetFont( pFont ); painter.DrawText( 56.69, pPage->GetPageSize().GetHeight() - 56.69, "Hello World!" ); painter.FinishPage(); _doc->GetInfo()->SetCreator ( PdfString("examplahelloworld - A PoDoFo test application") ); _doc->GetInfo()->SetAuthor ( PdfString("Dominik Seichter") ); _doc->GetInfo()->SetTitle ( PdfString("Hello World") ); _doc->GetInfo()->SetSubject ( PdfString("Testing the PoDoFo PDF Library") ); _doc->GetInfo()->SetKeywords( PdfString("Test;PDF;Hello World;") ); _doc->Close(); } catch (const PdfError &eCode) { return err_make (ERRFN, E_pdf_creation_error1, eCode.ErrorMessage (eCode.GetError())); } #endif return NULL; }