| 66 | } |
| 67 | |
| 68 | void |
| 69 | Viewport::set_box (const db::DBox &in_box) |
| 70 | { |
| 71 | m_target_box = in_box; |
| 72 | |
| 73 | db::DBox box = m_global_trans * in_box; |
| 74 | |
| 75 | // use double arithmetics to avoid overflows |
| 76 | double w = box.right () - box.left (); |
| 77 | double h = box.top () - box.bottom (); |
| 78 | double fx = w / double (std::max (width (), (unsigned int) 1)); |
| 79 | double fy = h / double (std::max (height (), (unsigned int) 1)); |
| 80 | double f = std::max (fx, fy); |
| 81 | |
| 82 | // as a safety measure we treat the zero factor case somewhat more graceful |
| 83 | if (f < 1e-13) { |
| 84 | f = 0.001; // default mag. factor |
| 85 | } |
| 86 | |
| 87 | double mx = double (box.right ()) + double (box.left ()); |
| 88 | double my = double (box.top ()) + double (box.bottom ()); |
| 89 | |
| 90 | // use only integer shift vectors. That enables a partial update of the image. |
| 91 | double dx = floor (0.5 + (mx / f - double (width ())) * 0.5); |
| 92 | double dy = floor (0.5 + (my / f - double (height ())) * 0.5); |
| 93 | |
| 94 | // preserve the angle and mirror properties of the transformation |
| 95 | m_trans = db::DCplxTrans (1.0 / f /*mag*/, 0.0 /*angle*/, false, db::DVector (-dx, -dy)) * m_global_trans; |
| 96 | } |
| 97 | |
| 98 | db::DBox |
| 99 | Viewport::box () const |