Kaydet (Commit) 51af3179 authored tarafından Muhammet Kara's avatar Muhammet Kara

Support bitmap PDF export for Redaction

* Add a new parameter IsRedactMode (SID_IS_REDACT_MODE) to .uno:ExportDirectToPDF
* Make sure the new param makes it into PDFExport as part of FilterData
* Hijack the metafile before being sent to ImplExportPage(), convert to bitmap, and replace the original
* Add a new entry to GenericCommands.xcu to make our button with param visible

* Nitpick: For things to be included in the bitmap conversion,
           they need to be added to the metafile before the conversion
           in PDFExport::ExportSelection(). Things added after that point
           (inside ImplExportPage() for example) will not be bitmapped/pixelized

Change-Id: Iec7020917da920a968ea969b98e53f17eadaa275
Reviewed-on: https://gerrit.libreoffice.org/67108
Tested-by: Jenkins
Reviewed-by: 's avatarMuhammet Kara <muhammet.kara@collabora.com>
üst fb95d74f
...@@ -117,6 +117,8 @@ PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc, ...@@ -117,6 +117,8 @@ PDFExport::PDFExport( const Reference< XComponent >& rxSrcDoc,
mnProgressValue ( 0 ), mnProgressValue ( 0 ),
mbRemoveTransparencies ( false ), mbRemoveTransparencies ( false ),
mbIsRedactMode ( false ),
mbHideViewerToolbar ( false ), mbHideViewerToolbar ( false ),
mbHideViewerMenubar ( false ), mbHideViewerMenubar ( false ),
mbHideViewerWindowControls ( false ), mbHideViewerWindowControls ( false ),
...@@ -229,6 +231,24 @@ bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter, ...@@ -229,6 +231,24 @@ bool PDFExport::ExportSelection( vcl::PDFWriter& rPDFWriter,
if( aMtf.GetActionSize() && if( aMtf.GetActionSize() &&
( !mbSkipEmptyPages || aPageSize.Width || aPageSize.Height ) ) ( !mbSkipEmptyPages || aPageSize.Width || aPageSize.Height ) )
{ {
// We convert the whole metafile into a bitmap to get rid of the
// text covered by redaction shapes
if (mbIsRedactMode)
{
try
{
Graphic aGraph(aMtf);
BitmapEx bmp = aGraph.GetBitmapEx();
Graphic bgraph(bmp);
aMtf = bgraph.GetGDIMetaFile();
}
catch(const Exception& e)
{
SAL_WARN("filter.pdf", "Something went wrong while converting metafile to bitmap. Exception: "
<< e.Message);
}
}
ImplExportPage(rPDFWriter, rPDFExtOutDevData, aMtf); ImplExportPage(rPDFWriter, rPDFExtOutDevData, aMtf);
bRet = true; bRet = true;
} }
...@@ -559,6 +579,9 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >& ...@@ -559,6 +579,9 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
rFilterData[ nData ].Value >>= mbExportPlaceholders; rFilterData[ nData ].Value >>= mbExportPlaceholders;
else if ( rFilterData[ nData ].Name == "UseReferenceXObject" ) else if ( rFilterData[ nData ].Name == "UseReferenceXObject" )
rFilterData[ nData ].Value >>= mbUseReferenceXObject; rFilterData[ nData ].Value >>= mbUseReferenceXObject;
// Redaction & bitmap related stuff
else if ( rFilterData[ nData ].Name == "IsRedactMode" )
rFilterData[ nData ].Value >>= mbIsRedactMode;
} }
aContext.URL = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri); aContext.URL = aURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
......
...@@ -65,6 +65,8 @@ private: ...@@ -65,6 +65,8 @@ private:
sal_Int32 mnProgressValue; sal_Int32 mnProgressValue;
bool mbRemoveTransparencies; bool mbRemoveTransparencies;
bool mbIsRedactMode;
OUString msWatermark; OUString msWatermark;
// these variable are here only to have a location in filter/pdf to set the default // these variable are here only to have a location in filter/pdf to set the default
......
...@@ -46,11 +46,12 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor ) ...@@ -46,11 +46,12 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
Sequence< PropertyValue > aFilterData; Sequence< PropertyValue > aFilterData;
sal_Int32 nLength = rDescriptor.getLength(); sal_Int32 nLength = rDescriptor.getLength();
const PropertyValue* pValue = rDescriptor.getConstArray(); const PropertyValue* pValue = rDescriptor.getConstArray();
bool bIsRedactMode = false;
bool bRet = false; bool bRet = false;
Reference< task::XStatusIndicator > xStatusIndicator; Reference< task::XStatusIndicator > xStatusIndicator;
Reference< task::XInteractionHandler > xIH; Reference< task::XInteractionHandler > xIH;
for ( sal_Int32 i = 0 ; ( i < nLength ) && !xOStm.is(); ++i) for (sal_Int32 i = 0 ; ( i < nLength ) && !xOStm.is(); ++i)
{ {
if ( pValue[ i ].Name == "OutputStream" ) if ( pValue[ i ].Name == "OutputStream" )
pValue[ i ].Value >>= xOStm; pValue[ i ].Value >>= xOStm;
...@@ -62,6 +63,12 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor ) ...@@ -62,6 +63,12 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
pValue[i].Value >>= xIH; pValue[i].Value >>= xIH;
} }
for (sal_Int32 i = 0 ; i < nLength; ++i)
{
if ( pValue[i].Name == "IsRedactMode")
pValue[i].Value >>= bIsRedactMode;
}
/* we don't get FilterData if we are exporting directly /* we don't get FilterData if we are exporting directly
to pdf, but we have to use the last user settings (especially for the CompressMode) */ to pdf, but we have to use the last user settings (especially for the CompressMode) */
if ( !aFilterData.getLength() ) if ( !aFilterData.getLength() )
...@@ -109,9 +116,36 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor ) ...@@ -109,9 +116,36 @@ bool PDFFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
aCfgItem.ReadBool( "ExportBookmarks", true ); aCfgItem.ReadBool( "ExportBookmarks", true );
aCfgItem.ReadBool( "ExportHiddenSlides", false ); aCfgItem.ReadBool( "ExportHiddenSlides", false );
aCfgItem.ReadInt32( "OpenBookmarkLevels", -1 ); aCfgItem.ReadInt32( "OpenBookmarkLevels", -1 );
aCfgItem.ReadBool( "IsRedactMode", false);
aFilterData = aCfgItem.GetFilterData(); aFilterData = aCfgItem.GetFilterData();
} }
if (bIsRedactMode)
{
bool bFound = false;
for (int i = 0; i < aFilterData.getLength(); ++i)
{
if (aFilterData[i].Name == "IsRedactMode")
{
aFilterData[i].Value <<= bIsRedactMode;
bFound = true;
break;
}
}
if (!bFound)
{
sal_Int32 nNewSize = aFilterData.getLength() + 1;
aFilterData.realloc( nNewSize );
aFilterData[nNewSize - 1].Name = "IsRedactMode";
aFilterData[nNewSize - 1].Value <<= bIsRedactMode;
}
}
if( mxSrcDoc.is() && xOStm.is() ) if( mxSrcDoc.is() && xOStm.is() )
{ {
PDFExport aExport( mxSrcDoc, xStatusIndicator, xIH, mxContext ); PDFExport aExport( mxSrcDoc, xStatusIndicator, xIH, mxContext );
......
...@@ -256,8 +256,9 @@ class SfxDocumentInfoItem; ...@@ -256,8 +256,9 @@ class SfxDocumentInfoItem;
// Used to export a temporary file for preview in Mail Merge Wizard, where saving the data source is // Used to export a temporary file for preview in Mail Merge Wizard, where saving the data source is
// not required for preview, but interferes with not-yet-saved embedded data source for main document. // not required for preview, but interferes with not-yet-saved embedded data source for main document.
#define SID_NO_EMBEDDED_DS TypedWhichId<SfxBoolItem>(SID_SFX_START + 1731) #define SID_NO_EMBEDDED_DS TypedWhichId<SfxBoolItem>(SID_SFX_START + 1731)
#define SID_IS_REDACT_MODE (SID_SFX_START + 1733)
// SID_SFX_free_START (SID_SFX_START + 1733) // SID_SFX_free_START (SID_SFX_START + 1734)
// SID_SFX_free_END (SID_SFX_START + 3999) // SID_SFX_free_END (SID_SFX_START + 3999)
#define SID_OPEN_NEW_VIEW (SID_SFX_START + 520) #define SID_OPEN_NEW_VIEW (SID_SFX_START + 520)
......
...@@ -4991,6 +4991,20 @@ ...@@ -4991,6 +4991,20 @@
<value>1</value> <value>1</value>
</prop> </prop>
</node> </node>
<node oor:name=".uno:ExportDirectToPDF?IsRedactMode:bool=true" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">Sanitized PDF</value>
</prop>
<prop oor:name="ContextLabel" oor:type="xs:string">
<value xml:lang="en-US">Export Directly to PDF as Bitmap</value>
</prop>
<prop oor:name="TooltipLabel" oor:type="xs:string">
<value xml:lang="en-US">Export Directly to PDF as Bitmap</value>
</prop>
<prop oor:name="Properties" oor:type="xs:int">
<value>1</value>
</prop>
</node>
<node oor:name=".uno:ExportToEPUB" oor:op="replace"> <node oor:name=".uno:ExportToEPUB" oor:op="replace">
<prop oor:name="Label" oor:type="xs:string"> <prop oor:name="Label" oor:type="xs:string">
<value xml:lang="en-US">EPUB</value> <value xml:lang="en-US">EPUB</value>
......
...@@ -21,5 +21,5 @@ ...@@ -21,5 +21,5 @@
<toolbar:toolbaritem xlink:href=".uno:Rect?FillTransparence:short=50&amp;FillColor:string=COL_GRAY7&amp;LineStyle:short=0&amp;IsSticky:bool=true"/> <toolbar:toolbaritem xlink:href=".uno:Rect?FillTransparence:short=50&amp;FillColor:string=COL_GRAY7&amp;LineStyle:short=0&amp;IsSticky:bool=true"/>
<toolbar:toolbaritem xlink:href=".uno:Freeline_Unfilled?Transparence:short=50&amp;Color:string=COL_GRAY7&amp;Width:short=500&amp;IsSticky:bool=true"/> <toolbar:toolbaritem xlink:href=".uno:Freeline_Unfilled?Transparence:short=50&amp;Color:string=COL_GRAY7&amp;Width:short=500&amp;IsSticky:bool=true"/>
<toolbar:toolbarseparator/> <toolbar:toolbarseparator/>
<toolbar:toolbaritem xlink:href=".uno:ExportDirectToPDF"/> <toolbar:toolbaritem xlink:href=".uno:ExportDirectToPDF?IsRedactMode:bool=true"/>
</toolbar:toolbar> </toolbar:toolbar>
...@@ -4764,7 +4764,8 @@ SfxVoidItem ExportToPDF SID_EXPORTDOCASPDF ...@@ -4764,7 +4764,8 @@ SfxVoidItem ExportToPDF SID_EXPORTDOCASPDF
] ]
SfxVoidItem ExportDirectToPDF SID_DIRECTEXPORTDOCASPDF SfxVoidItem ExportDirectToPDF SID_DIRECTEXPORTDOCASPDF
(SfxStringItem URL SID_FILE_NAME, SfxStringItem FilterName SID_FILTER_NAME) (SfxStringItem URL SID_FILE_NAME, SfxStringItem FilterName SID_FILTER_NAME,
SfxBoolItem IsRedactMode SID_IS_REDACT_MODE)
[ [
AutoUpdate = FALSE, AutoUpdate = FALSE,
FastCall = FALSE, FastCall = FALSE,
......
...@@ -109,6 +109,7 @@ SfxFormalArgument const aFormalArgs[] = { ...@@ -109,6 +109,7 @@ SfxFormalArgument const aFormalArgs[] = {
{ reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoFileSync", SID_NO_FILE_SYNC }, { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoFileSync", SID_NO_FILE_SYNC },
{ reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoThumbnail", SID_NO_THUMBNAIL }, { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoThumbnail", SID_NO_THUMBNAIL },
{ reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoEmbDataSet", SID_NO_EMBEDDED_DS }, { reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "NoEmbDataSet", SID_NO_EMBEDDED_DS },
{ reinterpret_cast<SfxType*>(&aSfxBoolItem_Impl), "IsRedactMode", SID_IS_REDACT_MODE },
}; };
static sal_uInt16 nMediaArgsCount = SAL_N_ELEMENTS(aFormalArgs); static sal_uInt16 nMediaArgsCount = SAL_N_ELEMENTS(aFormalArgs);
......
...@@ -2361,6 +2361,7 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium ) ...@@ -2361,6 +2361,7 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium )
bool bHasStream = false; bool bHasStream = false;
bool bHasBaseURL = false; bool bHasBaseURL = false;
bool bHasFilterName = false; bool bHasFilterName = false;
bool bIsRedactMode = false;
sal_Int32 i; sal_Int32 i;
sal_Int32 nEnd = aOldArgs.getLength(); sal_Int32 nEnd = aOldArgs.getLength();
...@@ -2379,6 +2380,10 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium ) ...@@ -2379,6 +2380,10 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium )
bHasFilterName = true; bHasFilterName = true;
} }
// FIXME: Handle this inside TransformItems()
if (pItems->GetItemState(SID_IS_REDACT_MODE) == SfxItemState::SET)
bIsRedactMode = true;
if ( !bHasOutputStream ) if ( !bHasOutputStream )
{ {
aArgs.realloc ( ++nEnd ); aArgs.realloc ( ++nEnd );
...@@ -2408,6 +2413,13 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium ) ...@@ -2408,6 +2413,13 @@ bool SfxObjectShell::ExportTo( SfxMedium& rMedium )
aArgs[nEnd-1].Value <<= aFilterName; aArgs[nEnd-1].Value <<= aFilterName;
} }
if (bIsRedactMode)
{
aArgs.realloc( ++nEnd );
aArgs[nEnd-1].Name = "IsRedactMode";
aArgs[nEnd-1].Value <<= bIsRedactMode;
}
return xFilter->filter( aArgs ); return xFilter->filter( aArgs );
}catch(...) }catch(...)
{} {}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment