📄 pw_bitmap.c
字号:
#include <i_pwin.h>/* -------------------------------------------------------------------------- *//** An array of bitmasks. Used for manipulating bits in bitmaps. */const Pw_Byte _bm_bitmask[2][8] = { {127, 191, 223, 239, 247, 251, 253, 254}, {128, 64, 32, 16, 8, 4, 2, 1 }};/** An array of bitmasks. Used for manipulating bits in bitmaps. */static const Pw_Byte _bm_edgemask[2][9] = { {0x00, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x00}, {0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFF}};/** Bitmap low level drawing functions. */Pw_LLD _bitmap_lld;/* -------------------------------------------------------------------------- *//** * Draws a point. * @param gc pointer to bitmap graphic context * @param x point's x coord * @param y point's y coord * @internal */ static void _BitmapDrawPoint(Pw_GC* gc, Pw_Coord x, Pw_Coord y){ IPW_TRACE_ENTER(BM1); IPW_CHECK_PTR(gc); IPw_BitmapDrawPoint(gc->d.comp.bitmap, x, y, gc->color);//// ((gc->color == pw_black_pixel) ? 0 : 1)); IPW_TRACE_EXIT(BM1);}/** * Draws up to 8 points. * For each set bit in bits the point is drawn at (bit_idx + x, y) * @param gc pointer to bitmap graphic context * @param x points start x coord * @param y points y coord * @param bits byte defining wich points (of 8) to be drawn * @internal */ static void _BitmapDrawPoints(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Byte bits) { IPW_TRACE_ENTER(BM1); IPW_CHECK_PTR(gc); IPw_BitmapDrawPoints(gc->d.comp.bitmap, x, y, bits, gc->color);//// ((gc->color == pw_black_pixel) ? 0 : 1)); IPW_TRACE_EXIT(BM1);}/** * Draws a horizontal line. * @param gc pointer to bitmap graphic context * @param x1 line start point x coord * @param y1 line start point y coord * @param x2 line end point x coord * @internal */ static void _BitmapDrawHorLine(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord x2){ IPW_TRACE_ENTER(BM1); IPW_CHECK_PTR(gc); IPw_BitmapDrawHorLine(gc->d.comp.bitmap, x1, y1, x2, gc->color);//// ((gc->color == pw_black_pixel) ? 0 : 1)); IPW_TRACE_EXIT(BM1);}/** * Draws a vertical line. * @param gc pointer to bitmap graphic context * @param x1 line start point x coord * @param y1 line start point y coord * @param y2 line end point y coord * @internal */static void _BitmapDrawVerLine(Pw_GC* gc, Pw_Coord x1, Pw_Coord y1, Pw_Coord y2){ IPW_TRACE_ENTER(BM1); IPW_CHECK_PTR(gc); IPw_BitmapDrawVerLine(gc->d.comp.bitmap, x1, y1, y2, gc->color);//// ((gc->color == pw_black_pixel) ? 0 : 1)); IPW_TRACE_EXIT(BM1);}/** * Fills an rectangular area. * @param gc pointer to bitmap graphic context * @param x top left corner x coord * @param y top left corner y coord * @param w width * @param h height * @internal */static void _BitmapFillRect(Pw_GC* gc, Pw_Coord x, Pw_Coord y, Pw_Coord w, Pw_Coord h){ IPW_TRACE_ENTER(BM1); IPW_CHECK_PTR(gc); IPw_BitmapFillRect(gc->d.comp.bitmap, x, y, w, h, gc->color);//// ((gc->color == pw_black_pixel) ? 0 : 1)); IPW_TRACE_EXIT(BM1);}/* -------------------------------------------------------------------------- *//** * Draws a point. * @param bitmap pointer to bitmap * @param x point's x coord * @param y point's y coord * @param mode draw mode * @internal */ void IPw_BitmapDrawPoint(Pw_Bitmap* bitmap, Pw_Coord x, Pw_Coord y, Pw_uInt mode){ IPW_TRACE_ENTER(BM2); IPW_CHECK_PTR(bitmap); IPW_CHECK_BITMAP(bitmap); IPW_TRACE3(BM1, d, x, y, mode); /* * calculate the points location in bitmap bits array * and the set or reset it using the predefined bitmasks */ if (mode >= 1) { bitmap->bits[((x >> 3) + bitmap->width8 * y)] |= _bm_bitmask[1][(x & 0x07)]; } else { bitmap->bits[((x >> 3) + bitmap->width8 * y)] &= _bm_bitmask[0][(x & 0x07)]; } IPW_TRACE_EXIT(BM2);}/** * Draws up to 8 points. * For each set bit in bits the point is drawn at (bit_idx + x, y) * @param bitmap pointer to bitmap * @param x points start x coord * @param y points y coord * @param bits byte defining wich points (of 8) to be drawn * @param mode draw mode * @internal */ void IPw_BitmapDrawPoints(Pw_Bitmap* bitmap, Pw_Coord x, Pw_Coord y, Pw_Byte bits, Pw_uInt mode){ Pw_uInt16 mask; Pw_Byte* bm_bits; IPW_TRACE_ENTER(BM2); IPW_CHECK_PTR(bitmap); IPW_CHECK_BITMAP(bitmap); IPW_TRACE4(BM1, d, x, y, bits, mode); /* * calculate the location of the first byte * (can be 2 depending of the x coord) to mask * with specified bits (or part of) and then * calculate the 16 bit mask to use */ bm_bits = bitmap->bits + (x >> 3) + bitmap->width8 * y; mask = bits; mask = (mask << 8) >> (x & 0x07);#ifdef IPW_USE_ASSERTS if (((x >> 3) + bitmap->width8 * y) == ((bitmap->width8 * bitmap->height) -1)) { IPW_ASSERT((mask & 0x00FF) == 0, ("Bitmap edge case - mask = %x!", mask)); }#endif /* IPW_USE_ASSERTS */ /* * mask the first byte with mask's high byte and test * the mask's low byte - if it equals 0x00 (or 0xFF in * the second case) do nothing - the clipping layer * guarantees only that the first bit and the bits wich * are set to 1 fall inside this bitmap. */ if (mode >= 1) { *bm_bits |= mask >> 8; mask &= 0x00FF; if (mask != 0x00) { bm_bits++; *bm_bits |= mask; } } else { mask ^= 0xFFFF; *bm_bits &= mask >> 8; mask &= 0x00FF; if (mask != 0xFF) { bm_bits++; *bm_bits &= mask; } } IPW_TRACE_EXIT(BM2);}/** * Draws a horizontal line. * @param bitmap pointer to bitmap * @param x1 line start point x coord * @param y1 line start point y coord * @param x2 line end point x coord * @param mode draw mode * @internal */ void IPw_BitmapDrawHorLine(Pw_Bitmap* bitmap, Pw_Coord x1, Pw_Coord y1, Pw_Coord x2, Pw_uInt mode){ Pw_Int i, start_bits, stop_bits, width; Pw_Byte* bits; IPW_TRACE_ENTER(BM2); IPW_CHECK_PTR(bitmap); IPW_CHECK_BITMAP(bitmap); IPW_TRACE4(BM1, d, x1, y1, x2, mode); /* * calculate the start byte of the line in bitmap's bits * array, the line start bits in start byte and the width * of the line. Then check the width and choose the drawing * strategy. If width > 8 we have some (or none) start * bits, some (or none) bytes in the middle and some (or none) * stop bits. If width < 8 the line should fit into 1 or 2 bytes. */ bits = bitmap->bits + (x1 >> 3) + (bitmap->width8 * y1); start_bits = x1 & 0x07; width = x2 - x1 + 1; if (width > 8) { width -= ((8 - start_bits) & 0x07); if (width > 0) { stop_bits = width & 0x07; width >>= 3; } else { stop_bits = 0; width = 0; } if (mode >= 1) { if (start_bits != 0) *bits++ |= _bm_edgemask[0][start_bits]; for (i = 0; i < width; i++) *bits++ = 0xFF; if (stop_bits != 0) *bits |= _bm_edgemask[1][stop_bits]; } else { if (start_bits != 0) *bits++ &= _bm_edgemask[1][start_bits]; for (i = 0; i < width; i++) *bits++ = 0x00; if (stop_bits != 0) *bits &= _bm_edgemask[0][stop_bits]; } } else { Pw_uInt16 mask = _bm_edgemask[1][width]; mask = (mask << 8) >> start_bits; if (mode >= 1) { *bits |= (mask >> 8); bits++; *bits |= (mask & 0x00FF); } else { *bits &= (0x00FF ^ (mask >> 8)); bits++; *bits &= (0x00FF ^ (mask & 0x00FF)); } } IPW_TRACE_EXIT(BM2);}/** * Draws a horizontal line. * @param bitmap pointer to bitmap * @param x1 line start point x coord * @param y1 line start point y coord * @param y2 line end point y coord * @param mode draw mode * @internal */void IPw_BitmapDrawVerLine(Pw_Bitmap* bitmap, Pw_Coord x1, Pw_Coord y1, Pw_Coord y2, Pw_uInt mode){ Pw_uInt i, step, len; Pw_uInt16 mask; Pw_Byte* bits; IPW_TRACE_ENTER(BM2); IPW_CHECK_PTR(bitmap); IPW_CHECK_BITMAP(bitmap); IPW_TRACE4(BM1, d, x1, y1, y2, mode); /* * calculate the line start byte in bitmap's bits * array, get the step (num of bytes between the * bytes that should be masked to draw the line - * ie the byte width of bitmap). Then mask the line * bytes with calculated mask. */ bits = bitmap->bits + (x1 >> 3) + (y1 * bitmap->width8); step = bitmap->width8; len = (Pw_uInt)(y2 - y1) + 1; if (mode >= 1) { mask = _bm_bitmask[1][(x1 & 0x07)]; for (i = 0; i < len; i++) { *bits |= mask; bits += step; } } else { mask = _bm_bitmask[0][(x1 & 0x07)]; for (i = 0; i < len; i++) { *bits &= mask; bits += step; } } IPW_TRACE_EXIT(BM2);} /** * Fills an rectangular area. * @param bitmap pointer to bitmap * @param x top left corner x coord * @param y top left corner y coord * @param w width * @param h height * @param mode fill mode * @internal */void IPw_BitmapFillRect(Pw_Bitmap* bitmap, Pw_Coord x, Pw_Coord y, Pw_Coord w, Pw_Coord h, Pw_uInt mode){ Pw_Int i, j, start_bits, stop_bits, width, step; Pw_Byte start_mask, stop_mask; Pw_Byte* bits; IPW_TRACE_ENTER(BM2); IPW_CHECK_PTR(bitmap); IPW_CHECK_BITMAP(bitmap); IPW_TRACE5(BM1, d, x, y, w, h, mode); /* * this is like drawing a number (h) * of horizontal lines of width w. * See IPw_BitmapDrawHorLine for comments * on drawing horizontal lines */ bits = bitmap->bits + (x >> 3) + bitmap->width8 * y; start_bits = x & 0x07; if (w > 8) { width = w - ((8 - start_bits) & 0x07); if (width > 0) { stop_bits = width & 0x07; width >>= 3; } else { stop_bits = 0; width = 0; } step = bitmap->width8 - width; if (start_bits != 0) step--; if (mode >= 1) { start_mask = _bm_edgemask[0][start_bits]; stop_mask = _bm_edgemask[1][stop_bits]; for (j = 0; j < h; j++) { if (start_bits != 0) *bits++ |= start_mask;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -