1 #include "dl-pkfont.hh"
5 using namespace DviLib;
8 DL_PK_FIRST_COMMAND = 240,
28 Bitmap (uint width_arg, uint height)
31 data = new uint [width * height];
32 std::fill (data, data + width * height, 0x00000000);
34 uchar *steal_pixels (void)
36 uchar *r = (uchar *)data;
43 void fill_black (uint index, uint len)
46 cout << "filling: " << len << endl;
48 std::fill (data + index,
52 void copy (uint src_index, uint len, uint dest_index)
54 std::copy (data + src_index,
55 data + (src_index + len),
65 return (index * 4) / (width * 4);
68 bool pixel (uint index) {
69 return *(data + index) == 0xff000000;
73 class DviLib::RleContext {
76 uchar nyb0 (uchar x) { return x >> 4; };
77 uchar nyb1 (uchar x) { return x & 15; };
82 RleContext (uchar *data_arg,
92 uchar get_nybble (void)
102 return nyb1 (*data++);
105 Bitmap& get_bitmap () { return bitmap; }
109 PkChar::get_count (RleContext& nr, uint *count)
111 CountType result = RUN_COUNT;
122 result = REPEAT_COUNT;
127 throw string ("Duplicated repeat count");
130 for (i = 1; (*count = nr.get_nybble()) == 0; ++i)
133 *count = (*count << 4) + nr.get_nybble();
134 *count = *count - 15 + (13 - dyn_f)*16 + dyn_f;
140 *count = (i - dyn_f - 1)*16 + nr.get_nybble() + dyn_f + 1;
147 PkChar::unpack_rle (RleContext& nr)
151 while (nr.index < height * width)
153 CountType count_type = get_count (nr, &count);
154 Bitmap& bm = nr.get_bitmap ();
156 switch (count_type) {
158 if (nr.color == BLACK)
160 bm.fill_black (nr.index, count);
168 uint temp = nr.index;
170 nr.index += count * width;
175 if (bm.pixel (temp - x))
176 bm.fill_black (temp + count * width - x, x);
178 for (uint i = 0; i < count; ++i)
179 bm.copy (temp + count * width - x, width,
180 temp - x + i * width);
188 PkChar::unpack_bitmap (void)
193 = new uchar [4 * width * height];
194 fill (bitmap, bitmap + 4 * width * height, 0xFF);
198 for (i=0; i < height * width; i+=4)
200 if ((*data.packed & weight) != 0)
201 bitmap[i] = bitmap[i+1] =
202 bitmap[i+2] = bitmap[i+3] = 0x00;
203 weight = (weight == 1)?
204 (data.packed++, 128) : weight >> 1;
206 data.bitmap = bitmap;
210 PkChar::unpack (void)
219 Bitmap bitmap (width, height);
221 RleContext nr (data.packed,
222 first_is_black? BLACK : WHITE,
226 data.bitmap = bitmap.steal_pixels ();
230 PkChar::PkChar (AbstractLoader &loader)
232 uint flag_byte = loader.get_uint8 ();
234 dyn_f = flag_byte >> 4;
236 throw string ("Corrupt .pk file");
238 first_is_black = (flag_byte & 8)? true : false;
240 uint length = 0; // to quiet gcc
242 switch (flag_byte & 7)
244 case 0: case 1: case 2: case 3:
246 length = loader.get_uint8 () + ((flag_byte & 3) << 8) - 8;
247 character_code = loader.get_uint8 ();
248 tfm_width = loader.get_uint24 ();
249 dx = loader.get_uint8 () << 16;
251 width = loader.get_uint8 ();
252 height = loader.get_uint8 ();
253 hoffset = loader.get_int8 ();
254 voffset = loader.get_int8 ();
257 case 4: case 5: case 6:
258 /* extended short preamble */
259 length = loader.get_uint16 () + ((flag_byte & 3) << 16) - 13;
261 character_code = loader.get_uint8 ();
262 cout << ',' << character_code;
263 tfm_width = loader.get_uint24 ();
264 dx = loader.get_uint16 () << 16;
266 width = loader.get_uint16 ();
267 height = loader.get_uint16 ();
268 hoffset = loader.get_int16 ();
269 voffset = loader.get_int16 ();
274 length = loader.get_int32 () - 28;
275 character_code = loader.get_int32 ();
276 tfm_width = loader.get_int32 ();
277 dx = loader.get_int32 ();
278 dy = loader.get_int32 ();
279 width = loader.get_int32 ();
280 height = loader.get_int32 ();
281 hoffset = loader.get_int32 ();
282 voffset = loader.get_int32 ();
286 /* should not be reached */
290 data.packed = new uchar[length];
291 loader.get_n (length, data.packed);
295 PkChar::paint (DviRuntime &runtime)
297 const unsigned char *bitmap;
298 bitmap = get_bitmap ();
299 runtime.paint_bitmap (bitmap,
300 get_width(), get_height(),
301 get_hoffset(), get_voffset());
309 c = (PkOpcode) loader.get_uint8 ();
311 throw string ("Not a .pk file (no pre)");
313 id = loader.get_uint8 ();
315 throw string ("Not a .pk file (incorrect id)");
317 comment = loader.get_string8 ();
318 design_size = loader.get_uint32 ();
319 checksum = loader.get_uint32 ();
320 hppp = loader.get_uint32 ();
321 vppp = loader.get_uint32 ();
325 c = (PkOpcode)loader.get_uint8 ();
329 loader.skip_string8 ();
332 loader.skip_string16 ();
335 loader.skip_string24 ();
338 loader.skip_string32 ();
341 loader.get_uint32 ();
348 throw string ("Unexpected PRE");
351 loader.goto_from_current (-1);
352 if (c <= DL_PK_FIRST_COMMAND)
354 PkChar *pkc = new PkChar (loader);
355 chars[pkc->get_character_code()] = pkc;
357 cout << '[' << pkc->get_character_code() << ']';
361 throw string ("Undefined PK command");
364 } while (c != DL_PK_POST);
367 PkFont::PkFont (AbstractLoader& l, int at_size_arg) :
369 at_size (at_size_arg)
374 PkFont::PkFont (AbstractLoader& l) :
378 at_size = design_size;