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(); } }
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 ); }
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; }
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 ); }
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; }
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; } }
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 }
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; } } }
//**********************************************************// // 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(); } }
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(); } }