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>
48#include <officecfg/Office/Common.hxx>
49#include <osl/file.hxx>
50#include <osl/thread.h>
51#include <rtl/digest.h>
53#include <rtl/ustrbuf.hxx>
86#include <textlayout.hxx>
95using namespace::com::sun::star;
102constexpr sal_Int32 nLog10Divisor = 3;
103constexpr double fDivisor = 1000.0;
105constexpr double pixelToPoint(
double px)
107 return px / fDivisor;
112 return sal_Int32(pt * fDivisor);
115void appendObjectID(sal_Int32 nObjectID, OStringBuffer & aLine)
117 aLine.append(nObjectID);
118 aLine.append(
" 0 obj\n");
121void appendObjectReference(sal_Int32 nObjectID, OStringBuffer & aLine)
123 aLine.append(nObjectID);
124 aLine.append(
" 0 R ");
127void appendHex(
sal_Int8 nInt, OStringBuffer& rBuffer)
129 static const char pHexDigits[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
130 '8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
131 rBuffer.append( pHexDigits[ (nInt >> 4) & 15 ] );
132 rBuffer.append( pHexDigits[ nInt & 15 ] );
135void appendName( std::u16string_view rStr, OStringBuffer& rBuffer )
140 int nLen =
aStr.getLength();
141 for(
int i = 0;
i < nLen;
i++ )
150 if( (aStr[i] >=
'A' && aStr[i] <=
'Z' ) ||
151 (aStr[i] >=
'a' && aStr[i] <=
'z' ) ||
152 (aStr[i] >=
'0' && aStr[i] <=
'9' ) ||
155 rBuffer.append( aStr[i] );
159 rBuffer.append(
'#' );
160 appendHex(
static_cast<sal_Int8>(aStr[i]), rBuffer );
165void appendName(
const char* pStr, OStringBuffer& rBuffer )
168 while( pStr && *pStr )
170 if( (*pStr >=
'A' && *pStr <=
'Z' ) ||
171 (*pStr >=
'a' && *pStr <=
'z' ) ||
172 (*pStr >=
'0' && *pStr <=
'9' ) ||
175 rBuffer.append( *pStr );
179 rBuffer.append(
'#' );
180 appendHex(
static_cast<sal_Int8>(*pStr), rBuffer );
187void appendLiteralString(
const char* pStr, sal_Int32 nLength, OStringBuffer& rBuffer )
194 rBuffer.append(
"\\n" );
197 rBuffer.append(
"\\r" );
200 rBuffer.append(
"\\t" );
203 rBuffer.append(
"\\b" );
206 rBuffer.append(
"\\f" );
211 rBuffer.append(
"\\" );
212 rBuffer.append(
static_cast<char>(*pStr) );
215 rBuffer.append(
static_cast<char>(*pStr) );
246void appendDestinationName(
const OUString& rString, OStringBuffer& rBuffer )
249 sal_Int32 nLen = rString.getLength();
250 for(
int i = 0;
i < nLen;
i++ )
253 if( (aChar >=
'0' && aChar <=
'9' ) ||
254 (aChar >=
'a' && aChar <=
'z' ) ||
255 (aChar >=
'A' && aChar <=
'Z' ) ||
258 rBuffer.append(
static_cast<char>(aChar));
264 appendHex( aValueHigh, rBuffer );
265 appendHex(
static_cast<sal_Int8>(aChar & 255 ), rBuffer );
276 0x28, 0xBF, 0x4E, 0x5E, 0x4E, 0x75, 0x8A, 0x41, 0x64, 0x00, 0x4E, 0x56, 0xFF, 0xFA, 0x01, 0x08,
277 0x2E, 0x2E, 0x00, 0xB6, 0xD0, 0x68, 0x3E, 0x80, 0x2F, 0x0C, 0xA9, 0xFE, 0x64, 0x53, 0x69, 0x7A
283template <
class GEOMETRY >
284GEOMETRY lcl_convert(
const MapMode& _rSource,
const MapMode& _rDest,
OutputDevice* _pPixelConversion,
const GEOMETRY& _rObject )
287 if ( MapUnit::MapPixel == _rSource.
GetMapUnit() )
289 aPoint = _pPixelConversion->
PixelToLogic( _rObject, _rDest );
302 rBuffer.append(
"FEFF" );
304 sal_Int32 nLen = rString.getLength();
305 for(
int i = 0;
i < nLen;
i++ )
308 appendHex(
static_cast<sal_Int8>(aChar >> 8), rBuffer );
309 appendHex(
static_cast<sal_Int8>(aChar & 255 ), rBuffer );
319 const OUString& rName = i_rControl.
Name;
321 int nLen =
aStr.getLength();
323 OStringBuffer
aBuffer( rName.getLength()+64 );
324 for(
int i = 0;
i < nLen;
i++ )
339 OString aFullName(
aBuffer.makeStringAndClear() );
342 sal_Int32 nTokenIndex = 0, nLastTokenIndex = 0;
343 OString aPartialName;
347 nLastTokenIndex = nTokenIndex;
348 aPartialName = aFullName.getToken( 0,
'.', nTokenIndex );
349 if( nTokenIndex != -1 )
353 aDomain = aFullName.copy( 0, nTokenIndex-1 );
354 std::unordered_map< OString, sal_Int32 >::const_iterator it =
m_aFieldNameMap.find( aDomain );
362 m_aWidgets[nNewWidget].m_aName = aPartialName;
366 if( nLastTokenIndex > 0 )
370 OString aParentDomain( aDomain.copy( 0, nLastTokenIndex-1 ) );
375 OSL_ENSURE( it->second < sal_Int32(
m_aWidgets.size()),
"invalid field number entry" );
376 if( it->second < sal_Int32(
m_aWidgets.size()) )
395 aPartialName = aFullName.copy( aFullName.lastIndexOf(
'.' )+1 );
396 if( nLastTokenIndex > 0 )
398 aDomain = aFullName.copy( 0, nLastTokenIndex-1 );
399 aFullName = aDomain +
"." + aPartialName;
402 aFullName = aPartialName;
406 }
while( nTokenIndex != -1 );
409 if( !aDomain.isEmpty() )
411 std::unordered_map< OString, sal_Int32 >::const_iterator it =
m_aFieldNameMap.find( aDomain );
419 m_aWidgets[it->second].m_aKidsIndex.push_back( i_nWidgetIndex );
424 if( aPartialName.isEmpty() )
429 aPartialName =
"RadioGroup" +
433 aPartialName = OString(
"Widget" );
438 std::unordered_map<OString, sal_Int32>::iterator it =
m_aFieldNameMap.find( aFullName );
442 std::unordered_map< OString, sal_Int32 >::const_iterator check_it;
447 aTry = aFullName +
"_" + OString::number(nTry++);
452 aPartialName = aFullName.copy( aFullName.lastIndexOf(
'.' )+1 );
459 m_aWidgets[i_nWidgetIndex].m_aName = aPartialName;
465void appendFixedInt( sal_Int32 nValue, OStringBuffer& rBuffer )
469 rBuffer.append(
'-' );
472 sal_Int32 nFactor = 1, nDiv = nLog10Divisor;
476 sal_Int32 nInt =
nValue / nFactor;
477 rBuffer.append( nInt );
478 if (nFactor > 1 && nValue % nFactor)
480 rBuffer.append(
'.' );
484 rBuffer.append((nValue / nFactor) % 10);
486 while (nFactor > 1 && nValue % nFactor);
491void appendDouble(
double fValue, OStringBuffer& rBuffer, sal_Int32 nPrecision = 10 )
500 sal_Int64 nInt =
static_cast<sal_Int64
>(fValue);
501 fValue -=
static_cast<double>(nInt);
503 if( rtl::math::approxEqual(fValue, 1.0) || log10( 1.0-fValue ) <= -nPrecision )
511 fValue *= pow( 10.0,
static_cast<double>(nPrecision) );
512 nFrac =
static_cast<sal_Int64
>(fValue);
514 if( bNeg && ( nInt || nFrac ) )
515 rBuffer.append(
'-' );
516 rBuffer.append( nInt );
521 rBuffer.append(
'.' );
522 sal_Int64 nBound =
static_cast<sal_Int64
>(pow( 10.0, nPrecision - 1.0 )+0.5);
523 for ( i = 0; (
i < nPrecision ) && nFrac;
i++ )
525 sal_Int64 nNumb = nFrac / nBound;
526 nFrac -= nNumb * nBound;
527 rBuffer.append( nNumb );
532void appendColor(
const Color& rColor, OStringBuffer& rBuffer,
bool bConvertToGrey )
535 if( rColor == COL_TRANSPARENT )
541 appendDouble(
static_cast<double>(cByte) / 255.0, rBuffer );
545 appendDouble(
static_cast<double>(rColor.
GetRed()) / 255.0, rBuffer );
546 rBuffer.append(
' ' );
547 appendDouble(
static_cast<double>(rColor.
GetGreen()) / 255.0, rBuffer );
548 rBuffer.append(
' ' );
549 appendDouble(
static_cast<double>(rColor.
GetBlue()) / 255.0, rBuffer );
560 appendColor( rColor, rBuffer, bGrey );
561 rBuffer.append( bGrey ?
" G" :
" RG" );
570 appendColor( rColor, rBuffer, bGrey );
571 rBuffer.append( bGrey ?
" g" :
" rg" );
578void appendPdfTimeDate(OStringBuffer & rBuffer,
579 sal_Int16 year, sal_uInt16 month, sal_uInt16 day, sal_uInt16 hours, sal_uInt16 minutes, sal_uInt16 seconds, sal_Int32 tzDelta)
581 rBuffer.append(
"D:");
582 rBuffer.append(
char(
'0' + ((year / 1000) % 10)));
583 rBuffer.append(
char(
'0' + ((year / 100) % 10)));
584 rBuffer.append(
char(
'0' + ((year / 10) % 10)));
585 rBuffer.append(
char(
'0' + (year % 10)));
586 rBuffer.append(
char(
'0' + ((month / 10) % 10)));
587 rBuffer.append(
char(
'0' + (month % 10)));
588 rBuffer.append(
char(
'0' + ((day / 10) % 10)));
589 rBuffer.append(
char(
'0' + (day % 10)));
590 rBuffer.append(
char(
'0' + ((hours / 10) % 10)));
591 rBuffer.append(
char(
'0' + (hours % 10)));
592 rBuffer.append(
char(
'0' + ((minutes / 10) % 10)));
593 rBuffer.append(
char(
'0' + (minutes % 10)));
594 rBuffer.append(
char(
'0' + ((seconds / 10) % 10)));
595 rBuffer.append(
char(
'0' + (seconds % 10)));
611 rBuffer.append(
char(
'0' + ((tzDelta / 36000) % 10)));
612 rBuffer.append(
char(
'0' + ((tzDelta / 3600) % 10)));
614 rBuffer.append(
char(
'0' + ((tzDelta / 600) % 6)));
615 rBuffer.append(
char(
'0' + ((tzDelta / 60) % 10)));
623 m_pWriter( pWriter ),
624 m_nPageWidth( nPageWidth ),
625 m_nPageHeight( nPageHeight ),
627 m_eOrientation( eOrientation ),
629 m_nStreamLengthObject( 0 ),
630 m_nBeginStreamPos( 0 ),
641 m_nUserUnit = std::ceil(std::max(nPageWidth, nPageHeight) / 14400.0);
654 m_pWriter->emitComment(
"PDFWriterImpl::PDFPage::beginStream, +");
664 +
" 0 obj\n<</Length "
668 aLine.append(
"/Filter/FlateDecode" );
669 aLine.append(
">>\nstream\n" );
686 sal_uInt64 nEndStreamPos;
687 if (osl::File::E_None !=
m_pWriter->m_aFile.getPos(nEndStreamPos))
694 if( !
m_pWriter->writeBuffer(
"\nendstream\nendobj\n\n" ) )
716 "<</Type/Page/Parent "
717 + OString::number(nParentObject)
720 + OString::number(
m_pWriter->getResourceDictObj())
724 aLine.append(
"/MediaBox[0 0 "
731 aLine.append(
"\n/UserUnit " + OString::number(
m_nUserUnit));
742 aLine.append(
"/Annots[\n" );
743 for(
int i = 0;
i < nAnnots;
i++ )
747 aLine.append( ((
i+1)%15) ?
" " :
"\n" );
749 aLine.append(
"]\n" );
750 if (PDFWriter::PDFVersion::PDF_1_5 <= m_pWriter->
m_aContext.Version)
753 aLine.append(
"/Tabs/S\n" );
758 OStringBuffer aStructParents( 1024 );
759 aStructParents.append(
"[ " );
761 for(
int i = 0;
i < nParents;
i++ )
765 aStructParents.append( ((
i%10) == 9) ?
"\n" :
" " );
767 aStructParents.append(
"]" );
768 m_pWriter->m_aStructParentTree.push_back( aStructParents.makeStringAndClear() );
770 aLine.append(
"/StructParents "
771 + OString::number( sal_Int32(
m_pWriter->m_aStructParentTree.size()-1) )
777 aLine.append(
"/Trans<</D " );
778 appendDouble(
static_cast<double>(
m_nTransTime)/1000.0, aLine, 3 );
779 aLine.append(
"\n" );
780 const char *pStyle =
nullptr, *pDm =
nullptr, *pM =
nullptr, *pDi =
nullptr;
784 pStyle =
"Split"; pDm =
"H"; pM =
"I";
break;
786 pStyle =
"Split"; pDm =
"H"; pM =
"O";
break;
788 pStyle =
"Split"; pDm =
"V"; pM =
"I";
break;
790 pStyle =
"Split"; pDm =
"V"; pM =
"O";
break;
792 pStyle =
"Blinds"; pDm =
"H";
break;
794 pStyle =
"Blinds"; pDm =
"V";
break;
796 pStyle =
"Box"; pM =
"I";
break;
798 pStyle =
"Box"; pM =
"O";
break;
800 pStyle =
"Wipe"; pDi =
"0";
break;
802 pStyle =
"Wipe"; pDi =
"90";
break;
804 pStyle =
"Wipe"; pDi =
"180";
break;
806 pStyle =
"Wipe"; pDi =
"270";
break;
808 pStyle =
"Dissolve";
break;
815 aLine.append( OString::Concat(
"/S/") + pStyle +
"\n" );
819 aLine.append( OString::Concat(
"/Dm/") + pDm +
"\n" );
823 aLine.append( OString::Concat(
"/M/") + pM +
"\n" );
827 aLine.append( OString::Concat(
"/Di ") + pDi +
"\n" );
829 aLine.append(
">>\n" );
832 aLine.append(
"/Contents" );
834 if( nStreamObjects > 1 )
838 aLine.append(
" " + OString::number(
i ) +
" 0 R" );
840 if( nStreamObjects > 1 )
842 aLine.append(
">>\nendobj\n\n" );
848 Point aPoint( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
853 sal_Int32
nValue = aPoint.X();
855 appendFixedInt(
nValue, rBuffer );
857 rBuffer.append(
' ' );
861 appendFixedInt(
nValue, rBuffer );
866 double fValue = pixelToPoint(rPoint.
getX());
868 appendDouble( fValue, rBuffer, nLog10Divisor );
869 rBuffer.append(
' ' );
871 appendDouble( fValue, rBuffer, nLog10Divisor );
877 rBuffer.append(
' ' );
879 rBuffer.append(
' ' );
881 rBuffer.append(
" re" );
886 Point aLL = lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
891 Size aSize = lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
903 sal_uInt16 nPoints = rPoly.
GetSize();
907 sal_uInt32 nBufLen = rBuffer.getLength();
913 rBuffer.append(
" m\n" );
914 for( sal_uInt16
i = 1;
i < nPoints;
i++ )
916 if( pFlagArray && pFlagArray[
i] == PolyFlags::Control && nPoints-
i > 2 )
919 SAL_WARN_IF( pFlagArray[
i+1] != PolyFlags::Control || pFlagArray[
i+2] == PolyFlags::Control,
"vcl.pdfwriter",
"unexpected sequence of control points" );
921 rBuffer.append(
" " );
923 rBuffer.append(
" " );
925 rBuffer.append(
" c" );
932 rBuffer.append(
" l" );
934 if( (rBuffer.getLength() - nBufLen) > 65 )
936 rBuffer.append(
"\n" );
937 nBufLen = rBuffer.getLength();
940 rBuffer.append(
" " );
943 rBuffer.append(
"h\n" );
958 rBuffer.append(
' ' );
960 rBuffer.append(
' ' );
962 rBuffer.append(
" re\n" );
965 sal_uInt32 nPoints = aPoly.
count();
969 sal_uInt32 nBufLen = rBuffer.getLength();
972 rBuffer.append(
" m\n" );
973 for( sal_uInt32
i = 1;
i <= nPoints;
i++ )
978 sal_uInt32 nLastPoint =
i-1;
984 rBuffer.append(
' ' );
986 rBuffer.append(
' ' );
988 rBuffer.append(
" c" );
993 rBuffer.append(
' ' );
995 rBuffer.append(
" y" );
1000 rBuffer.append(
' ' );
1002 rBuffer.append(
" v" );
1007 rBuffer.append(
" l" );
1009 if( (rBuffer.getLength() - nBufLen) > 65 )
1011 rBuffer.append(
"\n" );
1012 nBufLen = rBuffer.getLength();
1015 rBuffer.append(
" " );
1018 rBuffer.append(
"h\n" );
1023 sal_uInt16 nPolygons = rPolyPoly.
Count();
1024 for( sal_uInt16
n = 0;
n < nPolygons;
n++ )
1030 for(
auto const& rPolygon : rPolyPoly)
1039 rBuffer.append(
'-' );
1042 Size aSize( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
1050 appendFixedInt(
nValue, rBuffer );
1055 Size aSize( lcl_convert(
m_pWriter->m_aGraphicsStack.front().m_aMapMode,
1058 Size( 1000, 1000 ) ) );
1059 fLength *= pixelToPoint(
static_cast<double>(bVertical ? aSize.
Height() : aSize.
Width()) / 1000.0);
1060 appendDouble( fLength, rBuffer, nPrecision );
1065 if(
LineStyle::Dash == rInfo.GetStyle() && rInfo.GetDashLen() != rInfo.GetDotLen())
1069 if(2 * (rInfo.GetDashCount() + rInfo.GetDotCount()) > 10)
1081 if(css::drawing::LineCap_BUTT != rInfo.GetLineCap())
1089 rBuffer.append(
"[ " );
1090 if( rInfo.GetDashLen() == rInfo.GetDotLen() )
1093 rBuffer.append(
' ' );
1095 rBuffer.append(
' ' );
1099 for(
int n = 0;
n < rInfo.GetDashCount();
n++ )
1102 rBuffer.append(
' ' );
1104 rBuffer.append(
' ' );
1106 for(
int m = 0;
m < rInfo.GetDotCount();
m++ )
1109 rBuffer.append(
' ' );
1111 rBuffer.append(
' ' );
1114 rBuffer.append(
"] 0 d\n" );
1117 if( rInfo.GetWidth() > 1 )
1120 rBuffer.append(
" w\n" );
1122 else if( rInfo.GetWidth() == 0 )
1125 appendDouble( 72.0/
double(
m_pWriter->GetDPIX()), rBuffer );
1126 rBuffer.append(
" w\n" );
1139 rBuffer.append(
"0 " );
1141 rBuffer.append(
" m\n" );
1142 for( sal_Int32
n = 0;
n < nWidth; )
1146 rBuffer.append(
' ' );
1148 rBuffer.append(
' ' );
1151 rBuffer.append(
' ' );
1153 rBuffer.append(
" v " );
1158 rBuffer.append(
' ' );
1160 rBuffer.append(
' ' );
1163 rBuffer.append(
' ' );
1165 rBuffer.append(
" v\n" );
1168 rBuffer.append(
"S\n" );
1173 appendDouble(rMatrix.
get(0), rBuffer);
1174 rBuffer.append(
' ');
1175 appendDouble(rMatrix.
get(1), rBuffer);
1176 rBuffer.append(
' ');
1177 appendDouble(rMatrix.
get(2), rBuffer);
1178 rBuffer.append(
' ');
1179 appendDouble(rMatrix.
get(3), rBuffer);
1180 rBuffer.append(
' ');
1197 const css::uno::Reference< css::beans::XMaterialHolder >& xEnc,
1201 m_aWidgetStyleSettings(
Application::GetSettings().GetStyleSettings()),
1202 m_nCurrentStructElement( 0 ),
1203 m_bEmitStructure( true ),
1205 m_aPDFBmpCache(
utl::ConfigManager::IsFuzzing() ? 15 :
1206 officecfg::Office::Common::VCL::PDFExportImageCacheSize::
get()),
1207 m_nCurrentPage( -1 ),
1208 m_nCatalogObject(0),
1209 m_nSignatureObject( -1 ),
1210 m_nSignatureContentOffset( 0 ),
1211 m_nSignatureLastByteRangeNoOffset( 0 ),
1212 m_nResourceDict( -1 ),
1213 m_nFontDictObject( -1 ),
1218 m_aCipher( nullptr ),
1221 m_bEncryptThisStream( false ),
1222 m_nAccessPermissions(0),
1223 m_bIsPDF_A1( false ),
1224 m_bIsPDF_A2( false ),
1225 m_bIsPDF_UA( false ),
1226 m_bIsPDF_A3( false ),
1227 m_rOuterFace( i_rOuterFace )
1245 osl::File::RC aError =
m_aFile.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create);
1246 if (aError != osl::File::E_None)
1248 if (aError == osl::File::E_EXIST)
1250 aError =
m_aFile.open(osl_File_OpenFlag_Write);
1251 if (aError == osl::File::E_None)
1255 if (aError != osl::File::E_None)
1264 m_aCipher = rtl_cipher_createARCFOUR( rtl_Cipher_ModeStream );
1281 OSL_ENSURE(
false,
"encryption data failed sanity check, encryption disabled" );
1302 aBuffer.append(
"\n%\303\244\303\274\303\266\303\237\n" );
1368 std::vector< sal_uInt8 > aId;
1379 TimeValue aTVal, aGMT;
1381 osl_getSystemTime(&aGMT);
1382 osl_getLocalTimeFromSystemTime(&aGMT, &aTVal);
1383 osl_getDateTimeFromTimeValue(&aTVal, &aDT);
1385 sal_Int32 nDelta = aTVal.Seconds-aGMT.Seconds;
1387 appendPdfTimeDate(aRet, aDT.Year, aDT.Month, aDT.Day, aDT.Hours, aDT.Minutes, aDT.Seconds, nDelta);
1390 return aRet.makeStringAndClear();
1395 const OString& i_rCString1,
1396 OString& o_rCString2
1399 o_rIdentifier.clear();
1402 OString aInfoValuesOut;
1403 OStringBuffer aID( 1024 );
1404 if( !i_rDocInfo.
Title.isEmpty() )
1406 if( !i_rDocInfo.
Author.isEmpty() )
1408 if( !i_rDocInfo.
Subject.isEmpty() )
1410 if( !i_rDocInfo.
Keywords.isEmpty() )
1412 if( !i_rDocInfo.
Creator.isEmpty() )
1414 if( !i_rDocInfo.
Producer.isEmpty() )
1417 TimeValue aTVal, aGMT;
1419 osl_getSystemTime( &aGMT );
1420 osl_getLocalTimeFromSystemTime( &aGMT, &aTVal );
1421 osl_getDateTimeFromTimeValue( &aTVal, &aDT );
1422 OStringBuffer aCreationMetaDateString(64);
1430 aCreationMetaDateString.append(
1431 OStringChar(
static_cast<char>(
'0' + ((aDT.Year/1000)%10)) )
1432 + OStringChar(
static_cast<char>(
'0' + ((aDT.Year/100)%10)) )
1433 + OStringChar(
static_cast<char>(
'0' + ((aDT.Year/10)%10)) )
1434 + OStringChar(
static_cast<char>(
'0' + ((aDT.Year)%10)) )
1436 + OStringChar(
static_cast<char>(
'0' + ((aDT.Month/10)%10)) )
1437 + OStringChar(
static_cast<char>(
'0' + ((aDT.Month)%10)) )
1439 + OStringChar(
static_cast<char>(
'0' + ((aDT.Day/10)%10)) )
1440 + OStringChar(
static_cast<char>(
'0' + ((aDT.Day)%10)) )
1442 + OStringChar(
static_cast<char>(
'0' + ((aDT.Hours/10)%10)) )
1443 + OStringChar(
static_cast<char>(
'0' + ((aDT.Hours)%10)) )
1445 + OStringChar(
static_cast<char>(
'0' + ((aDT.Minutes/10)%10)) )
1446 + OStringChar(
static_cast<char>(
'0' + ((aDT.Minutes)%10)) )
1448 + OStringChar(
static_cast<char>(
'0' + ((aDT.Seconds/10)%10)) )
1449 + OStringChar(
static_cast<char>(
'0' + ((aDT.Seconds)%10)) ));
1451 sal_uInt32 nDelta = 0;
1452 if( aGMT.Seconds > aTVal.Seconds )
1454 nDelta = aGMT.Seconds-aTVal.Seconds;
1455 aCreationMetaDateString.append(
"-" );
1457 else if( aGMT.Seconds < aTVal.Seconds )
1459 nDelta = aTVal.Seconds-aGMT.Seconds;
1460 aCreationMetaDateString.append(
"+" );
1464 aCreationMetaDateString.append(
"Z" );
1469 aCreationMetaDateString.append(
1470 OStringChar(
static_cast<char>(
'0' + ((nDelta/36000)%10)) )
1471 + OStringChar(
static_cast<char>(
'0' + ((nDelta/3600)%10)) )
1473 + OStringChar(
static_cast<char>(
'0' + ((nDelta/600)%6)) )
1474 + OStringChar(
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";
1577 sal_uInt64 nEndPos = pStream->
TellEnd();
1579 ZCodec aCodec( 0x4000, 0x4000 );
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;
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;
1686 OStringBuffer
aBuf( 16 );
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 = ~0
U;
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( OString::number(nObject)
1788 for( sal_Int32
n = 0;
n < nTreeItems;
n++ )
1790 aLine.append( OString::number(
n) +
" "
1794 aLine.append(
"]>>\nendobj\n\n" );
1804 return "id" + OString::number(nObjectId);
1815 std::map<OString, sal_Int32> ids;
1821 appendObjectID(nObject, buf);
1822 buf.append(
"<</Names [\n");
1823 for (
auto const& it : ids)
1827 appendObjectReference(it.second, buf);
1830 buf.append(
"] >>\nendobj\n\n");
1840 static std::map< PDFWriter::StructAttribute, const char* > aAttributeStrings;
1842 if( aAttributeStrings.empty() )
1869 std::map< PDFWriter::StructAttribute, const char* >::const_iterator it =
1870 aAttributeStrings.find( eAttr );
1872 if( it == aAttributeStrings.end() )
1873 SAL_INFO(
"vcl.pdfwriter",
"invalid PDFWriter::StructAttribute " << eAttr);
1875 return it != aAttributeStrings.end() ? it->second :
"";
1880 static std::map< PDFWriter::StructAttributeValue, const char* > aValueStrings;
1882 if( aValueStrings.empty() )
1926 std::map< PDFWriter::StructAttributeValue, const char* >::const_iterator it =
1927 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();
2107 OSL_FAIL(
"PDFWriterImpl::emitStructure: invalid child structure element" );
2108 SAL_INFO(
"vcl.pdfwriter",
"PDFWriterImpl::emitStructure: invalid child structure element with id " << child);
2114 OSL_FAIL(
"PDFWriterImpl::emitStructure: invalid child structure id" );
2115 SAL_INFO(
"vcl.pdfwriter",
"PDFWriterImpl::emitStructure: invalid child structure id " << child);
2119 OStringBuffer aLine( 512 );
2124 sal_Int32 nParentTree = -1;
2125 sal_Int32 nIDTree = -1;
2130 aLine.append(
"/StructTreeRoot\n"
2132 + OString::number(nParentTree)
2136 aLine.append(
"/RoleMap<<" );
2139 aLine.append(
"/" + role.first +
"/" + role.second +
"\n" );
2141 aLine.append(
">>\n" );
2146 aLine.append(
"/IDTree ");
2147 appendObjectReference(nIDTree, aLine);
2153 aLine.append(
"/StructElem\n"
2161 aLine.append(
"\n/ID ");
2174 aLine.append(
"/ActualText" );
2176 aLine.append(
"\n" );
2180 aLine.append(
"/Alt" );
2182 aLine.append(
"\n" );
2188 if( !aAttribs.isEmpty() )
2190 aLine.append(
"/A" + aAttribs +
"\n" );
2193 if( !rEle.
m_aLocale.Language.isEmpty() )
2202 OUString aLanguage, aScript, aCountry;
2204 if (!aLanguage.isEmpty())
2206 OUStringBuffer aLocBuf( 16 );
2207 aLocBuf.append( aLanguage );
2208 if( !aCountry.isEmpty() )
2210 aLocBuf.append(
"-" + aCountry );
2212 aLine.append(
"/Lang" );
2214 aLine.append(
"\n" );
2239 aLine.append(
"/K[" );
2240 for (
auto const& kid : rEle.
m_aKids)
2242 if( kid.nMCID == -1 )
2245 OString::number(kid.nObject)
2247 aLine.append( ( (
i & 15) == 15 ) ?
"\n" :
" " );
2253 aLine.append( OString::number(kid.nMCID) +
" " );
2259 + OString::number(kid.nObject)
2261 + OString::number(kid.nMCID)
2267 aLine.append(
"]\n" );
2269 aLine.append(
">>\nendobj\n\n" );
2291 OStringBuffer aTilingObj( 1024 );
2295 SAL_WARN_IF( !tiling.m_pTilingStream,
"vcl.pdfwriter",
"tiling without stream" );
2296 if( ! tiling.m_pTilingStream )
2299 aTilingObj.setLength( 0 );
2306 sal_Int32 nX =
static_cast<sal_Int32
>(tiling.m_aRectangle.Left());
2307 sal_Int32 nY =
static_cast<sal_Int32
>(tiling.m_aRectangle.Top());
2308 sal_Int32 nW =
static_cast<sal_Int32
>(tiling.m_aRectangle.GetWidth());
2309 sal_Int32 nH =
static_cast<sal_Int32
>(tiling.m_aRectangle.GetHeight());
2310 if( tiling.m_aCellSize.Width() == 0 )
2311 tiling.m_aCellSize.setWidth( nW );
2312 if( tiling.m_aCellSize.Height() == 0 )
2313 tiling.m_aCellSize.setHeight( nH );
2316 sal_uInt64
const nTilingStreamSize = tiling.m_pTilingStream->TellEnd();
2321 OString::number(tiling.m_nObject)
2323 "<</Type/Pattern/PatternType 1\n"
2327 appendFixedInt( nX, aTilingObj );
2328 aTilingObj.append(
' ' );
2329 appendFixedInt( nY, aTilingObj );
2330 aTilingObj.append(
' ' );
2331 appendFixedInt( nX+nW, aTilingObj );
2332 aTilingObj.append(
' ' );
2333 appendFixedInt( nY+nH, aTilingObj );
2334 aTilingObj.append(
"]\n"
2336 appendFixedInt( tiling.m_aCellSize.Width(), aTilingObj );
2337 aTilingObj.append(
"\n"
2339 appendFixedInt( tiling.m_aCellSize.Height(), aTilingObj );
2340 aTilingObj.append(
"\n" );
2341 if( tiling.m_aTransform.matrix[0] != 1.0 ||
2342 tiling.m_aTransform.matrix[1] != 0.0 ||
2343 tiling.m_aTransform.matrix[3] != 0.0 ||
2344 tiling.m_aTransform.matrix[4] != 1.0 ||
2345 tiling.m_aTransform.matrix[2] != 0.0 ||
2346 tiling.m_aTransform.matrix[5] != 0.0 )
2348 aTilingObj.append(
"/Matrix [" );
2350 appendDouble( tiling.m_aTransform.matrix[0], aTilingObj );
2351 aTilingObj.append(
' ' );
2352 appendDouble( tiling.m_aTransform.matrix[1], aTilingObj );
2353 aTilingObj.append(
' ' );
2354 appendDouble( tiling.m_aTransform.matrix[3], aTilingObj );
2355 aTilingObj.append(
' ' );
2356 appendDouble( tiling.m_aTransform.matrix[4], aTilingObj );
2357 aTilingObj.append(
' ' );
2358 appendDouble( tiling.m_aTransform.matrix[2], aTilingObj );
2359 aTilingObj.append(
' ' );
2360 appendDouble( tiling.m_aTransform.matrix[5], aTilingObj );
2361 aTilingObj.append(
"]\n" );
2363 aTilingObj.append(
"/Resources" );
2366 aTilingObj.append(
"/Filter/FlateDecode" );
2367 aTilingObj.append(
"/Length "
2368 + OString::number(
static_cast<sal_Int32
>(nTilingStreamSize))
2373 bool written =
writeBufferBytes( tiling.m_pTilingStream->GetData(), nTilingStreamSize );
2374 tiling.m_pTilingStream.reset();
2378 aTilingObj.setLength( 0 );
2379 aTilingObj.append(
"\nendstream\nendobj\n\n" );
2391 OStringBuffer aLine( 1024 );
2393 if( nFontObject <= 0 )
2397 OString::number(nFontObject)
2399 "<</Type/Font/Subtype/Type1/BaseFont/" );
2400 appendName( rBuildinFont.
m_pPSName, aLine );
2401 aLine.append(
"\n" );
2402 if( rBuildinFont.
m_eCharSet == RTL_TEXTENCODING_MS_1252 )
2403 aLine.append(
"/Encoding/WinAnsiEncoding\n" );
2404 aLine.append(
">>\nendobj\n\n" );
2412int XUnits(
int nUPEM,
int n) {
return (n * 1000) / nUPEM; }
2417 std::map< sal_Int32, sal_Int32 > aRet;
2430 sal_Int32 pWidths[256] = { 0 };
2433 for(
sal_Ucs c = 32; c < 256; c++ )
2442 std::vector<sal_uInt8>
aBuffer;
2447 if( nFontDescriptor )
2453 OStringBuffer aLine( 1024 );
2455 OString::number(nObject)
2457 "<</Type/Font/Subtype/TrueType"
2460 aLine.append(
"\n" );
2462 aLine.append(
"/Encoding/WinAnsiEncoding\n" );
2463 aLine.append(
"/FirstChar 32 /LastChar 255\n"
2465 for(
int i = 32;
i < 256;
i++ )
2467 aLine.append( pWidths[
i] );
2468 aLine.append( ((
i&15) == 15) ?
"\n" :
" " );
2472 + OString::number( nFontDescriptor )
2486uint32_t fillSubsetArrays(
const FontEmit& rSubset,
sal_GlyphId* pGlyphIds, sal_Int32* pWidths,
2487 sal_uInt8* pEncoding, sal_Int32* pEncToUnicodeIndex,
2488 sal_Int32* pCodeUnitsPerGlyph, std::vector<sal_Ucs>& rCodeUnits,
2489 sal_Int32& nToUnicodeStream)
2491 rCodeUnits.reserve(256);
2496 uint32_t nGlyphs = 1;
2499 sal_uInt8 nEnc = item.second.getGlyphId();
2501 SAL_WARN_IF(pGlyphIds[nEnc] != 0 || pEncoding[nEnc] != 0,
"vcl.pdfwriter",
2505 pGlyphIds[nEnc] = item.first;
2506 pEncoding[nEnc] = nEnc;
2507 pEncToUnicodeIndex[nEnc] =
static_cast<sal_Int32
>(rCodeUnits.size());
2508 pCodeUnitsPerGlyph[nEnc] = item.second.countCodes();
2509 pWidths[nEnc] = item.second.getGlyphWidth();
2510 for (sal_Int32 n = 0;
n < pCodeUnitsPerGlyph[nEnc];
n++)
2511 rCodeUnits.push_back(item.second.getCode(n));
2512 if (item.second.getCode(0))
2513 nToUnicodeStream = 1;
2517 OSL_FAIL(
"too many glyphs for subset");
2526 std::map<sal_Int32, sal_Int32>& rFontIDToObject)
2536 std::vector<sal_uInt8>
aBuffer;
2542 sal_Int32 pWidths[256];
2544 sal_Int32 pEncToUnicodeIndex[256] = {};
2545 sal_Int32 pCodeUnitsPerGlyph[256] = {};
2546 std::vector<sal_Ucs> aCodeUnits;
2547 sal_Int32 nToUnicodeStream = 0;
2550 auto nGlyphs = fillSubsetArrays(rSubset, pGlyphIds, pWidths, pEncoding, pEncToUnicodeIndex,
2551 pCodeUnitsPerGlyph, aCodeUnits, nToUnicodeStream);
2554 sal_Int32 nFontDescriptor = 0;
2558 if (nToUnicodeStream)
2560 pEncToUnicodeIndex, nGlyphs);
2567 OStringBuffer aLine(1024);
2569 OString::number(nFontObject)
2571 "<</Type/Font/Subtype/Type3/Name/");
2572 appendName(aSubsetInfo.
m_aPSName, aLine);
2589 + OString::number(nScale)
2591 + OString::number(nScale)
2594 sal_Int32 pGlyphStreams[256] = {};
2595 aLine.append(
"/CharProcs<<\n");
2596 for (
auto i = 1u;
i < nGlyphs;
i++)
2602 + OString::number(nStream)
2604 pGlyphStreams[
i] = nStream;
2608 "/Encoding<</Type/Encoding/Differences[1");
2609 for (
auto i = 1u;
i < nGlyphs;
i++)
2610 aLine.append(
" /" + pFace->
GetGlyphName(pGlyphIds[
i],
true));
2611 aLine.append(
"]>>\n"
2615 + OString::number(nGlyphs)
2619 for (
auto i = 0
u;
i < nGlyphs;
i++)
2621 aLine.append(OString::number(pWidths[
i]) +
" ");
2623 aLine.append(
"]\n");
2627 aLine.append(
"/FontDescriptor " + OString::number(nFontDescriptor) +
" 0 R\n");
2631 aLine.append(
"/Resources " + OString::number(nResources) +
" 0 R\n");
2633 if (nToUnicodeStream)
2635 aLine.append(
"/ToUnicode " + OString::number(nToUnicodeStream) +
" 0 R\n");
2644 std::set<sal_Int32> aUsedFonts;
2645 std::list<BitmapEmit> aUsedBitmaps;
2646 std::map<sal_uInt8, sal_Int32> aUsedAlpha;
2648 std::list<StreamRedirect> aOutputStreams;
2650 for (
auto i = 1u;
i < nGlyphs;
i++)
2652 auto nStream = pGlyphStreams[
i];
2655 OStringBuffer aContents(1024);
2656 aContents.append(OString::number(pWidths[
i]) +
" 0 d0\n");
2658 const auto& rGlyph = rSubset.
m_aMapping.find(pGlyphIds[
i])->second;
2659 const auto& rLayers = rGlyph.getColorLayers();
2660 for (
const auto& rLayer : rLayers)
2662 aUsedFonts.insert(rLayer.m_nFontID);
2664 aContents.append(
"q ");
2666 if (rLayer.m_nColorIndex != 0xFFFF)
2668 auto& rPalette = rColorPalettes[0];
2669 auto aColor(rPalette[rLayer.m_nColorIndex]);
2671 aContents.append(
" ");
2672 if (aColor.GetAlpha() != 0xFF
2675 auto nAlpha = aColor.GetAlpha();
2676 OStringBuffer
aName(16);
2678 appendHex(nAlpha,
aName);
2680 aContents.append(
"/" +
aName +
" gs ");
2682 if (aUsedAlpha.find(nAlpha) == aUsedAlpha.end())
2685 aUsedAlpha[nAlpha] = nObject;
2687 nObject, aResourceDict, aOutputStreams);
2693 "/F" + OString::number(rLayer.m_nFontID) +
" "
2694 + OString::number(pFace->
UnitsPerEm()) +
" Tf "
2696 appendHex(rLayer.m_nSubsetGlyphID, aContents);
2704 const auto& rBitmapData = rGlyph.getColorBitmap(aRect);
2705 if (!rBitmapData.empty())
2707 SvMemoryStream aStream(
const_cast<uint8_t*
>(rBitmapData.data()), rBitmapData.size(),
2711 aUsedBitmaps, aResourceDict, aOutputStreams);
2713 auto nObject = aBitmapEmit.m_aReferenceXObject.getObject();
2716 + OString::number(aRect.
GetWidth())
2720 + OString::number(aRect.
getX())
2722 + OString::number(aRect.
getY())
2725 + OString::number(nObject)
2729 const auto& rOutline = rGlyph.getOutline();
2730 if (rOutline.count())
2733 aContents.append(
"q 10 0 0 10 0 ");
2734 appendDouble(
m_aPages.back().getHeight() * -10, aContents, 3);
2735 aContents.append(
" cm\n");
2736 m_aPages.back().appendPolyPolygon(rOutline, aContents);
2737 aContents.append(
"f\n"
2742 aLine.append(OString::number(nStream)
2743 +
" 0 obj\n<</Length "
2744 + OString::number(aContents.getLength())
2751 aLine.append(
"endstream\nendobj\n\n");
2759 aLine.append(OString::number(nFontDict) +
" 0 obj\n<<");
2760 for (
auto nFontID : aUsedFonts)
2763 + OString::number(nFontID)
2765 + OString::number(rFontIDToObject[nFontID])
2768 aLine.append(
">>\nendobj\n\n");
2775 if (!aUsedAlpha.empty())
2777 for (
const auto & [ nAlpha, nObject ] : aUsedAlpha)
2780 aLine.append(OString::number(nObject) +
" 0 obj\n<<");
2783 aLine.append(
"/CA 1.0/ca 1.0");
2788 aLine.append(
"/CA ");
2789 appendDouble(nAlpha / 255., aLine);
2790 aLine.append(
"/ca ");
2791 appendDouble(nAlpha / 255., aLine);
2793 aLine.append(
">>\nendobj\n\n");
2802 for (
auto& aBitmap : aUsedBitmaps)
2807 aLine.append(OString::number(nResources) +
" 0 obj\n");
2808 aResourceDict.
append(aLine, nFontDict);
2809 aLine.append(
"endobj\n\n");
2815 rFontIDToObject[rSubset.
m_nFontID] = nFontObject;
2825 if( !pFontBytes || (nByteLen < 0) )
2827 const unsigned char* pPtr = pFontBytes;
2828 const unsigned char* pEnd = pFontBytes + nByteLen;
2830 for(
int & rSegmentLength : rSegmentLengths) {
2832 if( pPtr+6 >= pEnd )
2834 if( (pPtr[0] != 0x80) || (pPtr[1] >= 0x03) )
2836 const int nLen = (pPtr[5]<<24) + (pPtr[4]<<16) + (pPtr[3]<<8) + pPtr[2];
2839 rSegmentLength = nLen;
2844 if( pPtr+2 >= pEnd )
2846 if( (pPtr[0] != 0x80) || (pPtr[1] != 0x03) )
2852static void appendSubsetName(
int nSubsetID, std::u16string_view rPSName, OStringBuffer& rBuffer )
2856 for(
int i = 0;
i < 6;
i++ )
2858 int nOffset = nSubsetID % 26;
2860 rBuffer.append(
static_cast<char>(
'A'+nOffset) );
2862 rBuffer.append(
'+' );
2864 appendName( rPSName, rBuffer );
2868 const std::vector<sal_Ucs>& rCodeUnits,
2869 const sal_Int32* pCodeUnitsPerGlyph,
2870 const sal_Int32* pEncToUnicodeIndex,
2874 for (
auto n = 0
u;
n < nGlyphs; ++
n)
2875 if (pCodeUnitsPerGlyph[
n] && rCodeUnits[pEncToUnicodeIndex[
n]])
2884 OStringBuffer aContents( 1024 );
2886 "/CIDInit/ProcSet findresource begin\n"
2889 "/CIDSystemInfo<<\n"
2890 "/Registry (Adobe)\n"
2894 "/CMapName/Adobe-Identity-UCS def\n"
2896 "1 begincodespacerange\n"
2898 "endcodespacerange\n"
2901 for (
auto n = 0
u;
n < nGlyphs; ++
n)
2903 if (pCodeUnitsPerGlyph[
n] && rCodeUnits[pEncToUnicodeIndex[
n]])
2905 if( (
nCount % 100) == 0 )
2908 aContents.append(
"endbfchar\n" );
2909 aContents.append( OString::number(
static_cast<sal_Int32
>(std::min(nMapped-
nCount, 100)) )
2910 +
" beginbfchar\n" );
2912 aContents.append(
'<' );
2913 appendHex(
static_cast<sal_Int8>(pEncoding[
n]), aContents );
2914 aContents.append(
"> <" );
2916 sal_Int32
nIndex = pEncToUnicodeIndex[
n];
2917 for( sal_Int32 j = 0; j < pCodeUnitsPerGlyph[
n]; j++ )
2919 appendHex(
static_cast<sal_Int8>(rCodeUnits[
nIndex + j] / 256), aContents );
2920 appendHex(
static_cast<sal_Int8>(rCodeUnits[
nIndex + j] & 255), aContents );
2922 aContents.append(
">\n" );
2926 aContents.append(
"endbfchar\n"
2928 "CMapName currentdict /CMap defineresource pop\n"
2934 ZCodec aCodec( 0x4000, 0x4000 );
2936 aCodec.
Write( aStream,
reinterpret_cast<const sal_uInt8*
>(aContents.getStr()), aContents.getLength() );
2942 emitComment(
"PDFWriterImpl::createToUnicodeCMap" );
2944 OStringBuffer aLine( 40 );
2946 aLine.append( OString::number(nStream ) +
" 0 obj\n<</Length " );
2950 nLen =
static_cast<sal_Int32
>(aStream.
Tell());
2952 aLine.append( OString::number(nLen) +
"/Filter/FlateDecode" );
2955 aLine.append( aContents.getLength() );
2956 aLine.append(
">>\nstream\n" );
2968 aLine.setLength( 0 );
2969 aLine.append(
"\nendstream\n"
2977 OStringBuffer aLine( 1024 );
2981 sal_Int32 nFontFlags = (1<<2);
2983 nFontFlags |= (1 << 6);
2987 nFontFlags |= (1 << 3);
2989 nFontFlags |= (1 << 1);
2993 aLine.setLength( 0 );
2995 OString::number(nFontDescriptor)
2997 "<</Type/FontDescriptor/FontName/" );
3001 + OString::number( nFontFlags )
3007 + OString::number(
static_cast<sal_Int32
>(rInfo.
m_aFontBBox.
Top()) )
3012 +
"]/ItalicAngle " );
3014 aLine.append(
"-30" );
3016 aLine.append(
"0" );
3019 + OString::number(
static_cast<sal_Int32
>(rInfo.
m_nAscent) )
3022 + OString::number(
static_cast<sal_Int32
>(-rInfo.
m_nDescent) )
3025 + OString::number(
static_cast<sal_Int32
>(rInfo.
m_nCapHeight) )
3032 aLine.append(
"/FontFile" );
3036 aLine.append(
'2' );
3043 OSL_FAIL(
"unknown fonttype in PDF font descriptor" );
3046 aLine.append(
" " + OString::number(nFontStream) +
" 0 R\n" );
3048 aLine.append(
">>\n"
3052 return nFontDescriptor;
3060 rDict.append(
' ' );
3061 rDict.append( item.second );
3062 rDict.append(
" 0 R" );
3068 OStringBuffer aLine( 1024 );
3070 std::map< sal_Int32, sal_Int32 > aFontIDToObject;
3074 for (
auto & s_subset :subset.second.m_aSubsets)
3077 sal_Int32 pWidths[ 256 ];
3079 sal_Int32 pEncToUnicodeIndex[ 256 ] = {};
3080 sal_Int32 pCodeUnitsPerGlyph[ 256 ] = {};
3081 std::vector<sal_Ucs> aCodeUnits;
3082 sal_Int32 nToUnicodeStream = 0;
3085 auto nGlyphs = fillSubsetArrays(s_subset, pGlyphIds, pWidths, pEncoding, pEncToUnicodeIndex,
3086 pCodeUnitsPerGlyph, aCodeUnits, nToUnicodeStream);
3088 std::vector<sal_uInt8>
aBuffer;
3090 const auto* pFace = subset.first;
3091 if (pFace->CreateFontSubset(
aBuffer, pGlyphIds, pEncoding, nGlyphs, aSubsetInfo))
3101 aLine.setLength( 0 );
3102 aLine.append( OString::number(nFontStream)
3105 + OString::number( nStreamLengthObject ) );
3107 aLine.append(
" 0 R"
3108 "/Filter/FlateDecode"
3111 aLine.append(
" 0 R"
3114 sal_uInt64 nStartPos = 0;
3117 aLine.append( OString::number(
static_cast<sal_Int32
>(
aBuffer.size()))
3121 if ( osl::File::E_None !=
m_aFile.getPos(nStartPos) )
return false;
3132 OSL_FAIL(
"PDFWriterImpl does not support CFF-font subsets yet!" );
3141 aLine.append( OString::number(
static_cast<sal_Int32
>(aSegmentLengths[0]) )
3143 + OString::number(
static_cast<sal_Int32
>(aSegmentLengths[1]) )
3145 + OString::number(
static_cast<sal_Int32
>(aSegmentLengths[2]) )
3149 if ( osl::File::E_None !=
m_aFile.getPos(nStartPos) )
return false;
3156 if ( !
writeBufferBytes( &
aBuffer[18] + aSegmentLengths[0] + aSegmentLengths[1], aSegmentLengths[2] ) )
return false;
3160 SAL_INFO(
"vcl.pdfwriter",
"PDF: CreateFontSubset result in not yet supported format=" <<
static_cast<int>(aSubsetInfo.
m_nFontType));
3161 aLine.append(
"0 >>\nstream\n" );
3167 sal_uInt64 nEndPos = 0;
3168 if ( osl::File::E_None !=
m_aFile.getPos(nEndPos) )
return false;
3170 aLine.setLength( 0 );
3171 aLine.append(
"\nendstream\nendobj\n\n" );
3175 if ( !
updateObject( nStreamLengthObject ) )
return false;
3176 aLine.setLength( 0 );
3177 aLine.append( OString::number(nStreamLengthObject)
3179 + OString::number(
static_cast<sal_Int64
>(nEndPos-nStartPos) )
3184 sal_Int32 nFontDescriptor =
emitFontDescriptor( subset.first, aSubsetInfo, s_subset.m_nFontID, nFontStream );
3186 if( nToUnicodeStream )
3187 nToUnicodeStream =
createToUnicodeCMap( pEncoding, aCodeUnits, pCodeUnitsPerGlyph, pEncToUnicodeIndex, nGlyphs );
3191 aLine.setLength( 0 );
3192 aLine.append( OString::number(nFontObject) +
" 0 obj\n" );
3194 "<</Type/Font/Subtype/Type1/BaseFont/" :
3195 "<</Type/Font/Subtype/TrueType/BaseFont/" );
3200 + OString::number(
static_cast<sal_Int32
>(nGlyphs-1) )
3203 for (
auto i = 0
u;
i < nGlyphs;
i++)
3205 aLine.append( pWidths[
i ] );
3206 aLine.append( ((
i & 15) == 15) ?
"\n" :
" " );
3210 + OString::number( nFontDescriptor )
3212 if( nToUnicodeStream )
3214 aLine.append(
"/ToUnicode "
3215 + OString::number( nToUnicodeStream )
3218 aLine.append(
">>\n"
3222 aFontIDToObject[ s_subset.m_nFontID ] = nFontObject;
3226 OStringBuffer aErrorComment( 256 );
3227 aErrorComment.append(
"CreateFontSubset failed for font \""
3231 aErrorComment.append(
" italic" );
3233 aErrorComment.append(
" oblique" );
3234 aErrorComment.append(
" weight=" + OString::number( sal_Int32(pFace->GetWeight()) ) );
3243 std::map< sal_Int32, sal_Int32 > aObjects =
emitSystemFont( systemFont.first, systemFont.second );
3244 for (
auto const& item : aObjects)
3246 if ( !item.second )
return false;
3247 aFontIDToObject[ item.first ] = item.second;
3258 OStringBuffer aFontDict( 1024 );
3263 for (
auto const& itemMap : aFontIDToObject)
3265 aFontDict.append(
"/F"
3266 + OString::number( itemMap.first )
3268 + OString::number( itemMap.second )
3270 if( ((++ni) & 7) == 0 )
3271 aFontDict.append(
'\n' );
3281 aFontDict.append(
"\n>>\nendobj\n\n" );
3301 OStringBuffer aLine( 512 );
3304 aLine.setLength( 0 );
3305 aLine.append( OString::number(nResourceDict)
3308 aLine.append(
"endobj\n\n" );
3310 return nResourceDict;
3314 sal_Int32 nItemLevel,
3315 sal_Int32 nCurrentItemId )
3332 for( sal_Int32
i = 0;
i < nChildren;
i++ )
3334 rCounts[nCurrentItemId] =
nCount;
3345 rCounts[ nCurrentItemId ] = -sal_Int32(rItem.
m_aChildren.size());
3346 for( sal_Int32
i = 0;
i < nChildren;
i++ )
3363 for(
i = 0;
i < nItems; ++
i )
3367 for(
i = 0;
i < nItems; ++
i )
3374 for(
int n = 0;
n < nChildren; ++
n )
3387 std::vector< sal_Int32 > aCounts( nItems );
3391 for(
i = 0;
i < nItems; ++
i )
3394 OStringBuffer aLine( 1024 );
3397 aLine.append( OString::number(rItem.
m_nObject)
3401 if(
i > 0 || aCounts[0] > 0 )
3403 aLine.append(
"/Count " + OString::number( aCounts[
i] ) );
3408 aLine.append(
"/First "
3417 aLine.append(
"/Title" );
3419 aLine.append(
"\n" );
3423 aLine.append(
"/Dest" );
3426 aLine.append(
"/Parent "
3431 aLine.append(
"/Prev "
3437 aLine.append(
"/Next "
3442 aLine.append(
">>\nendobj\n\n" );
3450#define CHECK_RETURN( x ) if( !x ) return false
3456 SAL_INFO(
"vcl.pdfwriter",
"ERROR: invalid dest " <<
static_cast<int>(nDestID) <<
" requested");
3463 rBuffer.append(
'[' );
3465 rBuffer.append(
" 0 R" );
3471 rBuffer.append(
"/XYZ " );
3473 rBuffer.append(
' ' );
3475 rBuffer.append(
" 0" );
3478 rBuffer.append(
"/FitR " );
3480 rBuffer.append(
' ' );
3481 appendFixedInt( rDest.
m_aRect.
Top(), rBuffer );
3482 rBuffer.append(
' ' );
3484 rBuffer.append(
' ' );
3488 rBuffer.append(
']' );
3497 rAttachedFile.maFilename = rFileName;
3498 rAttachedFile.maMimeType = rMimeType;
3499 rAttachedFile.maDescription = rDescription;
3500 rAttachedFile.mnEmbeddedFileObjectId = nObjectID;
3508 rEmbedded.m_nObject = aObjectID;
3509 rEmbedded.m_aSubType = rMimeType;
3510 rEmbedded.m_pStream = std::move(rStream);
3526 for (
int i = 0;
i < nAnnots;
i++)
3530 OStringBuffer aLine;
3531 bool bEmbed =
false;
3543 aLine.append(
" 0 obj\n");
3544 aLine.append(
"<< /Type /EmbeddedFile /Length ");
3545 aLine.append(
static_cast<sal_Int64
>(aMemoryStream.
GetSize()));
3546 aLine.append(
" >>\nstream\n");
3552 aLine.append(
"\nendstream\nendobj\n\n");
3561 aLine.append(OString::number(rScreen.
m_nObject)
3564 "/Subtype/Screen/Rect[");
3567 appendFixedInt(rScreen.
m_aRect.
Top(), aLine);
3575 aLine.append(
"/A<</Type/Action /S/Rendition /AN "
3580 aLine.append(
"/R<</Type/Rendition /S/MR ");
3583 aLine.append(
"/C<</Type/MediaClip /S/MCD ");
3586 aLine.append(
"\n/D << /Type /Filespec /F (<embedded file>) ");
3589 aLine.append(
"/UF (<embedded file>) ");
3591 aLine.append(
"/EF << /F ");
3593 aLine.append(
" 0 R >>");
3598 aLine.append(
"\n/D << /Type /Filespec /FS /URL /F ");
3602 aLine.append(
"/UF ");
3609 aLine.append(
"/Desc ");
3612 aLine.append(
" >>\n");
3614 aLine.append(
"/P <</TF (TEMPACCESS)>>");
3616 aLine.append(
"/CT ");
3620 aLine.append(
" /Alt [ () ");
3626 aLine.append(
"/P<</BE<</C true >>>>"
3630 aLine.append(
"/OP 0 >>");
3634 aLine.append(
"\n/StructParent "
3642 +
" 0 R\n>>\nendobj\n\n");
3651 MARK(
"PDFWriterImpl::emitLinkAnnotations");
3653 for(
int i = 0;
i < nAnnots;
i++ )
3659 OStringBuffer aLine( 1024 );
3661 aLine.append(
" 0 obj\n" );
3664 aLine.append(
"<</Type/Annot" );
3666 aLine.append(
"/F 4" );
3667 aLine.append(
"/Subtype/Link/Border[0 0 0]/Rect[" );
3670 aLine.append(
' ' );
3671 appendFixedInt( rLink.
m_aRect.
Top(), aLine );
3672 aLine.append(
' ' );
3674 aLine.append(
' ' );
3676 aLine.append(
"]" );
3678 aLine.append(
"/Contents");
3682 aLine.append(
"/Dest" );
3713 bool bSetGoToRMode =
false;
3714 bool bTargetHasPDFExtension =
false;
3716 bool bIsUNCPath =
false;
3717 bool bUnparsedURI =
false;
3722 if( eTargetProtocol == INetProtocol::NotValid )
3724 if( url.getLength() > 4 && url.startsWith(
"\\\\\\\\"))
3734 u"http://ahost.ax"),
3742 bUnparsedURI = eTargetProtocol == INetProtocol::NotValid;
3746 OUString aFileExtension =
aTargetURL.GetFileExtension();
3754 if( !aFileExtension.isEmpty() )
3758 bool bChangeFileExtensionToPDF =
false;
3760 if( aFileExtension.equalsIgnoreAsciiCase(
"odm" ) )
3761 bChangeFileExtensionToPDF =
true;
3762 if( aFileExtension.equalsIgnoreAsciiCase(
"odt" ) )
3763 bChangeFileExtensionToPDF =
true;
3764 else if( aFileExtension.equalsIgnoreAsciiCase(
"odp" ) )
3765 bChangeFileExtensionToPDF =
true;
3766 else if( aFileExtension.equalsIgnoreAsciiCase(
"odg" ) )
3767 bChangeFileExtensionToPDF =
true;
3768 else if( aFileExtension.equalsIgnoreAsciiCase(
"ods" ) )
3769 bChangeFileExtensionToPDF =
true;
3770 if( bChangeFileExtensionToPDF )
3774 bTargetHasPDFExtension =
aTargetURL.GetFileExtension().equalsIgnoreAsciiCase(
"pdf" );
3776 bSetGoToRMode =
true;
3781 aLine.append(
"/A<</Type/Action/S");
3784 aLine.append(
"/Launch/Win<</F" );
3787 aLine.append(
">>" );
3791 bool bSetRelative =
false;
3792 bool bFileSpec =
false;
3794 if(
m_aContext.
RelFsys && eBaseProtocol == eTargetProtocol && eTargetProtocol == INetProtocol::File )
3795 bSetRelative =
true;
3798 if( !bSetGoToRMode )
3805 aLine.append(
"/URI/URI" );
3815 if( (!aFragment.isEmpty() && !bTargetHasPDFExtension) ||
3816 eTargetProtocol != INetProtocol::File )
3818 aLine.append(
"/URI/URI" );
3822 aLine.append(
"/Launch/F" );
3834 aLine.append(
"/GoToR");
3839 aURLNoMark, rLink.
m_nObject, aLine, osl_getThreadTextEncoding() );
3840 if( !aFragment.isEmpty() )
3842 aLine.append(
"/D/");
3843 appendDestinationName( aFragment , aLine );
3851 bTargetHasPDFExtension && !aFragment.isEmpty() )
3853 OStringBuffer aLineLoc( 1024 );
3854 appendDestinationName( aFragment , aLineLoc );
3856 aTargetURL.SetMark( OStringToOUString(aLineLoc, RTL_TEXTENCODING_ASCII_US) );
3858 OUString
aURL = bUnparsedURI ? url :
3865 aURL , rLink.
m_nObject, aLine, osl_getThreadTextEncoding() );
3868 aLine.append(
">>\n" );
3872 aLine.append(
"/StructParent " );
3875 aLine.append(
">>\nendobj\n\n" );
3885void appendAnnotationRect(
tools::Rectangle const & rRectangle, OStringBuffer & aLine)
3887 aLine.append(
"/Rect[");
3888 appendFixedInt(rRectangle.
Left(), aLine);
3890 appendFixedInt(rRectangle.
Top(), aLine);
3892 appendFixedInt(rRectangle.
Right(), aLine);
3894 appendFixedInt(rRectangle.
Bottom(), aLine);
3904 aLine.append(
"<</Type /Annot /Subtype /Text ");
3909 aLine.append(
"/F 4 ");
3911 appendAnnotationRect(rNote.
m_aRect, aLine);
3913 aLine.append(
"/Popup ");
3918 aLine.append(
"/M (");
3919 appendPdfTimeDate(aLine, rDateTime.Year, rDateTime.Month, rDateTime.Day, rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds, 0);
3923 aLine.append(
"/Contents ");
3930 aLine.append(
"/T ");
3934 aLine.append(
">>\n");
3935 aLine.append(
"endobj\n\n");
3940 appendObjectID(rPopUp.
m_nObject, aLine);
3941 aLine.append(
"<</Type /Annot /Subtype /Popup ");
3942 aLine.append(
"/Parent ");
3944 aLine.append(
">>\n");
3945 aLine.append(
"endobj\n\n");
3952 for(
int i = 0;
i < nAnnots;
i++ )
3961 OStringBuffer aLine(1024);
3974 OStringBuffer aLine(1024);
3987 bool bAdjustSize =
false;
3989 Font aFont( rControlFont );
3992 aFont = rAppSetFont;
4019 sal_Int32 nBest = 4;
4028 aFontName = aFontName.toAsciiLowerCase();
4030 if( aFontName.indexOf(
"times" ) != -1 )
4032 else if( aFontName.indexOf(
"courier" ) != -1 )
4034 else if( aFontName.indexOf(
"dingbats" ) != -1 )
4036 else if( aFontName.indexOf(
"symbol" ) != -1 )
4083 OStringBuffer aDA( 256 );
4091 aDA.append(
" Tf" );
4110 rButton.
m_aMKDict =
"/BC [] /BG [] /CA";
4124 sal_Int32 nDelta =
GetDPIX() / 500;
4177 OStringBuffer aDA( 32 );
4182 OStringBuffer aDR( 32 );
4183 aDR.append(
"/Font " );
4185 aDR.append(
" 0 R" );
4186 rEdit.
m_aDRDict = aDR.makeStringAndClear();
4189 aDA.append(
" Tf" );
4235 OStringBuffer aDA( 256 );
4240 aDA.append( nBest );
4242 OStringBuffer aDR( 32 );
4243 aDR.append(
"/Font " );
4245 aDR.append(
" 0 R" );
4246 rBox.
m_aDRDict = aDR.makeStringAndClear();
4249 aDA.append(
" Tf" );
4272 sal_Int32 nDelta = aFontSize.
Height()/10;
4298 OStringBuffer aLW( 32 );
4301 aLW.append(
" w " );
4310 OStringBuffer aDA( 256 );
4324 const auto nGlyphWidth = pFontInstance->
GetGlyphWidth(nGlyphId,
false,
false);
4327 sal_Int32 nMappedFontObject;
4328 registerGlyph(nGlyphId, pFace, pFontInstance, { cMark }, nGlyphWidth, nMappedGlyph, nMappedFontObject);
4333 aDA.append( nMappedFontObject );
4334 aDA.append(
" 0 Tf" );
4336 OStringBuffer aDR( 32 );
4337 aDR.append(
"/Font " );
4339 aDR.append(
" 0 R" );
4340 rBox.
m_aDRDict = aDR.makeStringAndClear();
4347 sal_Int32 nCharXOffset = 1000 - 787;
4349 nCharXOffset /= 2000;
4350 sal_Int32 nCharYOffset = 1000 - (820-143);
4352 nCharYOffset /= 2000;
4357 aDA.append(
"/Tx BMC\nq BT\n" );
4361 aDA.append( nMappedFontObject );
4364 aDA.append(
" Tf\n" );
4368 aDA.append(
" Td <" );
4369 appendHex( nMappedGlyph, aDA );
4370 aDA.append(
"> Tj\nET\nQ\nEMC\n" );
4402 sal_Int32 nDelta = aFontSize.
Height()/10;
4428 OStringBuffer aLW( 32 );
4431 aLW.append(
" w " );
4452 OStringBuffer aDA( 256 );
4453 aDA.append(
"/Tx BMC\nq BT\n" );
4457 aDA.append(
" 0 0 Td\nET\nQ\n" );
4482 OString aStandardAppearance;
4494 rAnnotDict.append(
"/AP<<\n" );
4497 rAnnotDict.append(
"/" );
4498 rAnnotDict.append( dict_item.first );
4499 bool bUseSubDict = (dict_item.second.size() > 1);
4513 rAnnotDict.append( bUseSubDict ?
"<<" :
" " );
4515 for (
auto const& stream_item : dict_item.second)
4518 dict_item.second[ stream_item.first ] =
nullptr;
4522 sal_Int64 nStreamLen = pAppearanceStream->
TellEnd();
4530 OStringBuffer aLine;
4531 aLine.append( nObject );
4533 aLine.append(
" 0 obj\n"
4538 aLine.append(
" " );
4543 aLine.append(
" 0 R\n"
4545 aLine.append( nStreamLen );
4546 aLine.append(
"\n" );
4548 aLine.append(
"/Filter/FlateDecode\n" );
4549 aLine.append(
">>\nstream\n" );
4558 rAnnotDict.append(
" /" );
4559 rAnnotDict.append( stream_item.first );
4560 rAnnotDict.append(
" " );
4562 rAnnotDict.append( nObject );
4563 rAnnotDict.append(
" 0 R" );
4565 delete pAppearanceStream;
4568 rAnnotDict.append( bUseSubDict ?
">>\n" :
"\n" );
4570 rAnnotDict.append(
">>\n" );
4571 if( !aStandardAppearance.isEmpty() )
4573 rAnnotDict.append(
"/AS /" );
4574 rAnnotDict.append( aStandardAppearance );
4575 rAnnotDict.append(
"\n" );
4587 for(
int a = 0;
a < nAnnots;
a++ )
4598 auto stream_it = app_it->second.find(
"Yes" );
4599 if( stream_it != app_it->second.end() )
4602 app_it->second.erase( stream_it );
4605 (app_it->second)[
aBuf.makeStringAndClear() ] = pStream;
4608 SAL_INFO(
"vcl.pdfwriter",
"error: CheckBox without \"Yes\" stream" );
4617 auto stream_it = app_it->second.find(
"Off" );
4618 if( stream_it != app_it->second.end() )
4621 app_it->second.erase( stream_it );
4624 (app_it->second)[
aBuf.makeStringAndClear() ] = pStream;
4627 SAL_INFO(
"vcl.pdfwriter",
"error: CheckBox without \"Off\" stream" );
4632 OStringBuffer aLine( 1024 );
4633 OStringBuffer aValue( 256 );
4635 aLine.append(
" 0 obj\n"
4644 aLine.append(
"/Type/Annot/Subtype/Widget/F " );
4648 aLine.append(
"132\n" );
4653 aLine.append(
"4\n" );
4659 aLine.append(
"/StructParent ");
4664 aLine.append(
"/Rect[" );
4665 appendFixedInt( rWidget.
m_aRect.
Left()-iRectMargin, aLine );
4666 aLine.append(
' ' );
4667 appendFixedInt( rWidget.
m_aRect.
Top()+iRectMargin, aLine );
4668 aLine.append(
' ' );
4669 appendFixedInt( rWidget.
m_aRect.
Right()+iRectMargin, aLine );
4670 aLine.append(
' ' );
4671 appendFixedInt( rWidget.
m_aRect.
Bottom()-iRectMargin, aLine );
4672 aLine.append(
"]\n" );
4674 aLine.append(
"/FT/" );
4686 aValue.append(
"/" );
4689 aValue.append(
"Off" );
4691 appendName( rWidget.
m_aValue, aValue );
4695 aLine.append(
"Btn" );
4700 aValue.append(
"[" );
4708 aValue.append(
"]" );
4718 aLine.append(
"Ch" );
4722 aLine.append(
"Ch" );
4725 aLine.append(
"Tx" );
4729 aLine.append(
"Sig" );
4735 aLine.append(
"\n" );
4736 aLine.append(
"/P " );
4738 aLine.append(
" 0 R\n" );
4742 aLine.append(
"/Parent " );
4744 aLine.append(
" 0 R\n" );
4746 if( !rWidget.
m_aKids.empty() )
4748 aLine.append(
"/Kids[" );
4749 for(
size_t i = 0;
i < rWidget.
m_aKids.size();
i++ )
4751 aLine.append( rWidget.
m_aKids[
i] );
4752 aLine.append(
" 0 R" );
4753 aLine.append( ( (
i&15) == 15 ) ?
"\n" :
" " );
4755 aLine.append(
"]\n" );
4757 if( !rWidget.
m_aName.isEmpty() )
4759 aLine.append(
"/T" );
4761 aLine.append(
"\n" );
4767 aLine.append(
"/TU" );
4769 aLine.append(
"\n" );
4774 aLine.append(
"/Ff " );
4776 aLine.append(
"\n" );
4778 if( !aValue.isEmpty() )
4780 OString aVal = aValue.makeStringAndClear();
4781 aLine.append(
"/V " );
4782 aLine.append( aVal );
4785 aLine.append( aVal );
4786 aLine.append(
"\n" );
4791 aLine.append(
"/Opt[\n" );
4796 aLine.append(
"\n" );
4801 aLine.append(
"]\n" );
4804 aLine.append(
"/TI " );
4805 aLine.append( nTI );
4806 aLine.append(
"\n" );
4809 aLine.append(
"/I [" );
4810 aLine.append( nTI );
4811 aLine.append(
"]\n" );
4819 aLine.append(
"/MaxLen " );
4821 aLine.append(
"\n" );
4832 aHexText =
"\\\\u" + OString::number(cChar, 16);
4835 aLine.append(
"/AA<<\n");
4836 aLine.append(
"/F<</JS(AFNumber_Format\\(");
4838 aLine.append(
", 0, 0, 0, \"");
4839 aLine.append( aHexText );
4840 aLine.append(
"\",");
4842 aLine.append(
"\\);)");
4843 aLine.append(
"/S/JavaScript>>\n");
4844 aLine.append(
"/K<</JS(AFNumber_Keystroke\\(");
4846 aLine.append(
", 0, 0, 0, \"");
4847 aLine.append( aHexText );
4848 aLine.append(
"\",");
4850 aLine.append(
"\\);)");
4851 aLine.append(
"/S/JavaScript>>\n");
4852 aLine.append(
">>\n");
4856 aLine.append(
"/AA<<\n");
4857 aLine.append(
"/F<</JS(AFTime_FormatEx\\(\"");
4859 aLine.append(
"\"\\);)");
4860 aLine.append(
"/S/JavaScript>>\n");
4861 aLine.append(
"/K<</JS(AFTime_KeystrokeEx\\(\"");
4863 aLine.append(
"\"\\);)");
4864 aLine.append(
"/S/JavaScript>>\n");
4865 aLine.append(
">>\n");
4869 aLine.append(
"/AA<<\n");
4870 aLine.append(
"/F<</JS(AFDate_FormatEx\\(\"");
4872 aLine.append(
"\"\\);)");
4873 aLine.append(
"/S/JavaScript>>\n");
4874 aLine.append(
"/K<</JS(AFDate_KeystrokeEx\\(\"");
4876 aLine.append(
"\"\\);)");
4877 aLine.append(
"/S/JavaScript>>\n");
4878 aLine.append(
">>\n");
4885 OStringBuffer aDest;
4888 aLine.append(
"/AA<</D<</Type/Action/S/GoTo/D " );
4889 aLine.append( aDest );
4890 aLine.append(
">>>>\n" );
4897 aLine.append(
"/AA<</D<</Type/Action/S/ResetForm>>>>\n" );
4903 aLine.append(
"/AA<</D<</Type/Action/S/SubmitForm/F" );
4905 aLine.append(
"/Flags " );
4907 sal_Int32 nFlags = 0;
4925 aLine.append( nFlags );
4926 aLine.append(
">>>>\n" );
4931 aLine.append(
"/AA<</D<</Type/Action/S/URI/URI(" );
4933 aLine.append(
")>>>>\n" );
4943 aLine.append(
"/DR<<" );
4945 aLine.append(
">>\n" );
4949 aLine.append(
"/DR<</Font<<" );
4951 aLine.append(
">>>>\n" );
4953 aLine.append(
"/DA" );
4955 aLine.append(
"\n" );
4957 aLine.append(
"/Q 1\n" );
4959 aLine.append(
"/Q 2\n" );
4966 aLine.append(
"/MK<<" );
4970 aLine.append(
">>\n" );
4975 aLine.append(
">>\n"
4996class PDFStreamIf :
public cppu::WeakImplHelper< css::io::XOutputStream >
5003 virtual void SAL_CALL
writeBytes(
const css::uno::Sequence< sal_Int8 >& aData )
override
5007 sal_Int32 nBytes =
aData.getLength();
5011 virtual void SAL_CALL
flush()
override {}
5028 OStringBuffer aLine;
5029 aLine.append(rEmbeddedFile.m_nObject);
5030 aLine.append(
" 0 obj\n");
5031 aLine.append(
"<< /Type /EmbeddedFile");