void PdfOutputDevice::Seek( size_t offset ) { if( m_hFile ) { if( fseeko( m_hFile, offset, SEEK_SET ) == -1 ) { PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange ); } } else if( m_pBuffer ) { if( offset >= m_lBufferLen ) { PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange ); } } else if( m_pStream ) { m_pStream->seekp( offset, std::ios_base::beg ); } else if( m_pRefCountedBuffer ) { m_ulPosition = offset; } m_ulPosition = offset; // Seek should not change the length of the device // m_ulLength = offset; }
pdf_long PdfMemoryOutputStream::Write( const char* pBuffer, pdf_long lLen ) { if( !m_pBuffer ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } if( m_lLen + lLen > m_lSize ) { if( m_bOwnBuffer ) { // a reallocation is required m_lSize = PDF_MAX( (m_lLen + lLen), (m_lSize << 1 ) ); m_pBuffer = static_cast<char*>(podofo_realloc( m_pBuffer, m_lSize )); if( !m_pBuffer ) { PODOFO_RAISE_ERROR( ePdfError_OutOfMemory ); } } else { PODOFO_RAISE_ERROR( ePdfError_OutOfMemory ); } } memcpy( m_pBuffer + m_lLen, pBuffer, lLen ); m_lLen += lLen; return lLen; }
PdfOutputDevice::PdfOutputDevice( const char* pszFilename ) { this->Init(); if( !pszFilename ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } std::fstream *pStream = new std::fstream(pszFilename, std::fstream::binary|std::ios_base::in | std::ios_base::out | std::ios_base::trunc); if(pStream->fail()) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } m_pStream = pStream; m_pReadStream = pStream; PdfLocaleImbue(*m_pStream); /* m_hFile = fopen( pszFilename, "wb" ); if( !m_hFile ) { PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, pszFilename ); } */ }
void PdfTilingPattern::AddToResources(const PdfName &rIdentifier, const PdfReference &rRef, const PdfName &rName) { PdfObject* pResource = GetObject()->GetDictionary().GetKey( "Resources" ); if( !pResource ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } if( !pResource->GetDictionary().HasKey( rName ) ) { pResource->GetDictionary().AddKey( rName, PdfDictionary() ); } if (ePdfDataType_Reference == pResource->GetDictionary().GetKey( rName )->GetDataType()) { PdfObject *directObject = pResource->GetOwner()->GetObject(pResource->GetDictionary().GetKey( rName )->GetReference()); if (0 == directObject) { PODOFO_RAISE_ERROR( ePdfError_NoObject ); } if( !directObject->GetDictionary().HasKey( rIdentifier ) ) directObject->GetDictionary().AddKey( rIdentifier, rRef ); }else { if( !pResource->GetDictionary().GetKey( rName )->GetDictionary().HasKey( rIdentifier ) ) pResource->GetDictionary().GetKey( rName )->GetDictionary().AddKey( rIdentifier, rRef ); } }
void PdfSignOutputDevice::SetSignature(const PdfData &sigData) { if(!m_bBeaconFound) { PODOFO_RAISE_ERROR( ePdfError_InternalLogic ); } size_t maxSigSize = m_pSignatureBeacon->data().size(); size_t sigByteSize = sigData.data().size(); // check signature size if((sigByteSize*2)> maxSigSize) { PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange ); } PdfString sig(sigData.data().c_str(), sigByteSize, true); m_pRealDevice->Seek(m_sBeaconPos); sig.Write(m_pRealDevice, PoDoFo::ePdfWriteMode_Compact); // insert padding size_t numPadding = maxSigSize-2*sigByteSize; if(numPadding>0) { // Seek back m_pRealDevice->Seek(m_pRealDevice->Tell()-1); while(numPadding>0) { char c='0'; m_pRealDevice->Write(&c, 1); numPadding--; } } }
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 PdfPagesTree::DeletePage( int nPageNumber ) { // Delete from cache m_cache.DeletePage( nPageNumber ); // Delete from pages tree PdfObjectList lstParents; PdfObject* pPageNode = this->GetPageNode( nPageNumber, this->GetRoot(), lstParents ); if( !pPageNode ) { PdfError::LogMessage( eLogSeverity_Information, "Invalid argument to PdfPagesTree::DeletePage: %i - Page not found\n", nPageNumber ); PODOFO_RAISE_ERROR( ePdfError_PageNotFound ); } if( lstParents.size() > 0 ) { PdfObject* pParent = lstParents.back(); int nKidsIndex = this->GetPosInKids( pPageNode, pParent ); DeletePageFromNode( pParent, lstParents, nKidsIndex, pPageNode ); } else { PdfError::LogMessage( eLogSeverity_Error, "PdfPagesTree::DeletePage: Page %i has no parent - cannot be deleted.\n", nPageNumber ); PODOFO_RAISE_ERROR( ePdfError_PageNotFound ); } }
void PdfOutputDevice::PrintV( const char* pszFormat, long lBytes, va_list args ) { if( !pszFormat ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } if( m_pBuffer ) { if( m_ulPosition + lBytes <= m_lBufferLen ) { vsnprintf( m_pBuffer + m_ulPosition, m_lBufferLen - m_ulPosition, pszFormat, args ); } else { PODOFO_RAISE_ERROR( ePdfError_OutOfMemory ); } } else if( m_pStream || m_pRefCountedBuffer ) { ++lBytes; m_printBuffer.Resize( lBytes ); char* data = m_printBuffer.GetBuffer(); if( !data ) { PODOFO_RAISE_ERROR( ePdfError_OutOfMemory ); } vsnprintf( data, lBytes, pszFormat, args ); if( lBytes ) --lBytes; if( m_pStream ) { std::string str; str.assign( data, lBytes ); *m_pStream << str; } else // if( m_pRefCountedBuffer ) { if( m_ulPosition + lBytes > static_cast<unsigned long>(m_pRefCountedBuffer->GetSize()) ) { m_pRefCountedBuffer->Resize( m_ulPosition + lBytes ); } memcpy( m_pRefCountedBuffer->GetBuffer() + m_ulPosition, data, lBytes ); } } m_ulPosition += static_cast<size_t>(lBytes); if(m_ulPosition>m_ulLength) { m_ulLength = m_ulPosition; } }
void PdfFontSimple::Init( bool bEmbed, const PdfName & rsSubType ) { PdfObject* pWidth; PdfObject* pDescriptor; PdfVariant var; PdfArray array; pWidth = this->GetObject()->GetOwner()->CreateObject(); if( !pWidth ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } m_pMetrics->GetWidthArray( *pWidth, m_pEncoding->GetFirstChar(), m_pEncoding->GetLastChar(), m_pEncoding ); pDescriptor = this->GetObject()->GetOwner()->CreateObject( "FontDescriptor" ); if( !pDescriptor ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } std::string name; if ( m_bIsSubsetting ) name = this->GetObject()->GetOwner()->GetNextSubsetPrefix(); name += this->GetBaseFont().GetName(); this->GetObject()->GetDictionary().AddKey( PdfName::KeySubtype, rsSubType ); this->GetObject()->GetDictionary().AddKey("BaseFont", PdfName( name ) ); this->GetObject()->GetDictionary().AddKey("FirstChar", PdfVariant( static_cast<pdf_int64>(m_pEncoding->GetFirstChar()) ) ); this->GetObject()->GetDictionary().AddKey("LastChar", PdfVariant( static_cast<pdf_int64>(m_pEncoding->GetLastChar()) ) ); m_pEncoding->AddToDictionary( this->GetObject()->GetDictionary() ); // Add encoding key this->GetObject()->GetDictionary().AddKey("Widths", pWidth->Reference() ); this->GetObject()->GetDictionary().AddKey( "FontDescriptor", pDescriptor->Reference() ); m_pMetrics->GetBoundingBox( array ); pDescriptor->GetDictionary().AddKey( "FontName", PdfName( name ) ); //pDescriptor->GetDictionary().AddKey( "FontWeight", (long)m_pMetrics->Weight() ); pDescriptor->GetDictionary().AddKey( PdfName::KeyFlags, PdfVariant( static_cast<pdf_int64>(PODOFO_LL_LITERAL(32)) ) ); // TODO: 0 ???? pDescriptor->GetDictionary().AddKey( "FontBBox", array ); pDescriptor->GetDictionary().AddKey( "ItalicAngle", PdfVariant( static_cast<pdf_int64>(m_pMetrics->GetItalicAngle()) ) ); pDescriptor->GetDictionary().AddKey( "Ascent", m_pMetrics->GetPdfAscent() ); pDescriptor->GetDictionary().AddKey( "Descent", m_pMetrics->GetPdfDescent() ); pDescriptor->GetDictionary().AddKey( "CapHeight", m_pMetrics->GetPdfAscent() ); // m_pMetrics->CapHeight() ); pDescriptor->GetDictionary().AddKey( "StemV", PdfVariant( static_cast<pdf_int64>(PODOFO_LL_LITERAL(1)) ) ); // m_pMetrics->StemV() ); // Peter Petrov 24 September 2008 m_pDescriptor = pDescriptor; if( bEmbed ) { this->EmbedFontFile( pDescriptor ); m_bWasEmbedded = true; } }
PdfElement::PdfElement( EPdfDataType eExpectedDataType, PdfObject* pObject ) { if( !pObject ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } m_pObject = pObject; if( m_pObject->GetDataType() != eExpectedDataType ) { PODOFO_RAISE_ERROR( ePdfError_InvalidDataType ); } }
void PdfParser::ReadXRefStreamEntry( char* pBuffer, pdf_long, long lW[W_ARRAY_SIZE], int nObjNo ) { int i, z; unsigned long nData[W_ARRAY_SIZE]; for( i=0;i<W_ARRAY_SIZE;i++ ) { if( lW[i] > W_MAX_BYTES ) { PdfError::LogMessage( eLogSeverity_Error, "The XRef stream dictionary has an entry in /W of size %i.\nThe maximum supported value is %i.\n", lW[i], W_MAX_BYTES ); PODOFO_RAISE_ERROR( ePdfError_InvalidXRefStream ); } nData[i] = 0; for( z=W_MAX_BYTES-lW[i];z<W_MAX_BYTES;z++ ) { nData[i] = (nData[i] << 8) + static_cast<unsigned char>(*pBuffer); ++pBuffer; } } m_offsets[nObjNo].bParsed = true; switch( nData[0] ) // nData[0] contains the type information of this entry { case 0: // a free object m_offsets[nObjNo].lOffset = nData[1]; m_offsets[nObjNo].lGeneration = nData[2]; m_offsets[nObjNo].cUsed = 'f'; break; case 1: // normal uncompressed object m_offsets[nObjNo].lOffset = nData[1]; m_offsets[nObjNo].lGeneration = nData[2]; m_offsets[nObjNo].cUsed = 'n'; break; case 2: // object that is part of an object stream m_offsets[nObjNo].lOffset = nData[2]; // index in the object stream m_offsets[nObjNo].lGeneration = nData[1]; // object number of the stream m_offsets[nObjNo].cUsed = 's'; // mark as stream break; default: { PODOFO_RAISE_ERROR( ePdfError_InvalidXRefType ); } } }
PdfOutputDevice::PdfOutputDevice( const char* pszFilename, bool bTruncate ) { this->Init(); if( !pszFilename ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } std::ios_base::openmode openmode = std::fstream::binary | std::ios_base::in | std::ios_base::out; if( bTruncate ) openmode |= std::ios_base::trunc; std::fstream *pStream = new std::fstream( pszFilename, openmode ); if( pStream->fail() ) { delete pStream; PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, pszFilename ); } m_pStream = pStream; m_pReadStream = pStream; PdfLocaleImbue( *m_pStream ); if( !bTruncate ) { m_pStream->seekp( 0, std::ios_base::end ); m_ulPosition = m_pStream->tellp(); m_ulLength = m_ulPosition; } }
void PdfParser::ReadNextTrailer() { // ReadXRefcontents has read the first 't' from "trailer" so just check for "railer" if( this->IsNextToken( "trailer" ) ) //if( strcmp( m_buffer.GetBuffer(), "railer" ) == 0 ) { PdfParserObject trailer( m_vecObjects, m_device, m_buffer ); try { // Ignore the encryption in the trailer as the trailer may not be encrypted trailer.ParseFile( NULL, true ); } catch( PdfError & e ) { e.AddToCallstack( __FILE__, __LINE__, "The linearized trailer was found in the file, but contains errors." ); throw e; } // now merge the information of this trailer with the main documents trailer MergeTrailer( &trailer ); if( trailer.GetDictionary().HasKey( "Prev" ) ) { try { ReadXRefContents( static_cast<pdf_long>(trailer.GetDictionary().GetKeyAsLong( "Prev", 0 )) ); } catch( PdfError & e ) { e.AddToCallstack( __FILE__, __LINE__, "Unable to load /Prev xref entries." ); throw e; } } else { PODOFO_RAISE_ERROR( ePdfError_NoTrailer ); } } }
void PdfAnnotation::SetAppearanceStream( PdfXObject* pObject ) { PdfDictionary dict; PdfDictionary internal; if( !pObject ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } // when adding #On/Off# entries to #AP#, and set #AS# to "On", // will cause desktop adobe pdf reader not showing display content of the Appearance Stream of PolyLine // so comment out it, joy@onyx // internal.AddKey( "On", pObject->GetObject()->Reference() ); // internal.AddKey( "Off", pObject->GetObject()->Reference() ); // // dict.AddKey( "N", internal ); // // this->GetObject()->GetDictionary().AddKey( "AP", dict ); // this->GetObject()->GetDictionary().AddKey( "AS", PdfName("On") ); dict.AddKey( "N", pObject->GetObject()->Reference() ); this->GetObject()->GetDictionary().AddKey( "AP", dict ); }
void PdfOutputDevice::Write( const char* pBuffer, size_t lLen ) { if( m_hFile ) { if( fwrite( pBuffer, sizeof(char), lLen, m_hFile ) != static_cast<size_t>(lLen) ) { PODOFO_RAISE_ERROR( ePdfError_UnexpectedEOF ); } } else if( m_pBuffer ) { if( m_ulPosition + lLen <= m_lBufferLen ) { memcpy( m_pBuffer + m_ulPosition, pBuffer, lLen ); } else { PODOFO_RAISE_ERROR_INFO( ePdfError_OutOfMemory, "Allocated buffer to small for PdfOutputDevice. Cannot write!" ); } } else if( m_pStream ) { m_pStream->write( pBuffer, lLen ); } else if( m_pRefCountedBuffer ) { if( m_ulPosition + lLen > m_pRefCountedBuffer->GetSize() ) m_pRefCountedBuffer->Resize( m_ulPosition + lLen ); memcpy( m_pRefCountedBuffer->GetBuffer() + m_ulPosition, pBuffer, lLen ); } m_ulPosition += static_cast<size_t>(lLen); if(m_ulPosition>m_ulLength) m_ulLength = m_ulPosition; }
void PdfFontMetricsFreetype::GetWidthArray( PdfVariant & var, unsigned int nFirst, unsigned int nLast ) const { unsigned int i; PdfArray list; if( !m_pFace ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } for( i=nFirst;i<=nLast;i++ ) { if( i < PODOFO_WIDTH_CACHE_SIZE ) list.push_back( PdfVariant( m_vecWidth[i] ) ); else { if( !FT_Load_Char( m_pFace, i, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP ) ) // | FT_LOAD_NO_RENDER { //PODOFO_RAISE_ERROR( ePdfError_FreeType ); list.push_back( PdfVariant( 0.0 ) ); continue; } list.push_back( PdfVariant( m_pFace->glyph->metrics.horiAdvance * 1000.0 / m_pFace->units_per_EM ) ); } } var = PdfVariant( list ); }
PdfInputDevice::PdfInputDevice( const wchar_t* pszFilename ) { this->Init(); if( !pszFilename ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } try { // James McGill 16.02.2011 Fix wide character filename loading in windows m_pFile = _wfopen(pszFilename, L"rb"); if( !m_pFile) { PdfError e( ePdfError_FileNotFound, __FILE__, __LINE__ ); e.SetErrorInformation( pszFilename ); throw e; } m_StreamOwned = true; } catch(...) { // should probably check the exact error, but for now it's a good error PdfError e( ePdfError_FileNotFound, __FILE__, __LINE__ ); e.SetErrorInformation( pszFilename ); throw e; } }
PdfXObject::PdfXObject( const PdfMemDocument & rDoc, int nPage, PdfDocument* pParent ) : PdfElement( "XObject", pParent ), PdfCanvas() { m_rRect = PdfRect(); InitXObject( m_rRect, "XObInd" ); // Implementation note: source document must be different from distination if ( pParent == reinterpret_cast<const PdfDocument*>(&rDoc) ) { PODOFO_RAISE_ERROR( ePdfError_InternalLogic ); } // After filling set correct BBox m_rRect = pParent->FillXObjectFromDocumentPage( this, rDoc, nPage ); PdfVariant var; m_rRect.ToVariant( var ); m_pObject->GetDictionary().AddKey( "BBox", var ); PdfArray matrix; matrix.push_back( PdfVariant( 1LL ) ); matrix.push_back( PdfVariant( 0LL ) ); matrix.push_back( PdfVariant( 0LL ) ); matrix.push_back( PdfVariant( 1LL ) ); if( m_rRect.GetLeft() != 0 ) matrix.push_back( PdfVariant( m_rRect.GetLeft() * (-1.0) ) ); else matrix.push_back( PdfVariant( 0LL ) ); if( m_rRect.GetBottom() != 0 ) matrix.push_back( PdfVariant( m_rRect.GetBottom() * (-1.0) ) ); else matrix.push_back( PdfVariant( 0LL ) ); m_pObject->GetDictionary().AddKey( "Matrix", matrix ); }
PdfOutputDevice::PdfOutputDevice( const wchar_t* pszFilename, bool bTruncate ) { this->Init(); if( !pszFilename ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } m_hFile = _wfopen( pszFilename, bTruncate ? L"w+b" : L"r+b" ); if( !m_hFile ) { PdfError e( ePdfError_FileNotFound, __FILE__, __LINE__ ); e.SetErrorInformation( pszFilename ); throw e; } if( !bTruncate ) { if( fseeko( m_hFile, 0, SEEK_END ) == -1 ) { PODOFO_RAISE_ERROR_INFO( ePdfError_ValueOutOfRange, "Failed to seek to the end of the file" ); } m_ulPosition = ftello( m_hFile ); m_ulLength = m_ulPosition; } }
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 ); } }
void PdfParser::ParseFile( const PdfRefCountedInputDevice & rDevice, bool bLoadOnDemand ) { // make sure everything is clean Clear(); m_device = rDevice; m_bLoadOnDemand = bLoadOnDemand; if( !IsPdfFile() ) { PODOFO_RAISE_ERROR( ePdfError_NoPdfFile ); } ReadDocumentStructure(); try { ReadObjects(); } catch( PdfError & e ) { // If this is being called from a constructor then the // destructor will not be called. // Clean up here Clear(); e.AddToCallstack( __FILE__, __LINE__, "Unable to load objects from file." ); throw e; } // Now sort the list of objects m_vecObjects->Sort(); }
size_t PdfSignOutputDevice::ReadForSignature(char* pBuffer, size_t lLen) { if(!m_bBeaconFound) { PODOFO_RAISE_ERROR( ePdfError_InternalLogic ); } size_t pos = m_pRealDevice->Tell(); size_t numRead = 0; // Check if we are before beacon if(pos<m_sBeaconPos) { size_t readSize = std::min(lLen, m_sBeaconPos-pos); if(readSize>0) { numRead = m_pRealDevice->Read(pBuffer, readSize); pBuffer += numRead; lLen -= numRead; if(lLen==0) return numRead; } } // shift at the end of beacon if( (pos+numRead)>= m_sBeaconPos && pos < (m_sBeaconPos+(m_pSignatureBeacon->data().size()+2) ) ) { m_pRealDevice->Seek(m_sBeaconPos+(m_pSignatureBeacon->data().size()+2) ); } // read after beacon lLen = std::min(lLen, m_pRealDevice->GetLength()-m_pRealDevice->Tell()); if(lLen==0) return numRead; return numRead+m_pRealDevice->Read(pBuffer, lLen); }
void PdfXRef::MergeBlocks() { PdfXRef::TIVecXRefBlock it = m_vecBlocks.begin(); PdfXRef::TIVecXRefBlock itNext = it+1; // Do not crash in case we have no blocks at all if( it == m_vecBlocks.end() ) { PODOFO_RAISE_ERROR( ePdfError_NoXRef ); } while( itNext != m_vecBlocks.end() ) { if( (*itNext).m_nFirst == (*it).m_nFirst + (*it).m_nCount ) { // merge the two (*it).m_nCount += (*itNext).m_nCount; (*it).items.reserve( (*it).items.size() + (*itNext).items.size() ); (*it).items.insert( (*it).items.end(), (*itNext).items.begin(), (*itNext).items.end() ); (*it).freeItems.reserve( (*it).freeItems.size() + (*itNext).freeItems.size() ); (*it).freeItems.insert( (*it).freeItems.end(), (*itNext).freeItems.begin(), (*itNext).freeItems.end() ); itNext = m_vecBlocks.erase( itNext ); it = itNext - 1; } else it = itNext++; } }
void PdfSignOutputDevice::AdjustByteRange() { if(!m_bBeaconFound) { PODOFO_RAISE_ERROR( ePdfError_InternalLogic ); } // Get final position size_t sFileEnd = GetLength(); PdfArray arr; arr.push_back( PdfVariant(static_cast<pdf_int64>(0)) ); arr.push_back( PdfVariant(static_cast<pdf_int64>(m_sBeaconPos)) ); arr.push_back( PdfVariant(static_cast<pdf_int64>(m_sBeaconPos+m_pSignatureBeacon->data().size()+2) ) ); arr.push_back( PdfVariant(static_cast<pdf_int64>(sFileEnd-(m_sBeaconPos+m_pSignatureBeacon->data().size()+2)) ) ); std::string sPosition; PdfVariant(arr).ToString(sPosition, ePdfWriteMode_Compact); // Fill padding unsigned int sPosSize = sizeof("[ 0 1234567890 1234567890 1234567890]")-1; if(sPosition.size()<sPosSize) { // drop last ']' sPosition.resize(sPosition.size()-1); while(sPosition.size()<(sPosSize-1)) { sPosition+=' '; } sPosition+=']'; } m_pRealDevice->Seek(m_sBeaconPos-sPosition.size()-9); m_pRealDevice->Write(sPosition.c_str(), sPosition.size()); }
void PdfFont::WriteStringToStream( const PdfString & rsString, PdfStream* pStream ) { if( !m_pEncoding ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } PdfString sEncoded = m_pEncoding->ConvertToEncoding( rsString, this ); if( sEncoded.IsUnicode() ) { PODOFO_RAISE_ERROR_INFO( ePdfError_InternalLogic, "ConvertToEncoding must not return a unicode string" ); } pdf_long lLen = 0; char* pBuffer = NULL; std::auto_ptr<PdfFilter> pFilter = PdfFilterFactory::Create( ePdfFilter_ASCIIHexDecode ); pFilter->Encode( sEncoded.GetString(), sEncoded.GetLength(), &pBuffer, &lLen ); pStream->Append( "<", 1 ); pStream->Append( pBuffer, lLen ); pStream->Append( ">", 1 ); free( pBuffer ); }
PdfAnnotation::PdfAnnotation( PdfPage* pPage, EPdfAnnotation eAnnot, const PdfRect & rRect, PdfVecObjects* pParent ) : PdfElement( "Annot", pParent ), m_eAnnotation( eAnnot ), m_pAction( NULL ), m_pFileSpec( NULL ), m_pPage( pPage ) { PdfVariant rect; PdfDate date; PdfString sDate; const PdfName name( TypeNameForIndex( eAnnot, s_names, s_lNumActions ) ); if( !name.GetLength() ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } rRect.ToVariant( rect ); m_pObject->GetDictionary().AddKey( PdfName::KeyRect, rect ); rRect.ToVariant( rect ); date.ToString( sDate ); m_pObject->GetDictionary().AddKey( PdfName::KeySubtype, name ); m_pObject->GetDictionary().AddKey( PdfName::KeyRect, rect ); m_pObject->GetDictionary().AddKey( "P", pPage->GetObject()->Reference() ); m_pObject->GetDictionary().AddKey( "M", sDate ); }
void PdfMemStream::GetCopy(PdfOutputStream * pStream) const { if( !pStream) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pStream->Write(m_buffer.GetBuffer(), m_lLength); }
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 PdfMemStream::GetCopy( char** pBuffer, pdf_long* lLen ) const { if( !pBuffer || !lLen ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } *pBuffer = static_cast<char*>(malloc( sizeof( char ) * m_lLength )); *lLen = m_lLength; if( !*pBuffer ) { PODOFO_RAISE_ERROR( ePdfError_OutOfMemory ); } memcpy( *pBuffer, m_buffer.GetBuffer(), m_lLength ); }
void PdfPagesTree::InsertPagesIntoNode( PdfObject* pParent, const PdfObjectList & rlstParents, int nIndex, const std::vector<PdfObject*>& vecPages ) { if( !pParent || !vecPages.size() ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } // 1. Add the reference of the new page to the kids array of pParent // 2. Increase count of every node in lstParents (which also includes pParent) // 3. Add Parent key to the page // 1. Add reference const PdfArray oldKids = pParent->GetDictionary().GetKey( PdfName("Kids") )->GetArray(); PdfArray newKids; newKids.reserve( oldKids.GetSize() + vecPages.size() ); bool bIsPushedIn = false; int i=0; for (PdfArray::const_iterator it=oldKids.begin(); it!=oldKids.end(); ++it, ++i ) { if ( !bIsPushedIn && (nIndex < i) ) // Pushing before { for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages) { newKids.push_back( (*itPages)->Reference() ); // Push all new kids at once } bIsPushedIn = true; } newKids.push_back( *it ); // Push in the old kids } // If new kids are still not pushed in then they may be appending to the end if ( !bIsPushedIn && ( (nIndex + 1) == static_cast<int>(oldKids.size())) ) { for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages) { newKids.push_back( (*itPages)->Reference() ); // Push all new kids at once } bIsPushedIn = true; } pParent->GetDictionary().AddKey( PdfName("Kids"), newKids ); // 2. increase count for ( PdfObjectList::const_reverse_iterator itParents = rlstParents.rbegin(); itParents != rlstParents.rend(); ++itParents ) { this->ChangePagesCount( *itParents, vecPages.size() ); } // 3. add parent key to each of the pages for (std::vector<PdfObject*>::const_iterator itPages=vecPages.begin(); itPages!=vecPages.end(); ++itPages) { (*itPages)->GetDictionary().AddKey( PdfName("Parent"), pParent->Reference() ); } }