Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #6
0
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;
}
Exemple #8
0
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;
}
Exemple #10
0
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
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 );
}
Exemple #15
0
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 );
}
Exemple #16
0
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) );
}
Exemple #17
0
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 );
}
Exemple #19
0
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 );
    }
}
Exemple #21
0
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;
}
Exemple #23
0
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;
    }
}
Exemple #28
0
    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";
    }
Exemple #29
0
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
}