cid#1640468 Dereference after null check
[LibreOffice.git] / cui / source / dialogs / cuigrfflt.cxx
blob9f9d9273b5f28a1c39653961ed55875eaf07cdc1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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)
35 , mfScaleX(0.0)
36 , mfScaleY(0.0)
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);
62 else
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)
73 maPreview = rGraphic;
74 Invalidate();
77 void CuiGraphicPreviewWindow::ScaleImageToFit()
79 if (!mpOrigGraphic)
80 return;
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();
94 if( fGrfWH < fPreWH )
96 aGrfSize.setWidth( static_cast<tools::Long>( aPreviewSize.Height() * fGrfWH ) );
97 aGrfSize.setHeight( aPreviewSize.Height() );
99 else
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();
123 ScaleImageToFit();
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)
144 maTimer.Stop();
145 maPreview.SetPreview(GetFilteredGraphic(maPreview.GetScaledOriginal(),
146 maPreview.GetScaleX(), maPreview.GetScaleY()));
149 IMPL_LINK_NOARG(GraphicFilterDialog, ImplModifyHdl, LinkParamNone*, void)
151 if (bIsBitmap)
153 maTimer.Stop();
154 maTimer.Start();
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 )
192 Graphic aRet;
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());
207 aRet = aAnim;
210 else
212 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
214 if (BitmapFilter::Filter(aBmpEx, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
216 if( IsEnhanceEdges() )
217 BitmapFilter::Filter(aBmpEx, BitmapSharpenFilter());
219 aRet = aBmpEx;
223 return aRet;
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 )
242 Graphic aRet;
243 double nRadius = mxMtrRadius->get_value() / 10.0;
245 if( rGraphic.IsAnimated() )
247 Animation aAnim( rGraphic.GetAnimation() );
249 if (BitmapFilter::Filter(aAnim, BitmapSmoothenFilter(nRadius)))
251 aRet = aAnim;
254 else
256 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
258 if (BitmapFilter::Filter(aBmpEx, BitmapSmoothenFilter(nRadius)))
260 aRet = aBmpEx;
264 return aRet;
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 )
292 Graphic aRet;
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)))
301 if( IsInvert() )
302 aAnim.Invert();
304 aRet = aAnim;
307 else
309 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
311 if (BitmapFilter::Filter(aBmpEx, BitmapSolarizeFilter(nGreyThreshold)))
313 if( IsInvert() )
314 aBmpEx.Invert();
316 aRet = aBmpEx;
320 return aRet;
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 )
339 Graphic aRet;
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)))
347 aRet = aAnim;
349 else
351 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
353 if (BitmapFilter::Filter(aBmpEx, BitmapSepiaFilter(nSepiaPct)))
354 aRet = aBmpEx;
357 return aRet;
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 )
377 Graphic aRet;
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 ) )
385 aRet = aAnim;
387 else
389 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
391 if (BitmapFilter::Filter(aBmpEx, BitmapColorQuantizationFilter(nPosterCount)))
392 aRet = aBmpEx;
395 return aRet;
398 bool EmbossControl::MouseButtonDown( const MouseEvent& rEvt )
400 const RectPoint eOldRP = GetActualRP();
402 SvxRectCtl::MouseButtonDown( rEvt );
404 if( GetActualRP() != eOldRP )
405 maModifyHdl.Call( nullptr );
407 return true;
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 )
433 Graphic aRet;
434 Degree100 nAzim, nElev;
436 switch (maCtlLight.GetActualRP())
438 default: OSL_FAIL("svx::GraphicFilterEmboss::GetFilteredGraphic(), unknown Reference Point!" );
439 [[fallthrough]];
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)))
456 aRet = aAnim;
458 else
460 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
462 if (BitmapFilter::Filter(aBmpEx, BitmapEmbossGreyFilter(nAzim, nElev)))
463 aRet = aBmpEx;
466 return aRet;
469 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */