1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_basegfx.hxx" 30 31 #include <basegfx/range/b2drange.hxx> 32 #include <basegfx/range/b2irange.hxx> 33 #include <basegfx/range/b2ibox.hxx> 34 35 36 namespace basegfx 37 { 38 namespace 39 { 40 /** Generic implementation of the difference set computation 41 42 @tpl RangeType 43 Type to operate on. Must provide ValueType and TraitsType 44 nested types. 45 */ 46 template< class RangeType > void doComputeSetDifference( 47 ::std::vector< RangeType >& o_rRanges, 48 const RangeType& a, 49 const RangeType& b ) 50 { 51 o_rRanges.clear(); 52 53 // special-casing the empty rect case (this will fail most 54 // of the times below, because of the DBL_MIN/MAX special 55 // values denoting emptyness in the rectangle. 56 if( a.isEmpty() ) 57 { 58 o_rRanges.push_back( b ); 59 return; 60 } 61 if( b.isEmpty() ) 62 { 63 o_rRanges.push_back( a ); 64 return; 65 } 66 67 const typename RangeType::ValueType ax(a.getMinX()); 68 const typename RangeType::ValueType ay(a.getMinY()); 69 const typename RangeType::TraitsType::DifferenceType aw(a.getWidth()); 70 const typename RangeType::TraitsType::DifferenceType ah(a.getHeight()); 71 const typename RangeType::ValueType bx(b.getMinX()); 72 const typename RangeType::ValueType by(b.getMinY()); 73 const typename RangeType::TraitsType::DifferenceType bw(b.getWidth()); 74 const typename RangeType::TraitsType::DifferenceType bh(b.getHeight()); 75 76 const typename RangeType::TraitsType::DifferenceType h0( (by > ay) ? by - ay : 0 ); 77 const typename RangeType::TraitsType::DifferenceType h3( (by + bh < ay + ah) ? ay + ah - by - bh : 0 ); 78 const typename RangeType::TraitsType::DifferenceType w1( (bx > ax) ? bx - ax : 0 ); 79 const typename RangeType::TraitsType::DifferenceType w2( (ax + aw > bx + bw) ? ax + aw - bx - bw : 0 ); 80 const typename RangeType::TraitsType::DifferenceType h12( (h0 + h3 < ah) ? ah - h0 - h3 : 0 ); 81 82 // TODO(E2): Use numeric_cast instead of static_cast here, 83 // need range checks! 84 if (h0 > 0) 85 o_rRanges.push_back( 86 RangeType(ax,ay, 87 static_cast<typename RangeType::ValueType>(ax+aw), 88 static_cast<typename RangeType::ValueType>(ay+h0)) ); 89 90 if (w1 > 0 && h12 > 0) 91 o_rRanges.push_back( 92 RangeType(ax, 93 static_cast<typename RangeType::ValueType>(ay+h0), 94 static_cast<typename RangeType::ValueType>(ax+w1), 95 static_cast<typename RangeType::ValueType>(ay+h0+h12)) ); 96 97 if (w2 > 0 && h12 > 0) 98 o_rRanges.push_back( 99 RangeType(static_cast<typename RangeType::ValueType>(bx+bw), 100 static_cast<typename RangeType::ValueType>(ay+h0), 101 static_cast<typename RangeType::ValueType>(bx+bw+w2), 102 static_cast<typename RangeType::ValueType>(ay+h0+h12)) ); 103 104 if (h3 > 0) 105 o_rRanges.push_back( 106 RangeType(ax, 107 static_cast<typename RangeType::ValueType>(ay+h0+h12), 108 static_cast<typename RangeType::ValueType>(ax+aw), 109 static_cast<typename RangeType::ValueType>(ay+h0+h12+h3)) ); 110 } 111 } 112 113 ::std::vector< B2IRange >& computeSetDifference( ::std::vector< B2IRange >& o_rResult, 114 const B2IRange& rFirst, 115 const B2IRange& rSecond ) 116 { 117 doComputeSetDifference( o_rResult, rFirst, rSecond ); 118 119 return o_rResult; 120 } 121 122 ::std::vector< B2DRange >& computeSetDifference( ::std::vector< B2DRange >& o_rResult, 123 const B2DRange& rFirst, 124 const B2DRange& rSecond ) 125 { 126 doComputeSetDifference( o_rResult, rFirst, rSecond ); 127 128 return o_rResult; 129 } 130 131 ::std::vector< B2IBox >& computeSetDifference( ::std::vector< B2IBox >& o_rResult, 132 const B2IBox& rFirst, 133 const B2IBox& rSecond ) 134 { 135 doComputeSetDifference( o_rResult, rFirst, rSecond ); 136 137 return o_rResult; 138 } 139 140 } // end of namespace basegfx 141 142 // eof 143