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 uint [width * height];
194 fill (bitmap, bitmap + width * height, 0x00000000);
198 for (i=0; i < height * width; i++)
200 if ((*data.packed & weight) != 0)
202 bitmap[i] = 0xff000000;
216 data.bitmap = (uchar *)bitmap;
220 PkChar::unpack (void)
231 Bitmap bitmap (width, height);
233 RleContext nr (data.packed,
234 first_is_black? BLACK : WHITE,
237 data.bitmap = bitmap.steal_pixels ();
240 if (character_code == '6')
241 cout << "HERER" << endl;
243 cout << '[' << character_code << " not " << (int)'6' << ']' << endl;
250 PkChar::PkChar (AbstractLoader &loader)
252 uint flag_byte = loader.get_uint8 ();
254 dyn_f = flag_byte >> 4;
256 throw string ("Corrupt .pk file");
258 first_is_black = (flag_byte & 8)? true : false;
260 uint length = 0; // to quiet gcc
262 switch (flag_byte & 7)
264 case 0: case 1: case 2: case 3:
266 length = loader.get_uint8 () + ((flag_byte & 3) << 8) - 8;
267 character_code = loader.get_uint8 ();
268 tfm_width = loader.get_uint24 ();
269 dx = loader.get_uint8 () << 16;
271 width = loader.get_uint8 ();
272 height = loader.get_uint8 ();
273 hoffset = loader.get_int8 ();
274 voffset = loader.get_int8 ();
277 case 4: case 5: case 6:
278 /* extended short preamble */
279 length = loader.get_uint16 () + ((flag_byte & 3) << 16) - 13;
283 character_code = loader.get_uint8 ();
285 cout << ',' << character_code;
287 tfm_width = loader.get_uint24 ();
288 dx = loader.get_uint16 () << 16;
290 width = loader.get_uint16 ();
291 height = loader.get_uint16 ();
292 hoffset = loader.get_int16 ();
293 voffset = loader.get_int16 ();
298 length = loader.get_int32 () - 28;
299 character_code = loader.get_int32 ();
300 tfm_width = loader.get_int32 ();
301 dx = loader.get_int32 ();
302 dy = loader.get_int32 ();
303 width = loader.get_int32 ();
304 height = loader.get_int32 ();
305 hoffset = loader.get_int32 ();
306 voffset = loader.get_int32 ();
310 /* should not be reached */
314 data.packed = new uchar[length];
315 loader.get_n (length, data.packed);
319 PkChar::paint (DviRuntime &runtime)
321 const unsigned char *bitmap;
322 bitmap = get_bitmap ();
323 runtime.paint_bitmap (bitmap,
324 get_width(), get_height(),
325 get_hoffset(), get_voffset());
333 c = (PkOpcode) loader.get_uint8 ();
335 throw string ("Not a .pk file (no pre)");
337 id = loader.get_uint8 ();
339 throw string ("Not a .pk file (incorrect id)");
341 comment = loader.get_string8 ();
342 design_size = loader.get_uint32 ();
343 checksum = loader.get_uint32 ();
344 hppp = loader.get_uint32 ();
345 vppp = loader.get_uint32 ();
349 c = (PkOpcode)loader.get_uint8 ();
353 loader.skip_string8 ();
356 loader.skip_string16 ();
359 loader.skip_string24 ();
362 loader.skip_string32 ();
365 loader.get_uint32 ();
372 throw string ("Unexpected PRE");
375 loader.goto_from_current (-1);
376 if (c <= DL_PK_FIRST_COMMAND)
378 PkChar *pkc = new PkChar (loader);
379 chars[pkc->get_character_code()] = pkc;
381 cout << '[' << pkc->get_character_code() << ']';
385 throw string ("Undefined PK command");
388 } while (c != DL_PK_POST);
391 PkFont::PkFont (AbstractLoader& l, int at_size_arg) :
393 at_size (at_size_arg)
398 PkFont::PkFont (AbstractLoader& l) :
402 at_size = design_size;