Example #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;
}
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();
    }
}
Example #3
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 );
}
Example #4
0
PDFFont PDFAnalyzer::getFontInfo(PdfObject* fontObj)
{
	PDFFont currFont;
	PdfObject* subtype = fontObj->GetIndirectKey("Subtype");
	if (subtype && subtype->IsName())
	{
		PdfObject* fontDesc = fontObj->GetIndirectKey("FontDescriptor");
		if (subtype->GetName() == "Type1")
			currFont.fontType = F_Type1;
		else if (subtype->GetName() == "MMType1")
			currFont.fontType = F_MMType1;
		else if (subtype->GetName() == "TrueType")
			currFont.fontType = F_TrueType;
		else if (subtype->GetName() == "Type3")
		{
			currFont.fontType = F_Type3;
			currFont.isEmbedded = true;
			fontDesc = NULL;
		}
		else if (subtype->GetName() == "Type0")
		{
			PdfObject* descendantFonts = fontObj->GetIndirectKey("DescendantFonts");
			if (descendantFonts && descendantFonts->IsArray())
			{
				PdfObject descendantFont = descendantFonts->GetArray()[0];
				descendantFont.SetOwner(descendantFonts->GetOwner());
				PdfObject* subtypeDescFont = descendantFont.GetIndirectKey("Subtype");
				fontDesc = descendantFont.MustGetIndirectKey("FontDescriptor");
				if (subtypeDescFont && subtypeDescFont->IsName())
				{
					if (subtypeDescFont->GetName() == "CIDFontType0")
						currFont.fontType = F_CIDFontType0;
					else if (subtypeDescFont->GetName() == "CIDFontType2")
						currFont.fontType = F_CIDFontType2;
				}
			}
		}
		if (fontDesc)
		{
			PdfObject* fontFile = fontDesc->GetIndirectKey("FontFile");
			PdfObject* fontFile2 = fontDesc->GetIndirectKey("FontFile2");
			PdfObject* fontFile3 = fontDesc->GetIndirectKey("FontFile3");
			if (fontFile && fontFile->HasStream())
				currFont.isEmbedded = true;
			if (fontFile2 && fontFile2->HasStream())
				currFont.isEmbedded = true;
			if (fontFile3 && fontFile3->HasStream())
			{
				currFont.isEmbedded = true;
				PdfObject* ff3Subtype = fontFile3->GetIndirectKey("Subtype");
				if (ff3Subtype && ff3Subtype->IsName() && ff3Subtype->GetName() == "OpenType")
					currFont.isOpenType = true;
			}
		}
	}
	return currFont;
}
Example #5
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 );
}
Example #6
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;
}
Example #7
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;
}
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;
    }
}
Example #9
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";
    }
Example #10
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
}
Example #12
0
void PdfSigIncWriter::Write( PdfOutputDevice* pDevice, pdf_int64 prevOffset)
{
    //CreateFileIdentifier( m_identifier, m_pTrailer );
    if( m_pTrailer->GetDictionary().HasKey( "ID" ) ) {
       PdfObject *idObj =  m_pTrailer->GetDictionary().GetKey("ID");
       
       TCIVariantList it = idObj->GetArray().begin();
		 while( it != idObj->GetArray().end() ) {
			if( (*it).GetDataType() == ePdfDataType_HexString ) {
				 PdfVariant var = (*it);
             m_identifier = var.GetString();
			}
				
			++it;
		}
    } else {
       PdfDate   date;
       PdfString dateString;
       PdfObject*      pInfo;
       PdfOutputDevice length;

       date.ToString( dateString );

       pInfo = new PdfObject();
       pInfo->GetDictionary().AddKey( "CreationDate", dateString );
       pInfo->GetDictionary().AddKey( "Creator", PdfString("PoDoFo") );
       pInfo->GetDictionary().AddKey( "Producer", PdfString("PoDoFo") );
       
      pInfo->GetDictionary().AddKey( "Location", PdfString("SOMEFILENAME") );

      pInfo->WriteObject( &length, ePdfWriteMode_Clean, NULL );

      char *pBuffer = static_cast<char*>(podofo_calloc( length.GetLength(), sizeof(char) ));
      if( !pBuffer )  {
        delete pInfo;
        PODOFO_RAISE_ERROR( ePdfError_OutOfMemory );
      } 

      PdfOutputDevice device( pBuffer, length.GetLength() );
      pInfo->WriteObject( &device, ePdfWriteMode_Clean, NULL );

      // calculate the MD5 Sum
      m_identifier = PdfEncryptMD5Base::GetMD5String( reinterpret_cast<unsigned char*>(pBuffer),
                                           static_cast<unsigned int>(length.GetLength()) );
      podofo_free( pBuffer );

      delete pInfo;
    }

    if( !pDevice )
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    // setup encrypt dictionary
    if( m_pEncrypt )
    {
        m_pEncrypt->GenerateEncryptionKey( m_identifier );

        // Add our own Encryption dictionary
        m_pEncryptObj = m_vecObjects->CreateObject();
        m_pEncrypt->CreateEncryptionDictionary( m_pEncryptObj->GetDictionary() );
    }

    if( GetLinearized() ) 
    {
        this->WriteLinearized( pDevice );
    }
    else
    {
        PdfXRef* pXRef = m_bXRefStream ? new PdfXRefStream( m_vecObjects, this ) : new PdfXRef();

        try {
//            WritePdfHeader  ( pDevice );
            WritePdfObjects ( pDevice, *m_vecObjects, pXRef );
            pXRef->SetFirstEmptyBlock();

            pXRef->Write( 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, pXRef->GetSize(), false, false );

                PdfObject prevOffsetObj(prevOffset);
                trailer.GetDictionary().AddKey( "Prev", prevOffsetObj);
                pDevice->Print("trailer\n");
                trailer.WriteObject( pDevice, ePdfWriteMode_Clean, NULL ); // Do not encrypt the trailer dicionary!!!
            }
            
            pDevice->Print( "startxref\n%li\n%%%%EOF\n", pXRef->GetOffset());
            delete pXRef;
        } catch( PdfError & e ) {
            // Make sure pXRef is always deleted
            delete pXRef;
            e.AddToCallstack( __FILE__, __LINE__ );
            throw e;
        }
    }
}
Example #13
0
//**********************************************************//
//                       PdfeFontType3                      //
//**********************************************************//
PdfeFontType3::PdfeFontType3( PoDoFo::PdfObject* pFont, FT_Library ftLibrary ) :
    PdfeFont( pFont, ftLibrary )
{
    this->init();

    // Subtype of the font.
    const PdfName& subtype = pFont->GetIndirectKey( PdfName::KeySubtype )->GetName();
    if( subtype == PdfName( "Type3" ) ) {
        this->setType( PdfeFontType::Type3 );
        this->setSubtype( PdfeFontSubType::Type3 );
    }
    else {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "The PdfObject is not a Type 3 font." );
    }

    // Need the following entries in the font dictionary.
    PdfObject* pBBox = pFont->GetIndirectKey( "FontBBox" );
    PdfObject* pMatrix = pFont->GetIndirectKey( "FontMatrix" );
    PdfObject* pFChar = pFont->GetIndirectKey( "FirstChar" );
    PdfObject* pLChar = pFont->GetIndirectKey( "LastChar" );
    PdfObject* pWidths = pFont->GetIndirectKey( "Widths" );
    PdfObject* pEncoding = pFont->GetIndirectKey( "Encoding" );

    // If does not exist: raise exception.
    if( !( pBBox && pMatrix && pFChar && pLChar && pWidths && pEncoding ) ) {
        PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "Entries missing in the Type 3 font dictionary." );
    }

    // Initialize font BBox from array.
    m_fontBBox = PdfRect( pBBox->GetArray() );

    // Font matrix.
    const PdfArray& matrixA = pMatrix->GetArray();
    m_fontMatrix(0,0) = matrixA[0].GetReal();
    m_fontMatrix(0,1) = matrixA[1].GetReal();
    m_fontMatrix(1,0) = matrixA[2].GetReal();
    m_fontMatrix(1,1) = matrixA[3].GetReal();
    m_fontMatrix(2,0) = matrixA[4].GetReal();
    m_fontMatrix(2,1) = matrixA[5].GetReal();

    // Read char widths.
    m_firstCID = static_cast<pdfe_cid>( pFChar->GetNumber() );
    m_lastCID = static_cast<pdfe_cid>( pLChar->GetNumber() );

    const PdfArray&  widthsA = pWidths->GetArray();
    m_advanceCID.resize( widthsA.size(), PdfeVector() );
    for( size_t i = 0 ; i < widthsA.size() ; ++i ) {
        m_advanceCID[i](0) = widthsA[i].GetReal();
    }
    // Check the size for coherence.
    if( m_advanceCID.size() != static_cast<size_t>( m_lastCID - m_firstCID + 1 ) ) {
        m_advanceCID.resize( m_lastCID - m_firstCID + 1, PdfeVector( 1000., 0. ) );
    }

    // Font descriptor (required in Tagged documents).
    PdfObject* pDescriptor = pFont->GetIndirectKey( "FontDescriptor" );
    if( pDescriptor ) {
        m_fontDescriptor.init( pDescriptor );
    }

    // Font encoding.
    this->initEncoding( pEncoding );
    // Unicode CMap.
    PdfObject* pUnicodeCMap = pFont->GetIndirectKey( "ToUnicode" );
    this->initUnicodeCMap( pUnicodeCMap );

    // Space characters vector.
    this->initSpaceCharacters( m_firstCID, m_lastCID, true );
    // Glyph vectors.
    this->initGlyphs( pFont );
    // Default space bounding box.
    this->initSpaceBBox();

    // Log font information.
    this->initLogInformation();
}
void PdfMemStream::FlateCompress()
{
    PdfObject*        pObj;
    PdfVariant        vFilter( PdfName("FlateDecode" ) );
    PdfVariant        vFilterList;
    PdfArray          tFilters;

    PdfArray::const_iterator tciFilters;
    
    if( !m_lLength )
        return; // ePdfError_ErrOk

    // TODO: Handle DecodeParms
    if( m_pParent->GetDictionary().HasKey( "Filter" ) )
    {
        pObj = m_pParent->GetIndirectKey( "Filter" );

        if( pObj->IsName() )
        {
            if( pObj->GetName() != "DCTDecode" && pObj->GetName() != "FlateDecode" )
            {
                tFilters.push_back( vFilter );
                tFilters.push_back( *pObj );
            }
        }
        else if( pObj->IsArray() )
        {
            tciFilters = pObj->GetArray().begin();

            while( tciFilters != pObj->GetArray().end() )
            {
                if( (*tciFilters).IsName() )
                {
                    // do not compress DCTDecoded are already FlateDecoded streams again
                    if( (*tciFilters).GetName() == "DCTDecode" || (*tciFilters).GetName() == "FlateDecode" )
                    {
                        return;
                    }
                }

                ++tciFilters;
            }

            tFilters.push_back( vFilter );

            tciFilters = pObj->GetArray().begin();

            while( tciFilters != pObj->GetArray().end() )
            {
                tFilters.push_back( (*tciFilters) );
                
                ++tciFilters;
            }
        }
        else
            return;

        vFilterList = PdfVariant( tFilters );
        m_pParent->GetDictionary().AddKey( "Filter", vFilterList );

        FlateCompressStreamData(); // throws an exception on error
    }
    else
    {
        m_pParent->GetDictionary().AddKey( "Filter", PdfName( "FlateDecode" ) );
        FlateCompressStreamData();
    }
}
Example #15
0
void PDFAnalyzer::inspectExtGStateObj(PdfObject* extGStateObj, QList<PDFColorSpace> & usedColorSpaces, bool & hasTransparency, QList<PDFFont> & usedFonts, PDFGraphicState & currGS)
{
	PdfObject* bmObj = extGStateObj->GetIndirectKey("BM");
	if (bmObj && bmObj->IsName())
	{
		currGS.blendModes.clear();
		currGS.blendModes.append(bmObj->GetName().GetEscapedName().c_str());
		if (!(bmObj->GetName() == "Normal" || bmObj->GetName() == "Compatible"))
			hasTransparency = true;
	}
	else if (bmObj && bmObj->IsArray())
	{
		PdfArray arr = bmObj->GetArray();
		currGS.blendModes.clear();
		for(int i=0; i<arr.GetSize(); ++i)
			currGS.blendModes.append(arr[i].GetName().GetEscapedName().c_str());
		if (arr[0].IsName() && !(arr[0].GetName() == "Normal" || arr[0].GetName() == "Compatible"))
			hasTransparency = true;
	}
	PdfObject* caObj = extGStateObj->GetIndirectKey("ca");
	if (caObj && (caObj->IsReal() || caObj->IsNumber()))
	{
		currGS.fillAlphaConstant = caObj->GetReal();
		if (caObj->GetReal() < 1)
			hasTransparency = true;
	}
	PdfObject* cAObj = extGStateObj->GetIndirectKey("CA");
	if (cAObj && (cAObj->IsReal() || cAObj->IsNumber()))
	{
		if (cAObj->GetReal() < 1)
		hasTransparency = true;
	}
	PdfObject* sMaskObj = extGStateObj->GetIndirectKey("SMask");
	if (sMaskObj && !(sMaskObj->IsName() && sMaskObj->GetName() == "None"))
		hasTransparency = true;
	PdfObject* fontObj = extGStateObj->GetIndirectKey("Font");
	if (fontObj && fontObj->IsArray())
	{
		PdfArray arr = fontObj->GetArray();
		if (arr[0].IsReference())
		{
			PdfReference ref = arr[0].GetReference();
			PdfObject* fontObject = m_doc->GetObjects().GetObject(ref);
			if (fontObject)
			{
				PDFFont font = getFontInfo(fontObject);
				usedFonts.append(font);
				currGS.font.first = font;
				currGS.font.second = arr[1].GetReal();
			}

		}
	}
	PdfObject* lwObj = extGStateObj->GetIndirectKey("LW");
	if (lwObj)
		currGS.lineWidth = lwObj->GetReal();
	PdfObject* lcObj = extGStateObj->GetIndirectKey("LC");
	if (lcObj)
		currGS.lineCap = lcObj->GetNumber();
	PdfObject* ljObj = extGStateObj->GetIndirectKey("LJ");
	if (ljObj)
		currGS.lineJoin = ljObj->GetNumber();
	PdfObject* mlObj = extGStateObj->GetIndirectKey("ML");
	if (mlObj)
		currGS.miterLimit = mlObj->GetReal();
	PdfObject* dObj = extGStateObj->GetIndirectKey("D");
	if (dObj)
	{
		PdfArray dashArr = dObj->GetArray()[0];
		currGS.dashPattern.first.clear();
		for (int i=0; i<dashArr.GetSize(); ++i)
			currGS.dashPattern.first.append(dashArr[i].GetNumber());
		currGS.dashPattern.second = dObj->GetArray()[1].GetNumber();
	}
}
PdfContentsTokenizer::PdfContentsTokenizer( PdfCanvas* pCanvas )
    : PdfTokenizer(), m_readingInlineImgData(false)
{
    if( !pCanvas ) 
    {
        PODOFO_RAISE_ERROR( ePdfError_InvalidHandle );
    }

    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" );

            }

            if ( !pContents->GetOwner()->GetObject( (*it).GetReference() ) )
            {
                // some damaged PDFs may have dangling references
                PODOFO_RAISE_ERROR_INFO( ePdfError_InvalidDataType, "/Contents array NULL reference" );
            }

            m_lstContents.push_back( pContents->GetOwner()->GetObject( (*it).GetReference() ) );
        }
    }
    else if ( pContents && pContents->HasStream() )
    {
        m_lstContents.push_back( pContents );
    }
    else if ( pContents && pContents->IsDictionary() )
    {
        m_lstContents.push_back( pContents );
        PdfError::LogMessage(eLogSeverity_Information,
                  "PdfContentsTokenizer: found canvas-dictionary without stream => empty page");
        // OC 18.09.2010 BugFix: Found an empty page in a PDF document:
        //    103 0 obj
        //    <<
        //    /Type /Page
        //    /MediaBox [ 0 0 595 842 ]
        //    /Parent 3 0 R
        //    /Resources <<
        //    /ProcSet [ /PDF ]
        //    >>
        //    /Rotate 0
        //    >>
        //    endobj
    }
    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();
    }
}