LibreOffice Module drawinglayer (master) 1
texture3d.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
20#include <sal/config.h>
21
22#include <algorithm>
23
24#include <texture/texture3d.hxx>
26#include <vcl/BitmapTools.hxx>
28#include <sal/log.hxx>
29#include <osl/diagnose.h>
30
32{
34 const basegfx::BColor& rSingleColor,
35 double fOpacity)
36 : maSingleColor(rSingleColor),
37 mfOpacity(fOpacity)
38 {
39 }
40
41 bool GeoTexSvxMono::operator==(const GeoTexSvx& rGeoTexSvx) const
42 {
43 const GeoTexSvxMono* pCompare = dynamic_cast< const GeoTexSvxMono* >(&rGeoTexSvx);
44
45 return (pCompare
46 && maSingleColor == pCompare->maSingleColor
47 && mfOpacity == pCompare->mfOpacity);
48 }
49
50 void GeoTexSvxMono::modifyBColor(const basegfx::B2DPoint& /*rUV*/, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
51 {
52 rBColor = maSingleColor;
53 }
54
55 void GeoTexSvxMono::modifyOpacity(const basegfx::B2DPoint& /*rUV*/, double& rfOpacity) const
56 {
57 rfOpacity = mfOpacity;
58 }
59
60
62 const BitmapEx& rBitmapEx,
63 const basegfx::B2DRange& rRange)
64 : maBitmapEx(rBitmapEx),
65 maTopLeft(rRange.getMinimum()),
66 maSize(rRange.getRange()),
67 mfMulX(0.0),
68 mfMulY(0.0),
69 mbIsAlpha(maBitmapEx.IsAlpha())
70 {
73 // #121194# Todo: use alpha channel, too (for 3d)
75
76 if(mbIsAlpha)
77 {
80 }
81
82 if (!maBitmap.IsEmpty())
84 SAL_WARN_IF(!mpReadBitmap, "drawinglayer", "GeoTexSvxBitmapEx: Got no read access to Bitmap");
85 if (mpReadBitmap)
86 {
87 mfMulX = static_cast<double>(mpReadBitmap->Width()) / maSize.getX();
88 mfMulY = static_cast<double>(mpReadBitmap->Height()) / maSize.getY();
89 }
90
91 if(maSize.getX() <= 1.0)
92 {
93 maSize.setX(1.0);
94 }
95
96 if(maSize.getY() <= 1.0)
97 {
98 maSize.setY(1.0);
99 }
100 }
101
103 {
104 }
105
106 sal_uInt8 GeoTexSvxBitmapEx::impGetTransparence(sal_Int32 rX, sal_Int32 rY) const
107 {
108 if(mbIsAlpha)
109 {
110 OSL_ENSURE(mpReadTransparence, "OOps, transparence type Bitmap, but no read access created in the constructor (?)");
111 const BitmapColor aBitmapColor(mpReadTransparence->GetPixel(rY, rX));
112 return aBitmapColor.GetIndex();
113 }
114 return 0;
115 }
116
117 bool GeoTexSvxBitmapEx::impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const
118 {
119 if(mpReadBitmap)
120 {
121 rX = static_cast<sal_Int32>((rUV.getX() - maTopLeft.getX()) * mfMulX);
122
123 if(rX >= 0 && rX < mpReadBitmap->Width())
124 {
125 rY = static_cast<sal_Int32>((rUV.getY() - maTopLeft.getY()) * mfMulY);
126
127 return (rY >= 0 && rY < mpReadBitmap->Height());
128 }
129 }
130
131 return false;
132 }
133
134 void GeoTexSvxBitmapEx::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
135 {
136 sal_Int32 nX, nY;
137
138 if(impIsValid(rUV, nX, nY))
139 {
140 const double fConvertColor(1.0 / 255.0);
141 const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX));
142 const basegfx::BColor aBSource(
143 static_cast<double>(aBMCol.GetRed()) * fConvertColor,
144 static_cast<double>(aBMCol.GetGreen()) * fConvertColor,
145 static_cast<double>(aBMCol.GetBlue()) * fConvertColor);
146
147 rBColor = aBSource;
148
149 if(mbIsAlpha)
150 {
151 // when we have a transparence, make use of it
152 const sal_uInt8 aLuminance(impGetTransparence(nX, nY));
153
154 rfOpacity = (static_cast<double>(0xff - aLuminance) * (1.0 / 255.0));
155 }
156 else
157 {
158 rfOpacity = 1.0;
159 }
160 }
161 else
162 {
163 rfOpacity = 0.0;
164 }
165 }
166
167 void GeoTexSvxBitmapEx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
168 {
169 sal_Int32 nX, nY;
170
171 if(impIsValid(rUV, nX, nY))
172 {
173 if(mbIsAlpha)
174 {
175 // this texture has an alpha part, use it
176 const sal_uInt8 aLuminance(impGetTransparence(nX, nY));
177 const double fNewOpacity(static_cast<double>(0xff - aLuminance) * (1.0 / 255.0));
178
179 rfOpacity = 1.0 - ((1.0 - fNewOpacity) * (1.0 - rfOpacity));
180 }
181 else
182 {
183 // this texture is a color bitmap used as transparence map
184 const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX));
185 const Color aColor(aBMCol.GetRed(), aBMCol.GetGreen(), aBMCol.GetBlue());
186
187 rfOpacity = (static_cast<double>(0xff - aColor.GetLuminance()) * (1.0 / 255.0));
188 }
189 }
190 else
191 {
192 rfOpacity = 0.0;
193 }
194 }
195
196
198 {
199 double fX(rUV.getX() - maTopLeft.getX());
200 double fY(rUV.getY() - maTopLeft.getY());
201
202 if(mbUseOffsetX)
203 {
204 const sal_Int32 nCol(static_cast< sal_Int32 >((fY < 0.0 ? maSize.getY() -fY : fY) / maSize.getY()));
205
206 if(nCol % 2)
207 {
208 fX += mfOffsetX * maSize.getX();
209 }
210 }
211 else if(mbUseOffsetY)
212 {
213 const sal_Int32 nRow(static_cast< sal_Int32 >((fX < 0.0 ? maSize.getX() -fX : fX) / maSize.getX()));
214
215 if(nRow % 2)
216 {
217 fY += mfOffsetY * maSize.getY();
218 }
219 }
220
221 fX = fmod(fX, maSize.getX());
222 fY = fmod(fY, maSize.getY());
223
224 if(fX < 0.0)
225 {
226 fX += maSize.getX();
227 }
228
229 if(fY < 0.0)
230 {
231 fY += maSize.getY();
232 }
233
234 return basegfx::B2DPoint(fX + maTopLeft.getX(), fY + maTopLeft.getY());
235 }
236
238 const BitmapEx& rBitmapEx,
239 const basegfx::B2DRange& rRange,
240 double fOffsetX,
241 double fOffsetY)
242 : GeoTexSvxBitmapEx(rBitmapEx, rRange),
243 mfOffsetX(std::clamp(fOffsetX, 0.0, 1.0)),
244 mfOffsetY(std::clamp(fOffsetY, 0.0, 1.0)),
245 mbUseOffsetX(!basegfx::fTools::equalZero(mfOffsetX)),
246 mbUseOffsetY(!mbUseOffsetX && !basegfx::fTools::equalZero(mfOffsetY))
247 {
248 }
249
250 void GeoTexSvxBitmapExTiled::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
251 {
252 if(mpReadBitmap)
253 {
254 GeoTexSvxBitmapEx::modifyBColor(impGetCorrected(rUV), rBColor, rfOpacity);
255 }
256 }
257
258 void GeoTexSvxBitmapExTiled::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
259 {
260 if(mpReadBitmap)
261 {
263 }
264 }
265
266
268 const primitive3d::HatchTexturePrimitive3D& rPrimitive,
269 double fLogicPixelSize)
270 : mfLogicPixelSize(fLogicPixelSize)
271 {
272 const attribute::FillHatchAttribute& rHatch(rPrimitive.getHatch());
273 const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY());
274 const double fAngleA(rHatch.getAngle());
275 maColor = rHatch.getColor();
277 mp0.reset( new GeoTexSvxHatch(
278 aOutlineRange,
279 aOutlineRange,
280 rHatch.getDistance(),
281 fAngleA) );
282
284 {
285 mp1.reset( new GeoTexSvxHatch(
286 aOutlineRange,
287 aOutlineRange,
288 rHatch.getDistance(),
289 fAngleA + M_PI_2) );
290 }
291
293 {
294 mp2.reset( new GeoTexSvxHatch(
295 aOutlineRange,
296 aOutlineRange,
297 rHatch.getDistance(),
298 fAngleA + M_PI_4) );
299 }
300 }
301
303 {
304 }
305
307 {
308 if(mp0->getDistanceToHatch(rUV) < mfLogicPixelSize)
309 {
310 return true;
311 }
312
313 if(mp1 && mp1->getDistanceToHatch(rUV) < mfLogicPixelSize)
314 {
315 return true;
316 }
317
318 if(mp2 && mp2->getDistanceToHatch(rUV) < mfLogicPixelSize)
319 {
320 return true;
321 }
322
323 return false;
324 }
325
326 void GeoTexSvxMultiHatch::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const
327 {
328 if(impIsOnHatch(rUV))
329 {
330 rBColor = maColor;
331 }
332 else if(!mbFillBackground)
333 {
334 rfOpacity = 0.0;
335 }
336 }
337
338 void GeoTexSvxMultiHatch::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
339 {
341 {
342 rfOpacity = 1.0;
343 }
344 else
345 {
346 rfOpacity = 0.0;
347 }
348 }
349
350} // end of namespace
351
352/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
geometry::RealSize2D maSize
Bitmap const & GetBitmap() const
sal_uInt8 GetIndex() const
const AlphaMask & GetAlphaMask() const
bool IsAlpha() const
Bitmap GetBitmap(Color aTransparentReplaceColor) const
bool IsEmpty() const
vcl::ScopedBitmapAccess< BitmapReadAccess, Bitmap, &Bitmap::AcquireReadAccess > ScopedReadAccess
sal_uInt8 GetLuminance() const
TYPE getX() const
void setY(TYPE fY)
TYPE getY() const
void setX(TYPE fX)
const attribute::FillHatchAttribute & getHatch() const
data read access
const basegfx::B2DVector & getTextureSize() const
data read access
basegfx::B2DPoint impGetCorrected(const basegfx::B2DPoint &rUV) const
Definition: texture3d.cxx:197
virtual void modifyOpacity(const basegfx::B2DPoint &rUV, double &rfOpacity) const override
Definition: texture3d.cxx:258
GeoTexSvxBitmapExTiled(const BitmapEx &rBitmapEx, const basegfx::B2DRange &rRange, double fOffsetX, double fOffsetY)
Definition: texture3d.cxx:237
virtual void modifyBColor(const basegfx::B2DPoint &rUV, basegfx::BColor &rBColor, double &rfOpacity) const override
Definition: texture3d.cxx:250
sal_uInt8 impGetTransparence(sal_Int32 rX, sal_Int32 rY) const
Definition: texture3d.cxx:106
bool impIsValid(const basegfx::B2DPoint &rUV, sal_Int32 &rX, sal_Int32 &rY) const
Definition: texture3d.cxx:117
virtual void modifyBColor(const basegfx::B2DPoint &rUV, basegfx::BColor &rBColor, double &rfOpacity) const override
Definition: texture3d.cxx:134
GeoTexSvxBitmapEx(const BitmapEx &rBitmapEx, const basegfx::B2DRange &rRange)
Definition: texture3d.cxx:61
Bitmap::ScopedReadAccess mpReadBitmap
Definition: texture3d.hxx:56
Bitmap::ScopedReadAccess mpReadTransparence
Definition: texture3d.hxx:58
virtual void modifyOpacity(const basegfx::B2DPoint &rUV, double &rfOpacity) const override
Definition: texture3d.cxx:167
virtual void modifyBColor(const basegfx::B2DPoint &rUV, basegfx::BColor &rBColor, double &rfOpacity) const override
Definition: texture3d.cxx:50
virtual void modifyOpacity(const basegfx::B2DPoint &rUV, double &rfOpacity) const override
Definition: texture3d.cxx:55
GeoTexSvxMono(const basegfx::BColor &rSingleColor, double fOpacity)
Definition: texture3d.cxx:33
virtual bool operator==(const GeoTexSvx &rGeoTexSvx) const override
Definition: texture3d.cxx:41
virtual void modifyBColor(const basegfx::B2DPoint &rUV, basegfx::BColor &rBColor, double &rfOpacity) const override
Definition: texture3d.cxx:326
GeoTexSvxMultiHatch(const primitive3d::HatchTexturePrimitive3D &rPrimitive, double fLogicPixelSize)
Definition: texture3d.cxx:267
std::unique_ptr< GeoTexSvxHatch > mp2
Definition: texture3d.hxx:116
std::unique_ptr< GeoTexSvxHatch > mp1
Definition: texture3d.hxx:115
std::unique_ptr< GeoTexSvxHatch > mp0
Definition: texture3d.hxx:114
bool impIsOnHatch(const basegfx::B2DPoint &rUV) const
Definition: texture3d.cxx:306
virtual void modifyOpacity(const basegfx::B2DPoint &rUV, double &rfOpacity) const override
Definition: texture3d.cxx:338
#define SAL_WARN_IF(condition, area, stream)
bool equalZero(const T &rfVal)
B2DRange getRange(const B2DPolygon &rCandidate)
bool convertBitmap32To24Plus8(BitmapEx const &rInput, BitmapEx &rResult)
unsigned char sal_uInt8