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 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 PdfFontType1::EmbedFontFile( PdfObject* pDescriptor ) { pdf_long lSize = 0; pdf_long lLength1 = 0L; pdf_long lLength2 = 0L; pdf_long lLength3 = 0L; PdfObject* pContents; const char* pBuffer; char* pAllocated = NULL; m_bWasEmbedded = true; pContents = m_pObject->GetOwner()->CreateObject(); if( !pContents ) { PODOFO_RAISE_ERROR( ePdfError_InvalidHandle ); } pDescriptor->GetDictionary().AddKey( "FontFile", pContents->Reference() ); // if the data was loaded from memory - use it from there // otherwise, load from disk if ( m_pMetrics->GetFontDataLen() && m_pMetrics->GetFontData() ) { pBuffer = m_pMetrics->GetFontData(); lSize = m_pMetrics->GetFontDataLen(); } else { FILE* hFile = fopen( m_pMetrics->GetFilename(), "rb" ); if( !hFile ) { PODOFO_RAISE_ERROR_INFO( ePdfError_FileNotFound, m_pMetrics->GetFilename() ); } fseek( hFile, 0L, SEEK_END ); lSize = ftell( hFile ); fseek( hFile, 0L, SEEK_SET ); pAllocated = static_cast<char*>(malloc( sizeof(char) * lSize )); if( !pAllocated ) { fclose( hFile ); PODOFO_RAISE_ERROR( ePdfError_OutOfMemory ); } fread( pAllocated, sizeof(char), lSize, hFile ); fclose( hFile ); pBuffer = pAllocated; } // Remove binary segment headers from pfb unsigned char *pBinary = reinterpret_cast<unsigned char*>(const_cast<char*>(pBuffer)); while( *pBinary == 0x80 ) // binary segment header { const int cHeaderLength = 6; int iSegmentType = pBinary[1]; // binary segment type long lSegmentLength = 0L; long lSegmentDelta = static_cast<long>(&pBuffer[lSize] - reinterpret_cast<const char*>(pBinary) ); switch( iSegmentType ) { case 1: // ASCII text lSegmentLength = pBinary[2] + // little endian pBinary[3] * 256L + pBinary[4] * 65536L + pBinary[5] * 16777216L; if( lLength1 == 0L ) lLength1 = lSegmentLength; else lLength3 = lSegmentLength; lSize -= cHeaderLength; memmove( pBinary, &pBinary[cHeaderLength], lSegmentDelta ); pBinary = &pBinary[lSegmentLength]; break; case 2: // binary data lSegmentLength = pBinary[2] + // little endian pBinary[3] * 256L + pBinary[4] * 65536L + pBinary[5] * 16777216L; lLength2 = lSegmentLength; lSize -= cHeaderLength; memmove( pBinary, &pBinary[cHeaderLength], lSegmentDelta ); pBinary = &pBinary[lSegmentLength]; break; case 3: // end-of-file pContents->GetStream()->Set( pBuffer, lSize - 2L ); if( pAllocated ) free( pAllocated ); pContents->GetDictionary().AddKey( "Length1", PdfVariant( static_cast<long long>(lLength1) ) ); pContents->GetDictionary().AddKey( "Length2", PdfVariant( static_cast<long long>(lLength2) ) ); pContents->GetDictionary().AddKey( "Length3", PdfVariant( static_cast<long long>(lLength3) ) ); return; default: break; } } // Parse the font data buffer to get the values for length1, length2 and length3 lLength1 = FindInBuffer( "eexec", pBuffer, lSize ); if( lLength1 > 0 ) lLength1 += 6; // 6 == eexec + lf else lLength1 = 0; if( lLength1 ) { lLength2 = FindInBuffer( "cleartomark", pBuffer, lSize ); if( lLength2 > 0 ) lLength2 = lSize - lLength1 - 520; // 520 == 512 + strlen(cleartomark) else lLength1 = 0; } lLength3 = lSize - lLength2 - lLength1; // TODO: Pdf Supports only Type1 fonts with binary encrypted sections and not the hex format pContents->GetStream()->Set( pBuffer, lSize ); if( pAllocated ) free( pAllocated ); pContents->GetDictionary().AddKey( "Length1", PdfVariant( static_cast<long long>(lLength1) ) ); pContents->GetDictionary().AddKey( "Length2", PdfVariant( static_cast<long long>(lLength2) ) ); pContents->GetDictionary().AddKey( "Length3", PdfVariant( static_cast<long long>(lLength3) ) ); }