1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
24 #include <o3tl/safeint.hxx>
25 #include <tools/stream.hxx>
26 #include <tools/fract.hxx>
27 #include <vcl/graphicfilter.hxx>
28 #include <vcl/FilterConfigItem.hxx>
29 #include <svtools/strings.hrc>
30 #include <svtools/svtresid.hxx>
31 #include <svtools/DocumentToGraphicRenderer.hxx>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/awt/Size.hpp>
34 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
35 #include <com/sun/star/drawing/XDrawView.hpp>
36 #include <com/sun/star/frame/XModel.hpp>
37 #include <com/sun/star/frame/XController.hpp>
38 #include <com/sun/star/graphic/PrimitiveFactory2D.hpp>
39 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
40 #include <com/sun/star/io/XStream.hpp>
41 #include <unotools/streamwrap.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/outdev.hxx>
44 #include <vcl/graph.hxx>
45 #include <rtl/ustrbuf.hxx>
46 #include <basegfx/matrix/b2dhommatrix.hxx>
47 #include "exportdialog.hxx"
49 #define FORMAT_UNKNOWN 0
60 #define UNIT_DEFAULT -1
66 #define UNIT_MAX_ID UNIT_PIXEL
68 using namespace ::com::sun::star
;
70 static sal_Int16
GetFilterFormat(const OUString
& rExt
)
72 sal_Int16 nFormat
= FORMAT_UNKNOWN
;
75 else if ( rExt
== "PNG" )
77 else if ( rExt
== "BMP" )
79 else if ( rExt
== "GIF" )
81 else if ( rExt
== "TIF" )
83 else if ( rExt
== "WMF" )
85 else if ( rExt
== "EMF" )
87 else if ( rExt
== "EPS" )
89 else if ( rExt
== "SVG" )
94 static MapUnit
GetMapUnit( sal_Int32 nUnit
)
96 MapUnit
aMapUnit( MapUnit::MapPixel
);
99 case UNIT_INCH
: aMapUnit
= MapUnit::MapInch
; break;
100 case UNIT_CM
: aMapUnit
= MapUnit::MapCM
; break;
101 case UNIT_MM
: aMapUnit
= MapUnit::MapMM
; break;
102 case UNIT_POINT
: aMapUnit
= MapUnit::MapPoint
; break;
103 case UNIT_PIXEL
: aMapUnit
= MapUnit::MapPixel
; break;
108 sal_Int32
ExportDialog::GetDefaultUnit() const
110 sal_Int32 nDefaultUnit
= UNIT_CM
;
111 switch( mrFltCallPara
.eFieldUnit
)
113 // case FieldUnit::NONE :
114 // case FieldUnit::PERCENT :
115 // case FieldUnit::CUSTOM :
116 default: nDefaultUnit
= UNIT_CM
; break;
118 case FieldUnit::MILE
: // PASSTHROUGH INTENDED
119 case FieldUnit::FOOT
:
120 case FieldUnit::TWIP
:
121 case FieldUnit::PICA
: nDefaultUnit
= UNIT_INCH
; break;
123 case FieldUnit::KM
: // PASSTHROUGH INTENDED
125 case FieldUnit::MM_100TH
: nDefaultUnit
= UNIT_CM
; break;
127 case FieldUnit::INCH
: nDefaultUnit
= UNIT_INCH
; break;
128 case FieldUnit::CM
: nDefaultUnit
= UNIT_CM
; break;
129 case FieldUnit::MM
: nDefaultUnit
= UNIT_MM
; break;
130 case FieldUnit::POINT
: nDefaultUnit
= UNIT_POINT
; break;
135 static basegfx::B2DRange
GetShapeRangeForXShape( const uno::Reference
< drawing::XShape
>& rxShape
,
136 const uno::Reference
< graphic::XPrimitiveFactory2D
>& rxPrimitiveFactory2D
, const uno::Sequence
< beans::PropertyValue
>& rViewInformation
)
138 basegfx::B2DRange aShapeRange
;
140 const uno::Sequence
< beans::PropertyValue
> aParams
;
141 const uno::Sequence
< uno::Reference
< graphic::XPrimitive2D
> > aPrimitiveSequence( rxPrimitiveFactory2D
->createPrimitivesFromXShape( rxShape
, aParams
) );
143 for( const auto& rPrimitive
: aPrimitiveSequence
)
145 const geometry::RealRectangle2D
aRect( rPrimitive
->getRange( rViewInformation
) );
146 aShapeRange
.expand( basegfx::B2DTuple( aRect
.X1
, aRect
.Y1
) );
147 aShapeRange
.expand( basegfx::B2DTuple( aRect
.X2
, aRect
.Y2
) );
152 uno::Sequence
< beans::PropertyValue
> ExportDialog::GetFilterData( bool bUpdateConfig
)
156 sal_Int32 nUnit
= mxLbSizeX
->get_active();
160 if ( ( mnInitialResolutionUnit
== UNIT_DEFAULT
) && ( nUnit
== GetDefaultUnit() ) )
161 nUnit
= UNIT_DEFAULT
;
163 // updating ui configuration
164 if ( mbIsPixelFormat
)
166 if ( nUnit
> UNIT_MAX_ID
)
169 sal_Int32 nResolution
= mxNfResolution
->get_value();
170 if ( nResolution
< 1 )
173 mpOptionsItem
->WriteInt32("PixelExportUnit", nUnit
);
174 mpOptionsItem
->WriteInt32("PixelExportResolution", nResolution
);
175 mpOptionsItem
->WriteInt32("PixelExportResolutionUnit", mxLbResolution
->get_active());
179 if ( nUnit
>= UNIT_PIXEL
)
182 mpOptionsItem
->WriteInt32("VectorExportUnit", nUnit
);
186 FilterConfigItem
* pFilterOptions
;
188 pFilterOptions
= mpFilterOptionsItem
.get();
191 uno::Sequence
< beans::PropertyValue
> aFilterData( mpFilterOptionsItem
->GetFilterData() );
192 pFilterOptions
= new FilterConfigItem( &aFilterData
);
195 const OUString
sLogicalWidth("LogicalWidth");
196 const OUString
sLogicalHeight("LogicalHeight");
197 if ( mbIsPixelFormat
)
199 pFilterOptions
->WriteInt32("PixelWidth", maSize
.Width
);
200 pFilterOptions
->WriteInt32("PixelHeight", maSize
.Height
);
201 if ( maResolution
.Width
&& maResolution
.Height
)
203 const double f100thmmPerPixelX
= 100000.0 / maResolution
.Width
;
204 const double f100thmmPerPixelY
= 100000.0 / maResolution
.Height
;
205 sal_Int32 nLogicalWidth
= static_cast< sal_Int32
>( f100thmmPerPixelX
* maSize
.Width
);
206 sal_Int32 nLogicalHeight
= static_cast< sal_Int32
>( f100thmmPerPixelY
* maSize
.Height
);
207 if ( nLogicalWidth
&& nLogicalHeight
)
209 pFilterOptions
->WriteInt32( sLogicalWidth
, nLogicalWidth
);
210 pFilterOptions
->WriteInt32( sLogicalHeight
, nLogicalHeight
);
216 pFilterOptions
->WriteInt32( sLogicalWidth
, maSize
.Width
);
217 pFilterOptions
->WriteInt32( sLogicalHeight
, maSize
.Height
);
223 sal_Int32 nColor
= mxLbColorDepth
->get_active();
228 pFilterOptions
->WriteInt32("ColorMode", nColor
);
229 assert(mpSbCompression
);
230 pFilterOptions
->WriteInt32("Quality", static_cast<sal_Int32
>(mpSbCompression
->get_value()));
236 assert(mpSbCompression
);
237 pFilterOptions
->WriteInt32("Compression", static_cast<sal_Int32
>(mpSbCompression
->get_value()));
238 sal_Int32 nInterlace
= 0;
239 if ( mxCbInterlaced
->get_active() )
241 pFilterOptions
->WriteInt32("Interlaced", nInterlace
);
242 sal_Int32 nValue
= 0;
243 if ( mxCbSaveTransparency
->get_active() )
245 pFilterOptions
->WriteInt32("Translucent", nValue
);
251 pFilterOptions
->WriteInt32("Color", mxLbColorDepth
->get_active() + 1);
252 pFilterOptions
->WriteBool("RLE_Coding", mxCbRLEEncoding
->get_active());
258 sal_Int32 nValue
= 0;
259 if ( mxCbInterlaced
->get_active() )
261 pFilterOptions
->WriteInt32("Interlaced", nValue
);
264 if (mxCbSaveTransparency
->get_active())
266 pFilterOptions
->WriteInt32("Translucent", nValue
);
272 sal_Int32 nCheck
= 0;
273 if ( mxCbEPSPreviewTIFF
->get_active() )
275 if ( mxCbEPSPreviewEPSI
->get_active() )
277 pFilterOptions
->WriteInt32("Preview", nCheck
);
280 if ( mxRbEPSLevel2
->get_active() )
282 pFilterOptions
->WriteInt32("Version", nCheck
);
285 if ( mxRbEPSColorFormat2
->get_active() )
287 pFilterOptions
->WriteInt32("ColorFormat", nCheck
);
290 if ( mxRbEPSCompressionNone
->get_active() )
292 pFilterOptions
->WriteInt32("CompressionMode", nCheck
);
297 uno::Sequence
< beans::PropertyValue
> aRet( pFilterOptions
->GetFilterData() );
298 if ( !bUpdateConfig
)
299 delete pFilterOptions
;
304 awt::Size
ExportDialog::GetOriginalSize()
306 basegfx::B2DRange aShapesRange
;
310 uno::Reference
< beans::XPropertySet
> xPagePropSet( mxPage
, uno::UNO_QUERY
);
311 if ( xPagePropSet
.is() )
313 sal_Int32 nWidth
= 0;
314 sal_Int32 nHeight
= 0;
316 aAny
= xPagePropSet
->getPropertyValue("Width");
318 aAny
= xPagePropSet
->getPropertyValue("Height");
320 aShapesRange
= basegfx::B2DRange( 0, 0, nWidth
, nHeight
);
323 else if (mxShapes
.is() || mxShape
.is())
325 uno::Reference
< graphic::XPrimitiveFactory2D
> xPrimitiveFactory
= graphic::PrimitiveFactory2D::create( mxContext
);
327 basegfx::B2DHomMatrix
aViewTransformation( Application::GetDefaultDevice()->GetViewTransformation() );
328 css::geometry::AffineMatrix2D aTransformation
;
329 aTransformation
.m00
= aViewTransformation
.get(0,0);
330 aTransformation
.m01
= aViewTransformation
.get(0,1);
331 aTransformation
.m02
= aViewTransformation
.get(0,2);
332 aTransformation
.m10
= aViewTransformation
.get(1,0);
333 aTransformation
.m11
= aViewTransformation
.get(1,1);
334 aTransformation
.m12
= aViewTransformation
.get(1,2);
336 uno::Sequence
< beans::PropertyValue
> aViewInformation( 1 );
337 aViewInformation
[ 0 ].Value
<<= aTransformation
;
338 aViewInformation
[ 0 ].Name
= "ViewTransformation";
341 aShapesRange
= GetShapeRangeForXShape( mxShape
, xPrimitiveFactory
, aViewInformation
);
342 else if ( mxShapes
.is() )
344 const sal_Int32 nCount
= mxShapes
->getCount();
345 for( sal_Int32 nIndex
= 0; nIndex
< nCount
; nIndex
++ )
347 uno::Reference
< drawing::XShape
> xShape
;
348 mxShapes
->getByIndex( nIndex
) >>= xShape
;
349 aShapesRange
.expand( GetShapeRangeForXShape( xShape
, xPrimitiveFactory
, aViewInformation
) );
353 else if (!mbGraphicsSource
)
355 DocumentToGraphicRenderer
aRenderer( mxSourceDocument
, mbExportSelection
);
356 const sal_Int32 nCurrentPage
= aRenderer
.getCurrentPage();
357 const Size aSize
= aRenderer
.getDocumentSizeIn100mm( nCurrentPage
);
358 return awt::Size( aSize
.Width(), aSize
.Height());
360 return awt::Size( static_cast<sal_Int32
>(aShapesRange
.getWidth()), static_cast<sal_Int32
>(aShapesRange
.getHeight()) );
363 void ExportDialog::GetGraphicSource()
368 if ( !mxSourceDocument
.is() )
371 uno::Reference
< frame::XModel
> xModel( mxSourceDocument
, uno::UNO_QUERY
);
375 uno::Reference
< frame::XController
> xController( xModel
->getCurrentController() );
376 if ( !xController
.is() )
379 if ( mbExportSelection
) // check if there is a selection
381 if (DocumentToGraphicRenderer::isShapeSelected( mxShapes
, mxShape
, xController
))
382 mbGraphicsSource
= true;
384 if ( !mxShape
.is() && !mxShapes
.is() && mbGraphicsSource
)
386 uno::Reference
< drawing::XDrawView
> xDrawView( xController
, uno::UNO_QUERY
);
387 if ( xDrawView
.is() )
389 uno::Reference
< drawing::XDrawPage
> xCurrentPage( xDrawView
->getCurrentPage() );
390 if ( xCurrentPage
.is() )
392 mxPage
= xCurrentPage
; // exporting whole page
396 // For !mbGraphicsSource the mxSourceDocument is used, from
397 // which XRenderable can query XController and
398 // XSelectionSupplier the same.
401 void ExportDialog::GetGraphicStream()
403 if ( !IsTempExportAvailable() )
405 mpTempStream
.reset(new SvMemoryStream());
409 bool bRecreateOutputStream
= mpTempStream
->Tell() == 0;
411 static uno::Sequence
< beans::PropertyValue
> aOldFilterData
;
412 uno::Sequence
< beans::PropertyValue
> aNewFilterData( GetFilterData( false ) );
413 if ( aOldFilterData
!= aNewFilterData
)
415 aOldFilterData
= aNewFilterData
;
416 bRecreateOutputStream
= true;
420 if ( bRecreateOutputStream
)
422 mpTempStream
.reset(new SvMemoryStream());
424 uno::Reference
< graphic::XGraphic
> xGraphic
;
425 if (!mbGraphicsSource
&& !mxGraphic
.is())
427 // Create a Graphic to be used below.
428 DocumentToGraphicRenderer
aRenderer( mxSourceDocument
, mbExportSelection
);
429 const sal_Int32 nCurrentPage
= aRenderer
.getCurrentPage();
430 const Size aDocumentSizePixel
= aRenderer
.getDocumentSizeInPixels( nCurrentPage
);
432 const Size
aTargetSizePixel( mbIsPixelFormat
?
433 Size( maSize
.Width
, maSize
.Height
) :
434 aDocumentSizePixel
);
436 Graphic
aGraphic( aRenderer
.renderToGraphic( nCurrentPage
,
437 aDocumentSizePixel
, aTargetSizePixel
, COL_WHITE
, /*bExtOutDevData=*/false));
438 xGraphic
= aGraphic
.GetXGraphic();
441 if ( mxGraphic
.is() || xGraphic
.is() )
443 Graphic
aGraphic( mxGraphic
.is() ? mxGraphic
: xGraphic
);
445 if ( aGraphic
.GetType() == GraphicType::Bitmap
)
447 Size
aSizePixel( aGraphic
.GetSizePixel() );
448 if( maSize
.Width
&& maSize
.Height
&&
449 ( ( maSize
.Width
!= aSizePixel
.Width() ) ||
450 ( maSize
.Height
!= aSizePixel
.Height() ) ) )
452 BitmapEx
aBmpEx( aGraphic
.GetBitmapEx() );
453 // export: use highest quality
454 aBmpEx
.Scale( Size( maSize
.Width
, maSize
.Height
), BmpScaleFlag::Lanczos
);
459 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
460 const sal_uInt16 nFilter
= rFilter
.GetExportFormatNumberForShortName( maExt
);
461 if ( rFilter
.IsExportPixelFormat( nFilter
) )
463 mpTempStream
->SetResizeOffset(1024);
464 mpTempStream
->SetStreamSize(1024);
465 rFilter
.ExportGraphic( aGraphic
, "", *mpTempStream
, nFilter
, &aNewFilterData
);
470 uno::Reference
< lang::XComponent
> xSourceDoc
;
472 xSourceDoc
.set( mxPage
, uno::UNO_QUERY_THROW
);
473 else if ( mxShapes
.is() )
474 xSourceDoc
.set( mxShapes
, uno::UNO_QUERY_THROW
);
475 else if ( mxShape
.is() )
476 xSourceDoc
.set( mxShape
, uno::UNO_QUERY_THROW
);
477 if ( xSourceDoc
.is() )
479 uno::Reference
< io::XStream
> xStream( new utl::OStreamWrapper( *mpTempStream
) );
480 uno::Reference
< io::XOutputStream
> xOutputStream( xStream
->getOutputStream() );
482 OUString
sFormat( maExt
);
483 uno::Sequence
< beans::PropertyValue
> aDescriptor( 3 );
484 aDescriptor
[0].Name
= "OutputStream";
485 aDescriptor
[0].Value
<<= xOutputStream
;
486 aDescriptor
[1].Name
= "FilterName";
487 aDescriptor
[1].Value
<<= sFormat
;
488 aDescriptor
[2].Name
= "FilterData";
489 aDescriptor
[2].Value
<<= aNewFilterData
;
491 uno::Reference
< drawing::XGraphicExportFilter
> xGraphicExporter
=
492 drawing::GraphicExportFilter::create( mxContext
);
494 xGraphicExporter
->setSourceDocument( xSourceDoc
);
495 xGraphicExporter
->filter( aDescriptor
);
500 catch( uno::Exception
& )
508 sal_uInt32
ExportDialog::GetRawFileSize() const
510 sal_uInt64 nRawFileSize
= 0;
511 if ( mbIsPixelFormat
)
513 sal_Int32 nBitsPerPixel
= 24;
514 OUString
aEntry(mxLbColorDepth
->get_active_text());
515 if ( ms1BitThreshold
== aEntry
)
517 else if ( ms1BitDithered
== aEntry
)
519 else if ( ms4BitGrayscale
== aEntry
)
521 else if ( ms4BitColorPalette
== aEntry
)
523 else if ( ms8BitGrayscale
== aEntry
)
525 else if ( ms8BitColorPalette
== aEntry
)
527 else if ( ms24BitColor
== aEntry
)
530 if ( mbIsPixelFormat
)
532 nRawFileSize
= ( maSize
.Width
* nBitsPerPixel
+ 7 ) &~ 7; // rounding up to 8 bits
533 nRawFileSize
/= 8; // in bytes
534 nRawFileSize
*= maSize
.Height
;
536 if ( nRawFileSize
> SAL_MAX_UINT32
)
539 return static_cast< sal_uInt32
>( nRawFileSize
);
542 // checks if the source dimension/resolution is not too big
543 // to determine the exact graphic output size and preview for jpg
544 bool ExportDialog::IsTempExportAvailable() const
546 return GetRawFileSize() < o3tl::make_unsigned( mnMaxFilesizeForRealtimePreview
);
549 ExportDialog::ExportDialog(FltCallDialogParameter
& rPara
,
550 const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
,
551 const css::uno::Reference
< css::lang::XComponent
>& rxSourceDocument
,
552 bool bExportSelection
, bool bIsPixelFormat
, bool bGraphicsSource
,
553 const css::uno::Reference
< css::graphic::XGraphic
>& rxGraphic
)
554 : GenericDialogController(rPara
.pWindow
, "svt/ui/graphicexport.ui", "GraphicExportDialog")
555 , mrFltCallPara(rPara
)
556 , mxContext(rxContext
)
557 , mxSourceDocument(rxSourceDocument
)
558 , mxGraphic(rxGraphic
)
559 , msEstimatedSizePix1(SvtResId(STR_SVT_ESTIMATED_SIZE_PIX_1
))
560 , msEstimatedSizePix2(SvtResId(STR_SVT_ESTIMATED_SIZE_PIX_2
))
561 , msEstimatedSizeVec(SvtResId(STR_SVT_ESTIMATED_SIZE_VEC
))
562 , ms1BitThreshold(SvtResId(STR_SVT_1BIT_THRESHOLD
))
563 , ms1BitDithered(SvtResId(STR_SVT_1BIT_DITHERED
))
564 , ms4BitGrayscale(SvtResId(STR_SVT_4BIT_GRAYSCALE
))
565 , ms4BitColorPalette(SvtResId(STR_SVT_4BIT_COLOR_PALETTE
))
566 , ms8BitGrayscale(SvtResId(STR_SVT_8BIT_GRAYSCALE
))
567 , ms8BitColorPalette(SvtResId(STR_SVT_8BIT_COLOR_PALETTE
))
568 , ms24BitColor(SvtResId(STR_SVT_24BIT_TRUE_COLOR
))
569 , maExt(rPara
.aFilterExt
)
570 , mnFormat(FORMAT_UNKNOWN
)
571 , mnMaxFilesizeForRealtimePreview(0)
572 , mpTempStream(new SvMemoryStream())
573 , maOriginalSize(awt::Size(0, 0))
574 , mbIsPixelFormat(bIsPixelFormat
)
575 , mbExportSelection(bExportSelection
)
576 , mbGraphicsSource(bGraphicsSource
)
577 , mpSbCompression(nullptr)
578 , mpNfCompression(nullptr)
579 , mxMfSizeX(m_xBuilder
->weld_spin_button("widthmf"))
580 , mxLbSizeX(m_xBuilder
->weld_combo_box("widthlb"))
581 , mxMfSizeY(m_xBuilder
->weld_spin_button( "heightmf"))
582 , mxFtResolution(m_xBuilder
->weld_label("resolutionft"))
583 , mxNfResolution(m_xBuilder
->weld_spin_button("resolutionmf"))
584 , mxLbResolution(m_xBuilder
->weld_combo_box("resolutionlb"))
585 , mxColorDepth(m_xBuilder
->weld_widget("colordepth"))
586 , mxLbColorDepth(m_xBuilder
->weld_combo_box("colordepthlb"))
587 , mxJPGQuality(m_xBuilder
->weld_widget("jpgquality"))
588 , mxPNGCompression(m_xBuilder
->weld_widget("pngcompression"))
589 , mxSbPngCompression(m_xBuilder
->weld_scale("compressionpngsb"))
590 , mxNfPngCompression(m_xBuilder
->weld_spin_button("compressionpngnf"))
591 , mxSbJpgCompression(m_xBuilder
->weld_scale("compressionjpgsb"))
592 , mxNfJpgCompression(m_xBuilder
->weld_spin_button("compressionjpgnf"))
593 , mxMode(m_xBuilder
->weld_widget("mode"))
594 , mxCbInterlaced(m_xBuilder
->weld_check_button("interlacedcb"))
595 , mxBMPCompression(m_xBuilder
->weld_widget("bmpcompression"))
596 , mxCbRLEEncoding(m_xBuilder
->weld_check_button("rlecb"))
597 , mxDrawingObjects(m_xBuilder
->weld_widget("drawingobjects"))
598 , mxCbSaveTransparency(m_xBuilder
->weld_check_button("savetransparencycb"))
599 , mxEncoding(m_xBuilder
->weld_widget("encoding"))
600 , mxRbBinary(m_xBuilder
->weld_radio_button("binarycb"))
601 , mxRbText(m_xBuilder
->weld_radio_button("textcb"))
602 , mxEPSGrid(m_xBuilder
->weld_widget("epsgrid"))
603 , mxCbEPSPreviewTIFF(m_xBuilder
->weld_check_button("tiffpreviewcb"))
604 , mxCbEPSPreviewEPSI(m_xBuilder
->weld_check_button("epsipreviewcb"))
605 , mxRbEPSLevel1(m_xBuilder
->weld_radio_button("level1rb"))
606 , mxRbEPSLevel2(m_xBuilder
->weld_radio_button("level2rb"))
607 , mxRbEPSColorFormat1(m_xBuilder
->weld_radio_button("color1rb"))
608 , mxRbEPSColorFormat2(m_xBuilder
->weld_radio_button("color2rb"))
609 , mxRbEPSCompressionLZW(m_xBuilder
->weld_radio_button("compresslzw"))
610 , mxRbEPSCompressionNone(m_xBuilder
->weld_radio_button("compressnone"))
611 , mxInfo(m_xBuilder
->weld_widget("information"))
612 , mxFtEstimatedSize(m_xBuilder
->weld_label("estsizeft"))
613 , mxBtnOK(m_xBuilder
->weld_button("ok"))
617 maExt
= maExt
.toAsciiUpperCase();
619 OUString
aFilterConfigPath( "Office.Common/Filter/Graphic/Export/" );
620 mpOptionsItem
.reset(new FilterConfigItem( aFilterConfigPath
, &rPara
.aFilterData
));
621 aFilterConfigPath
+= maExt
;
622 mpFilterOptionsItem
.reset(new FilterConfigItem( aFilterConfigPath
, &rPara
.aFilterData
));
624 mnInitialResolutionUnit
= mbIsPixelFormat
625 ? mpOptionsItem
->ReadInt32("PixelExportUnit", UNIT_DEFAULT
)
626 : mpOptionsItem
->ReadInt32("VectorExportUnit", UNIT_DEFAULT
);
628 mnMaxFilesizeForRealtimePreview
= std::max(
629 mpOptionsItem
->ReadInt32("MaxFilesizeForRealtimePreview", 0), sal_Int32(0));
630 mxFtEstimatedSize
->set_label(" \n ");
632 m_xDialog
->set_title(m_xDialog
->get_title().replaceFirst("%1", maExt
)); //Set dialog title
634 mnFormat
= GetFilterFormat( maExt
);
636 Size
aResolution( Application::GetDefaultDevice()->LogicToPixel(Size(100, 100), MapMode(MapUnit::MapCM
)) );
637 maResolution
.Width
= aResolution
.Width();
638 maResolution
.Height
= aResolution
.Height();
640 if ( mxGraphic
.is() )
642 Graphic
aGraphic(mxGraphic
);
643 Size aSize
= aGraphic
.GetSizePixel();
644 maSize
= awt::Size(aSize
.getWidth(), aSize
.getHeight());
645 double f100thmmPerPixel
= 100000.0 / static_cast< double >( maResolution
.Width
);
646 maOriginalSize
= awt::Size(
647 static_cast< sal_Int32
>( f100thmmPerPixel
* maSize
.Width
),
648 static_cast< sal_Int32
>( f100thmmPerPixel
* maSize
.Height
) );
652 maOriginalSize
= GetOriginalSize();
653 if ( bIsPixelFormat
)
655 double fPixelsPer100thmm
= static_cast< double >( maResolution
.Width
) / 100000.0;
656 maSize
= awt::Size( static_cast< sal_Int32
>( ( fPixelsPer100thmm
* maOriginalSize
.Width
) + 0.5 ),
657 static_cast< sal_Int32
>( ( fPixelsPer100thmm
* maOriginalSize
.Height
) + 0.5 ) );
661 maSize
= maOriginalSize
;
667 mxLbSizeX
->connect_changed( LINK( this, ExportDialog
, SelectListBoxHdl
) );
670 mpSbCompression
->connect_value_changed(LINK(this, ExportDialog
, SbCompressionUpdateHdl
));
672 mpNfCompression
->connect_value_changed(LINK(this, ExportDialog
, SelectHdl
));
674 mxMfSizeX
->connect_value_changed( LINK( this, ExportDialog
, UpdateHdlMtfSizeX
) );
675 mxMfSizeY
->connect_value_changed( LINK( this, ExportDialog
, UpdateHdlMtfSizeY
) );
677 mxNfResolution
->connect_value_changed( LINK( this, ExportDialog
, UpdateHdlNfResolution
) );
678 mxLbResolution
->connect_changed( LINK( this, ExportDialog
, SelectListBoxHdl
) );
680 mxLbColorDepth
->connect_changed( LINK( this, ExportDialog
, SelectListBoxHdl
) );
682 mxCbInterlaced
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
684 mxCbSaveTransparency
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
686 mxCbEPSPreviewTIFF
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
687 mxCbEPSPreviewEPSI
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
689 mxRbEPSCompressionLZW
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
690 mxRbEPSCompressionNone
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
692 mxRbBinary
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
693 mxRbText
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
696 mxCbRLEEncoding
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
699 mxRbEPSLevel1
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
700 mxRbEPSLevel2
->connect_toggled( LINK( this, ExportDialog
, UpdateHdl
) );
702 mxBtnOK
->connect_clicked( LINK( this, ExportDialog
, OK
) );
707 void ExportDialog::setupSizeControls()
709 sal_Int32 nUnit
= mnInitialResolutionUnit
;
710 if (nUnit
== UNIT_DEFAULT
)
711 nUnit
= GetDefaultUnit();
713 if (!mbIsPixelFormat
)
715 mxFtResolution
->hide();
716 mxNfResolution
->hide();
717 mxLbResolution
->hide();
718 mxLbSizeX
->remove( UNIT_PIXEL
); // removing pixel
719 if ( nUnit
>= UNIT_PIXEL
)
722 else if ( nUnit
> UNIT_MAX_ID
)
726 mxLbSizeX
->set_active( static_cast< sal_uInt16
>( nUnit
) );
728 if ( !mbIsPixelFormat
) // TODO: (metafileresolutionsupport) should be supported for vector formats also... this makes
731 // sense eg for bitmap fillings in metafiles, to preserve high dpi output
732 // (atm without special vector support the bitmaps are rendered with 96dpi)
733 sal_Int32 nResolution
= mpOptionsItem
->ReadInt32("PixelExportResolution", 96);
734 if ( nResolution
< 1 )
736 mxNfResolution
->set_value( nResolution
);
738 sal_Int32 nResolutionUnit
= mpOptionsItem
->ReadInt32("PixelExportResolutionUnit", 1);
739 if ( ( nResolutionUnit
< 0 ) || ( nResolutionUnit
> 2 ) )
741 mxLbResolution
->set_active( static_cast< sal_uInt16
>( nResolutionUnit
) );
744 void ExportDialog::createFilterOptions()
750 sal_Int32 nColor
= mpFilterOptionsItem
->ReadInt32("ColorMode", 0);
755 mxLbColorDepth
->append_text( ms8BitGrayscale
);
756 mxLbColorDepth
->append_text( ms24BitColor
);
757 mxLbColorDepth
->set_active( nColor
);
758 mxColorDepth
->show();
761 mxJPGQuality
->show();
762 sal_Int32 nQuality
= mpFilterOptionsItem
->ReadInt32("Quality", 75);
763 if ((nQuality
< 1 ) || (nQuality
> 100))
765 mpSbCompression
= mxSbJpgCompression
.get();
766 mpNfCompression
= mxNfJpgCompression
.get();
767 mpSbCompression
->set_range(1, 100);
768 mpNfCompression
->set_range(1, 100);
769 mpNfCompression
->set_value(nQuality
);
775 mxPNGCompression
->show();
776 sal_Int32 nCompression
= mpFilterOptionsItem
->ReadInt32("Compression", 6);
777 if ( ( nCompression
< 1 ) || ( nCompression
> 9 ) )
780 mpSbCompression
= mxSbPngCompression
.get();
781 mpNfCompression
= mxNfPngCompression
.get();
782 mpSbCompression
->set_range(1, 9);
783 mpNfCompression
->set_range(1, 9);
784 mpNfCompression
->set_value(nCompression
);
788 mxCbInterlaced
->set_active(mpFilterOptionsItem
->ReadInt32("Interlaced", 0) != 0);
791 mxDrawingObjects
->show();
792 mxCbSaveTransparency
->set_active(mpFilterOptionsItem
->ReadInt32("Translucent", 1) != 0);
797 sal_Int32 nColor
= mpFilterOptionsItem
->ReadInt32("Color", 0);
802 mxLbColorDepth
->append_text( ms1BitThreshold
);
803 mxLbColorDepth
->append_text( ms1BitDithered
);
804 mxLbColorDepth
->append_text( ms4BitGrayscale
);
805 mxLbColorDepth
->append_text( ms4BitColorPalette
);
806 mxLbColorDepth
->append_text( ms8BitGrayscale
);
807 mxLbColorDepth
->append_text( ms8BitColorPalette
);
808 mxLbColorDepth
->append_text( ms24BitColor
);
809 mxLbColorDepth
->set_active( nColor
);
810 mxColorDepth
->show();
813 mxBMPCompression
->show();
814 mxCbRLEEncoding
->set_active(mpFilterOptionsItem
->ReadBool("RLE_Coding", true));
821 mxCbInterlaced
->set_active(mpFilterOptionsItem
->ReadInt32("Interlaced", 1) != 0);
824 mxDrawingObjects
->show();
825 mxCbSaveTransparency
->set_active(mpFilterOptionsItem
->ReadInt32("Translucent", 1) != 0);
832 sal_Int32 nPreview
= mpFilterOptionsItem
->ReadInt32("Preview", 0);
833 sal_Int32 nVersion
= mpFilterOptionsItem
->ReadInt32("Version", 2);
834 sal_Int32 nColor
= mpFilterOptionsItem
->ReadInt32("ColorFormat", 0);
835 sal_Int32 nCompr
= mpFilterOptionsItem
->ReadInt32("CompressionMode", 2);
837 mpFilterOptionsItem
->ReadInt32("TextMode", 0);
839 mxCbEPSPreviewTIFF
->set_active( ( nPreview
& 1 ) != 0 );
840 mxCbEPSPreviewEPSI
->set_active( ( nPreview
& 2 ) != 0 );
842 mxRbEPSLevel1
->set_active( nVersion
== 1 );
843 mxRbEPSLevel2
->set_active( nVersion
== 2 );
845 mxRbEPSColorFormat1
->set_active( nColor
== 1 );
846 mxRbEPSColorFormat2
->set_active( nColor
!= 1 );
848 mxRbEPSCompressionLZW
->set_active( nCompr
== 1 );
849 mxRbEPSCompressionNone
->set_active( nCompr
!= 1 );
855 void ExportDialog::setupControls()
858 createFilterOptions();
860 if (mnMaxFilesizeForRealtimePreview
|| mbIsPixelFormat
)
864 static OUString
ImpValueOfInKB( sal_Int64 rVal
)
866 double fVal( static_cast<double>( rVal
) );
869 OUStringBuffer
aVal( OUString::number( fVal
) );
870 sal_Int32
nX( aVal
.indexOf( '.' ) );
872 aVal
.setLength( nX
+ 2 );
873 return aVal
.makeStringAndClear();
876 void ExportDialog::updateControls()
879 if ( !mbIsPixelFormat
)
881 awt::Size
aSize100thmm( maSize
);
882 Size
aSize( OutputDevice::LogicToLogic( Size(aSize100thmm
.Width
* 100, aSize100thmm
.Height
* 100),
883 MapMode(MapUnit::Map100thMM
),
884 MapMode( GetMapUnit( mxLbSizeX
->get_active() ) ) ) );
885 mxMfSizeX
->set_value( aSize
.Width() );
886 mxMfSizeY
->set_value( aSize
.Height() );
890 MapUnit
aMapUnit( GetMapUnit( mxLbSizeX
->get_active() ) );
891 if ( aMapUnit
== MapUnit::MapPixel
)
892 { // calculating pixel count via resolution and original graphic size
893 mxMfSizeX
->set_digits( 0 );
894 mxMfSizeY
->set_digits( 0 );
895 mxMfSizeX
->set_value( maSize
.Width
);
896 mxMfSizeY
->set_value( maSize
.Height
);
900 mxMfSizeX
->set_digits( 2 );
901 mxMfSizeY
->set_digits( 2 );
903 switch( GetMapUnit( mxLbSizeX
->get_active() ) )
905 case MapUnit::MapInch
: fRatio
= static_cast< double >( maResolution
.Width
) * 0.0254; break;
906 case MapUnit::MapMM
: fRatio
= static_cast< double >( maResolution
.Width
) * 0.001; break;
907 case MapUnit::MapPoint
:fRatio
= ( static_cast< double >( maResolution
.Width
) * 0.0254 ) / 72.0; break;
909 case MapUnit::MapCM
: fRatio
= static_cast< double >( maResolution
.Width
) * 0.01; break;
911 mxMfSizeX
->set_value( static_cast< sal_Int32
>( ( static_cast< double >( maSize
.Width
* 100 ) / fRatio
) + 0.5 ) );
912 mxMfSizeY
->set_value( static_cast< sal_Int32
>( ( static_cast< double >( maSize
.Height
* 100 ) / fRatio
) + 0.5 ) );
915 sal_Int32 nResolution
= 0;
916 switch( mxLbResolution
->get_active() )
918 case 0 : nResolution
= maResolution
.Width
/ 100; break; // pixels / cm
919 case 2 : nResolution
= maResolution
.Width
; break; // pixels / meter
921 case 1 : nResolution
= static_cast< sal_Int32
>(maResolution
.Width
* 0.0254); break; // pixels / inch
923 mxNfResolution
->set_value( nResolution
);
925 if (mpSbCompression
&& mpSbCompression
->get_visible() && mpNfCompression
)
926 mpSbCompression
->set_value(mpNfCompression
->get_value());
930 // updating estimated size
931 sal_Int64
nRealFileSize( mpTempStream
->Tell() );
932 if ( mbIsPixelFormat
)
934 OUString
aEst( nRealFileSize
? msEstimatedSizePix2
: msEstimatedSizePix1
);
935 sal_Int64
nRawFileSize( GetRawFileSize() );
936 sal_Int32 nInd
= aEst
.indexOf( "%" );
938 aEst
= aEst
.replaceAt( nInd
, 2, ImpValueOfInKB( nRawFileSize
) );
940 if ( nRealFileSize
&& nInd
!= -1 )
942 nInd
= aEst
.indexOf( "%", nInd
);
944 aEst
= aEst
.replaceAt( nInd
, 2, ImpValueOfInKB( nRealFileSize
) );
946 mxFtEstimatedSize
->set_label( aEst
);
950 if ( mnMaxFilesizeForRealtimePreview
)
952 OUString
aEst( msEstimatedSizeVec
);
953 sal_Int32 nInd
= aEst
.indexOf( "%" );
955 aEst
= aEst
.replaceAt( nInd
, 2, ImpValueOfInKB( nRealFileSize
) );
956 mxFtEstimatedSize
->set_label( aEst
);
961 if ( mxRbEPSLevel1
->get_visible() )
963 bool bEnabled
= !mxRbEPSLevel1
->get_active();
964 mxRbEPSColorFormat1
->set_sensitive( bEnabled
);
965 mxRbEPSColorFormat2
->set_sensitive( bEnabled
);
966 mxRbEPSCompressionLZW
->set_sensitive( bEnabled
);
967 mxRbEPSCompressionNone
->set_sensitive( bEnabled
);
971 ExportDialog::~ExportDialog()
975 /*************************************************************************
977 |* stores values set in the ini-file
979 \************************************************************************/
980 IMPL_LINK_NOARG(ExportDialog
, SelectHdl
, weld::SpinButton
&, void)
985 IMPL_LINK_NOARG(ExportDialog
, SelectListBoxHdl
, weld::ComboBox
&, void)
990 IMPL_LINK_NOARG(ExportDialog
, UpdateHdl
, weld::ToggleButton
&, void)
995 IMPL_LINK_NOARG(ExportDialog
, UpdateHdlMtfSizeX
, weld::SpinButton
&, void)
997 double fRatio
= static_cast< double >( maOriginalSize
.Height
) / maOriginalSize
.Width
;
999 if ( mbIsPixelFormat
)
1001 switch( GetMapUnit( mxLbSizeX
->get_active() ) )
1003 case MapUnit::MapInch
: maSize
.Width
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Width
) * 0.0254 * mxMfSizeX
->get_value() / 100.0 + 0.5 ); break;
1004 case MapUnit::MapCM
: maSize
.Width
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Width
) * 0.01 * mxMfSizeX
->get_value() / 100.0 + 0.5 ); break;
1005 case MapUnit::MapMM
: maSize
.Width
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Width
) * 0.001 * mxMfSizeX
->get_value() / 100.0 + 0.5 ); break;
1006 case MapUnit::MapPoint
: maSize
.Width
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Width
) * 0.0254 * mxMfSizeX
->get_value() / 100.0 * 72 + 0.5 ); break;
1008 case MapUnit::MapPixel
: maSize
.Width
= mxMfSizeX
->get_value(); break;
1010 maSize
.Height
= static_cast< sal_Int32
>( fRatio
* maSize
.Width
+ 0.5 );
1014 Fraction
aFract( 1, 100 );
1015 sal_Int32 nWidth
= mxMfSizeX
->get_value();
1016 sal_Int32 nHeight
= static_cast< sal_Int32
>( nWidth
* fRatio
);
1017 const Size
aSource( nWidth
, nHeight
);
1018 MapMode
aSourceMapMode( GetMapUnit( mxLbSizeX
->get_active() ),Point(), aFract
, aFract
);
1019 Size
aDest(OutputDevice::LogicToLogic(aSource
, aSourceMapMode
, MapMode(MapUnit::Map100thMM
)));
1021 maSize
.Width
= aDest
.Width();
1022 maSize
.Height
= aDest
.Height();
1027 IMPL_LINK_NOARG(ExportDialog
, UpdateHdlMtfSizeY
, weld::SpinButton
&, void)
1029 double fRatio
= static_cast< double >( maOriginalSize
.Width
) / maOriginalSize
.Height
;
1031 if ( mbIsPixelFormat
)
1033 switch( GetMapUnit( mxLbSizeX
->get_active() ) )
1035 case MapUnit::MapInch
: maSize
.Height
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Height
) * 0.0254 * mxMfSizeY
->get_value() / 100.0 + 0.5 ); break;
1036 case MapUnit::MapCM
: maSize
.Height
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Height
) * 0.01 * mxMfSizeY
->get_value() / 100.0 + 0.5 ); break;
1037 case MapUnit::MapMM
: maSize
.Height
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Height
) * 0.001 * mxMfSizeY
->get_value() / 100.0 + 0.5 ); break;
1038 case MapUnit::MapPoint
: maSize
.Height
= static_cast< sal_Int32
>( static_cast< double >( maResolution
.Height
) * 0.0254 * mxMfSizeY
->get_value() / 100.0 * 72 + 0.5 ); break;
1040 case MapUnit::MapPixel
: maSize
.Height
= mxMfSizeY
->get_value(); break;
1042 maSize
.Width
= static_cast< sal_Int32
>( fRatio
* maSize
.Height
+ 0.5 );
1046 Fraction
aFract( 1, 100 );
1047 sal_Int32 nHeight
= mxMfSizeY
->get_value();
1048 sal_Int32 nWidth
= static_cast< sal_Int32
>( nHeight
* fRatio
);
1049 const Size
aSource( nWidth
, nHeight
);
1050 MapMode
aSourceMapMode( GetMapUnit( mxLbSizeX
->get_active() ),Point(), aFract
, aFract
);
1051 Size
aDest( OutputDevice::LogicToLogic(aSource
, aSourceMapMode
, MapMode(MapUnit::Map100thMM
)) );
1053 maSize
.Height
= aDest
.Height();
1054 maSize
.Width
= aDest
.Width();
1059 IMPL_LINK_NOARG(ExportDialog
, UpdateHdlNfResolution
, weld::SpinButton
&, void)
1061 auto nResolution
= mxNfResolution
->get_value();
1062 if ( mxLbResolution
->get_active() == 0 ) // pixels / cm
1064 else if ( mxLbResolution
->get_active() == 1 ) // pixels / inch
1065 nResolution
= static_cast< sal_Int32
>( ( ( static_cast< double >( nResolution
) + 0.5 ) / 0.0254 ) );
1066 maResolution
.Width
= nResolution
;
1067 maResolution
.Height
= nResolution
;
1072 IMPL_LINK_NOARG(ExportDialog
, SbCompressionUpdateHdl
, weld::Scale
&, void)
1074 mpNfCompression
->set_value(mpSbCompression
->get_value());
1078 IMPL_LINK_NOARG(ExportDialog
, OK
, weld::Button
&, void)
1080 // writing config parameter
1082 mrFltCallPara
.aFilterData
= GetFilterData( true );
1083 m_xDialog
->response(RET_OK
);
1086 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */