1*69de5a4cSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*69de5a4cSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*69de5a4cSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*69de5a4cSAndrew Rist * distributed with this work for additional information 6*69de5a4cSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*69de5a4cSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*69de5a4cSAndrew Rist * "License"); you may not use this file except in compliance 9*69de5a4cSAndrew Rist * with the License. You may obtain a copy of the License at 10*69de5a4cSAndrew Rist * 11*69de5a4cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*69de5a4cSAndrew Rist * 13*69de5a4cSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*69de5a4cSAndrew Rist * software distributed under the License is distributed on an 15*69de5a4cSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*69de5a4cSAndrew Rist * KIND, either express or implied. See the License for the 17*69de5a4cSAndrew Rist * specific language governing permissions and limitations 18*69de5a4cSAndrew Rist * under the License. 19*69de5a4cSAndrew Rist * 20*69de5a4cSAndrew Rist *************************************************************/ 21*69de5a4cSAndrew Rist 22*69de5a4cSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "basebmp/polypolygonrenderer.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include <algorithm> 27cdf0e10cSrcweir 28cdf0e10cSrcweir 29cdf0e10cSrcweir namespace basebmp 30cdf0e10cSrcweir { 31cdf0e10cSrcweir namespace detail 32cdf0e10cSrcweir { setupGlobalEdgeTable(VectorOfVectorOfVertices & rGET,basegfx::B2DPolyPolygon const & rPolyPoly,sal_Int32 nMinY)33cdf0e10cSrcweir sal_uInt32 setupGlobalEdgeTable( VectorOfVectorOfVertices& rGET, 34cdf0e10cSrcweir basegfx::B2DPolyPolygon const& rPolyPoly, 35cdf0e10cSrcweir sal_Int32 nMinY ) 36cdf0e10cSrcweir { 37cdf0e10cSrcweir sal_Int32 const nNumScanlines( (sal_Int32)rGET.size() ); 38cdf0e10cSrcweir 39cdf0e10cSrcweir // add all polygons to GET 40cdf0e10cSrcweir for( sal_uInt32 i(0), nCount(rPolyPoly.count()); 41cdf0e10cSrcweir i<nCount; 42cdf0e10cSrcweir ++i ) 43cdf0e10cSrcweir { 44cdf0e10cSrcweir // add all vertices to GET 45cdf0e10cSrcweir const basegfx::B2DPolygon& rPoly( rPolyPoly.getB2DPolygon(i) ); 46cdf0e10cSrcweir for( sal_uInt32 k(0), nVertices(rPoly.count()); 47cdf0e10cSrcweir k<nVertices; 48cdf0e10cSrcweir ++k ) 49cdf0e10cSrcweir { 50cdf0e10cSrcweir const basegfx::B2DPoint& rP1( rPoly.getB2DPoint(k) ); 51cdf0e10cSrcweir const basegfx::B2DPoint& rP2( rPoly.getB2DPoint( (k + 1) % nVertices ) ); 52cdf0e10cSrcweir 53cdf0e10cSrcweir const sal_Int32 nVertexYP1( basegfx::fround(rP1.getY()) ); 54cdf0e10cSrcweir const sal_Int32 nVertexYP2( basegfx::fround(rP2.getY()) ); 55cdf0e10cSrcweir 56cdf0e10cSrcweir // insert only vertices which are not strictly 57cdf0e10cSrcweir // horizontal. Strictly horizontal vertices don't add 58cdf0e10cSrcweir // any information that is not already present - due 59cdf0e10cSrcweir // to their adjacent vertices. 60cdf0e10cSrcweir if(nVertexYP1 != nVertexYP2) 61cdf0e10cSrcweir { 62cdf0e10cSrcweir if( nVertexYP2 < nVertexYP1 ) 63cdf0e10cSrcweir { 64cdf0e10cSrcweir const sal_Int32 nStartScanline(nVertexYP2 - nMinY); 65cdf0e10cSrcweir 66cdf0e10cSrcweir // edge direction is upwards - add with swapped vertices 67cdf0e10cSrcweir if( nStartScanline < nNumScanlines ) 68cdf0e10cSrcweir rGET[ nStartScanline ].push_back( Vertex(rP2, rP1, false) ); 69cdf0e10cSrcweir } 70cdf0e10cSrcweir else 71cdf0e10cSrcweir { 72cdf0e10cSrcweir const sal_Int32 nStartScanline(nVertexYP1 - nMinY); 73cdf0e10cSrcweir 74cdf0e10cSrcweir if( nStartScanline < nNumScanlines ) 75cdf0e10cSrcweir rGET[ nStartScanline ].push_back( Vertex(rP1, rP2, true) ); 76cdf0e10cSrcweir } 77cdf0e10cSrcweir } 78cdf0e10cSrcweir } 79cdf0e10cSrcweir } 80cdf0e10cSrcweir 81cdf0e10cSrcweir // now sort all scanlines individually, with increasing x 82cdf0e10cSrcweir // coordinates 83cdf0e10cSrcweir VectorOfVectorOfVertices::iterator aIter( rGET.begin() ); 84cdf0e10cSrcweir const VectorOfVectorOfVertices::iterator aEnd( rGET.end() ); 85cdf0e10cSrcweir sal_uInt32 nVertexCount(0); 86cdf0e10cSrcweir RasterConvertVertexComparator aComp; 87cdf0e10cSrcweir while( aIter != aEnd ) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir std::sort( aIter->begin(), 90cdf0e10cSrcweir aIter->end(), 91cdf0e10cSrcweir aComp ); 92cdf0e10cSrcweir nVertexCount += aIter->size(); 93cdf0e10cSrcweir 94cdf0e10cSrcweir ++aIter; 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir return nVertexCount; 98cdf0e10cSrcweir } 99cdf0e10cSrcweir sortAET(VectorOfVertexPtr & rAETSrc,VectorOfVertexPtr & rAETDest)100cdf0e10cSrcweir void sortAET( VectorOfVertexPtr& rAETSrc, 101cdf0e10cSrcweir VectorOfVertexPtr& rAETDest ) 102cdf0e10cSrcweir { 103cdf0e10cSrcweir static RasterConvertVertexComparator aComp; 104cdf0e10cSrcweir 105cdf0e10cSrcweir rAETDest.clear(); 106cdf0e10cSrcweir 107cdf0e10cSrcweir // prune AET from ended edges 108cdf0e10cSrcweir VectorOfVertexPtr::iterator iter( rAETSrc.begin() ); 109cdf0e10cSrcweir VectorOfVertexPtr::iterator const end( rAETSrc.end() ); 110cdf0e10cSrcweir while( iter != end ) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir if( (*iter)->mnYCounter > 0 ) 113cdf0e10cSrcweir rAETDest.push_back( *iter ); 114cdf0e10cSrcweir ++iter; 115cdf0e10cSrcweir } 116cdf0e10cSrcweir 117cdf0e10cSrcweir // stable sort is necessary, to avoid segment crossing where 118cdf0e10cSrcweir // none was intended. 119cdf0e10cSrcweir std::stable_sort( rAETDest.begin(), rAETDest.end(), aComp ); 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir } // namespace detail 123cdf0e10cSrcweir } // namespace basebmp 124