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
48void 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
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());
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<tools::Long>( aPreviewSize.Height() * fGrfWH ) );
97 aGrfSize.setHeight( aPreviewSize.Height() );
98 }
99 else
100 {
101 aGrfSize.setWidth( aPreviewSize.Width() );
102 aGrfSize.setHeight( static_cast<tools::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 {
111
112 if( aBmpEx.Scale( aGrfSize ) )
113 maScaledOrig = aBmpEx;
114 }
115 }
116
117 maModifyHdl.Call(nullptr);
118}
119
121{
124}
125
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, "preview", maPreview))
133{
134 bIsBitmap = rGraphic.GetType() == GraphicType::Bitmap;
135
136 maTimer.SetInvokeHandler(LINK(this, GraphicFilterDialog, ImplPreviewTimeoutHdl));
138
139 maPreview.init(&rGraphic, maModifyHdl);
140}
141
142IMPL_LINK_NOARG(GraphicFilterDialog, ImplPreviewTimeoutHdl, Timer *, void)
143{
144 maTimer.Stop();
145 maPreview.SetPreview(GetFilteredGraphic(maPreview.GetScaledOriginal(),
146 maPreview.GetScaleX(), maPreview.GetScaleY()));
147}
148
150{
151 if (bIsBitmap)
152 {
153 maTimer.Stop();
154 maTimer.Start();
155 }
156}
157
159 sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges)
160 : GraphicFilterDialog(pParent, "cui/ui/mosaicdialog.ui", "MosaicDialog", rGraphic)
161 , mxMtrWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::PIXEL))
162 , mxMtrHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::PIXEL))
163 , mxCbxEdges(m_xBuilder->weld_check_button("edges"))
164{
165 mxMtrWidth->set_value(nTileWidth, FieldUnit::PIXEL);
166 mxMtrWidth->set_max(GetGraphicSizePixel().Width(), FieldUnit::PIXEL);
167 mxMtrWidth->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
168
169 mxMtrHeight->set_value(nTileHeight, FieldUnit::PIXEL);
170 mxMtrHeight->set_max(GetGraphicSizePixel().Height(), FieldUnit::PIXEL);
171 mxMtrHeight->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
172
173 mxCbxEdges->set_active(bEnhanceEdges);
174 mxCbxEdges->connect_toggled(LINK(this, GraphicFilterMosaic, CheckBoxModifyHdl));
175
176 mxMtrWidth->grab_focus();
177}
178
180{
181 GetModifyHdl().Call(nullptr);
182}
183
185{
186 GetModifyHdl().Call(nullptr);
187}
188
190 double fScaleX, double fScaleY )
191{
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( FRound( nTileWidth * fScaleX ), tools::Long(1) ),
196 std::max( FRound( nTileHeight * fScaleY ), tools::Long(1) ) );
197
198 if( rGraphic.IsAnimated() )
199 {
200 Animation aAnim( rGraphic.GetAnimation() );
201
202 if (BitmapFilter::Filter(aAnim, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
203 {
204 if( IsEnhanceEdges() )
206
207 aRet = aAnim;
208 }
209 }
210 else
211 {
212 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
213
214 if (BitmapFilter::Filter(aBmpEx, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
215 {
216 if( IsEnhanceEdges() )
218
219 aRet = aBmpEx;
220 }
221 }
222
223 return aRet;
224}
225
226GraphicFilterSmooth::GraphicFilterSmooth(weld::Window* pParent, const Graphic& rGraphic, double nRadius)
227 : GraphicFilterDialog(pParent, "cui/ui/smoothdialog.ui", "SmoothDialog", rGraphic)
228 , mxMtrRadius(m_xBuilder->weld_spin_button("radius"))
229{
230 mxMtrRadius->set_value(nRadius * 10);
231 mxMtrRadius->connect_value_changed(LINK(this, GraphicFilterSmooth, EditModifyHdl));
232 mxMtrRadius->grab_focus();
233}
234
236{
237 GetModifyHdl().Call(nullptr);
238}
239
241{
242 Graphic aRet;
243 double nRadius = mxMtrRadius->get_value() / 10.0;
244
245 if( rGraphic.IsAnimated() )
246 {
247 Animation aAnim( rGraphic.GetAnimation() );
248
249 if (BitmapFilter::Filter(aAnim, BitmapSmoothenFilter(nRadius)))
250 {
251 aRet = aAnim;
252 }
253 }
254 else
255 {
256 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
257
258 if (BitmapFilter::Filter(aBmpEx, BitmapSmoothenFilter(nRadius)))
259 {
260 aRet = aBmpEx;
261 }
262 }
263
264 return aRet;
265}
266
268 sal_uInt8 cGreyThreshold, bool bInvert)
269 : GraphicFilterDialog(pParent, "cui/ui/solarizedialog.ui", "SolarizeDialog", rGraphic)
270 , mxMtrThreshold(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
271 , mxCbxInvert(m_xBuilder->weld_check_button("invert"))
272{
273 mxMtrThreshold->set_value(FRound(cGreyThreshold / 2.55), FieldUnit::PERCENT);
274 mxMtrThreshold->connect_value_changed(LINK(this, GraphicFilterSolarize, EditModifyHdl));
275
276 mxCbxInvert->set_active(bInvert);
277 mxCbxInvert->connect_toggled(LINK(this, GraphicFilterSolarize, CheckBoxModifyHdl));
278}
279
281{
282 GetModifyHdl().Call(nullptr);
283}
284
286{
287 GetModifyHdl().Call(nullptr);
288}
289
291{
292 Graphic aRet;
293 sal_uInt8 nGreyThreshold = static_cast<sal_uInt8>(FRound(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 2.55));
294
295 if( rGraphic.IsAnimated() )
296 {
297 Animation aAnim( rGraphic.GetAnimation() );
298
299 if (BitmapFilter::Filter(aAnim, BitmapSolarizeFilter(nGreyThreshold)))
300 {
301 if( IsInvert() )
302 aAnim.Invert();
303
304 aRet = aAnim;
305 }
306 }
307 else
308 {
309 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
310
311 if (BitmapFilter::Filter(aBmpEx, BitmapSolarizeFilter(nGreyThreshold)))
312 {
313 if( IsInvert() )
314 aBmpEx.Invert();
315
316 aRet = aBmpEx;
317 }
318 }
319
320 return aRet;
321}
322
324 sal_uInt16 nSepiaPercent)
325 : GraphicFilterDialog(pParent, "cui/ui/agingdialog.ui", "AgingDialog", rGraphic)
326 , mxMtrSepia(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
327{
328 mxMtrSepia->set_value(nSepiaPercent, FieldUnit::PERCENT);
329 mxMtrSepia->connect_value_changed(LINK(this, GraphicFilterSepia, EditModifyHdl));
330}
331
333{
334 GetModifyHdl().Call(nullptr);
335}
336
338{
339 Graphic aRet;
340 sal_uInt16 nSepiaPct = sal::static_int_cast< sal_uInt16 >(mxMtrSepia->get_value(FieldUnit::PERCENT));
341
342 if( rGraphic.IsAnimated() )
343 {
344 Animation aAnim( rGraphic.GetAnimation() );
345
346 if (BitmapFilter::Filter(aAnim, BitmapSepiaFilter(nSepiaPct)))
347 aRet = aAnim;
348 }
349 else
350 {
351 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
352
353 if (BitmapFilter::Filter(aBmpEx, BitmapSepiaFilter(nSepiaPct)))
354 aRet = aBmpEx;
355 }
356
357 return aRet;
358}
359
361 sal_uInt16 nPosterCount)
362 : GraphicFilterDialog(pParent, "cui/ui/posterdialog.ui", "PosterDialog", rGraphic)
363 , mxNumPoster(m_xBuilder->weld_spin_button("value"))
364{
366 mxNumPoster->set_value(nPosterCount);
367 mxNumPoster->connect_value_changed(LINK(this, GraphicFilterPoster, EditModifyHdl));
368}
369
371{
372 GetModifyHdl().Call(nullptr);
373}
374
376{
377 Graphic aRet;
378 const sal_uInt16 nPosterCount = static_cast<sal_uInt16>(mxNumPoster->get_value());
379
380 if( rGraphic.IsAnimated() )
381 {
382 Animation aAnim( rGraphic.GetAnimation() );
383
384 if( aAnim.ReduceColors( nPosterCount ) )
385 aRet = aAnim;
386 }
387 else
388 {
389 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
390
391 if (BitmapFilter::Filter(aBmpEx, BitmapColorQuantizationFilter(nPosterCount)))
392 aRet = aBmpEx;
393 }
394
395 return aRet;
396}
397
399{
400 const RectPoint eOldRP = GetActualRP();
401
403
404 if( GetActualRP() != eOldRP )
405 maModifyHdl.Call( nullptr );
406
407 return true;
408}
409
411{
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());
415}
416
418 const Graphic& rGraphic, RectPoint eLightSource)
419 : GraphicFilterDialog(pParent, "cui/ui/embossdialog.ui", "EmbossDialog", rGraphic)
420 , mxCtlLight(new weld::CustomWeld(*m_xBuilder, "lightsource", maCtlLight))
421{
422 maCtlLight.SetActualRP(eLightSource);
424 maCtlLight.GrabFocus();
425}
426
428{
429}
430
432{
433 Graphic aRet;
434 sal_uInt16 nAzim, nElev;
435
436 switch (maCtlLight.GetActualRP())
437 {
438 default: OSL_FAIL("svx::GraphicFilterEmboss::GetFilteredGraphic(), unknown Reference Point!" );
439 [[fallthrough]];
440 case RectPoint::LT: nAzim = 4500; nElev = 4500; break;
441 case RectPoint::MT: nAzim = 9000; nElev = 4500; break;
442 case RectPoint::RT: nAzim = 13500; nElev = 4500; break;
443 case RectPoint::LM: nAzim = 0; nElev = 4500; break;
444 case RectPoint::MM: nAzim = 0; nElev = 9000; break;
445 case RectPoint::RM: nAzim = 18000; nElev = 4500; break;
446 case RectPoint::LB: nAzim = 31500; nElev = 4500; break;
447 case RectPoint::MB: nAzim = 27000; nElev = 4500; break;
448 case RectPoint::RB: nAzim = 22500; nElev = 4500; break;
449 }
450
451 if( rGraphic.IsAnimated() )
452 {
453 Animation aAnim( rGraphic.GetAnimation() );
454
455 if (BitmapFilter::Filter(aAnim, BitmapEmbossGreyFilter(nAzim, nElev)))
456 aRet = aAnim;
457 }
458 else
459 {
460 BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
461
462 if (BitmapFilter::Filter(aBmpEx, BitmapEmbossGreyFilter(nAzim, nElev)))
463 aRet = aBmpEx;
464 }
465
466 return aRet;
467}
468
469/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool ReduceColors(sal_uInt16 nNewColorCount)
bool Invert()
static const AllSettings & GetSettings()
bool Invert()
bool Scale(const Size &rNewSize, BmpScaleFlag nScaleFlag=BmpScaleFlag::Default)
vcl::PixelFormat getPixelFormat() const
static bool Filter(BitmapEx &rBmpEx, BitmapFilter const &rFilter)
virtual void Resize() override
Definition: cuigrfflt.cxx:120
const Graphic * mpOrigGraphic
Definition: cuigrfflt.hxx:29
Link< LinkParamNone *, void > maModifyHdl
Definition: cuigrfflt.hxx:32
void SetPreview(const Graphic &rGraphic)
Definition: cuigrfflt.cxx:71
void init(const Graphic *pOrigGraphic, const Link< LinkParamNone *, void > &rLink)
Definition: cuigrfflt.hxx:46
virtual void Paint(vcl::RenderContext &rRenderContext, const ::tools::Rectangle &rRect) override
Definition: cuigrfflt.cxx:48
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: cuigrfflt.cxx:40
void SetModifyHdl(const Link< LinkParamNone *, void > &rHdl)
Definition: cuigrfflt.hxx:164
virtual bool MouseButtonDown(const MouseEvent &rEvt) override
Definition: cuigrfflt.cxx:398
Link< LinkParamNone *, void > maModifyHdl
Definition: cuigrfflt.hxx:155
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
Definition: cuigrfflt.cxx:410
CuiGraphicPreviewWindow maPreview
Definition: cuigrfflt.hxx:73
const Link< LinkParamNone *, void > & GetModifyHdl() const
Definition: cuigrfflt.hxx:77
GraphicFilterDialog(weld::Window *pParent, const OUString &rUIXMLDescription, const OUString &rID, const Graphic &rGraphic)
Definition: cuigrfflt.cxx:126
const Size & GetGraphicSizePixel() const
Definition: cuigrfflt.hxx:78
Link< LinkParamNone *, void > maModifyHdl
Definition: cuigrfflt.hxx:67
virtual ~GraphicFilterEmboss() override
Definition: cuigrfflt.cxx:427
EmbossControl maCtlLight
Definition: cuigrfflt.hxx:170
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:431
GraphicFilterEmboss(weld::Window *pParent, const Graphic &rGraphic, RectPoint eLightSource)
Definition: cuigrfflt.cxx:417
std::unique_ptr< weld::MetricSpinButton > mxMtrWidth
Definition: cuigrfflt.hxx:101
bool IsEnhanceEdges() const
Definition: cuigrfflt.hxx:112
std::unique_ptr< weld::CheckButton > mxCbxEdges
Definition: cuigrfflt.hxx:103
GraphicFilterMosaic(weld::Window *pParent, const Graphic &rGraphic, sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges)
Definition: cuigrfflt.cxx:158
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:189
std::unique_ptr< weld::MetricSpinButton > mxMtrHeight
Definition: cuigrfflt.hxx:102
GraphicFilterPoster(weld::Window *pParent, const Graphic &rGraphic, sal_uInt16 nPosterColorCount)
Definition: cuigrfflt.cxx:360
std::unique_ptr< weld::SpinButton > mxNumPoster
Definition: cuigrfflt.hxx:144
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:375
std::unique_ptr< weld::MetricSpinButton > mxMtrSepia
Definition: cuigrfflt.hxx:133
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:337
GraphicFilterSepia(weld::Window *pParent, const Graphic &rGraphic, sal_uInt16 nSepiaPercent)
Definition: cuigrfflt.cxx:323
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:240
GraphicFilterSmooth(weld::Window *pParent, const Graphic &rGraphic, double nRadius)
Definition: cuigrfflt.cxx:226
std::unique_ptr< weld::SpinButton > mxMtrRadius
Definition: cuigrfflt.hxx:89
bool IsInvert() const
Definition: cuigrfflt.hxx:127
GraphicFilterSolarize(weld::Window *pParent, const Graphic &rGraphic, sal_uInt8 nGreyThreshold, bool bInvert)
Definition: cuigrfflt.cxx:267
std::unique_ptr< weld::MetricSpinButton > mxMtrThreshold
Definition: cuigrfflt.hxx:118
std::unique_ptr< weld::CheckButton > mxCbxInvert
Definition: cuigrfflt.hxx:119
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
Definition: cuigrfflt.cxx:290
Size GetPrefSize() const
Animation GetAnimation() const
GraphicType GetType() const
bool IsAnimated() const
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
MapMode GetPrefMapMode() const
Size GetSizePixel(const OutputDevice *pRefDevice=nullptr) const
void Draw(OutputDevice &rOutDev, const Point &rDestPt) const
void StartAnimation(OutputDevice &rOutDev, const Point &rDestPt, const Size &rDestSize, tools::Long nExtraData=0, OutputDevice *pFirstFrameOutDev=nullptr)
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
void SetBackground()
constexpr tools::Long getHeight() const
constexpr tools::Long Height() const
constexpr tools::Long getWidth() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
void SetActualRP(RectPoint eNewRP)
virtual bool MouseButtonDown(const MouseEvent &) override
virtual void SetDrawingArea(weld::DrawingArea *pDrawingArea) override
RectPoint GetActualRP() const
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
Size const & GetOutputSizePixel() const
virtual OutputDevice & get_ref_device()=0
virtual void set_size_request(int nWidth, int nHeight)=0
Link< ColorFieldControl &, void > maModifyHdl
IMPL_LINK_NOARG(GraphicFilterDialog, ImplPreviewTimeoutHdl, Timer *, void)
Definition: cuigrfflt.cxx:142
virtual Graphic GetFilteredGraphic(const Graphic &rGraphic, double fScaleX, double fScaleY) override
FieldUnit
tools::Long FRound(double fVal)
long Long
constexpr sal_uInt16 pixelFormatBitCount(PixelFormat ePixelFormat)
RectPoint
unsigned char sal_uInt8
constexpr OUStringLiteral PERCENT(u"Percent")