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 <vcl/bitmap/BitmapMosaicFilter.hxx>
21 #include <vcl/bitmap/BitmapSharpenFilter.hxx>
22 #include <vcl/bitmap/BitmapEmbossGreyFilter.hxx>
23 #include <vcl/bitmap/BitmapSepiaFilter.hxx>
24 #include <vcl/bitmap/BitmapSmoothenFilter.hxx>
25 #include <vcl/bitmap/BitmapSolarizeFilter.hxx>
26 #include <vcl/bitmap/BitmapColorQuantizationFilter.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/svapp.hxx>
29 #include <osl/diagnose.h>
30 #include <tools/helpers.hxx>
31 #include <cuigrfflt.hxx>
33 CuiGraphicPreviewWindow::CuiGraphicPreviewWindow()
34 : mpOrigGraphic(nullptr)
40 void CuiGraphicPreviewWindow::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
42 CustomWidgetController::SetDrawingArea(pDrawingArea
);
43 OutputDevice
&rDevice
= pDrawingArea
->get_ref_device();
44 maOutputSizePixel
= rDevice
.LogicToPixel(Size(81, 73), MapMode(MapUnit::MapAppFont
));
45 pDrawingArea
->set_size_request(maOutputSizePixel
.Width(), maOutputSizePixel
.Height());
48 void CuiGraphicPreviewWindow::Paint(vcl::RenderContext
& rRenderContext
, const ::tools::Rectangle
&)
50 rRenderContext
.SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetDialogColor()));
51 rRenderContext
.Erase();
53 const Size
aOutputSize(GetOutputSizePixel());
55 if (maPreview
.IsAnimated())
57 const Size
aGraphicSize(rRenderContext
.LogicToPixel(maPreview
.GetPrefSize(), maPreview
.GetPrefMapMode()));
58 const Point
aGraphicPosition((aOutputSize
.Width() - aGraphicSize
.Width() ) >> 1,
59 (aOutputSize
.Height() - aGraphicSize
.Height() ) >> 1);
60 maPreview
.StartAnimation(rRenderContext
, aGraphicPosition
, aGraphicSize
);
64 const Size
aGraphicSize(maPreview
.GetSizePixel());
65 const Point
aGraphicPosition((aOutputSize
.Width() - aGraphicSize
.Width()) >> 1,
66 (aOutputSize
.Height() - aGraphicSize
.Height()) >> 1);
67 maPreview
.Draw(rRenderContext
, aGraphicPosition
, aGraphicSize
);
71 void CuiGraphicPreviewWindow::SetPreview(const Graphic
& rGraphic
)
77 void CuiGraphicPreviewWindow::ScaleImageToFit()
82 maScaledOrig
= *mpOrigGraphic
;
84 const Size
aPreviewSize(GetOutputSizePixel());
85 Size
aGrfSize(maOrigGraphicSizePixel
);
87 if( mpOrigGraphic
->GetType() == GraphicType::Bitmap
&&
88 aPreviewSize
.Width() && aPreviewSize
.Height() &&
89 aGrfSize
.Width() && aGrfSize
.Height() )
91 const double fGrfWH
= static_cast<double>(aGrfSize
.Width()) / aGrfSize
.Height();
92 const double fPreWH
= static_cast<double>(aPreviewSize
.Width()) / aPreviewSize
.Height();
96 aGrfSize
.setWidth( static_cast<tools::Long
>( aPreviewSize
.Height() * fGrfWH
) );
97 aGrfSize
.setHeight( aPreviewSize
.Height() );
101 aGrfSize
.setWidth( aPreviewSize
.Width() );
102 aGrfSize
.setHeight( static_cast<tools::Long
>( aPreviewSize
.Width() / fGrfWH
) );
105 mfScaleX
= static_cast<double>(aGrfSize
.Width()) / maOrigGraphicSizePixel
.Width();
106 mfScaleY
= static_cast<double>(aGrfSize
.Height()) / maOrigGraphicSizePixel
.Height();
108 if( !mpOrigGraphic
->IsAnimated() )
110 BitmapEx
aBmpEx( mpOrigGraphic
->GetBitmapEx() );
112 if( aBmpEx
.Scale( aGrfSize
) )
113 maScaledOrig
= aBmpEx
;
117 maModifyHdl
.Call(nullptr);
120 void CuiGraphicPreviewWindow::Resize()
122 maOutputSizePixel
= GetOutputSizePixel();
126 GraphicFilterDialog::GraphicFilterDialog(weld::Window
* pParent
,
127 const OUString
& rUIXMLDescription
, const OUString
& rID
,
128 const Graphic
& rGraphic
)
129 : GenericDialogController(pParent
, rUIXMLDescription
, rID
)
130 , maTimer("cui GraphicFilterDialog maTimer")
131 , maModifyHdl(LINK(this, GraphicFilterDialog
, ImplModifyHdl
))
132 , mxPreview(new weld::CustomWeld(*m_xBuilder
, u
"preview"_ustr
, maPreview
))
134 bIsBitmap
= rGraphic
.GetType() == GraphicType::Bitmap
;
136 maTimer
.SetInvokeHandler(LINK(this, GraphicFilterDialog
, ImplPreviewTimeoutHdl
));
137 maTimer
.SetTimeout(5);
139 maPreview
.init(&rGraphic
, maModifyHdl
);
142 IMPL_LINK_NOARG(GraphicFilterDialog
, ImplPreviewTimeoutHdl
, Timer
*, void)
145 maPreview
.SetPreview(GetFilteredGraphic(maPreview
.GetScaledOriginal(),
146 maPreview
.GetScaleX(), maPreview
.GetScaleY()));
149 IMPL_LINK_NOARG(GraphicFilterDialog
, ImplModifyHdl
, LinkParamNone
*, void)
158 GraphicFilterMosaic::GraphicFilterMosaic(weld::Window
* pParent
, const Graphic
& rGraphic
,
159 sal_uInt16 nTileWidth
, sal_uInt16 nTileHeight
, bool bEnhanceEdges
)
160 : GraphicFilterDialog(pParent
, u
"cui/ui/mosaicdialog.ui"_ustr
, u
"MosaicDialog"_ustr
, rGraphic
)
161 , mxMtrWidth(m_xBuilder
->weld_metric_spin_button(u
"width"_ustr
, FieldUnit::PIXEL
))
162 , mxMtrHeight(m_xBuilder
->weld_metric_spin_button(u
"height"_ustr
, FieldUnit::PIXEL
))
163 , mxCbxEdges(m_xBuilder
->weld_check_button(u
"edges"_ustr
))
165 mxMtrWidth
->set_value(nTileWidth
, FieldUnit::PIXEL
);
166 mxMtrWidth
->set_max(GetGraphicSizePixel().Width(), FieldUnit::PIXEL
);
167 mxMtrWidth
->connect_value_changed(LINK(this, GraphicFilterMosaic
, EditModifyHdl
));
169 mxMtrHeight
->set_value(nTileHeight
, FieldUnit::PIXEL
);
170 mxMtrHeight
->set_max(GetGraphicSizePixel().Height(), FieldUnit::PIXEL
);
171 mxMtrHeight
->connect_value_changed(LINK(this, GraphicFilterMosaic
, EditModifyHdl
));
173 mxCbxEdges
->set_active(bEnhanceEdges
);
174 mxCbxEdges
->connect_toggled(LINK(this, GraphicFilterMosaic
, CheckBoxModifyHdl
));
176 mxMtrWidth
->grab_focus();
179 IMPL_LINK_NOARG(GraphicFilterMosaic
, CheckBoxModifyHdl
, weld::Toggleable
&, void)
181 GetModifyHdl().Call(nullptr);
184 IMPL_LINK_NOARG(GraphicFilterMosaic
, EditModifyHdl
, weld::MetricSpinButton
&, void)
186 GetModifyHdl().Call(nullptr);
189 Graphic
GraphicFilterMosaic::GetFilteredGraphic( const Graphic
& rGraphic
,
190 double fScaleX
, double fScaleY
)
193 tools::Long nTileWidth
= static_cast<tools::Long
>(mxMtrWidth
->get_value(FieldUnit::PIXEL
));
194 tools::Long nTileHeight
= static_cast<tools::Long
>(mxMtrHeight
->get_value(FieldUnit::PIXEL
));
195 const Size
aSize( std::max( basegfx::fround
<tools::Long
>( nTileWidth
* fScaleX
), tools::Long(1) ),
196 std::max( basegfx::fround
<tools::Long
>( nTileHeight
* fScaleY
), tools::Long(1) ) );
198 if( rGraphic
.IsAnimated() )
200 Animation
aAnim( rGraphic
.GetAnimation() );
202 if (BitmapFilter::Filter(aAnim
, BitmapMosaicFilter(aSize
.getWidth(), aSize
.getHeight())))
204 if( IsEnhanceEdges() )
205 (void)BitmapFilter::Filter(aAnim
, BitmapSharpenFilter());
212 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
214 if (BitmapFilter::Filter(aBmpEx
, BitmapMosaicFilter(aSize
.getWidth(), aSize
.getHeight())))
216 if( IsEnhanceEdges() )
217 BitmapFilter::Filter(aBmpEx
, BitmapSharpenFilter());
226 GraphicFilterSmooth::GraphicFilterSmooth(weld::Window
* pParent
, const Graphic
& rGraphic
, double nRadius
)
227 : GraphicFilterDialog(pParent
, u
"cui/ui/smoothdialog.ui"_ustr
, u
"SmoothDialog"_ustr
, rGraphic
)
228 , mxMtrRadius(m_xBuilder
->weld_spin_button(u
"radius"_ustr
))
230 mxMtrRadius
->set_value(nRadius
* 10);
231 mxMtrRadius
->connect_value_changed(LINK(this, GraphicFilterSmooth
, EditModifyHdl
));
232 mxMtrRadius
->grab_focus();
235 IMPL_LINK_NOARG(GraphicFilterSmooth
, EditModifyHdl
, weld::SpinButton
&, void)
237 GetModifyHdl().Call(nullptr);
240 Graphic
GraphicFilterSmooth::GetFilteredGraphic( const Graphic
& rGraphic
, double, double )
243 double nRadius
= mxMtrRadius
->get_value() / 10.0;
245 if( rGraphic
.IsAnimated() )
247 Animation
aAnim( rGraphic
.GetAnimation() );
249 if (BitmapFilter::Filter(aAnim
, BitmapSmoothenFilter(nRadius
)))
256 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
258 if (BitmapFilter::Filter(aBmpEx
, BitmapSmoothenFilter(nRadius
)))
267 GraphicFilterSolarize::GraphicFilterSolarize(weld::Window
* pParent
, const Graphic
& rGraphic
,
268 sal_uInt8 cGreyThreshold
, bool bInvert
)
269 : GraphicFilterDialog(pParent
, u
"cui/ui/solarizedialog.ui"_ustr
, u
"SolarizeDialog"_ustr
, rGraphic
)
270 , mxMtrThreshold(m_xBuilder
->weld_metric_spin_button(u
"value"_ustr
, FieldUnit::PERCENT
))
271 , mxCbxInvert(m_xBuilder
->weld_check_button(u
"invert"_ustr
))
273 mxMtrThreshold
->set_value(basegfx::fround(cGreyThreshold
/ 2.55), FieldUnit::PERCENT
);
274 mxMtrThreshold
->connect_value_changed(LINK(this, GraphicFilterSolarize
, EditModifyHdl
));
276 mxCbxInvert
->set_active(bInvert
);
277 mxCbxInvert
->connect_toggled(LINK(this, GraphicFilterSolarize
, CheckBoxModifyHdl
));
280 IMPL_LINK_NOARG(GraphicFilterSolarize
, CheckBoxModifyHdl
, weld::Toggleable
&, void)
282 GetModifyHdl().Call(nullptr);
285 IMPL_LINK_NOARG(GraphicFilterSolarize
, EditModifyHdl
, weld::MetricSpinButton
&, void)
287 GetModifyHdl().Call(nullptr);
290 Graphic
GraphicFilterSolarize::GetFilteredGraphic( const Graphic
& rGraphic
, double, double )
293 sal_uInt8 nGreyThreshold
= basegfx::fround
<sal_uInt8
>(mxMtrThreshold
->get_value(FieldUnit::PERCENT
) * 2.55);
295 if( rGraphic
.IsAnimated() )
297 Animation
aAnim( rGraphic
.GetAnimation() );
299 if (BitmapFilter::Filter(aAnim
, BitmapSolarizeFilter(nGreyThreshold
)))
309 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
311 if (BitmapFilter::Filter(aBmpEx
, BitmapSolarizeFilter(nGreyThreshold
)))
323 GraphicFilterSepia::GraphicFilterSepia(weld::Window
* pParent
, const Graphic
& rGraphic
,
324 sal_uInt16 nSepiaPercent
)
325 : GraphicFilterDialog(pParent
, u
"cui/ui/agingdialog.ui"_ustr
, u
"AgingDialog"_ustr
, rGraphic
)
326 , mxMtrSepia(m_xBuilder
->weld_metric_spin_button(u
"value"_ustr
, FieldUnit::PERCENT
))
328 mxMtrSepia
->set_value(nSepiaPercent
, FieldUnit::PERCENT
);
329 mxMtrSepia
->connect_value_changed(LINK(this, GraphicFilterSepia
, EditModifyHdl
));
332 IMPL_LINK_NOARG(GraphicFilterSepia
, EditModifyHdl
, weld::MetricSpinButton
&, void)
334 GetModifyHdl().Call(nullptr);
337 Graphic
GraphicFilterSepia::GetFilteredGraphic( const Graphic
& rGraphic
, double, double )
340 sal_uInt16 nSepiaPct
= sal::static_int_cast
< sal_uInt16
>(mxMtrSepia
->get_value(FieldUnit::PERCENT
));
342 if( rGraphic
.IsAnimated() )
344 Animation
aAnim( rGraphic
.GetAnimation() );
346 if (BitmapFilter::Filter(aAnim
, BitmapSepiaFilter(nSepiaPct
)))
351 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
353 if (BitmapFilter::Filter(aBmpEx
, BitmapSepiaFilter(nSepiaPct
)))
360 GraphicFilterPoster::GraphicFilterPoster(weld::Window
* pParent
, const Graphic
& rGraphic
,
361 sal_uInt16 nPosterCount
)
362 : GraphicFilterDialog(pParent
, u
"cui/ui/posterdialog.ui"_ustr
, u
"PosterDialog"_ustr
, rGraphic
)
363 , mxNumPoster(m_xBuilder
->weld_spin_button(u
"value"_ustr
))
365 mxNumPoster
->set_range(2, vcl::pixelFormatBitCount(rGraphic
.GetBitmapEx().getPixelFormat()));
366 mxNumPoster
->set_value(nPosterCount
);
367 mxNumPoster
->connect_value_changed(LINK(this, GraphicFilterPoster
, EditModifyHdl
));
370 IMPL_LINK_NOARG(GraphicFilterPoster
, EditModifyHdl
, weld::SpinButton
&, void)
372 GetModifyHdl().Call(nullptr);
375 Graphic
GraphicFilterPoster::GetFilteredGraphic( const Graphic
& rGraphic
, double, double )
378 const sal_uInt16 nPosterCount
= static_cast<sal_uInt16
>(mxNumPoster
->get_value());
380 if( rGraphic
.IsAnimated() )
382 Animation
aAnim( rGraphic
.GetAnimation() );
384 if( aAnim
.ReduceColors( nPosterCount
) )
389 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
391 if (BitmapFilter::Filter(aBmpEx
, BitmapColorQuantizationFilter(nPosterCount
)))
398 bool EmbossControl::MouseButtonDown( const MouseEvent
& rEvt
)
400 const RectPoint eOldRP
= GetActualRP();
402 SvxRectCtl::MouseButtonDown( rEvt
);
404 if( GetActualRP() != eOldRP
)
405 maModifyHdl
.Call( nullptr );
410 void EmbossControl::SetDrawingArea(weld::DrawingArea
* pDrawingArea
)
412 SvxRectCtl::SetDrawingArea(pDrawingArea
);
413 Size
aSize(pDrawingArea
->get_ref_device().LogicToPixel(Size(77, 60), MapMode(MapUnit::MapAppFont
)));
414 pDrawingArea
->set_size_request(aSize
.Width(), aSize
.Height());
417 GraphicFilterEmboss::GraphicFilterEmboss(weld::Window
* pParent
,
418 const Graphic
& rGraphic
, RectPoint eLightSource
)
419 : GraphicFilterDialog(pParent
, u
"cui/ui/embossdialog.ui"_ustr
, u
"EmbossDialog"_ustr
, rGraphic
)
420 , mxCtlLight(new weld::CustomWeld(*m_xBuilder
, u
"lightsource"_ustr
, maCtlLight
))
422 maCtlLight
.SetActualRP(eLightSource
);
423 maCtlLight
.SetModifyHdl( GetModifyHdl() );
424 maCtlLight
.GrabFocus();
427 GraphicFilterEmboss::~GraphicFilterEmboss()
431 Graphic
GraphicFilterEmboss::GetFilteredGraphic( const Graphic
& rGraphic
, double, double )
434 Degree100 nAzim
, nElev
;
436 switch (maCtlLight
.GetActualRP())
438 default: OSL_FAIL("svx::GraphicFilterEmboss::GetFilteredGraphic(), unknown Reference Point!" );
440 case RectPoint::LT
: nAzim
= 4500_deg100
; nElev
= 4500_deg100
; break;
441 case RectPoint::MT
: nAzim
= 9000_deg100
; nElev
= 4500_deg100
; break;
442 case RectPoint::RT
: nAzim
= 13500_deg100
; nElev
= 4500_deg100
; break;
443 case RectPoint::LM
: nAzim
= 0_deg100
; nElev
= 4500_deg100
; break;
444 case RectPoint::MM
: nAzim
= 0_deg100
; nElev
= 9000_deg100
; break;
445 case RectPoint::RM
: nAzim
= 18000_deg100
; nElev
= 4500_deg100
; break;
446 case RectPoint::LB
: nAzim
= 31500_deg100
; nElev
= 4500_deg100
; break;
447 case RectPoint::MB
: nAzim
= 27000_deg100
; nElev
= 4500_deg100
; break;
448 case RectPoint::RB
: nAzim
= 22500_deg100
; nElev
= 4500_deg100
; break;
451 if( rGraphic
.IsAnimated() )
453 Animation
aAnim( rGraphic
.GetAnimation() );
455 if (BitmapFilter::Filter(aAnim
, BitmapEmbossGreyFilter(nAzim
, nElev
)))
460 BitmapEx
aBmpEx( rGraphic
.GetBitmapEx() );
462 if (BitmapFilter::Filter(aBmpEx
, BitmapEmbossGreyFilter(nAzim
, nElev
)))
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */