PdfAnnotation* PdfPage::GetAnnotation( int index ) { PdfAnnotation* pAnnot; PdfReference ref; PdfObject* pObj = this->GetAnnotationsArray( false ); if( !(pObj && pObj->IsArray()) ) { PODOFO_RAISE_ERROR( ePdfError_InvalidDataType ); } if( index < 0 && static_cast<unsigned int>(index) >= pObj->GetArray().size() ) { PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange ); } ref = pObj->GetArray()[index].GetReference(); pAnnot = m_mapAnnotations[ref]; if( !pAnnot ) { pObj = m_pObject->GetOwner()->GetObject( ref ); if( !pObj ) { PdfError::DebugMessage( "Error looking up object %i %i R\n", ref.ObjectNumber(), ref.GenerationNumber() ); PODOFO_RAISE_ERROR( ePdfError_NoObject ); } pAnnot = new PdfAnnotation( pObj, this ); m_mapAnnotations[ref] = pAnnot; } return pAnnot; }
void PdfeFontType3::initGlyphs( const PdfObject* pFont ) { // CharProcs and Resources objects. PdfObject* pCharProcs = pFont->GetIndirectKey( "CharProcs" ); PdfObject* pResources = pFont->GetIndirectKey( "Resources" ); // No CharProcs: exception raised. if( !pCharProcs || !pCharProcs->IsDictionary() ) { PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Entries missing in the Type 3 font dictionary." ); } // Resize space vectors. m_mapCIDToGID.resize( m_lastCID-m_firstCID+1, 0 ); m_glyphs.resize( m_lastCID-m_firstCID+1, PdfeGlyphType3() ); // Look at each character. PdfName cname; PdfObject* pGlyph; for( pdfe_cid c = m_firstCID ; c <= m_lastCID ; ++c ) { // Get character name and search it in CharProcs. cname = this->fromCIDToName( c ); pGlyph = pCharProcs->GetIndirectKey( cname ); // If found, set GID to c-m_firstCID+1 and create glyph. if( pGlyph ) { m_mapCIDToGID[c-m_firstCID] = c-m_firstCID+1; m_glyphs[c-m_firstCID] = PdfeGlyphType3( cname, pGlyph, pResources ); } } }
PdfObject* PdfContents::GetContentsForAppending() const { // if ( mContObj->GetDataType() == ePdfDataType_Stream || // mContObj->GetDataType() == ePdfDataType_Dictionary ) { // Use PdfObject::HasStream() instead of the datatype ePdfDataType_Stream // as large parts of the code rely on all PdfObjects having the datatype // ePdfDataType_Dictionary wether they have a stream or not if( mContObj->GetDataType() == ePdfDataType_Dictionary ) { return mContObj; // just return the stream itself } else if ( mContObj->GetDataType() == ePdfDataType_Array ) { /* Create a new stream, add it to the array, return it */ PdfObject* newStm = mContObj->GetOwner()->CreateObject(); newStm->GetStream(); PdfReference pdfr( newStm->Reference().ObjectNumber(), newStm->Reference().GenerationNumber() ); PdfArray& cArr = mContObj->GetArray(); cArr.push_back( pdfr ); return newStm; } else { PODOFO_RAISE_ERROR( ePdfError_InvalidDataType ); } }
PdfContentsTokenizer::PdfContentsTokenizer( PdfCanvas* pCanvas ) : PdfTokenizer() { PdfObject* pContents = pCanvas->GetContents(); if( pContents && pContents->IsArray() ) { PdfArray& a = pContents->GetArray(); for ( PdfArray::iterator it = a.begin(); it != a.end() ; ++it ) { if ( !(*it).IsReference() ) { PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "/Contents array contained non-references" ); } m_lstContents.push_back( pContents->GetOwner()->GetObject( (*it).GetReference() ) ); } } else if ( pContents && pContents->HasStream() ) { m_lstContents.push_back( pContents ); } else { PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Page /Contents not stream or array of streams" ); } if( m_lstContents.size() ) { SetCurrentContentsStream( m_lstContents.front() ); m_lstContents.pop_front(); } }
PdfObject* PdfVecObjects::CreateObject( const PdfVariant & rVariant ) { PdfReference ref = this->GetNextFreeObject(); PdfObject* pObj = new PdfObject( ref, rVariant ); pObj->SetOwner( this ); this->push_back( pObj ); return pObj; }
int PdfPage::GetRotation() const { int rot = 0; PdfObject* pObj = GetInheritedKeyFromObject( "Rotate", m_pObject ); if ( pObj && pObj->IsNumber() ) rot = static_cast<int>(pObj->GetNumber()); return rot; }
PdfObject* PdfVecObjects::CreateObject( const char* pszType ) { PdfReference ref = this->GetNextFreeObject(); PdfObject* pObj = new PdfObject( ref, pszType ); pObj->SetOwner( this ); this->push_back( pObj ); return pObj; }
PdfAnnotation* PdfPage::CreateAnnotation( EPdfAnnotation eType, const PdfRect & rRect ) { PdfAnnotation* pAnnot = new PdfAnnotation( this, eType, rRect, m_pObject->GetOwner() ); PdfObject* pObj = this->GetAnnotationsArray( true ); PdfReference ref = pAnnot->GetObject()->Reference(); pObj->GetArray().push_back( ref ); m_mapAnnotations[ref] = pAnnot; return pAnnot; }
TVecFilters PdfFilterFactory::CreateFilterList( const PdfObject* pObject ) { TVecFilters filters; const PdfObject* pObj = NULL; if( pObject->IsDictionary() && pObject->GetDictionary().HasKey( "Filter" ) ) pObj = pObject->GetDictionary().GetKey( "Filter" ); else if( pObject->IsArray() ) pObj = pObject; else if( pObject->IsName() ) pObj = pObject; if (!pObj) // Object had no /Filter key . Return a null filter list. return filters; if( pObj->IsName() ) filters.push_back( PdfFilterFactory::FilterNameToType( pObj->GetName() ) ); else if( pObj->IsArray() ) { TCIVariantList it = pObj->GetArray().begin(); while( it != pObj->GetArray().end() ) { if ( (*it).IsName() ) { filters.push_back( PdfFilterFactory::FilterNameToType( (*it).GetName() ) ); } else if ( (*it).IsReference() ) { PdfObject* pFilter = pObject->GetOwner()->GetObject( (*it).GetReference() ); if( pFilter == NULL ) { PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Filter array contained unexpected reference" ); } filters.push_back( PdfFilterFactory::FilterNameToType( pFilter->GetName() ) ); } else { PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Filter array contained unexpected non-name type" ); } ++it; } } return filters; }
PdfObject* PdfPagesTree::GetPageNodeFromArray( int nPageNum, const PdfArray & rKidsArray, PdfObjectList & rLstParents ) { if( static_cast<size_t>(nPageNum) >= rKidsArray.GetSize() ) { PdfError::LogMessage( eLogSeverity_Critical, "Requesting page index %i from array of size %i\n", nPageNum, rKidsArray.size() ); return NULL; } // TODO: Fill cache immediately with all pages // in this kids array PdfVariant rVar = rKidsArray[nPageNum]; while( true ) { if( rVar.IsArray() ) { // Fixes some broken PDFs who have trees with 1 element kids arrays return GetPageNodeFromArray( 0, rVar.GetArray(), rLstParents ); } else if( !rVar.IsReference() ) { PODOFO_RAISE_ERROR_INFO( ePdfError_NotImplemented, "Cannot handle inline pages." ); } PdfObject* pgObject = GetRoot()->GetOwner()->GetObject( rVar.GetReference() ); if(pgObject==NULL) { PODOFO_RAISE_ERROR_INFO( ePdfError_PageNotFound, "Invalid reference." ); } //printf("Reading %s\n", pgObject->Reference().ToString().c_str()); // make sure the object is a /Page and not a /Pages with a single kid if( this->IsTypePage(pgObject) ) { return pgObject; } // it's a /Pages with a single kid, so dereference and try again... if (this->IsTypePages(pgObject) ) { if( !pgObject->GetDictionary().HasKey( "Kids" ) ) return NULL; rLstParents.push_back( pgObject ); rVar = *(pgObject->GetDictionary().GetKey( "Kids" )); } else { // Reference to unexpected object PODOFO_RAISE_ERROR_INFO( ePdfError_PageNotFound, "Reference to unexpected object." ); } } return NULL; }
PdfObject* PdfPage::GetFromResources( const PdfName & rType, const PdfName & rKey ) { if( m_pResources->GetDictionary().HasKey( rType ) ) { PdfObject* pType = m_pResources->GetDictionary().GetKey( rType ); if( pType->IsDictionary() && pType->GetDictionary().HasKey( rKey ) ) { const PdfReference & ref = pType->GetDictionary().GetKey( rKey )->GetReference(); return m_pObject->GetOwner()->GetObject( ref ); } } return NULL; }
const PdfRect PdfPage::GetPageBox( const char* inBox ) const { PdfRect pageBox; PdfObject* pObj; // Take advantage of inherited values - walking up the tree if necessary pObj = GetInheritedKeyFromObject( inBox, m_pObject ); // assign the value of the box from the array if ( pObj && pObj->IsArray() ) pageBox.FromArray( pObj->GetArray() ); return pageBox; }
PDFColorSpace PDFAnalyzer::getCSType(PdfObject* cs) { try { // colorspace is either a name or an array if (cs && cs->IsName()) { PdfName csName = cs->GetName(); if (csName == "DeviceGray") return CS_DeviceGray; else if (csName == "DeviceRGB") return CS_DeviceRGB; else if (csName == "DeviceCMYK") return CS_DeviceCMYK; } else if (cs && cs->IsArray()) { PdfArray csArr = cs->GetArray(); PdfObject csTypePdfName = csArr[0]; if (csTypePdfName.IsName()) { PdfName csTypeName = csTypePdfName.GetName(); if (csTypeName == "ICCBased") return CS_ICCBased; else if (csTypeName == "CalGray") return CS_CalGray; else if (csTypeName == "CalRGB") return CS_CalRGB; else if (csTypeName == "Lab") return CS_Lab; else if (csTypeName == "Indexed") { PdfObject base = cs->GetArray()[1]; PdfObject* pBase = &base; if (base.IsReference()) { pBase = cs->GetOwner()->GetObject(base.GetReference()); } pBase->SetOwner(cs->GetOwner()); return getCSType(pBase); } else if (csTypeName == "Separation") return CS_Separation; else if (csTypeName == "DeviceN") return CS_DeviceN; else if (csTypeName == "Pattern") return CS_Pattern; } } } catch (PdfError & e) { qDebug() << "Error in identifying the color type"; e.PrintErrorMsg(); return CS_Unknown; } return CS_Unknown; }
void PdfFileSpec::Init( const char* pszFilename, const unsigned char* data, ptrdiff_t size, bool bStripPath ) { PdfObject* pEmbeddedStream; PdfString filename( MaybeStripPath( pszFilename, true) ); this->GetObject()->GetDictionary().AddKey( "F", this->CreateFileSpecification( MaybeStripPath( pszFilename, bStripPath) ) ); this->GetObject()->GetDictionary().AddKey( "UF", filename.ToUnicode () ); PdfDictionary ef; pEmbeddedStream = this->CreateObject( "EmbeddedFile" ); this->EmbeddFileFromMem( pEmbeddedStream, data, size ); ef.AddKey( "F", pEmbeddedStream->Reference() ); this->GetObject()->GetDictionary().AddKey( "EF", ef ); }
void PdfPage::DeleteAnnotation( const PdfReference & ref ) { PdfAnnotation* pAnnot; PdfArray::iterator it; PdfObject* pObj = this->GetAnnotationsArray( false ); bool bFound = false; // delete the annotation from the array if( !(pObj && pObj->IsArray()) ) { PODOFO_RAISE_ERROR( ePdfError_InvalidDataType ); } it = pObj->GetArray().begin(); while( it != pObj->GetArray().end() ) { if( (*it).GetReference() == ref ) { pObj->GetArray().erase( it ); bFound = true; break; } ++it; } // if no such annotation was found // throw an error instead of deleting // another object with this reference if( !bFound ) { PODOFO_RAISE_ERROR( ePdfError_NoObject ); } // delete any cached PdfAnnotations pAnnot = m_mapAnnotations[ref]; if( pAnnot ) { delete pAnnot; m_mapAnnotations.erase( ref ); } // delete the PdfObject in the file delete m_pObject->GetOwner()->RemoveObject( ref ); }
void PagesTreeTest::CreateTestTreeCustom( PoDoFo::PdfMemDocument & rDoc ) { const int COUNT = PODOFO_TEST_NUM_PAGES / 10; PdfObject* pRoot = rDoc.GetPagesTree()->GetObject(); PdfArray rootKids; for(int z=0; z<COUNT; z++) { PdfObject* pNode = rDoc.GetObjects().CreateObject("Pages"); PdfArray nodeKids; for(int i=0; i<COUNT; i++) { PdfPage* pPage = new PdfPage( PdfPage::CreateStandardPageSize( ePdfPageSize_A4 ), &(rDoc.GetObjects()) ); pPage->GetObject()->GetDictionary().AddKey( PODOFO_TEST_PAGE_KEY, static_cast<long long>(z * COUNT + i) ); //printf("Creating page %i z=%i i=%i\n", z * COUNT + i, z, i ); nodeKids.push_back( pPage->GetObject()->Reference() ); } pNode->GetDictionary().AddKey( PdfName("Kids"), nodeKids ); pNode->GetDictionary().AddKey( PdfName("Count"), static_cast<long long>(COUNT) ); rootKids.push_back( pNode->Reference() ); } pRoot->GetDictionary().AddKey( PdfName("Kids"), rootKids ); pRoot->GetDictionary().AddKey( PdfName("Count"), static_cast<long long>(PODOFO_TEST_NUM_PAGES) ); }
unsigned int PdfPage::GetPageNumber() const { unsigned int nPageNumber = 0; PdfObject* pParent = m_pObject->GetIndirectKey( "Parent" ); PdfReference ref = m_pObject->Reference(); while( pParent ) { const PdfArray& kids = pParent->GetIndirectKey( "Kids" )->GetArray(); PdfArray::const_iterator it = kids.begin(); while( it != kids.end() && (*it).GetReference() != ref ) { PdfObject* pNode = m_pObject->GetOwner()->GetObject( (*it).GetReference() ); if( pNode->GetDictionary().GetKey( PdfName::KeyType )->GetName() == PdfName( "Pages" ) ) nPageNumber += static_cast<int>(pNode->GetDictionary().GetKey( "Count" )->GetNumber()); else // if we do not have a page tree node, // we most likely have a page object: // so the page count is 1 ++nPageNumber; ++it; } ref = pParent->Reference(); pParent = pParent->GetIndirectKey( "Parent" ); } return ++nPageNumber; }
void EncryptTest::testEnableAlgorithms() { int nDefault = PdfEncrypt::GetEnabledEncryptionAlgorithms(); // By default every algorithms should be enabled CPPUNIT_ASSERT( PdfEncrypt::IsEncryptionEnabled( PdfEncrypt::ePdfEncryptAlgorithm_RC4V1 ) ); CPPUNIT_ASSERT( PdfEncrypt::IsEncryptionEnabled( PdfEncrypt::ePdfEncryptAlgorithm_RC4V2 ) ); CPPUNIT_ASSERT( PdfEncrypt::IsEncryptionEnabled( PdfEncrypt::ePdfEncryptAlgorithm_AESV2 ) ); CPPUNIT_ASSERT_EQUAL( PdfEncrypt::ePdfEncryptAlgorithm_RC4V1 | PdfEncrypt::ePdfEncryptAlgorithm_RC4V2 | PdfEncrypt::ePdfEncryptAlgorithm_AESV2, PdfEncrypt::GetEnabledEncryptionAlgorithms() ); // Disable AES PdfEncrypt::SetEnabledEncryptionAlgorithms( PdfEncrypt::ePdfEncryptAlgorithm_RC4V1 | PdfEncrypt::ePdfEncryptAlgorithm_RC4V2 ); CPPUNIT_ASSERT( PdfEncrypt::IsEncryptionEnabled( PdfEncrypt::ePdfEncryptAlgorithm_RC4V1 ) ); CPPUNIT_ASSERT( PdfEncrypt::IsEncryptionEnabled( PdfEncrypt::ePdfEncryptAlgorithm_RC4V2 ) ); CPPUNIT_ASSERT( !PdfEncrypt::IsEncryptionEnabled( PdfEncrypt::ePdfEncryptAlgorithm_AESV2 ) ); CPPUNIT_ASSERT_EQUAL( PdfEncrypt::ePdfEncryptAlgorithm_RC4V1 | PdfEncrypt::ePdfEncryptAlgorithm_RC4V2, PdfEncrypt::GetEnabledEncryptionAlgorithms() ); PdfObject object; object.GetDictionary().AddKey(PdfName("Filter"), PdfName("Standard")); object.GetDictionary().AddKey(PdfName("V"), static_cast<pdf_int64>(4L)); object.GetDictionary().AddKey(PdfName("R"), static_cast<pdf_int64>(4L)); object.GetDictionary().AddKey(PdfName("P"), static_cast<pdf_int64>(1L)); object.GetDictionary().AddKey(PdfName("O"), PdfString("")); object.GetDictionary().AddKey(PdfName("U"), PdfString("")); try { (void)PdfEncrypt::CreatePdfEncrypt( &object ); CPPUNIT_ASSERT( false ); } catch( PdfError & rError ) { CPPUNIT_ASSERT_EQUAL( rError.GetError(), ePdfError_UnsupportedFilter ); } // Restore default PdfEncrypt::SetEnabledEncryptionAlgorithms( nDefault ); }
void PdfPage::DeleteAnnotation( int index ) { PdfReference ref; PdfObject* pObj = this->GetAnnotationsArray( false ); if( !(pObj && pObj->IsArray()) ) { PODOFO_RAISE_ERROR( ePdfError_InvalidDataType ); } if( index < 0 && static_cast<unsigned int>(index) >= pObj->GetArray().size() ) { PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange ); } ref = pObj->GetArray()[index].GetReference(); this->DeleteAnnotation( ref ); }
void PdfFileSpec::Init( const char* pszFilename, bool bEmbedd, bool bStripPath ) { PdfObject* pEmbeddedStream; PdfString filename( MaybeStripPath( pszFilename, true) ); this->GetObject()->GetDictionary().AddKey( "F", this->CreateFileSpecification( MaybeStripPath( pszFilename, bStripPath ) ) ); this->GetObject()->GetDictionary().AddKey( "UF", filename.ToUnicode () ); if( bEmbedd ) { PdfDictionary ef; pEmbeddedStream = this->CreateObject( "EmbeddedFile" ); this->EmbeddFile( pEmbeddedStream, pszFilename ); ef.AddKey( "F", pEmbeddedStream->Reference() ); this->GetObject()->GetDictionary().AddKey( "EF", ef ); } }
PdfObject* PdfPage::GetAnnotationsArray( bool bCreate ) const { PdfObject* pObj; // check for it in the object itself if ( m_pObject->GetDictionary().HasKey( "Annots" ) ) { pObj = m_pObject->GetIndirectKey( "Annots" ); if( pObj && pObj->IsArray() ) return pObj; } else if( bCreate ) { PdfArray array; const_cast<PdfPage*>(this)->m_pObject->GetDictionary().AddKey( "Annots", array ); return m_pObject->GetDictionary().GetKey( "Annots" ); } return NULL; }
PdfObject* PdfVecObjects::RemoveObject( const PdfReference & ref, bool bMarkAsFree ) { if( !m_bSorted ) this->Sort(); PdfObject* pObj; PdfObject refObj( ref, NULL ); std::pair<TIVecObjects,TIVecObjects> it = std::equal_range( m_vector.begin(), m_vector.end(), &refObj, ObjectComparatorPredicate() ); if( it.first != it.second ) { pObj = *(it.first); if( bMarkAsFree ) this->AddFreeObject( pObj->Reference() ); m_vector.erase( it.first ); return pObj; } return NULL; }
PdfObject* PdfPage::GetInheritedKeyFromObject( const char* inKey, PdfObject* inObject ) const { PdfObject* pObj = NULL; // check for it in the object itself if ( inObject->GetDictionary().HasKey( inKey ) ) { pObj = inObject->GetDictionary().GetKey( inKey ); if ( !pObj->IsNull() ) return pObj; } // if we get here, we need to go check the parent - if there is one! if( inObject->GetDictionary().HasKey( "Parent" ) ) { pObj = inObject->GetIndirectKey( "Parent" ); if( pObj ) pObj = GetInheritedKeyFromObject( inKey, pObj ); } return pObj; }
void PdfImmediateWriter::Finish() { // write all objects which are still in RAM this->FinishLastObject(); // setup encrypt dictionary if( m_pEncrypt ) { // Add our own Encryption dictionary m_pEncryptObj = m_vecObjects->CreateObject(); m_pEncrypt->CreateEncryptionDictionary( m_pEncryptObj->GetDictionary() ); } this->WritePdfObjects( m_pDevice, *m_pParent, m_pXRef ); // write the XRef pdf_long lXRefOffset = m_pDevice->Tell(); m_pXRef->Write( m_pDevice ); // XRef streams contain the trailer in the XRef if( !m_bXRefStream ) { PdfObject trailer; // if we have a dummy offset we write also a prev entry to the trailer FillTrailerObject( &trailer, m_pXRef->GetSize(), false, false ); m_pDevice->Print("trailer\n"); trailer.WriteObject( m_pDevice, this->GetWriteMode(), NULL ); } m_pDevice->Print( "startxref\n%li\n%%%%EOF\n", lXRefOffset ); m_pDevice->Flush(); // we are done now m_pParent->Detach( this ); m_pParent = NULL; }
void PdfFontTrueType::EmbedFontFile( PdfObject* pDescriptor ) { PdfObject* pContents; pdf_long lSize = 0; m_bWasEmbedded = true; pContents = this->GetObject()->GetOwner()->CreateObject(); if( !pContents ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pDescriptor->GetDictionary().AddKey( "FontFile2", pContents->Reference() ); // if the data was loaded from memory - use it from there // otherwise, load from disk if ( m_pMetrics->GetFontDataLen() && m_pMetrics->GetFontData() ) { // FIXME const_cast<char*> is dangerous if string literals may ever be passed char* pBuffer = const_cast<char*>( m_pMetrics->GetFontData() ); lSize = m_pMetrics->GetFontDataLen(); // Set Length1 before creating the stream // as PdfStreamedDocument does not allow // adding keys to an object after a stream was written pContents->GetDictionary().AddKey( "Length1", PdfVariant( static_cast<pdf_int64>(lSize) ) ); pContents->GetStream()->Set( pBuffer, lSize ); } else { PdfFileInputStream stream( m_pMetrics->GetFilename() ); lSize = stream.GetFileLength(); // Set Length1 before creating the stream // as PdfStreamedDocument does not allow // adding keys to an object after a stream was written pContents->GetDictionary().AddKey( "Length1", PdfVariant( static_cast<pdf_int64>(lSize) ) ); pContents->GetStream()->Set( &stream ); } }
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 PdfDestination::Init( PdfObject* pObject, PdfDocument* pDocument ) { bool bValueExpected = false; PdfObject* pValue = NULL; if ( pObject->GetDataType() == ePdfDataType_Array ) { m_array = pObject->GetArray(); m_pObject = pObject; } else if( pObject->GetDataType() == ePdfDataType_String ) { PdfNamesTree* pNames = pDocument->GetNamesTree( ePdfDontCreateObject ); if( !pNames ) { PODOFO_RAISE_ERROR( ePdfError_NoObject ); } pValue = pNames->GetValue( "Dests", pObject->GetString() ); bValueExpected = true; } else if( pObject->GetDataType() == ePdfDataType_Name ) { PdfMemDocument* pMemDoc = dynamic_cast<PdfMemDocument*>(pDocument); if ( !pMemDoc ) { PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidHandle, "For reading from a document, only use PdfMemDocument." ); } PdfObject* pCatalog = pMemDoc->GetCatalog(); if ( !pCatalog ) { PODOFO_RAISE_ERROR( ePdfError_NoObject ); } PdfObject* pDests = pCatalog->GetIndirectKey( PdfName( "Dests" ) ); if( !pDests ) { // The error code has been chosen for its distinguishability. PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidKey, "No PDF-1.1-compatible destination dictionary found." ); } pValue = pDests->GetIndirectKey( pObject->GetName() ); bValueExpected = true; } else { PdfError::LogMessage( eLogSeverity_Error, "Unsupported object given to" " PdfDestination::Init of type %s", pObject->GetDataTypeString() ); m_array = PdfArray(); // needed to prevent crash on method calls // needed for GetObject() use w/o checking its return value for NULL m_pObject = pDocument->GetObjects()->CreateObject( m_array ); } if ( bValueExpected ) { if( !pValue ) { PODOFO_RAISE_ERROR( ePdfError_InvalidName ); } if( pValue->IsArray() ) m_array = pValue->GetArray(); else if( pValue->IsDictionary() ) m_array = pValue->GetDictionary().GetKey( "D" )->GetArray(); m_pObject = pValue; } }
void PDFProcessor::start () { int nNum = 0; try { PdfObject* pObj = NULL; // open document qDebug() << "Opening file: " << filename.toStdString().c_str(); PdfMemDocument document( filename.toStdString().c_str() ); // m_pszOutputDirectory = const_cast<char*>(pszOutput); TCIVecObjects it = document.GetObjects().begin(); while( it != document.GetObjects().end() ) { if( (*it)->IsDictionary() ) { PdfObject* pObjType = (*it)->GetDictionary().GetKey( PdfName::KeyType ); PdfObject* pObjSubType = (*it)->GetDictionary().GetKey( PdfName::KeySubtype ); if( ( pObjType && pObjType->IsName() && ( pObjType->GetName().GetName() == "XObject" ) ) || ( pObjSubType && pObjSubType->IsName() && ( pObjSubType->GetName().GetName() == "Image" ) ) ) { pObj = (*it)->GetDictionary().GetKey( PdfName::KeyFilter ); if( pObj && pObj->IsArray() && pObj->GetArray().GetSize() == 1 && pObj->GetArray()[0].IsName() && (pObj->GetArray()[0].GetName().GetName() == "DCTDecode") ) pObj = &pObj->GetArray()[0]; std::string filterName = pObj->GetName().GetName(); bool processed = 0; if( pObj && pObj->IsName() && ( filterName == "DCTDecode" ) ) { // The only filter is JPEG -> create a JPEG file qDebug() << "JPG found.\n"; processed = true; nNum++; } if( pObj && pObj->IsName() && ( filterName == "JPXDecode" ) ) { // The only filter is JPEG -> create a JPEG file qDebug() << "JPG found.\n"; processed = true; nNum++; } if( pObj && pObj->IsName() && ( filterName == "FlateDecode" ) ) { // The only filter is JPEG -> create a JPEG file qDebug() << "JPG found.\n"; processed = true; nNum++; } // else we found something strange, we do not care about it for now. if (processed == false) { qDebug() << "Unknown image type found:" << QString::fromStdString(filterName) << "\n"; nNum++; } document.FreeObjectMemory( *it ); } } ++it; } } catch( PdfError & e ) { qDebug() << "Error: An error ocurred during processing the pdf file:" << e.GetError(); e.PrintErrorMsg(); return;// e.GetError(); } // TODO: statistics of no of images etc // nNum = extractor.GetNumImagesExtracted(); qDebug() << "Extracted " << nNum << " images successfully from the PDF file.\n"; }
int PdfPage::GetNumAnnots() const { PdfObject* pObj = this->GetAnnotationsArray(); return pObj ? static_cast<int>(pObj->GetArray().size()) : 0; }
PdfFontMetricsObject::PdfFontMetricsObject( PdfObject* pFont, PdfObject* pDescriptor, const PdfEncoding* const pEncoding ) : PdfFontMetrics( ePdfFontType_Unknown, "", NULL ), m_pEncoding( pEncoding ), m_dDefWidth(0.0) { if( !pDescriptor ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } const PdfName & rSubType = pFont->GetDictionary().GetKey( PdfName::KeySubtype )->GetName(); // OC 15.08.2010 BugFix: /FirstChar /LastChar /Widths are in the Font dictionary and not in the FontDescriptor if ( rSubType == PdfName("Type1") || rSubType == PdfName("TrueType") ) { m_sName = pDescriptor->GetIndirectKey( "FontName" )->GetName(); m_bbox = pDescriptor->GetIndirectKey( "FontBBox" )->GetArray(); m_nFirst = static_cast<int>(pFont->GetDictionary().GetKeyAsLong( "FirstChar", 0L )); m_nLast = static_cast<int>(pFont->GetDictionary().GetKeyAsLong( "LastChar", 0L )); // OC 15.08.2010 BugFix: GetIndirectKey() instead of GetDictionary().GetKey() and "Widths" instead of "Width" PdfObject* widths = pFont->GetIndirectKey( "Widths" ); if( widths != NULL ) { m_width = widths->GetArray(); m_missingWidth = NULL; } else { widths = pDescriptor->GetDictionary().GetKey( "MissingWidth" ); if( widths == NULL ) { PODOFO_RAISE_ERROR_INFO( ePdfError_NoObject, "Font object defines neither Widths, nor MissingWidth values!" ); m_missingWidth = widths; } } } else if ( rSubType == PdfName("CIDFontType0") || rSubType == PdfName("CIDFontType2") ) { PdfObject *pObj = pDescriptor->GetIndirectKey( "FontName" ); if (pObj) { m_sName = pObj->GetName(); } pObj = pDescriptor->GetIndirectKey( "FontBBox" ); if (pObj) { m_bbox = pObj->GetArray(); } m_nFirst = 0; m_nLast = 0; m_dDefWidth = static_cast<double>(pFont->GetDictionary().GetKeyAsLong( "DW", 1000L )); PdfVariant default_width(m_dDefWidth); PdfObject * pw = pFont->GetIndirectKey( "W" ); for (int i = m_nFirst; i <= m_nLast; ++i) { m_width.push_back(default_width); } if (pw) { PdfArray w = pw->GetArray(); int pos = 0; while (pos < static_cast<int>(w.GetSize())) { int start = static_cast<int>(w[pos++].GetNumber()); PODOFO_ASSERT (start >= 0); if (w[pos].IsArray()) { PdfArray widths = w[pos++].GetArray(); int length = start + static_cast<int>(widths.GetSize()); PODOFO_ASSERT (length >= start); if (length > static_cast<int>(m_width.GetSize())) { m_width.resize(length, default_width); } for (int i = 0; i < static_cast<int>(widths.GetSize()); ++i) { m_width[start + i] = widths[i]; } } else { int end = static_cast<int>(w[pos++].GetNumber()); int length = start + end; PODOFO_ASSERT (length >= start); if (length > static_cast<int>(m_width.GetSize())) { m_width.resize(length, default_width); } pdf_int64 width = w[pos++].GetNumber(); for (int i = start; i <= end; ++i) m_width[i] = PdfVariant(width); } } } m_nLast = m_width.GetSize() - 1; } else { PODOFO_RAISE_ERROR_INFO( ePdfError_UnsupportedFontFormat, rSubType.GetEscapedName().c_str() ); } m_nWeight = static_cast<unsigned int>(pDescriptor->GetDictionary().GetKeyAsLong( "FontWeight", 400L )); m_nItalicAngle = static_cast<int>(pDescriptor->GetDictionary().GetKeyAsLong( "ItalicAngle", 0L )); m_dPdfAscent = pDescriptor->GetDictionary().GetKeyAsReal( "Ascent", 0.0 ); m_dAscent = m_dPdfAscent / 1000.0; m_dPdfDescent = pDescriptor->GetDictionary().GetKeyAsReal( "Descent", 0.0 ); m_dDescent = m_dPdfDescent / 1000.0; m_dLineSpacing = m_dAscent + m_dDescent; // Try to fine some sensible values m_dUnderlineThickness = 1.0; m_dUnderlinePosition = 0.0; m_dStrikeOutThickness = m_dUnderlinePosition; m_dStrikeOutPosition = m_dAscent / 2.0; m_bSymbol = false; // TODO }