📄 pw_bitmap.c
字号:
for (i = 0; i < width; i++) *bits++ = 0xFF; if (stop_bits != 0) *bits |= stop_mask; bits += step; } } else { start_mask = _bm_edgemask[1][start_bits]; stop_mask = _bm_edgemask[0][stop_bits]; for (j = 0; j < h; j++){ if (start_bits != 0) *bits++ &= start_mask; for (i = 0; i < width; i++) *bits++ = 0x00; if (stop_bits != 0) *bits &= stop_mask; bits += step; } } } else { Pw_uInt16 mask; if (mode >= 1) { mask = _bm_edgemask[1][w]; mask = (mask << 8) >> start_bits; start_mask = mask >> 8; stop_mask = (mask & 0x00FF); step = bitmap->width8 - 1; for (i = 0; i < h; i++) { *bits |= start_mask; bits++; *bits |= stop_mask; bits += step; } } else { mask = _bm_edgemask[1][w]; mask = (mask << 8) >> start_bits; start_mask = 0x00FF ^ (mask >> 8); stop_mask = 0x00FF ^ (mask & 0x00FF); step = bitmap->width8 - 1; for (i = 0; i < h; i++) { *bits &= start_mask; bits++; *bits &= stop_mask; bits += step; } } } IPW_TRACE_EXIT(BM2);}/** * Compares the area @p area of bitmap @p bm1 and @p bm2. * When a different byte is found the function @p diff_func * is called and @p bm2 is set to equal @p bm1 at that byte. * NOTE: the bitmaps @bm1 and @bm2 must be of same size. * @param bm1 pointer to bitmap 1 * @param bm2 pointer to bitmap 2 * @param area pointer to rectangular area * @param diff_func function to call on different bytes * @internal */ void IPw_BitmapDiff(Pw_Bitmap* bm1, Pw_Bitmap* bm2, Pw_Rectangle* area, void (*diff_func)(Pw_uInt baddr, Pw_Byte dbyte)){ Pw_uInt i, j, baddr; Pw_uInt left_bytes, right_bytes, width; Pw_Byte* bits1; Pw_Byte* bits2; IPW_TRACE_ENTER(BM2); IPW_CHECK_PTR4(bm1, bm2, area, diff_func); IPW_CHECK_BITMAP(bm1); IPW_CHECK_BITMAP(bm2); IPW_CHECK_COND((bm1->width == bm2->width) && (bm1->height == bm2->height)); IPW_TRACE_RECT(BM1, area); /* * calculate the start line byte, the number of bytes to * skip on left, the number of bytes to skip on rigth and * the number of bytes to compare in one line (width). * The comparing goes like this: first skip bytes on top, * then compare area->h lines (skip bytes on left, compare * bytes in the middle (width) and skip bytes on right) */ baddr = area->y * bm1->width8; bits1 = bm1->bits + baddr; bits2 = bm2->bits + baddr; left_bytes = area->x >> 3; right_bytes = bm1->width8 - ((area->x + area->w + 0x07) >> 3); width = bm1->width8 - left_bytes - right_bytes; IPW_TRACE4(BM1, d, bm1->width8, left_bytes, width, right_bytes); for (i = 0; i < area->h; i++) { bits1 += left_bytes; bits2 += left_bytes; baddr += left_bytes; for (j = 0; j < width; j++) { if (*bits1 != *bits2) { diff_func(baddr, *bits1); *bits2 = *bits1; } bits1++; bits2++; baddr++; } bits1 += right_bytes; bits2 += right_bytes; baddr += right_bytes; } IPW_TRACE_EXIT(BM2);}/** * Compares the area @p area of bitmap @p bm1 and @p bm2. * When a different pixel is found the function @p diff_func * is called and bm2 is set to equal bm1 at that pixel. * @param bm1 pointer to bitmap 1 * @param bm2 pointer to bitmap 2 * @param area pointer to rectangular area * @param diff_func function to call on different pixels * @internal */ void IPw_BitmapPixDiff(Pw_Bitmap* bm1, Pw_Bitmap* bm2, Pw_Rectangle* area, void (*diff_func)(Pw_uInt x, Pw_uInt y, Pw_uInt mode)){ Pw_uInt i, j, x, y, sx, baddr; Pw_uInt left_bytes, right_bytes, width; Pw_Byte b1, b2; Pw_Byte* bits1; Pw_Byte* bits2; IPW_TRACE_ENTER(BM2); IPW_CHECK_PTR4(bm1, bm2, area, diff_func); IPW_CHECK_BITMAP(bm1); IPW_CHECK_BITMAP(bm2); IPW_CHECK_COND((bm1->width == bm2->width) && (bm1->height == bm2->height)); IPW_TRACE_RECT(BM1, area); /* * this is like comparing bytes in bitmaps - * see IPw_BitmapPixDiff for comments. The only * difference is that we compare each bit in * current bm1 and bm2 bytes (actually there is * some simple optimisation to speed up things :-) */ baddr = area->y * bm1->width8; bits1 = bm1->bits + baddr; bits2 = bm2->bits + baddr; left_bytes = area->x >> 3; right_bytes = bm1->width8 - ((area->x + area->w + 0x07) >> 3); width = bm1->width8 - left_bytes - right_bytes; sx = x = left_bytes << 3; y = area->y; IPW_TRACE5(BM1, d, left_bytes, width, right_bytes, x, y); for (i = 0; i < area->h; i++) { bits1 += left_bytes; bits2 += left_bytes; for (j = 0; j < width; j++) { if (*bits1 != *bits2) { if ((*bits1 & 0xF0) != (*bits2 & 0xF0)) { b1 = *bits1 & 0x80; b2 = *bits2 & 0x80; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; b1 = *bits1 & 0x40; b2 = *bits2 & 0x40; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; b1 = *bits1 & 0x20; b2 = *bits2 & 0x20; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; b1 = *bits1 & 0x10; b2 = *bits2 & 0x10; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; } else { x += 4; } if ((*bits1 & 0x0F) != (*bits2 & 0x0F)) { b1 = *bits1 & 0x08; b2 = *bits2 & 0x08; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; b1 = *bits1 & 0x04; b2 = *bits2 & 0x04; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; b1 = *bits1 & 0x02; b2 = *bits2 & 0x02; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; b1 = *bits1 & 0x01; b2 = *bits2 & 0x01; if (b1 != b2) diff_func(x, y, (b1 > 0 ? 1 : 0)); x++; } else { x += 4; } *bits2 = *bits1; } else { x += 8; } bits1++; bits2++; } x = sx; y++; bits1 += right_bytes; bits2 += right_bytes; } IPW_TRACE_EXIT(BM2);}/** * Initializes the bitmap low level drawing routines. * This function must be called before any other * bitmap functions are used. * @internal */void IPw_BitmapInit(void){ IPW_TRACE_ENTER(BM2); _bitmap_lld.draw_point = _BitmapDrawPoint; _bitmap_lld.draw_points = _BitmapDrawPoints; _bitmap_lld.draw_hor_line = _BitmapDrawHorLine; _bitmap_lld.draw_ver_line = _BitmapDrawVerLine; _bitmap_lld.fill_rect = _BitmapFillRect; IPW_TRACE_EXIT(BM2);}#if IPW_CHECK_EN(BITMAP_STRUCT)Pw_Bool IPw_BitmapCheck(Pw_Bitmap* bitmap){ if (PW_NULL == bitmap->bits) { IPW_ASSERT(FALSE, ("bitmap (%d) bits == NULL", (Pw_Addr)bitmap)); return(FALSE); } if (bitmap->width <= 0) { IPW_ASSERT(FALSE, ("bitmap (%d) width = %d!", (Pw_Addr)bitmap, bitmap->width)); return(FALSE); } if (bitmap->width8 <= 0) { IPW_ASSERT(FALSE, ("bitmap (%d) height = %d!", (Pw_Addr)bitmap, bitmap->height)); return(FALSE); } if (bitmap->width8 != ((bitmap->width + 0x07) >> 3)) { IPW_ASSERT(FALSE, ("bitmap (%d) width8 = %d width = %d!", (Pw_Addr)bitmap, bitmap->width8, bitmap->width)); return(FALSE); } if (bitmap->height <= 0) { IPW_ASSERT(FALSE, ("bitmap (%d) height = %d!", (Pw_Addr)bitmap, bitmap->height)); return(FALSE); } return(TRUE);}#endif /* IPW_CHECK_EN(BITMAP_STRUCT) *//* -------------------------------------------------------------------------- *//** * Creates a new bitmap. * @param width bitmap width * @param height bitmap height * @param bitmap pointer to bitmap to create * @param bits pointer to bitmap bits array * @return created bitmap (same as @p bitmap)
* @see Pw_BitmapDestroy */ Pw_Bitmap* Pw_BitmapCreate(Pw_Coord width, Pw_Coord height, Pw_Byte* bits, Pw_Bitmap* bitmap){ Pw_uInt i, width8, byte_size; IPW_TRACE_ENTER(BM3); IPW_CHECK_PTR2(bitmap, bits); width8 = (width + 0x07) >> 3; byte_size = width8 * height; bitmap->width = width; bitmap->height = height; bitmap->width8 = width8; bitmap->bits = bits; IPW_TRACE3(BM2, d, width, height, width8); for (i = 0; i < byte_size; i++) bitmap->bits[i] = 0x00; IPW_CHECK_BITMAP(bitmap); IPW_TRACE_EXIT_V(BM3, p, bitmap); return(bitmap);}/** * Destroys the bitmap. * @param bitmap pointer to bitmap to destroy * @see Pw_BitmapCreate */ void Pw_BitmapDestroy(Pw_Bitmap* bitmap){
bitmap = bitmap ;/* IPW_TRACE_ENTER(BM3); IPW_CHECK_PTR(bitmap); IPW_CHECK_BITMAP(bitmap); IPW_TRACE1(BM2, p, bitmap); IPW_TRACE3(BM2, d, bitmap->width, bitmap->height, bitmap->width8); IPW_CHECK_COND(bitmap->width8 == ((bitmap->width + 0x07) >> 3)); IPW_TRACE_EXIT(BM3); */} /** * Creates a new graphic context for bitmap. * @param bitmap pointer to bitmap * @param gc pointer to graphics context to create * @return bitmap's graphic context (same as @p gc) * @see Pw_BitmapDestroyGC */ Pw_GC* Pw_BitmapCreateGC(Pw_Bitmap* bitmap, Pw_GC* gc){ IPW_TRACE_ENTER(BM3); IPW_CHECK_PTR2(bitmap, gc); IPW_CHECK_BITMAP(bitmap); IPW_TRACE2(BM2, d, bitmap->width, bitmap->height); gc->d.type = Pw_DrawableBitmapType; gc->d.comp.bitmap = bitmap; gc->d.lld = &_bitmap_lld; IPW_CHECK_COND(gc->d.lld->draw_point != PW_NULL); IPW_CHECK_COND(gc->d.lld->draw_points != PW_NULL); IPW_CHECK_COND(gc->d.lld->draw_hor_line != PW_NULL); IPW_CHECK_COND(gc->d.lld->draw_ver_line != PW_NULL); IPW_CHECK_COND(gc->d.lld->fill_rect != PW_NULL); gc->xoff = 0; gc->yoff = 0; gc->clip_reg.regs_num = 1; gc->clip_reg.bounds.x = 0; gc->clip_reg.bounds.y = 0; gc->clip_reg.bounds.w = bitmap->width; gc->clip_reg.bounds.h = bitmap->height; gc->clip_reg.regs = IPw_RegionNew(); IPW_FAIL(gc->clip_reg.regs != PW_NULL, ("Out of free regions!")); IPW_RECT_COPY(&gc->clip_reg.regs->area, &gc->clip_reg.bounds); gc->color = pw_black_pixel; gc->font = PW_NULL; IPW_CHECK_GC(gc); IPW_TRACE_EXIT_V(BM3, p, gc); return(gc);}/** * Destroys the bitmap graphic context. * @param gc graphic context to destroy * @see Pw_BitmapCreateGC */ void Pw_BitmapDestroyGC(Pw_GC* gc){ IPW_TRACE_ENTER(BM3); IPW_CHECK_PTR(gc); IPW_CHECK_GC(gc); IPW_CHECK_COND(gc->d.type == Pw_DrawableBitmapType); IPw_RegionFree(gc->clip_reg.regs); IPW_TRACE_EXIT(BM3);}/*---------------------------------------------------------------------------// end of pw_bitmap.c //--------------------------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -