vcl/source/gdi/pdfwriter_impl.cxx | 560 -------------------------------------- vcl/source/gdi/pdfwriter_impl.hxx | 3 2 files changed, 563 deletions(-)
New commits: commit 70ecf1919e3e3b9509ff55b2265b3d98d2a5f1aa Author: Khaled Hosny <khaledho...@eglug.org> Date: Tue Nov 29 11:51:23 2016 +0200 Dead code m_aEmbeddedFonts is always empty now. Change-Id: Ia0cdfbabff29722d51b92ed47e04ef40d71f65be Reviewed-on: https://gerrit.libreoffice.org/31373 Reviewed-by: Khaled Hosny <khaledho...@eglug.org> Tested-by: Khaled Hosny <khaledho...@eglug.org> diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 12fe24d..30daf70 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -3046,555 +3046,6 @@ static bool getPfbSegmentLengths( const unsigned char* pFontBytes, int nByteLen, return true; } -struct FontException : public std::exception -{ -}; - -// TODO: always subset instead of embedding the full font => this method becomes obsolete then -std::map< sal_Int32, sal_Int32 > PDFWriterImpl::emitEmbeddedFont( const PhysicalFontFace* pFont, EmbedFont& rEmbed ) -{ - std::map< sal_Int32, sal_Int32 > aRet; - - sal_Int32 nStreamObject = 0; - sal_Int32 nFontDescriptor = 0; - - SalGraphics *pGraphics = m_pReferenceDevice->GetGraphics(); - - assert(pGraphics); - - // prepare font encoding - sal_Int32 nToUnicodeStream = 0; - sal_uInt8 nEncoding[256]; - sal_Ucs nEncodedCodes[256]; - std::vector<sal_Ucs> aUnicodes; - aUnicodes.reserve( 256 ); - sal_Int32 pUnicodesPerGlyph[256]; - sal_Int32 pEncToUnicodeIndex[256]; - - FontSubsetInfo aInfo; - sal_Int32 pWidths[256]; - const unsigned char* pFontData = nullptr; - long nFontLen = 0; - sal_Int32 nLength1, nLength2; - try - { - if( (pFontData = static_cast<const unsigned char*>(pGraphics->GetEmbedFontData(pFont, nEncodedCodes, pWidths, 256, aInfo, &nFontLen))) != nullptr ) - { - if( (aInfo.m_nFontType & FontSubsetInfo::ANY_TYPE1) == 0 ) - throw FontException(); - // see whether it is pfb or pfa; if it is a pfb, fill ranges - // of 6 bytes that are not part of the font program - std::list< int > aSections; - std::list< int >::const_iterator it; - int nIndex = 0; - while( (nIndex < nFontLen-1) && pFontData[nIndex] == 0x80 ) - { - aSections.push_back( nIndex ); - if( pFontData[nIndex+1] == 0x03 ) - break; - sal_Int32 nBytes = - ((sal_Int32)pFontData[nIndex+2]) | - ((sal_Int32)pFontData[nIndex+3]) << 8 | - ((sal_Int32)pFontData[nIndex+4]) << 16 | - ((sal_Int32)pFontData[nIndex+5]) << 24; - nIndex += nBytes+6; - } - - // search for eexec - // TODO: use getPfbSegmentLengths() if possible to skip the search thingies below - nIndex = 0; - int nEndAsciiIndex; - int nBeginBinaryIndex; - int nEndBinaryIndex; - do - { - while( nIndex < nFontLen-4 && - ( pFontData[nIndex] != 'e' || - pFontData[nIndex+1] != 'e' || - pFontData[nIndex+2] != 'x' || - pFontData[nIndex+3] != 'e' || - pFontData[nIndex+4] != 'c' - ) - ) - { - ++nIndex; - } - // check whether we are in a excluded section - for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it ) - ; - } while( it != aSections.end() && nIndex < nFontLen-4 ); - // this should end the ascii part - if( nIndex > nFontLen-5 ) - throw FontException(); - - nEndAsciiIndex = nIndex+4; - // now count backwards until we can account for 512 '0' - // which is the endmarker of the (hopefully) binary data - // do not count the pfb header sections - int nFound = 0; - nIndex = nFontLen-1; - while( nIndex > 0 && nFound < 512 ) - { - for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it ) - ; - if( it == aSections.end() ) - { - // inside the 512 '0' block there may only be whitespace - // according to T1 spec; probably it would be to simple - // if all fonts complied - if( pFontData[nIndex] == '0' ) - nFound++; - else if( nFound > 0 && - pFontData[nIndex] != '\r' && - pFontData[nIndex] != '\t' && - pFontData[nIndex] != '\n' && - pFontData[nIndex] != ' ' ) - break; - } - nIndex--; - } - - if( nIndex < 1 || nIndex <= nEndAsciiIndex ) - throw FontException(); - - // nLength3 is the rest of the file - excluding any section headers - // nIndex now points before the first of the 512 '0' characters marking the - // fixed content portion - sal_Int32 nLength3 = nFontLen - nIndex - 1; - for( it = aSections.begin(); it != aSections.end(); ++it ) - { - // special case: nIndex inside a section marker - if( nIndex >= (*it) && (*it)+6 > nIndex ) - nLength3 -= (*it)+6 - nIndex; - else if( *it >= nIndex ) - { - if( *it < nFontLen - 6 ) - nLength3 -= 6; - else // the last section 0x8003 is only 2 bytes after all - nLength3 -= (nFontLen - *it); - } - } - - // there may be whitespace to ignore before the 512 '0' - while( pFontData[nIndex] == '\r' || pFontData[nIndex] == '\n' ) - { - nIndex--; - for( it = aSections.begin(); it != aSections.end() && (nIndex < *it || nIndex > ((*it) + 5) ); ++it ) - ; - if( it != aSections.end() ) - { - nIndex = (*it)-1; - break; // this is surely a binary boundary, in ascii case it wouldn't matter - } - } - nEndBinaryIndex = nIndex; - - // search for beginning of binary section - nBeginBinaryIndex = nEndAsciiIndex; - do - { - nBeginBinaryIndex++; - for( it = aSections.begin(); it != aSections.end() && (nBeginBinaryIndex < *it || nBeginBinaryIndex > ((*it) + 5) ); ++it ) - ; - } while( nBeginBinaryIndex < nEndBinaryIndex && - ( pFontData[nBeginBinaryIndex] == '\r' || - pFontData[nBeginBinaryIndex] == '\n' || - it != aSections.end() ) ); - - // it seems to be vital to copy the exact whitespace between binary data - // and eexec, else a invalid font results. so make nEndAsciiIndex - // always immediate in front of nBeginBinaryIndex - nEndAsciiIndex = nBeginBinaryIndex-1; - for( it = aSections.begin(); it != aSections.end() && (nEndAsciiIndex < *it || nEndAsciiIndex > ((*it)+5)); ++it ) - ; - if( it != aSections.end() ) - nEndAsciiIndex = (*it)-1; - - nLength1 = nEndAsciiIndex+1; // including the last character - for( it = aSections.begin(); it != aSections.end() && *it < nEndAsciiIndex; ++it ) - nLength1 -= 6; // decrease by pfb section size - - // if the first four bytes are all ascii hex characters, then binary data - // has to be converted to real binary data - for( nIndex = 0; nIndex < 4 && - ( ( pFontData[ nBeginBinaryIndex+nIndex ] >= '0' && pFontData[ nBeginBinaryIndex+nIndex ] <= '9' ) || - ( pFontData[ nBeginBinaryIndex+nIndex ] >= 'a' && pFontData[ nBeginBinaryIndex+nIndex ] <= 'f' ) || - ( pFontData[ nBeginBinaryIndex+nIndex ] >= 'A' && pFontData[ nBeginBinaryIndex+nIndex ] <= 'F' ) - ); ++nIndex ) - ; - bool bConvertHexData = true; - if( nIndex < 4 ) - { - bConvertHexData = false; - nLength2 = nEndBinaryIndex - nBeginBinaryIndex + 1; // include the last byte - for( it = aSections.begin(); it != aSections.end(); ++it ) - if( *it > nBeginBinaryIndex && *it < nEndBinaryIndex ) - nLength2 -= 6; - } - else - { - // count the hex ascii characters to get nLength2 - nLength2 = 0; - int nNextSectionIndex = 0; - for( it = aSections.begin(); it != aSections.end() && *it < nBeginBinaryIndex; ++it ) - ; - if( it != aSections.end() ) - nNextSectionIndex = *it; - for( nIndex = nBeginBinaryIndex; nIndex <= nEndBinaryIndex; nIndex++ ) - { - if( nIndex == nNextSectionIndex ) - { - nIndex += 6; - ++it; - nNextSectionIndex = (it == aSections.end() ? 0 : *it ); - } - if( ( pFontData[ nIndex ] >= '0' && pFontData[ nIndex ] <= '9' ) || - ( pFontData[ nIndex ] >= 'a' && pFontData[ nIndex ] <= 'f' ) || - ( pFontData[ nIndex ] >= 'A' && pFontData[ nIndex ] <= 'F' ) ) - nLength2++; - } - SAL_WARN_IF( (nLength2 & 1), "vcl", "uneven number of hex chars in binary pfa section" ); - nLength2 /= 2; - } - - // now we can actually write the font stream ! - #if OSL_DEBUG_LEVEL > 1 - emitComment( " PDFWriterImpl::emitEmbeddedFont" ); - #endif - OStringBuffer aLine( 512 ); - nStreamObject = createObject(); - if( !updateObject(nStreamObject)) - throw FontException(); - sal_Int32 nStreamLengthObject = createObject(); - aLine.append( nStreamObject ); - aLine.append( " 0 obj\n" - "<</Length " ); - aLine.append( nStreamLengthObject ); - if (!g_bDebugDisableCompression) - aLine.append( " 0 R" - "/Filter/FlateDecode" - "/Length1 " ); - else - aLine.append( " 0 R" - "/Length1 " ); - aLine.append( nLength1 ); - aLine.append( " /Length2 " ); - aLine.append( nLength2 ); - aLine.append( " /Length3 "); - aLine.append( nLength3 ); - aLine.append( ">>\n" - "stream\n" ); - if( !writeBuffer( aLine.getStr(), aLine.getLength() ) ) - throw FontException(); - - sal_uInt64 nBeginStreamPos = 0; - m_aFile.getPos(nBeginStreamPos); - - beginCompression(); - checkAndEnableStreamEncryption( nStreamObject ); - - // write ascii section - if( aSections.begin() == aSections.end() ) - { - if( ! writeBuffer( pFontData, nEndAsciiIndex+1 ) ) - throw FontException(); - } - else - { - // first section always starts at 0 - it = aSections.begin(); - nIndex = (*it)+6; - ++it; - while( *it < nEndAsciiIndex ) - { - if( ! writeBuffer( pFontData+nIndex, (*it)-nIndex ) ) - throw FontException(); - nIndex = (*it)+6; - ++it; - } - // write partial last section - if( ! writeBuffer( pFontData+nIndex, nEndAsciiIndex-nIndex+1 ) ) - throw FontException(); - } - - // write binary section - if( ! bConvertHexData ) - { - if( aSections.begin() == aSections.end() ) - { - if( ! writeBuffer( pFontData+nBeginBinaryIndex, nFontLen-nBeginBinaryIndex ) ) - throw FontException(); - } - else - { - for( it = aSections.begin(); *it < nBeginBinaryIndex; ++it ) - ; - // write first partial section - if( ! writeBuffer( pFontData+nBeginBinaryIndex, (*it) - nBeginBinaryIndex ) ) - throw FontException(); - // write following sections - while( it != aSections.end() ) - { - nIndex = (*it)+6; - ++it; - if( nIndex < nFontLen ) // last section marker is usually the EOF which has only 2 bytes - { - sal_Int32 nSectionLen = (it == aSections.end()) ? nFontLen - nIndex : (*it) - nIndex; - if( ! writeBuffer( pFontData+nIndex, nSectionLen ) ) - throw FontException(); - } - } - } - } - else - { - std::unique_ptr<unsigned char[]> xWriteBuffer(new unsigned char[nLength2]); - memset(xWriteBuffer.get(), 0, nLength2); - int nWriteIndex = 0; - - int nNextSectionIndex = 0; - for( it = aSections.begin(); it != aSections.end() && *it < nBeginBinaryIndex; ++it ) - ; - if( it != aSections.end() ) - nNextSectionIndex = *it; - for( nIndex = nBeginBinaryIndex; nIndex <= nEndBinaryIndex; nIndex++ ) - { - if( nIndex == nNextSectionIndex ) - { - nIndex += 6; - ++it; - nNextSectionIndex = (it == aSections.end() ? nFontLen : *it ); - } - unsigned char cNibble = 0x80; - if( pFontData[ nIndex ] >= '0' && pFontData[ nIndex ] <= '9' ) - cNibble = pFontData[nIndex] - '0'; - else if( pFontData[ nIndex ] >= 'a' && pFontData[ nIndex ] <= 'f' ) - cNibble = pFontData[nIndex] - 'a' + 10; - else if( pFontData[ nIndex ] >= 'A' && pFontData[ nIndex ] <= 'F' ) - cNibble = pFontData[nIndex] - 'A' + 10; - if( cNibble != 0x80 ) - { - if( !(nWriteIndex & 1 ) ) - cNibble <<= 4; - xWriteBuffer.get()[ nWriteIndex/2 ] |= cNibble; - nWriteIndex++; - } - } - if (!writeBuffer(xWriteBuffer.get(), nLength2)) - throw FontException(); - if( aSections.empty() ) - { - if( ! writeBuffer( pFontData+nIndex, nFontLen-nIndex ) ) - throw FontException(); - } - else - { - // write rest of this section - if( nIndex < nNextSectionIndex ) - { - if( ! writeBuffer( pFontData+nIndex, nNextSectionIndex - nIndex ) ) - throw FontException(); - } - // write following sections - while( it != aSections.end() ) - { - nIndex = (*it)+6; - ++it; - if( nIndex < nFontLen ) // last section marker is usually the EOF which has only 2 bytes - { - sal_Int32 nSectionLen = (it == aSections.end()) ? nFontLen - nIndex : (*it) - nIndex; - if( ! writeBuffer( pFontData+nIndex, nSectionLen ) ) - throw FontException(); - } - } - } - } - endCompression(); - disableStreamEncryption(); - - sal_uInt64 nEndStreamPos = 0; - m_aFile.getPos(nEndStreamPos); - - // and finally close the stream - aLine.setLength( 0 ); - aLine.append( "\nendstream\nendobj\n\n" ); - if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) ) - throw FontException(); - - // write stream length object - aLine.setLength( 0 ); - if( ! updateObject( nStreamLengthObject ) ) - throw FontException(); - aLine.append( nStreamLengthObject ); - aLine.append( " 0 obj\n" ); - aLine.append( (sal_Int64)(nEndStreamPos-nBeginStreamPos ) ); - aLine.append( "\nendobj\n\n" ); - if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) ) - throw FontException(); - } - else - { - OStringBuffer aErrorComment( 256 ); - aErrorComment.append( "GetEmbedFontData failed for font \"" ); - aErrorComment.append( OUStringToOString( pFont->GetFamilyName(), RTL_TEXTENCODING_UTF8 ) ); - aErrorComment.append( '\"' ); - if( pFont->GetItalic() == ITALIC_NORMAL ) - aErrorComment.append( " italic" ); - else if( pFont->GetItalic() == ITALIC_OBLIQUE ) - aErrorComment.append( " oblique" ); - aErrorComment.append( " weight=" ); - aErrorComment.append( sal_Int32(pFont->GetWeight()) ); - emitComment( aErrorComment.getStr() ); - } - - if( nStreamObject ) - { - // write font descriptor - nFontDescriptor = emitFontDescriptor( pFont, aInfo, 0, nStreamObject ); - } - - if( nFontDescriptor ) - { - // write font object - sal_Int32 nObject = createObject(); - if( ! updateObject( nObject ) ) - throw FontException(); - - OStringBuffer aLine( 1024 ); - aLine.append( nObject ); - aLine.append( " 0 obj\n" - "<</Type/Font/Subtype/Type1/BaseFont/" ); - appendName( aInfo.m_aPSName, aLine ); - aLine.append( "\n" ); - if (!pFont->IsSymbolFont()) - aLine.append( "/Encoding/WinAnsiEncoding\n" ); - if( nToUnicodeStream ) - { - aLine.append( "/ToUnicode " ); - aLine.append( nToUnicodeStream ); - aLine.append( " 0 R\n" ); - } - aLine.append( "/FirstChar 0 /LastChar 255\n" - "/Widths[" ); - for( int i = 0; i < 256; i++ ) - { - aLine.append( pWidths[i] ); - aLine.append( ((i&15) == 15) ? "\n" : " " ); - } - aLine.append( "]\n" - "/FontDescriptor " ); - aLine.append( nFontDescriptor ); - aLine.append( " 0 R>>\n" - "endobj\n\n" ); - if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) ) - throw FontException(); - - aRet[ rEmbed.m_nNormalFontID ] = nObject; - - // write additional encodings - for( std::list< EmbedEncoding >::iterator enc_it = rEmbed.m_aExtendedEncodings.begin(); enc_it != rEmbed.m_aExtendedEncodings.end(); ++enc_it ) - { - sal_Int32 aEncWidths[ 256 ]; - // emit encoding dict - sal_Int32 nEncObject = createObject(); - if( ! updateObject( nEncObject ) ) - throw FontException(); - - OutputDevice* pRef = getReferenceDevice(); - pRef->Push( PushFlags::FONT | PushFlags::MAPMODE ); - pRef->SetMapMode( MapMode( MapUnit::MapPixel ) ); - Font aFont( pFont->GetFamilyName(), pFont->GetStyleName(), Size( 0, 1000 ) ); - aFont.SetWeight( pFont->GetWeight() ); - aFont.SetItalic( pFont->GetItalic() ); - aFont.SetPitch( pFont->GetPitch() ); - pRef->SetFont( aFont ); - pRef->ImplNewFont(); - - aLine.setLength( 0 ); - aLine.append( nEncObject ); - aLine.append( " 0 obj\n" - "<</Type/Encoding/Differences[ 0\n" ); - int nEncoded = 0; - aUnicodes.clear(); - for( std::vector< EmbedCode >::iterator str_it = enc_it->m_aEncVector.begin(); str_it != enc_it->m_aEncVector.end(); ++str_it ) - { - OUString aStr( str_it->m_aUnicode ); - aEncWidths[nEncoded] = pRef->GetTextWidth( aStr ); - nEncodedCodes[nEncoded] = str_it->m_aUnicode; - nEncoding[nEncoded] = sal::static_int_cast<sal_uInt8>(nEncoded); - pEncToUnicodeIndex[nEncoded] = static_cast<sal_Int32>(aUnicodes.size()); - aUnicodes.push_back( nEncodedCodes[nEncoded] ); - pUnicodesPerGlyph[nEncoded] = 1; - - aLine.append( " /" ); - aLine.append( str_it->m_aName ); - if( !((++nEncoded) & 15) ) - aLine.append( "\n" ); - } - aLine.append( "]>>\n" - "endobj\n\n" ); - - pRef->Pop(); - - if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) ) - throw FontException(); - - nToUnicodeStream = createToUnicodeCMap( nEncoding, &aUnicodes[0], pUnicodesPerGlyph, pEncToUnicodeIndex, nEncoded ); - - nObject = createObject(); - if( ! updateObject( nObject ) ) - throw FontException(); - - aLine.setLength( 0 ); - aLine.append( nObject ); - aLine.append( " 0 obj\n" - "<</Type/Font/Subtype/Type1/BaseFont/" ); - appendName( aInfo.m_aPSName, aLine ); - aLine.append( "\n" ); - aLine.append( "/Encoding " ); - aLine.append( nEncObject ); - aLine.append( " 0 R\n" ); - if( nToUnicodeStream ) - { - aLine.append( "/ToUnicode " ); - aLine.append( nToUnicodeStream ); - aLine.append( " 0 R\n" ); - } - aLine.append( "/FirstChar 0\n" - "/LastChar " ); - aLine.append( (sal_Int32)(nEncoded-1) ); - aLine.append( "\n" - "/Widths[" ); - for( int i = 0; i < nEncoded; i++ ) - { - aLine.append( aEncWidths[i] ); - aLine.append( ((i&15) == 15) ? "\n" : " " ); - } - aLine.append( " ]\n" - "/FontDescriptor " ); - aLine.append( nFontDescriptor ); - aLine.append( " 0 R>>\n" - "endobj\n\n" ); - if( ! writeBuffer( aLine.getStr(), aLine.getLength() ) ) - throw FontException(); - - aRet[ enc_it->m_nFontID ] = nObject; - } - } - } - catch( FontException& ) - { - // these do nothing in case there was no compression or encryption ongoing - endCompression(); - disableStreamEncryption(); - } - - if( pFontData ) - pGraphics->FreeEmbedFontData( pFontData, nFontLen ); - - return aRet; -} - static void appendSubsetName( int nSubsetID, const OUString& rPSName, OStringBuffer& rBuffer ) { if( nSubsetID ) @@ -4045,17 +3496,6 @@ bool PDFWriterImpl::emitFonts() } osl_removeFile( aTmpName.pData ); - // emit embedded fonts - for( FontEmbedData::iterator eit = m_aEmbeddedFonts.begin(); eit != m_aEmbeddedFonts.end(); ++eit ) - { - std::map< sal_Int32, sal_Int32 > aObjects = emitEmbeddedFont( eit->first, eit->second ); - for( std::map< sal_Int32, sal_Int32 >::iterator fit = aObjects.begin(); fit != aObjects.end(); ++fit ) - { - if ( !fit->second ) return false; - aFontIDToObject[ fit->first ] = fit->second; - } - } - // emit system fonts for( FontEmbedData::iterator sit = m_aSystemFonts.begin(); sit != m_aSystemFonts.end(); ++sit ) { diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index 16f1fbd..8cad2f9 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -627,7 +627,6 @@ private: std::list< TransparencyEmit > m_aTransparentObjects; /* contains all font subsets in use */ FontSubsetData m_aSubsets; - FontEmbedData m_aEmbeddedFonts; FontEmbedData m_aSystemFonts; sal_Int32 m_nNextFID; PDFFontCache m_aFontCache; @@ -806,8 +805,6 @@ i12626 bool emitGradients(); /* writes a builtin font object and returns its objectid (or 0 in case of failure ) */ sal_Int32 emitBuiltinFont( const PdfBuiltinFontFace*, sal_Int32 nObject ); - /* writes a type1 embedded font object and returns its mapping from font ids to object ids (or 0 in case of failure ) */ - std::map< sal_Int32, sal_Int32 > emitEmbeddedFont( const PhysicalFontFace*, EmbedFont& ); /* writes a type1 system font object and returns its mapping from font ids to object ids (or 0 in case of failure ) */ std::map< sal_Int32, sal_Int32 > emitSystemFont( const PhysicalFontFace*, EmbedFont& ); /* writes a font descriptor and returns its object id (or 0) */ _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits