//----------------------------------------------------------------------------- // Copyright © 2006 - Philip Howard - All rights reserved // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //----------------------------------------------------------------------------- // package libh/arith // homepage http://libh.slashusr.org/ //----------------------------------------------------------------------------- // author Philip Howard // email libh at ipal dot org // homepage http://phil.ipal.org/ //----------------------------------------------------------------------------- // This file is best viewed using a fixed spaced font such as Courier // and in a display at least 120 columns wide. //----------------------------------------------------------------------------- #include "arith_lib.h" __PROTO_BEGIN__ //----------------------------------------------------------------------------- // function zoom_scan_d // // purpose Scan a string of zooming command characters and produce a set // of values to multiply and add to transform 2D coordinates to // given a zoomed and positioned view. // // arguments 1 (const char *) zooming/positioning command string // 2 (double *) where to store X multiplier // 3 (double *) where to store Y multiplier // 4 (double *) where to store X adder // 5 (double *) where to store Y adder // // returns (int) == -1 : general failure // (int) >= 0 : number of successful commands // // note If an unrecognized command is found, command interpretation // stops and the returned number represents an index into the // command sequence string to the unrecognized character. The // stored results only apply to the last successful command. // // commands 0 o O - zoom out (unzoom) by 2x // 1 - zoom in by 2x to the upper left quadrant // 2 - zoom in by 2x to the upper center quadrant // 3 - zoom in by 2x to the upper fright quadrant // 4 - zoom in by 2x to the middle left quadrant // 5 i I - zoom in by 2x to the middle center quadrant // 6 - zoom in by 2x to the middle right quadrant // 7 - zoom in by 2x to the lower left quadrant // 8 - zoom in by 2x to the lower center quadrant // 9 - zoom in by 2x to the lower right quadrant // x X - zoom only X axis by 2x // y Y - zoom only Y axis by 2x // l L - shift by 1/2 width leftward // u U - shift by 1/2 height upward // r R - shift by 1/2 width rightward // d D - shift by 1/2 height downward //----------------------------------------------------------------------------- int zoom_scan_d ( const char * arg_cmd_str , double * arg_mul_x_p , double * arg_mul_y_p , double * arg_add_x_p , double * arg_add_y_p ) __PROTO_END__ { double mul_x ; double mul_y ; double add_x ; double add_y ; const char * cmd_p ; int bad ; mul_x = 1.0; mul_y = 1.0; add_x = 0.0; add_y = 0.0; cmd_p = arg_cmd_str; bad = 0; for (;;) { //--------------------------- // Store current zoom values. //--------------------------- if ( arg_mul_x_p ) * arg_mul_x_p = mul_x; if ( arg_mul_y_p ) * arg_mul_y_p = mul_y; if ( arg_add_x_p ) * arg_add_x_p = add_x; if ( arg_add_y_p ) * arg_add_y_p = add_y; //----------------------------------------- // If no (more) characters remain, end now. //----------------------------------------- if ( ! * cmd_p ) break; //--------------------- // Select X multiplier. //--------------------- switch ( * cmd_p ) { case '0': case 'o': case 'O': mul_x += mul_x; break; case '1': case '4': case '7': case '2': case '5': case 'i': case 'I': case 'z': case 'Z': case '8': case '3': case '6': case '9': case 'x': case 'X': mul_x /= 2.0; break; case 'l': case 'L': case 'u': case 'U': case 'r': case 'R': case 'd': case 'D': case 'y': case 'Y': break; default: bad = 1; break; } //---------------- // Select X adder. //---------------- switch ( * cmd_p ) { case '1': case '4': case '7': add_x -= mul_x; break; case '3': case '6': case '9': add_x += mul_x; break; case 'l': case 'L': add_x -= mul_x / 2.0; break; case 'r': case 'R': add_x += mul_x / 2.0; break; case 'u': case 'U': case 'd': case 'D': break; case '0': case 'o': case 'O': case '2': case '5': case 'i': case 'I': case 'z': case 'Z': case '8': case 'x': case 'X': case 'y': case 'Y': break; default: bad = 1; break; } //--------------------- // Select Y multiplier. //--------------------- switch ( * cmd_p ) { case '0': case 'o': case 'O': mul_y += mul_y; break; case '1': case '4': case '7': case '2': case '5': case 'i': case 'I': case 'z': case 'Z': case '8': case '3': case '6': case '9': case 'y': case 'Y': mul_y /= 2.0; break; case 'l': case 'L': case 'u': case 'U': case 'r': case 'R': case 'd': case 'D': case 'x': case 'X': break; default: bad = 1; break; } //---------------- // Select Y adder. //---------------- switch ( * cmd_p ) { case '1': case '2': case '3': add_y -= mul_y; break; case '7': case '8': case '9': add_y += mul_y; break; case 'd': case 'D': add_y -= mul_y / 2.0; break; case 'u': case 'U': add_y += mul_y / 2.0; break; case '0': case 'o': case 'O': case '4': case '5': case 'i': case 'I': case 'z': case 'Z': case '6': case 'l': case 'L': case 'r': case 'R': case 'x': case 'X': case 'y': case 'Y': break; default: bad = 1; break; } //----------------------------------------- // If a bad character encountered, end now. //----------------------------------------- if ( bad ) break; //---------------- // Next character. //---------------- ++ cmd_p; } //----------------------------------------- // Return the number of characters scanned. //----------------------------------------- return ( cmd_p - arg_cmd_str ); }