21#include <config_crypto.h>
38#include <com/sun/star/io/XOutputStream.hpp>
39#include <com/sun/star/util/URL.hpp>
40#include <com/sun/star/util/URLTransformer.hpp>
49#include <officecfg/Office/Common.hxx>
50#include <osl/file.hxx>
51#include <osl/thread.h>
52#include <rtl/digest.h>
54#include <rtl/ustrbuf.hxx>
88#include <textlayout.hxx>
96#include <frozen/bits/defines.h>
97#include <frozen/bits/elsa_std.h>
98#include <frozen/map.h>
100using namespace::com::sun::star;
107constexpr sal_Int32 nLog10Divisor = 3;
108constexpr double fDivisor = 1000.0;
110constexpr double pixelToPoint(
double px)
112 return px / fDivisor;
117 return sal_Int32(pt * fDivisor);
120void appendObjectID(sal_Int32 nObjectID, OStringBuffer & aLine)
122 aLine.append(nObjectID);
123 aLine.append(
" 0 obj\n");
126void appendObjectReference(sal_Int32 nObjectID, OStringBuffer & aLine)
128 aLine.append(nObjectID);
129 aLine.append(
" 0 R ");
132void appendHex(
sal_Int8 nInt, OStringBuffer& rBuffer)
134 static const char pHexDigits[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
135 '8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
136 rBuffer.append( pHexDigits[ (nInt >> 4) & 15 ] );
137 rBuffer.append( pHexDigits[ nInt & 15 ] );
140void appendName( std::u16string_view rStr, OStringBuffer& rBuffer )
145 int nLen =
aStr.getLength();
146 for(
int i = 0;
i < nLen;
i++ )
155 if( (aStr[i] >=
'A' && aStr[i] <=
'Z' ) ||
156 (aStr[i] >=
'a' && aStr[i] <=
'z' ) ||
157 (aStr[i] >=
'0' && aStr[i] <=
'9' ) ||
160 rBuffer.append( aStr[i] );
164 rBuffer.append(
'#' );
165 appendHex(
static_cast<sal_Int8>(aStr[i]), rBuffer );
170void appendName(
const char* pStr, OStringBuffer& rBuffer )
173 while( pStr && *pStr )
175 if( (*pStr >=
'A' && *pStr <=
'Z' ) ||
176 (*pStr >=
'a' && *pStr <=
'z' ) ||
177 (*pStr >=
'0' && *pStr <=
'9' ) ||
180 rBuffer.append( *pStr );
184 rBuffer.append(
'#' );
185 appendHex(
static_cast<sal_Int8>(*pStr), rBuffer );
192void appendLiteralString(
const char* pStr, sal_Int32 nLength, OStringBuffer& rBuffer )
199 rBuffer.append(
"\\n" );
202 rBuffer.append(
"\\r" );
205 rBuffer.append(
"\\t" );
208 rBuffer.append(
"\\b" );
211 rBuffer.append(
"\\f" );
216 rBuffer.append(
"\\" );
217 rBuffer.append(
static_cast<char>(*pStr) );
220 rBuffer.append(
static_cast<char>(*pStr) );
251void appendDestinationName(
const OUString& rString, OStringBuffer& rBuffer )
254 sal_Int32 nLen = rString.getLength();
255 for(
int i = 0;
i < nLen;
i++ )
258 if( (aChar >=
'0' && aChar <=
'9' ) ||
259 (aChar >=
'a' && aChar <=
'z' ) ||
260 (aChar >=
'A' && aChar <=
'Z' ) ||
263 rBuffer.append(
static_cast<char>(aChar));
269 appendHex( aValueHigh, rBuffer );
270 appendHex(
static_cast<sal_Int8>(aChar & 255 ), rBuffer );
281 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
282 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
288template <
class GEOMETRY >
289GEOMETRY lcl_convert(
const MapMode& _rSource,
const MapMode& _rDest,
OutputDevice* _pPixelConversion,
const GEOMETRY& _rObject )
292 if ( MapUnit::MapPixel == _rSource.
GetMapUnit() )
294 aPoint = _pPixelConversion->
PixelToLogic( _rObject, _rDest );
303void removePlaceholderSE(std::vector<PDFStructureElement> & rStructure, PDFStructureElement& rEle);
309 rBuffer.append(
"FEFF" );
311 sal_Int32 nLen = rString.getLength();
312 for(
int i = 0;
i < nLen;
i++ )
315 appendHex(
static_cast<sal_Int8>(aChar >> 8), rBuffer );
316 appendHex(
static_cast<sal_Int8>(aChar & 255 ), rBuffer );
326 const OUString& rName = i_rControl.
Name;
328 int nLen =
aStr.getLength();
330 OStringBuffer
aBuffer( rName.getLength()+64 );
331 for(
int i = 0;
i < nLen;
i++ )
346 OString aFullName(
aBuffer.makeStringAndClear() );
349 sal_Int32 nTokenIndex = 0, nLastTokenIndex = 0;
350 OString aPartialName;
354 nLastTokenIndex = nTokenIndex;
355 aPartialName = aFullName.getToken( 0,
'.', nTokenIndex );
356 if( nTokenIndex != -1 )
360 aDomain = aFullName.copy( 0, nTokenIndex-1 );
361 std::unordered_map< OString, sal_Int32 >::const_iterator it =
m_aFieldNameMap.find( aDomain );
369 m_aWidgets[nNewWidget].m_aName = aPartialName;
373 if( nLastTokenIndex > 0 )
377 OString aParentDomain( aDomain.copy( 0, nLastTokenIndex-1 ) );
382 OSL_ENSURE( it->second < sal_Int32(
m_aWidgets.size()),
"invalid field number entry" );
383 if( it->second < sal_Int32(
m_aWidgets.size()) )
402 aPartialName = aFullName.copy( aFullName.lastIndexOf(
'.' )+1 );
403 if( nLastTokenIndex > 0 )
405 aDomain = aFullName.copy( 0, nLastTokenIndex-1 );
406 aFullName = aDomain +
"." + aPartialName;
409 aFullName = aPartialName;
413 }
while( nTokenIndex != -1 );
416 if( !aDomain.isEmpty() )
418 std::unordered_map< OString, sal_Int32 >::const_iterator it =
m_aFieldNameMap.find( aDomain );
426 m_aWidgets[it->second].m_aKidsIndex.push_back( i_nWidgetIndex );
431 if( aPartialName.isEmpty() )
436 aPartialName =
"RadioGroup" +
440 aPartialName = OString(
"Widget" );
445 std::unordered_map<OString, sal_Int32>::iterator it =
m_aFieldNameMap.find( aFullName );
449 std::unordered_map< OString, sal_Int32 >::const_iterator check_it;
454 aTry = aFullName +
"_" + OString::number(nTry++);
459 aPartialName = aFullName.copy( aFullName.lastIndexOf(
'.' )+1 );
466 m_aWidgets[i_nWidgetIndex].m_aName = aPartialName;
472void appendFixedInt( sal_Int32 nValue, OStringBuffer& rBuffer )
476 rBuffer.append(
'-' );
479 sal_Int32 nFactor = 1, nDiv = nLog10Divisor;
483 sal_Int32 nInt =
nValue / nFactor;
484 rBuffer.append( nInt );
485 if (nFactor > 1 && nValue % nFactor)
487 rBuffer.append(
'.' );
491 rBuffer.append((nValue / nFactor) % 10);
493 while (nFactor > 1 && nValue % nFactor);
498void appendDouble(
double fValue, OStringBuffer& rBuffer, sal_Int32 nPrecision = 10 )
507 sal_Int64 nInt =
static_cast<sal_Int64
>(fValue);
508 fValue -=
static_cast<double>(nInt);
510 if( rtl::math::approxEqual(fValue, 1.0) || log10( 1.0-fValue ) <= -nPrecision )
518 fValue *= pow( 10.0,
static_cast<double>(nPrecision) );
519 nFrac =
static_cast<sal_Int64
>(fValue);
521 if( bNeg && ( nInt || nFrac ) )
522 rBuffer.append(
'-' );
523 rBuffer.append( nInt );
528 rBuffer.append(
'.' );
529 sal_Int64 nBound =
static_cast<sal_Int64
>(pow( 10.0, nPrecision - 1.0 )+0.5);
530 for ( i = 0; (
i < nPrecision ) && nFrac;
i++ )
532 sal_Int64 nNumb = nFrac / nBound;
533 nFrac -= nNumb * nBound;
534 rBuffer.append( nNumb );
539void appendColor(
const Color& rColor, OStringBuffer& rBuffer,
bool bConvertToGrey )
542 if( rColor == COL_TRANSPARENT )
548 appendDouble(
static_cast<double>(cByte) / 255.0, rBuffer );
552 appendDouble(
static_cast<double>(rColor.
GetRed()) / 255.0, rBuffer );
553 rBuffer.append(
' ' );
554 appendDouble(
static_cast<double>(rColor.
GetGreen()) / 255.0, rBuffer );
555 rBuffer.append(
' ' );
556 appendDouble(
static_cast<double>(rColor.
GetBlue()) / 255.0, rBuffer );
567 appendColor( rColor, rBuffer, bGrey );
568 rBuffer.append( bGrey ?
" G" :
" RG" );
577 appendColor( rColor, rBuffer, bGrey );
578 rBuffer.append( bGrey ?
" g" :
" rg" );
585void appendPdfTimeDate(OStringBuffer & rBuffer,
586 sal_Int16 year, sal_uInt16 month, sal_uInt16 day, sal_uInt16 hours, sal_uInt16 minutes, sal_uInt16 seconds, sal_Int32 tzDelta)
588 rBuffer.append(
"D:");
589 rBuffer.append(
char(
'0' + ((year / 1000) % 10)));
590 rBuffer.append(
char(
'0' + ((year / 100) % 10)));
591 rBuffer.append(
char(
'0' + ((year / 10) % 10)));
592 rBuffer.append(
char(
'0' + (year % 10)));
593 rBuffer.append(
char(
'0' + ((month / 10) % 10)));
594 rBuffer.append(
char(
'0' + (month % 10)));
595 rBuffer.append(
char(
'0' + ((day / 10) % 10)));
596 rBuffer.append(
char(
'0' + (day % 10)));
597 rBuffer.append(
char(
'0' + ((hours / 10) % 10)));
598 rBuffer.append(
char(
'0' + (hours % 10)));
599 rBuffer.append(
char(
'0' + ((minutes / 10) % 10)));
600 rBuffer.append(
char(
'0' + (minutes % 10)));
601 rBuffer.append(
char(
'0' + ((seconds / 10) % 10)));
602 rBuffer.append(
char(
'0' + (seconds % 10)));
618 rBuffer.append(
char(
'0' + ((tzDelta / 36000) % 10)));
619 rBuffer.append(
char(
'0' + ((tzDelta / 3600) % 10)));
621 rBuffer.append(
char(
'0' + ((tzDelta / 600) % 6)));
622 rBuffer.append(
char(
'0' + ((tzDelta / 60) % 10)));
630 m_pWriter( pWriter ),
631 m_nPageWidth( nPageWidth ),
632 m_nPageHeight( nPageHeight ),
634 m_eOrientation( eOrientation ),
636 m_nStreamLengthObject( 0 ),
637 m_nBeginStreamPos( 0 ),
648 m_nUserUnit = std::ceil(std::max(nPageWidth, nPageHeight) / 14400.0);
661 m_pWriter->emitComment(
"PDFWriterImpl::PDFPage::beginStream, +");
671 +
" 0 obj\n<</Length "
675 aLine.append(
"/Filter/FlateDecode" );
676 aLine.append(
">>\nstream\n" );
693 sal_uInt64 nEndStreamPos;
694 if (osl::File::E_None !=
m_pWriter->m_aFile.getPos(nEndStreamPos))
701 if( !
m_pWriter->writeBuffer(
"\nendstream\nendobj\n\n" ) )
723 "<</Type/Page/Parent "
724 + OString::number(nParentObject)
727 + OString::number(
m_pWriter->getResourceDictObj())
731 aLine.append(
"/MediaBox[0 0 "
738 aLine.append(
"\n/UserUnit " + OString::number(
m_nUserUnit));
749 aLine.append(
"/Annots[\n" );
750 for(
int i = 0;
i < nAnnots;
i++ )
754 aLine.append( ((
i+1)%15) ?
" " :
"\n" );
756 aLine.append(
"]\n" );
757 if (PDFWriter::PDFVersion::PDF_1_5 <= m_pWriter->
m_aContext.Version)
760 aLine.append(
"/Tabs/S\n" );
765 OStringBuffer aStructParents( 1024 );
766 aStructParents.append(
"[ " );
768 for(
int i = 0;
i < nParents;
i++ )
772 aStructParents.append( ((
i%10) == 9) ?
"\n" :
" " );
774 aStructParents.append(
"]" );
775 m_pWriter->m_aStructParentTree.push_back( aStructParents.makeStringAndClear() );
777 aLine.append(
"/StructParents "
778 + OString::number( sal_Int32(
m_pWriter->m_aStructParentTree.size()-1) )
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( OString::Concat(
"/S/") + pStyle +
"\n" );
826 aLine.append( OString::Concat(
"/Dm/") + pDm +
"\n" );
830 aLine.append( OString::Concat(
"/M/") + pM +
"\n" );
834 aLine.append( OString::Concat(
"/Di ") + pDi +
"\n" );
836 aLine.append(
">>\n" );
839 aLine.append(
"/Contents" );
841 if( nStreamObjects > 1 )
845 aLine.append(
" " + OString::number(
i ) +
" 0 R" );
847 if( nStreamObjects > 1 )
849 aLine.append(
">>\nendobj\n\n" );
855 Point aPoint( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
862 appendFixedInt(
nValue, rBuffer );
864 rBuffer.append(
' ' );
868 appendFixedInt(
nValue, rBuffer );
873 double fValue = pixelToPoint(rPoint.
getX());
875 appendDouble( fValue, rBuffer, nLog10Divisor );
876 rBuffer.append(
' ' );
878 appendDouble( fValue, rBuffer, nLog10Divisor );
884 rBuffer.append(
' ' );
886 rBuffer.append(
' ' );
888 rBuffer.append(
" re" );
893 Point aLL = lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
898 Size aSize = lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
910 sal_uInt16 nPoints = rPoly.
GetSize();
914 sal_uInt32 nBufLen = rBuffer.getLength();
920 rBuffer.append(
" m\n" );
921 for( sal_uInt16
i = 1;
i < nPoints;
i++ )
923 if( pFlagArray && pFlagArray[
i] == PolyFlags::Control && nPoints-
i > 2 )
926 SAL_WARN_IF( pFlagArray[
i+1] != PolyFlags::Control || pFlagArray[
i+2] == PolyFlags::Control,
"vcl.pdfwriter",
"unexpected sequence of control points" );
928 rBuffer.append(
" " );
930 rBuffer.append(
" " );
932 rBuffer.append(
" c" );
939 rBuffer.append(
" l" );
941 if( (rBuffer.getLength() - nBufLen) > 65 )
943 rBuffer.append(
"\n" );
944 nBufLen = rBuffer.getLength();
947 rBuffer.append(
" " );
950 rBuffer.append(
"h\n" );
965 rBuffer.append(
' ' );
967 rBuffer.append(
' ' );
969 rBuffer.append(
" re\n" );
972 sal_uInt32 nPoints = aPoly.
count();
976 sal_uInt32 nBufLen = rBuffer.getLength();
979 rBuffer.append(
" m\n" );
980 for( sal_uInt32
i = 1;
i <= nPoints;
i++ )
985 sal_uInt32 nLastPoint =
i-1;
991 rBuffer.append(
' ' );
993 rBuffer.append(
' ' );
995 rBuffer.append(
" c" );
1000 rBuffer.append(
' ' );
1002 rBuffer.append(
" y" );
1007 rBuffer.append(
' ' );
1009 rBuffer.append(
" v" );
1014 rBuffer.append(
" l" );
1016 if( (rBuffer.getLength() - nBufLen) > 65 )
1018 rBuffer.append(
"\n" );
1019 nBufLen = rBuffer.getLength();
1022 rBuffer.append(
" " );
1025 rBuffer.append(
"h\n" );
1030 sal_uInt16 nPolygons = rPolyPoly.
Count();
1031 for( sal_uInt16
n = 0;
n < nPolygons;
n++ )
1037 for(
auto const& rPolygon : rPolyPoly)
1046 rBuffer.append(
'-' );
1049 Size aSize( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
1057 appendFixedInt(
nValue, rBuffer );
1062 Size aSize( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
1065 Size( 1000, 1000 ) ) );
1066 fLength *= pixelToPoint(
static_cast<double>(bVertical ? aSize.
Height() : aSize.
Width()) / 1000.0);
1067 appendDouble( fLength, rBuffer, nPrecision );
1072 if(
LineStyle::Dash == rInfo.GetStyle() && rInfo.GetDashLen() != rInfo.GetDotLen())
1076 if(2 * (rInfo.GetDashCount() + rInfo.GetDotCount()) > 10)
1088 if(css::drawing::LineCap_BUTT != rInfo.GetLineCap())
1096 rBuffer.append(
"[ " );
1097 if( rInfo.GetDashLen() == rInfo.GetDotLen() )
1100 rBuffer.append(
' ' );
1102 rBuffer.append(
' ' );
1106 for(
int n = 0;
n < rInfo.GetDashCount();
n++ )
1109 rBuffer.append(
' ' );
1111 rBuffer.append(
' ' );
1113 for(
int m = 0;
m < rInfo.GetDotCount();
m++ )
1116 rBuffer.append(
' ' );
1118 rBuffer.append(
' ' );
1121 rBuffer.append(
"] 0 d\n" );
1124 if( rInfo.GetWidth() > 1 )
1127 rBuffer.append(
" w\n" );
1129 else if( rInfo.GetWidth() == 0 )
1132 appendDouble( 72.0/
double(
m_pWriter->GetDPIX()), rBuffer );
1133 rBuffer.append(
" w\n" );
1146 rBuffer.append(
"0 " );
1148 rBuffer.append(
" m\n" );
1149 for( sal_Int32
n = 0;
n < nWidth; )
1153 rBuffer.append(
' ' );
1155 rBuffer.append(
' ' );
1158 rBuffer.append(
' ' );
1160 rBuffer.append(
" v " );
1165 rBuffer.append(
' ' );
1167 rBuffer.append(
' ' );
1170 rBuffer.append(
' ' );
1172 rBuffer.append(
" v\n" );
1175 rBuffer.append(
"S\n" );
1180 appendDouble(rMatrix.
get(0), rBuffer);
1181 rBuffer.append(
' ');
1182 appendDouble(rMatrix.
get(1), rBuffer);
1183 rBuffer.append(
' ');
1184 appendDouble(rMatrix.
get(2), rBuffer);
1185 rBuffer.append(
' ');
1186 appendDouble(rMatrix.
get(3), rBuffer);
1187 rBuffer.append(
' ');
1204 const css::uno::Reference< css::beans::XMaterialHolder >& xEnc,
1208 m_aWidgetStyleSettings(
Application::GetSettings().GetStyleSettings()),
1209 m_nCurrentStructElement( 0 ),
1210 m_bEmitStructure( true ),
1212 m_aPDFBmpCache(
utl::ConfigManager::IsFuzzing() ? 15 :
1213 officecfg::Office::Common::VCL::PDFExportImageCacheSize::
get()),
1214 m_nCurrentPage( -1 ),
1215 m_nCatalogObject(0),
1216 m_nSignatureObject( -1 ),
1217 m_nSignatureContentOffset( 0 ),
1218 m_nSignatureLastByteRangeNoOffset( 0 ),
1219 m_nResourceDict( -1 ),
1220 m_nFontDictObject( -1 ),
1225 m_aCipher( nullptr ),
1228 m_bEncryptThisStream( false ),
1229 m_nAccessPermissions(0),
1230 m_bIsPDF_A1( false ),
1231 m_bIsPDF_A2( false ),
1232 m_bIsPDF_UA( false ),
1233 m_bIsPDF_A3( false ),
1234 m_rOuterFace( i_rOuterFace )
1253 osl::File::RC aError =
m_aFile.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
1254 if (aError != osl::File::E_None)
1256 if (aError == osl::File::E_EXIST)
1258 aError =
m_aFile.open(osl_File_OpenFlag_Write);
1259 if (aError == osl::File::E_None)
1263 if (aError != osl::File::E_None)
1272 m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream );
1289 OSL_ENSURE(
false,
"encryption data failed sanity check, encryption disabled" );
1310 aBuffer.append(
"\n%\303\244\303\274\303\266\303\237\n" );
1376 std::vector< sal_uInt8 > aId;
1387 TimeValue aTVal, aGMT;
1389 osl_getSystemTime(&aGMT);
1390 osl_getLocalTimeFromSystemTime(&aGMT, &aTVal);
1391 osl_getDateTimeFromTimeValue(&aTVal, &aDT);
1393 sal_Int32 nDelta = aTVal.Seconds-aGMT.Seconds;
1395 appendPdfTimeDate(aRet, aDT.Year, aDT.Month, aDT.Day, aDT.Hours, aDT.Minutes, aDT.Seconds, nDelta);
1398 return aRet.makeStringAndClear();
1403 const OString& i_rCString1,
1404 OString& o_rCString2
1407 o_rIdentifier.clear();
1410 OString aInfoValuesOut;
1411 OStringBuffer aID( 1024 );
1412 if( !i_rDocInfo.
Title.isEmpty() )
1414 if( !i_rDocInfo.
Author.isEmpty() )
1416 if( !i_rDocInfo.
Subject.isEmpty() )
1418 if( !i_rDocInfo.
Keywords.isEmpty() )
1420 if( !i_rDocInfo.
Creator.isEmpty() )
1422 if( !i_rDocInfo.
Producer.isEmpty() )
1425 TimeValue aTVal, aGMT;
1427 osl_getSystemTime( &aGMT );
1428 osl_getLocalTimeFromSystemTime( &aGMT, &aTVal );
1429 osl_getDateTimeFromTimeValue( &aTVal, &aDT );
1430 OStringBuffer aCreationMetaDateString(64);
1438 aCreationMetaDateString.append(
1439 OStringChar(
static_cast<char>(
'0' + ((aDT.Year/1000)%10)) )
1440 + OStringChar(
static_cast<char>(
'0' + ((aDT.Year/100)%10)) )
1441 + OStringChar(
static_cast<char>(
'0' + ((aDT.Year/10)%10)) )
1442 + OStringChar(
static_cast<char>(
'0' + ((aDT.Year)%10)) )
1444 + OStringChar(
static_cast<char>(
'0' + ((aDT.Month/10)%10)) )
1445 + OStringChar(
static_cast<char>(
'0' + ((aDT.Month)%10)) )
1447 + OStringChar(
static_cast<char>(
'0' + ((aDT.Day/10)%10)) )
1448 + OStringChar(
static_cast<char>(
'0' + ((aDT.Day)%10)) )
1450 + OStringChar(
static_cast<char>(
'0' + ((aDT.Hours/10)%10)) )
1451 + OStringChar(
static_cast<char>(
'0' + ((aDT.Hours)%10)) )
1453 + OStringChar(
static_cast<char>(
'0' + ((aDT.Minutes/10)%10)) )
1454 + OStringChar(
static_cast<char>(
'0' + ((aDT.Minutes)%10)) )
1456 + OStringChar(
static_cast<char>(
'0' + ((aDT.Seconds/10)%10)) )
1457 + OStringChar(
static_cast<char>(
'0' + ((aDT.Seconds)%10)) ));
1459 sal_uInt32 nDelta = 0;
1460 if( aGMT.Seconds > aTVal.Seconds )
1462 nDelta = aGMT.Seconds-aTVal.Seconds;
1463 aCreationMetaDateString.append(
"-" );
1465 else if( aGMT.Seconds < aTVal.Seconds )
1467 nDelta = aTVal.Seconds-aGMT.Seconds;
1468 aCreationMetaDateString.append(
"+" );
1472 aCreationMetaDateString.append(
"Z" );
1477 aCreationMetaDateString.append(
1478 OStringChar(
static_cast<char>(
'0' + ((nDelta/36000)%10)) )
1479 + OStringChar(
static_cast<char>(
'0' + ((nDelta/3600)%10)) )
1481 + OStringChar(
static_cast<char>(
'0' + ((nDelta/600)%6)) )
1482 + OStringChar(
static_cast<char>(
'0' + ((nDelta/60)%10)) ));
1484 aID.append( i_rCString1.getStr(), i_rCString1.getLength() );
1486 aInfoValuesOut = aID.makeStringAndClear();
1487 o_rCString2 = aCreationMetaDateString.makeStringAndClear();
1490 aDigest.
update(
reinterpret_cast<unsigned char const*
>(&aGMT),
sizeof(aGMT));
1491 aDigest.
update(
reinterpret_cast<unsigned char const*
>(aInfoValuesOut.getStr()), aInfoValuesOut.getLength());
1493 o_rIdentifier = aDigest.
finalize();
1503 rOutBuffer.append(
"<" );
1507 sal_Int32 nLen = rInString.getLength();
1511 sal_Int32 nChars = 2 + (nLen * 2);
1516 for(
int i = 0;
i < nLen;
i++ )
1519 *pCopy++ =
static_cast<sal_uInt8>( aUnChar >> 8 );
1520 *pCopy++ =
static_cast<sal_uInt8>( aUnChar & 255 );
1525 for(
int i = 0;
i < nChars;
i++)
1530 rOutBuffer.append(
">" );
1535 rOutBuffer.append(
"(" );
1536 sal_Int32 nChars = rInString.size();
1544 appendLiteralString(
reinterpret_cast<char*
>(
m_vEncryptionBuffer.data()), nChars, rOutBuffer );
1547 appendLiteralString( rInString.data(), nChars , rOutBuffer );
1548 rOutBuffer.append(
")" );
1554 sal_Int32 nLen = aBufferString.getLength();
1555 OStringBuffer
aBuf( nLen );
1556 const char* pT = aBufferString.getStr();
1558 for( sal_Int32
i = 0;
i < nLen;
i++, pT++ )
1560 if( (*pT & 0x80) == 0 )
1565 appendHex( *pT,
aBuf );
1569 aBufferString =
aBuf.makeStringAndClear();
1577 OString aLine = OString::Concat(
"% ") + pComment +
"\n";
1585 sal_uInt64 nEndPos = pStream->
TellEnd();
1587 ZCodec aCodec( 0x4000, 0x4000 );
1592 nEndPos = aStream.
Tell();
1607 m_pCodec = std::make_unique<ZCodec>( 0x4000, 0x4000 );
1638 pBuffer, sal::static_int_cast<std::size_t>(nBytes));
1642 sal_uInt64 nWritten;
1657 pBuffer,
static_cast<sal_Size
>(nBytes),
1662 m_DocDigest.
update(
static_cast<unsigned char const*
>(pWriteBuffer),
static_cast<sal_uInt32
>(nBytes));
1664 if (
m_aFile.write(pWriteBuffer, nBytes, nWritten) != osl::File::E_None)
1667 if( nWritten != nBytes )
1674 return nWritten == nBytes;
1681 m_aPages.emplace_back(
this, nPageWidth, nPageHeight, eOrientation );
1683 sal_Int32 nUserUnit =
m_aPages.back().m_nUserUnit;
1694 OStringBuffer
aBuf( 16 );
1696 aBuf.append(
" w\n" );
1711 OSL_FAIL(
"redirection across pages !!!" );
1734 if( ! bitmap.m_aBitmap.IsEmpty() )
1742 if( jpeg.m_pStream )
1745 jpeg.m_pStream.reset();
1751 if( item.m_pContentStream )
1754 item.m_pContentStream.reset();
1771 sal_uInt64 nOffset = ~0
U;
1772 osl::File::RC aError =
m_aFile.getPos(nOffset);
1773 SAL_WARN_IF( aError != osl::File::E_None,
"vcl.pdfwriter",
"could not register object" );
1774 if (aError != osl::File::E_None)
1780 return aError == osl::File::E_None;
1783#define CHECK_RETURN( x ) if( !(x) ) return 0
1784#define CHECK_RETURN2( x ) if( !(x) ) return
1790 OStringBuffer aLine( 1024 );
1792 aLine.append( OString::number(nObject)
1796 for( sal_Int32
n = 0;
n < nTreeItems;
n++ )
1798 aLine.append( OString::number(
n) +
" "
1802 aLine.append(
"]>>\nendobj\n\n" );
1812 return "id" + OString::number(nObjectId);
1823 std::map<OString, sal_Int32> ids;
1829 appendObjectID(nObject, buf);
1830 buf.append(
"<</Names [\n");
1831 for (
auto const& it : ids)
1835 appendObjectReference(it.second, buf);
1838 buf.append(
"] >>\nendobj\n\n");
1848 static constexpr auto aAttributeStrings = frozen::make_map<PDFWriter::StructAttribute, const char*>({
1874 auto it = aAttributeStrings.find( eAttr );
1876 if( it == aAttributeStrings.end() )
1877 SAL_INFO(
"vcl.pdfwriter",
"invalid PDFWriter::StructAttribute " << eAttr);
1879 return it != aAttributeStrings.end() ? it->second :
"";
1884 static constexpr auto aValueStrings = frozen::make_map<PDFWriter::StructAttributeValue, const char*>({
1927 auto it = aValueStrings.find( eVal );
1929 if( it == aValueStrings.end() )
1930 SAL_INFO(
"vcl.pdfwriter",
"invalid PDFWriter::StructAttributeValue " << eVal);
1932 return it != aValueStrings.end() ? it->second :
"";
1937 o_rLine.append(
"/" );
1942 o_rLine.append(
"/" );
1948 o_rLine.append(
" " );
1950 appendFixedInt( i_rVal.
nValue, o_rLine );
1952 o_rLine.append( i_rVal.
nValue );
1954 o_rLine.append(
"\n" );
1961 OString
const aStructParentEntry(OString::number(i_rEle.
m_nObject) +
" 0 R");
1964 sal_Int32
const nAnnotObj(rAnnot.m_nObject);
1970 OString::number( nRefObject ) +
1972 "<</Type/OBJR/Obj " +
1973 OString::number(nAnnotObj) +
1979 i_rEle.
m_aKids.emplace_back( nRefObject );
1985 OStringBuffer aLayout(256), aList(64), aTable(64);
1986 OStringBuffer aPrintField;
2003 sal_Int32 nLink =
attribute.second.nValue;
2004 std::map< sal_Int32, sal_Int32 >::const_iterator link_it =
2007 nLink = link_it->second;
2014 OSL_FAIL(
"unresolved link id for Link structure" );
2015 SAL_INFO(
"vcl.pdfwriter",
"unresolved link id " << nLink <<
" for Link structure");
2018 OString aLine =
"unresolved link id " +
2019 OString::number( nLink ) +
2020 " for Link structure";
2030 aLayout.append(
"/BBox[" );
2032 aLayout.append(
" " );
2033 appendFixedInt( i_rEle.
m_aBBox.
Top(), aLayout );
2034 aLayout.append(
" " );
2036 aLayout.append(
" " );
2038 aLayout.append(
"]\n" );
2041 std::vector< sal_Int32 > aAttribObjects;
2042 auto const WriteAttrs = [&](
char const*
const pName, OStringBuffer & rBuf)
2047 OStringBuffer aObj( 64 );
2048 aObj.append( aAttribObjects.back() );
2049 aObj.append(
" 0 obj\n"
2053 rBuf.append(
">>\nendobj\n\n");
2058 if( !aLayout.isEmpty() )
2060 WriteAttrs(
"/Layout", aLayout);
2062 if( !aList.isEmpty() )
2064 WriteAttrs(
"/List", aList);
2066 if (!aPrintField.isEmpty())
2068 WriteAttrs(
"/PrintField", aPrintField);
2070 if( !aTable.isEmpty() )
2072 WriteAttrs(
"/Table", aTable);
2075 OStringBuffer aRet( 64 );
2076 if( aAttribObjects.size() > 1 )
2077 aRet.append(
" [" );
2078 for (
auto const& attrib : aAttribObjects)
2080 aRet.append(
" " + OString::number(attrib) +
" 0 R" );
2082 if( aAttribObjects.size() > 1 )
2083 aRet.append(
" ]" );
2084 return aRet.makeStringAndClear();
2108 OSL_FAIL(
"PDFWriterImpl::emitStructure: invalid child structure element" );
2109 SAL_INFO(
"vcl.pdfwriter",
"PDFWriterImpl::emitStructure: invalid child structure element with id " << child);
2115 OSL_FAIL(
"PDFWriterImpl::emitStructure: invalid child structure id" );
2116 SAL_INFO(
"vcl.pdfwriter",
"PDFWriterImpl::emitStructure: invalid child structure id " << child);
2120 OStringBuffer aLine( 512 );
2125 sal_Int32 nParentTree = -1;
2126 sal_Int32 nIDTree = -1;
2131 aLine.append(
"/StructTreeRoot\n"
2133 + OString::number(nParentTree)
2137 aLine.append(
"/RoleMap<<" );
2140 aLine.append(
"/" + role.first +
"/" + role.second +
"\n" );
2142 aLine.append(
">>\n" );
2147 aLine.append(
"/IDTree ");
2148 appendObjectReference(nIDTree, aLine);
2154 aLine.append(
"/StructElem\n"
2162 aLine.append(
"\n/ID ");
2175 aLine.append(
"/ActualText" );
2177 aLine.append(
"\n" );
2181 aLine.append(
"/Alt" );
2183 aLine.append(
"\n" );
2189 if( !aAttribs.isEmpty() )
2191 aLine.append(
"/A" + aAttribs +
"\n" );
2194 if( !rEle.
m_aLocale.Language.isEmpty() )
2203 OUString aLanguage, aScript, aCountry;
2205 if (!aLanguage.isEmpty())
2207 OUStringBuffer aLocBuf( 16 );
2208 aLocBuf.append( aLanguage );
2209 if( !aCountry.isEmpty() )
2211 aLocBuf.append(
"-" + aCountry );
2213 aLine.append(
"/Lang" );
2215 aLine.append(
"\n" );
2240 aLine.append(
"/K[" );
2241 for (
auto const& kid : rEle.
m_aKids)
2243 if( kid.nMCID == -1 )
2246 OString::number(kid.nObject)
2248 aLine.append( ( (
i & 15) == 15 ) ?
"\n" :
" " );
2254 aLine.append( OString::number(kid.nMCID) +
" " );
2260 + OString::number(kid.nObject)
2262 + OString::number(kid.nMCID)
2268 aLine.append(
"]\n" );
2270 aLine.append(
">>\nendobj\n\n" );
2292 OStringBuffer aTilingObj( 1024 );
2296 SAL_WARN_IF( !tiling.m_pTilingStream,
"vcl.pdfwriter",
"tiling without stream" );
2297 if( ! tiling.m_pTilingStream )
2300 aTilingObj.setLength( 0 );
2307 sal_Int32 nX =
static_cast<sal_Int32
>(tiling.m_aRectangle.Left());
2308 sal_Int32 nY =
static_cast<sal_Int32
>(tiling.m_aRectangle.Top());
2309 sal_Int32 nW =
static_cast<sal_Int32
>(tiling.m_aRectangle.GetWidth());
2310 sal_Int32 nH =
static_cast<sal_Int32
>(tiling.m_aRectangle.GetHeight());
2311 if( tiling.m_aCellSize.Width() == 0 )
2312 tiling.m_aCellSize.setWidth( nW );
2313 if( tiling.m_aCellSize.Height() == 0 )
2314 tiling.m_aCellSize.setHeight( nH );
2317 sal_uInt64
const nTilingStreamSize = tiling.m_pTilingStream->TellEnd();
2322 OString::number(tiling.m_nObject)
2324 "<</Type/Pattern/PatternType 1\n"
2328 appendFixedInt( nX, aTilingObj );
2329 aTilingObj.append(
' ' );
2330 appendFixedInt( nY, aTilingObj );
2331 aTilingObj.append(
' ' );
2332 appendFixedInt( nX+nW, aTilingObj );
2333 aTilingObj.append(
' ' );
2334 appendFixedInt( nY+nH, aTilingObj );
2335 aTilingObj.append(
"]\n"
2337 appendFixedInt( tiling.m_aCellSize.Width(), aTilingObj );
2338 aTilingObj.append(
"\n"
2340 appendFixedInt( tiling.m_aCellSize.Height(), aTilingObj );
2341 aTilingObj.append(
"\n" );
2342 if( tiling.m_aTransform.matrix[0] != 1.0 ||
2343 tiling.m_aTransform.matrix[1] != 0.0 ||
2344 tiling.m_aTransform.matrix[3] != 0.0 ||
2345 tiling.m_aTransform.matrix[4] != 1.0 ||
2346 tiling.m_aTransform.matrix[2] != 0.0 ||
2347 tiling.m_aTransform.matrix[5] != 0.0 )
2349 aTilingObj.append(
"/Matrix [" );
2351 appendDouble( tiling.m_aTransform.matrix[0], aTilingObj );
2352 aTilingObj.append(
' ' );
2353 appendDouble( tiling.m_aTransform.matrix[1], aTilingObj );
2354 aTilingObj.append(
' ' );
2355 appendDouble( tiling.m_aTransform.matrix[3], aTilingObj );
2356 aTilingObj.append(
' ' );
2357 appendDouble( tiling.m_aTransform.matrix[4], aTilingObj );
2358 aTilingObj.append(
' ' );
2359 appendDouble( tiling.m_aTransform.matrix[2], aTilingObj );
2360 aTilingObj.append(
' ' );
2361 appendDouble( tiling.m_aTransform.matrix[5], aTilingObj );
2362 aTilingObj.append(
"]\n" );
2364 aTilingObj.append(
"/Resources" );
2367 aTilingObj.append(
"/Filter/FlateDecode" );
2368 aTilingObj.append(
"/Length "
2369 + OString::number(
static_cast<sal_Int32
>(nTilingStreamSize))
2374 bool written =
writeBufferBytes( tiling.m_pTilingStream->GetData(), nTilingStreamSize );
2375 tiling.m_pTilingStream.reset();
2379 aTilingObj.setLength( 0 );
2380 aTilingObj.append(
"\nendstream\nendobj\n\n" );
2392 OStringBuffer aLine( 1024 );
2394 if( nFontObject <= 0 )
2398 OString::number(nFontObject)
2400 "<</Type/Font/Subtype/Type1/BaseFont/" );
2401 appendName( rBuildinFont.
m_pPSName, aLine );
2402 aLine.append(
"\n" );
2403 if( rBuildinFont.
m_eCharSet == RTL_TEXTENCODING_MS_1252 )
2404 aLine.append(
"/Encoding/WinAnsiEncoding\n" );
2405 aLine.append(
">>\nendobj\n\n" );
2413int XUnits(
int nUPEM,
int n) {
return (n * 1000) / nUPEM; }
2418 std::map< sal_Int32, sal_Int32 > aRet;
2431 sal_Int32 pWidths[256] = { 0 };
2434 for(
sal_Ucs c = 32; c < 256; c++ )
2443 std::vector<sal_uInt8>
aBuffer;
2448 if( nFontDescriptor )
2454 OStringBuffer aLine( 1024 );
2456 OString::number(nObject)
2458 "<</Type/Font/Subtype/TrueType"
2461 aLine.append(
"\n" );
2463 aLine.append(
"/Encoding/WinAnsiEncoding\n" );
2464 aLine.append(
"/FirstChar 32 /LastChar 255\n"
2466 for(
int i = 32;
i < 256;
i++ )
2468 aLine.append( pWidths[
i] );
2469 aLine.append( ((
i&15) == 15) ?
"\n" :
" " );
2473 + OString::number( nFontDescriptor )
2487uint32_t fillSubsetArrays(
const FontEmit& rSubset,
sal_GlyphId* pGlyphIds, sal_Int32* pWidths,
2488 sal_uInt8* pEncoding, sal_Int32* pEncToUnicodeIndex,
2489 sal_Int32* pCodeUnitsPerGlyph, std::vector<sal_Ucs>& rCodeUnits,
2490 sal_Int32& nToUnicodeStream)
2492 rCodeUnits.reserve(256);
2497 uint32_t nGlyphs = 1;
2500 sal_uInt8 nEnc = item.second.getGlyphId();
2502 SAL_WARN_IF(pGlyphIds[nEnc] != 0 || pEncoding[nEnc] != 0,
"vcl.pdfwriter",
2506 pGlyphIds[nEnc] = item.first;
2507 pEncoding[nEnc] = nEnc;
2508 pEncToUnicodeIndex[nEnc] =
static_cast<sal_Int32
>(rCodeUnits.size());
2509 pCodeUnitsPerGlyph[nEnc] = item.second.countCodes();
2510 pWidths[nEnc] = item.second.getGlyphWidth();
2511 for (sal_Int32 n = 0;
n < pCodeUnitsPerGlyph[nEnc];
n++)
2512 rCodeUnits.push_back(item.second.getCode(n));
2513 if (item.second.getCode(0))
2514 nToUnicodeStream = 1;
2518 OSL_FAIL(
"too many glyphs for subset");
2527 std::map<sal_Int32, sal_Int32>& rFontIDToObject)
2537 std::vector<sal_uInt8>
aBuffer;
2543 sal_Int32 pWidths[256];
2545 sal_Int32 pEncToUnicodeIndex[256] = {};
2546 sal_Int32 pCodeUnitsPerGlyph[256] = {};
2547 std::vector<sal_Ucs> aCodeUnits;
2548 sal_Int32 nToUnicodeStream = 0;
2551 auto nGlyphs = fillSubsetArrays(rSubset, pGlyphIds, pWidths, pEncoding, pEncToUnicodeIndex,
2552 pCodeUnitsPerGlyph, aCodeUnits, nToUnicodeStream);
2555 sal_Int32 nFontDescriptor = 0;
2559 if (nToUnicodeStream)
2561 pEncToUnicodeIndex, nGlyphs);
2568 OStringBuffer aLine(1024);
2570 OString::number(nFontObject)
2572 "<</Type/Font/Subtype/Type3/Name/");
2573 appendName(aSubsetInfo.
m_aPSName, aLine);
2590 + OString::number(nScale)
2592 + OString::number(nScale)
2595 sal_Int32 pGlyphStreams[256] = {};
2596 aLine.append(
"/CharProcs<<\n");
2597 for (
auto i = 1u;
i < nGlyphs;
i++)
2603 + OString::number(nStream)
2605 pGlyphStreams[
i] = nStream;
2609 "/Encoding<</Type/Encoding/Differences[1");
2610 for (
auto i = 1u;
i < nGlyphs;
i++)
2611 aLine.append(
" /" + pFace->
GetGlyphName(pGlyphIds[
i],
true));
2612 aLine.append(
"]>>\n"
2616 + OString::number(nGlyphs)
2620 for (
auto i = 0
u;
i < nGlyphs;
i++)
2622 aLine.append(OString::number(pWidths[
i]) +
" ");
2624 aLine.append(
"]\n");
2628 aLine.append(
"/FontDescriptor " + OString::number(nFontDescriptor) +
" 0 R\n");
2632 aLine.append(
"/Resources " + OString::number(nResources) +
" 0 R\n");
2634 if (nToUnicodeStream)
2636 aLine.append(
"/ToUnicode " + OString::number(nToUnicodeStream) +
" 0 R\n");
2645 std::set<sal_Int32> aUsedFonts;
2646 std::list<BitmapEmit> aUsedBitmaps;
2647 std::map<sal_uInt8, sal_Int32> aUsedAlpha;
2649 std::list<StreamRedirect> aOutputStreams;
2652 double fScaleX =
GetDPIX() / 72.;
2653 double fScaleY =
GetDPIY() / 72.;
2655 for (
auto i = 1u;
i < nGlyphs;
i++)
2657 auto nStream = pGlyphStreams[
i];
2660 OStringBuffer aContents(1024);
2661 aContents.append(OString::number(pWidths[
i]) +
" 0 d0\n");
2663 const auto& rGlyph = rSubset.
m_aMapping.find(pGlyphIds[
i])->second;
2664 const auto& rLayers = rGlyph.getColorLayers();
2665 for (
const auto& rLayer : rLayers)
2667 aUsedFonts.insert(rLayer.m_nFontID);
2669 aContents.append(
"q ");
2671 if (rLayer.m_nColorIndex != 0xFFFF)
2673 auto& rPalette = rColorPalettes[0];
2674 auto aColor(rPalette[rLayer.m_nColorIndex]);
2676 aContents.append(
" ");
2677 if (aColor.GetAlpha() != 0xFF
2680 auto nAlpha = aColor.GetAlpha();
2681 OStringBuffer
aName(16);
2683 appendHex(nAlpha,
aName);
2685 aContents.append(
"/" +
aName +
" gs ");
2687 if (aUsedAlpha.find(nAlpha) == aUsedAlpha.end())
2690 aUsedAlpha[nAlpha] = nObject;
2692 nObject, aResourceDict, aOutputStreams);
2698 "/F" + OString::number(rLayer.m_nFontID) +
" "
2699 + OString::number(pFace->
UnitsPerEm()) +
" Tf "
2701 appendHex(rLayer.m_nSubsetGlyphID, aContents);
2709 const auto& rBitmapData = rGlyph.getColorBitmap(aRect);
2710 if (!rBitmapData.empty())
2712 SvMemoryStream aStream(
const_cast<uint8_t*
>(rBitmapData.data()), rBitmapData.size(),
2716 aUsedBitmaps, aResourceDict, aOutputStreams);
2718 auto nObject = aBitmapEmit.m_aReferenceXObject.getObject();
2721 + OString::number(aRect.
GetWidth())
2725 + OString::number(aRect.
getX())
2727 + OString::number(aRect.
getY())
2730 + OString::number(nObject)
2734 const auto& rOutline = rGlyph.getOutline();
2735 if (rOutline.count())
2737 aContents.append(
"q ");
2738 appendDouble(fScaleX, aContents);
2739 aContents.append(
" 0 0 ");
2740 appendDouble(fScaleY, aContents);
2741 aContents.append(
" 0 ");
2742 appendDouble(
m_aPages.back().getHeight() * -fScaleY, aContents, 3);
2743 aContents.append(
" cm\n");
2744 m_aPages.back().appendPolyPolygon(rOutline, aContents);
2745 aContents.append(
"f\n"
2750 aLine.append(OString::number(nStream)
2751 +
" 0 obj\n<</Length "
2752 + OString::number(aContents.getLength())
2759 aLine.append(
"endstream\nendobj\n\n");
2765 sal_Int32 nFontDict = 0;
2766 if (!aUsedFonts.empty())
2770 aLine.append(OString::number(nFontDict) +
" 0 obj\n<<");
2771 for (
auto nFontID : aUsedFonts)
2774 + OString::number(nFontID)
2776 + OString::number(rFontIDToObject[nFontID])
2779 aLine.append(
">>\nendobj\n\n");
2787 if (!aUsedAlpha.empty())
2789 for (
const auto & [ nAlpha, nObject ] : aUsedAlpha)
2792 aLine.append(OString::number(nObject) +
" 0 obj\n<<");
2795 aLine.append(
"/CA 1.0/ca 1.0");
2800 aLine.append(
"/CA ");
2801 appendDouble(nAlpha / 255., aLine);
2802 aLine.append(
"/ca ");
2803 appendDouble(nAlpha / 255., aLine);
2805 aLine.append(
">>\nendobj\n\n");
2814 for (
auto& aBitmap : aUsedBitmaps)
2819 aLine.append(OString::number(nResources) +
" 0 obj\n");
2820 aResourceDict.
append(aLine, nFontDict);
2821 aLine.append(
"endobj\n\n");
2827 rFontIDToObject[rSubset.
m_nFontID] = nFontObject;
2837 if( !pFontBytes || (nByteLen < 0) )
2839 const unsigned char* pPtr = pFontBytes;
2840 const unsigned char* pEnd = pFontBytes + nByteLen;
2842 for(
int & rSegmentLength : rSegmentLengths) {
2844 if( pPtr+6 >= pEnd )
2846 if( (pPtr[0] != 0x80) || (pPtr[1] >= 0x03) )
2848 const int nLen = (pPtr[5]<<24) + (pPtr[4]<<16) + (pPtr[3]<<8) + pPtr[2];
2851 rSegmentLength = nLen;
2856 if( pPtr+2 >= pEnd )
2858 if( (pPtr[0] != 0x80) || (pPtr[1] != 0x03) )
2864static void appendSubsetName(
int nSubsetID, std::u16string_view rPSName, OStringBuffer& rBuffer )
2868 for(
int i = 0;
i < 6;
i++ )
2870 int nOffset = nSubsetID % 26;
2872 rBuffer.append(
static_cast<char>(
'A'+nOffset) );
2874 rBuffer.append(
'+' );
2876 appendName( rPSName, rBuffer );
2880 const std::vector<sal_Ucs>& rCodeUnits,
2881 const sal_Int32* pCodeUnitsPerGlyph,
2882 const sal_Int32* pEncToUnicodeIndex,
2886 for (
auto n = 0
u;
n < nGlyphs; ++
n)
2887 if (pCodeUnitsPerGlyph[
n] && rCodeUnits[pEncToUnicodeIndex[
n]])
2896 OStringBuffer aContents( 1024 );
2898 "/CIDInit/ProcSet findresource begin\n"
2901 "/CIDSystemInfo<<\n"
2902 "/Registry (Adobe)\n"
2906 "/CMapName/Adobe-Identity-UCS def\n"
2908 "1 begincodespacerange\n"
2910 "endcodespacerange\n"
2913 for (
auto n = 0
u;
n < nGlyphs; ++
n)
2915 if (pCodeUnitsPerGlyph[
n] && rCodeUnits[pEncToUnicodeIndex[
n]])
2917 if( (
nCount % 100) == 0 )
2920 aContents.append(
"endbfchar\n" );
2921 aContents.append( OString::number(
static_cast<sal_Int32
>(std::min(nMapped-
nCount, 100)) )
2922 +
" beginbfchar\n" );
2924 aContents.append(
'<' );
2925 appendHex(
static_cast<sal_Int8>(pEncoding[
n]), aContents );
2926 aContents.append(
"> <" );
2928 sal_Int32
nIndex = pEncToUnicodeIndex[
n];
2929 for( sal_Int32 j = 0; j < pCodeUnitsPerGlyph[
n]; j++ )
2931 appendHex(
static_cast<sal_Int8>(rCodeUnits[
nIndex + j] / 256), aContents );
2932 appendHex(
static_cast<sal_Int8>(rCodeUnits[
nIndex + j] & 255), aContents );
2934 aContents.append(
">\n" );
2938 aContents.append(
"endbfchar\n"
2940 "CMapName currentdict /CMap defineresource pop\n"
2946 ZCodec aCodec( 0x4000, 0x4000 );
2948 aCodec.
Write( aStream,
reinterpret_cast<const sal_uInt8*
>(aContents.getStr()), aContents.getLength() );
2954 emitComment(
"PDFWriterImpl::createToUnicodeCMap" );
2956 OStringBuffer aLine( 40 );
2958 aLine.append( OString::number(nStream ) +
" 0 obj\n<</Length " );
2962 nLen =
static_cast<sal_Int32
>(aStream.
Tell());
2964 aLine.append( OString::number(nLen) +
"/Filter/FlateDecode" );
2967 aLine.append( aContents.getLength() );
2968 aLine.append(
">>\nstream\n" );
2980 aLine.setLength( 0 );
2981 aLine.append(
"\nendstream\n"
2989 OStringBuffer aLine( 1024 );
2993 sal_Int32 nFontFlags = (1<<2);
2995 nFontFlags |= (1 << 6);
2999 nFontFlags |= (1 << 3);
3001 nFontFlags |= (1 << 1);
3005 aLine.setLength( 0 );
3007 OString::number(nFontDescriptor)
3009 "<</Type/FontDescriptor/FontName/" );
3013 + OString::number( nFontFlags )
3019 + OString::number(
static_cast<sal_Int32
>(rInfo.
m_aFontBBox.
Top()) )
3024 +
"]/ItalicAngle " );
3026 aLine.append(
"-30" );
3028 aLine.append(
"0" );
3031 + OString::number(
static_cast<sal_Int32
>(rInfo.
m_nAscent) )
3034 + OString::number(
static_cast<sal_Int32
>(-rInfo.
m_nDescent) )
3037 + OString::number(
static_cast<sal_Int32
>(rInfo.
m_nCapHeight) )
3044 aLine.append(
"/FontFile" );
3048 aLine.append(
'2' );
3055 OSL_FAIL(
"unknown fonttype in PDF font descriptor" );
3058 aLine.append(
" " + OString::number(nFontStream) +
" 0 R\n" );
3060 aLine.append(
">>\n"
3064 return nFontDescriptor;
3072 rDict.append(
' ' );
3073 rDict.append( item.second );
3074 rDict.append(
" 0 R" );
3080 OStringBuffer aLine( 1024 );
3082 std::map< sal_Int32, sal_Int32 > aFontIDToObject;
3086 for (
auto & s_subset :subset.second.m_aSubsets)
3089 sal_Int32 pWidths[ 256 ];
3091 sal_Int32 pEncToUnicodeIndex[ 256 ] = {};
3092 sal_Int32 pCodeUnitsPerGlyph[ 256 ] = {};
3093 std::vector<sal_Ucs> aCodeUnits;
3094 sal_Int32 nToUnicodeStream = 0;
3097 auto nGlyphs = fillSubsetArrays(s_subset, pGlyphIds, pWidths, pEncoding, pEncToUnicodeIndex,
3098 pCodeUnitsPerGlyph, aCodeUnits, nToUnicodeStream);
3100 std::vector<sal_uInt8>
aBuffer;
3102 const auto* pFace = subset.first;
3103 if (pFace->CreateFontSubset(
aBuffer, pGlyphIds, pEncoding, nGlyphs, aSubsetInfo))
3113 aLine.setLength( 0 );
3114 aLine.append( OString::number(nFontStream)
3117 + OString::number( nStreamLengthObject ) );
3119 aLine.append(
" 0 R"
3120 "/Filter/FlateDecode"
3123 aLine.append(
" 0 R"
3126 sal_uInt64 nStartPos = 0;
3129 aLine.append( OString::number(
static_cast<sal_Int32
>(
aBuffer.size()))
3133 if ( osl::File::E_None !=
m_aFile.getPos(nStartPos) )
return false;
3144 OSL_FAIL(
"PDFWriterImpl does not support CFF-font subsets yet!" );
3153 aLine.append( OString::number(
static_cast<sal_Int32
>(aSegmentLengths[0]) )
3155 + OString::number(
static_cast<sal_Int32
>(aSegmentLengths[1]) )
3157 + OString::number(
static_cast<sal_Int32
>(aSegmentLengths[2]) )
3161 if ( osl::File::E_None !=
m_aFile.getPos(nStartPos) )
return false;
3168 if ( !
writeBufferBytes( &
aBuffer[18] + aSegmentLengths[0] + aSegmentLengths[1], aSegmentLengths[2] ) )
return false;
3172 SAL_INFO(
"vcl.pdfwriter",
"PDF: CreateFontSubset result in not yet supported format=" <<
static_cast<int>(aSubsetInfo.
m_nFontType));
3173 aLine.append(
"0 >>\nstream\n" );
3179 sal_uInt64 nEndPos = 0;
3180 if ( osl::File::E_None !=
m_aFile.getPos(nEndPos) )
return false;
3182 aLine.setLength( 0 );
3183 aLine.append(
"\nendstream\nendobj\n\n" );
3187 if ( !
updateObject( nStreamLengthObject ) )
return false;
3188 aLine.setLength( 0 );
3189 aLine.append( OString::number(nStreamLengthObject)
3191 + OString::number(
static_cast<sal_Int64
>(nEndPos-nStartPos) )
3196 sal_Int32 nFontDescriptor =
emitFontDescriptor( subset.first, aSubsetInfo, s_subset.m_nFontID, nFontStream );
3198 if( nToUnicodeStream )
3199 nToUnicodeStream =
createToUnicodeCMap( pEncoding, aCodeUnits, pCodeUnitsPerGlyph, pEncToUnicodeIndex, nGlyphs );
3203 aLine.setLength( 0 );
3204 aLine.append( OString::number(nFontObject) +
" 0 obj\n" );
3206 "<</Type/Font/Subtype/Type1/BaseFont/" :
3207 "<</Type/Font/Subtype/TrueType/BaseFont/" );
3212 + OString::number(
static_cast<sal_Int32
>(nGlyphs-1) )
3215 for (
auto i = 0
u;
i < nGlyphs;
i++)
3217 aLine.append( pWidths[
i ] );
3218 aLine.append( ((
i & 15) == 15) ?
"\n" :
" " );
3222 + OString::number( nFontDescriptor )
3224 if( nToUnicodeStream )
3226 aLine.append(
"/ToUnicode "
3227 + OString::number( nToUnicodeStream )
3230 aLine.append(
">>\n"
3234 aFontIDToObject[ s_subset.m_nFontID ] = nFontObject;
3238 OStringBuffer aErrorComment( 256 );
3239 aErrorComment.append(
"CreateFontSubset failed for font \""
3243 aErrorComment.append(
" italic" );
3245 aErrorComment.append(
" oblique" );
3246 aErrorComment.append(
" weight=" + OString::number( sal_Int32(pFace->GetWeight()) ) );
3255 std::map< sal_Int32, sal_Int32 > aObjects =
emitSystemFont( systemFont.first, systemFont.second );
3256 for (
auto const& item : aObjects)
3258 if ( !item.second )
return false;
3259 aFontIDToObject[ item.first ] = item.second;
3270 OStringBuffer aFontDict( 1024 );
3275 for (
auto const& itemMap : aFontIDToObject)
3277 aFontDict.append(
"/F"
3278 + OString::number( itemMap.first )
3280 + OString::number( itemMap.second )
3282 if( ((++ni) & 7) == 0 )
3283 aFontDict.append(
'\n' );
3293 aFontDict.append(
"\n>>\nendobj\n\n" );
3313 OStringBuffer aLine( 512 );
3316 aLine.setLength( 0 );
3317 aLine.append( OString::number(nResourceDict)
3320 aLine.append(
"endobj\n\n" );
3322 return nResourceDict;
3326 sal_Int32 nItemLevel,
3327 sal_Int32 nCurrentItemId )
3344 for( sal_Int32
i = 0;
i < nChildren;
i++ )
3346 rCounts[nCurrentItemId] =
nCount;
3357 rCounts[ nCurrentItemId ] = -sal_Int32(rItem.
m_aChildren.size());
3358 for( sal_Int32
i = 0;
i < nChildren;
i++ )
3375 for(
i = 0;
i < nItems; ++
i )
3379 for(
i = 0;
i < nItems; ++
i )
3386 for(
int n = 0;
n < nChildren; ++
n )
3399 std::vector< sal_Int32 > aCounts( nItems );
3403 for(
i = 0;
i < nItems; ++
i )
3406 OStringBuffer aLine( 1024 );
3409 aLine.append( OString::number(rItem.
m_nObject)
3413 if(
i > 0 || aCounts[0] > 0 )
3415 aLine.append(
"/Count " + OString::number( aCounts[
i] ) );
3420 aLine.append(
"/First "
3429 aLine.append(
"/Title" );
3431 aLine.append(
"\n" );
3435 aLine.append(
"/Dest" );
3438 aLine.append(
"/Parent "
3443 aLine.append(
"/Prev "
3449 aLine.append(
"/Next "
3454 aLine.append(
">>\nendobj\n\n" );
3462#define CHECK_RETURN( x ) if( !x ) return false
3468 SAL_INFO(
"vcl.pdfwriter",
"ERROR: invalid dest " <<
static_cast<int>(nDestID) <<
" requested");
3475 rBuffer.append(
'[' );
3477 rBuffer.append(
" 0 R" );
3483 rBuffer.append(
"/XYZ " );
3485 rBuffer.append(
' ' );
3487 rBuffer.append(
" 0" );
3490 rBuffer.append(
"/FitR " );
3492 rBuffer.append(
' ' );
3493 appendFixedInt( rDest.
m_aRect.
Top(), rBuffer );
3494 rBuffer.append(
' ' );
3496 rBuffer.append(
' ' );
3500 rBuffer.append(
']' );
3509 rAttachedFile.maFilename = rFileName;
3510 rAttachedFile.maMimeType = rMimeType;
3511 rAttachedFile.maDescription = rDescription;
3512 rAttachedFile.mnEmbeddedFileObjectId = nObjectID;
3520 rEmbedded.m_nObject = aObjectID;
3521 rEmbedded.m_aSubType = rMimeType;
3522 rEmbedded.m_pStream = std::move(rStream);
3538 for (
int i = 0;
i < nAnnots;
i++)
3542 OStringBuffer aLine;
3543 bool bEmbed =
false;
3555 aLine.append(
" 0 obj\n");
3556 aLine.append(
"<< /Type /EmbeddedFile /Length ");
3557 aLine.append(
static_cast<sal_Int64
>(aMemoryStream.
GetSize()));
3558 aLine.append(
" >>\nstream\n");
3564 aLine.append(
"\nendstream\nendobj\n\n");
3573 aLine.append(OString::number(rScreen.
m_nObject)
3576 "/Subtype/Screen/Rect[");
3579 appendFixedInt(rScreen.
m_aRect.
Top(), aLine);
3587 aLine.append(
"/A<</Type/Action /S/Rendition /AN "
3592 aLine.append(
"/R<</Type/Rendition /S/MR ");
3595 aLine.append(
"/C<</Type/MediaClip /S/MCD ");
3598 aLine.append(
"\n/D << /Type /Filespec /F (<embedded file>) ");
3601 aLine.append(
"/UF (<embedded file>) ");
3603 aLine.append(
"/EF << /F ");
3605 aLine.append(
" 0 R >>");
3610 aLine.append(
"\n/D << /Type /Filespec /FS /URL /F ");
3614 aLine.append(
"/UF ");
3621 aLine.append(
"/Desc ");
3624 aLine.append(
" >>\n");
3626 aLine.append(
"/P <</TF (TEMPACCESS)>>");
3628 aLine.append(
"/CT ");
3632 aLine.append(
" /Alt [ () ");
3638 aLine.append(
"/P<</BE<</C true >>>>"
3642 aLine.append(
"/OP 0 >>");
3646 aLine.append(
"\n/StructParent "
3654 +
" 0 R\n>>\nendobj\n\n");
3663 MARK(
"PDFWriterImpl::emitLinkAnnotations");
3665 for(
int i = 0;
i < nAnnots;
i++ )
3671 OStringBuffer aLine( 1024 );
3673 aLine.append(
" 0 obj\n" );
3676 aLine.append(
"<</Type/Annot" );
3678 aLine.append(
"/F 4" );
3679 aLine.append(
"/Subtype/Link/Border[0 0 0]/Rect[" );
3682 aLine.append(
' ' );
3683 appendFixedInt( rLink.
m_aRect.
Top(), aLine );
3684 aLine.append(
' ' );
3686 aLine.append(
' ' );
3688 aLine.append(
"]" );
3690 aLine.append(
"/Contents");
3694 aLine.append(
"/Dest" );
3725 bool bSetGoToRMode =
false;
3726 bool bTargetHasPDFExtension =
false;
3728 bool bIsUNCPath =
false;
3729 bool bUnparsedURI =
false;
3734 if( eTargetProtocol == INetProtocol::NotValid )
3736 if( url.getLength() > 4 && url.startsWith(
"\\\\\\\\"))
3746 u"http://ahost.ax"),
3754 bUnparsedURI = eTargetProtocol == INetProtocol::NotValid;
3758 OUString aFileExtension =
aTargetURL.GetFileExtension();
3766 if( !aFileExtension.isEmpty() )
3770 bool bChangeFileExtensionToPDF =
false;
3772 if( aFileExtension.equalsIgnoreAsciiCase(
"odm" ) )
3773 bChangeFileExtensionToPDF =
true;
3774 if( aFileExtension.equalsIgnoreAsciiCase(
"odt" ) )
3775 bChangeFileExtensionToPDF =
true;
3776 else if( aFileExtension.equalsIgnoreAsciiCase(
"odp" ) )
3777 bChangeFileExtensionToPDF =
true;
3778 else if( aFileExtension.equalsIgnoreAsciiCase(
"odg" ) )
3779 bChangeFileExtensionToPDF =
true;
3780 else if( aFileExtension.equalsIgnoreAsciiCase(
"ods" ) )
3781 bChangeFileExtensionToPDF =
true;
3782 if( bChangeFileExtensionToPDF )
3786 bTargetHasPDFExtension =
aTargetURL.GetFileExtension().equalsIgnoreAsciiCase(
"pdf" );
3788 bSetGoToRMode =
true;
3793 aLine.append(
"/A<</Type/Action/S");
3796 aLine.append(
"/Launch/Win<</F" );
3799 aLine.append(
">>" );
3803 bool bSetRelative =
false;
3804 bool bFileSpec =
false;
3806 if(
m_aContext.
RelFsys && eBaseProtocol == eTargetProtocol && eTargetProtocol == INetProtocol::File )
3807 bSetRelative =
true;
3810 if( !bSetGoToRMode )
3817 aLine.append(
"/URI/URI" );
3827 if( (!aFragment.isEmpty() && !bTargetHasPDFExtension) ||
3828 eTargetProtocol != INetProtocol::File )
3830 aLine.append(
"/URI/URI" );
3834 aLine.append(
"/Launch/F" );
3846 aLine.append(
"/GoToR");
3851 aURLNoMark, rLink.
m_nObject, aLine, osl_getThreadTextEncoding() );
3852 if( !aFragment.isEmpty() )
3854 aLine.append(
"/D/");
3855 appendDestinationName( aFragment , aLine );
3863 bTargetHasPDFExtension && !aFragment.isEmpty() )
3865 OStringBuffer aLineLoc( 1024 );
3866 appendDestinationName( aFragment , aLineLoc );
3868 aTargetURL.SetMark( OStringToOUString(aLineLoc, RTL_TEXTENCODING_ASCII_US) );
3870 OUString
aURL = bUnparsedURI ? url :
3877 aURL , rLink.
m_nObject, aLine, osl_getThreadTextEncoding() );
3880 aLine.append(
">>\n" );
3884 aLine.append(
"/StructParent " );
3887 aLine.append(
">>\nendobj\n\n" );
3897void appendAnnotationRect(
tools::Rectangle const & rRectangle, OStringBuffer & aLine)
3899 aLine.append(
"/Rect[");
3900 appendFixedInt(rRectangle.
Left(), aLine);
3902 appendFixedInt(rRectangle.
Top(), aLine);
3904 appendFixedInt(rRectangle.
Right(), aLine);
3906 appendFixedInt(rRectangle.
Bottom(), aLine);
3916 aLine.append(
"<</Type /Annot /Subtype ");
3920 aLine.append(rPolygon.isClosed() ?
"/Polygon " :
"/Polyline ");
3921 aLine.append(
"/Vertices [");
3922 for (sal_uInt32
i = 0;
i < rPolygon.count(); ++
i)
3928 aLine, nLog10Divisor);
3932 aLine.append(
"/C [");
3935 if (rPolygon.isClosed())
3937 aLine.append(
"/IC [");
3944 aLine.append(
"/Ink /InkList [");
3948 for (sal_uInt32
i = 0;
i < rPolygon.count(); ++
i)
3955 aLine, nLog10Divisor);
3959 aLine.append(
"/C [");
3966 aLine.append(
"/FreeText ");
3968 aLine.append(
"/Text ");
3970 aLine.append(
"/BS<</W 0>>");
3975 aLine.append(
"/F 4 ");
3977 appendAnnotationRect(rNote.
m_aRect, aLine);
3979 aLine.append(
"/Popup ");
3984 aLine.append(
"/M (");
3985 appendPdfTimeDate(aLine, rDateTime.Year, rDateTime.Month, rDateTime.Day, rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds, 0);
3989 aLine.append(
"/Contents ");
3996 aLine.append(
"/T ");
4000 aLine.append(
">>\n");
4001 aLine.append(
"endobj\n\n");
4006 appendObjectID(rPopUp.
m_nObject, aLine);
4007 aLine.append(
"<</Type /Annot /Subtype /Popup ");
4008 aLine.append(
"/Parent ");
4010 aLine.append(
">>\n");
4011 aLine.append(
"endobj\n\n");
4018 for(
int i = 0;
i < nAnnots;
i++ )
4027 OStringBuffer aLine(1024);
4040 OStringBuffer aLine(1024);
4053 bool bAdjustSize =
false;
4055 Font aFont( rControlFont );
4058 aFont = rAppSetFont;
4085 sal_Int32 nBest = 4;
4094 aFontName = aFontName.toAsciiLowerCase();
4096 if( aFontName.indexOf(
"times" ) != -1 )
4098 else if( aFontName.indexOf(
"courier" ) != -1 )
4100 else if( aFontName.indexOf(
"dingbats" ) != -1 )
4102 else if( aFontName.indexOf(
"symbol" ) != -1 )
4149 OStringBuffer aDA( 256 );
4157 aDA.append(
" Tf" );
4176 rButton.
m_aMKDict =
"/BC [] /BG [] /CA";
4190 sal_Int32 nDelta =
GetDPIX() / 500;
4243 OStringBuffer aDA( 32 );
4248 OStringBuffer aDR( 32 );
4249 aDR.append(
"/Font " );
4251 aDR.append(
" 0 R" );
4252 rEdit.
m_aDRDict = aDR.makeStringAndClear();
4255 aDA.append(
" Tf" );
4301 OStringBuffer aDA( 256 );
4306 aDA.append( nBest );
4308 OStringBuffer aDR( 32 );
4309 aDR.append(
"/Font " );
4311 aDR.append(
" 0 R" );
4312 rBox.
m_aDRDict = aDR.makeStringAndClear();
4315 aDA.append(
" Tf" );
4338 sal_Int32 nDelta = aFontSize.
Height()/10;
4364 OStringBuffer aLW( 32 );
4367 aLW.append(
" w " );
4376 OStringBuffer aDA( 256 );
4390 const auto nGlyphWidth = pFontInstance->
GetGlyphWidth(nGlyphId,
false,
false);
4393 sal_Int32 nMappedFontObject;
4394 registerGlyph(nGlyphId, pFace, pFontInstance, { cMark }, nGlyphWidth, nMappedGlyph, nMappedFontObject);
4399 aDA.append( nMappedFontObject );
4400 aDA.append(
" 0 Tf" );
4402 OStringBuffer aDR( 32 );
4403 aDR.append(
"/Font " );
4405 aDR.append(
" 0 R" );
4406 rBox.
m_aDRDict = aDR.makeStringAndClear();
4413 sal_Int32 nCharXOffset = 1000 - 787;
4415 nCharXOffset /= 2000;
4416 sal_Int32 nCharYOffset = 1000 - (820-143);
4418 nCharYOffset /= 2000;
4423 aDA.append(
"/Tx BMC\nq BT\n" );
4427 aDA.append( nMappedFontObject );
4430 aDA.append(
" Tf\n" );
4434 aDA.append(
" Td <" );
4435 appendHex( nMappedGlyph, aDA );
4436 aDA.append(
"> Tj\nET\nQ\nEMC\n" );
4468 sal_Int32 nDelta = aFontSize.
Height()/10;
4494 OStringBuffer aLW( 32 );
4497 aLW.append(
" w " );
4518 OStringBuffer aDA( 256 );
4519 aDA.append(
"/Tx BMC\nq BT\n" );
4523 aDA.append(
" 0 0 Td\nET\nQ\n" );
4548 OString aStandardAppearance;
4560 rAnnotDict.append(
"/AP<<\n" );
4563 rAnnotDict.append(
"/" );
4564 rAnnotDict.append( dict_item.first );
4565 bool bUseSubDict = (dict_item.second.size() > 1);
4579 rAnnotDict.append( bUseSubDict ?
"<<" :
" " );
4581 for (
auto const& stream_item : dict_item.second)
4584 dict_item.second[ stream_item.first ] =
nullptr;
4588 sal_Int64 nStreamLen = pAppearanceStream->
TellEnd();
4596 OStringBuffer aLine;
4597 aLine.append( nObject );
4599 aLine.append(
" 0 obj\n"
4604 aLine.append(
" " );
4609 aLine.append(
" 0 R\n"
4611 aLine.append( nStreamLen );
4612 aLine.append(
"\n" );
4614 aLine.append(
"/Filter/FlateDecode\n" );
4615 aLine.append(
">>\nstream\n" );
4624 rAnnotDict.append(
" /" );
4625 rAnnotDict.append( stream_item.first );
4626 rAnnotDict.append(
" " );
4628 rAnnotDict.append( nObject );
4629 rAnnotDict.append(
" 0 R" );
4631 delete pAppearanceStream;
4634 rAnnotDict.append( bUseSubDict ?
">>\n" :
"\n" );
4636 rAnnotDict.append(
">>\n" );
4637 if( !aStandardAppearance.isEmpty() )
4639 rAnnotDict.append(
"/AS /" );
4640 rAnnotDict.append( aStandardAppearance );
4641 rAnnotDict.append(
"\n" );
4653 for(
int a = 0;
a < nAnnots;
a++ )
4664 auto stream_it = app_it->second.find(
"Yes" );
4665 if( stream_it != app_it->second.end() )
4668 app_it->second.erase( stream_it );
4671 (app_it->second)[
aBuf.makeStringAndClear() ] = pStream;
4674 SAL_INFO(
"vcl.pdfwriter",
"error: CheckBox without \"Yes\" stream" );
4683 auto stream_it = app_it->second.find(
"Off" );
4684 if( stream_it != app_it->second.end() )
4687 app_it->second.erase( stream_it );
4690 (app_it->second)[
aBuf.makeStringAndClear() ] = pStream;
4693 SAL_INFO(
"vcl.pdfwriter",
"error: CheckBox without \"Off\" stream" );
4698 OStringBuffer aLine( 1024 );
4699 OStringBuffer aValue( 256 );
4701 aLine.append(
" 0 obj\n"
4710 aLine.append(
"/Type/Annot/Subtype/Widget/F " );
4714 aLine.append(
"132\n" );
4719 aLine.append(
"4\n" );
4725 aLine.append(
"/StructParent ");
4730 aLine.append(
"/Rect[" );
4731 appendFixedInt( rWidget.
m_aRect.
Left()-iRectMargin, aLine );
4732 aLine.append(
' ' );
4733 appendFixedInt( rWidget.
m_aRect.
Top()+iRectMargin, aLine );
4734 aLine.append(
' ' );
4735 appendFixedInt( rWidget.
m_aRect.
Right()+iRectMargin, aLine );
4736 aLine.append(
' ' );
4737 appendFixedInt( rWidget.
m_aRect.
Bottom()-iRectMargin, aLine );
4738 aLine.append(
"]\n" );
4740 aLine.append(
"/FT/" );
4752 aValue.append(
"/" );
4755 aValue.append(
"Off" );
4757 appendName( rWidget.
m_aValue, aValue );
4761 aLine.append(
"Btn" );
4766 aValue.append(
"[" );
4774 aValue.append(
"]" );
4784 aLine.append(
"Ch" );
4788 aLine.append(
"Ch" );
4791 aLine.append(
"Tx" );
4795 aLine.append(
"Sig" );
4801 aLine.append(
"\n" );
4802 aLine.append(
"/P " );
4804 aLine.append(
" 0 R\n" );
4808 aLine.append(
"/Parent " );
4810 aLine.append(
" 0 R\n" );
4812 if( !rWidget.
m_aKids.empty() )
4814 aLine.append(
"/Kids[" );
4815 for(
size_t i = 0;
i < rWidget.
m_aKids.size();
i++ )
4817 aLine.append( rWidget.
m_aKids[
i] );
4818 aLine.append(
" 0 R" );
4819 aLine.append( ( (
i&15) == 15 ) ?
"\n" :
" " );
4821 aLine.append(
"]\n" );
4823 if( !rWidget.
m_aName.isEmpty() )
4825 aLine.append(
"/T" );
4827 aLine.append(
"\n" );
4833 aLine.append(
"/TU" );
4835 aLine.append(
"\n" );
4840 aLine.append(
"/Ff " );
4842 aLine.append(
"\n" );
4844 if( !aValue.isEmpty() )
4846 OString aVal = aValue.makeStringAndClear();
4847 aLine.append(
"/V " );
4848 aLine.append( aVal );
4851 aLine.append( aVal );
4852 aLine.append(
"\n" );
4857 aLine.append(
"/Opt[\n" );
4862 aLine.append(
"\n" );
4867 aLine.append(
"]\n" );
4870 aLine.append(
"/TI " );
4871 aLine.append( nTI );
4872 aLine.append(
"\n" );
4875 aLine.append(
"/I [" );
4876 aLine.append( nTI );
4877 aLine.append(
"]\n" );
4885 aLine.append(
"/MaxLen " );
4887 aLine.append(
"\n" );
4898 aHexText =
"\\\\u" + OString::number(cChar, 16);
4901 aLine.append(
"/AA<<\n");
4902 aLine.append(
"/F<</JS(AFNumber_Format\\(");
4904 aLine.append(
", 0, 0, 0, \"");
4905 aLine.append( aHexText );
4906 aLine.append(
"\",");
4908 aLine.append(
"\\);)");
4909 aLine.append(
"/S/JavaScript>>\n");
4910 aLine.append(
"/K<</JS(AFNumber_Keystroke\\(");
4912 aLine.append(
", 0, 0, 0, \"");
4913 aLine.append( aHexText );
4914 aLine.append(
"\",");
4916 aLine.append(
"\\);)");
4917 aLine.append(
"/S/JavaScript>>\n");
4918 aLine.append(
">>\n");
4922 aLine.append(
"/AA<<\n");
4923 aLine.append(
"/F<</JS(AFTime_FormatEx\\(\"");
4925 aLine.append(
"\"\\);)");
4926 aLine.append(
"/S/JavaScript>>\n");
4927 aLine.append(
"/K<</JS(AFTime_KeystrokeEx\\(\"");
4929 aLine.append(
"\"\\);)");
4930 aLine.append(
"/S/JavaScript>>\n");
4931 aLine.append(
">>\n");
4935 aLine.append(
"/AA<<\n");
4936 aLine.append(
"/F<</JS(AFDate_FormatEx\\(\"");
4938 aLine.append(
"\"\\);)");
4939 aLine.append(
"/S/JavaScript>>\n");
4940 aLine.append(
"/K<</JS(AFDate_KeystrokeEx\\(\"");
4942 aLine.append(
"\"\\);)");
4943 aLine.append(
"/S/JavaScript>>\n");
4944 aLine.append(
">>\n");
4951 OStringBuffer aDest;
4954 aLine.append(
"/AA<</D<</Type/Action/S/GoTo/D " );
4955 aLine.append( aDest );
4956 aLine.append(
">>>>\n" );
4963 aLine.append(
"/AA<</D<</Type/Action/S/ResetForm>>>>\n" );
4969 aLine.append(
"/AA<</D<</Type/Action/S/SubmitForm/F" );
4971 aLine.append(
"/Flags " );
4973 sal_Int32 nFlags = 0;
4991 aLine.append( nFlags );
4992 aLine.append(
">>>>\n" );
4997 aLine.append(
"/AA<</D<</Type/Action/S/URI/URI(" );
4999 aLine.append(
")>>>>\n" );
5009 aLine.append(
"/DR<<" );
5011 aLine.append(
">>\n" );
5015 aLine.append(
"/DR<</Font<<" );
5017 aLine.append(
">>>>\n" );
5019 aLine.append(
"/DA" );
5021 aLine.append(
"\n" );
5023 aLine.append(
"/Q 1\n" );
5025 aLine.append(
"/Q 2\n" );
5032 aLine.append(
"/MK<<" );
5036 aLine.append(
">>\n" );