graphic_context_state.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // Flexlay - A Generic 2D Game Editor
  2. // Copyright (C) 2002 Ingo Ruhnke <grumbel@gmx.de>
  3. //
  4. // This program is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. #include "graphic_context_state.hpp"
  17. #include <ClanLib/Display/display.h>
  18. #include <ClanLib/Display/display_window.h>
  19. #include <ClanLib/Display/graphic_context.h>
  20. class GraphicContextStateImpl
  21. {
  22. public:
  23. int width;
  24. int height;
  25. CL_Pointf offset;
  26. float zoom;
  27. float rotation;
  28. };
  29. GraphicContextState::GraphicContextState()
  30. : impl(new GraphicContextStateImpl())
  31. {
  32. impl->width = 1;
  33. impl->height = 1;
  34. impl->offset = CL_Pointf(0,0);
  35. impl->zoom = 1.0f;
  36. impl->rotation = 0;
  37. }
  38. GraphicContextState::GraphicContextState(int w, int h)
  39. : impl(new GraphicContextStateImpl())
  40. {
  41. impl->width = w;
  42. impl->height = h;
  43. impl->offset = CL_Pointf(0,0);
  44. impl->zoom = 1.0f;
  45. impl->rotation = 0;
  46. }
  47. void
  48. GraphicContextState::set_size(int w, int h)
  49. {
  50. impl->width = w;
  51. impl->height = h;
  52. }
  53. void
  54. GraphicContextState::push(CL_GraphicContext* gc) const
  55. {
  56. if (gc == 0)
  57. gc = CL_Display::get_current_window()->get_gc();
  58. gc->push_modelview();
  59. gc->add_translate(impl->width/2, impl->height/2);
  60. gc->add_rotate(impl->rotation, 0, 0, 1.0);
  61. gc->add_translate(-impl->width/2, -impl->height/2);
  62. gc->add_scale(get_zoom(), get_zoom());
  63. gc->add_translate(impl->offset.x, impl->offset.y);
  64. }
  65. void
  66. GraphicContextState::pop(CL_GraphicContext* gc) const
  67. {
  68. if (gc == 0)
  69. gc = CL_Display::get_current_window()->get_gc();
  70. gc->pop_modelview();
  71. }
  72. CL_Rectf
  73. GraphicContextState::get_clip_rect() const
  74. {
  75. return CL_Rectf(CL_Pointf(-impl->offset.x,
  76. -impl->offset.y),
  77. CL_Sizef(get_width() / impl->zoom,
  78. get_height() / impl->zoom));
  79. }
  80. void
  81. GraphicContextState::set_pos(const CL_Pointf& pos)
  82. {
  83. impl->offset.x = -pos.x + (get_width()/2 / impl->zoom);
  84. impl->offset.y = -pos.y + (get_height()/2 / impl->zoom);
  85. }
  86. CL_Pointf
  87. GraphicContextState::get_pos() const
  88. {
  89. return CL_Pointf(-impl->offset.x + (get_width()/2 / impl->zoom),
  90. -impl->offset.y + (get_height()/2 / impl->zoom));
  91. }
  92. void
  93. GraphicContextState::set_zoom(CL_Pointf pos, float z)
  94. {
  95. float old_zoom = impl->zoom;
  96. set_zoom(z);
  97. impl->offset.x = pos.x/impl->zoom - pos.x/old_zoom + impl->offset.x;
  98. impl->offset.y = pos.y/impl->zoom - pos.y/old_zoom + impl->offset.y;
  99. }
  100. void
  101. GraphicContextState::set_zoom(float z)
  102. {
  103. impl->zoom = z;
  104. }
  105. float
  106. GraphicContextState::get_zoom() const
  107. {
  108. return impl->zoom;
  109. }
  110. void
  111. GraphicContextState::zoom_to (const CL_Rectf& rect)
  112. {
  113. float center_x = (rect.left + rect.right) / 2.0f;
  114. float center_y = (rect.top + rect.bottom) / 2.0f;
  115. float width = rect.right - rect.left;
  116. float height = rect.bottom - rect.top;
  117. float screen_relation = float(get_height())/float(get_width ());
  118. float rect_relation = height/width;
  119. //std::cout << "Screen: " << screen_relation << " Zoom: " << rect_relation << std::endl;
  120. if (rect_relation < screen_relation) // take width, ignore height
  121. {
  122. impl->zoom = get_width()/width;
  123. }
  124. else // take height, ignore width
  125. {
  126. impl->zoom = get_height()/height;
  127. }
  128. impl->offset.x = (get_width() / (2*impl->zoom)) - center_x;
  129. impl->offset.y = (get_height() / (2*impl->zoom)) - center_y;
  130. }
  131. CL_Pointf
  132. GraphicContextState::screen2world(const CL_Point& pos_)
  133. {
  134. CL_Pointf pos = pos_;
  135. float sa = sin(-impl->rotation/180.0f*M_PI);
  136. float ca = cos(-impl->rotation/180.0f*M_PI);
  137. float dx = pos.x - impl->width/2;
  138. float dy = pos.y - impl->height/2;
  139. pos.x = impl->width/2 + (ca * dx - sa * dy);
  140. pos.y = impl->height/2 + (sa * dx + ca * dy);
  141. CL_Pointf p((float(pos.x) / impl->zoom) - impl->offset.x,
  142. (float(pos.y) / impl->zoom) - impl->offset.y);
  143. return p;
  144. }
  145. void
  146. GraphicContextState::set_rotation(float angle)
  147. {
  148. impl->rotation = angle;
  149. }
  150. float
  151. GraphicContextState::get_rotation() const
  152. {
  153. return impl->rotation;
  154. }
  155. int
  156. GraphicContextState::get_width() const
  157. {
  158. return impl->width;
  159. }
  160. int
  161. GraphicContextState::get_height() const
  162. {
  163. return impl->height;
  164. }
  165. /* EOF */