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

📄 xgeneral.c

📁 占星术4.0源码
💻 C
📖 第 1 页 / 共 3 页
字号:
  MetaWord(MAKEWORD(0 /* Strikeout */, C)); \
  MetaWord(MAKEWORD(4 /* TrueType */, 0 /* Clip */))
#define MetaBkMode(M) MetaRecord(4, 0x102); MetaWord(M)
#define MetaTextAlign(A) MetaRecord(4, 0x12E); MetaWord(A)
#define MetaTextColor(C) MetaRecord(5, 0x209); MetaLong(C);
#define MetaTextOut(X, Y, S) MetaRecord(7+((S)+1)/2, 0xA32); \
  MetaWord(Y); MetaWord(X); MetaWord(S); MetaWord(0 /* ETO */)
#define MetaRectangle(X1, Y1, X2, Y2) MetaRecord(7, 0x41B); \
  MetaWord(Y2); MetaWord(X2); MetaWord(Y1); MetaWord(X1)
#define MetaEllipse(X1, Y1, X2, Y2) MetaRecord(7, 0x418); \
  MetaWord(Y2); MetaWord(X2); MetaWord(Y1); MetaWord(X1)
#define MetaEscape(S) MetaRecord((S), 0x626); \
  MetaWord(15 /* MFCOMMENT */); MetaWord(((S)-5)*2 /* Bytes in comment */);


/* Output one 16 bit or 32 bit value into the metafile buffer stream. */

void MetaWord(w)
word w;
{
  if ((byte PTR)metacur - bm >= MAXMETA) {
    PrintError("Metafile would be more than %ld bytes.", MAXMETA);
    Terminate(_FATAL);
  }
  *metacur = w;
  metacur++;
}

void MetaLong(l)
long l;
{
  MetaWord(LOWORD(l));
  MetaWord(HIWORD(l));
}


/* Output any necessary metafile records to make the current actual     */
/* settings of line color, fill color, etc, be those that we know are   */
/* desired. This is generally called by the primitives routines before  */
/* any figure record is actually written into a metafile. We wait until */
/* the last moment before changing any settings to ensure that we don't */
/* output any unnecessary records, e.g. two select colors in a row.     */

void MetaSelect()
{
  if (metalinedes != metalineact) {
    MetaSelectObject(metalinedes);
    metalineact = metalinedes;
  }
  if (metafilldes != metafillact) {
    MetaSelectObject(16*4 + metafilldes);
    metafillact = metafilldes;
  }
  if (metafontdes != metafontact) {
    MetaSelectObject(16*5 + metafontdes);
    metafontact = metafontdes;
  }
  if (metatxtcdes != metatxtcact) {
    MetaTextColor(rgbbmp[metatxtcdes]);
    metatxtcact = metatxtcdes;
  }
  if (metatxtades != metatxtaact) {
    MetaTextAlign(metatxtades);
    metatxtaact = metatxtades;
  }
  xpen = -1;    /* Invalidate PolyLine cache */
}


/* Output initial metafile header information into our metafile buffer. */
/* We also setup and create all pen, brush, and font objects that may   */
/* possibly be used in the generation and playing of the picture.       */

void MetaInit()
{
  int i, j, k;

  metacur = (word PTR)bm;
  /* Placable Metaheader */
  MetaLong(0x9AC6CDD7L);
  MetaWord(0);      /* Not used */
  MetaWord(0); MetaWord(0);
  MetaWord(chartx); MetaWord(charty);
  MetaWord(chartx/6);  /* Units per inch */
  MetaLong(0L);     /* Not used */
  MetaWord(0x9AC6 ^ 0xCDD7 ^ chartx ^ charty ^ chartx/6);  /* Checksum */
  /* Metaheader */
  MetaWord(1);                   /* Metafile type */
  MetaWord(9);                   /* Size of header in words */
  MetaWord(0x300);               /* Windows version */
  MetaLong(0L);                  /* Size of entire metafile in words */
  MetaWord(16*5+1+(xfont>0)*4);  /* Number of objects in metafile */
  MetaLong(17L);                 /* Size of largest record in words */
  MetaWord(0);                   /* Not used */
  /* Setup */
  MetaEscape(17);
  MetaLong(MAKEQUAD('A', 's', 't', 'r'));  /* "Astr" */
  MetaWord(4);                             /* Creator */
  MetaLong(14L);                           /* Bytes in string */
  MetaLong(MAKEQUAD('A', 's', 't', 'r'));  /* "Astr" */
  MetaLong(MAKEQUAD('o', 'l', 'o', 'g'));  /* "olog" */
  MetaLong(MAKEQUAD(' ', '4', '.', '0'));  /* " 3.2" */
  MetaWord(MAKEWORD('0', 0));              /* "0"    */
  MetaSaveDc();
  MetaWindowOrg(0, 0);
  MetaWindowExt(chartx, charty);
  MetaBkMode(1 /* Transparent */);
  /* Colors */
  for (j = 1; j <= 4; j++)
    for (i = 0; i < 16; i++) {
      k = j <= 1 ? metawid : 0;
      MetaCreatePen(j <= 2 ? 0 : j-2 /* PS_SOLID; PS_DASH; PS_DOT */,
        k, rgbbmp[i]);
    }
  for (i = 0; i < 16; i++) {
    MetaCreateBrush(0 /* BS_SOLID */, rgbbmp[i]);
  }
  MetaCreateBrush(1 /* BS_NULL */, 0L);
  /* Fonts */
  if (xfont) {
    MetaCreateFont(5, 0, -8*SCALE, 2 /* Symbol Charset */);
    MetaWord(MAKEWORD(1 /* Draft */, 1 | 0x10 /* Fixed | Roman */));
    MetaLong(MAKEQUAD('W', 'i', 'n', 'g'));
    MetaLong(MAKEQUAD('d', 'i', 'n', 'g'));
    MetaWord(MAKEWORD('s', 0));

    MetaCreateFont(8, 0, -6*SCALE, 0 /* Ansi Charset */);
    MetaWord(MAKEWORD(0 /* Default */, 2 | 0x10 /* Variable | Roman */));
    MetaLong(MAKEQUAD('T', 'i', 'm', 'e'));
    MetaLong(MAKEQUAD('s', ' ', 'N', 'e'));
    MetaLong(MAKEQUAD('w', ' ', 'R', 'o'));
    MetaLong(MAKEQUAD('m', 'a', 'n', 0));

    MetaCreateFont(6, 6*METAMUL, 10*METAMUL, 0 /* Ansi Charset */);
    MetaWord(MAKEWORD(1 /* Draft */, 1 | 0x30 /* Fixed | Modern */));
    MetaLong(MAKEQUAD('C', 'o', 'u', 'r'));
    MetaLong(MAKEQUAD('i', 'e', 'r', ' '));
    MetaLong(MAKEQUAD('N', 'e', 'w', 0));

    MetaCreateFont(8, 0, -11*SCALE, 0 /* Ansi Charset */);
    MetaWord(MAKEWORD(0 /* Default */, 2 | 0 /* Variable | Don't Care */));
    MetaLong(MAKEQUAD('A', 's', 't', 'r'));
    MetaLong(MAKEQUAD('o', '-', 'S', 'e'));
    MetaLong(MAKEQUAD('m', 'i', 'B', 'o'));
    MetaLong(MAKEQUAD('l', 'd', 0, 0));
  }
}


/* Output trailing records to indicate the end of the metafile and then */
/* actually write out the entire buffer to the specifed file.           */

void WriteMeta(data)
FILE *data;
{
  word PTR w;
#if FALSE
  int i;

  for (i = 16*5+1+(xfont>0)*4; i >= 0; i--) {
    MetaDeleteObject(i);
  }
#endif
  MetaRestoreDc();
  MetaRecord(3, NULL);    /* End record */
  *(long PTR)(bm + 22 + 6) = ((long)((byte PTR)metacur - bm) - 22) / 2;
  for (w = (word PTR)bm; w < metacur; w++) {
    PutWord(*w);
  }
}
#endif /* META */


/*
******************************************************************************
** Core Graphic Procedures.
******************************************************************************
*/

/* Set the current color to use in drawing on the screen or bitmap array. */

void DrawColor(col)
colpal col;
{
#ifdef PS
  if (psfile) {
    if (colcur != col) {
      PSforcestroke();      /* Render existing path with current color */
      fprintf(psdata, "%.2f %.2f %.2f c\n",
        (real)RGBR(rgbbmp[col])/255.0, (real)RGBG(rgbbmp[col])/255.0,
        (real)RGBB(rgbbmp[col])/255.0);
    }
    colcur = col;
    return;
  }
#endif
#ifdef META
  if (metafile)
    metalinedes = col;
#endif
#ifdef X11
  else if (!xfile)
    XSetForeground(disp, gc, rgbind[col]);
#endif
#ifdef MSG
  else if (!xfile)
    _setcolor(col);
#endif
  colcur = col;
}


/* Set a single point on the screen. This is the most basic graphic function */
/* and is called by all the more complex routines. Based on what mode we are */
/* in, we either set a cell in the bitmap array or a pixel on the window.    */

void DrawPoint(x, y)
int x, y;
{
  if (xfile) {
    if (xbitmap) {
      /* Force the coordinates to be within the bounds of the bitmap array. */

      if (x < 0)
        x = 0;
      else if (x >= chartx)
        x = chartx-1;
      if (y < 0)
        y = 0;
      else if (y >= charty)
        y = charty-1;
      PSET(bm, x, y, colcur);
    }
#ifdef PS
    else if (psfile) {
      DrawColor(colcur);
      PSlinecap(TRUE);
      fprintf(psdata, "%d %d d\n", x, y);
      PSstroke(2);
    }
#endif
#ifdef META
    else {
      metafilldes = colcur;
      MetaSelect();
      MetaEllipse(x-metawid/2, y-metawid/2, x+metawid/2, y+metawid/2);
    }
#endif
  }
#ifdef X11
  else
    XDrawPoint(disp, pixmap, gc, x, y);
#endif
#ifdef MSG
  else
    _setpixel(offsetx + x, offsety + y);
#endif
}


/* Draw dot a little larger than just a single pixel at specified location. */

void DrawSpot(x, y)
int x, y;
{
#ifdef PS
  if (psfile) {
    PSlinewidth(currentlinewidth*3);
    DrawPoint(x, y);
    PSlinewidth(currentlinewidth/3);
    return;
  }
#endif
#ifdef META
  if (metafile) {
    metafilldes = colcur;
    MetaSelect();
    MetaEllipse(x-metawid, y-metawid, x+metawid, y+metawid);
    return;
  }
#endif
  DrawPoint(x, y);
  DrawPoint(x, y-1);
  DrawPoint(x-1, y);
  DrawPoint(x+1, y);
  DrawPoint(x, y+1);
}


/* Draw a filled in block, defined by the corners of its rectangle. */

void DrawBlock(x1, y1, x2, y2)
int x1, y1, x2, y2;
{
  int x, y;

  if (xfile) {
    if (xbitmap) {
      for (y = y1; y <= y2; y++)         /* For bitmap, we have to  */
        for (x = x1; x <= x2; x++)       /* just fill in the array. */
          PSET(bm, x, y, colcur);
    }
#ifdef PS
    else if (psfile) {
      DrawColor(colcur);
      fprintf(psdata, "%d %d %d %d rf\n",
        x1-metawid/4, y1-metawid/4, x2-x1+metawid/4, y2-y1+metawid/4);
    }
#endif
#ifdef META
    else {
      metafilldes = colcur;
      MetaSelect();
      MetaRectangle(x1-metawid/2, y1-metawid/2, x2+metawid/2, y2+metawid/2);
    }
#endif
  }
#ifdef X11
  else
    XFillRectangle(disp, pixmap, gc, x1, y1, x2, y2);
#endif
#ifdef MSG
  else
    _rectangle(_GFILLINTERIOR,
      offsetx + x1, offsety + y1, offsetx + x2, offsety + y2);
#endif
}


/* Draw a rectangle on the screen with specified thickness. This is just   */
/* like DrawBlock() except that we are only drawing the edges of the area. */

void DrawBox(x1, y1, x2, y2, xsiz, ysiz)
int x1, y1, x2, y2, xsiz, ysiz;
{
#ifdef META
  if (metafile)
    /* For thin boxes in metafiles, we can just output one rectangle record */
    /* instead of drawing each side separately as we have to do otherwise.  */
    if (xsiz <= 1 && ysiz <= 1) {
      metafilldes = 16;              /* Specify a hollow fill brush. */
      MetaSelect();
      MetaRectangle(x1, y1, x2, y2);
      return;
    }
#endif
  DrawBlock(x1, y1, x2, y1 + ysiz - 1);
  DrawBlock(x1, y1 + ysiz, x1 + xsiz - 1, y2 - ysiz);
  DrawBlock(x2 - xsiz + 1, y1 + ysiz, x2, y2 - ysiz);
  DrawBlock(x1, y2 - ysiz + 1, x2, y2);
}


/* Clear and erase the graphics screen or bitmap contents. */

void DrawClearScreen()
{
#ifdef PS
  if (psfile) {
    /* For PostScript charts first output page orientation information. */
    if (!epsfile) {
      if (modex == MODEL || modex == MODEW ||
        (modex == MODEZ && (todisplay & DASHZ0) == 0)) {
        /* Chartx and charty are reversed for Landscape mode. */
        fprintf(psdata, "%d %d translate\n",
          ((int)(8.5*72) + charty)/2, (chartx + 11*72)/2);
        fprintf(psdata, "-90 rotate\n");
      } else {
        /* Most charts are in Portrait mode */
        fprintf(psdata, "%d %d translate\n", (int)(8.5*72/2) - chartx/2,
        charty/2 + 11*72/2);
      }
    } else
      fprintf(psdata, "0 %d translate\n", charty);
    fprintf(psdata, "1 -1 scale\n");
    scale *= PSMUL; chartx *= PSMUL; charty *= PSMUL;
    fprintf(psdata, "1 %d div dup scale\n", PSMUL);
  }
#endif
#ifdef META
  if (metafile)
    MetaInit();    /* For metafiles first go write our header information. */
#endif

  /* Hack: If a comparison relationship chart is set and we're in the -Z  */
  /* horizon or -S space graphics chart modes (which normally is just the */
  /* same as single chart graphics) don't actually clear the screen.      */

  if (relation <= DASHr0 && xnow > 0 && (modex == MODEZ || modex == MODES))
    return;
#ifdef MSG
  if (!xfile)
    _clearscreen(_GCLEARSCREEN);
#endif
  DrawColor(off);
  DrawBlock(0, 0, chartx - 1, charty - 1);    /* Clear bitmap screen. */
}


/* Draw a line on the screen, specified by its endpoints. In addition, we */
/* have specified a skip factor, which allows us to draw dashed lines.    */

void DrawDash(x1, y1, x2, y2, skip)
int x1, y1, x2, y2, skip;
{
  static word PTR poly;
  int x = x1, y = y1, xadd, yadd, yinc, xabs, yabs, i, j = 0;

  if (skip < 0)
    skip = 0;
#ifdef ISG
  if (!xfile) {
    if (!skip) {
#ifdef X11
      /* For non-dashed X window lines, let's have the Xlib do it for us. */

      XDrawLine(disp, pixmap, gc, x1, y1, x2, y2);
#else
      /* For non-dashed lines, let's have the graphics library do it for us. */

      _moveto(offsetx + x1, offsety + y1);
      _lineto(offsetx + x2, offsety + y2);
#endif
      return;
    }
  }
#endif /* ISG */

#ifdef PS
  if (psfile) {

    /* For PostScript charts we can save file size if we output a LineTo  */
    /* command when the start vertex is the same as the end vertex of the */
    /* previous line drawn, instead of writing out both vertices.         */

    PSlinecap(TRUE);
    PSdash(skip);
    if (xpen != x1 || ypen != y1)
      fprintf(psdata, "%d %d %d %d l\n", x1, y1, x2, y2);
    else
      fprintf(psdata, "%d %d t\n", x2, y2);
    xpen = x2; ypen = y2;
    PSstroke(2);
    return;
  }
#endif
#ifdef META
  if (metafile) {

    /* For metafile charts we can really save file size for consecutive */
    /* lines sharing endpoints by consolidating them into a PolyLine.   */

    if (xpen != x1 || ypen != y1) {
      metalinedes = (metalinedes & 15) + 16*(skip > 3 ? 3 : skip);
      MetaSelect();
      poly = metacur;
      MetaRecord(8, 0x325);    /* Polyline */
      MetaWord(2); MetaWord(x1); MetaWord(y1);
    } else {
      *poly += 2;
      (*(poly+3))++;
      /* Note: We should technically update the max record size in the   */
      /* file header if need be here too, but it doesn't seem necessary. */
    }
    MetaWord(x2); MetaWord(y2);
    xpen = x2; ypen = y2;
    return;
  }
#endif

  /* If none of the above cases hold, we have to draw the line dot by dot. */

  xadd = x2 - x1 >= 0 ? 1 : 3;
  yadd = y2 - y1 >= 0 ? 2 : 4;

⌨️ 快捷键说明

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