Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / include / basegfx / raster / rasterconvert3d.hxx
blob83f753e3184b4e4f8700fb087d0bbfc57f636ab6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include <config_options.h>
23 #include <sal/types.h>
24 #include <vector>
26 #include <osl/diagnose.h>
28 #include <basegfx/color/bcolor.hxx>
29 #include <basegfx/vector/b3dvector.hxx>
30 #include <basegfx/point/b2dpoint.hxx>
31 #include <basegfx/basegfxdllapi.h>
33 namespace basegfx
35 class B3DPolygon;
36 class B3DPolyPolygon;
39 // interpolators for double precision
41 namespace basegfx
43 class ip_single
45 private:
46 double mfVal;
47 double mfInc;
49 public:
50 ip_single()
51 : mfVal(0.0),
52 mfInc(0.0)
55 ip_single(double fVal, double fInc)
56 : mfVal(fVal),
57 mfInc(fInc)
60 double getVal() const { return mfVal; }
61 double getInc() const { return mfInc; }
63 void increment(double fStep) { mfVal += fStep * mfInc; }
66 class ip_double
68 private:
69 ip_single maX;
70 ip_single maY;
72 public:
73 ip_double()
76 ip_double(double fXVal, double fXInc, double fYVal, double fYInc)
77 : maX(fXVal, fXInc),
78 maY(fYVal, fYInc)
81 const ip_single& getX() const { return maX; }
82 const ip_single& getY() const { return maY; }
84 void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); }
87 class ip_triple
89 private:
90 ip_single maX;
91 ip_single maY;
92 ip_single maZ;
94 public:
95 ip_triple()
98 ip_triple(double fXVal, double fXInc, double fYVal, double fYInc, double fZVal, double fZInc)
99 : maX(fXVal, fXInc),
100 maY(fYVal, fYInc),
101 maZ(fZVal, fZInc)
104 const ip_single& getX() const { return maX; }
105 const ip_single& getY() const { return maY; }
106 const ip_single& getZ() const { return maZ; }
108 void increment(double fStep) { maX.increment(fStep); maY.increment(fStep); maZ.increment(fStep); }
111 // InterpolatorProvider3D to have a common source for allocating interpolators
112 // which may then be addressed using the index to the vectors
114 #define SCANLINE_EMPTY_INDEX (0xffffffff)
116 class InterpolatorProvider3D
118 private:
119 ::std::vector< ip_triple > maColorInterpolators;
120 ::std::vector< ip_triple > maNormalInterpolators;
121 ::std::vector< ip_double > maTextureInterpolators;
122 ::std::vector< ip_triple > maInverseTextureInterpolators;
124 protected:
125 sal_uInt32 addColorInterpolator(const BColor& rA, const BColor& rB, double fInvYDelta)
127 double aDeltaRed(rB.getRed() - rA.getRed());
129 if(fTools::equalZero(aDeltaRed))
131 aDeltaRed = 0.0;
133 else
135 aDeltaRed *= fInvYDelta;
138 double aDeltaGreen(rB.getGreen() - rA.getGreen());
140 if(fTools::equalZero(aDeltaGreen))
142 aDeltaGreen = 0.0;
144 else
146 aDeltaGreen *= fInvYDelta;
149 double aDeltaBlue(rB.getBlue() - rA.getBlue());
151 if(fTools::equalZero(aDeltaBlue))
153 aDeltaBlue = 0.0;
155 else
157 aDeltaBlue *= fInvYDelta;
160 maColorInterpolators.push_back(
161 ip_triple(
162 rA.getRed(), aDeltaRed,
163 rA.getGreen(), aDeltaGreen,
164 rA.getBlue(), aDeltaBlue));
166 return (maColorInterpolators.size() - 1);
169 sal_uInt32 addNormalInterpolator(const B3DVector& rA, const B3DVector& rB, double fInvYDelta)
171 double aDeltaX(rB.getX() - rA.getX());
173 if(fTools::equalZero(aDeltaX))
175 aDeltaX = 0.0;
177 else
179 aDeltaX *= fInvYDelta;
182 double aDeltaY(rB.getY() - rA.getY());
184 if(fTools::equalZero(aDeltaY))
186 aDeltaY = 0.0;
188 else
190 aDeltaY *= fInvYDelta;
193 double aDeltaZ(rB.getZ() - rA.getZ());
195 if(fTools::equalZero(aDeltaZ))
197 aDeltaZ = 0.0;
199 else
201 aDeltaZ *= fInvYDelta;
204 maNormalInterpolators.push_back(
205 ip_triple(
206 rA.getX(), aDeltaX,
207 rA.getY(), aDeltaY,
208 rA.getZ(), aDeltaZ));
210 return (maNormalInterpolators.size() - 1);
213 sal_uInt32 addTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fInvYDelta)
215 double aDeltaX(rB.getX() - rA.getX());
217 if(fTools::equalZero(aDeltaX))
219 aDeltaX = 0.0;
221 else
223 aDeltaX *= fInvYDelta;
226 double aDeltaY(rB.getY() - rA.getY());
228 if(fTools::equalZero(aDeltaY))
230 aDeltaY = 0.0;
232 else
234 aDeltaY *= fInvYDelta;
237 maTextureInterpolators.push_back(
238 ip_double(
239 rA.getX(), aDeltaX,
240 rA.getY(), aDeltaY));
242 return (maTextureInterpolators.size() - 1);
245 sal_uInt32 addInverseTextureInterpolator(const B2DPoint& rA, const B2DPoint& rB, double fZEyeA, double fZEyeB, double fInvYDelta)
247 double fZDelta(fZEyeB - fZEyeA);
248 const double fInvZEyeA(fTools::equalZero(fZEyeA) ? fZEyeA : 1.0 / fZEyeA);
249 double fInvZEyeB(fInvZEyeA);
251 if(fTools::equalZero(fZDelta))
253 fZDelta = 0.0;
255 else
257 fInvZEyeB = fTools::equalZero(fZEyeB) ? fZEyeB : 1.0 / fZEyeB;
258 fZDelta = (fInvZEyeB - fInvZEyeA) * fInvYDelta;
261 const B2DPoint aInvA(rA * fInvZEyeA);
262 const B2DPoint aInvB(rB * fInvZEyeB);
263 const double aDeltaX((aInvB.getX() - aInvA.getX()) * fInvYDelta);
264 const double aDeltaY((aInvB.getY() - aInvA.getY()) * fInvYDelta);
266 maInverseTextureInterpolators.push_back(
267 ip_triple(
268 aInvA.getX(), aDeltaX,
269 aInvA.getY(), aDeltaY,
270 fInvZEyeA, fZDelta));
272 return (maInverseTextureInterpolators.size() - 1);
275 void reset()
277 maColorInterpolators.clear();
278 maNormalInterpolators.clear();
279 maTextureInterpolators.clear();
280 maInverseTextureInterpolators.clear();
283 public:
284 InterpolatorProvider3D() {}
286 ::std::vector< ip_triple >& getColorInterpolators() { return maColorInterpolators; }
287 ::std::vector< ip_triple >& getNormalInterpolators() { return maNormalInterpolators; }
288 ::std::vector< ip_double >& getTextureInterpolators() { return maTextureInterpolators; }
289 ::std::vector< ip_triple >& getInverseTextureInterpolators() { return maInverseTextureInterpolators; }
292 // RasterConversionLineEntry3D for Rasterconversion of 3D PolyPolygons
294 class RasterConversionLineEntry3D
296 private:
297 ip_single maX;
298 ip_single maZ;
299 sal_Int32 mnY;
300 sal_uInt32 mnCount;
302 sal_uInt32 mnColorIndex;
303 sal_uInt32 mnNormalIndex;
304 sal_uInt32 mnTextureIndex;
305 sal_uInt32 mnInverseTextureIndex;
307 public:
308 RasterConversionLineEntry3D(const double& rfX, const double& rfDeltaX, const double& rfZ, const double& rfDeltaZ, sal_Int32 nY, sal_uInt32 nCount)
309 : maX(rfX, rfDeltaX),
310 maZ(rfZ, rfDeltaZ),
311 mnY(nY),
312 mnCount(nCount),
313 mnColorIndex(SCANLINE_EMPTY_INDEX),
314 mnNormalIndex(SCANLINE_EMPTY_INDEX),
315 mnTextureIndex(SCANLINE_EMPTY_INDEX),
316 mnInverseTextureIndex(SCANLINE_EMPTY_INDEX)
319 void setColorIndex(sal_uInt32 nIndex) { mnColorIndex = nIndex; }
320 void setNormalIndex(sal_uInt32 nIndex) { mnNormalIndex = nIndex; }
321 void setTextureIndex(sal_uInt32 nIndex) { mnTextureIndex = nIndex; }
322 void setInverseTextureIndex(sal_uInt32 nIndex) { mnInverseTextureIndex = nIndex; }
324 bool operator<(const RasterConversionLineEntry3D& rComp) const
326 if(mnY == rComp.mnY)
328 return maX.getVal() < rComp.maX.getVal();
331 return mnY < rComp.mnY;
334 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep)
336 if(nStep >= mnCount)
338 return false;
340 else
342 mnCount -= nStep;
343 return true;
347 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep, InterpolatorProvider3D& rProvider)
349 const double fStep(static_cast<double>(nStep));
350 maX.increment(fStep);
351 maZ.increment(fStep);
352 mnY += nStep;
354 if(SCANLINE_EMPTY_INDEX != mnColorIndex)
356 rProvider.getColorInterpolators()[mnColorIndex].increment(fStep);
359 if(SCANLINE_EMPTY_INDEX != mnNormalIndex)
361 rProvider.getNormalInterpolators()[mnNormalIndex].increment(fStep);
364 if(SCANLINE_EMPTY_INDEX != mnTextureIndex)
366 rProvider.getTextureInterpolators()[mnTextureIndex].increment(fStep);
369 if(SCANLINE_EMPTY_INDEX != mnInverseTextureIndex)
371 rProvider.getInverseTextureInterpolators()[mnInverseTextureIndex].increment(fStep);
375 // data read access
376 const ip_single& getX() const { return maX; }
377 sal_Int32 getY() const { return mnY; }
378 const ip_single& getZ() const { return maZ; }
379 sal_uInt32 getColorIndex() const { return mnColorIndex; }
380 sal_uInt32 getNormalIndex() const { return mnNormalIndex; }
381 sal_uInt32 getTextureIndex() const { return mnTextureIndex; }
382 sal_uInt32 getInverseTextureIndex() const { return mnInverseTextureIndex; }
385 // the basic RasterConverter itself. Only one method needs to be overridden. The
386 // class itself is pure virtual
388 class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) RasterConverter3D : public InterpolatorProvider3D
390 private:
391 // the line entries for an area conversion run
392 ::std::vector< RasterConversionLineEntry3D > maLineEntries;
394 struct lineComparator
396 bool operator()(const RasterConversionLineEntry3D* pA, const RasterConversionLineEntry3D* pB)
398 OSL_ENSURE(pA && pB, "lineComparator: empty pointer (!)");
399 return pA->getX().getVal() < pB->getX().getVal();
403 SAL_DLLPRIVATE void addArea(const B3DPolygon& rFill, const B3DHomMatrix* pViewToEye);
404 SAL_DLLPRIVATE void addArea(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye);
405 SAL_DLLPRIVATE void addEdge(const B3DPolygon& rFill, sal_uInt32 a, sal_uInt32 b, const B3DHomMatrix* pViewToEye);
407 SAL_DLLPRIVATE void rasterconvertB3DArea(sal_Int32 nStartLine, sal_Int32 nStopLine);
408 SAL_DLLPRIVATE void rasterconvertB3DEdge(const B3DPolygon& rLine, sal_uInt32 nA, sal_uInt32 nB, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth);
410 virtual void processLineSpan(const RasterConversionLineEntry3D& rA, const RasterConversionLineEntry3D& rB, sal_Int32 nLine, sal_uInt32 nSpanCount) = 0;
412 public:
413 RasterConverter3D();
414 virtual ~RasterConverter3D();
416 void rasterconvertB3DPolyPolygon(const B3DPolyPolygon& rFill, const B3DHomMatrix* pViewToEye, sal_Int32 nStartLine, sal_Int32 nStopLine);
417 void rasterconvertB3DPolygon(const B3DPolygon& rLine, sal_Int32 nStartLine, sal_Int32 nStopLine, sal_uInt16 nLineWidth);
419 } // end of namespace basegfx
421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */