han2gd.c

Modified at 1999. 7.20 14:02
Printed at 1999. 7.20 14:05

  1: /*
  2:  * Han2gd.c
  3:  *
  4:  * made by scgyong@nownuri.net
  5:  *
  6:  * you can modify and redistribute this source
  7:  * under the rule of Copy-Left, GNU
  8:  */
  9: 
 10: #include <stdio.h>
 11: #include <string.h>
 12: #include <stdlib.h>
 13: 
 14: // for gd library
 15: #include <gd.h>
 16: 
 17: #define MAXLINEWIDTH 80
 18: #define BUFWIDTH (MAXLINEWIDTH + 2)
 19: 
 20: #define MAXHEIGHT 10
 21: 
 22: #define MAXGIFWIDTH     (8*BUFWIDTH)
 23: #define MAXGIFHEIGHT   (16*MAXHEIGHT)
 24: 
 25: #define CHAR_ON  '0'
 26: #define CHAR_OFF ' '
 27: 
 28: typedef enum { FALSE, TRUE } BOOL;
 29: typedef unsigned short WORD;
 30: typedef unsigned char BYTE;
 31: 
 32: #define HIBYTE(w) ((BYTE)(((WORD)(w) >> 8) & 0xFF))
 33: #define LOBYTE(w) ((BYTE)(w))
 34: 
 35: #define MAKEWORD(a, b) \
 36:     ((WORD) (((BYTE) (a)) | ((WORD) ((BYTE) (b))) << 8))
 37: 
 38: #define HAN_FIR(w) (((w) >> 10) & 0x1F)
 39: #define HAN_MID(w) (((w) >> 5)  & 0x1F)
 40: #define HAN_LAS(w) ( (w)        & 0x1F)
 41: 
 42: #define OFFSET_MID (20 * 8)
 43: #define OFFSET_LAS (OFFSET_MID + 22 * 4)
 44: 
 45: static char szHFileName[] = "hangul.fnt";
 46: static char szEFileName[] = "english.fnt";
 47: 
 48: static unsigned short hfont[8*20 + 4*22 + 4*27][16];
 49: static unsigned char  efont[96][16];
 50: 
 51: static gdImagePtr img;
 52: static int black, white;
 53: 
 54: static int  chSaved;
 55: static int  nChar;
 56: static int  cyChar;
 57: 
 58: static int dirty_left;
 59: static int dirty_top;
 60: static int dirty_right;
 61: static int dirty_bottom;
 62: 
 63: static const int nFirTable[32] = {
 64:      0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
 65:     15, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
 66: };
 67: static const int nMidTable[32] = {
 68:     0,  0,  0,  1,  2,  3,  4,  5,  0,  0,  6,  7,  8,  9, 10, 11,
 69:     0,  0, 12, 13, 14, 15, 16, 17,  0,  0, 18, 19, 20, 21,  0,  0
 70: };
 71: static const int nLasTable[32] = {
 72:      0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
 73:     15, 16,  0, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,  0,  0
 74: };
 75: 
 76: static const int nFirRef[22][2] = {
 77:     0, 0, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 1, 6, 3, 7,
 78:     3, 7, 3, 7, 1, 6, 2, 6, 4, 7, 4, 7, 4, 7, 2, 6, 1, 6, 3, 7, 0, 5
 79: };
 80: 
 81: static const int nMidRef[20] = {
 82:     1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1
 83: };
 84: 
 85: static const int nLasRef[22] = {
 86:     0, 0, 2, 0, 2, 1, 2, 1, 2, 3, 0, 2, 1, 3, 3, 1, 2, 1, 3, 3, 1, 1
 87: };
 88: 
 89: BOOL LoadFont(char *szFileName, void *dest, int cbSize)
 90: {
 91:     FILE *pFile;
 92:     int   ret;
 93: 
 94:     pFile = fopen(szFileName, "rb");
 95:     if (!pFile) {
 96:         printf("Font File %s Open Error\n", szFileName);
 97:         return FALSE;
 98:     }
 99: 
100:     ret = fread(dest, cbSize, 1, pFile);
101: 
102:     fclose(pFile);
103: 
104:     return ret ? TRUE : FALSE;
105: }
106: 
107: BOOL InitProgram(void)
108: {
109:     BOOL ret;
110: 
111:     ret = LoadFont(szHFileName, hfont, sizeof (hfont));
112:     if (!ret)
113:         return FALSE;
114: 
115:     ret = LoadFont(szEFileName, efont, sizeof (efont));
116:     if (!ret)
117:         return FALSE;
118: 
119:     img = gdImageCreate(MAXGIFWIDTH, MAXGIFHEIGHT);
120:     if (!img)
121:         return FALSE;
122: 
123:     black = gdImageColorAllocate(img, 0x00, 0x00, 0x00);
124:     white = gdImageColorAllocate(img, 0xFF, 0xFF, 0xFF);
125: 
126:     return TRUE;
127: }
128: 
129: BOOL DestroyBuffer(void)
130: {
131:     if (img) {
132:         gdImageDestroy(img);
133:     }
134: 
135:     return TRUE;
136: }
137: 
138: BOOL PrintBuffer(void)
139: {
140:     int cx, cy;
141:     gdImagePtr nimg;
142: 
143:     if (dirty_left > 0)
144:         dirty_left--;
145:     if (dirty_top > 0)
146:         dirty_top--;
147:     if (dirty_right < MAXGIFWIDTH)
148:         dirty_right++;
149:     if (dirty_bottom < MAXGIFHEIGHT)
150:         dirty_bottom++;
151: 
152:     cx = dirty_right - dirty_left + 1;
153:     cy = dirty_bottom - dirty_top + 1;
154: 
155:     nimg = gdImageCreate(cx, cy);
156:     if (!nimg) {
157:         return FALSE;
158:     }
159: 
160:     gdImageCopy(nimg, img, 0, 0, dirty_left, dirty_top, cx, cy);
161: 
162:     gdImagePng(nimg, stdout);
163:     //gdImageGif(nimg, stdout);
164: 
165:     gdImageDestroy(nimg);
166: 
167:     return TRUE;
168: }
169: 
170: BOOL ClearBuffer(void)
171: {
172:     gdImageFilledRectangle(img, 0, 0, MAXGIFWIDTH, MAXGIFHEIGHT, white);
173:     dirty_left = MAXGIFWIDTH;
174:     dirty_top = MAXGIFHEIGHT;
175:     dirty_right = 0;
176:     dirty_bottom = 0;
177: 
178:     nChar = 0;
179: 
180:     return TRUE;
181: }
182: 
183: BOOL SetBufOn(int x, int y)
184: {
185:     int img_x = nChar * 8 + x;
186:     int img_y = cyChar * 16 + y;
187: 
188:     gdImageSetPixel(img, img_x, img_y, black);
189: 
190:     if (dirty_left > img_x)
191:         dirty_left = img_x;
192:     if (dirty_right < img_x)
193:         dirty_right = img_x;
194:     if (dirty_top > img_y)
195:         dirty_top = img_y;
196:     if (dirty_bottom < img_y)
197:         dirty_bottom = img_y;
198: 
199:     return TRUE;
200: }
201: 
202: BOOL CheckForLineEnd(int nWidth)
203: {
204:     nChar += nWidth;
205: 
206:     if (nWidth <= 0 || nChar >= MAXLINEWIDTH) {
207:         nChar = 0;
208:         cyChar++;
209: 
210:         if (cyChar >= MAXHEIGHT) {
211:             return FALSE;
212:         }
213:     }
214: 
215:     return TRUE;
216: }
217: 
218: BOOL PutSingleByte(int ch)
219: {
220:     int src, x, y;
221: 
222:     if (ch == '\n') {
223:         return CheckForLineEnd(0);
224:     }
225: 
226:     if (ch < 32) {
227:         ch = 32;
228:     }
229: 
230:     ch -= 32;
231: 
232:     for (y = 0; y < 16; y++) {
233:         src = efont[ch][y];
234:         for (x = 0; x < 8; x++) {
235:             if (src & 0x80)
236:                 SetBufOn(x, y);
237:             src <<= 1;
238:         }
239:     }
240: 
241:     if (!CheckForLineEnd(1)) {
242:         return FALSE;
243:     }
244: 
245:     return TRUE;
246: }
247: 
248: static BOOL memor(unsigned short *dest, unsigned short *src)
249: {
250:     int i = 16;
251: 
252:     while (i--) {
253:         *dest++ |= *src++;
254:     }
255: 
256:     return TRUE;
257: }
258: 
259: BOOL PutDoubleByte(int wChar)
260: {
261:     unsigned short buf[16];
262:     int            src, x, y;
263: 
264:     int     cfir, cmid, clas;
265:     int     ofir, omid, olas;
266:     int     mfir, mmid, mlas;
267: 
268:     //
269:     // counters
270:     //
271:     cfir = nFirTable[HAN_FIR(wChar)];
272:     cmid = nMidTable[HAN_MID(wChar)];
273:     clas = nLasTable[HAN_LAS(wChar)];
274: 
275:     //
276:     // index offsets
277:     //
278:     ofir = nFirRef[cmid][clas != 0];
279:     omid = nMidRef[cfir] + (clas ? 2 : 0);
280:     olas = nLasRef[cmid];
281: 
282:     //
283:     // memory offsets
284:     //
285:     mfir = ofir * 20 + cfir;
286:     mmid = omid * 22 + cmid;
287:     mlas = olas * 28 + clas;
288: 
289:     if (cfir) {
290:         memcpy(buf, hfont[mfir], 32);
291:     } else {
292:         memset(buf, 0, 32);
293:     }
294: 
295:     if (cmid) {
296:         memor(buf, hfont[mmid + OFFSET_MID]);
297:     }
298: 
299:     if (clas) {
300:         memor(buf, hfont[mlas + OFFSET_LAS]);
301:     }
302: 
303:     for (y = 0; y < 16; y++) {
304:         // change byte order
305:         src = MAKEWORD(HIBYTE(buf[y]), LOBYTE(buf[y]));
306:         for (x = 0; x < 16; x++) {
307:             if (src & 0x8000)
308:                 SetBufOn(x, y);
309:             src <<= 1;
310:         }
311:     }
312: 
313:     if (!CheckForLineEnd(2)) {
314:         return FALSE;
315:     }
316: 
317:     return TRUE;
318: }
319: 
320: BOOL PutChar(int ch)
321: {
322:     BOOL ret = TRUE;
323: 
324:     if (chSaved) {
325:         ret = PutDoubleByte(MAKEWORD(ch, chSaved));
326:         chSaved = 0;
327:     } else if (ch & 0x80) {
328:         chSaved = ch;
329:     } else {
330:         ret = PutSingleByte(ch);
331:     }
332: 
333:     return ret;
334: }
335: 
336: int main(void)
337: {
338:     int ch;
339: 
340:     if (!InitProgram()) {
341:         printf("Program Initialization Error\n");
342:         exit(0);
343:     }
344: 
345:     ClearBuffer();
346: 
347:     while ((ch = getchar()) != EOF) {
348:         if (!PutChar(ch)) {
349:             break;
350:         }
351:     }
352: 
353:     PrintBuffer();
354: 
355:     DestroyBuffer();
356: 
357:     return 0;
358: }
359: 

This document has been generated using RooTMAN's Source Printer ver. 1.3.1.
han2gd.c / Confidential / BbCom / July 20, 1999