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/.
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 .
22 #include <config_options.h>
23 #include <sal/types.h>
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>
39 // interpolators for double precision
55 ip_single(double fVal
, double fInc
)
60 double getVal() const { return mfVal
; }
61 double getInc() const { return mfInc
; }
63 void increment(double fStep
) { mfVal
+= fStep
* mfInc
; }
76 ip_double(double fXVal
, double fXInc
, double fYVal
, double 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
); }
98 ip_triple(double fXVal
, double fXInc
, double fYVal
, double fYInc
, double fZVal
, double 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
119 ::std::vector
< ip_triple
> maColorInterpolators
;
120 ::std::vector
< ip_triple
> maNormalInterpolators
;
121 ::std::vector
< ip_double
> maTextureInterpolators
;
122 ::std::vector
< ip_triple
> maInverseTextureInterpolators
;
125 sal_uInt32
addColorInterpolator(const BColor
& rA
, const BColor
& rB
, double fInvYDelta
)
127 double aDeltaRed(rB
.getRed() - rA
.getRed());
129 if(fTools::equalZero(aDeltaRed
))
135 aDeltaRed
*= fInvYDelta
;
138 double aDeltaGreen(rB
.getGreen() - rA
.getGreen());
140 if(fTools::equalZero(aDeltaGreen
))
146 aDeltaGreen
*= fInvYDelta
;
149 double aDeltaBlue(rB
.getBlue() - rA
.getBlue());
151 if(fTools::equalZero(aDeltaBlue
))
157 aDeltaBlue
*= fInvYDelta
;
160 maColorInterpolators
.push_back(
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
))
179 aDeltaX
*= fInvYDelta
;
182 double aDeltaY(rB
.getY() - rA
.getY());
184 if(fTools::equalZero(aDeltaY
))
190 aDeltaY
*= fInvYDelta
;
193 double aDeltaZ(rB
.getZ() - rA
.getZ());
195 if(fTools::equalZero(aDeltaZ
))
201 aDeltaZ
*= fInvYDelta
;
204 maNormalInterpolators
.push_back(
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
))
223 aDeltaX
*= fInvYDelta
;
226 double aDeltaY(rB
.getY() - rA
.getY());
228 if(fTools::equalZero(aDeltaY
))
234 aDeltaY
*= fInvYDelta
;
237 maTextureInterpolators
.push_back(
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
))
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(
268 aInvA
.getX(), aDeltaX
,
269 aInvA
.getY(), aDeltaY
,
270 fInvZEyeA
, fZDelta
));
272 return (maInverseTextureInterpolators
.size() - 1);
277 maColorInterpolators
.clear();
278 maNormalInterpolators
.clear();
279 maTextureInterpolators
.clear();
280 maInverseTextureInterpolators
.clear();
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
302 sal_uInt32 mnColorIndex
;
303 sal_uInt32 mnNormalIndex
;
304 sal_uInt32 mnTextureIndex
;
305 sal_uInt32 mnInverseTextureIndex
;
308 RasterConversionLineEntry3D(const double& rfX
, const double& rfDeltaX
, const double& rfZ
, const double& rfDeltaZ
, sal_Int32 nY
, sal_uInt32 nCount
)
309 : maX(rfX
, rfDeltaX
),
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
328 return maX
.getVal() < rComp
.maX
.getVal();
331 return mnY
< rComp
.mnY
;
334 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep
)
347 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep
, InterpolatorProvider3D
& rProvider
)
349 const double fStep(static_cast<double>(nStep
));
350 maX
.increment(fStep
);
351 maZ
.increment(fStep
);
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
);
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
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;
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: */