/******************************************************* * Zeit Shotai Kurabu interface routine for xdvi pl.17 * Written by Y. Hayashi (hayashi@me.aoyama.ac.jp) ******************************************************/ /* #include "xdvi.h" */ #include "xdvi-config.h" #ifndef X_NOT_STDC_ENV #include #endif #include "jtfm.h" #ifndef SEEK_SET #define SEEK_SET 0 #endif #ifdef USE_ZEIT /* static void */ void dispfont(bm) struct bitmap *bm; { int w, h; unsigned char mask; unsigned char *p; for (h = 0; h < bm->h; ++h) { p = (unsigned char *) &bm->bits[bm->bytes_wide * h]; for (w = 0; w < bm->w; p++) { for (mask = 0x80; w < bm->w && mask != 0; w++, mask >>= 1) Putc(*p & mask ? '*' : '.', stderr); Putc('|', stderr); } Putc('\n', stderr); } } #if !defined(WORDS_BIGENDIAN) && !defined(USE_PXL) static unsigned char _reverse_byte[0x100] = { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff }; #endif /* WORDS_BIGENDIAN */ #define jis2ccode(jis) (((jis) / 256 - 0x21) * 0x5e + ((jis) % 256 - 0x21)) #if !defined(WORDS_BIGENDIAN) || (BMBYTES == 4) || (BMBYTES == 2) void adj_ZEIT_bitmap(bm) struct bitmap *bm; { int bwidth; int n; unsigned char *p; #if (BMBYTES == 4) || (BMBYTES == 2) int m, m1, m2; unsigned char *bits; BMUNIT bmunit, *q; #endif bwidth = (bm->w + 7) / 8; #ifndef WORDS_BIGENDIAN n = bwidth * bm->h; p = (unsigned char *) bm->bits; while (n--) { *p = _reverse_byte[*p]; ++p; } #endif #if (BMBYTES == 4) || (BMBYTES == 2) bits = (unsigned char *) xmalloc(bm->bytes_wide * bm->h); m1 = bwidth / BMBYTES; m2 = bwidth % BMBYTES; for (n = 0; n < bm->h; n++) { p = (unsigned char *) &bm->bits[n * bwidth]; q = (BMUNIT *) &bits[n * bm->bytes_wide]; for (m = 0; m < m1; m++, p += BMBYTES, q++) { #ifndef WORDS_BIGENDIAN #if (BMBYTES == 4) bmunit = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); #else bmunit = p[0] | (p[1] << 8); #endif #else #if (BMBYTES == 4) bmunit = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; #else bmunit = (p[0] << 8) | p[1]; #endif #endif *q = bmunit; } switch (m2) { case 0: break; case 1: #ifndef WORDS_BIGENDIAN bmunit = p[0]; #else #if (BMBYTES == 4) bmunit = p[0] << 24; #else bmunit = p[0] << 8; #endif #endif *q = bmunit; break; #if (BMBYTES == 4) case 2: #ifndef WORDS_BIGENDIAN bmunit = p[0] | (p[1] << 8); #else bmunit = (p[0] << 24) | (p[1] << 16); #endif *q = bmunit; break; case 3: #ifndef WORDS_BIGENDIAN bmunit = p[0] | (p[1] << 8) | (p[2] << 16); #else bmunit = (p[0] << 24) | (p[1] << 16) | (p[2] << 8); #endif *q = bmunit; break; #endif } } bcopy(bits, bm->bits, bm->bytes_wide * bm->h); free(bits); #endif } #endif static int trim_side_blanks_in_ZEIT_bitmap(bm, width) struct bitmap *bm; int width; { int bwidth; int w, h; int ll, rr, l, r; int delta, d1, d2; unsigned char u, mask; int found = False; bwidth = (bm->w + 7) / 8; ll = bm->w; rr = 0; for (h = 0; h < bm->h; h++) { for (w = 0; w < bwidth; w++) if (u = bm->bits[h * bwidth + w]) { found = True; for (l = w * 8, mask = 0x80; (u & mask) == 0; l++, mask >>= 1); if (l < ll) ll = l; break; } for (w = bwidth - 1; 0 <= w; w--) if (u = bm->bits[h * bwidth + w]) { found = True; for (r = w * 8 + 7, mask = 0x01; (u & mask) == 0; r--, mask <<= 1); if (rr < r) rr = r; break; } } if (!found) return 0; #ifdef DEBUGZEIT if (rr - ll + 1 > width) { Fprintf(stderr, "Cannot trim side blanks; ll=%d, rr=%d, width=%d\n", ll, rr, width); dispfont(bm); return rr - ll + 1 - width; } #endif /* DEBUGZEIT */ delta = (ll + rr) / 2 - (width / 2); if (delta == 0) return; else if (delta > 0) { d1 = delta / 8; d2 = delta % 8; for (h = 0; h < bm->h; h++) { unsigned char *p = (unsigned char *) &bm->bits[h * bwidth]; if (d2 > 0) { for (w = 0; w < bwidth - 1; w++) { unsigned int word; word = *(p + w) << 8 | *(p + w + 1); word <<= d2; *(p + w) = word >> 8; } *(p + bwidth - 1) = *(p + bwidth - 1) << d2; } for (w = 0; w < bwidth; w++) *(p + w) = (w < bwidth - d1) ? *(p + w + d1) : 0; } } else { d1 = -delta / 8; d2 = -delta % 8; for (h = 0; h < bm->h; h++) { unsigned char *p = (unsigned char *) &bm->bits[h * bwidth]; if (d2 > 0) { for (w = bwidth - 1; 0 < w; w--) { unsigned int word; word = *(p + w - 1) << 8 | *(p + w); word >>= d2; *(p + w) = word & 0xff; } *p = *p >> d2; } for (w = bwidth - 1; w <= 0; w++) *(p + w) = (w > d1) ? *(p + w - d1) : 0; } } return 0; } #ifdef PTEX static int trim_tate_blanks_in_ZEIT_bitmap(bm, height) struct bitmap *bm; int height; { int bwidth; int w, h; int t, b; int delta; int found = False; bwidth = (bm->w + 7) / 8; t = bm->h; b = 0; for (h = 0; h < bm->h; h++) for (w = 0; w < bwidth; w++) if (bm->bits[h * bwidth + w]) { found = True; t = h; break; } for (h = bm->h - 1; 0 <= h; h--) for (w = 0; w < bwidth; w++) if (bm->bits[h * bwidth + w]) { found = True; b = h; break; } if (!found) return 0; #ifdef DEBUGZEIT if (b - t + 1 > height) { Fprintf(stderr, "Cannot trim tate blanks; t=%d, b=%d, height=%d\n", t, b, height); dispfont(bm); return rr - ll + 1 - width; } #endif /* DEBUGZEIT */ delta = (height / 2) - (t + b) / 2; if (delta == 0) return; else if (delta > 0) { for (h = bm->h - delta - 1; 0 <= h; h--) { unsigned char *p = (unsigned char *) &bm->bits[h * bwidth]; unsigned char *p1 = (unsigned char *) &bm->bits[(h + delta) * bwidth]; for (w = 0; w < bwidth; w++) *(p1 + w) = *(p + w); } for (h = 0; h < delta; h++) { unsigned char *p = (unsigned char *) &bm->bits[h * bwidth]; for (w = 0; w < bwidth; w++) *(p + w) = 0; } } else { delta = -delta; for (h = 0; h < bm->h - delta; h++) { unsigned char *p = (unsigned char *) &bm->bits[h * bwidth]; unsigned char *p1 = (unsigned char *) &bm->bits[(h + delta) * bwidth]; for (w = 0; w < bwidth; w++) *(p + w) = *(p1 + w); } for (h = bm->h - delta; h < bm->h; h++) { unsigned char *p = (unsigned char *) &bm->bits[h * bwidth]; for (w = 0; w < bwidth; w++) *(p + w) = 0; } } return 0; } int auto_shift(bm) struct bitmap *bm; { int x, y, rc; BMUNIT b, m; BMUNIT *ptr; ptr = (BMUNIT *)bm->bits; for (x = 0; x < bm->bytes_wide / BMBYTES; x++, ptr++) { b = 0; for (y = 0; y < bm->h; y++) b |= ptr[y * bm->bytes_wide / BMBYTES]; if (b) break; } x *= BMBITS; #ifndef WORDS_BIGENDIAN m = (1 << 0); while ((b & m) == 0 && m) { x++; m <<= 1; } #else m = (1 << (BMBITS-1)); while ((b & m) == 0 && m) { x++; m >>= 1; } #endif rc = -x; ptr = (BMUNIT *)(bm->bits + bm->bytes_wide) - 1; for (x = 0; x < bm->bytes_wide / BMBYTES; x++, ptr--) { b = 0; for (y = 0; y < bm->h; y++) b |= ptr[y * bm->bytes_wide / BMBYTES]; if (b) break; } x *= BMBITS; #ifdef WORDS_BIGENDIAN m = (1 << 0); while ((b & m) == 0 && m) { x++; m <<= 1; } #else m = (1 << (BMBITS-1)); while ((b & m) == 0 && m) { x++; m >>= 1; } #endif x -= BMBITS - (bm->w % BMBITS); rc += x; return rc; } #endif /* PTEX */ #ifndef PTEX static void get_ZEIT_font(fontp, code) struct font *fontp; int code; #else static void get_ZEIT_font(fontp, code, code2, flag) struct font *fontp; int code, code2, flag; #endif { struct bitmap *bm; int rc, bwidth; bm = &fontp->kglyph[jisindex(code)]->bitmap; bwidth = (bm->w + 7) / 8; bzero(bm->bits, bwidth * bm->h); #ifdef PTEX if (!flag && bm->w < bm->h) { #else /* !PTEX */ if (bm->w < bm->h) { #endif /* PTEX */ struct bitmap bitmap; int bwidth2; int w, h; bitmap.w = bitmap.h = bm->h; retry_side: bwidth2 = (bitmap.w + 7) / 8; alloc_bitmap(&bitmap); bzero(bitmap.bits, bwidth2 * bitmap.h); #ifdef PTEX VF_GetBitmap(code2, fontp->vf, bitmap.w, bitmap.h, bwidth2, 0, bitmap.bits); #else VF_GetBitmap(code, fontp->vf, bitmap.w, bitmap.h, bwidth2, 0, bitmap.bits); #endif rc = trim_side_blanks_in_ZEIT_bitmap(&bitmap, bm->w); if (rc) { free(bitmap.bits); bitmap.w -= rc; goto retry_side; } for (h = 0; h < bm->h; h++) for (w = 0; w < bwidth; w++) bm->bits[h * bwidth + w] = bitmap.bits[h * bwidth2 + w]; free(bitmap.bits); #ifdef PTEX } else if (flag && bm->w > bm->h) { struct bitmap bitmap; int w, h; bitmap.w = bitmap.h = bm->w; retry_tate: alloc_bitmap(&bitmap); bzero(bitmap.bits, bwidth * bitmap.h); VF_GetBitmap(code2, fontp->vf, bitmap.w, bitmap.h, bwidth, 0, bitmap.bits); rc = trim_tate_blanks_in_ZEIT_bitmap(&bitmap, bm->h); if (rc) { free(bitmap.bits); bitmap.h -= rc; goto retry_tate; } for (h = 0; h < bm->h; h++) for (w = 0; w < bwidth; w++) bm->bits[h * bwidth + w] = #if 1 bitmap.bits[h * bwidth + w]; #else bitmap.bits[(h + bm->w - bm->h) * bwidth + w]; #endif free(bitmap.bits); #endif /* PTEX */ } else { #ifdef PTEX VF_GetBitmap(code2, fontp->vf, bm->w, bm->h, bwidth, 0, bm->bits); #else VF_GetBitmap(code, fontp->vf, bm->w, bm->h, bwidth, 0, bm->bits); #endif } } static void read_ZEIT_char(fontp, ch) struct font *fontp; int ch; { struct bitmap *bm; struct glyph *g; int ch2; #ifdef PTEX int ch3; extern void rotate_bitmap(); #endif #ifdef DEBUGZEIT if (list_fonts) Fprintf(stderr, "zeit raster: %x in %s\n", ch, fontp->fontname); #endif /* DEBUGZEIT */ ch2 = jisindex(ch); if (NULL == fontp->kglyph[ch2]) { fontp->kglyph[ch2] = (struct glyph *) xmalloc(sizeof(struct glyph)); g = fontp->kglyph[ch2]; g->bitmap2.bits = NULL; #ifdef GREY g->pixmap2 = NULL; #endif g->bitmap3.bits = NULL; if (fontp->kglyph[0] == NULL) { Fprintf(stderr, "Unexpected error in \"read_ZEIT_char()\"\n"); exit(1); } g->bitmap.w = fontp->kglyph[0]->bitmap.w; g->bitmap.h = fontp->kglyph[0]->bitmap.h; g->x = fontp->kglyph[0]->x; g->y = fontp->kglyph[0]->y; g->dvi_adv = fontp->kglyph[0]->dvi_adv; } bm = &fontp->kglyph[ch2]->bitmap; #ifdef PTEX if (!fontp->tate) { if (ch >= 0x2121 && ch < 0x217f) ch3 = ch - 0x2121; else if (ch >= 0x2221 && ch < 0x222f) ch3 = ch - 0x2221 + (0x7f - 0x21); else if (ch >= 0x2421 && ch < 0x246f) ch3 = ch - 0x2421 + (0x7f - 0x21) + (0x2f - 0x21); else if (ch >= 0x2521 && ch < 0x2577) ch3 = ch - 0x2521 + (0x7f - 0x21) + (0x2f - 0x21) + (0x6f - 0x21); else ch3 = 0; if (fontp->dir && TateCorrectionTable[ch3].code != TCOR_ROTATE) { int tmp; tmp = bm->h; bm->h = bm->w; bm->w = tmp; alloc_bitmap(bm); if (TateCorrectionTable[ch3].code >= 0x2121) get_ZEIT_font(fontp, ch, TateCorrectionTable[ch3].code, 1); else get_ZEIT_font(fontp, ch, ch, 1); } else { alloc_bitmap(bm); get_ZEIT_font(fontp, ch, ch, 0); } } else { if (fontp->dir) { int tmp; tmp = bm->h; bm->h = bm->w; bm->w = tmp; alloc_bitmap(bm); get_ZEIT_font(fontp, ch, ch, 1); } else { alloc_bitmap(bm); get_ZEIT_font(fontp, ch, ch, 0); } } #else /* !PTEX */ alloc_bitmap(bm); get_ZEIT_font(fontp, ch); #endif /* PTEX */ #ifdef DEBUGZEIT dispfont(bm); #endif /* DEBUGZEIT */ #if !defined(WORDS_BIGENDIAN) || (BMBYTES == 4) || (BMBYTES == 2) adj_ZEIT_bitmap(bm); #endif #ifdef PTEX fontp->kglyph[ch2]->tdir = fontp->dir; if (fontp->dir) { int tmp; tmp = fontp->kglyph[ch2]->x; fontp->kglyph[ch2]->x = fontp->kglyph[ch2]->y; fontp->kglyph[ch2]->y = tmp; if (!fontp->tate) switch (TateCorrectionTable[ch3].code) { case TCOR_SHIFT: fontp->kglyph[ch2]->x -= TateCorrectionTable[ch3].x * fontp->kglyph[0]->bitmap.h / 128; fontp->kglyph[ch2]->y += TateCorrectionTable[ch3].y * fontp->kglyph[0]->bitmap.h / 128; break; case TCOR_AUTOSHIFT: tmp = auto_shift(bm); fontp->kglyph[ch2]->x -= tmp; break; case TCOR_ROTATE: rotate_bitmap(bm); break; } } #endif /* PTEX */ } static void bbox(buf, size) char *buf; int size; { int n; for (n = 0; n < size; ++n) buf[n] = 0xff; } int read_ZEIT_index(fontp) register struct font *fontp; { struct jfm *j; struct bitmap *bm; double dimconv; int n, index, code, width, height, depth; fontp->read_char = read_ZEIT_char; fontp->kglyph = (struct glyph **) xmalloc(sizeof(struct glyph *) * KTABLESIZE); bzero((char *)fontp->kglyph, sizeof(struct glyph *) * KTABLESIZE); dimconv = fontp->dimconv; if (NULL == (j = read_jfm(fontp->file, fontp->fontname))) return -1; if (-1 == open_ZEIT_font(fontp, iskanjifont(fontp->fontname))) return -1; for (n = 0; n < j->table[J_NT]; ++n) { code = jisindex(j->type[n].code); fontp->kglyph[code] = (struct glyph *) xmalloc(sizeof(struct glyph)); index = j->type[n].index; width = j->width[j->info[index].width_ix]; height= j->height[j->info[index].height_depth_ix >> 4]; depth = j->depth[j->info[index].height_depth_ix & 0xf]; bm = &(fontp->kglyph[code]->bitmap); bm->w = (int) (dimconv * width) >> 16; bm->h = (int) (dimconv * (height + depth)) >> 16; bm->bits = NULL; fontp->kglyph[code]->bitmap2.bits = NULL; #ifdef GREY fontp->kglyph[code]->pixmap2 = NULL; #endif fontp->kglyph[code]->bitmap3.bits = NULL; fontp->kglyph[code]->x = 0; fontp->kglyph[code]->y = (int) (dimconv * height) >> 16; fontp->kglyph[code]->dvi_adv = dimconv * width; } bm = &(fontp->kglyph[0]->bitmap); alloc_bitmap(bm); bbox(bm->bits, bm->bytes_wide * bm->h); } extern struct vfontmap *first_ptr; int open_ZEIT_font(fontp, shotai) struct font *fontp; int shotai; { char *path; int i, *fd; struct vfontmap *current_ptr; current_ptr = first_ptr; for(i = 0; i < shotai - 1 && current_ptr; i++) current_ptr = current_ptr->next_ptr; path = current_ptr->vfname; fd = &(current_ptr->flag); if (-1 == *fd && -1 == (*fd = VF_OpenFont(path))) return -1; fontp->vf = *fd; #ifdef PTEX fontp->tate = current_ptr->tate ? 1 : 0; #endif return 0; } #endif /* USE_ZEIT */ #ifdef KANJI struct jfm * read_jfm(fp, fn) FILE *fp; char *fn; { struct jfmchain { struct jfmchain *next; struct jfm *jfm; }; static struct jfmchain *jfmtop = NULL; struct jfmchain *jcp, *new; for (jcp = jfmtop; jcp; jcp = jcp->next) if (0 == strcmp(fn, jcp->jfm->fn)) return jcp->jfm; new = (struct jfmchain *) xmalloc(sizeof(struct jfmchain)); new->next = NULL; new->jfm = (struct jfm *) xmalloc(sizeof(struct jfm)); strcpy(new->jfm->fn, fn); if (read_jfm0(fp, new->jfm)) { Fprintf(stderr, "Cannot open metric file: %s\n", fn); free(new->jfm); free(new); return (struct jfm *) NULL; } if (NULL == jfmtop) { jfmtop = new; } else { for (jcp = jfmtop; jcp->next; jcp = jcp->next) ; jcp->next = new; } return new->jfm; } /**** read_jfm0: borrowed from jxdvi-NEWS ****/ int read_jfm0(fp, j) FILE *fp; struct jfm *j; { int i; fseek(fp, 0L, SEEK_SET); /* read jfm table field. */ for (i = 0; i <= J_NP; i++) j->table[i] = (short) two(fp); /* read jfm header */ j->check_sum = four(fp); j->design_size = four(fp); fseek(fp, (long) (4 * (j->table[J_LH] - 2)), 1); /* read jfm char_type */ j->type = (struct jfm_char_type *) xmalloc(sizeof(struct jfm_char_type) * j->table[J_NT]); for (i=0; i < j->table[J_NT]; i++) { j->type[i].code = (short) two(fp); j->type[i].index = (short) two(fp); } /* read jfm char_info */ j->info = (struct jfm_char_info *) xmalloc(sizeof(struct jfm_char_info) * (j->table[J_EC] + 1)); for (i = 0; i <= j->table[J_EC]; i++) { j->info[i].width_ix = (unsigned char) one(fp); j->info[i].height_depth_ix = (unsigned char) one(fp); j->info[i].italic_ix_tag = (unsigned char) one(fp); j->info[i].remainder_ix = (unsigned char) one(fp); } /* read jfm width */ j->width = (unsigned long *) xmalloc(sizeof(unsigned long) * j->table[J_NW]); for (i = 0; i < j->table[J_NW]; i++) j->width[i] = four(fp); /* read jfm height */ j->height = (unsigned long *) xmalloc(sizeof(unsigned long) * j->table[J_NH]); for (i = 0; i < j->table[J_NH]; i++) j->height[i] = four(fp); /* read jfm depth */ j->depth = (unsigned long *) xmalloc(sizeof(unsigned long) *j->table[J_ND]); for (i = 0; i < j->table[J_ND]; i++) j->depth[i] = four(fp); /* read jfm italic */ j->italic = (unsigned long *) xmalloc(sizeof(unsigned long) * j->table[J_NI]); for (i = 0; i < j->table[J_NI]; i++) j->italic[i] = four(fp); return 0; } #endif /* KANJI */