/* * VF_BitOp.c * * Programmmed by Hirotsugu Kakugawa, Hiroshima University * E-Mail: h.kakugawa@computer.org * * Edition History * 22 Jan 1994 * 26 Jan 1994 * 8 Mar 1994 Removed dead code * 16 Mar 1995 Added NOP operation * */ /* This file is part of VFlib * * Copyright (C) 1994-1998 Hirotsugu KAKUGAWA. All rights reserved. * * This file is part of the VFlib Library. This library is free * software; you can redistribute it and/or modify it under the terms of * the GNU Library General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your * option) any later version. This library is distributed in the hope * that it will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Library General Public License for more details. * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Capabilities interpretable by bitop font objects:: "op" (str) -- Sequence of operations. Operation List:: (x, y, z must be one of S, D, R, which are SRC, DEST, REG, resp.) Nx : Reverse register x. (x := not x) Cx : Clear register x. (x <== 0) Exy : Exchange register x and y. (x <==> y) Lxy : Load register x with y. (x := y) Axyz : AND operation. (x := y & z) Oxyz : OR operation. (x := y | z) Xxyz : XOR operation. (x := y xor z) Hxy : Half-tone operation. (x := half y) Bxnnnn : Get bitmap of char nnnn (hexadecimal of 4 digits) of subfont specified by `sf' capability on register x. (x <= Char nnnn of subfont) SPACE, TAB, NEWLINE: Non-operation. "fo" (str) -- Font entry name which is `operated' by this class. "sf" (str) -- Subfont entry name for Bnnnn operation. */ #include #include #include #include #include #include "config.h" #include "defs.h" #include "_VF.h" #include "VF.h" #include "VFcap.h" struct s_font { int fd; char *Operations; /* op */ char *FontEntry; /* fo */ int FontId; /* fid for `fo' */ char *SubFontEntry; /* sf */ int SubFontId; /* fid for `sf' */ }; typedef struct s_font Font; Private int OpenFont(); Private int CloseFont(); Private int GetBitmap(); Private long* GetOutline(); Private long* GetOutline2(); Private int DrawOutline(); Private int FreeOutline(); Private int Link(); Private int Unlink(); Private int ReadCapa(); Private int BitOperations(); Private int HexCh2Int(); Private unsigned char *Reg(); Public FontObj* CreateFont_BitOp(ent) char *ent; { Font *font; FontObj *fobj; if ((font = (Font*) malloc(sizeof(Font))) == NULL) return NULL; /* ERR: malloc err */ font->fd = -1; if (ReadCapa(font, ent) < 0){ free(font); return NULL; } fobj = (FontObj*) malloc(sizeof(FontObj)); fobj->ClassID = VF_FONT_BITOP; fobj->Self = fobj; fobj->LinkCount = 0; fobj->OpenFont = OpenFont; fobj->CloseFont = CloseFont; fobj->GetBitmap = GetBitmap; fobj->GetOutline = GetOutline; fobj->GetOutline2 = GetOutline2; fobj->DrawOutline = DrawOutline; fobj->FreeOutline = FreeOutline; fobj->GetCharSet = NULL; fobj->GetEnc = NULL; fobj->Link = Link; fobj->Unlink = Unlink; fobj->Locals = (long) font; return fobj; } Private int OpenFont(obj) FontObj* obj; { Font *font; font = (Font*) obj->Locals; if (font->FontEntry == NULL) return -1; /* no font entry name */ if ((font->FontId = VF_OpenFont(font->FontEntry)) < 0) return -1; return 0; } Private int CloseFont(obj, fid) FontObj *obj; int fid; { Font *font; font = (Font*) obj->Locals; if (font->Operations != NULL) free(font->Operations); if (font->FontEntry != NULL) free(font->FontEntry); if (font->FontId != -1) VF_CloseFont(font->FontId); return 0; } Private int GetBitmap(obj, jiscode, w, h, bw, bo, bm_buf) FontObj *obj; int jiscode, w, h, bw, bo; char *bm_buf; { Font *font; font = (Font*) obj->Locals; if (font->FontId == -1) return -1; return BitOperations(0, obj, jiscode, (long*)NULL, w, h, bw, bo, bm_buf); } Private long* GetOutline(obj, jiscode) FontObj *obj; int jiscode; { long *outline; Font *font; font = (Font*) obj->Locals; if (font->FontId == -1) return NULL; outline = VF_GetOutline(jiscode, font->FontId); return outline; } Private long* GetOutline2(obj, jiscode) FontObj *obj; int jiscode; { long *outline; Font *font; font = (Font*) obj->Locals; if (font->FontId == -1) return NULL; outline = VF_GetOutline2(jiscode, font->FontId); return outline; } Private int DrawOutline(obj, vfdata, w, h, bw, bo, bm_buf) FontObj *obj; long *vfdata; int w; int h; int bw; int bo; char *bm_buf; { Font *font; font = (Font*) obj->Locals; if (font->FontId == -1) return -1; return BitOperations(1, obj, vfdata[0], vfdata, w, h, bw, bo, bm_buf); } Private int FreeOutline(obj, vfdata) FontObj *obj; long* vfdata; { Font *font; int val; font = (Font*) obj->Locals; if (font->FontId == -1) return -1; val = VF_FreeOutline(vfdata, font->FontId); return val; } Private int Link(obj) FontObj *obj; { obj->LinkCount = obj->LinkCount + 1; return obj->LinkCount; } Private int Unlink(obj) FontObj *obj; { obj->LinkCount = obj->LinkCount - 1; return obj->LinkCount; } static int ReadCapa(font, ent) Font *font; char *ent; { char *p; VFC_GetEntry(ent); if ((p = VFC_GetString(VFCE_OPERATIONS)) != NULL){ if ((font->Operations = malloc(strlen(p)+1)) == NULL) return -1; /* ERR: malloc err */ } else p = ""; strcpy(font->Operations, p); font->FontEntry = NULL; if ((p = VFC_GetString(VFCE_FONTENTRY)) != NULL){ if ((font->FontEntry = malloc(strlen(p)+1)) == NULL) return -1; /* ERR: malloc err */ strcpy(font->FontEntry, p); } font->SubFontId = -1; font->SubFontEntry = NULL; if ((p = VFC_GetString(VFCE_SUBFONTENTRY)) != NULL){ if ((font->SubFontEntry = malloc(strlen(p)+1)) == NULL) return -1; /* ERR: malloc err */ strcpy(font->SubFontEntry, p); } return 0; } Private int BitOperations(flag, obj, jiscode, vfdata, w, h, bw, bo, bm_buf) int flag; FontObj *obj; int jiscode, w, h, bw, bo; long *vfdata; unsigned char *bm_buf; { int val, rast, yy1, yy2, x, y, pc, ch, i; Font *font; unsigned char *src, *dest, *reg, *xreg, *yreg, *zreg, d; char *prog; Private unsigned char Mask1[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; Private unsigned char Mask2[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01}; Private unsigned char Mask3[] = { 0xff, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; font = (Font*) obj->Locals; if (font->FontId == -1) return -1; if (font->Operations == NULL) return 0; rast = (w+7)/8; src = (unsigned char*) malloc(h*rast); dest = (unsigned char*) malloc(h*rast); reg = (unsigned char*) malloc(h*rast); if ((src == NULL) || (dest == NULL) || (reg == NULL)){ if (src != NULL) free(src); if (dest != NULL) free(dest); if (reg != NULL) free(reg); return -1; } bzero(src, rast*h); bzero(dest, rast*h); bzero(reg, rast*h); /* Get DEST */ yy1 = 0; yy2 = 0; for (y = 0; y < h; y++){ for (x = 0; x < rast; x++) dest[yy2 + x] = (bm_buf[yy1 + x] << bo) | (bm_buf[yy1 + x+1] >> (8-bo)) ; yy1 += bw; yy2 += rast; } /* Get SRC */ if (flag == 0) val = VF_GetBitmap(jiscode, font->FontId, w, h, rast, 0, src); else val = VF_DrawOutline(vfdata, font->FontId, w, h, rast, 0, src); if (val < 0) goto ExitLabel; pc = 0; prog = font->Operations; while (prog[pc] != '\0'){ switch (prog[pc++]){ case 'N': /* x := not x */ xreg = Reg(prog[pc++], dest, src, reg); for (yy1 = 0, y = 0; y < h; y++, yy1 += rast){ for (x = 0; x < rast; x++) xreg[yy1 + x] = ~xreg[yy1 + x]; } break; case 'C': /* x <= 0 */ xreg = Reg(prog[pc++], dest, src, reg); for (yy1 = 0, y = 0; y < h; y++){ for (x = 0; x < rast; x++) xreg[yy1 + x] = 0x00; yy1 += rast; } break; case 'E': /* x <==> y */ xreg = Reg(prog[pc++], dest, src, reg); yreg = Reg(prog[pc++], dest, src, reg); for (yy1 = 0, y = 0; y < h; y++, yy1 += rast){ for (x = 0; x < rast; x++){ d = xreg[yy1 + x]; xreg[yy1 + x] = yreg[yy1 + x]; yreg[yy1 + x] = d; } } break; case 'L': /* x := y */ xreg = Reg(prog[pc++], dest, src, reg); yreg = Reg(prog[pc++], dest, src, reg); for (yy1 = 0, y = 0; y < h; y++, yy1 += rast){ for (x = 0; x < rast; x++) xreg[yy1 + x] = yreg[yy1 + x]; } break; case 'A': /* x := y & z */ xreg = Reg(prog[pc++], dest, src, reg); yreg = Reg(prog[pc++], dest, src, reg); zreg = Reg(prog[pc++], dest, src, reg); for (yy1 = 0, y = 0; y < h; y++, yy1 += rast){ for (x = 0; x < rast; x++) xreg[yy1 + x] = yreg[yy1 + x] & zreg[yy1 + x]; } break; case 'O': /* x := y | z */ xreg = Reg(prog[pc++], dest, src, reg); yreg = Reg(prog[pc++], dest, src, reg); zreg = Reg(prog[pc++], dest, src, reg); for (yy1 = 0, y = 0; y < h; y++, yy1 += rast){ for (x = 0; x < rast; x++) xreg[yy1 + x] = yreg[yy1 + x] | zreg[yy1 + x]; } break; case 'X': /* x := y xor z */ xreg = Reg(prog[pc++], dest, src, reg); yreg = Reg(prog[pc++], dest, src, reg); zreg = Reg(prog[pc++], dest, src, reg); for (yy1 = 0, y = 0; y < h; y++){ for (x = 0; x < rast; x++) xreg[yy1 + x] = yreg[yy1 + x] ^ zreg[yy1 + x]; yy1 += rast; } break; case 'B': xreg = Reg(prog[pc++], dest, src, reg); if (font->SubFontId == -1){ /* DEMAND OPEN */ if (font->SubFontEntry == NULL){ val = -1; goto ExitLabel; } if ((font->SubFontId = VF_OpenFont(font->SubFontEntry)) < 0){ free(font->SubFontEntry); font->SubFontEntry = NULL; val = -1; goto ExitLabel; } } ch = 0; for (i = 1; i <= 4; i++) ch = ch*0x10 + HexCh2Int(prog[pc++]); bzero(src, rast*h); if ((val = VF_GetBitmap(ch, font->SubFontId, w, h, rast, 0, xreg)) < 0) goto ExitLabel; break; case 'H': /* x := half y */ xreg = Reg(prog[pc++], dest, src, reg); yreg = Reg(prog[pc++], dest, src, reg); { unsigned char hm; int m; static unsigned char hmask[2] = {0xaa, 0x55}; m = 0; for (yy1 = 0, y = 0; y < h; y++){ hm = hmask[m]; for (x = 0; x < rast; x++) xreg[yy1 + x] = yreg[yy1 + x] & hm; yy1 += rast; m = (m+1)%2; } } break; case ' ': /* NOP */ case '\t': case '\n': case ',': break; default: val = -1; /* ILL OPERATION */ goto ExitLabel; } } /* Set DEST */ for (yy1 = 0, yy2 = 0, y = 0; y < h; y++){ bm_buf[yy1] &= Mask1[bo]; bm_buf[yy1+rast-1] &= Mask2[(bo+w)%8]; dest[yy2 + rast-1] &= Mask3[w % 8]; for (x = 0; x < rast-1; x++){ d = dest[yy2 + x]; bm_buf[yy1 + x] |= d >> bo; bm_buf[yy1 + x+1] = d << (8-bo); } d = dest[yy2 + rast - 1]; bm_buf[yy1 + x] |= d >> bo; bm_buf[yy1 + rast-1] |= d << (8-bo); yy1 += bw; yy2 += rast; } ExitLabel: free(src); free(dest); free(reg); return val; } Private int HexCh2Int(ch) char ch; { typedef struct { char xch; int ich; } _Tbl; static _Tbl Table[] = { {'0', 0}, {'1', 1}, {'2', 2}, {'3', 3}, {'4', 4}, {'5', 5}, {'6', 6}, {'7', 7}, {'8', 8}, {'9', 9}, {'a', 10}, {'b', 11}, {'c', 12}, {'d', 13}, {'e', 14}, {'f', 15}, {'S', -1} /* sentinel */ }; int i; char ch2; ch2 = tolower(ch); Table[16].xch = ch2; i = 0; while (Table[i].xch != ch2) /* THIS IS STUPID, BUT PORTABLE */ i++; return Table[i].ich; } Private unsigned char* Reg(r, dest, src, reg) char r; unsigned char *dest, *src, *reg; { switch (r){ case 'D': case 'd': return dest; case 'S': case 's': return src; case 'R': case 'r': return reg; default: break; } return NULL; }