⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccc_x11.cpp

📁 BigC++的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*

COPYRIGHT (C) 1994 - 2002 Cay S. Horstmann. All Rights Reserved.

NOTE TO STUDENTS: Do not attempt to study the contents of this file. You
can, and should, use the services provided in this file without knowing
the highly technical details of the implementation.

*/

#include <cmath>
#include <cstdlib>
#include <iostream>

#include "ccc_x11.h"

/* CONSTANTS ****************************************************************/

const double DEFAULT_XMIN = -10;
const double DEFAULT_YMIN = 10;
const double DEFAULT_XMAX = 10;
const double DEFAULT_YMAX = -10;

static int DEF_WIDTH = 480;
static int DEF_HEIGHT = 480;

// The following is an alias for an X fonts.
// Make sure this is available on your system.  Substitute as necessary.
#define SYS_FONT_NAME  "-adobe-courier-bold-r-normal-*-14-*-*-*-*-*-*"

/* Our program wrapper. */
extern int ccc_win_main();

GraphicWindow cwin;

/**************************************************************************/

GraphicWindow::GraphicWindow()
:  _user_xmin(DEFAULT_XMIN), _user_ymin(DEFAULT_YMIN), 
   _user_xmax(DEFAULT_XMAX), _user_ymax(DEFAULT_YMAX),
   _disp_xmax(DEF_WIDTH), _disp_ymax(DEF_HEIGHT)
{
}

void GraphicWindow::open(Display* d, Window w)
{  
   display = d;
   win = w;
   screen_num = DefaultScreen(display);

   XGCValues xgc_values;  // ignored
   xgc = XCreateGC(display, win, 0, &xgc_values);

   //   specify black foreground since default window background is
   //   white and default foreground is undefined.
   XSetForeground(display, xgc, BlackPixel(display, screen_num));

   // set line attributes.  This class only uses rounded styles.
   XSetLineAttributes(display, xgc, 2 /* pen thickness */, LineSolid,
         CapRound, JoinRound);

   // set up the font - uses only 14pt bold Courier
   _fontinfo_ptr = XLoadQueryFont(display, SYS_FONT_NAME);
   if (_fontinfo_ptr == NULL)
   {   cerr << "Unable to initialize font: " << SYS_FONT_NAME << endl;
      exit(1);
    }
   XSetFont(display, xgc, _fontinfo_ptr->fid);

   // sets the rop mode, using Copy for the user prompts
   XSetFunction(display, xgc, GXcopy /*0x3 COPY*/);

   _ppm = XCreatePixmap(display, win, DEF_WIDTH, DEF_HEIGHT, 
      DefaultDepth(display, screen_num));

   clear();
}

void GraphicWindow::close()
{
   XFreePixmap(display, _ppm);
   XFreeFont(display, _fontinfo_ptr);
}

void GraphicWindow::repaint()
{  
   XCopyArea(display, _ppm, win, xgc, 0, 0, DEF_WIDTH, DEF_HEIGHT, 0, 0);
}

void GraphicWindow::clear()
{
   XClearWindow(display, win);

   XGCValues vals;
   XGetGCValues(display, xgc, GCForeground, &vals);
   unsigned long color = WhitePixel(display, screen_num);
   unsigned long fg = vals.foreground;
   XSetForeground(display, xgc, color);
   XFillRectangle(display, _ppm, xgc, 0, 0, DEF_WIDTH + 1, DEF_HEIGHT + 1);
   XSetForeground(display, xgc, fg);
}

void GraphicWindow::coord(double xmin, double ymin,
   double xmax, double ymax)
{  
   _user_xmin = xmin;
   _user_xmax = xmax;
   _user_ymin = ymin;
   _user_ymax = ymax;
}

int GraphicWindow::user_to_disp_x(double x) const
{  
   return (int) ((x - _user_xmin) * _disp_xmax / (_user_xmax - _user_xmin));
}

int GraphicWindow::user_to_disp_y(double y) const
{  
   return (int) ((y - _user_ymin) * _disp_ymax / (_user_ymax - _user_ymin)); 
}

int GraphicWindow::user_to_disp_dx(double x) const
{  
   return (int) (x * _disp_xmax / (_user_xmax - _user_xmin));
}

int GraphicWindow::user_to_disp_dy(double y) const
{  
   return (int) (y * _disp_ymax / (_user_ymax - _user_ymin));
}

double GraphicWindow::disp_to_user_x(int x) const
{  
   return (double)x * (_user_xmax - _user_xmin) / _disp_xmax + _user_xmin;
}

double GraphicWindow::disp_to_user_y(int y) const
{  
   return (double)y * (_user_ymax - _user_ymin) / _disp_ymax + _user_ymin;
}

void GraphicWindow::point(double x, double y)
{  
   const int POINT_RADIUS = 3;
   int disp_x = user_to_disp_x(x);
   int disp_y = user_to_disp_y(y);

   XSetForeground(display, xgc, BlackPixel(display, screen_num));
   XDrawArc(display, win, xgc, disp_x - POINT_RADIUS, disp_y - POINT_RADIUS,
      2 * POINT_RADIUS, 2 * POINT_RADIUS, 0 , 360 * 64);
   XDrawArc(display, _ppm, xgc, disp_x - POINT_RADIUS,
      disp_y - POINT_RADIUS, 2 * POINT_RADIUS, 2 * POINT_RADIUS, 0 , 360 * 64);
}

void GraphicWindow::ellipse(double x, double y, double ra, double rb)
{  
   int disp_x = user_to_disp_x(x);
   int disp_y = user_to_disp_y(y);
   int disp_rx = abs(user_to_disp_dx(ra));
   int disp_ry = abs(user_to_disp_dy(rb));

   XSetForeground(display, xgc, BlackPixel(display, screen_num));
   XDrawArc(display, win, 
      xgc,               // the drawable
      disp_x - disp_rx,  // the x coord of upperleft corner of bounding rect
      disp_y - disp_ry,  // the y coord of upperleft corner of bounding rect
      disp_rx * 2,       // the major axis length
      disp_ry * 2,       // the minor axis length
      0,                 // offset from 3 o'clock  
      360 * 64);         // complete circle (360 degrees * 64 clicks per degree)
   XDrawArc(display, _ppm, xgc, disp_x - disp_rx, 
   disp_y - disp_ry, disp_rx * 2, disp_ry * 2, 0, 360 * 64);
}

void GraphicWindow::line(double xfrom, double yfrom, double xto,
   double yto) 
{  
   XSetForeground(display, xgc, BlackPixel(display, screen_num));
   XDrawLine(display, win, xgc, user_to_disp_x(xfrom), user_to_disp_y(yfrom),
      user_to_disp_x(xto), user_to_disp_y(yto));
   XDrawLine(display, _ppm, xgc, user_to_disp_x(xfrom),
      user_to_disp_y(yfrom), user_to_disp_x(xto), user_to_disp_y(yto));
}

void GraphicWindow::text(const char t[], double x, double y)
{  
   int direction, ascent, descent;
   XCharStruct overall;
   XTextExtents(_fontinfo_ptr, t, strlen(t), &direction, &ascent, &descent, &overall);

   int disp_x = user_to_disp_x(x);
   int disp_y = user_to_disp_y(y) + ascent;

   XSetForeground(display, xgc, BlackPixel(display, screen_num));
   XDrawString(display, win, xgc, disp_x, disp_y, t, strlen(t));
   XDrawString(display, _ppm, xgc, disp_x, disp_y, 
      t, strlen(t));
}

GraphicWindow& GraphicWindow::operator<<(Point p)
{  
   point(p.get_x(), p.get_y());
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Circle c)
{  
   ellipse (c.get_center().get_x(), 
      c.get_center().get_y(),
      c.get_radius(),
      c.get_radius());
   return *this;
}

GraphicWindow& GraphicWindow::operator<<(Message m)
{  
   _display_string = m.get_text();
   text(_display_string.c_str(), m.get_start().get_x(), m.get_start().get_y());

   return *this;
}

GraphicWindow& GraphicWindow::operator<< (Line l)
{  
   line(l.get_start().get_x(), l.get_start().get_y(), 
       l.get_end().get_x(), l.get_end().get_y());
   return *this;
}


void GraphicWindow::statusline_prompt(string s)
{  
   int direction, ascent, descent;
   XCharStruct overall;
   const char* t = s.c_str();
   XTextExtents(_fontinfo_ptr, t, strlen(t), 
      &direction, &ascent, &descent, &overall);
  
   XSetBackground(display, xgc, WhitePixel(display, screen_num));

   XClearArea(display, win, 
                0,
                0, /*clear from top*/
                0 /*clear to right edge of screen*/, 
                ascent + descent, 
                0 /* generate exposure events */);

   XDrawImageString(display, win, xgc, 0, ascent, t, strlen(t));
   XDrawImageString(display, _ppm, xgc, 0, ascent, t, strlen(t)); 
}

Point GraphicWindow::get_mouse(string outstr)
{  
   XEvent report;
   Point p;
   int x, y;

   cwin.statusline_prompt(outstr);   

   // Event Loop
   while (true)
   {
      XNextEvent(display, &report);
      switch(report.type)
      {
         case Expose:
             cwin.repaint();
             break;

         case ButtonPress:
            if (report.xbutton.button == Button1)
            {
               x = report.xbutton.x;
               y = report.xbutton.y;
               p = Point(cwin.disp_to_user_x(x), cwin.disp_to_user_y(y));
               cwin.statusline_prompt(outstr);
               return p;               
            }
       }
   }

   return p; // to keep compiler happy, will never get here!
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -