/** * \brief Get the part of the sprite that is fully opaque. * \param r A fully opaque part of the sprite. */ void bear::visual::sprite::set_opaque_rectangle( const rectangle_type& r ) { CLAW_PRECOND( r.width() >= 0 ); CLAW_PRECOND( r.height() >= 0 ); m_opaque_rectangle = r; } // sprite::set_opaque_rectangle()
/** * \brief Render the opaque box of an element. * \param e The element whose opaque box is rendered. */ void bear::visual::screen::render_opaque_box( const scene_element& e ) const { const rectangle_type box = e.get_opaque_box(); std::vector<position_type> border(4); border[0] = box.top_left(); border[1] = box.top_right(); border[2] = box.bottom_right(); border[3] = box.bottom_left(); m_impl->draw_polygon( color("#80C0C0C0"), border ); m_impl->draw_line( color("#F0F0F0"), border, 2, true ); } // screen::render_opaque_box()
/** * \brief Tell if a rectangle intersects a rectangle from a list. * \param r The rectangle to check. * \param boxes The boxes to compare to. */ bool bear::visual::screen::intersects_any ( const rectangle_type& r, const rectangle_list& boxes ) const { bool result=false; rectangle_list::const_iterator it; for (it=boxes.begin(); !result && (it!=boxes.end()); ++it) if ( r.intersects(*it) ) { const rectangle_type inter = r.intersection(*it); result = (inter.width() > 0) && (inter.height() > 0); } return result; } // screen::intersects_any()
/** * \brief Split a scene element to only keep its visible parts and update the * screen cover. * \param e The element that will be rendered. * \param output The parts of \a e to render. * \param boxes The cover of the screen. */ void bear::visual::screen::split ( const scene_element& e, scene_element_list& output, rectangle_list& boxes ) const { e.burst(boxes, output); const rectangle_type r( e.get_opaque_box() ); const double opaque_box_min_size(0); if ( (r.width() > opaque_box_min_size) && (r.height() > opaque_box_min_size) ) { rectangle_list input_boxes; rectangle_list::const_iterator it; std::swap( input_boxes, boxes ); for ( it=input_boxes.begin(); it!=input_boxes.end(); ++it ) subtract( *it, r, boxes ); } } // screen::split()
/** * \brief Subtract a rectangle \a b from a rectangle \a a. * \param a The target. * \param b The rectangle to remove in \a a. * \param boxes The subparts of \a a after the subtraction. */ void bear::visual::screen::subtract ( const rectangle_type& a, const rectangle_type& b, rectangle_list& result ) const { if ( !a.intersects(b) ) result.push_front(a); else { const rectangle_type inter = a.intersection(b); if ( (inter.width() <= 8) || (inter.height() <= 8) ) result.push_front(a); else { if ( a.left() != inter.left() ) result.push_front ( rectangle_type( a.left(), a.bottom(), inter.left(), a.top() ) ); if ( a.top() != inter.top() ) result.push_front ( rectangle_type ( inter.left(), inter.top(), inter.right(), a.top() ) ); if ( a.right() != inter.right() ) result.push_front ( rectangle_type ( inter.right(), a.bottom(), a.right(), a.top() ) ); if ( a.bottom() != inter.bottom() ) result.push_front ( rectangle_type ( inter.left(), a.bottom(), inter.right(), inter.bottom() ) ); } } } // screen::subtract()
/** * \brief Align a rectangle on the left of an other. * \param this_box The box to which we will align the other. * \param that_old_pos The position from where comes the other box. * \param that_new_box (in/out) The box we will align. */ void bear::universe::align_left::align ( const rectangle_type& this_box, const position_type& that_old_pos, rectangle_type& that_new_box ) const { that_new_box.right(this_box.left()); } // align_left::align()
/** * \brief Align one box at the bottom of an other one. * \param this_box The box to which we will align the other. * \param that_old_pos The position from where comes the other box. * \param that_new_box (in/out) The box we will align. */ void bear::universe::align_bottom::align ( const rectangle_type& this_box, const position_type& that_old_pos, rectangle_type& that_new_box ) const { that_new_box.top( this_box.bottom() ); } // align_bottom::align()