LibreOffice Module cui (master)  1
cuigrfflt.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
27 #include <vcl/settings.hxx>
28 #include <vcl/svapp.hxx>
29 #include <osl/diagnose.h>
30 #include <tools/helpers.hxx>
31 #include <cuigrfflt.hxx>
32 
34  : mpOrigGraphic(nullptr)
35  , mfScaleX(0.0)
36  , mfScaleY(0.0)
37 {
38 }
39 
41 {
42  CustomWidgetController::SetDrawingArea(pDrawingArea);
43  OutputDevice &rDevice = pDrawingArea->get_ref_device();
44  maOutputSizePixel = rDevice.LogicToPixel(Size(81, 73), MapMode(MapUnit::MapAppFont));
46 }
47 
48 void CuiGraphicPreviewWindow::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
49 {
50  rRenderContext.SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetDialogColor()));
51  rRenderContext.Erase();
52 
53  const Size aOutputSize(GetOutputSizePixel());
54 
55  if (maPreview.IsAnimated())
56  {
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);
61  }
62  else
63  {
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);
68  }
69 }
70 
72 {
73  maPreview = rGraphic;
74  Invalidate();
75 }
76 
78 {
79  if (!mpOrigGraphic)
80  return;
81 
83 
84  const Size aPreviewSize(GetOutputSizePixel());
85  Size aGrfSize(maOrigGraphicSizePixel);
86 
87  if( mpOrigGraphic->GetType() == GraphicType::Bitmap &&
88  aPreviewSize.Width() && aPreviewSize.Height() &&
89  aGrfSize.Width() && aGrfSize.Height() )
90  {
91  const double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
92  const double fPreWH = static_cast<double>(aPreviewSize.Width()) / aPreviewSize.Height();
93 
94  if( fGrfWH < fPreWH )
95  {
96  aGrfSize.setWidth( static_cast<long>( aPreviewSize.Height() * fGrfWH ) );
97  aGrfSize.setHeight( aPreviewSize.Height() );
98  }
99  else
100  {
101  aGrfSize.setWidth( aPreviewSize.Width() );
102  aGrfSize.setHeight( static_cast<long>( aPreviewSize.Width() / fGrfWH ) );
103  }
104 
105  mfScaleX = static_cast<double>(aGrfSize.Width()) / maOrigGraphicSizePixel.Width();
106  mfScaleY = static_cast<double>(aGrfSize.Height()) / maOrigGraphicSizePixel.Height();
107 
108  if( !mpOrigGraphic->IsAnimated() )
109  {
110  BitmapEx aBmpEx( mpOrigGraphic->GetBitmapEx() );
111 
112  if( aBmpEx.Scale( aGrfSize ) )
113  maScaledOrig = aBmpEx;
114  }
115  }
116 
117  maModifyHdl.Call(nullptr);
118 }
119 
121 {
123  ScaleImageToFit();
124 }
125 
127  const OUString& rUIXMLDescription, const OString& rID,
128  const Graphic& rGraphic)
129  : GenericDialogController(pParent, rUIXMLDescription, rID)
130  , maModifyHdl(LINK(this, GraphicFilterDialog, ImplModifyHdl))
131  , mxPreview(new weld::CustomWeld(*m_xBuilder, "preview", maPreview))
132 {
133  bIsBitmap = rGraphic.GetType() == GraphicType::Bitmap;
134 
135  maTimer.SetInvokeHandler(LINK(this, GraphicFilterDialog, ImplPreviewTimeoutHdl));
136  maTimer.SetTimeout(5);
137 
138  maPreview.init(&rGraphic, maModifyHdl);
139 }
140 
141 IMPL_LINK_NOARG(GraphicFilterDialog, ImplPreviewTimeoutHdl, Timer *, void)
142 {
143  maTimer.Stop();
144  maPreview.SetPreview(GetFilteredGraphic(maPreview.GetScaledOriginal(),
145  maPreview.GetScaleX(), maPreview.GetScaleY()));
146 }
147 
149 {
150  if (bIsBitmap)
151  {
152  maTimer.Stop();
153  maTimer.Start();
154  }
155 }
156 
158  sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges)
159  : GraphicFilterDialog(pParent, "cui/ui/mosaicdialog.ui", "MosaicDialog", rGraphic)
160  , mxMtrWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::PIXEL))
161  , mxMtrHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::PIXEL))
162  , mxCbxEdges(m_xBuilder->weld_check_button("edges"))
163 {
164  mxMtrWidth->set_value(nTileWidth, FieldUnit::PIXEL);
165  mxMtrWidth->set_max(GetGraphicSizePixel().Width(), FieldUnit::PIXEL);
166  mxMtrWidth->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
167 
168  mxMtrHeight->set_value(nTileHeight, FieldUnit::PIXEL);
169  mxMtrHeight->set_max(GetGraphicSizePixel().Height(), FieldUnit::PIXEL);
170  mxMtrHeight->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
171 
172  mxCbxEdges->set_active(bEnhanceEdges);
173  mxCbxEdges->connect_toggled(LINK(this, GraphicFilterMosaic, CheckBoxModifyHdl));
174 
175  mxMtrWidth->grab_focus();
176 }
177 
179 {
180  GetModifyHdl().Call(nullptr);
181 }
182 
184 {
185  GetModifyHdl().Call(nullptr);
186 }
187 
189  double fScaleX, double fScaleY )
190 {
191  Graphic aRet;
192  long nTileWidth = static_cast<long>(mxMtrWidth->get_value(FieldUnit::PIXEL));
193  long nTileHeight = static_cast<long>(mxMtrHeight->get_value(FieldUnit::PIXEL));
194  const Size aSize( std::max( FRound( nTileWidth * fScaleX ), 1L ),
195  std::max( FRound( nTileHeight * fScaleY ), 1L ) );
196 
197  if( rGraphic.IsAnimated() )
198  {
199  Animation aAnim( rGraphic.GetAnimation() );
200 
201  if (BitmapFilter::Filter(aAnim, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
202  {
203  if( IsEnhanceEdges() )
205 
206  aRet = aAnim;
207  }
208  }
209  else
210  {
211  BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
212 
213  if (BitmapFilter::Filter(aBmpEx, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
214  {
215  if( IsEnhanceEdges() )
217 
218  aRet = aBmpEx;
219  }
220  }
221 
222  return aRet;
223 }
224 
225 GraphicFilterSmooth::GraphicFilterSmooth(weld::Window* pParent, const Graphic& rGraphic, double nRadius)
226  : GraphicFilterDialog(pParent, "cui/ui/smoothdialog.ui", "SmoothDialog", rGraphic)
227  , mxMtrRadius(m_xBuilder->weld_spin_button("radius"))
228 {
229  mxMtrRadius->set_value(nRadius * 10);
230  mxMtrRadius->connect_value_changed(LINK(this, GraphicFilterSmooth, EditModifyHdl));
231  mxMtrRadius->grab_focus();
232 }
233 
235 {
236  GetModifyHdl().Call(nullptr);
237 }
238 
239 Graphic GraphicFilterSmooth::GetFilteredGraphic( const Graphic& rGraphic, double, double )
240 {
241  Graphic aRet;
242  double nRadius = mxMtrRadius->get_value() / 10.0;
243 
244  if( rGraphic.IsAnimated() )
245  {
246  Animation aAnim( rGraphic.GetAnimation() );
247 
248  if (BitmapFilter::Filter(aAnim, BitmapSmoothenFilter(nRadius)))
249  {
250  aRet = aAnim;
251  }
252  }
253  else
254  {
255  BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
256 
257  if (BitmapFilter::Filter(aBmpEx, BitmapSmoothenFilter(nRadius)))
258  {
259  aRet = aBmpEx;
260  }
261  }
262 
263  return aRet;
264 }
265 
267  sal_uInt8 cGreyThreshold, bool bInvert)
268  : GraphicFilterDialog(pParent, "cui/ui/solarizedialog.ui", "SolarizeDialog", rGraphic)
269  , mxMtrThreshold(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
270  , mxCbxInvert(m_xBuilder->weld_check_button("invert"))
271 {
272  mxMtrThreshold->set_value(FRound(cGreyThreshold / 2.55), FieldUnit::PERCENT);
273  mxMtrThreshold->connect_value_changed(LINK(this, GraphicFilterSolarize, EditModifyHdl));
274 
275  mxCbxInvert->set_active(bInvert);
276  mxCbxInvert->connect_toggled(LINK(this, GraphicFilterSolarize, CheckBoxModifyHdl));
277 }
278 
280 {
281  GetModifyHdl().Call(nullptr);
282 }
283 
285 {
286  GetModifyHdl().Call(nullptr);
287 }
288 
290 {
291  Graphic aRet;
292  sal_uInt8 nGreyThreshold = static_cast<sal_uInt8>(FRound(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 2.55));
293 
294  if( rGraphic.IsAnimated() )
295  {
296  Animation aAnim( rGraphic.GetAnimation() );
297 
298  if (BitmapFilter::Filter(aAnim, BitmapSolarizeFilter(nGreyThreshold)))
299  {
300  if( IsInvert() )
301  aAnim.Invert();
302 
303  aRet = aAnim;
304  }
305  }
306  else
307  {
308  BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
309 
310  if (BitmapFilter::Filter(aBmpEx, BitmapSolarizeFilter(nGreyThreshold)))
311  {
312  if( IsInvert() )
313  aBmpEx.Invert();
314 
315  aRet = aBmpEx;
316  }
317  }
318 
319  return aRet;
320 }
321 
323  sal_uInt16 nSepiaPercent)
324  : GraphicFilterDialog(pParent, "cui/ui/agingdialog.ui", "AgingDialog", rGraphic)
325  , mxMtrSepia(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
326 {
327  mxMtrSepia->set_value(nSepiaPercent, FieldUnit::PERCENT);
328  mxMtrSepia->connect_value_changed(LINK(this, GraphicFilterSepia, EditModifyHdl));
329 }
330 
332 {
333  GetModifyHdl().Call(nullptr);
334 }
335 
336 Graphic GraphicFilterSepia::GetFilteredGraphic( const Graphic& rGraphic, double, double )
337 {
338  Graphic aRet;
339  sal_uInt16 nSepiaPct = sal::static_int_cast< sal_uInt16 >(mxMtrSepia->get_value(FieldUnit::PERCENT));
340 
341  if( rGraphic.IsAnimated() )
342  {
343  Animation aAnim( rGraphic.GetAnimation() );
344 
345  if (BitmapFilter::Filter(aAnim, BitmapSepiaFilter(nSepiaPct)))
346  aRet = aAnim;
347  }
348  else
349  {
350  BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
351 
352  if (BitmapFilter::Filter(aBmpEx, BitmapSepiaFilter(nSepiaPct)))
353  aRet = aBmpEx;
354  }
355 
356  return aRet;
357 }
358 
360  sal_uInt16 nPosterCount)
361  : GraphicFilterDialog(pParent, "cui/ui/posterdialog.ui", "PosterDialog", rGraphic)
362  , mxNumPoster(m_xBuilder->weld_spin_button("value"))
363 {
364  mxNumPoster->set_range(2, rGraphic.GetBitmapEx().GetBitCount());
365  mxNumPoster->set_value(nPosterCount);
366  mxNumPoster->connect_value_changed(LINK(this, GraphicFilterPoster, EditModifyHdl));
367 }
368 
370 {
371  GetModifyHdl().Call(nullptr);
372 }
373 
374 Graphic GraphicFilterPoster::GetFilteredGraphic( const Graphic& rGraphic, double, double )
375 {
376  Graphic aRet;
377  const sal_uInt16 nPosterCount = static_cast<sal_uInt16>(mxNumPoster->get_value());
378 
379  if( rGraphic.IsAnimated() )
380  {
381  Animation aAnim( rGraphic.GetAnimation() );
382 
383  if( aAnim.ReduceColors( nPosterCount ) )
384  aRet = aAnim;
385  }
386  else
387  {
388  BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
389 
390  if (BitmapFilter::Filter(aBmpEx, BitmapColorQuantizationFilter(nPosterCount)))
391  aRet = aBmpEx;
392  }
393 
394  return aRet;
395 }
396 
398 {
399  const RectPoint eOldRP = GetActualRP();
400 
402 
403  if( GetActualRP() != eOldRP )
404  maModifyHdl.Call( nullptr );
405 
406  return true;
407 }
408 
410 {
411  SvxRectCtl::SetDrawingArea(pDrawingArea);
412  Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(77, 60), MapMode(MapUnit::MapAppFont)));
413  pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
414 }
415 
417  const Graphic& rGraphic, RectPoint eLightSource)
418  : GraphicFilterDialog(pParent, "cui/ui/embossdialog.ui", "EmbossDialog", rGraphic)
419  , mxCtlLight(new weld::CustomWeld(*m_xBuilder, "lightsource", maCtlLight))
420 {
421  maCtlLight.SetActualRP(eLightSource);
423  maCtlLight.GrabFocus();
424 }
425 
427 {
428 }
429 
430 Graphic GraphicFilterEmboss::GetFilteredGraphic( const Graphic& rGraphic, double, double )
431 {
432  Graphic aRet;
433  sal_uInt16 nAzim, nElev;
434 
435  switch (maCtlLight.GetActualRP())
436  {
437  default: OSL_FAIL("svx::GraphicFilterEmboss::GetFilteredGraphic(), unknown Reference Point!" );
438  [[fallthrough]];
439  case RectPoint::LT: nAzim = 4500; nElev = 4500; break;
440  case RectPoint::MT: nAzim = 9000; nElev = 4500; break;
441  case RectPoint::RT: nAzim = 13500; nElev = 4500; break;
442  case RectPoint::LM: nAzim = 0; nElev = 4500; break;
443  case RectPoint::MM: nAzim = 0; nElev = 9000; break;
444  case RectPoint::RM: nAzim = 18000; nElev = 4500; break;
445  case RectPoint::LB: nAzim = 31500; nElev = 4500; break;
446  case RectPoint::MB: nAzim = 27000; nElev = 4500; break;
447  case RectPoint::RB: nAzim = 22500; nElev = 4500; break;
448  }
449 
450  if( rGraphic.IsAnimated() )
451  {
452  Animation aAnim( rGraphic.GetAnimation() );
453 
454  if (BitmapFilter::Filter(aAnim, BitmapEmbossGreyFilter(nAzim, nElev)))
455  aRet = aAnim;
456  }
457  else
458  {
459  BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
460 
461  if (BitmapFilter::Filter(aBmpEx, BitmapEmbossGreyFilter(nAzim, nElev)))
462  aRet = aBmpEx;
463  }
464 
465  return aRet;
466 }
467 
468 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:239
long Width() const
const Link< LinkParamNone *, void > & GetModifyHdl() const
Definition: cuigrfflt.hxx:78
FieldUnit
void SetActualRP(RectPoint eNewRP)
GraphicFilterEmboss(weld::Window *pParent, const Graphic &rGraphic, RectPoint eLightSource)
Definition: cuigrfflt.cxx:416
GraphicFilterPoster(weld::Window *pParent, const Graphic &rGraphic, sal_uInt16 nPosterColorCount)
Definition: cuigrfflt.cxx:359
void SetModifyHdl(const Link< LinkParamNone *, void > &rHdl)
Definition: cuigrfflt.hxx:165
void init(const Graphic *pOrigGraphic, const Link< LinkParamNone *, void > &rLink)
Definition: cuigrfflt.hxx:47
long FRound(double fVal)
EmbossControl maCtlLight
Definition: cuigrfflt.hxx:171
GraphicFilterSolarize(weld::Window *pParent, const Graphic &rGraphic, sal_uInt8 nGreyThreshold, bool bInvert)
Definition: cuigrfflt.cxx:266
Size GetSizePixel(const OutputDevice *pRefDevice=nullptr) const
Link< LinkParamNone *, void > maModifyHdl
Definition: cuigrfflt.hxx:156
long Height() const
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
static const AllSettings & GetSettings()
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:374
std::unique_ptr< weld::MetricSpinButton > mxMtrHeight
Definition: cuigrfflt.hxx:103
RectPoint GetActualRP() const
virtual void Paint(vcl::RenderContext &rRenderContext, const ::tools::Rectangle &rRect) override
Definition: cuigrfflt.cxx:48
GraphicFilterSmooth(weld::Window *pParent, const Graphic &rGraphic, double nRadius)
Definition: cuigrfflt.cxx:225
Size const & GetOutputSizePixel() const
std::unique_ptr< weld::MetricSpinButton > mxMtrWidth
Definition: cuigrfflt.hxx:102
void SetBackground()
GraphicFilterSepia(weld::Window *pParent, const Graphic &rGraphic, sal_uInt16 nSepiaPercent)
Definition: cuigrfflt.cxx:322
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:336
static bool Filter(BitmapEx &rBmpEx, BitmapFilter const &rFilter)
std::unique_ptr< weld::CheckButton > mxCbxEdges
Definition: cuigrfflt.hxx:104
virtual ~GraphicFilterEmboss() override
Definition: cuigrfflt.cxx:426
virtual OutputDevice & get_ref_device()=0
Link< LinkParamNone *, void > maModifyHdl
Definition: cuigrfflt.hxx:33
bool IsAnimated() const
Animation GetAnimation() const
bool Invert()
RectPoint
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: cuigrfflt.cxx:40
void Draw(OutputDevice *pOutDev, const Point &rDestPt) const
IMPL_LINK_NOARG(GraphicFilterDialog, ImplPreviewTimeoutHdl, Timer *, void)
Definition: cuigrfflt.cxx:141
GraphicType GetType() const
const Graphic * mpOrigGraphic
Definition: cuigrfflt.hxx:30
bool Invert()
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:289
Link< LinkParamNone *, void > maModifyHdl
Definition: cuigrfflt.hxx:68
void StartAnimation(OutputDevice *pOutDev, const Point &rDestPt, const Size &rDestSize, long nExtraData=0, OutputDevice *pFirstFrameOutDev=nullptr)
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetPreview(const Graphic &rGraphic)
Definition: cuigrfflt.cxx:71
sal_uInt16 GetBitCount() const
std::unique_ptr< weld::CheckButton > mxCbxInvert
Definition: cuigrfflt.hxx:120
Point LogicToPixel(const Point &rLogicPt) const
Size GetPrefSize() const
std::unique_ptr< weld::MetricSpinButton > mxMtrSepia
Definition: cuigrfflt.hxx:134
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:430
std::unique_ptr< weld::SpinButton > mxMtrRadius
Definition: cuigrfflt.hxx:90
bool IsInvert() const
Definition: cuigrfflt.hxx:128
MapMode GetPrefMapMode() const
unsigned char sal_uInt8
CuiGraphicPreviewWindow maPreview
Definition: cuigrfflt.hxx:74
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: cuigrfflt.cxx:409
virtual bool MouseButtonDown(const MouseEvent &) override
GraphicFilterDialog(weld::Window *pParent, const OUString &rUIXMLDescription, const OString &rID, const Graphic &rGraphic)
Definition: cuigrfflt.cxx:126
const Size & GetGraphicSizePixel() const
Definition: cuigrfflt.hxx:79
const OUString PERCENT("Percent")
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:188
virtual bool MouseButtonDown(const MouseEvent &rEvt) override
Definition: cuigrfflt.cxx:397
std::unique_ptr< weld::SpinButton > mxNumPoster
Definition: cuigrfflt.hxx:145
virtual void Resize() override
Definition: cuigrfflt.cxx:120
long getHeight() const
bool IsEnhanceEdges() const
Definition: cuigrfflt.hxx:113
virtual void set_size_request(int nWidth, int nHeight)=0
long getWidth() const
void setWidth(long nWidth)
GraphicFilterMosaic(weld::Window *pParent, const Graphic &rGraphic, sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges)
Definition: cuigrfflt.cxx:157
std::unique_ptr< weld::MetricSpinButton > mxMtrThreshold
Definition: cuigrfflt.hxx:119
void setHeight(long nHeight)