?? xgeneral.c
字號:
/*
** Astrolog (Version 4.00) File: xgeneral.c
**
** IMPORTANT NOTICE: the graphics database and chart display routines
** used in this program are Copyright (C) 1991-1993 by Walter D. Pullen
** (cruiser1@stein.u.washington.edu). Permission is granted to freely
** use and distribute these routines provided one doesn't sell,
** restrict, or profit from them in any way. Modification is allowed
** provided these notices remain with any altered or edited versions of
** the program.
**
** The main planetary calculation routines used in this program have
** been Copyrighted and the core of this program is basically a
** conversion to C of the routines created by James Neely as listed in
** Michael Erlewine's 'Manual of Computer Programming for Astrologers',
** available from Matrix Software. The copyright gives us permission to
** use the routines for personal use but not to sell them or profit from
** them in any way.
**
** The PostScript code within the core graphics routines are programmed
** and Copyright (C) 1992-1993 by Brian D. Willoughby
** (brianw@sounds.wa.com). Conditions are identical to those above.
**
** The extended accurate ephemeris databases and formulas are from the
** calculation routines in the program "Placalc" and are programmed and
** Copyright (C) 1989,1991,1993 by Astrodienst AG and Alois Treindl
** (alois@azur.ch). The use of that source code is subject to
** regulations made by Astrodienst Zurich, and the code is not in the
** public domain. This copyright notice must not be changed or removed
** by any user of this program.
**
** Initial programming 8/28,30, 9/10,13,16,20,23, 10/3,6,7, 11/7,10,21/1991.
** X Window graphics initially programmed 10/23-29/1991.
** PostScript graphics initially programmed 11/29-30/1992.
** Last code change made 12/31/1993.
*/
#include "astrolog.h"
#ifdef GRAPH
int xpen, ypen;
/*
******************************************************************************
** Bitmap File Routines.
******************************************************************************
*/
/* Write the bitmap array to a previously opened file in a format that */
/* can be read in by the Unix X commands bitmap and xsetroot. The 'mode' */
/* parameter defines how much white space is put in the file. */
void WriteXBitmap(data, name, mode)
FILE *data;
char *name, mode;
{
int x, y, i, temp = 0;
uint value;
fprintf(data, "#define %s_width %d\n" , name, chartx);
fprintf(data, "#define %s_height %d\n", name, charty);
fprintf(data, "static %s %s_bits[] = {",
mode != 'V' ? "char" : "short", name);
for (y = 0; y < charty; y++) {
x = 0;
do {
/* Process each row, eight columns at a time. */
if (y + x > 0)
fprintf(data, ",");
if (temp == 0)
fprintf(data, "\n%s",
mode == 'N' ? " " : (mode == 'C' ? " " : ""));
value = 0;
for (i = (mode != 'V' ? 7 : 15); i >= 0; i--)
value = (value << 1) +
(!(PGET(bm, x+i, y)^(xreverse*15))^xreverse && (x + i < chartx));
if (mode == 'N')
putc(' ', data);
fprintf(data, "0x");
if (mode == 'V')
fprintf(data, "%c%c",
INTTOHEX(value >> 12), INTTOHEX((value >> 8) & 15));
fprintf(data, "%c%c",
INTTOHEX((value >> 4) & 15), INTTOHEX(value & 15));
temp++;
/* Is it time to skip to the next line while writing the file yet? */
if ((mode == 'N' && temp >= 12) ||
(mode == 'C' && temp >= 15) ||
(mode == 'V' && temp >= 11))
temp = 0;
x += (mode != 'V' ? 8 : 16);
} while (x < chartx);
}
fprintf(data, "};\n");
}
/* Write the bitmap array to a previously opened file in a simple boolean */
/* Ascii rectangle, one char per pixel, where '#' represents an off bit and */
/* '-' an on bit. The output format is identical to the format generated by */
/* the Unix bmtoa command, and it can be converted into a bitmap with atobm. */
void WriteAscii(data)
FILE *data;
{
int x, y, i;
for (y = 0; y < charty; y++) {
for (x = 0; x < chartx; x++) {
i = PGET(bm, x, y);
if (xcolor)
putc(INTTOHEX(i), data);
else
putc(i ? '-' : '#', data);
}
putc('\n', data);
}
}
/* Write the bitmap array to a previously opened file in the bitmap format */
/* used in Microsoft Windows for its .bmp extension files. This is a pretty */
/* efficient format, only requiring one bit per pixel and a small header. */
void WriteBmp(data)
FILE *data;
{
int x, y;
dword value;
/* BitmapFileHeader */
PutByte('B'); PutByte('M');
PutLong(14+40 + (xcolor ? 64 : 8) +
(long)4*charty*((chartx-1 >> (xcolor ? 3 : 5))+1));
PutWord(0); PutWord(0);
PutLong(14+40 + (xcolor ? 64 : 8));
/* BitmapInfo / BitmapInfoHeader */
PutLong(40);
PutLong(chartx); PutLong(charty);
PutWord(1); PutWord(xcolor ? 4 : 1);
PutLong(0 /*BI_RGB*/); PutLong(0);
PutLong(0); PutLong(0);
PutLong(0); PutLong(0);
/* RgbQuad */
if (xcolor)
for (x = 0; x < 16; x++) {
PutByte(RGBB(rgbbmp[x])); PutByte(RGBG(rgbbmp[x]));
PutByte(RGBR(rgbbmp[x])); PutByte(0);
}
else {
PutLong(0);
PutByte(255); PutByte(255); PutByte(255); PutByte(0);
}
/* Data */
for (y = charty-1; y >= 0; y--) {
value = 0;
for (x = 0; x < chartx; x++) {
if ((x & (xcolor ? 7 : 31)) == 0 && x > 0) {
PutLong(value);
value = 0;
}
if (xcolor)
value |= (dword)PGET(bm, x, y) << ((x & 7 ^ 1) << 2);
else
if (PGET(bm, x, y))
value |= (dword)1 << (x & 31 ^ 7);
}
PutLong(value);
}
}
/* Output the bitmap in memory to a file. This basically consists of just */
/* calling some routine to actually write a bitmap to a file, although we */
/* need to prompt the user for a filename if it wasn't specified beforehand. */
void WriteFile()
{
char line[STRING];
FILE *data;
#ifdef PS
if (psfile) {
PSend();
return;
}
#endif
if (outputfile == NULL && (metafile || (xbitmap && bitmapmode == 'B')))
fprintf(stdout, "(It is recommended to specify an extension of '.%s'.)\n",
xbitmap ? "bmp" : "wmf");
loop {
if (outputfile == NULL) {
sprintf(line, "Enter name of file to write %s to",
xbitmap ? "bitmap" : "metafile");
InputString(line, line);
outputfile = line;
}
data = fopen(outputfile, "wb");
if (data != NULL)
break;
else {
PrintWarning("Couldn't create output file.");
outputfile = NULL;
}
}
if (xbitmap) {
if (bitmapmode == 'B')
WriteBmp(data);
else if (bitmapmode == 'A')
WriteAscii(data);
else
WriteXBitmap(data, outputfile, bitmapmode);
}
#ifdef META
else
WriteMeta(data);
#endif
fclose(data);
}
/*
******************************************************************************
** PostScript File Routines.
******************************************************************************
*/
#ifdef PS
/* Global variables used by the PostScript generator. */
FILE *psdata;
int strokecount = 0, currentlinecap = 0, currentdash = 0, currentfont = 0;
real currentlinewidth = 1.0;
/* Table of PostScript header alias lines used by the program. */
char PSfunctions[] =
"/languagelevel where{pop languagelevel}{1}ifelse\
2 lt{\n\
/sf{exch findfont exch\
dup type/arraytype eq{makefont}{scalefont}ifelse setfont}bind def\n\
/rf{gsave newpath\n\
4 -2 roll moveto\
dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath\n\
fill grestore}bind def\n\
/rc{newpath\n\
4 -2 roll moveto\
dup 0 exch rlineto exch 0 rlineto neg 0 exch rlineto closepath\n\
clip newpath}bind def\n\
}{/sf/selectfont load def/rf/rectfill load def\
/rc/rectclip load def}ifelse\n\
/center{0 begin gsave dup 4 2 roll\
translate newpath 0 0 moveto\
false charpath flattenpath pathbbox\
/URy exch def/URx exch def/LLy exch def/LLx exch def\
URx LLx sub 0.5 mul LLx add neg URy LLy sub 0.5 mul LLy add neg\
0 0 moveto rmoveto\
show grestore end}bind def\n\
/center load 0 4 dict put\n\
/c{setrgbcolor}bind def\n\
/d{moveto 0 0 rlineto}bind def\n\
/l{4 2 roll moveto lineto}bind def\n\
/t{lineto}bind def\n\
/el{newpath matrix currentmatrix 5 1 roll translate scale\
0 0 1 0 360 arc setmatrix stroke}bind def\n";
/* Write a command to flush the PostScript buffer. */
void PSforcestroke()
{
if (strokecount > 0) { /* render any existing path */
fprintf(psdata, "stroke\n");
strokecount = 0;
xpen = -1; /* Invalidate PolyLine cache */
}
}
/* Indicate that a certain number of PostScript commands have been done. */
void PSstroke(n)
int n;
{
strokecount += n;
if (strokecount > 5000) /* Whenever we reach a certain limit, flush. */
PSforcestroke();
}
/* Set the type of line end to be used by PostScript commands. If linecap */
/* is true, then the line ends are rounded, otherwise they are squared. */
void PSlinecap(linecap)
int linecap;
{
if (linecap != currentlinecap) {
PSforcestroke();
fprintf(psdata, "%d setlinecap\n", linecap);
currentlinecap = linecap;
}
}
/* Set the dash length to be used by PostScript line commands. */
void PSdash(dashoff)
int dashoff;
{
if (dashoff != currentdash) {
PSforcestroke();
if (dashoff)
fprintf(psdata, "[%d %d", PSMUL, dashoff * PSMUL);
else
fprintf(psdata, "[");
fprintf(psdata, "]0 setdash\n");
currentdash = dashoff;
}
}
/* Set a linewidth size to be used by PostScript figure primitive commands. */
void PSlinewidth(linewidth)
int linewidth;
{
real oldlinewidth = currentlinewidth;
if (linewidth != currentlinewidth) {
PSforcestroke();
fprintf(psdata, "%d setlinewidth\n", linewidth);
currentlinewidth = linewidth;
}
}
/* Set a system font and size to be used by PostScript text commands. */
void PSfont(psfont)
int psfont;
{
int temp;
if (psfont != currentfont && xfont) {
if (psfont <= 2) {
temp = psfont == 1 ? 32*PSMUL : 23*PSMUL;
fprintf(psdata, "/Astro[%d 0 0 -%d 0 0]sf\n", temp, temp);
} else if (psfont == 3) {
temp = 26*PSMUL;
fprintf(psdata, "/Times-Roman[%d 0 0 -%d 0 0]sf\n", temp, temp);
} else {
temp = 10*PSMUL;
fprintf(psdata, "/Courier[%d 0 0 -%d 0 0]sf\n", temp, temp);
}
currentfont = psfont;
}
}
/* Prompt the user for the name of a file to write the PostScript file to */
/* (if not already specified), open it, and write out file header info. */
void PSbegin()
{
char line[STRING];
if (outputfile == NULL && epsfile)
fprintf(stdout,
"(It is recommended to specify an extension of '.eps'.)\n");
loop {
if (outputfile == NULL) {
sprintf(line, "Enter name of file to write PostScript to");
InputString(line, line);
outputfile = line;
}
psdata = fopen(outputfile, "w");
if (psdata != NULL)
break;
else {
PrintWarning("Couldn't create output file.");
outputfile = NULL;
}
}
fprintf(psdata, "%%!PS-Adobe-2.0");
if (epsfile)
fprintf(psdata, " EPSF-2.0");
fprintf(psdata, "\n%%%%Title: %s\n", outputfile);
fprintf(psdata, "%%%%Creator: %s %s\n", appname, VERSION);
fprintf(psdata, "%%%%CreationDate: %s\n", DATE);
if (epsfile) {
fprintf(psdata, "%%%%BoundingBox: 0 0 %d %d\n", chartx, charty);
fprintf(psdata, "%%%%EndComments\n");
fprintf(psdata, "%%%%BeginSetup\n");
fprintf(psdata, PSfunctions, 6 * PSMUL, 6 * PSMUL);
fprintf(psdata, "%%%%EndSetup\n");
fprintf(psdata, "0 0 %d %d rc\n", chartx, charty);
} else {
fprintf(psdata, "%%%%Pages: 1 1\n");
fprintf(psdata, "%%%%DocumentFonts: (atend)\n");
fprintf(psdata, "%%%%BoundingBox: 9 9 603 783\n"); /* 8.5" x 11" */
fprintf(psdata, "%%%%EndComments\n");
fprintf(psdata, "%%%%BeginProcSet: common\n");
fprintf(psdata, PSfunctions, 6 * PSMUL, 6 * PSMUL);
fprintf(psdata, "%%%%EndProcSet\n");
fprintf(psdata, "%%%%Page: 1 1\n");
}
PSfont(2);
fprintf(psdata, "gsave\n");
PSlinewidth(metawid/2);
xpen = -1;
}
/* Write out trailing information to the PostScript file and close it. */
void PSend()
{
PSforcestroke();
if (epsfile)
fprintf(psdata, "%%%%EOF\n");
else {
fprintf(psdata, "showpage\n");
fprintf(psdata, "%%%%PageTrailer\n");
fprintf(psdata, "%%%%Trailer\n");
fprintf(psdata, "%%%%DocumentFonts: Times-Roman\n");
if (xfont) {
fprintf(psdata, "%%%%+ Courier\n");
fprintf(psdata, "%%%%+ Astro\n");
}
}
fclose(psdata);
}
#endif /* PS */
/*
******************************************************************************
** Metafile Routines.
******************************************************************************
*/
#ifdef META
/* Global variables used by the metafile generator. */
colpal metalinedes, metalineact = -1, /* Desired and actual line color. */
metafilldes, metafillact = -1, /* Desired and actual fill color. */
metafontdes = -1, metafontact = -1, /* Desired and actual text font. */
metatxtcdes = -1, metatxtcact = -1, /* Desired and actual text color. */
metatxtades = -1, metatxtaact = -1; /* Desired/actual text alignment. */
/* Macros to output the various metafile commands we use. */
#define MetaRecord(S, R) MetaLong((long)(S)); MetaWord(R)
#define MetaSelectObject(O) MetaRecord(4, 0x12D); MetaWord(O)
#define MetaDeleteObject(O) MetaRecord(4, 0x1F0); MetaWord(O)
#define MetaSaveDc() MetaRecord(3, 0x01E)
#define MetaRestoreDc() MetaRecord(4, 0x127); MetaWord(-1)
#define MetaWindowOrg(X, Y) MetaRecord(5, 0x20B); MetaWord(Y); MetaWord(X)
#define MetaWindowExt(X, Y) MetaRecord(5, 0x20C); MetaWord(Y); MetaWord(X)
#define MetaCreatePen(S, W, C) MetaRecord(8, 0x2FA); MetaWord(S); \
MetaWord(W); MetaWord(W); MetaLong(C)
#define MetaCreateBrush(S, C) MetaRecord(7, 0x2FC); \
MetaWord(S); MetaLong(C); MetaWord(0 /* Not used */);
#define MetaCreateFont(S, X, Y, C) MetaRecord(12+(S), 0x2FB); MetaWord(Y); \
MetaWord(X); MetaWord(0 /* Angle */); MetaWord(0 /* Not used */); \
MetaWord(400 /* Normal Weight */); MetaWord(0 /* Italic, Underline */); \
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -