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