VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gximage.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
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 // ===
17 //
18 // gximage.cpp
19 //
20 
21 #include "gdef.h"
22 #include "gxdef.h"
23 #include "gximage.h"
24 #include "gxwindow.h"
25 #include "gxdisplay.h"
26 #include "gxvisual.h"
27 #include "gxerror.h"
28 #include "grlinedraw.h"
29 #include "gassert.h"
30 #include <cstdlib> // malloc
31 #include <cstring> // memset
32 #include <new> // std::bad_alloc
33 
34 GX::Image::Image( Display & display , const GX::Window & window , int dx_in , int dy_in ) :
35  m_display(display) ,
36  m_image(nullptr)
37 {
38  m_dx = dx_in ? dx_in : window.dx() ;
39  m_dy = dy_in ? dy_in : window.dy() ;
40  G_ASSERT( m_dx > 0 && m_dy > 0 ) ;
41 
42  char * p = nullptr ;
43  Visual visual( m_display ) ;
44  m_image = XCreateImage( display.x() , visual.x() , static_cast<unsigned int>(visual.depth()) ,
45  ZPixmap , 0 , p , static_cast<unsigned int>(m_dx) , static_cast<unsigned int>(m_dy) , 8 , 0 ) ;
46  if( m_image == nullptr )
47  throw Error( "XCreateImage failed" ) ;
48 
49  int size = m_dy * m_image->bytes_per_line ;
50  G_ASSERT( size >= 0 ) ;
51  p = static_cast<char*>(std::malloc(static_cast<size_t>(size))) ;
52  if( p == nullptr )
53  throw std::bad_alloc() ; // malloc() failed
54  m_image->data = p ;
55 }
56 
57 GX::Image::Image( Display & display , XImage * p , int dx , int dy ) :
58  m_display(display) ,
59  m_image(p) ,
60  m_dx(dx) ,
61  m_dy(dy)
62 {
63 }
64 
66 {
67  try
68  {
69  if( m_image )
70  XDestroyImage( m_image ) ;
71  }
72  catch(...)
73  {
74  }
75 }
76 
77 void GX::Image::blit( GX::Window & window , int src_x , int src_y , int dx , int dy , int dst_x , int dst_y )
78 {
79  Context gc = m_display.defaultContext() ;
80  blit( window , gc , src_x , src_y , dx , dy , dst_x , dst_y ) ;
81 }
82 
83 void GX::Image::blit( GX::Window & window , Context & gc ,
84  int src_x , int src_y , int dx , int dy , int dst_x , int dst_y )
85 {
86  XPutImage( m_display.x() , window.x() , gc.x() , m_image , src_x , src_y , dst_x , dst_y ,
87  static_cast<unsigned int>(dx) , static_cast<unsigned int>(dy) ) ;
88 }
89 
90 void GX::Image::clear( bool white )
91 {
92  std::memset( m_image->data , white?255:0 , m_image->bytes_per_line * m_image->height ) ;
93 }
94 
95 unsigned long GX::Image::readPoint( int x , int y ) const
96 {
97  return XGetPixel( m_image , x , y ) ;
98 }
99 
100 void GX::Image::drawLine( int x1 , int y1 , int x2 , int y2 , unsigned long p , bool or_ )
101 {
102  Gr::LineDraw<int> line_draw( x1 , y1 , x2 , y2 ) ;
103  while( line_draw.more() )
104  {
105  for( int x = line_draw.x1() ; x <= line_draw.x2() ; x++ )
106  drawPoint( x , line_draw.y() , p , or_ ) ;
107  }
108 }
109 
110 void GX::Image::drawLineAcross( int x1 , int x2 , int y , unsigned long p )
111 {
112  if( y >= 0 && y < m_dy )
113  {
114  x1 = x1 < 0 ? 0 : ( x1 >= m_dx ? (m_dx-1) : x1 ) ;
115  x2 = x2 < 0 ? 0 : ( x2 >= m_dx ? (m_dx-1) : x2 ) ;
116  for( int x = x1 ; x <= x2 ; x++ )
117  XPutPixel( m_image , x , y , p ) ;
118  }
119 }
120 
121 void GX::Image::drawLineDown( int x , int y1 , int y2 , unsigned long p )
122 {
123  if( x >= 0 && x < m_dx )
124  {
125  y1 = y1 < 0 ? 0 : ( y1 >= m_dy ? (m_dy-1) : y1 ) ;
126  y2 = y2 < 0 ? 0 : ( y2 >= m_dy ? (m_dy-1) : y2 ) ;
127  for( int y = y1 ; y <= y2 ; y++ )
128  XPutPixel( m_image , x , y , p ) ;
129  }
130 }
131 
132 /// \file gximage.cpp
A window class that is-a GX::Drawable and a GX::EventHandler.
Definition: gxwindow.h:47
::Display * x()
Returns the X object.
Definition: gxdisplay.cpp:53
void drawLine(int x1, int y1, int x2, int y2, unsigned long p, bool or_=false)
Draws a line. The pixel value typically comes from GX::ColourMap::get().
Definition: gximage.cpp:100
int dx() const
Returns the current width.
Definition: gxwindow.cpp:186
An Xlib Display wrapper.
Definition: gxdisplay.h:38
T y() const
Returns the current y coordinate.
Definition: grlinedraw.h:293
An exception class for GX classes.
Definition: gxerror.h:37
A class template for drawing lines in terms of separate horizontal line segments. ...
Definition: grlinedraw.h:30
::GC x()
Returns the X object.
Definition: gxcontext.cpp:63
::Window x()
Returns the X object.
Definition: gxwindow.cpp:149
int depth() const
Returns the depth.
Definition: gxvisual.cpp:103
int dy() const
Returns the current hieght.
Definition: gxwindow.cpp:191
void drawLineDown(int x, int y1, int y2, unsigned long p)
Draws a vertical line.
Definition: gximage.cpp:121
T x1() const
Returns the current smaller x coordinate.
Definition: grlinedraw.h:281
void drawLineAcross(int x1, int x2, int y, unsigned long p)
Draws a horizontal line.
Definition: gximage.cpp:110
An Xlib GC wrapper.
Definition: gxcontext.h:37
~Image()
Destructor.
Definition: gximage.cpp:65
Image(Display &, const GX::Window &window, int dx=0, int dy=0)
Constructor. The display reference is kept.
Definition: gximage.cpp:34
void clear(bool white=false)
Clears the image.
Definition: gximage.cpp:90
void blit(GX::Window &, int src_x, int src_y, int dx, int dy, int dst_x, int dst_y)
Blits to a window.
Definition: gximage.cpp:77
An Xlib XVisual wrapper.
Definition: gxvisual.h:38
unsigned long readPoint(int x, int y) const
Reads a pixel value at a point.
Definition: gximage.cpp:95
T x2() const
Returns the current larger x coordinate.
Definition: grlinedraw.h:287
bool more()
Iterator for the next line segment. Returns true at least once.
Definition: grlinedraw.h:232
::Visual * x()
Returns the X object.
Definition: gxvisual.cpp:61