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/.
11 #include <sal/config.h>
15 #include <tools/helpers.hxx>
16 #include <vcl/bitmap.hxx>
17 #include <vcl/bitmapex.hxx>
18 #include <vcl/bitmapaccess.hxx>
19 #include <vcl/BitmapEmbossGreyFilter.hxx>
21 #include <bitmapwriteaccess.hxx>
23 BitmapEx
BitmapEmbossGreyFilter::execute(BitmapEx
const& rBitmapEx
) const
25 Bitmap
aBitmap(rBitmapEx
.GetBitmap());
27 bool bRet
= aBitmap
.ImplMakeGreyscales(256);
33 Bitmap::ScopedReadAccess
pReadAcc(aBitmap
);
37 Bitmap
aNewBmp(aBitmap
.GetSizePixel(), 8, &pReadAcc
->GetPalette());
38 BitmapScopedWriteAccess
pWriteAcc(aNewBmp
);
42 BitmapColor
aGrey(sal_uInt8(0));
43 const long nWidth
= pWriteAcc
->Width();
44 const long nHeight
= pWriteAcc
->Height();
45 long nGrey11
, nGrey12
, nGrey13
;
46 long nGrey21
, nGrey22
, nGrey23
;
47 long nGrey31
, nGrey32
, nGrey33
;
48 double fAzim
= basegfx::deg2rad(mnAzimuthAngle100
* 0.01);
49 double fElev
= basegfx::deg2rad(mnElevationAngle100
* 0.01);
50 std::unique_ptr
<long[]> pHMap(new long[nWidth
+ 2]);
51 std::unique_ptr
<long[]> pVMap(new long[nHeight
+ 2]);
52 long nX
, nY
, nNx
, nNy
, nDotL
;
53 const long nLx
= FRound(cos(fAzim
) * cos(fElev
) * 255.0);
54 const long nLy
= FRound(sin(fAzim
) * cos(fElev
) * 255.0);
55 const long nLz
= FRound(sin(fElev
) * 255.0);
56 const auto nZ2
= ((6 * 255) / 4) * ((6 * 255) / 4);
57 const long nNzLz
= ((6 * 255) / 4) * nLz
;
58 const sal_uInt8 cLz
= static_cast<sal_uInt8
>(std::clamp(nLz
, 0L, 255L));
60 // fill mapping tables
63 for (nX
= 1; nX
<= nWidth
; nX
++)
68 pHMap
[nWidth
+ 1] = nWidth
- 1;
72 for (nY
= 1; nY
<= nHeight
; nY
++)
77 pVMap
[nHeight
+ 1] = nHeight
- 1;
79 for (nY
= 0; nY
< nHeight
; nY
++)
81 nGrey11
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[0]).GetIndex();
82 nGrey12
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[1]).GetIndex();
83 nGrey13
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[2]).GetIndex();
84 nGrey21
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[0]).GetIndex();
85 nGrey22
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[1]).GetIndex();
86 nGrey23
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[2]).GetIndex();
87 nGrey31
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[0]).GetIndex();
88 nGrey32
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[1]).GetIndex();
89 nGrey33
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[2]).GetIndex();
91 Scanline pScanline
= pWriteAcc
->GetScanline(nY
);
92 for (nX
= 0; nX
< nWidth
; nX
++)
94 nNx
= nGrey11
+ nGrey21
+ nGrey31
- nGrey13
- nGrey23
- nGrey33
;
95 nNy
= nGrey31
+ nGrey32
+ nGrey33
- nGrey11
- nGrey12
- nGrey13
;
101 else if ((nDotL
= nNx
* nLx
+ nNy
* nLy
+ nNzLz
) < 0)
108 = nDotL
/ sqrt(static_cast<double>(nNx
* nNx
+ nNy
* nNy
+ nZ2
));
109 aGrey
.SetIndex(static_cast<sal_uInt8
>(std::clamp(fGrey
, 0.0, 255.0)));
112 pWriteAcc
->SetPixelOnData(pScanline
, nX
, aGrey
);
114 if (nX
< (nWidth
- 1))
116 const long nNextX
= pHMap
[nX
+ 3];
120 nGrey13
= pReadAcc
->GetPixel(pVMap
[nY
], nNextX
).GetIndex();
123 nGrey23
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], nNextX
).GetIndex();
126 nGrey33
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], nNextX
).GetIndex();
141 const MapMode
aMap(aBitmap
.GetPrefMapMode());
142 const Size
aPrefSize(aBitmap
.GetPrefSize());
146 aBitmap
.SetPrefMapMode(aMap
);
147 aBitmap
.SetPrefSize(aPrefSize
);
153 return BitmapEx(aBitmap
);
158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */