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>
27 #include <osl/diagnose.h>
29 #include <basegfx/color/bcolor.hxx>
30 #include <basegfx/vector/b3dvector.hxx>
31 #include <basegfx/point/b2dpoint.hxx>
32 #include <basegfx/basegfxdllapi.h>
40 // interpolators for double precision
56 ip_single(double fVal
, double fInc
)
61 double getVal() const { return mfVal
; }
62 double getInc() const { return mfInc
; }
64 void increment(double fStep
) { mfVal
+= fStep
* mfInc
; }
77 ip_double(double fXVal
, double fXInc
, double fYVal
, double fYInc
)
82 const ip_single
& getX() const { return maX
; }
83 const ip_single
& getY() const { return maY
; }
85 void increment(double fStep
) { maX
.increment(fStep
); maY
.increment(fStep
); }
99 ip_triple(double fXVal
, double fXInc
, double fYVal
, double fYInc
, double fZVal
, double fZInc
)
105 const ip_single
& getX() const { return maX
; }
106 const ip_single
& getY() const { return maY
; }
107 const ip_single
& getZ() const { return maZ
; }
109 void increment(double fStep
) { maX
.increment(fStep
); maY
.increment(fStep
); maZ
.increment(fStep
); }
112 // InterpolatorProvider3D to have a common source for allocating interpolators
113 // which may then be addressed using the index to the vectors
115 #define SCANLINE_EMPTY_INDEX (0xffffffff)
117 class InterpolatorProvider3D
120 ::std::vector
< ip_triple
> maColorInterpolators
;
121 ::std::vector
< ip_triple
> maNormalInterpolators
;
122 ::std::vector
< ip_double
> maTextureInterpolators
;
123 ::std::vector
< ip_triple
> maInverseTextureInterpolators
;
126 sal_uInt32
addColorInterpolator(const BColor
& rA
, const BColor
& rB
, double fInvYDelta
)
128 double aDeltaRed(rB
.getRed() - rA
.getRed());
130 if(fTools::equalZero(aDeltaRed
))
136 aDeltaRed
*= fInvYDelta
;
139 double aDeltaGreen(rB
.getGreen() - rA
.getGreen());
141 if(fTools::equalZero(aDeltaGreen
))
147 aDeltaGreen
*= fInvYDelta
;
150 double aDeltaBlue(rB
.getBlue() - rA
.getBlue());
152 if(fTools::equalZero(aDeltaBlue
))
158 aDeltaBlue
*= fInvYDelta
;
161 maColorInterpolators
.push_back(
163 rA
.getRed(), aDeltaRed
,
164 rA
.getGreen(), aDeltaGreen
,
165 rA
.getBlue(), aDeltaBlue
));
167 return (maColorInterpolators
.size() - 1);
170 sal_uInt32
addNormalInterpolator(const B3DVector
& rA
, const B3DVector
& rB
, double fInvYDelta
)
172 double aDeltaX(rB
.getX() - rA
.getX());
174 if(fTools::equalZero(aDeltaX
))
180 aDeltaX
*= fInvYDelta
;
183 double aDeltaY(rB
.getY() - rA
.getY());
185 if(fTools::equalZero(aDeltaY
))
191 aDeltaY
*= fInvYDelta
;
194 double aDeltaZ(rB
.getZ() - rA
.getZ());
196 if(fTools::equalZero(aDeltaZ
))
202 aDeltaZ
*= fInvYDelta
;
205 maNormalInterpolators
.push_back(
209 rA
.getZ(), aDeltaZ
));
211 return (maNormalInterpolators
.size() - 1);
214 sal_uInt32
addTextureInterpolator(const B2DPoint
& rA
, const B2DPoint
& rB
, double fInvYDelta
)
216 double aDeltaX(rB
.getX() - rA
.getX());
218 if(fTools::equalZero(aDeltaX
))
224 aDeltaX
*= fInvYDelta
;
227 double aDeltaY(rB
.getY() - rA
.getY());
229 if(fTools::equalZero(aDeltaY
))
235 aDeltaY
*= fInvYDelta
;
238 maTextureInterpolators
.push_back(
241 rA
.getY(), aDeltaY
));
243 return (maTextureInterpolators
.size() - 1);
246 sal_uInt32
addInverseTextureInterpolator(const B2DPoint
& rA
, const B2DPoint
& rB
, double fZEyeA
, double fZEyeB
, double fInvYDelta
)
248 double fZDelta(fZEyeB
- fZEyeA
);
249 const double fInvZEyeA(fTools::equalZero(fZEyeA
) ? fZEyeA
: 1.0 / fZEyeA
);
250 double fInvZEyeB(fInvZEyeA
);
252 if(fTools::equalZero(fZDelta
))
258 fInvZEyeB
= fTools::equalZero(fZEyeB
) ? fZEyeB
: 1.0 / fZEyeB
;
259 fZDelta
= (fInvZEyeB
- fInvZEyeA
) * fInvYDelta
;
262 const B2DPoint
aInvA(rA
* fInvZEyeA
);
263 const B2DPoint
aInvB(rB
* fInvZEyeB
);
264 const double aDeltaX((aInvB
.getX() - aInvA
.getX()) * fInvYDelta
);
265 const double aDeltaY((aInvB
.getY() - aInvA
.getY()) * fInvYDelta
);
267 maInverseTextureInterpolators
.push_back(
269 aInvA
.getX(), aDeltaX
,
270 aInvA
.getY(), aDeltaY
,
271 fInvZEyeA
, fZDelta
));
273 return (maInverseTextureInterpolators
.size() - 1);
278 maColorInterpolators
.clear();
279 maNormalInterpolators
.clear();
280 maTextureInterpolators
.clear();
281 maInverseTextureInterpolators
.clear();
285 InterpolatorProvider3D() {}
287 ::std::vector
< ip_triple
>& getColorInterpolators() { return maColorInterpolators
; }
288 ::std::vector
< ip_triple
>& getNormalInterpolators() { return maNormalInterpolators
; }
289 ::std::vector
< ip_double
>& getTextureInterpolators() { return maTextureInterpolators
; }
290 ::std::vector
< ip_triple
>& getInverseTextureInterpolators() { return maInverseTextureInterpolators
; }
293 // RasterConversionLineEntry3D for Rasterconversion of 3D PolyPolygons
295 class RasterConversionLineEntry3D
303 sal_uInt32 mnColorIndex
;
304 sal_uInt32 mnNormalIndex
;
305 sal_uInt32 mnTextureIndex
;
306 sal_uInt32 mnInverseTextureIndex
;
309 RasterConversionLineEntry3D(const double& rfX
, const double& rfDeltaX
, const double& rfZ
, const double& rfDeltaZ
, sal_Int32 nY
, sal_uInt32 nCount
)
310 : maX(rfX
, rfDeltaX
),
314 mnColorIndex(SCANLINE_EMPTY_INDEX
),
315 mnNormalIndex(SCANLINE_EMPTY_INDEX
),
316 mnTextureIndex(SCANLINE_EMPTY_INDEX
),
317 mnInverseTextureIndex(SCANLINE_EMPTY_INDEX
)
320 void setColorIndex(sal_uInt32 nIndex
) { mnColorIndex
= nIndex
; }
321 void setNormalIndex(sal_uInt32 nIndex
) { mnNormalIndex
= nIndex
; }
322 void setTextureIndex(sal_uInt32 nIndex
) { mnTextureIndex
= nIndex
; }
323 void setInverseTextureIndex(sal_uInt32 nIndex
) { mnInverseTextureIndex
= nIndex
; }
325 bool operator<(const RasterConversionLineEntry3D
& rComp
) const
329 return maX
.getVal() < rComp
.maX
.getVal();
332 return mnY
< rComp
.mnY
;
335 bool decrementRasterConversionLineEntry3D(sal_uInt32 nStep
)
348 void incrementRasterConversionLineEntry3D(sal_uInt32 nStep
, InterpolatorProvider3D
& rProvider
)
350 const double fStep(static_cast<double>(nStep
));
351 maX
.increment(fStep
);
352 maZ
.increment(fStep
);
355 if(SCANLINE_EMPTY_INDEX
!= mnColorIndex
)
357 rProvider
.getColorInterpolators()[mnColorIndex
].increment(fStep
);
360 if(SCANLINE_EMPTY_INDEX
!= mnNormalIndex
)
362 rProvider
.getNormalInterpolators()[mnNormalIndex
].increment(fStep
);
365 if(SCANLINE_EMPTY_INDEX
!= mnTextureIndex
)
367 rProvider
.getTextureInterpolators()[mnTextureIndex
].increment(fStep
);
370 if(SCANLINE_EMPTY_INDEX
!= mnInverseTextureIndex
)
372 rProvider
.getInverseTextureInterpolators()[mnInverseTextureIndex
].increment(fStep
);
377 const ip_single
& getX() const { return maX
; }
378 sal_Int32
getY() const { return mnY
; }
379 const ip_single
& getZ() const { return maZ
; }
380 sal_uInt32
getColorIndex() const { return mnColorIndex
; }
381 sal_uInt32
getNormalIndex() const { return mnNormalIndex
; }
382 sal_uInt32
getTextureIndex() const { return mnTextureIndex
; }
383 sal_uInt32
getInverseTextureIndex() const { return mnInverseTextureIndex
; }
386 // the basic RasterConverter itself. Only one method needs to be overridden. The
387 // class itself is pure virtual
389 class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC
) RasterConverter3D
: public InterpolatorProvider3D
392 // the line entries for an area conversion run
393 ::std::vector
< RasterConversionLineEntry3D
> maLineEntries
;
395 struct lineComparator
397 bool operator()(const RasterConversionLineEntry3D
* pA
, const RasterConversionLineEntry3D
* pB
)
399 assert(pA
&& pB
&& "lineComparator: empty pointer (!)");
400 return pA
->getX().getVal() < pB
->getX().getVal();
404 SAL_DLLPRIVATE
void addArea(const B3DPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
);
405 SAL_DLLPRIVATE
void addArea(const B3DPolyPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
);
406 SAL_DLLPRIVATE
void addEdge(const B3DPolygon
& rFill
, sal_uInt32 a
, sal_uInt32 b
, const B3DHomMatrix
* pViewToEye
);
408 SAL_DLLPRIVATE
void rasterconvertB3DArea(sal_Int32 nStartLine
, sal_Int32 nStopLine
);
409 SAL_DLLPRIVATE
void rasterconvertB3DEdge(const B3DPolygon
& rLine
, sal_uInt32 nA
, sal_uInt32 nB
, sal_Int32 nStartLine
, sal_Int32 nStopLine
, sal_uInt16 nLineWidth
);
411 virtual void processLineSpan(const RasterConversionLineEntry3D
& rA
, const RasterConversionLineEntry3D
& rB
, sal_Int32 nLine
, sal_uInt32 nSpanCount
) = 0;
415 virtual ~RasterConverter3D();
417 void rasterconvertB3DPolyPolygon(const B3DPolyPolygon
& rFill
, const B3DHomMatrix
* pViewToEye
, sal_Int32 nStartLine
, sal_Int32 nStopLine
);
418 void rasterconvertB3DPolygon(const B3DPolygon
& rLine
, sal_Int32 nStartLine
, sal_Int32 nStopLine
, sal_uInt16 nLineWidth
);
420 } // end of namespace basegfx
422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */