PLplot
5.10.0
|
00001 // PLplot MEM (in user-supplied memory) device driver. 00002 // The idea here is that the user will specify the Y by X by RGB 00003 // area in which to plot using the plsmem function (added by me). 00004 // 00005 // This is a bare-bones driver which allows one to plot on an existing 00006 // image in memory. This is useful if the user has an image in memory 00007 // that he wants to decorate with PLPLOT. 00008 // 00009 // Contributed by Doug Hunt 00010 // Included in PLplot by Rafael Laboissiere on Sat Feb 22 18:34:06 CET 2003 00011 // 00012 00013 #include "plDevs.h" 00014 00015 #ifdef PLD_mem 00016 00017 #include "plplotP.h" 00018 #include "drivers.h" 00019 00020 // Device info 00021 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_mem = "mem:User-supplied memory device:-1:mem:46:mem\n"; 00022 00023 void plD_dispatch_init_mem( PLDispatchTable *pdt ); 00024 00025 void plD_init_mem( PLStream * ); 00026 void plD_line_mem( PLStream *, short, short, short, short ); 00027 void plD_polyline_mem( PLStream *, short *, short *, PLINT ); 00028 void plD_eop_mem( PLStream * ); 00029 void plD_bop_mem( PLStream * ); 00030 void plD_tidy_mem( PLStream * ); 00031 void plD_state_mem( PLStream *, PLINT ); 00032 void plD_esc_mem( PLStream *, PLINT, void * ); 00033 00034 #undef MAX 00035 #undef ABS 00036 #define MAX( a, b ) ( ( a > b ) ? a : b ) 00037 #define ABS( a ) ( ( a < 0 ) ? -a : a ) 00038 00039 #define MAX_INTENSITY 255 00040 00041 void plD_dispatch_init_mem( PLDispatchTable *pdt ) 00042 { 00043 #ifndef ENABLE_DYNDRIVERS 00044 pdt->pl_MenuStr = "User-supplied memory device"; 00045 pdt->pl_DevName = "mem"; 00046 #endif 00047 pdt->pl_type = plDevType_Null; 00048 pdt->pl_seq = 45; 00049 pdt->pl_init = (plD_init_fp) plD_init_mem; 00050 pdt->pl_line = (plD_line_fp) plD_line_mem; 00051 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_mem; 00052 pdt->pl_eop = (plD_eop_fp) plD_eop_mem; 00053 pdt->pl_bop = (plD_bop_fp) plD_bop_mem; 00054 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_mem; 00055 pdt->pl_state = (plD_state_fp) plD_state_mem; 00056 pdt->pl_esc = (plD_esc_fp) plD_esc_mem; 00057 } 00058 00059 //-------------------------------------------------------------------------- 00060 // plD_init_mem() 00061 // 00062 // Initialize device (terminal). 00063 //-------------------------------------------------------------------------- 00064 00065 void 00066 plD_init_mem( PLStream *pls ) 00067 { 00068 // plsmem must have already been called to set pls->dev to the 00069 // user supplied plotting area. The dimensions of the plot area 00070 // have also been set by plsmem. Verify this. 00071 // 00072 00073 if ( ( pls->phyxma == 0 ) || ( pls->dev == NULL ) ) 00074 { 00075 plexit( "Must call plsmem first to set user plotting area!" ); 00076 } 00077 00078 if ( pls->dev_mem_alpha == 1 ) 00079 { 00080 plexit( "The mem driver does not support alpha values! Use plsmem!" ); 00081 } 00082 00083 plP_setpxl( (PLFLT) 4, (PLFLT) 4 ); // rough pixels/mm on *my* screen 00084 00085 00086 pls->color = 1; // Is a color device 00087 pls->dev_fill0 = 0; // Handle solid fills 00088 pls->dev_fill1 = 0; // Use PLplot core fallback for pattern fills 00089 pls->nopause = 1; // Don't pause between frames 00090 } 00091 00092 #define sign( a ) ( ( a < 0 ) ? -1 : ( ( a == 0 ) ? 0 : 1 ) ) 00093 00094 // Modified version of the ljii routine (see ljii.c) 00095 void 00096 plD_line_mem( PLStream *pls, short x1a, short y1a, short x2a, short y2a ) 00097 { 00098 int i; 00099 PLINT idx; 00100 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a; 00101 PLINT x1b, y1b, x2b, y2b; 00102 PLFLT length, fx, fy, dx, dy; 00103 unsigned char *mem = (unsigned char *) pls->dev; 00104 PLINT xm = pls->phyxma; 00105 PLINT ym = pls->phyyma; 00106 00107 // Take mirror image, since (0,0) must be at top left 00108 00109 y1 = ym - ( y1 - 0 ); 00110 y2 = ym - ( y2 - 0 ); 00111 00112 x1b = x1, x2b = x2, y1b = y1, y2b = y2; 00113 length = (PLFLT) sqrt( (double) 00114 ( ( x2b - x1b ) * ( x2b - x1b ) + ( y2b - y1b ) * ( y2b - y1b ) ) ); 00115 00116 if ( length == 0. ) 00117 length = 1.; 00118 dx = ( x2 - x1 ) / length; 00119 dy = ( y2 - y1 ) / length; 00120 00121 fx = x1; 00122 fy = y1; 00123 mem[3 * xm * y1 + 3 * x1 + 0] = pls->curcolor.r; 00124 mem[3 * xm * y1 + 3 * x1 + 1] = pls->curcolor.g; 00125 mem[3 * xm * y1 + 3 * x1 + 2] = pls->curcolor.b; 00126 00127 mem[3 * xm * y2 + 3 * x2 + 0] = pls->curcolor.r; 00128 mem[3 * xm * y2 + 3 * x2 + 1] = pls->curcolor.g; 00129 mem[3 * xm * y2 + 3 * x2 + 2] = pls->curcolor.b; 00130 00131 for ( i = 1; i <= (int) length; i++ ) 00132 { 00133 fx += dx; 00134 fy += dy; 00135 idx = 3 * xm * (PLINT) fy + 3 * (PLINT) fx; 00136 mem[idx + 0] = pls->curcolor.r; 00137 mem[idx + 1] = pls->curcolor.g; 00138 mem[idx + 2] = pls->curcolor.b; 00139 } 00140 } 00141 00142 void 00143 plD_polyline_mem( PLStream *pls, short *xa, short *ya, PLINT npts ) 00144 { 00145 int i; 00146 for ( i = 0; i < npts - 1; i++ ) 00147 plD_line_mem( pls, xa[i], ya[i], xa[i + 1], ya[i + 1] ); 00148 } 00149 00150 void 00151 plD_eop_mem( PLStream *pls ) 00152 { 00153 // Set the 'dev' member (which holds the user supplied memory image) 00154 // to NULL here so it won't be freed when PLplot is closed. 00155 // (the user is responsible for freeing it when ready). 00156 // 00157 pls->dev = NULL; 00158 } 00159 00160 void 00161 plD_bop_mem( PLStream * PL_UNUSED( pls ) ) 00162 { 00163 // Nothing to do here 00164 } 00165 00166 void 00167 plD_tidy_mem( PLStream * PL_UNUSED( pls ) ) 00168 { 00169 // Nothing to do here 00170 } 00171 00172 void 00173 plD_state_mem( PLStream * PL_UNUSED( pls ), PLINT PL_UNUSED( op ) ) 00174 { 00175 // Nothing to do here 00176 } 00177 00178 void 00179 plD_esc_mem( PLStream *PL_UNUSED( pls ), PLINT PL_UNUSED( op ), void * PL_UNUSED( ptr ) ) 00180 { 00181 // Nothing to do here 00182 } 00183 00184 #endif // PLD_mem