2
* hyakubm --- Make a bitmap of "Ogura Hyakunin Issyu" in PGM-ASCII format.
3
* hyakux11 --- Display "Ogura Hyakunin Issyu" on an X11 window.
5
* by Hirotsugu Kakugawa (h.kakugawa@computer.org)
7
* Copyright (C) 1998 by H. Kakugawa
9
* Oct 1998 Version 1.0: only mode 1 fonts.
10
* 10 Dec 1998 Version 1.1: supports mode1 and 2 switch.
11
* Uses "jiskan16.pcf" in mode 2 by default; this works
12
* (possibly) all X11 environment.
15
* Copyright (C) 1998 Hirotsugu Kakugawa.
16
* All rights reserved.
18
* This program is free software; you can redistribute it and/or modify
19
* it under the terms of the GNU General Public License as published by
20
* the Free Software Foundation; either version 2, or (at your option)
23
* This program is distributed in the hope that it will be useful,
24
* but WITHOUT ANY WARRANTY; without even the implied warranty of
25
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
* GNU General Public License for more details.
28
* You should have received a copy of the GNU General Public License
29
* along with this program; if not, write to the Free Software
30
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38
#include <VFlib-3_6.h>
43
#include <X11/Xutil.h>
44
#include <X11/cursorfont.h>
45
#include <X11/keysym.h>
48
#define PARAM_NAME_DPI "TeX_DPI"
49
#define PARAM_NAME_MODE "TeX_KPATHSEA_MODE"
50
#define PARAM_NAME_PROG "TeX_KPATHSEA_PROGRAM"
52
#define PARAM_DEFAULT_VFLIBCAP "vflibcap"
53
#define PARAM_DEFAULT_DPI 300
54
#define PARAM_DEFAULT_KMODE "cx"
55
#define PARAM_DEFAULT_PROG "/usr/local/bin/hyakubm"
56
#define PARAM_DEFAULT_FONT_MODE 2
57
#define PARAM_DEFAULT_FONT_SIZE -1
58
#define PARAM_DEFAULT_FONT_NAME "jiskan16.pcf"
59
#define PARAM_DEFAULT_BASELINESKIP 1.4
60
#define PARAM_DEFAULT_WAIT 300
61
#define PARAM_DEFAULT_SHRINK 1
62
#define PARAM_DEFAULT_MARGIN_Y 5
63
#define PARAM_DEFAULT_MARGIN_X 5
65
static char* param_vflibcap = PARAM_DEFAULT_VFLIBCAP;
66
static int param_dpi = PARAM_DEFAULT_DPI;
67
static char* param_kmode = PARAM_DEFAULT_KMODE;
68
static char* param_prog = PARAM_DEFAULT_PROG;
69
static int param_font_mode = PARAM_DEFAULT_FONT_MODE;
70
static double param_font_size = PARAM_DEFAULT_FONT_SIZE;
71
static char* param_font_name = PARAM_DEFAULT_FONT_NAME;
72
static double param_baselineskip = PARAM_DEFAULT_BASELINESKIP;
73
static int param_shrink = PARAM_DEFAULT_SHRINK;
74
static int param_margin_t = PARAM_DEFAULT_MARGIN_Y;
75
static int param_margin_b = PARAM_DEFAULT_MARGIN_Y;
76
static int param_margin_l = PARAM_DEFAULT_MARGIN_X;
77
static int param_margin_r = PARAM_DEFAULT_MARGIN_X;
78
static double param_indent1 = 0;
79
static double param_indent2 = 4;
80
static double param_indent3 = 1;
83
static double param_wait = PARAM_DEFAULT_WAIT;
84
static char* param_geometry = NULL;
89
void typeset(int,int,VF_BITMAPLIST);
90
void typeset_phase(long*,int,VF_BITMAPLIST,long*,long*);
91
void typeset_length(long*,int,long*,long*);
92
void shipout(VF_BITMAP,FILE*,int);
94
int shipoutx11(VF_BITMAP,FILE*,int,int);
97
#define PR1(s1) fprintf(stderr, s1);
98
#define PR2(s1,s2) fprintf(stderr, s1, s2);
99
#define PR3(s1,s2,s3) fprintf(stderr, s1, s2, s3);
104
main(int argc, char **argv)
110
for (--argc, argv++; argc > 0; --argc, argv++){
111
if (isdigit((int)*argv[0])){
112
poem_no = atoi(*argv);
113
if ((poem_no < 1) || (100 < poem_no)){
117
if ((strcmp(*argv, "-v") == 0) && (argc > 1)){
118
param_vflibcap = argv[1];
120
} else if (strcmp(*argv, "-cx") == 0){
121
param_dpi = 300; param_kmode = "cx";
122
} else if (strcmp(*argv, "-sparcptr") == 0){
123
param_dpi = 400; param_kmode = "sparcptr";
124
} else if (strcmp(*argv, "-ljfour") == 0){
125
param_dpi = 600; param_kmode = "ljfour";
126
} else if ((strcmp(*argv, "-dpi") == 0) && (argc > 1)){
127
param_dpi = atoi(argv[1]);
129
} else if ((strcmp(*argv, "-mode") == 0) && (argc > 1)){
130
param_kmode = argv[1];
132
} else if ((strcmp(*argv, "-s") == 0) && (argc > 1)){
133
param_shrink = atoi(argv[1]);
135
} else if ((strcmp(*argv, "-f") == 0) && (argc > 1)){
136
param_font_name = argv[1];
138
} else if (strcmp(*argv, "-mode1") == 0){
140
} else if (strcmp(*argv, "-mode2") == 0){
142
} else if ((strcmp(*argv, "-p") == 0) && (argc > 1)){
143
param_font_size = atof(argv[1]);
145
} else if ((strcmp(*argv, "-f") == 0) && (argc > 1)){
146
param_font_name = argv[1];
148
} else if ((strcmp(*argv, "-b") == 0) && (argc > 1)){
149
param_baselineskip = atof(argv[1]);
151
} else if ((strcmp(*argv, "-g") == 0) && (argc > 1)){
153
param_margin_t = param_margin_b = m;
154
param_margin_l = param_margin_r = m;
156
} else if ((strcmp(*argv, "-gy") == 0) && (argc > 1)){
157
param_margin_t = param_margin_b = atoi(argv[1]);
159
} else if ((strcmp(*argv, "-gx") == 0) && (argc > 1)){
160
param_margin_l = param_margin_r = atoi(argv[1]);
163
} else if ((strcmp(*argv, "-w") == 0) && (argc > 1)){
164
param_wait = atoi(argv[1]);
166
} else if ((strcmp(*argv, "-geometry") == 0) && (argc > 1)){
167
param_geometry = argv[1];
170
} else if ((strcmp(*argv, "-i1") == 0) && (argc > 1)){
171
param_indent1 = atof(argv[1]);
173
} else if ((strcmp(*argv, "-i2") == 0) && (argc > 1)){
174
param_indent2 = atof(argv[1]);
176
} else if ((strcmp(*argv, "-i3") == 0) && (argc > 1)){
177
param_indent3 = atof(argv[1]);
179
} else if ((strcmp(*argv, "-h") == 0) || (strcmp(*argv, "--help") == 0)){
196
PR1("hyakubm --- Make bitmap of Hyakunin-Issyu.\n");
198
PR1("hyakux11 --- Print Hyakunin-Issyu on an X11 Window.\n");
200
PR1("Usage: hyakubm [OPTIONS] [POEM_NO]\n");
201
PR1("POEM_NO is the poem number, from 1 to 100\n");
203
PR2(" -v VFLIBCAP vflibcap file [%s]\n", PARAM_DEFAULT_VFLIBCAP);
204
PR2(" -f FONT font name [%s]\n", PARAM_DEFAULT_FONT_NAME);
205
PR1(" -mode1 font is opened in VFlib mode 1\n");
206
PR1(" -mode2 font is opened in VFlib mode 2 (defualt mode)\n");
207
PR1(" -p font size in pixel (mode 1) or point (mode 2)\n");
208
PR2(" -dpi device resolution (mode 1) [%d]\n",
210
PR2(" -mode device mode for font search in kpathsea [%s]\n",
211
PARAM_DEFAULT_KMODE);
212
PR1(" -cx same as '-dpi 300 -mode cx'\n");
213
PR1(" -sparcptr same as '-dpi 400 -mode sparcptr'\n");
214
PR1(" -ljfour same as '-dpi 600 -mode ljfour'\n");
215
PR2(" -b B baseline skip factor [%.2f]\n",
216
PARAM_DEFAULT_BASELINESKIP);
217
PR2(" -gx MX horizontal margin [%d]\n", PARAM_DEFAULT_MARGIN_X);
218
PR2(" -gy MY vertical margin [%d]\n", PARAM_DEFAULT_MARGIN_Y);
219
PR1(" -g M same as '-gx M -gy M'\n");
220
PR2(" -s S shrink factor of an image [%d]\n", PARAM_DEFAULT_SHRINK);
222
PR2(" -w S wait for S second for each poem [%d]\n",
224
PR1(" -geometry G window geometry\n");
235
char vflib_param[1024];
236
struct vf_s_bitmaplist bmlist;
238
sprintf(vflib_param, "%s=%d, %s=%s, %s=%s",
239
PARAM_NAME_DPI, param_dpi,
240
PARAM_NAME_MODE, param_kmode,
241
PARAM_NAME_PROG, param_prog);
242
if (VF_Init(param_vflibcap, vflib_param) < 0){
243
PR1("Failed to initialize VFlib\n");
247
if (param_font_mode == 1){
248
fid = VF_OpenFont1(param_font_name, param_dpi, param_dpi, param_font_size,
251
fid = VF_OpenFont2(param_font_name, param_font_size, 1.0, 1.0);
254
PR2("Failed to open a font: %s\n", param_font_name);
264
VF_BitmapListInit(&bmlist);
265
typeset(p, fid, &bmlist);
266
bm = VF_BitmapListCompose(&bmlist);
267
VF_BitmapListFinish(&bmlist);
268
shipout(bm, stdout, p);
273
VF_BitmapListInit(&bmlist);
274
typeset(p, fid, &bmlist);
275
bm = VF_BitmapListCompose(&bmlist);
276
VF_BitmapListFinish(&bmlist);
277
p = shipoutx11(bm, stdout, p, param_wait);
290
typeset(int poem_no, int fid, VF_BITMAPLIST bmlist)
296
long ref1, ref2, ref_max, x3, y3;
298
if (param_font_mode == 1){
299
bm3121 = VF_GetBitmap1(fid, 0x3121L, 1.0, 1.0);
301
bm3121 = VF_GetBitmap2(fid, 0x3121L, 1.0, 1.0);
305
w = bm3121->bbx_width;
306
h = bm3121->bbx_height;
309
dir = 0; /* horizontal */
311
dir = 1; /* vertical */
315
refp_x = param_indent1 * dx;
317
typeset_phase(poem_table[poem_no-1].phase1, fid, bmlist, &refp_x, &refp_y);
318
typeset_phase(poem_table[poem_no-1].phase2, fid, bmlist, &refp_x, &refp_y);
319
typeset_phase(poem_table[poem_no-1].phase3, fid, bmlist, &refp_x, &refp_y);
322
refp_x = param_indent2 * dx;
323
refp_y -= param_baselineskip * h;
324
typeset_phase(poem_table[poem_no-1].phase4, fid, bmlist, &refp_x, &refp_y);
325
typeset_phase(poem_table[poem_no-1].phase5, fid, bmlist, &refp_x, &refp_y);
328
refp_y -= param_baselineskip * h;
329
if ((ref_max = ref1) < ref2)
331
typeset_length(poem_table[poem_no-1].auth, fid, &x3, &y3);
332
refp_x = ref_max - x3 + param_indent3 * dx;
333
typeset_phase(poem_table[poem_no-1].auth, fid, bmlist, &refp_x, &refp_y);
335
} else /* vertical */ {
338
refp_y = param_indent1 * dy;
339
typeset_phase(poem_table[poem_no-1].phase1, fid, bmlist, &refp_x, &refp_y);
340
typeset_phase(poem_table[poem_no-1].phase2, fid, bmlist, &refp_x, &refp_y);
341
typeset_phase(poem_table[poem_no-1].phase3, fid, bmlist, &refp_x, &refp_y);
344
refp_x -= param_baselineskip * w;
345
refp_y = param_indent2 * dy;
346
typeset_phase(poem_table[poem_no-1].phase4, fid, bmlist, &refp_x, &refp_y);
347
typeset_phase(poem_table[poem_no-1].phase5, fid, bmlist, &refp_x, &refp_y);
350
refp_x -= param_baselineskip * w;
351
if ((ref_max = ref1) > ref2) /* Note: ref1, ref2 < 0 */
353
typeset_length(poem_table[poem_no-1].auth, fid, &x3, &y3);
354
refp_y = ref_max - y3 + param_indent3 * dy;
355
typeset_phase(poem_table[poem_no-1].auth, fid, bmlist, &refp_x, &refp_y);
360
typeset_phase(long *s, int fid, VF_BITMAPLIST bmlist,
361
long *refp_x, long *refp_y)
366
for (i = 0; s[i] != 0L; i++){
367
if (param_font_mode == 1){
368
bm = VF_GetBitmap1(fid, s[i], 1.0, 1.0);
370
bm = VF_GetBitmap2(fid, s[i], 1.0, 1.0);
372
VF_BitmapListPut(bmlist, bm, *refp_x, *refp_y);
380
typeset_length(long *s, int fid, long *x, long *y)
392
for (i = 0; s[i] != 0L; i++){
393
if (param_font_mode == 1){
394
bm = VF_GetBitmap1(fid, s[i], 1.0, 1.0);
396
bm = VF_GetBitmap2(fid, s[i], 1.0, 1.0);
408
shipout(VF_BITMAP bm, FILE *fp, int poem_no)
412
sprintf(title, "Hyakunin Issyu #%d", poem_no);
413
VF_ImageOut_PGMAscii(bm, fp, -1, -1,
414
VF_IMAGEOUT_POSITION_NONE, VF_IMAGEOUT_POSITION_NONE,
415
param_margin_l, param_margin_r,
416
param_margin_t, param_margin_b,
417
0, param_shrink, "hyakubm", title);
422
static int x_initialized = 0;
423
static int x_mapped = 0;
424
static Display *x_disp;
429
static unsigned long x_pix_fg;
430
static unsigned long x_pix_bg;
431
static unsigned long *x_pix_table = NULL;
433
static char *param_fg = "black";
434
static char *param_bg = "white";
435
static unsigned char bits[] = {
436
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
438
static void x_create_window(VF_BITMAP);
439
static void x_update_window(VF_BITMAP,int);
443
shipoutx11(VF_BITMAP bm, FILE *fp, int p, int t)
450
if (x_initialized == 0){
455
x_update_window(bm, p);
457
if ((waitsec = t) < 0)
460
while ((t < 0) || (waitsec > 0)){
461
while ((waitsec > 0) && (XPending(x_disp) == 0)){
465
if (XPending(x_disp) > 0){
466
XNextEvent(x_disp, &xev);
469
while (XCheckWindowEvent(x_disp, x_win, ExposureMask, &xev) == True)
471
x_update_window(bm, p);
474
if (XLookupString(&xev.xkey, keyin, sizeof(keyin), &ks, NULL) != 1){
476
case XK_space: return (p) % 100 + 1;
480
case ' ': return (p) % 100 + 1;
481
case 'b': case 'B': return (p-2+100) % 100 + 1;
483
case '>': return 100;
484
case 'q': case 'Q': exit(0);
491
return (p) % 100 + 1;
495
x_create_window(VF_BITMAP bm)
498
XColor col, xc_fg, xc_bg, xc;
501
unsigned int geom_w, geom_h;
504
if (x_initialized == 1)
507
x_aa = param_shrink * param_shrink + 1;
511
if ((x_disp = XOpenDisplay(NULL)) == NULL){
512
PR1("Can't open X display.\n");
516
XAllocNamedColor(x_disp, DefaultColormap(x_disp,0), param_fg, &xc_fg, &xc);
517
XAllocNamedColor(x_disp, DefaultColormap(x_disp,0), param_bg, &xc_bg, &xc);
518
x_pix_fg = xc_fg.pixel;
519
x_pix_bg = xc_bg.pixel;
521
geom_x = geom_y = geom_w = geom_h = 1;
522
gf = XParseGeometry(param_geometry, &geom_x, &geom_y, &geom_w, &geom_h);
524
x_win = XCreateSimpleWindow(x_disp, RootWindow(x_disp, 0), geom_x, geom_y,
525
w, h, 2, XBlackPixel(x_disp,0), x_pix_bg);
527
if (((gf & XValue) != 0) || ((gf & YValue) != 0)){
528
hints.flags = USPosition;
531
XSetStandardProperties(x_disp, x_win, "", "", None, NULL, 0, &hints);
534
x_gc_win = XCreateGC(x_disp, x_win, 0, 0);
535
x_pix_table = (unsigned long*)malloc(x_aa * sizeof(unsigned long));
536
if (x_pix_table == NULL){
540
for (i = 0; i < x_aa; i++){
541
col.flags = DoRed | DoGreen | DoBlue;
542
col.red = xc_bg.red + ((xc_fg.red - xc_bg.red) * i)/(x_aa-1);
543
col.green = xc_bg.green + ((xc_fg.green - xc_bg.green) * i)/(x_aa-1);
544
col.blue = xc_bg.blue + ((xc_fg.blue - xc_bg.blue) * i)/(x_aa-1);
545
if (XAllocColor(x_disp, DefaultColormap(x_disp, 0), &col) == 0){
546
PR1("Can't allocate colors.\n");
549
x_pix_table[i] = col.pixel;
551
XSetForeground(x_disp, x_gc_win, x_pix_table[0]);
552
XSetBackground(x_disp, x_gc_win, x_pix_table[x_aa-1]);
553
XStoreName(x_disp, x_win, "OHI");
554
XSelectInput(x_disp, x_win, KeyPressMask|ButtonPressMask|ExposureMask);
558
x_update_window(VF_BITMAP bm, int poem_no)
561
int *pgm_buff, *g, pgm_w, pgm_h, max_val;
566
if (param_shrink <= 0)
568
max_val = param_shrink * param_shrink;
569
pgm_w = (bm->bbx_width + param_shrink - 1) / param_shrink;
570
pgm_h = (bm->bbx_height + param_shrink - 1) / param_shrink;
572
x_w = param_margin_l + pgm_w + param_margin_r;
573
x_h = param_margin_t + pgm_h + param_margin_b;
575
sprintf(name, "OHI#%d", poem_no);
576
XStoreName(x_disp, x_win, name);
577
XResizeWindow(x_disp, x_win, x_w, x_h);
579
XMapWindow(x_disp, x_win);
582
XClearWindow(x_disp, x_win);
584
if ((pgm_buff = calloc(pgm_w * pgm_h, sizeof(int))) == NULL){
590
for (y = 0; y < bm->bbx_height; y++){
591
g = &pgm_buff[(y/param_shrink)*pgm_w];
592
for (x = 0; x < bm->bbx_width; x++){
593
if ((p[x/8] & bits[x%8]) != 0)
594
g[x/param_shrink] += 1;
599
if ((x_image = XCreateImage(x_disp,
600
DefaultVisual(x_disp,0), DefaultDepth(x_disp,0),
601
ZPixmap, 0, NULL, x_w, x_h, 8, 0)) == NULL){
605
z = x_image->bytes_per_line * x_h;
606
if ((x_image->data = (char*)malloc((z!=0)?z:1)) == NULL){
612
for (y = 0; y < pgm_h; y++){
613
for (x = 0; x < pgm_w; x++)
614
XPutPixel(x_image, x, y, x_pix_table[pgm_buff[pgm_w * y + x]]);
618
XPutImage(x_disp, x_win, x_gc_win, x_image, 0, 0,
619
param_margin_l, param_margin_t, pgm_w, pgm_h);
621
XDestroyImage(x_image);