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 tools::Long nWidth
= pWriteAcc
->Width();
44 const tools::Long nHeight
= pWriteAcc
->Height();
45 tools::Long nGrey11
, nGrey12
, nGrey13
;
46 tools::Long nGrey21
, nGrey22
, nGrey23
;
47 tools::Long nGrey31
, nGrey32
, nGrey33
;
48 double fAzim
= basegfx::deg2rad(mnAzimuthAngle100
* 0.01);
49 double fElev
= basegfx::deg2rad(mnElevationAngle100
* 0.01);
50 std::unique_ptr
<tools::Long
[]> pHMap(new tools::Long
[nWidth
+ 2]);
51 std::unique_ptr
<tools::Long
[]> pVMap(new tools::Long
[nHeight
+ 2]);
52 tools::Long nX
, nY
, nNx
, nNy
, nDotL
;
53 const tools::Long nLx
= FRound(cos(fAzim
) * cos(fElev
) * 255.0);
54 const tools::Long nLy
= FRound(sin(fAzim
) * cos(fElev
) * 255.0);
55 const tools::Long nLz
= FRound(sin(fElev
) * 255.0);
56 const auto nZ2
= ((6 * 255) / 4) * ((6 * 255) / 4);
57 const tools::Long nNzLz
= ((6 * 255) / 4) * nLz
;
59 = static_cast<sal_uInt8
>(std::clamp(nLz
, tools::Long(0), tools::Long(255)));
61 // fill mapping tables
64 for (nX
= 1; nX
<= nWidth
; nX
++)
69 pHMap
[nWidth
+ 1] = nWidth
- 1;
73 for (nY
= 1; nY
<= nHeight
; nY
++)
78 pVMap
[nHeight
+ 1] = nHeight
- 1;
80 for (nY
= 0; nY
< nHeight
; nY
++)
82 nGrey11
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[0]).GetIndex();
83 nGrey12
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[1]).GetIndex();
84 nGrey13
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[2]).GetIndex();
85 nGrey21
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[0]).GetIndex();
86 nGrey22
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[1]).GetIndex();
87 nGrey23
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[2]).GetIndex();
88 nGrey31
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[0]).GetIndex();
89 nGrey32
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[1]).GetIndex();
90 nGrey33
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[2]).GetIndex();
92 Scanline pScanline
= pWriteAcc
->GetScanline(nY
);
93 for (nX
= 0; nX
< nWidth
; nX
++)
95 nNx
= nGrey11
+ nGrey21
+ nGrey31
- nGrey13
- nGrey23
- nGrey33
;
96 nNy
= nGrey31
+ nGrey32
+ nGrey33
- nGrey11
- nGrey12
- nGrey13
;
102 else if ((nDotL
= nNx
* nLx
+ nNy
* nLy
+ nNzLz
) < 0)
109 = nDotL
/ sqrt(static_cast<double>(nNx
* nNx
+ nNy
* nNy
+ nZ2
));
110 aGrey
.SetIndex(static_cast<sal_uInt8
>(std::clamp(fGrey
, 0.0, 255.0)));
113 pWriteAcc
->SetPixelOnData(pScanline
, nX
, aGrey
);
115 if (nX
< (nWidth
- 1))
117 const tools::Long nNextX
= pHMap
[nX
+ 3];
121 nGrey13
= pReadAcc
->GetPixel(pVMap
[nY
], nNextX
).GetIndex();
124 nGrey23
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], nNextX
).GetIndex();
127 nGrey33
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], nNextX
).GetIndex();
142 const MapMode
aMap(aBitmap
.GetPrefMapMode());
143 const Size
aPrefSize(aBitmap
.GetPrefSize());
147 aBitmap
.SetPrefMapMode(aMap
);
148 aBitmap
.SetPrefSize(aPrefSize
);
154 return BitmapEx(aBitmap
);
159 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */