1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_basegfx.hxx" 26 27 #include <basegfx/range/b2drange.hxx> 28 #include <basegfx/range/b2irange.hxx> 29 #include <basegfx/range/b2ibox.hxx> 30 31 32 namespace basegfx 33 { 34 namespace 35 { 36 /** Generic implementation of the difference set computation 37 38 @tpl RangeType 39 Type to operate on. Must provide ValueType and TraitsType 40 nested types. 41 */ doComputeSetDifference(::std::vector<RangeType> & o_rRanges,const RangeType & a,const RangeType & b)42 template< class RangeType > void doComputeSetDifference( 43 ::std::vector< RangeType >& o_rRanges, 44 const RangeType& a, 45 const RangeType& b ) 46 { 47 o_rRanges.clear(); 48 49 // special-casing the empty rect case (this will fail most 50 // of the times below, because of the DBL_MIN/MAX special 51 // values denoting emptyness in the rectangle. 52 if( a.isEmpty() ) 53 { 54 o_rRanges.push_back( b ); 55 return; 56 } 57 if( b.isEmpty() ) 58 { 59 o_rRanges.push_back( a ); 60 return; 61 } 62 63 const typename RangeType::ValueType ax(a.getMinX()); 64 const typename RangeType::ValueType ay(a.getMinY()); 65 const typename RangeType::TraitsType::DifferenceType aw(a.getWidth()); 66 const typename RangeType::TraitsType::DifferenceType ah(a.getHeight()); 67 const typename RangeType::ValueType bx(b.getMinX()); 68 const typename RangeType::ValueType by(b.getMinY()); 69 const typename RangeType::TraitsType::DifferenceType bw(b.getWidth()); 70 const typename RangeType::TraitsType::DifferenceType bh(b.getHeight()); 71 72 const typename RangeType::TraitsType::DifferenceType h0( (by > ay) ? by - ay : 0 ); 73 const typename RangeType::TraitsType::DifferenceType h3( (by + bh < ay + ah) ? ay + ah - by - bh : 0 ); 74 const typename RangeType::TraitsType::DifferenceType w1( (bx > ax) ? bx - ax : 0 ); 75 const typename RangeType::TraitsType::DifferenceType w2( (ax + aw > bx + bw) ? ax + aw - bx - bw : 0 ); 76 const typename RangeType::TraitsType::DifferenceType h12( (h0 + h3 < ah) ? ah - h0 - h3 : 0 ); 77 78 // TODO(E2): Use numeric_cast instead of static_cast here, 79 // need range checks! 80 if (h0 > 0) 81 o_rRanges.push_back( 82 RangeType(ax,ay, 83 static_cast<typename RangeType::ValueType>(ax+aw), 84 static_cast<typename RangeType::ValueType>(ay+h0)) ); 85 86 if (w1 > 0 && h12 > 0) 87 o_rRanges.push_back( 88 RangeType(ax, 89 static_cast<typename RangeType::ValueType>(ay+h0), 90 static_cast<typename RangeType::ValueType>(ax+w1), 91 static_cast<typename RangeType::ValueType>(ay+h0+h12)) ); 92 93 if (w2 > 0 && h12 > 0) 94 o_rRanges.push_back( 95 RangeType(static_cast<typename RangeType::ValueType>(bx+bw), 96 static_cast<typename RangeType::ValueType>(ay+h0), 97 static_cast<typename RangeType::ValueType>(bx+bw+w2), 98 static_cast<typename RangeType::ValueType>(ay+h0+h12)) ); 99 100 if (h3 > 0) 101 o_rRanges.push_back( 102 RangeType(ax, 103 static_cast<typename RangeType::ValueType>(ay+h0+h12), 104 static_cast<typename RangeType::ValueType>(ax+aw), 105 static_cast<typename RangeType::ValueType>(ay+h0+h12+h3)) ); 106 } 107 } 108 computeSetDifference(::std::vector<B2IRange> & o_rResult,const B2IRange & rFirst,const B2IRange & rSecond)109 ::std::vector< B2IRange >& computeSetDifference( ::std::vector< B2IRange >& o_rResult, 110 const B2IRange& rFirst, 111 const B2IRange& rSecond ) 112 { 113 doComputeSetDifference( o_rResult, rFirst, rSecond ); 114 115 return o_rResult; 116 } 117 computeSetDifference(::std::vector<B2DRange> & o_rResult,const B2DRange & rFirst,const B2DRange & rSecond)118 ::std::vector< B2DRange >& computeSetDifference( ::std::vector< B2DRange >& o_rResult, 119 const B2DRange& rFirst, 120 const B2DRange& rSecond ) 121 { 122 doComputeSetDifference( o_rResult, rFirst, rSecond ); 123 124 return o_rResult; 125 } 126 computeSetDifference(::std::vector<B2IBox> & o_rResult,const B2IBox & rFirst,const B2IBox & rSecond)127 ::std::vector< B2IBox >& computeSetDifference( ::std::vector< B2IBox >& o_rResult, 128 const B2IBox& rFirst, 129 const B2IBox& rSecond ) 130 { 131 doComputeSetDifference( o_rResult, rFirst, rSecond ); 132 133 return o_rResult; 134 } 135 136 } // end of namespace basegfx 137 138 // eof 139