20 #include <config_features.h>
26 #include <string_view>
37 #include <com/sun/star/io/XOutputStream.hpp>
38 #include <com/sun/star/util/URL.hpp>
39 #include <com/sun/star/util/URLTransformer.hpp>
45 #include <officecfg/Office/Common.hxx>
46 #include <osl/file.hxx>
47 #include <osl/thread.h>
48 #include <rtl/digest.h>
49 #include <rtl/ustrbuf.hxx>
75 #include <textlayout.hxx>
92 #include <config_eot.h>
95 #include <libeot/libeot.h>
98 using namespace::com::sun::star;
116 #define MAX_SIGNATURE_CONTENT_LENGTH 50000
122 constexpr sal_Int32 nLog10Divisor = 3;
123 constexpr
double fDivisor = 1000.0;
125 constexpr
double pixelToPoint(
double px)
127 return px / fDivisor;
130 constexpr sal_Int32 pointToPixel(
double pt)
132 return sal_Int32(pt * fDivisor);
135 void appendHex(
sal_Int8 nInt, OStringBuffer& rBuffer)
137 static const char pHexDigits[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
138 '8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
139 rBuffer.append( pHexDigits[ (nInt >> 4) & 15 ] );
140 rBuffer.append( pHexDigits[ nInt & 15 ] );
143 void appendName( std::u16string_view rStr, OStringBuffer& rBuffer )
148 int nLen =
aStr.getLength();
149 for(
int i = 0;
i < nLen;
i++ )
158 if( (aStr[i] >=
'A' && aStr[i] <=
'Z' ) ||
159 (aStr[i] >=
'a' && aStr[i] <=
'z' ) ||
160 (aStr[i] >=
'0' && aStr[i] <=
'9' ) ||
163 rBuffer.append( aStr[i] );
167 rBuffer.append(
'#' );
168 appendHex( static_cast<sal_Int8>(aStr[i]), rBuffer );
173 void appendName(
const char* pStr, OStringBuffer& rBuffer )
176 while( pStr && *pStr )
178 if( (*pStr >=
'A' && *pStr <=
'Z' ) ||
179 (*pStr >=
'a' && *pStr <=
'z' ) ||
180 (*pStr >=
'0' && *pStr <=
'9' ) ||
183 rBuffer.append( *pStr );
187 rBuffer.append(
'#' );
188 appendHex( static_cast<sal_Int8>(*pStr), rBuffer );
195 void appendLiteralString(
const char* pStr, sal_Int32 nLength, OStringBuffer& rBuffer )
202 rBuffer.append(
"\\n" );
205 rBuffer.append(
"\\r" );
208 rBuffer.append(
"\\t" );
211 rBuffer.append(
"\\b" );
214 rBuffer.append(
"\\f" );
219 rBuffer.append(
"\\" );
220 rBuffer.append( static_cast<char>(*pStr) );
223 rBuffer.append( static_cast<char>(*pStr) );
254 void appendDestinationName(
const OUString& rString, OStringBuffer& rBuffer )
257 sal_Int32 nLen = rString.getLength();
258 for(
int i = 0;
i < nLen;
i++ )
261 if( (aChar >=
'0' && aChar <=
'9' ) ||
262 (aChar >=
'a' && aChar <=
'z' ) ||
263 (aChar >=
'A' && aChar <=
'Z' ) ||
266 rBuffer.append(static_cast<char>(aChar));
272 appendHex( aValueHigh, rBuffer );
273 appendHex( static_cast<sal_Int8>(aChar & 255 ), rBuffer );
284 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
285 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
291 template <
class GEOMETRY >
292 GEOMETRY lcl_convert(
const MapMode& _rSource,
const MapMode& _rDest,
OutputDevice* _pPixelConversion,
const GEOMETRY& _rObject )
295 if ( MapUnit::MapPixel == _rSource.
GetMapUnit() )
297 aPoint = _pPixelConversion->
PixelToLogic( _rObject, _rDest );
310 rBuffer.append(
"FEFF" );
312 sal_Int32 nLen = rString.getLength();
313 for(
int i = 0;
i < nLen;
i++ )
316 appendHex( static_cast<sal_Int8>(aChar >> 8), rBuffer );
317 appendHex( static_cast<sal_Int8>(aChar & 255 ), rBuffer );
329 int nLen =
aStr.getLength();
331 OStringBuffer
aBuffer( rName.getLength()+64 );
332 for(
int i = 0;
i < nLen;
i++ )
343 appendHex( static_cast<sal_Int8>(
aStr[i]),
aBuffer );
347 OString aFullName(
aBuffer.makeStringAndClear() );
350 sal_Int32 nTokenIndex = 0, nLastTokenIndex = 0;
351 OString aPartialName;
355 nLastTokenIndex = nTokenIndex;
356 aPartialName = aFullName.getToken( 0,
'.', nTokenIndex );
357 if( nTokenIndex != -1 )
361 aDomain = aFullName.copy( 0, nTokenIndex-1 );
362 std::unordered_map< OString, sal_Int32 >::const_iterator it =
m_aFieldNameMap.find( aDomain );
370 m_aWidgets[nNewWidget].m_aName = aPartialName;
374 if( nLastTokenIndex > 0 )
378 OString aParentDomain( aDomain.copy( 0, nLastTokenIndex-1 ) );
383 OSL_ENSURE( it->second < sal_Int32(
m_aWidgets.size()),
"invalid field number entry" );
384 if( it->second < sal_Int32(
m_aWidgets.size()) )
403 aPartialName = aFullName.copy( aFullName.lastIndexOf(
'.' )+1 );
404 if( nLastTokenIndex > 0 )
406 aDomain = aFullName.copy( 0, nLastTokenIndex-1 );
407 aFullName = aDomain +
"." + aPartialName;
410 aFullName = aPartialName;
414 }
while( nTokenIndex != -1 );
417 if( !aDomain.isEmpty() )
419 std::unordered_map< OString, sal_Int32 >::const_iterator it =
m_aFieldNameMap.find( aDomain );
422 OSL_ENSURE( it->second >= 0 && it->second < sal_Int32(
m_aWidgets.size() ),
"invalid field index" );
423 if( it->second >= 0 && it->second < sal_Int32(
m_aWidgets.size()) )
427 m_aWidgets[it->second].m_aKidsIndex.push_back( i_nWidgetIndex );
432 if( aPartialName.isEmpty() )
437 aPartialName =
"RadioGroup" +
438 OString::number( static_cast<const PDFWriter::RadioButtonWidget&>(i_rControl).RadioGroup );
441 aPartialName = OString(
"Widget" );
446 std::unordered_map<OString, sal_Int32>::iterator it =
m_aFieldNameMap.find( aFullName );
450 std::unordered_map< OString, sal_Int32 >::const_iterator check_it;
455 OStringBuffer aUnique( aFullName.getLength() + 16 );
456 aUnique.append( aFullName );
457 aUnique.append(
'_' );
458 aUnique.append( nTry++ );
459 aTry = aUnique.makeStringAndClear();
464 aPartialName = aFullName.copy( aFullName.lastIndexOf(
'.' )+1 );
471 m_aWidgets[i_nWidgetIndex].m_aName = aPartialName;
477 void appendFixedInt( sal_Int32 nValue, OStringBuffer& rBuffer )
481 rBuffer.append(
'-' );
484 sal_Int32 nFactor = 1, nDiv = nLog10Divisor;
488 sal_Int32 nInt = nValue / nFactor;
489 rBuffer.append( nInt );
490 if (nFactor > 1 && nValue % nFactor)
492 rBuffer.append(
'.' );
496 rBuffer.append((nValue / nFactor) % 10);
498 while (nFactor > 1 && nValue % nFactor);
503 void appendDouble(
double fValue, OStringBuffer& rBuffer, sal_Int32 nPrecision = 5 )
512 sal_Int64 nInt =
static_cast<sal_Int64
>(fValue);
513 fValue -=
static_cast<double>(nInt);
515 if( rtl::math::approxEqual(fValue, 1.0) || log10( 1.0-fValue ) <= -nPrecision )
523 fValue *= pow( 10.0, static_cast<double>(nPrecision) );
524 nFrac =
static_cast<sal_Int64
>(fValue);
526 if( bNeg && ( nInt || nFrac ) )
527 rBuffer.append(
'-' );
528 rBuffer.append( nInt );
533 rBuffer.append(
'.' );
534 sal_Int64 nBound =
static_cast<sal_Int64
>(pow( 10.0, nPrecision - 1.0 )+0.5);
535 for ( i = 0; ( i < nPrecision ) && nFrac; i++ )
537 sal_Int64 nNumb = nFrac / nBound;
538 nFrac -= nNumb * nBound;
539 rBuffer.append( nNumb );
544 void appendColor(
const Color& rColor, OStringBuffer& rBuffer,
bool bConvertToGrey )
547 if( rColor == COL_TRANSPARENT )
553 appendDouble( static_cast<double>(cByte) / 255.0, rBuffer );
557 appendDouble( static_cast<double>(rColor.
GetRed()) / 255.0, rBuffer );
558 rBuffer.append(
' ' );
559 appendDouble( static_cast<double>(rColor.
GetGreen()) / 255.0, rBuffer );
560 rBuffer.append(
' ' );
561 appendDouble( static_cast<double>(rColor.
GetBlue()) / 255.0, rBuffer );
572 appendColor( rColor, rBuffer, bGrey );
573 rBuffer.append( bGrey ?
" G" :
" RG" );
582 appendColor( rColor, rBuffer, bGrey );
583 rBuffer.append( bGrey ?
" g" :
" rg" );
590 void appendPdfTimeDate(OStringBuffer & rBuffer,
591 sal_Int16 year, sal_uInt16 month, sal_uInt16 day, sal_uInt16 hours, sal_uInt16 minutes, sal_uInt16 seconds, sal_Int32 tzDelta)
593 rBuffer.append(
"D:");
594 rBuffer.append(
char(
'0' + ((year / 1000) % 10)));
595 rBuffer.append(
char(
'0' + ((year / 100) % 10)));
596 rBuffer.append(
char(
'0' + ((year / 10) % 10)));
597 rBuffer.append(
char(
'0' + (year % 10)));
598 rBuffer.append(
char(
'0' + ((month / 10) % 10)));
599 rBuffer.append(
char(
'0' + (month % 10)));
600 rBuffer.append(
char(
'0' + ((day / 10) % 10)));
601 rBuffer.append(
char(
'0' + (day % 10)));
602 rBuffer.append(
char(
'0' + ((hours / 10) % 10)));
603 rBuffer.append(
char(
'0' + (hours % 10)));
604 rBuffer.append(
char(
'0' + ((minutes / 10) % 10)));
605 rBuffer.append(
char(
'0' + (minutes % 10)));
606 rBuffer.append(
char(
'0' + ((seconds / 10) % 10)));
607 rBuffer.append(
char(
'0' + (seconds % 10)));
623 rBuffer.append(
char(
'0' + ((tzDelta / 36000) % 10)));
624 rBuffer.append(
char(
'0' + ((tzDelta / 3600) % 10)));
626 rBuffer.append(
char(
'0' + ((tzDelta / 600) % 6)));
627 rBuffer.append(
char(
'0' + ((tzDelta / 60) % 10)));
635 m_pWriter( pWriter ),
636 m_nPageWidth( nPageWidth ),
637 m_nPageHeight( nPageHeight ),
639 m_eOrientation( eOrientation ),
641 m_nStreamLengthObject( 0 ),
642 m_nBeginStreamPos( 0 ),
652 m_nUserUnit = std::ceil(std::max(nPageWidth, nPageHeight) / 14400.0);
664 m_pWriter->emitComment(
"PDFWriterImpl::PDFPage::beginStream, +");
674 aLine.append(
" 0 obj\n<</Length " );
676 aLine.append(
" 0 R" );
678 aLine.append(
"/Filter/FlateDecode" );
679 aLine.append(
">>\nstream\n" );
680 if( !
m_pWriter->writeBuffer( aLine.getStr(), aLine.getLength() ) )
696 sal_uInt64 nEndStreamPos;
697 if (osl::File::E_None !=
m_pWriter->m_aFile.getPos(nEndStreamPos))
704 if( !
m_pWriter->writeBuffer(
"\nendstream\nendobj\n\n", 19 ) )
714 m_pWriter->writeBuffer( aLine.getStr(), aLine.getLength() );
726 aLine.append(
" 0 obj\n"
727 "<</Type/Page/Parent " );
728 aLine.append( nParentObject );
729 aLine.append(
" 0 R" );
730 aLine.append(
"/Resources " );
731 aLine.append(
m_pWriter->getResourceDictObj() );
732 aLine.append(
" 0 R" );
735 aLine.append(
"/MediaBox[0 0 " );
742 aLine.append(
"\n/UserUnit ");
754 aLine.append(
"/Annots[\n" );
755 for(
int i = 0; i < nAnnots; i++ )
758 aLine.append(
" 0 R" );
759 aLine.append( ((i+1)%15) ?
" " :
"\n" );
761 aLine.append(
"]\n" );
765 OStringBuffer aStructParents( 1024 );
766 aStructParents.append(
"[ " );
768 for(
int i = 0; i < nParents; i++ )
771 aStructParents.append(
" 0 R" );
772 aStructParents.append( ((i%10) == 9) ?
"\n" :
" " );
774 aStructParents.append(
"]" );
775 m_pWriter->m_aStructParentTree.push_back( aStructParents.makeStringAndClear() );
777 aLine.append(
"/StructParents " );
778 aLine.append( sal_Int32(
m_pWriter->m_aStructParentTree.size()-1) );
779 aLine.append(
"\n" );
784 aLine.append(
"/Trans<</D " );
785 appendDouble( static_cast<double>(
m_nTransTime)/1000.0, aLine, 3 );
786 aLine.append(
"\n" );
787 const char *pStyle =
nullptr, *pDm =
nullptr, *pM =
nullptr, *pDi =
nullptr;
791 pStyle =
"Split"; pDm =
"H"; pM =
"I";
break;
793 pStyle =
"Split"; pDm =
"H"; pM =
"O";
break;
795 pStyle =
"Split"; pDm =
"V"; pM =
"I";
break;
797 pStyle =
"Split"; pDm =
"V"; pM =
"O";
break;
799 pStyle =
"Blinds"; pDm =
"H";
break;
801 pStyle =
"Blinds"; pDm =
"V";
break;
803 pStyle =
"Box"; pM =
"I";
break;
805 pStyle =
"Box"; pM =
"O";
break;
807 pStyle =
"Wipe"; pDi =
"0";
break;
809 pStyle =
"Wipe"; pDi =
"90";
break;
811 pStyle =
"Wipe"; pDi =
"180";
break;
813 pStyle =
"Wipe"; pDi =
"270";
break;
815 pStyle =
"Dissolve";
break;
822 aLine.append(
"/S/" );
823 aLine.append( pStyle );
824 aLine.append(
"\n" );
828 aLine.append(
"/Dm/" );
830 aLine.append(
"\n" );
834 aLine.append(
"/M/" );
836 aLine.append(
"\n" );
840 aLine.append(
"/Di " );
842 aLine.append(
"\n" );
844 aLine.append(
">>\n" );
848 aLine.append(
"/Group<</S/Transparency/CS/DeviceRGB/I true>>" );
850 aLine.append(
"/Contents" );
852 if( nStreamObjects > 1 )
858 aLine.append(
" 0 R" );
860 if( nStreamObjects > 1 )
862 aLine.append(
">>\nendobj\n\n" );
863 return m_pWriter->writeBuffer( aLine.getStr(), aLine.getLength() );
868 Point aPoint( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
873 sal_Int32 nValue = aPoint.X();
875 appendFixedInt( nValue, rBuffer );
877 rBuffer.append(
' ' );
879 nValue = pointToPixel(
getHeight()) - aPoint.Y();
881 appendFixedInt( nValue, rBuffer );
886 double fValue = pixelToPoint(rPoint.
getX());
888 appendDouble( fValue, rBuffer, nLog10Divisor );
889 rBuffer.append(
' ' );
891 appendDouble( fValue, rBuffer, nLog10Divisor );
897 rBuffer.append(
' ' );
899 rBuffer.append(
' ' );
901 rBuffer.append(
" re" );
906 Point aLL = lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
911 Size aSize = lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
916 rRect.
SetRight( aLL.X() + aSize.Width() );
923 sal_uInt16 nPoints = rPoly.
GetSize();
927 sal_uInt32 nBufLen = rBuffer.getLength();
933 rBuffer.append(
" m\n" );
934 for( sal_uInt16 i = 1; i < nPoints; i++ )
936 if( pFlagArray && pFlagArray[i] == PolyFlags::Control && nPoints-i > 2 )
939 SAL_WARN_IF( pFlagArray[i+1] != PolyFlags::Control || pFlagArray[i+2] == PolyFlags::Control,
"vcl.pdfwriter",
"unexpected sequence of control points" );
941 rBuffer.append(
" " );
943 rBuffer.append(
" " );
945 rBuffer.append(
" c" );
952 rBuffer.append(
" l" );
954 if( (rBuffer.getLength() - nBufLen) > 65 )
956 rBuffer.append(
"\n" );
957 nBufLen = rBuffer.getLength();
960 rBuffer.append(
" " );
963 rBuffer.append(
"h\n" );
978 rBuffer.append(
' ' );
980 rBuffer.append(
' ' );
982 rBuffer.append(
" re\n" );
985 sal_uInt32 nPoints = aPoly.
count();
989 sal_uInt32 nBufLen = rBuffer.getLength();
992 rBuffer.append(
" m\n" );
993 for( sal_uInt32 i = 1; i <= nPoints; i++ )
995 if( i != nPoints || aPoly.
isClosed() )
998 sal_uInt32 nLastPoint = i-1;
1004 rBuffer.append(
' ' );
1006 rBuffer.append(
' ' );
1008 rBuffer.append(
" c" );
1013 rBuffer.append(
' ' );
1015 rBuffer.append(
" y" );
1020 rBuffer.append(
' ' );
1022 rBuffer.append(
" v" );
1027 rBuffer.append(
" l" );
1029 if( (rBuffer.getLength() - nBufLen) > 65 )
1031 rBuffer.append(
"\n" );
1032 nBufLen = rBuffer.getLength();
1035 rBuffer.append(
" " );
1038 rBuffer.append(
"h\n" );
1043 sal_uInt16 nPolygons = rPolyPoly.
Count();
1044 for( sal_uInt16
n = 0;
n < nPolygons;
n++ )
1050 for(
auto const& rPolygon : rPolyPoly)
1056 sal_Int32 nValue = nLength;
1059 rBuffer.append(
'-' );
1062 Size aSize( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
1065 Size( nValue, nValue ) ) );
1066 nValue = bVertical ? aSize.
Height() : aSize.
Width();
1068 *pOutLength = ((nLength < 0 ) ? -nValue : nValue);
1070 appendFixedInt( nValue, rBuffer );
1075 Size aSize( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
1078 Size( 1000, 1000 ) ) );
1079 fLength *= pixelToPoint(static_cast<double>(bVertical ? aSize.
Height() : aSize.
Width()) / 1000.0);
1080 appendDouble( fLength, rBuffer, nPrecision );
1085 if(
LineStyle::Dash == rInfo.GetStyle() && rInfo.GetDashLen() != rInfo.GetDotLen())
1089 if(2 * (rInfo.GetDashCount() + rInfo.GetDotCount()) > 10)
1101 if(css::drawing::LineCap_BUTT != rInfo.GetLineCap())
1109 rBuffer.append(
"[ " );
1110 if( rInfo.GetDashLen() == rInfo.GetDotLen() )
1113 rBuffer.append(
' ' );
1115 rBuffer.append(
' ' );
1119 for(
int n = 0;
n < rInfo.GetDashCount();
n++ )
1122 rBuffer.append(
' ' );
1124 rBuffer.append(
' ' );
1126 for(
int m = 0;
m < rInfo.GetDotCount();
m++ )
1129 rBuffer.append(
' ' );
1131 rBuffer.append(
' ' );
1134 rBuffer.append(
"] 0 d\n" );
1137 if( rInfo.GetWidth() > 1 )
1140 rBuffer.append(
" w\n" );
1142 else if( rInfo.GetWidth() == 0 )
1145 appendDouble( 72.0/
double(
m_pWriter->GetDPIX()), rBuffer );
1146 rBuffer.append(
" w\n" );
1159 rBuffer.append(
"0 " );
1161 rBuffer.append(
" m\n" );
1162 for( sal_Int32
n = 0;
n < nWidth; )
1166 rBuffer.append(
' ' );
1168 rBuffer.append(
' ' );
1171 rBuffer.append(
' ' );
1173 rBuffer.append(
" v " );
1178 rBuffer.append(
' ' );
1180 rBuffer.append(
' ' );
1183 rBuffer.append(
' ' );
1185 rBuffer.append(
" v\n" );
1188 rBuffer.append(
"S\n" );
1193 appendDouble(rMatrix.
get(0), rBuffer);
1194 rBuffer.append(
' ');
1195 appendDouble(rMatrix.
get(1), rBuffer);
1196 rBuffer.append(
' ');
1197 appendDouble(rMatrix.
get(2), rBuffer);
1198 rBuffer.append(
' ');
1199 appendDouble(rMatrix.
get(3), rBuffer);
1200 rBuffer.append(
' ');
1217 const css::uno::Reference< css::beans::XMaterialHolder >& xEnc,
1221 m_nCurrentStructElement( 0 ),
1222 m_bEmitStructure( true ),
1225 officecfg::Office::Common::VCL::PDFExportImageCacheSize::
get() ),
1226 m_nCurrentPage( -1 ),
1227 m_nCatalogObject(0),
1228 m_nSignatureObject( -1 ),
1229 m_nSignatureContentOffset( 0 ),
1230 m_nSignatureLastByteRangeNoOffset( 0 ),
1231 m_nResourceDict( -1 ),
1232 m_nFontDictObject( -1 ),
1237 m_aCipher( nullptr ),
1240 m_bEncryptThisStream( false ),
1241 m_nAccessPermissions(0),
1242 m_bIsPDF_A1( false ),
1243 m_bIsPDF_A2( false ),
1244 m_bIsPDF_UA( false ),
1245 m_bIsPDF_A3( false ),
1246 m_rOuterFace( i_rOuterFace )
1261 osl::File::RC aError =
m_aFile.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
1262 if (aError != osl::File::E_None)
1264 if (aError == osl::File::E_EXIST)
1266 aError =
m_aFile.open(osl_File_OpenFlag_Write);
1267 if (aError == osl::File::E_None)
1271 if (aError != osl::File::E_None)
1280 m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream );
1297 OSL_ENSURE(
false,
"encryption data failed sanity check, encryption disabled" );
1305 aBuffer.append(
"%PDF-" );
1317 aBuffer.append(
"\n%\303\244\303\274\303\266\303\237\n" );
1318 if( !
writeBuffer( aBuffer.getStr(), aBuffer.getLength() ) )
1370 std::vector< sal_uInt8 >
aId;
1381 TimeValue aTVal, aGMT;
1383 osl_getSystemTime(&aGMT);
1384 osl_getLocalTimeFromSystemTime(&aGMT, &aTVal);
1385 osl_getDateTimeFromTimeValue(&aTVal, &aDT);
1387 sal_Int32 nDelta = aTVal.Seconds-aGMT.Seconds;
1389 appendPdfTimeDate(aRet, aDT.Year, aDT.Month, aDT.Day, aDT.Hours, aDT.Minutes, aDT.Seconds, nDelta);
1392 return aRet.makeStringAndClear();
1397 const OString& i_rCString1,
1398 OString& o_rCString2
1401 o_rIdentifier.clear();
1404 OString aInfoValuesOut;
1405 OStringBuffer aID( 1024 );
1406 if( !i_rDocInfo.
Title.isEmpty() )
1408 if( !i_rDocInfo.
Author.isEmpty() )
1410 if( !i_rDocInfo.
Subject.isEmpty() )
1412 if( !i_rDocInfo.
Keywords.isEmpty() )
1414 if( !i_rDocInfo.
Creator.isEmpty() )
1416 if( !i_rDocInfo.
Producer.isEmpty() )
1419 TimeValue aTVal, aGMT;
1421 osl_getSystemTime( &aGMT );
1422 osl_getLocalTimeFromSystemTime( &aGMT, &aTVal );
1423 osl_getDateTimeFromTimeValue( &aTVal, &aDT );
1424 OStringBuffer aCreationMetaDateString(64);
1432 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Year/1000)%10)) );
1433 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Year/100)%10)) );
1434 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Year/10)%10)) );
1435 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Year)%10)) );
1436 aCreationMetaDateString.append(
"-" );
1437 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Month/10)%10)) );
1438 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Month)%10)) );
1439 aCreationMetaDateString.append(
"-" );
1440 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Day/10)%10)) );
1441 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Day)%10)) );
1442 aCreationMetaDateString.append(
"T" );
1443 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Hours/10)%10)) );
1444 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Hours)%10)) );
1445 aCreationMetaDateString.append(
":" );
1446 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Minutes/10)%10)) );
1447 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Minutes)%10)) );
1448 aCreationMetaDateString.append(
":" );
1449 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Seconds/10)%10)) );
1450 aCreationMetaDateString.append( static_cast<char>(
'0' + ((aDT.Seconds)%10)) );
1452 sal_uInt32 nDelta = 0;
1453 if( aGMT.Seconds > aTVal.Seconds )
1455 nDelta = aGMT.Seconds-aTVal.Seconds;
1456 aCreationMetaDateString.append(
"-" );
1458 else if( aGMT.Seconds < aTVal.Seconds )
1460 nDelta = aTVal.Seconds-aGMT.Seconds;
1461 aCreationMetaDateString.append(
"+" );
1465 aCreationMetaDateString.append(
"Z" );
1470 aCreationMetaDateString.append( static_cast<char>(
'0' + ((nDelta/36000)%10)) );
1471 aCreationMetaDateString.append( static_cast<char>(
'0' + ((nDelta/3600)%10)) );
1472 aCreationMetaDateString.append(
":" );
1473 aCreationMetaDateString.append( static_cast<char>(
'0' + ((nDelta/600)%6)) );
1474 aCreationMetaDateString.append( static_cast<char>(
'0' + ((nDelta/60)%10)) );
1476 aID.append( i_rCString1.getStr(), i_rCString1.getLength() );
1478 aInfoValuesOut = aID.makeStringAndClear();
1479 o_rCString2 = aCreationMetaDateString.makeStringAndClear();
1482 aDigest.
update(reinterpret_cast<unsigned char const*>(&aGMT),
sizeof(aGMT));
1483 aDigest.
update(reinterpret_cast<unsigned char const*>(aInfoValuesOut.getStr()), aInfoValuesOut.getLength());
1485 o_rIdentifier = aDigest.
finalize();
1495 rOutBuffer.append(
"<" );
1499 sal_Int32 nLen = rInString.getLength();
1503 sal_Int32 nChars = 2 + (nLen * 2);
1508 for(
int i = 0; i < nLen; i++ )
1511 *pCopy++ =
static_cast<sal_uInt8>( aUnChar >> 8 );
1512 *pCopy++ =
static_cast<sal_uInt8>( aUnChar & 255 );
1517 for(
int i = 0; i < nChars; i++)
1522 rOutBuffer.append(
">" );
1527 rOutBuffer.append(
"(" );
1528 sal_Int32 nChars = rInString.size();
1536 appendLiteralString( reinterpret_cast<char*>(
m_vEncryptionBuffer.data()), nChars, rOutBuffer );
1539 appendLiteralString( rInString.data(), nChars , rOutBuffer );
1540 rOutBuffer.append(
")" );
1546 sal_Int32 nLen = aBufferString.getLength();
1547 OStringBuffer
aBuf( nLen );
1548 const char* pT = aBufferString.getStr();
1550 for( sal_Int32 i = 0; i < nLen; i++, pT++ )
1552 if( (*pT & 0x80) == 0 )
1557 appendHex( *pT, aBuf );
1561 aBufferString = aBuf.makeStringAndClear();
1569 OString aLine = OString::Concat(
"% ") + pComment +
"\n";
1579 ZCodec aCodec( 0x4000, 0x4000 );
1582 aCodec.
Write( aStream, static_cast<const sal_uInt8*>(pStream->
GetData()), nEndPos );
1584 nEndPos = aStream.
Tell();
1599 m_pCodec = std::make_unique<ZCodec>( 0x4000, 0x4000 );
1630 pBuffer, sal::static_int_cast<std::size_t>(nBytes));
1634 sal_uInt64 nWritten;
1637 m_pCodec->Write( *
m_pMemStream, static_cast<const sal_uInt8*>(pBuffer), static_cast<sal_uLong>(nBytes) );
1649 pBuffer, static_cast<sal_Size>(nBytes),
1654 m_DocDigest.
update(static_cast<unsigned char const*>(pWriteBuffer), static_cast<sal_uInt32>(nBytes));
1656 if (
m_aFile.write(pWriteBuffer, nBytes, nWritten) != osl::File::E_None)
1659 if( nWritten != nBytes )
1666 return nWritten == nBytes;
1673 m_aPages.emplace_back(
this, nPageWidth, nPageHeight, eOrientation );
1675 sal_Int32 nUserUnit =
m_aPages.back().m_nUserUnit;
1679 Fraction(nUserUnit, pointToPixel(1)));
1686 OStringBuffer
aBuf( 16 );
1687 appendDouble( 72.0/
double(
GetDPIX()), aBuf );
1688 aBuf.append(
" w\n" );
1703 OSL_FAIL(
"redirection across pages !!!" );
1726 if( ! bitmap.m_aBitmap.IsEmpty() )
1734 if( jpeg.m_pStream )
1737 jpeg.m_pStream.reset();
1743 if( item.m_pContentStream )
1746 item.m_pContentStream.reset();
1763 sal_uInt64 nOffset = ~0U;
1764 osl::File::RC aError =
m_aFile.getPos(nOffset);
1765 SAL_WARN_IF( aError != osl::File::E_None,
"vcl.pdfwriter",
"could not register object" );
1766 if (aError != osl::File::E_None)
1772 return aError == osl::File::E_None;
1775 #define CHECK_RETURN( x ) if( !(x) ) return 0
1776 #define CHECK_RETURN2( x ) if( !(x) ) return
1782 OStringBuffer aLine( 1024 );
1784 aLine.append( nObject );
1785 aLine.append(
" 0 obj\n"
1788 for( sal_Int32
n = 0;
n < nTreeItems;
n++ )
1791 aLine.append(
' ' );
1793 aLine.append(
"\n" );
1795 aLine.append(
"]>>\nendobj\n\n" );
1804 static std::map< PDFWriter::StructAttribute, const char* > aAttributeStrings;
1806 if( aAttributeStrings.empty() )
1829 std::map< PDFWriter::StructAttribute, const char* >::const_iterator it =
1830 aAttributeStrings.find( eAttr );
1832 if( it == aAttributeStrings.end() )
1833 SAL_INFO(
"vcl.pdfwriter",
"invalid PDFWriter::StructAttribute " << eAttr);
1835 return it != aAttributeStrings.end() ? it->second :
"";
1840 static std::map< PDFWriter::StructAttributeValue, const char* > aValueStrings;
1842 if( aValueStrings.empty() )
1872 std::map< PDFWriter::StructAttributeValue, const char* >::const_iterator it =
1873 aValueStrings.find( eVal );
1875 if( it == aValueStrings.end() )
1876 SAL_INFO(
"vcl.pdfwriter",
"invalid PDFWriter::StructAttributeValue " << eVal);
1878 return it != aValueStrings.end() ? it->second :
"";
1883 o_rLine.append(
"/" );
1888 o_rLine.append(
"/" );
1894 o_rLine.append(
" " );
1896 appendFixedInt( i_rVal.
nValue, o_rLine );
1898 o_rLine.append( i_rVal.
nValue );
1900 o_rLine.append(
"\n" );
1906 OStringBuffer aLayout(256), aList(64), aTable(64);
1916 sal_Int32 nLink =
attribute.second.nValue;
1917 std::map< sal_Int32, sal_Int32 >::const_iterator link_it =
1920 nLink = link_it->second;
1921 if( nLink >= 0 && nLink < static_cast<sal_Int32>(
m_aLinks.size()) )
1924 OString aStructParentEntry =
1934 OString::number( nRefObject ) +
1936 "<</Type/OBJR/Obj " +
1937 OString::number(
m_aLinks[ nLink ].m_nObject ) +
1943 i_rEle.
m_aKids.emplace_back( nRefObject );
1947 OSL_FAIL(
"unresolved link id for Link structure" );
1948 SAL_INFO(
"vcl.pdfwriter",
"unresolved link id " << nLink <<
" for Link structure");
1951 OString aLine =
"unresolved link id " +
1952 OString::number( nLink ) +
1953 " for Link structure";
1963 aLayout.append(
"/BBox[" );
1965 aLayout.append(
" " );
1966 appendFixedInt( i_rEle.
m_aBBox.
Top(), aLayout );
1967 aLayout.append(
" " );
1969 aLayout.append(
" " );
1971 aLayout.append(
"]\n" );
1974 std::vector< sal_Int32 > aAttribObjects;
1975 if( !aLayout.isEmpty() )
1980 OStringBuffer aObj( 64 );
1981 aObj.append( aAttribObjects.back() );
1982 aObj.append(
" 0 obj\n"
1984 aLayout.append(
">>\nendobj\n\n" );
1986 writeBuffer( aLayout.getStr(), aLayout.getLength() );
1989 if( !aList.isEmpty() )
1994 OStringBuffer aObj( 64 );
1995 aObj.append( aAttribObjects.back() );
1996 aObj.append(
" 0 obj\n"
1998 aList.append(
">>\nendobj\n\n" );
2003 if( !aTable.isEmpty() )
2008 OStringBuffer aObj( 64 );
2009 aObj.append( aAttribObjects.back() );
2010 aObj.append(
" 0 obj\n"
2012 aTable.append(
">>\nendobj\n\n" );
2014 writeBuffer( aTable.getStr(), aTable.getLength() );
2018 OStringBuffer aRet( 64 );
2019 if( aAttribObjects.size() > 1 )
2020 aRet.append(
" [" );
2021 for (
auto const& attrib : aAttribObjects)
2024 aRet.append( attrib );
2025 aRet.append(
" 0 R" );
2027 if( aAttribObjects.size() > 1 )
2028 aRet.append(
" ]" );
2029 return aRet.makeStringAndClear();
2043 if( child > 0 && child < sal_Int32(
m_aStructure.size()) )
2052 OSL_FAIL(
"PDFWriterImpl::emitStructure: invalid child structure element" );
2053 SAL_INFO(
"vcl.pdfwriter",
"PDFWriterImpl::emitStructure: invalid child structure element with id " << child);
2059 OSL_FAIL(
"PDFWriterImpl::emitStructure: invalid child structure id" );
2060 SAL_INFO(
"vcl.pdfwriter",
"PDFWriterImpl::emitStructure: invalid child structure id " << child);
2064 OStringBuffer aLine( 512 );
2066 aLine.append(
" 0 obj\n"
2068 sal_Int32 nParentTree = -1;
2073 aLine.append(
"/StructTreeRoot\n" );
2074 aLine.append(
"/ParentTree " );
2075 aLine.append( nParentTree );
2076 aLine.append(
" 0 R\n" );
2079 aLine.append(
"/RoleMap<<" );
2082 aLine.append(
'/' );
2083 aLine.append(role.first);
2084 aLine.append(
'/' );
2085 aLine.append( role.second );
2086 aLine.append(
'\n' );
2088 aLine.append(
">>\n" );
2093 aLine.append(
"/StructElem\n"
2102 aLine.append(
" 0 R\n"
2105 aLine.append(
" 0 R\n" );
2108 aLine.append(
"/ActualText" );
2110 aLine.append(
"\n" );
2114 aLine.append(
"/Alt" );
2116 aLine.append(
"\n" );
2122 if( !aAttribs.isEmpty() )
2124 aLine.append(
"/A" );
2125 aLine.append( aAttribs );
2126 aLine.append(
"\n" );
2129 if( !rEle.
m_aLocale.Language.isEmpty() )
2138 OUString aLanguage, aScript, aCountry;
2140 if (!aLanguage.isEmpty())
2142 OUStringBuffer aLocBuf( 16 );
2143 aLocBuf.append( aLanguage );
2144 if( !aCountry.isEmpty() )
2146 aLocBuf.append(
'-' );
2147 aLocBuf.append( aCountry );
2149 aLine.append(
"/Lang" );
2151 aLine.append(
"\n" );
2157 aLine.append(
"/K[" );
2158 for (
auto const& kid : rEle.
m_aKids)
2160 if( kid.nMCID == -1 )
2162 aLine.append( kid.nObject );
2163 aLine.append(
" 0 R" );
2164 aLine.append( ( (i & 15) == 15 ) ?
"\n" :
" " );
2170 aLine.append( kid.nMCID );
2171 aLine.append(
" " );
2175 aLine.append(
"<</Type/MCR/Pg " );
2176 aLine.append( kid.nObject );
2177 aLine.append(
" 0 R /MCID " );
2178 aLine.append( kid.nMCID );
2179 aLine.append(
">>\n" );
2184 aLine.append(
"]\n" );
2186 aLine.append(
">>\nendobj\n\n" );
2207 OStringBuffer aTilingObj( 1024 );
2211 SAL_WARN_IF( !tiling.m_pTilingStream,
"vcl.pdfwriter",
"tiling without stream" );
2212 if( ! tiling.m_pTilingStream )
2215 aTilingObj.setLength( 0 );
2222 sal_Int32 nX =
static_cast<sal_Int32
>(tiling.m_aRectangle.Left());
2223 sal_Int32 nY =
static_cast<sal_Int32
>(tiling.m_aRectangle.Top());
2224 sal_Int32 nW =
static_cast<sal_Int32
>(tiling.m_aRectangle.GetWidth());
2225 sal_Int32 nH =
static_cast<sal_Int32
>(tiling.m_aRectangle.GetHeight());
2226 if( tiling.m_aCellSize.Width() == 0 )
2227 tiling.m_aCellSize.setWidth( nW );
2228 if( tiling.m_aCellSize.Height() == 0 )
2229 tiling.m_aCellSize.setHeight( nH );
2232 sal_uInt64
const nTilingStreamSize = tiling.m_pTilingStream->TellEnd();
2236 aTilingObj.append( tiling.m_nObject );
2237 aTilingObj.append(
" 0 obj\n" );
2238 aTilingObj.append(
"<</Type/Pattern/PatternType 1\n"
2242 appendFixedInt( nX, aTilingObj );
2243 aTilingObj.append(
' ' );
2244 appendFixedInt( nY, aTilingObj );
2245 aTilingObj.append(
' ' );
2246 appendFixedInt( nX+nW, aTilingObj );
2247 aTilingObj.append(
' ' );
2248 appendFixedInt( nY+nH, aTilingObj );
2249 aTilingObj.append(
"]\n"
2251 appendFixedInt( tiling.m_aCellSize.Width(), aTilingObj );
2252 aTilingObj.append(
"\n"
2254 appendFixedInt( tiling.m_aCellSize.Height(), aTilingObj );
2255 aTilingObj.append(
"\n" );
2256 if( tiling.m_aTransform.matrix[0] != 1.0 ||
2257 tiling.m_aTransform.matrix[1] != 0.0 ||
2258 tiling.m_aTransform.matrix[3] != 0.0 ||
2259 tiling.m_aTransform.matrix[4] != 1.0 ||
2260 tiling.m_aTransform.matrix[2] != 0.0 ||
2261 tiling.m_aTransform.matrix[5] != 0.0 )
2263 aTilingObj.append(
"/Matrix [" );
2265 appendDouble( tiling.m_aTransform.matrix[0], aTilingObj );
2266 aTilingObj.append(
' ' );
2267 appendDouble( tiling.m_aTransform.matrix[1], aTilingObj );
2268 aTilingObj.append(
' ' );
2269 appendDouble( tiling.m_aTransform.matrix[3], aTilingObj );
2270 aTilingObj.append(
' ' );
2271 appendDouble( tiling.m_aTransform.matrix[4], aTilingObj );
2272 aTilingObj.append(
' ' );
2273 appendDouble( tiling.m_aTransform.matrix[2], aTilingObj );
2274 aTilingObj.append(
' ' );
2275 appendDouble( tiling.m_aTransform.matrix[5], aTilingObj );
2276 aTilingObj.append(
"]\n" );
2278 aTilingObj.append(
"/Resources" );
2281 aTilingObj.append(
"/Filter/FlateDecode" );
2282 aTilingObj.append(
"/Length " );
2283 aTilingObj.append( static_cast<sal_Int32>(nTilingStreamSize) );
2284 aTilingObj.append(
">>\nstream\n" );
2286 if ( !
writeBuffer( aTilingObj.getStr(), aTilingObj.getLength() ) )
return false;
2288 bool written =
writeBuffer( tiling.m_pTilingStream->GetData(), nTilingStreamSize );
2289 tiling.m_pTilingStream.reset();
2293 aTilingObj.setLength( 0 );
2294 aTilingObj.append(
"\nendstream\nendobj\n\n" );
2295 if ( !
writeBuffer( aTilingObj.getStr(), aTilingObj.getLength() ) )
return false;
2306 OStringBuffer aLine( 1024 );
2308 if( nFontObject <= 0 )
2311 aLine.append( nFontObject );
2312 aLine.append(
" 0 obj\n"
2313 "<</Type/Font/Subtype/Type1/BaseFont/" );
2314 appendName( rBuildinFont.
m_pPSName, aLine );
2315 aLine.append(
"\n" );
2316 if( rBuildinFont.
m_eCharSet == RTL_TEXTENCODING_MS_1252 )
2317 aLine.append(
"/Encoding/WinAnsiEncoding\n" );
2318 aLine.append(
">>\nendobj\n\n" );
2325 std::map< sal_Int32, sal_Int32 > aRet;
2327 sal_Int32 nFontDescriptor = 0;
2328 OString aSubType(
"/Type1" );
2336 sal_Int32 pWidths[256] = {};
2342 aSubType = OString(
"/TrueType" );
2343 std::vector< sal_Int32 > aGlyphWidths;
2345 pGraphics->
GetGlyphWidths( pFont,
false, aGlyphWidths, aUnicodeMap );
2348 osl_createTempFile(
nullptr,
nullptr, &aTmpName.pData );
2351 sal_Int32 pDuWidths[ 256 ] = {};
2353 for(
sal_Ucs c = 32; c < 256; c++ )
2357 if( aUnicodeMap.find( c ) != aUnicodeMap.end() )
2358 pWidths[ c ] = aGlyphWidths[ aUnicodeMap[ c ] ];
2364 pGraphics->
CreateFontSubset( aTmpName, pFont, aGlyphIds, pEncoding, pDuWidths, 256, aInfo );
2365 osl_removeFile( aTmpName.pData );
2369 if( nFontDescriptor )
2375 OStringBuffer aLine( 1024 );
2376 aLine.append( nObject );
2377 aLine.append(
" 0 obj\n"
2378 "<</Type/Font/Subtype" );
2379 aLine.append( aSubType );
2380 aLine.append(
"/BaseFont/" );
2382 aLine.append(
"\n" );
2384 aLine.append(
"/Encoding/WinAnsiEncoding\n" );
2385 aLine.append(
"/FirstChar 32 /LastChar 255\n"
2387 for(
int i = 32; i < 256; i++ )
2389 aLine.append( pWidths[i] );
2390 aLine.append( ((i&15) == 15) ?
"\n" :
" " );
2393 "/FontDescriptor " );
2394 aLine.append( nFontDescriptor );
2395 aLine.append(
" 0 R>>\n"
2408 ThreeInts& rSegmentLengths )
2410 if( !pFontBytes || (nByteLen < 0) )
2412 const unsigned char* pPtr = pFontBytes;
2413 const unsigned char* pEnd = pFontBytes + nByteLen;
2415 for(
int & rSegmentLength : rSegmentLengths) {
2417 if( pPtr+6 >= pEnd )
2419 if( (pPtr[0] != 0x80) || (pPtr[1] >= 0x03) )
2421 const int nLen = (pPtr[5]<<24) + (pPtr[4]<<16) + (pPtr[3]<<8) + pPtr[2];
2424 rSegmentLength = nLen;
2429 if( pPtr+2 >= pEnd )
2431 if( (pPtr[0] != 0x80) || (pPtr[1] != 0x03) )
2437 static void appendSubsetName(
int nSubsetID, std::u16string_view rPSName, OStringBuffer& rBuffer )
2441 for(
int i = 0; i < 6; i++ )
2443 int nOffset = nSubsetID % 26;
2445 rBuffer.append( static_cast<char>(
'A'+nOffset) );
2447 rBuffer.append(
'+' );
2449 appendName( rPSName, rBuffer );
2454 const sal_Int32* pCodeUnitsPerGlyph,
2455 const sal_Int32* pEncToUnicodeIndex,
2459 for (
int n = 0;
n < nGlyphs; ++
n)
2460 if( pCodeUnits[pEncToUnicodeIndex[
n]] && pCodeUnitsPerGlyph[
n] )
2469 OStringBuffer aContents( 1024 );
2471 "/CIDInit/ProcSet findresource begin\n"
2474 "/CIDSystemInfo<<\n"
2475 "/Registry (Adobe)\n"
2479 "/CMapName/Adobe-Identity-UCS def\n"
2481 "1 begincodespacerange\n"
2483 "endcodespacerange\n"
2486 for (
int n = 0; n < nGlyphs; ++n)
2488 if( pCodeUnits[pEncToUnicodeIndex[n]] && pCodeUnitsPerGlyph[n] )
2490 if( (nCount % 100) == 0 )
2493 aContents.append(
"endbfchar\n" );
2494 aContents.append( static_cast<sal_Int32>(std::min(nMapped-nCount, 100)) );
2495 aContents.append(
" beginbfchar\n" );
2497 aContents.append(
'<' );
2498 appendHex( static_cast<sal_Int8>(pEncoding[n]), aContents );
2499 aContents.append(
"> <" );
2501 sal_Int32
nIndex = pEncToUnicodeIndex[n];
2502 for( sal_Int32 j = 0; j < pCodeUnitsPerGlyph[n]; j++ )
2504 appendHex( static_cast<sal_Int8>(pCodeUnits[nIndex + j] / 256), aContents );
2505 appendHex( static_cast<sal_Int8>(pCodeUnits[nIndex + j] & 255), aContents );
2507 aContents.append(
">\n" );
2511 aContents.append(
"endbfchar\n"
2513 "CMapName currentdict /CMap defineresource pop\n"
2519 ZCodec aCodec( 0x4000, 0x4000 );
2521 aCodec.
Write( aStream, reinterpret_cast<const sal_uInt8*>(aContents.getStr()), aContents.getLength() );
2527 emitComment(
"PDFWriterImpl::createToUnicodeCMap" );
2529 OStringBuffer aLine( 40 );
2531 aLine.append( nStream );
2532 aLine.append(
" 0 obj\n<</Length " );
2536 nLen =
static_cast<sal_Int32
>(aStream.
Tell());
2538 aLine.append( nLen );
2539 aLine.append(
"/Filter/FlateDecode" );
2542 aLine.append( aContents.getLength() );
2543 aLine.append(
">>\nstream\n" );
2555 aLine.setLength( 0 );
2556 aLine.append(
"\nendstream\n"
2564 OStringBuffer aLine( 1024 );
2568 sal_Int32 nFontFlags = (1<<2);
2570 nFontFlags |= (1 << 6);
2574 nFontFlags |= (1 << 3);
2576 nFontFlags |= (1 << 1);
2580 aLine.setLength( 0 );
2581 aLine.append( nFontDescriptor );
2582 aLine.append(
" 0 obj\n"
2583 "<</Type/FontDescriptor/FontName/" );
2587 aLine.append( nFontFlags );
2592 aLine.append(
' ' );
2594 aLine.append(
' ' );
2596 aLine.append(
' ' );
2598 aLine.append(
"]/ItalicAngle " );
2600 aLine.append(
"-30" );
2602 aLine.append(
"0" );
2605 aLine.append( static_cast<sal_Int32>(rInfo.
m_nAscent) );
2608 aLine.append( static_cast<sal_Int32>(-rInfo.
m_nDescent) );
2611 aLine.append( static_cast<sal_Int32>(rInfo.
m_nCapHeight) );
2618 aLine.append(
"/FontFile" );
2622 aLine.append(
'2' );
2629 OSL_FAIL(
"unknown fonttype in PDF font descriptor" );
2632 aLine.append(
' ' );
2633 aLine.append( nFontStream );
2634 aLine.append(
" 0 R\n" );
2636 aLine.append(
">>\n"
2640 return nFontDescriptor;
2648 rDict.append(
' ' );
2649 rDict.append( item.second );
2650 rDict.append(
" 0 R" );
2661 OStringBuffer aLine( 1024 );
2663 std::map< sal_Int32, sal_Int32 > aFontIDToObject;
2666 osl_createTempFile(
nullptr,
nullptr, &aTmpName.pData );
2669 for (
auto & s_subset :subset.second.m_aSubsets)
2672 sal_Int32 pWidths[ 256 ];
2674 sal_Int32 pEncToUnicodeIndex[ 256 ] = {};
2675 sal_Int32 pCodeUnitsPerGlyph[ 256 ] = {};
2676 std::vector<sal_Ucs> aCodeUnits;
2677 aCodeUnits.reserve( 256 );
2680 sal_Int32 nToUnicodeStream = 0;
2682 for (
auto const& item : s_subset.m_aMapping)
2684 sal_uInt8 nEnc = item.second.getGlyphId();
2686 SAL_WARN_IF( aGlyphIds[nEnc] != 0 || pEncoding[nEnc] != 0,
"vcl.pdfwriter",
"duplicate glyph" );
2687 SAL_WARN_IF( nEnc > s_subset.m_aMapping.size(),
"vcl.pdfwriter",
"invalid glyph encoding" );
2689 aGlyphIds[ nEnc ] = item.first;
2690 pEncoding[ nEnc ] = nEnc;
2691 pEncToUnicodeIndex[ nEnc ] =
static_cast<sal_Int32
>(aCodeUnits.size());
2692 pCodeUnitsPerGlyph[ nEnc ] = item.second.countCodes();
2693 for( sal_Int32
n = 0;
n < pCodeUnitsPerGlyph[ nEnc ];
n++ )
2694 aCodeUnits.push_back( item.second.getCode(
n ) );
2695 if( item.second.getCode(0) )
2696 nToUnicodeStream = 1;
2701 OSL_FAIL(
"too many glyphs for subset" );
2705 if( pGraphics->
CreateFontSubset( aTmpName, subset.first, aGlyphIds, pEncoding, pWidths, nGlyphs, aSubsetInfo ) )
2708 osl::File aFontFile(aTmpName);
2709 if (osl::File::E_None != aFontFile.open(osl_File_OpenFlag_Read))
return false;
2711 sal_uInt64 nLength1;
2712 if ( osl::File::E_None != aFontFile.setPos(osl_Pos_End, 0) )
return false;
2713 if ( osl::File::E_None != aFontFile.getPos(nLength1) )
return false;
2714 if ( osl::File::E_None != aFontFile.setPos(osl_Pos_Absolut, 0) )
return false;
2723 aLine.setLength( 0 );
2724 aLine.append( nFontStream );
2725 aLine.append(
" 0 obj\n"
2727 aLine.append( nStreamLengthObject );
2729 aLine.append(
" 0 R"
2730 "/Filter/FlateDecode"
2733 aLine.append(
" 0 R"
2736 sal_uInt64 nStartPos = 0;
2739 aLine.append( static_cast<sal_Int32>(nLength1) );
2741 aLine.append(
">>\n"
2743 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return false;
2744 if ( osl::File::E_None !=
m_aFile.getPos(nStartPos) )
return false;
2754 if ( osl::File::E_None != aFontFile.read(buf,
sizeof(buf), nRead) )
return false;
2756 if ( osl::File::E_None != aFontFile.isEndOfFile(&bEOF) )
return false;
2762 OSL_FAIL(
"PDFWriterImpl does not support CFF-font subsets yet!" );
2766 std::unique_ptr<unsigned char[]> xBuffer(
new unsigned char[nLength1]);
2768 sal_uInt64 nBytesRead = 0;
2769 if ( osl::File::E_None != aFontFile.read(xBuffer.get(), nLength1, nBytesRead) )
return false;
2770 SAL_WARN_IF( nBytesRead!=nLength1,
"vcl.pdfwriter",
"PDF-FontSubset read incomplete!" );
2771 if ( osl::File::E_None != aFontFile.setPos(osl_Pos_Absolut, 0) )
return false;
2773 ThreeInts aSegmentLengths = {0,0,0};
2777 aLine.append( static_cast<sal_Int32>(aSegmentLengths[0]) );
2778 aLine.append(
"/Length2 " );
2779 aLine.append( static_cast<sal_Int32>(aSegmentLengths[1]) );
2780 aLine.append(
"/Length3 " );
2781 aLine.append( static_cast<sal_Int32>(aSegmentLengths[2]) );
2783 aLine.append(
">>\n"
2785 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return false;
2786 if ( osl::File::E_None !=
m_aFile.getPos(nStartPos) )
return false;
2791 if ( !
writeBuffer( &xBuffer[6], aSegmentLengths[0] ) )
return false;
2792 if ( !
writeBuffer( &xBuffer[12] + aSegmentLengths[0], aSegmentLengths[1] ) )
return false;
2793 if ( !
writeBuffer( &xBuffer[18] + aSegmentLengths[0] + aSegmentLengths[1], aSegmentLengths[2] ) )
return false;
2797 SAL_INFO(
"vcl.pdfwriter",
"PDF: CreateFontSubset result in not yet supported format=" << static_cast<int>(aSubsetInfo.
m_nFontType));
2798 aLine.append(
"0 >>\nstream\n" );
2806 sal_uInt64 nEndPos = 0;
2807 if ( osl::File::E_None !=
m_aFile.getPos(nEndPos) )
return false;
2809 aLine.setLength( 0 );
2810 aLine.append(
"\nendstream\nendobj\n\n" );
2811 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return false;
2814 if ( !
updateObject( nStreamLengthObject ) )
return false;
2815 aLine.setLength( 0 );
2816 aLine.append( nStreamLengthObject );
2817 aLine.append(
" 0 obj\n" );
2818 aLine.append( static_cast<sal_Int64>(nEndPos-nStartPos) );
2819 aLine.append(
"\nendobj\n\n" );
2820 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return false;
2823 sal_Int32 nFontDescriptor =
emitFontDescriptor( subset.first, aSubsetInfo, s_subset.m_nFontID, nFontStream );
2825 if( nToUnicodeStream )
2826 nToUnicodeStream =
createToUnicodeCMap( pEncoding, aCodeUnits.data(), pCodeUnitsPerGlyph, pEncToUnicodeIndex, nGlyphs );
2830 aLine.setLength( 0 );
2831 aLine.append( nFontObject );
2833 aLine.append(
" 0 obj\n" );
2835 "<</Type/Font/Subtype/Type1/BaseFont/" :
2836 "<</Type/Font/Subtype/TrueType/BaseFont/" );
2841 aLine.append( static_cast<sal_Int32>(nGlyphs-1) );
2844 for(
int i = 0; i < nGlyphs; i++ )
2846 aLine.append( pWidths[ i ] );
2847 aLine.append( ((i & 15) == 15) ?
"\n" :
" " );
2850 "/FontDescriptor " );
2851 aLine.append( nFontDescriptor );
2852 aLine.append(
" 0 R\n" );
2853 if( nToUnicodeStream )
2855 aLine.append(
"/ToUnicode " );
2856 aLine.append( nToUnicodeStream );
2857 aLine.append(
" 0 R\n" );
2859 aLine.append(
">>\n"
2861 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return false;
2863 aFontIDToObject[ s_subset.m_nFontID ] = nFontObject;
2868 OStringBuffer aErrorComment( 256 );
2869 aErrorComment.append(
"CreateFontSubset failed for font \"" );
2871 aErrorComment.append(
'\"' );
2873 aErrorComment.append(
" italic" );
2875 aErrorComment.append(
" oblique" );
2876 aErrorComment.append(
" weight=" );
2877 aErrorComment.append( sal_Int32(pFont->
GetWeight()) );
2882 osl_removeFile( aTmpName.pData );
2887 std::map< sal_Int32, sal_Int32 > aObjects =
emitSystemFont( systemFont.first, systemFont.second );
2888 for (
auto const& item : aObjects)
2890 if ( !item.second )
return false;
2891 aFontIDToObject[ item.first ] = item.second;
2895 OStringBuffer aFontDict( 1024 );
2897 aFontDict.append(
" 0 obj\n"
2900 for (
auto const& itemMap : aFontIDToObject)
2902 aFontDict.append(
"/F" );
2903 aFontDict.append( itemMap.first );
2904 aFontDict.append(
' ' );
2905 aFontDict.append( itemMap.second );
2906 aFontDict.append(
" 0 R" );
2907 if( ((++ni) & 7) == 0 )
2908 aFontDict.append(
'\n' );
2918 aFontDict.append(
"\n>>\nendobj\n\n" );
2921 if ( !
writeBuffer( aFontDict.getStr(), aFontDict.getLength() ) )
return false;
2938 OStringBuffer aLine( 512 );
2941 aLine.setLength( 0 );
2942 aLine.append( nResourceDict );
2943 aLine.append(
" 0 obj\n" );
2945 aLine.append(
"endobj\n\n" );
2947 return nResourceDict;
2951 sal_Int32 nItemLevel,
2952 sal_Int32 nCurrentItemId )
2969 for( sal_Int32 i = 0; i < nChildren; i++ )
2971 rCounts[nCurrentItemId] = nCount;
2982 rCounts[ nCurrentItemId ] = -sal_Int32(rItem.
m_aChildren.size());
2983 for( sal_Int32 i = 0; i < nChildren; i++ )
3000 for( i = 0; i < nItems; ++i )
3004 for( i = 0; i < nItems; ++i )
3011 for(
int n = 0;
n < nChildren; ++
n )
3024 std::vector< sal_Int32 > aCounts( nItems );
3028 for( i = 0; i < nItems; ++i )
3031 OStringBuffer aLine( 1024 );
3035 aLine.append(
" 0 obj\n" );
3036 aLine.append(
"<<" );
3038 if( i > 0 || aCounts[0] > 0 )
3040 aLine.append(
"/Count " );
3041 aLine.append( aCounts[i] );
3046 aLine.append(
"/First " );
3048 aLine.append(
" 0 R/Last " );
3050 aLine.append(
" 0 R\n" );
3055 aLine.append(
"/Title" );
3057 aLine.append(
"\n" );
3061 aLine.append(
"/Dest" );
3064 aLine.append(
"/Parent " );
3066 aLine.append(
" 0 R" );
3069 aLine.append(
"/Prev " );
3071 aLine.append(
" 0 R" );
3075 aLine.append(
"/Next " );
3077 aLine.append(
" 0 R" );
3080 aLine.append(
">>\nendobj\n\n" );
3088 #define CHECK_RETURN( x ) if( !x ) return false
3092 if( nDestID < 0 || nDestID >= static_cast<sal_Int32>(
m_aDests.size()) )
3094 SAL_INFO(
"vcl.pdfwriter",
"ERROR: invalid dest " << static_cast<int>(nDestID) <<
" requested");
3101 rBuffer.append(
'[' );
3103 rBuffer.append(
" 0 R" );
3109 rBuffer.append(
"/XYZ " );
3111 rBuffer.append(
' ' );
3113 rBuffer.append(
" 0" );
3116 rBuffer.append(
"/FitR " );
3118 rBuffer.append(
' ' );
3119 appendFixedInt( rDest.
m_aRect.
Top(), rBuffer );
3120 rBuffer.append(
' ' );
3122 rBuffer.append(
' ' );
3126 rBuffer.append(
']' );
3134 for (
int i = 0; i < nAnnots; i++)
3138 OStringBuffer aLine;
3139 bool bEmbed =
false;
3151 aLine.append(
" 0 obj\n");
3152 aLine.append(
"<< /Type /EmbeddedFile /Length ");
3153 aLine.append(static_cast<sal_Int64>(aMemoryStream.
GetSize()));
3154 aLine.append(
" >>\nstream\n");
3160 aLine.append(
"\nendstream\nendobj\n\n");
3170 aLine.append(
" 0 obj\n");
3171 aLine.append(
"<</Type/Annot");
3172 aLine.append(
"/Subtype/Screen/Rect[");
3175 appendFixedInt(rScreen.
m_aRect.
Top(), aLine);
3183 aLine.append(
"/A<</Type/Action /S/Rendition /AN ");
3185 aLine.append(
" 0 R ");
3188 aLine.append(
"/R<</Type/Rendition /S/MR ");
3191 aLine.append(
"/C<</Type/MediaClip /S/MCD ");
3194 aLine.append(
"/D << /Type /Filespec /F (<embedded file>) /EF << /F ");
3196 aLine.append(
" 0 R >> >>");
3201 aLine.append(
"/D << /Type /Filespec /FS /URL /F ");
3203 aLine.append(
" >>");
3206 aLine.append(
"/P <</TF (TEMPACCESS)>>");
3208 aLine.append(
"/CT (video/mp4)");
3212 aLine.append(
"/P<</BE<</C true >>>>");
3216 aLine.append(
"/OP 0 >>");
3219 aLine.append(
"/P ");
3221 aLine.append(
" 0 R\n>>\nendobj\n\n");
3230 MARK(
"PDFWriterImpl::emitLinkAnnotations");
3232 for(
int i = 0; i < nAnnots; i++ )
3238 OStringBuffer aLine( 1024 );
3240 aLine.append(
" 0 obj\n" );
3243 aLine.append(
"<</Type/Annot" );
3245 aLine.append(
"/F 4" );
3246 aLine.append(
"/Subtype/Link/Border[0 0 0]/Rect[" );
3249 aLine.append(
' ' );
3250 appendFixedInt( rLink.
m_aRect.
Top(), aLine );
3251 aLine.append(
' ' );
3253 aLine.append(
' ' );
3255 aLine.append(
"]" );
3258 aLine.append(
"/Dest" );
3289 bool bSetGoToRMode =
false;
3290 bool bTargetHasPDFExtension =
false;
3292 bool bIsUNCPath =
false;
3297 if( eTargetProtocol == INetProtocol::NotValid )
3299 if( url.getLength() > 4 && url.startsWith(
"\\\\\\\\"))
3309 aTargetURL = aNewBase;
3324 if( !aFileExtension.isEmpty() )
3328 bool bChangeFileExtensionToPDF =
false;
3330 if( aFileExtension.equalsIgnoreAsciiCase(
"odm" ) )
3331 bChangeFileExtensionToPDF =
true;
3332 if( aFileExtension.equalsIgnoreAsciiCase(
"odt" ) )
3333 bChangeFileExtensionToPDF =
true;
3334 else if( aFileExtension.equalsIgnoreAsciiCase(
"odp" ) )
3335 bChangeFileExtensionToPDF =
true;
3336 else if( aFileExtension.equalsIgnoreAsciiCase(
"odg" ) )
3337 bChangeFileExtensionToPDF =
true;
3338 else if( aFileExtension.equalsIgnoreAsciiCase(
"ods" ) )
3339 bChangeFileExtensionToPDF =
true;
3340 if( bChangeFileExtensionToPDF )
3344 bTargetHasPDFExtension = aTargetURL.
GetFileExtension().equalsIgnoreAsciiCase(
"pdf" );
3346 bSetGoToRMode =
true;
3351 aLine.append(
"/A<</Type/Action/S");
3354 aLine.append(
"/Launch/Win<</F" );
3357 aLine.append(
">>" );
3361 bool bSetRelative =
false;
3362 bool bFileSpec =
false;
3364 if(
m_aContext.
RelFsys && eBaseProtocol == eTargetProtocol && eTargetProtocol == INetProtocol::File )
3365 bSetRelative =
true;
3368 if( !bSetGoToRMode )
3375 aLine.append(
"/URI/URI" );
3385 if( (!aFragment.isEmpty() && !bTargetHasPDFExtension) ||
3386 eTargetProtocol != INetProtocol::File )
3388 aLine.append(
"/URI/URI" );
3392 aLine.append(
"/Launch/F" );
3404 aLine.append(
"/GoToR");
3409 aURLNoMark, rLink.
m_nObject, aLine, osl_getThreadTextEncoding() );
3410 if( !aFragment.isEmpty() )
3412 aLine.append(
"/D/");
3413 appendDestinationName( aFragment , aLine );
3421 bTargetHasPDFExtension && !aFragment.isEmpty() )
3423 OStringBuffer aLineLoc( 1024 );
3424 appendDestinationName( aFragment , aLineLoc );
3426 aTargetURL.
SetMark( OStringToOUString(aLineLoc.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US) );
3433 aURL , rLink.
m_nObject, aLine, osl_getThreadTextEncoding() );
3436 aLine.append(
">>\n" );
3440 aLine.append(
"/StructParent " );
3443 aLine.append(
">>\nendobj\n\n" );
3453 void appendAnnotationRect(
tools::Rectangle const & rRectangle, OStringBuffer & aLine)
3455 aLine.append(
"/Rect[");
3456 appendFixedInt(rRectangle.
Left(), aLine);
3458 appendFixedInt(rRectangle.
Top(), aLine);
3460 appendFixedInt(rRectangle.
Right(), aLine);
3462 appendFixedInt(rRectangle.
Bottom(), aLine);
3466 void appendObjectID(sal_Int32 nObjectID, OStringBuffer & aLine)
3468 aLine.append(nObjectID);
3469 aLine.append(
" 0 obj\n");
3472 void appendObjectReference(sal_Int32 nObjectID, OStringBuffer & aLine)
3474 aLine.append(nObjectID);
3475 aLine.append(
" 0 R ");
3484 aLine.append(
"<</Type /Annot /Subtype /Text ");
3489 aLine.append(
"/F 4 ");
3491 appendAnnotationRect(rNote.
m_aRect, aLine);
3493 aLine.append(
"/Popup ");
3498 aLine.append(
"/M (");
3499 appendPdfTimeDate(aLine, rDateTime.Year, rDateTime.Month, rDateTime.Day, rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds, 0);
3503 aLine.append(
"/Contents ");
3510 aLine.append(
"/T ");
3514 aLine.append(
">>\n");
3515 aLine.append(
"endobj\n\n");
3520 appendObjectID(rPopUp.
m_nObject, aLine);
3521 aLine.append(
"<</Type /Annot /Subtype /Popup ");
3522 aLine.append(
"/Parent ");
3524 aLine.append(
">>\n");
3525 aLine.append(
"endobj\n\n");
3532 for(
int i = 0; i < nAnnots; i++ )
3541 OStringBuffer aLine(1024);
3545 if (!
writeBuffer(aLine.getStr(), aLine.getLength()))
3554 OStringBuffer aLine(1024);
3558 if (!
writeBuffer(aLine.getStr(), aLine.getLength()))
3567 bool bAdjustSize =
false;
3569 Font aFont( rControlFont );
3572 aFont = rAppSetFont;
3599 sal_Int32 nBest = 4;
3608 aFontName = aFontName.toAsciiLowerCase();
3610 if( aFontName.indexOf(
"times" ) != -1 )
3612 else if( aFontName.indexOf(
"courier" ) != -1 )
3614 else if( aFontName.indexOf(
"dingbats" ) != -1 )
3616 else if( aFontName.indexOf(
"symbol" ) != -1 )
3648 if( rWidget.Background || rWidget.Border )
3663 OStringBuffer aDA( 256 );
3671 aDA.append(
" Tf" );
3690 rButton.
m_aMKDict =
"/BC [] /BG [] /CA";
3695 const PDFWriter::AnyWidget& rWidget,
3700 if( rWidget.Background || rWidget.Border )
3704 sal_Int32 nDelta =
GetDPIX() / 500;
3729 if( rWidget.Border )
3757 OStringBuffer aDA( 32 );
3762 OStringBuffer aDR( 32 );
3763 aDR.append(
"/Font " );
3765 aDR.append(
" 0 R" );
3766 rEdit.
m_aDRDict = aDR.makeStringAndClear();
3769 aDA.append(
" Tf" );
3779 OString aAppearance =
"/Tx BMC\nEMC\n";
3780 writeBuffer( aAppearance.getStr(), aAppearance.getLength() );
3808 OString aAppearance =
"/Tx BMC\nEMC\n";
3809 writeBuffer( aAppearance.getStr(), aAppearance.getLength() );
3817 OStringBuffer aDA( 256 );
3822 aDA.append( nBest );
3824 OStringBuffer aDR( 32 );
3825 aDR.append(
"/Font " );
3827 aDR.append(
" 0 R" );
3828 rBox.
m_aDRDict = aDR.makeStringAndClear();
3831 aDA.append(
" Tf" );
3842 if( rWidget.Background || rWidget.Border )
3854 sal_Int32 nDelta = aFontSize.
Height()/10;
3880 OStringBuffer aLW( 32 );
3883 aLW.append(
" w " );
3892 OStringBuffer aDA( 256 );
3910 const std::vector<sal_Ucs> aCodeUnits={ cMark };
3912 sal_Int32 nMappedFontObject;
3913 registerGlyph(&aItem, pDevFont, aCodeUnits, nMappedGlyph, nMappedFontObject);
3918 aDA.append( nMappedFontObject );
3919 aDA.append(
" 0 Tf" );
3921 OStringBuffer aDR( 32 );
3922 aDR.append(
"/Font " );
3924 aDR.append(
" 0 R" );
3925 rBox.
m_aDRDict = aDR.makeStringAndClear();
3932 sal_Int32 nCharXOffset = 1000 - 787;
3934 nCharXOffset /= 2000;
3935 sal_Int32 nCharYOffset = 1000 - (820-143);
3937 nCharYOffset /= 2000;
3942 aDA.append(
"/Tx BMC\nq BT\n" );
3946 aDA.append( nMappedFontObject );
3949 aDA.append(
" Tf\n" );
3953 aDA.append(
" Td <" );
3954 appendHex( nMappedGlyph, aDA );
3955 aDA.append(
"> Tj\nET\nQ\nEMC\n" );
3975 if( rWidget.Background || rWidget.Border )
3987 sal_Int32 nDelta = aFontSize.
Height()/10;
4013 OStringBuffer aLW( 32 );
4016 aLW.append(
" w " );
4025 OStringBuffer aDA( 256 );
4040 aDA.append(
"/Tx BMC\nq BT\n" );
4044 aDA.append(
" 0 0 Td\nET\nQ\n" );
4069 OString aStandardAppearance;
4081 rAnnotDict.append(
"/AP<<\n" );
4084 rAnnotDict.append(
"/" );
4085 rAnnotDict.append( dict_item.first );
4086 bool bUseSubDict = (dict_item.second.size() > 1);
4100 rAnnotDict.append( bUseSubDict ?
"<<" :
" " );
4102 for (
auto const& stream_item : dict_item.second)
4105 dict_item.second[ stream_item.first ] =
nullptr;
4109 sal_Int64 nStreamLen = pAppearanceStream->
TellEnd();
4117 OStringBuffer aLine;
4118 aLine.append( nObject );
4120 aLine.append(
" 0 obj\n"
4125 aLine.append(
" " );
4130 aLine.append(
" 0 R\n"
4132 aLine.append( nStreamLen );
4133 aLine.append(
"\n" );
4135 aLine.append(
"/Filter/FlateDecode\n" );
4136 aLine.append(
">>\nstream\n" );
4145 rAnnotDict.append(
" /" );
4146 rAnnotDict.append( stream_item.first );
4147 rAnnotDict.append(
" " );
4149 rAnnotDict.append( nObject );
4150 rAnnotDict.append(
" 0 R" );
4152 delete pAppearanceStream;
4155 rAnnotDict.append( bUseSubDict ?
">>\n" :
"\n" );
4157 rAnnotDict.append(
">>\n" );
4158 if( !aStandardAppearance.isEmpty() )
4160 rAnnotDict.append(
"/AS /" );
4161 rAnnotDict.append( aStandardAppearance );
4162 rAnnotDict.append(
"\n" );
4174 for(
int a = 0;
a < nAnnots;
a++ )
4178 OStringBuffer aLine( 1024 );
4179 OStringBuffer aValue( 256 );
4181 aLine.append(
" 0 obj\n"
4190 aLine.append(
"/Type/Annot/Subtype/Widget/F " );
4194 aLine.append(
"132\n" );
4199 aLine.append(
"4\n" );
4203 aLine.append(
"/Rect[" );
4204 appendFixedInt( rWidget.
m_aRect.
Left()-iRectMargin, aLine );
4205 aLine.append(
' ' );
4206 appendFixedInt( rWidget.
m_aRect.
Top()+iRectMargin, aLine );
4207 aLine.append(
' ' );
4208 appendFixedInt( rWidget.
m_aRect.
Right()+iRectMargin, aLine );
4209 aLine.append(
' ' );
4210 appendFixedInt( rWidget.
m_aRect.
Bottom()-iRectMargin, aLine );
4211 aLine.append(
"]\n" );
4213 aLine.append(
"/FT/" );
4225 aValue.append(
"/" );
4228 aValue.append(
"Off" );
4230 appendName( rWidget.
m_aValue, aValue );
4234 aLine.append(
"Btn" );
4239 aValue.append(
"[" );
4243 if( nEntry >= 0 && nEntry < sal_Int32(rWidget.
m_aListEntries.size()) )
4246 aValue.append(
"]" );
4256 aLine.append(
"Ch" );
4260 aLine.append(
"Ch" );
4263 aLine.append(
"Tx" );
4267 aLine.append(
"Sig" );
4273 aLine.append(
"\n" );
4274 aLine.append(
"/P " );
4276 aLine.append(
" 0 R\n" );
4280 aLine.append(
"/Parent " );
4282 aLine.append(
" 0 R\n" );
4284 if( !rWidget.
m_aKids.empty() )
4286 aLine.append(
"/Kids[" );
4287 for(
size_t i = 0; i < rWidget.
m_aKids.size(); i++ )
4289 aLine.append( rWidget.
m_aKids[i] );
4290 aLine.append(
" 0 R" );
4291 aLine.append( ( (i&15) == 15 ) ?
"\n" :
" " );
4293 aLine.append(
"]\n" );
4295 if( !rWidget.
m_aName.isEmpty() )
4297 aLine.append(
"/T" );
4299 aLine.append(
"\n" );
4305 aLine.append(
"/TU" );
4307 aLine.append(
"\n" );
4312 aLine.append(
"/Ff " );
4314 aLine.append(
"\n" );
4316 if( !aValue.isEmpty() )
4318 OString aVal = aValue.makeStringAndClear();
4319 aLine.append(
"/V " );
4320 aLine.append( aVal );
4323 aLine.append( aVal );
4324 aLine.append(
"\n" );
4329 aLine.append(
"/Opt[\n" );
4334 aLine.append(
"\n" );
4339 aLine.append(
"]\n" );
4342 aLine.append(
"/TI " );
4343 aLine.append( nTI );
4344 aLine.append(
"\n" );
4347 aLine.append(
"/I [" );
4348 aLine.append( nTI );
4349 aLine.append(
"]\n" );
4355 aLine.append(
"/MaxLen " );
4357 aLine.append(
"\n" );
4363 OStringBuffer aDest;
4366 aLine.append(
"/AA<</D<</Type/Action/S/GoTo/D " );
4367 aLine.append( aDest.makeStringAndClear() );
4368 aLine.append(
">>>>\n" );
4375 aLine.append(
"/AA<</D<</Type/Action/S/ResetForm>>>>\n" );
4381 aLine.append(
"/AA<</D<</Type/Action/S/SubmitForm/F" );
4383 aLine.append(
"/Flags " );
4385 sal_Int32 nFlags = 0;
4405 aLine.append( nFlags );
4406 aLine.append(
">>>>\n" );
4411 aLine.append(
"/AA<</D<</Type/Action/S/URI/URI(" );
4413 aLine.append(
")>>>>\n" );
4423 aLine.append(
"/DR<<" );
4425 aLine.append(
">>\n" );
4429 aLine.append(
"/DR<</Font<<" );
4431 aLine.append(
">>>>\n" );
4433 aLine.append(
"/DA" );
4435 aLine.append(
"\n" );
4437 aLine.append(
"/Q 1\n" );
4439 aLine.append(
"/Q 2\n" );
4446 aLine.append(
"/MK<<" );
4450 aLine.append(
">>\n" );
4455 aLine.append(
">>\n"
4483 OStringBuffer aLine;
4484 aLine.append(rEmbeddedFile.m_nObject);
4485 aLine.append(
" 0 obj\n");
4486 aLine.append(
"<< /Type /EmbeddedFile /Length ");
4487 aLine.append(static_cast<sal_Int64>(rEmbeddedFile.m_aDataContainer.getSize()));
4488 aLine.append(
" >>\nstream\n");
4492 CHECK_RETURN(
writeBuffer(rEmbeddedFile.m_aDataContainer.getData(), rEmbeddedFile.m_aDataContainer.getSize()));
4494 aLine.append(
"\nendstream\nendobj\n\n");
4501 #define CHECK_RETURN( x ) if( !x ) return false
4516 if( ! page.emit( nTreeNode ) )
4529 sal_Int32 nStructureDict = 0;
4543 OStringBuffer aLine( 2048 );
4544 aLine.append( nTreeNode );
4545 aLine.append(
" 0 obj\n" );
4546 aLine.append(
"<</Type/Pages\n" );
4547 aLine.append(
"/Resources " );
4549 aLine.append(
" 0 R\n" );
4551 sal_Int32 nMediaBoxWidth = 0;
4552 sal_Int32 nMediaBoxHeight = 0;
4553 sal_Int32 nUserUnit = 1;
4554 if( m_aPages.empty() )
4561 for (
auto const& page : m_aPages)
4563 if( page.m_nPageWidth > nMediaBoxWidth )
4565 nMediaBoxWidth = page.m_nPageWidth;
4566 nUserUnit = page.m_nUserUnit;
4568 if( page.m_nPageHeight > nMediaBoxHeight )
4570 nMediaBoxHeight = page.m_nPageHeight;
4571 nUserUnit = page.m_nUserUnit;
4575 aLine.append(
"/MediaBox[ 0 0 " );
4576 aLine.append(nMediaBoxWidth / nUserUnit);
4577 aLine.append(
' ' );
4578 aLine.append(nMediaBoxHeight / nUserUnit);
4579 aLine.append(
" ]\n");
4582 aLine.append(
"/UserUnit ");
4583 aLine.append(nUserUnit);
4586 aLine.append(
"/Kids[ ");
4588 for (
const auto & page : m_aPages)
4590 aLine.append( page.m_nPageObject );
4591 aLine.append(
" 0 R" );
4592 aLine.append( ( (i&15) == 15 ) ?
"\n" :
" " );
4597 aLine.append( static_cast<sal_Int32>(m_aPages.size()) );
4598 aLine.append(
">>\n"
4610 aLine.setLength( 0 );
4612 aLine.append(
" 0 obj\n"
4613 "<</Type/Catalog/Pages " );
4614 aLine.append( nTreeNode );
4615 aLine.append(
" 0 R\n" );
4618 if( nNamedDestinationsDictionary )
4620 aLine.append(
"/Dests ");
4621 aLine.append( nNamedDestinationsDictionary );
4622 aLine.append(
" 0 R\n" );
4630 aLine.append(
"/PageLayout/SinglePage\n" );
4633 aLine.append(
"/PageLayout/OneColumn\n" );
4637 aLine.append(
"/PageLayout/TwoColumnRight\n" );
4644 aLine.append(
"/PageMode/UseNone\n" );
4647 aLine.append(
"/PageMode/UseOutlines\n" );
4650 aLine.append(
"/PageMode/UseThumbs\n" );
4654 aLine.append(
"/PageMode/FullScreen\n" );
4656 OStringBuffer aInitPageRef;
4660 aInitPageRef.append(
" 0 R" );
4663 aInitPageRef.append(
"0" );
4669 if( aInitPageRef.getLength() > 1 )
4671 aLine.append(
"/OpenAction[" );
4672 aLine.append( aInitPageRef.makeStringAndClear() );
4673 aLine.append(
" /XYZ null null 0]\n" );
4677 aLine.append(
"/OpenAction[" );
4678 aLine.append( aInitPageRef.makeStringAndClear() );
4679 aLine.append(
" /Fit]\n" );
4682 aLine.append(
"/OpenAction[" );
4683 aLine.append( aInitPageRef.makeStringAndClear() );
4684 aLine.append(
" /FitH " );
4686 aLine.append(
"]\n" );
4689 aLine.append(
"/OpenAction[" );
4690 aLine.append( aInitPageRef.makeStringAndClear() );
4691 aLine.append(
" /FitBH " );
4693 aLine.append(
"]\n" );
4696 aLine.append(
"/OpenAction[" );
4697 aLine.append( aInitPageRef.makeStringAndClear() );
4698 aLine.append(
" /XYZ null null " );
4702 aLine.append(
"0" );
4703 aLine.append(
"]\n" );
4715 aLine.append(
"/ViewerPreferences<<" );
4717 aLine.append(
"/HideToolbar true\n" );
4719 aLine.append(
"/HideMenubar true\n" );
4721 aLine.append(
"/HideWindowUI true\n" );
4723 aLine.append(
"/FitWindow true\n" );
4725 aLine.append(
"/CenterWindow true\n" );
4727 aLine.append(
"/DisplayDocTitle true\n" );
4729 aLine.append(
"/Direction/R2L\n" );
4735 aLine.append(
"/NonFullScreenPageMode/UseNone\n" );
4738 aLine.append(
"/NonFullScreenPageMode/UseOutlines\n" );
4741 aLine.append(
"/NonFullScreenPageMode/UseThumbs\n" );
4744 aLine.append(
">>\n" );
4749 aLine.append(
"/Outlines " );
4750 aLine.append( nOutlineDict );
4751 aLine.append(
" 0 R\n" );
4753 if( nStructureDict )
4755 aLine.append(
"/StructTreeRoot " );
4756 aLine.append( nStructureDict );
4757 aLine.append(
" 0 R\n" );
4763 OUString aLanguage, aScript, aCountry;
4765 if (!aLanguage.isEmpty())
4767 OUStringBuffer aLocBuf( 16 );
4768 aLocBuf.append( aLanguage );
4769 if( !aCountry.isEmpty() )
4771 aLocBuf.append(
'-' );
4772 aLocBuf.append( aCountry );
4774 aLine.append(
"/Lang" );
4776 aLine.append(
"\n" );
4781 aLine.append(
"/MarkInfo<</Marked true>>\n" );
4785 aLine.append(
"/AcroForm<</Fields[\n" );
4788 for(
int j = 0; j < nWidgets; j++ )
4794 aLine.append( (nOut++ % 5)==4 ?
" 0 R\n" :
" 0 R " );
4797 aLine.append(
"\n]" );
4799 #if HAVE_FEATURE_NSS
4801 aLine.append(
"/SigFlags 3");
4804 aLine.append(
"/DR " );
4806 aLine.append(
" 0 R" );
4809 #
if HAVE_FEATURE_NSS
4813 aLine.append(
">>\n" );
4815 aLine.append(
"/NeedAppearances true>>\n" );
4819 if( nOutputIntentObject )
4821 aLine.append(
"/OutputIntents[");
4822 aLine.append( nOutputIntentObject );
4823 aLine.append(
" 0 R]" );
4826 if( nMetadataObject )
4828 aLine.append(
"/Metadata ");
4829 aLine.append( nMetadataObject );
4830 aLine.append(
" 0 R" );
4833 aLine.append(
">>\n"
4835 return writeBuffer( aLine.getStr(), aLine.getLength() );
4838 #if HAVE_FEATURE_NSS
4845 OStringBuffer aLine( 0x5000 );
4847 aLine.append(
" 0 obj\n" );
4848 aLine.append(
"<</Contents <" );
4850 sal_uInt64 nOffset = ~0U;
4858 aLine.append( aContentFiller.makeStringAndClear() );
4859 aLine.append(
">\n/Type/Sig/SubFilter/adbe.pkcs7.detached");
4863 aLine.append(
"/Name" );
4867 aLine.append(
" /M ");
4870 aLine.append(
" /ByteRange [ 0 ");
4872 aLine.append(
" " );
4874 aLine.append(
" " );
4881 OStringBuffer aByteRangeFiller( 100 );
4883 aLine.append( aByteRangeFiller.makeStringAndClear() );
4884 aLine.append(
" /Filter/Adobe.PPKMS");
4889 aLine.append(
"/Reason");
4895 aLine.append(
"/Location");
4901 aLine.append(
"/ContactInfo");
4905 aLine.append(
" >>\nendobj\n\n" );
4907 return writeBuffer( aLine.getStr(), aLine.getLength() );
4916 sal_uInt64 nOffset = ~0U;
4922 sal_uInt64 nWritten = 0;
4924 OString aByteRangeNo = OString::number( nLastByteRangeNo ) +
" ]";
4926 if (
m_aFile.write(aByteRangeNo.getStr(), aByteRangeNo.getLength(), nWritten) != osl::File::E_None)
4938 sal_uInt64 bytesRead1;
4944 SAL_WARN(
"vcl.pdfwriter",
"First buffer read failed");
4948 std::unique_ptr<char[]> buffer2(
new char[nLastByteRangeNo + 1]);
4949 sal_uInt64 bytesRead2;
4952 osl::File::E_None !=
m_aFile.read(buffer2.get(), nLastByteRangeNo, bytesRead2) ||
4953 bytesRead2 != static_cast<sal_uInt64>(nLastByteRangeNo))
4955 SAL_WARN(
"vcl.pdfwriter",
"Second buffer read failed");
4959 OStringBuffer aCMSHexBuffer;
4961 aSigning.AddDataRange(buffer1.get(), bytesRead1);
4962 aSigning.AddDataRange(buffer2.get(), bytesRead2);
4965 if (!aSigning.Sign(aCMSHexBuffer))
4967 SAL_WARN(
"vcl.pdfwriter",
"PDFWriter::Sign() failed");
4976 m_aFile.write(aCMSHexBuffer.getStr(), aCMSHexBuffer.getLength(), nWritten);
4978 return osl::File::E_None ==
m_aFile.setPos(osl_Pos_Absolut, nOffset);
4981 #endif //HAVE_FEATURE_NSS
4989 OStringBuffer aLine( 1024 );
4990 aLine.append( nObject );
4991 aLine.append(
" 0 obj\n"
4995 aLine.append(
"/Title" );
4997 aLine.append(
"\n" );
5001 aLine.append(
"/Author" );
5003 aLine.append(
"\n" );
5007 aLine.append(
"/Subject" );
5009 aLine.append(
"\n" );
5013 aLine.append(
"/Keywords" );
5015 aLine.append(
"\n" );
5019 aLine.append(
"/Creator" );
5021 aLine.append(
"\n" );
5025 aLine.append(
"/Producer" );
5027 aLine.append(
"\n" );
5030 aLine.append(
"/CreationDate" );
5032 aLine.append(
">>\nendobj\n\n" );
5033 if( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
5055 OStringBuffer aLine( 1024 );
5056 aLine.append( nObject );
5057 aLine.append(
" 0 obj\n"
5061 for( nDestID = 0; nDestID < nCount; nDestID++ )
5075 aLine.append(
'/' );
5076 appendDestinationName( aName, aLine );
5077 aLine.append(
'[' );
5080 aLine.append(
" 0 R" );
5086 aLine.append(
"/XYZ " );
5088 aLine.append(
' ' );
5090 aLine.append(
" 0" );
5093 aLine.append(
"/FitR " );
5095 aLine.append(
' ' );
5096 appendFixedInt( rDest.
m_aRect.
Top(), aLine );
5097 aLine.append(
' ' );
5099 aLine.append(
' ' );
5103 aLine.append(
"]\n" );
5107 aLine.append(
">>\nendobj\n\n" );
5108 if( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
5125 OStringBuffer aLine( 1024 );
5129 aLine.append( nICCObject );
5131 aLine.append(
" 0 obj\n<</N 3/Length " );
5132 aLine.append( nStreamLengthObject );
5133 aLine.append(
" 0 R" );
5135 aLine.append(
"/Filter/FlateDecode" );
5136 aLine.append(
">>\nstream\n" );
5138 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return 0;
5140 sal_uInt64 nBeginStreamPos = 0;
5141 if (osl::File::E_None !=
m_aFile.getPos(nBeginStreamPos))
5145 cmsHPROFILE hProfile = cmsCreate_sRGBProfile();
5147 cmsSetProfileVersion(hProfile, 2.1);
5148 cmsUInt32Number nBytesNeeded = 0;
5149 cmsSaveProfileToMem(hProfile,
nullptr, &nBytesNeeded);
5152 std::vector<unsigned char>
aBuffer(nBytesNeeded);
5153 cmsSaveProfileToMem(hProfile, aBuffer.data(), &nBytesNeeded);
5154 cmsCloseProfile(hProfile);
5155 bool written =
writeBuffer( aBuffer.data(),
static_cast<sal_Int32
>(aBuffer.size()) );
5159 sal_uInt64 nEndStreamPos = 0;
5160 if (
m_aFile.getPos(nEndStreamPos) != osl::File::E_None)
5165 if( !
writeBuffer(
"\nendstream\nendobj\n\n", 19 ) )
5167 aLine.setLength( 0 );
5171 aLine.setLength( 0 );
5172 aLine.append( nStreamLengthObject );
5173 aLine.append(
" 0 obj\n" );
5174 aLine.append( static_cast<sal_Int64>(nEndStreamPos-nBeginStreamPos) );
5175 aLine.append(
"\nendobj\n\n" );
5176 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return 0;
5177 aLine.setLength( 0 );
5182 aLine.append( nOIObject );
5183 aLine.append(
" 0 obj\n"
5184 "<</Type/OutputIntent/S/GTS_PDFA1/OutputConditionIdentifier");
5187 aLine.append(
"/DestOutputProfile ");
5188 aLine.append( nICCObject );
5189 aLine.append(
" 0 R>>\nendobj\n\n" );
5190 if ( !
writeBuffer( aLine.getStr(), aLine.getLength() ) )
return 0;
5199 int nLen = rStr.getLength();
5200 for( ; nLen; nLen--, pUni++ )
5220 rValue += OUStringChar( *pUni );
5228 if (!aValue.isEmpty())
5230 OUString aTempString;