所謂テキストファイルを印刷するツールです。emacsと連携しやすくなっています。
Révision | 6d361c524c7b2df59d4c0a979050d09ebab4c26a (tree) |
---|---|
l'heure | 2005-05-01 02:15:08 |
Auteur | tfuruka1 <tfuruka1> |
Commiter | tfuruka1 |
新規追加
@@ -0,0 +1,375 @@ | ||
1 | +/* -*- mode: c++ -*- | |
2 | + * $Id: xbm.c,v 1.1 2005/04/30 17:15:08 tfuruka1 Exp $ | |
3 | + * $Name: $ | |
4 | + * | |
5 | + * xbm, uncompface ファイルの展開等を行ないます。本当は, 元々 | |
6 | + * uncompface を展開するのが目的で, uncompface の -X オプションで生成 | |
7 | + * した xbm ファイルを展開できるのを確認したところで… uncompface の | |
8 | + * -X オプションって, version によって, サポートされない事が判明してし | |
9 | + * まい, 急遽, umcompface に対応したのであった。 | |
10 | + * | |
11 | + * リンク時は、gdi32.lib, user32.lib が必要です。 | |
12 | + * | |
13 | + * $Log: xbm.c,v $ | |
14 | + * Revision 1.1 2005/04/30 17:15:08 tfuruka1 | |
15 | + * 新規追加 | |
16 | + * | |
17 | + */ | |
18 | + | |
19 | +#include "xbm.h" | |
20 | + | |
21 | +/* | |
22 | + * XBMファイルから、幅、又は高さを得る | |
23 | + */ | |
24 | +static int | |
25 | +GetXbmValue(FILE *fp, char *lpszItem) | |
26 | +{ | |
27 | + char szBuf[1024]; | |
28 | + char *p; | |
29 | + char *p1; | |
30 | + | |
31 | + // ファイルの先頭へシーク | |
32 | + if (0 != fseek(fp, 0, SEEK_SET)) { | |
33 | + perror("SEEK"); | |
34 | + return 0; | |
35 | + } | |
36 | + | |
37 | + while (fgets(szBuf, 1024, fp)) { | |
38 | + if ('#' != szBuf[0]) { | |
39 | + continue; | |
40 | + } | |
41 | + if (NULL == (p = strstr(szBuf, lpszItem))) { | |
42 | + continue; | |
43 | + } | |
44 | + if (NULL == (p1 = strrchr(p, ' '))) { | |
45 | + continue; | |
46 | + } | |
47 | + return atoi(p1); | |
48 | + } | |
49 | + return 0; | |
50 | +} | |
51 | + | |
52 | +/* | |
53 | + * XBMファイルから、幅を得る | |
54 | + */ | |
55 | +static int | |
56 | +GetXbmWidth(FILE *fp) | |
57 | +{ | |
58 | + return GetXbmValue(fp, "_width "); | |
59 | +} | |
60 | + | |
61 | +/* | |
62 | + * XBMファイルから、高さを得る | |
63 | + */ | |
64 | +static int | |
65 | +GetXbmHeight(FILE *fp) | |
66 | +{ | |
67 | + return GetXbmValue(fp, "_height "); | |
68 | +} | |
69 | + | |
70 | +/* | |
71 | + * XBMファイルのデータ部分の先頭にシークする | |
72 | + */ | |
73 | +static BOOL | |
74 | +SkipToFirstByte(FILE *fp) | |
75 | +{ | |
76 | + int c; | |
77 | + | |
78 | + while (EOF != (c = getc(fp))) { | |
79 | + if ('{' == c) { | |
80 | + return TRUE; | |
81 | + } | |
82 | + } | |
83 | + return FALSE; | |
84 | +} | |
85 | + | |
86 | +/* | |
87 | + * XBMファイルから1バイト分読み込むか、uncompressが出力したデータファ | |
88 | + * イルから2バイト分読み込む。 | |
89 | + */ | |
90 | +static long | |
91 | +GetByte(FILE *fp, int kind) | |
92 | +{ | |
93 | + int c; | |
94 | + int idx; | |
95 | + int max = (AXBM_XBM == kind) ? 4 : 6; | |
96 | + char szBuf[12]; | |
97 | + | |
98 | + // 最初の空白を消去 | |
99 | + while (EOF != (c = getc(fp))) { | |
100 | + if (!isspace(c)) { | |
101 | + break; | |
102 | + } | |
103 | + } | |
104 | + idx = 0; | |
105 | + if (!isdigit(c)) { | |
106 | + printf("想定外の文字: %c[%02x]\n", c, c); | |
107 | + return -1; | |
108 | + } | |
109 | + szBuf[idx] = c; | |
110 | + idx++; | |
111 | + szBuf[idx] = '\0'; | |
112 | + while (EOF != (c = getc(fp))) { | |
113 | + if (isspace(c)) { | |
114 | + continue; | |
115 | + } | |
116 | + if (('X' != c) && ('x' != c) && (!isxdigit(c))) { | |
117 | + return (int)strtol(szBuf, NULL, 16); | |
118 | + } | |
119 | + szBuf[idx] = c; | |
120 | + idx++; | |
121 | + szBuf[idx] = '\0'; | |
122 | + if (max < idx) { | |
123 | + printf("文字数が長すぎます: %s\n", szBuf); | |
124 | + return -1; | |
125 | + } | |
126 | + } | |
127 | + printf("EOF検出\n"); | |
128 | + return -1; | |
129 | +} | |
130 | + | |
131 | +/* | |
132 | + * XBM または, uncompface ファイルの情報を展開する。引数で渡されたファ | |
133 | + * イルポインタは処理完了後クローズします。エラーが発生した場合は, ク | |
134 | + * ローズしません。 | |
135 | + */ | |
136 | +LPXBM_INFO | |
137 | +AllocXBM(FILE *fp, int kind) | |
138 | +{ | |
139 | + int i; | |
140 | + long c; | |
141 | + | |
142 | + LPXBM_INFO lpXbm = (LPXBM_INFO)malloc(sizeof(XBM_INFO)); | |
143 | + | |
144 | + if (!lpXbm) { | |
145 | + printf("メモリ不足(XBM-INFO):%s(%d)\n", __FILE__, __LINE__); | |
146 | + return NULL; | |
147 | + } | |
148 | + lpXbm->lpData = NULL; | |
149 | + lpXbm->kind = kind; | |
150 | + | |
151 | + if (AXBM_XBM == kind) { // xbm | |
152 | + lpXbm->nWidth = GetXbmWidth(fp); | |
153 | + lpXbm->nHeight = GetXbmHeight(fp); | |
154 | + } else { // uncompface | |
155 | + lpXbm->nWidth = 48; | |
156 | + lpXbm->nHeight = 48; | |
157 | + } | |
158 | + lpXbm->cbWidth = ((lpXbm->nWidth / 8) | |
159 | + + (0 == (lpXbm->nWidth % 8) ? 0 : 1)); | |
160 | + lpXbm->cbData = lpXbm->cbWidth * lpXbm->nHeight; | |
161 | + | |
162 | + lpXbm->lpData = (unsigned char *)malloc(lpXbm->cbData); | |
163 | + if (!lpXbm->lpData) { | |
164 | + free(lpXbm); | |
165 | + printf("メモリ不足(XBM-DATA):%s(%d)\n", __FILE__, __LINE__); | |
166 | + return NULL; | |
167 | + } | |
168 | + | |
169 | + if (AXBM_XBM == kind) { // xbm | |
170 | + SkipToFirstByte(fp); | |
171 | + | |
172 | + for (i = 0; i < lpXbm->cbData; i++) { | |
173 | + c = GetByte(fp, kind); | |
174 | + *(lpXbm->lpData + i) = c & 0xff; | |
175 | + } | |
176 | + } else { // uncompface | |
177 | + for (i = 0; i < lpXbm->cbData; i += 2) { | |
178 | + c = GetByte(fp, kind); | |
179 | + *(lpXbm->lpData + i) = (c >> 8)& 0xff; | |
180 | + *(lpXbm->lpData + i + 1) = c & 0xff; | |
181 | + } | |
182 | + } | |
183 | + fclose(fp); | |
184 | + | |
185 | + return lpXbm; | |
186 | +} | |
187 | + | |
188 | +/* | |
189 | + * AllocXBMで取得した情報エリアを開放します。 | |
190 | + */ | |
191 | +void | |
192 | +FreeXBM(LPXBM_INFO lpXbm) | |
193 | +{ | |
194 | + if (lpXbm && lpXbm->lpData) { | |
195 | + free(lpXbm->lpData); | |
196 | + } | |
197 | + if (lpXbm) { | |
198 | + free(lpXbm); | |
199 | + } | |
200 | +} | |
201 | + | |
202 | +/* | |
203 | + * XBM情報の座標の内容を返却します。 | |
204 | + */ | |
205 | +int | |
206 | +PeekXBM(LPXBM_INFO lpXbm, int x, int y) | |
207 | +{ | |
208 | + int idx = y * (lpXbm->cbWidth) + (x / 8); | |
209 | + int shift = (x % 8); | |
210 | + int c = *(lpXbm->lpData + idx); | |
211 | + | |
212 | + if (AXBM_UFACE == lpXbm->kind) { | |
213 | + shift = 7 - shift; | |
214 | + } | |
215 | + return (c >> shift) & 1; | |
216 | +} | |
217 | + | |
218 | +/* | |
219 | + * XBM情報の内容を描画します。 | |
220 | + */ | |
221 | +BOOL WINAPI | |
222 | +DrawXBM( | |
223 | + LPXBM_INFO lpXbm, // xbm情報 | |
224 | + HDC hDC, // 描画するDC | |
225 | + int x, // 描画座標 | |
226 | + int y, // 描画座標 | |
227 | + int nWidth, // 描画幅 | |
228 | + int nHeight, // 描画高 | |
229 | + COLORREF crFg, // 全景色 | |
230 | + COLORREF crBg, // 背景色 | |
231 | + DWORD dwRop // ラスターオペレーション | |
232 | + ) | |
233 | +{ | |
234 | + HDC hMemDC; // デバイスコンテキスト(仮想) | |
235 | + HBITMAP hBitMap; // ビットマップ | |
236 | + HBITMAP hOldBitmap; // 古いビットマップ | |
237 | + int xx, yy; | |
238 | + | |
239 | + // 仮想デバイスコンテキストを作成する | |
240 | + if (!(hMemDC = CreateCompatibleDC(hDC))) { | |
241 | + printf("仮想デバイスコンテキスト作成失敗\n"); | |
242 | + return FALSE; | |
243 | + } | |
244 | + | |
245 | + // ビットマップの作成 | |
246 | + if (!(hBitMap = CreateBitmap(lpXbm->nWidth, lpXbm->nHeight, 1, 1, NULL))) { | |
247 | + printf("ビットマップの作成に失敗しました\n"); | |
248 | + DeleteDC(hMemDC); // デバイスコンテキスト削除 | |
249 | + return FALSE; | |
250 | + } | |
251 | + | |
252 | + // ビットマップの選択 | |
253 | + if (!(hOldBitmap = SelectObject(hMemDC, hBitMap))) { | |
254 | + printf("ビットマップの選択に失敗しました。\n"); | |
255 | + DeleteDC(hMemDC); // デバイスコンテキスト削除 | |
256 | + DeleteObject(hBitMap); // ビットマップ削除 | |
257 | + return FALSE; | |
258 | + } | |
259 | + | |
260 | + // XBMの描画 | |
261 | + for (yy = 0; yy < lpXbm->nWidth; yy++) { | |
262 | + for (xx = 0; xx < lpXbm->nHeight; xx++) { | |
263 | + SetPixel(hMemDC, xx, yy, PeekXBM(lpXbm, xx, yy) ? crFg : crBg); | |
264 | + } | |
265 | + } | |
266 | + | |
267 | + // XBMの転送 | |
268 | + StretchBlt(hDC, x, y, nWidth, nHeight, | |
269 | + hMemDC, 0, 0, lpXbm->nWidth, lpXbm->nHeight, dwRop); | |
270 | + | |
271 | + // 後始末 | |
272 | + SelectObject(hMemDC, hOldBitmap); // ビットマップを戻す | |
273 | + DeleteObject(hBitMap); // ビットマップ削除 | |
274 | + DeleteDC(hMemDC); // 仮想DC削除 | |
275 | + | |
276 | + return TRUE; | |
277 | +} | |
278 | + | |
279 | +#if 1 // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | |
280 | + | |
281 | +/* | |
282 | + * SDK32:コンソールウィンドウのハンドル取得 | |
283 | + * | |
284 | + * 本関数は以下の記事を参考にして作成しました。 | |
285 | + * | |
286 | + * 最終更新日: 1999/02/09 | |
287 | + * 文書番号: J046738 | |
288 | + * | |
289 | + * この資料は以下について記述したものです。 | |
290 | + * | |
291 | + * Microsoft(R) Win32(R) Software Development Kit (SDK) | |
292 | + * | |
293 | + * この資料は、米国 Microsoft Corporation から提供されている Knowledge | |
294 | + * Base の Article ID Q124103 (最終更新日 1988-12-23) をもとに作成した | |
295 | + * ものです。 | |
296 | + */ | |
297 | +#define MY_BUFSIZE 1024 // コンソールのタイトル用 | |
298 | +HWND GetConsoleHwnd(VOID) | |
299 | +{ | |
300 | + HWND hwndFound; | |
301 | + char pszNewWindowTitle[MY_BUFSIZE]; | |
302 | + char pszOldWindowTitle[MY_BUFSIZE]; | |
303 | + int i; | |
304 | + | |
305 | + // コンソールタイトルの取得 | |
306 | + GetConsoleTitle(pszOldWindowTitle, MY_BUFSIZE); | |
307 | + | |
308 | + // 独自に、ウィンドウの新規タイトルをフォーマットします | |
309 | + wsprintf(pszNewWindowTitle,"%d/%d-%s", | |
310 | + GetTickCount(), | |
311 | + GetCurrentProcessId(), | |
312 | + pszOldWindowTitle); | |
313 | + | |
314 | + // 現在のウィンドウタイトルを変更します | |
315 | + SetConsoleTitle(pszNewWindowTitle); | |
316 | + | |
317 | + for (i = 0; i < 100; i++) { | |
318 | + // ウィンドウの新規タイトルを探しにいきます | |
319 | + hwndFound = FindWindow(NULL, pszNewWindowTitle); | |
320 | + if (hwndFound) { | |
321 | + printf("GetConsoleHwnd(): 回数=%d, T=%s\n", | |
322 | + i, pszNewWindowTitle); | |
323 | + break; // 見つかった | |
324 | + } | |
325 | + Sleep(10); // 10m Wait | |
326 | + } | |
327 | + | |
328 | + // 元のウィンドウタイトルへ戻します | |
329 | + SetConsoleTitle(pszOldWindowTitle); | |
330 | + | |
331 | + return hwndFound; | |
332 | +} | |
333 | + | |
334 | +int main(int argc, char *argv[]) | |
335 | +{ | |
336 | + FILE *fp; | |
337 | + int x, y; | |
338 | + int kind; | |
339 | + LPXBM_INFO lpXbm; | |
340 | + HWND hWnd = GetConsoleHwnd(); | |
341 | + HDC hDC = GetDC(hWnd); | |
342 | + | |
343 | + if (3 != argc) { | |
344 | + printf("Usage: xbm [u | x] FileName\n"); | |
345 | + return 1; | |
346 | + } | |
347 | + | |
348 | + kind = (*argv[1] == 'u') ? AXBM_UFACE : AXBM_XBM; | |
349 | + | |
350 | + if (!(fp = fopen(argv[2], "rt"))) { | |
351 | + perror(argv[1]); | |
352 | + return 1; | |
353 | + } | |
354 | + | |
355 | + if (!(lpXbm = AllocXBM(fp, kind))) { | |
356 | + return 1; | |
357 | + } | |
358 | + | |
359 | + // テキストで描画 | |
360 | + for (y = 0; y < lpXbm->nHeight; y++) { | |
361 | + for (x = 0; x < lpXbm->nWidth; x++) { | |
362 | + printf("%c", PeekXBM(lpXbm, x, y) ? 'X': ' '); | |
363 | + } | |
364 | + printf("\n"); | |
365 | + } | |
366 | + | |
367 | + // グラフィックで描画 | |
368 | + DrawXBM(lpXbm, hDC, 100, 100, lpXbm->nWidth * 2, lpXbm->nHeight * 2, | |
369 | + RGB(0, 0, 0), RGB(255, 255, 255), SRCCOPY); | |
370 | + FreeXBM(lpXbm); | |
371 | + | |
372 | + ReleaseDC(hWnd, hDC); | |
373 | + return 0; | |
374 | +} | |
375 | +#endif |
@@ -0,0 +1,41 @@ | ||
1 | +/* -*- mode: c++ -*- | |
2 | + * $Id: xbm.h,v 1.1 2005/04/30 17:15:12 tfuruka1 Exp $ | |
3 | + * $Name: $ | |
4 | + * | |
5 | + * xbm ファイルの展開等 | |
6 | + * | |
7 | + * $Log: xbm.h,v $ | |
8 | + * Revision 1.1 2005/04/30 17:15:12 tfuruka1 | |
9 | + * 新規追加 | |
10 | + * | |
11 | + */ | |
12 | +#ifndef _XBM_H_ | |
13 | +#define _XBM_H_ | |
14 | + | |
15 | +#include <windows.h> | |
16 | +#include <stdio.h> | |
17 | + | |
18 | +// ファイルの種類(AllocXBMの引数) | |
19 | +enum { | |
20 | + AXBM_XBM = 0, // 純粋なXBMファイル | |
21 | + AXBM_UFACE, // uncompface | |
22 | + NUM_OF_XBM | |
23 | +}; | |
24 | + | |
25 | +// xbm情報 | |
26 | +typedef struct { | |
27 | + int kind; // XBM, uncompface | |
28 | + int nWidth; // 幅のピクセル数 | |
29 | + int nHeight; // 高さのピクセル数 | |
30 | + int cbWidth; // 幅のバイト数 | |
31 | + int cbData; // データサイズ | |
32 | + unsigned char *lpData; // データエリア | |
33 | +} XBM_INFO, *PXBM_INFO, *LPXBM_INFO; | |
34 | + | |
35 | +// プロトタイプ宣言 | |
36 | +LPXBM_INFO AllocXBM(FILE *fp, int kind); | |
37 | +void FreeXBM(LPXBM_INFO lpXbm); | |
38 | +int PeekXBM(LPXBM_INFO lpXbm, int x, int y); | |
39 | + | |
40 | +#endif | |
41 | + |