static void rtgui_dc_buffer_draw_hline(struct rtgui_dc *self, int x1, int x2, int y1) { struct rtgui_dc_buffer *dst; unsigned r, g, b, a; dst = (struct rtgui_dc_buffer *)self; if (y1 >= dst->height) return; if (x1 > dst->width) x1 = dst->width; if (x2 > dst->width) x2 = dst->width; r = RTGUI_RGB_R(dst->gc.foreground); g = RTGUI_RGB_G(dst->gc.foreground); b = RTGUI_RGB_B(dst->gc.foreground); a = RTGUI_RGB_A(dst->gc.foreground); switch (dst->pixel_format) { case RTGRAPHIC_PIXEL_FORMAT_RGB565: HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB565, 0); break; case RTGRAPHIC_PIXEL_FORMAT_BGR565: HLINE(rt_uint16_t, DRAW_SETPIXEL_BGR565, 0); break; case RTGRAPHIC_PIXEL_FORMAT_RGB888: HLINE(rt_uint16_t, DRAW_SETPIXEL_RGB888, 0); break; case RTGRAPHIC_PIXEL_FORMAT_ARGB888: HLINE(rt_uint32_t, DRAW_SETPIXEL_ARGB8888, 0); break; } }
static void rtgui_dc_buffer_draw_color_point(struct rtgui_dc *self, int x, int y, rtgui_color_t color) { struct rtgui_dc_buffer *dst; unsigned r, g, b, a; dst = (struct rtgui_dc_buffer *)self; /* does not draw point out of dc */ if ((x > dst->width) || (y > dst->height)) return ; r = RTGUI_RGB_R(color); g = RTGUI_RGB_G(color); b = RTGUI_RGB_B(color); a = RTGUI_RGB_A(color); switch (dst->pixel_format) { case RTGRAPHIC_PIXEL_FORMAT_RGB565: DRAW_SETPIXELXY_RGB565(x, y); break; case RTGRAPHIC_PIXEL_FORMAT_BGR565: DRAW_SETPIXELXY_BGR565(x, y); break; case RTGRAPHIC_PIXEL_FORMAT_RGB888: DRAW_SETPIXELXY_RGB888(x, y); break; case RTGRAPHIC_PIXEL_FORMAT_ARGB888: DRAW_SETPIXELXY_ARGB8888(x, y); break; } }
static void rtgui_dc_buffer_fill_rect(struct rtgui_dc *self, struct rtgui_rect *dst_rect) { struct rtgui_dc_buffer *dst; unsigned r, g, b, a; rtgui_rect_t _r, *rect; RT_ASSERT(self); if (dst_rect == RT_NULL) rtgui_dc_get_rect(self, &_r); else _r = *dst_rect; dst = (struct rtgui_dc_buffer *)self; if (_r.x2 < 0 || _r.y2 < 0) return; /* out of rect */ /* parameter checking */ if (_r.x1 >= dst->width) return; else if (_r.x1 < 0) _r.x1 = 0; if (_r.x2 > dst->width) _r.x2 = dst->width; if (_r.y1 >= dst->height) return; else if (_r.y1 < 0) _r.y1 = 0; if (_r.y2 > dst->height) _r.y2 = dst->height; rect = &_r; r = RTGUI_RGB_R(dst->gc.background); g = RTGUI_RGB_G(dst->gc.background); b = RTGUI_RGB_B(dst->gc.background); a = RTGUI_RGB_A(dst->gc.background); switch (dst->pixel_format) { case RTGRAPHIC_PIXEL_FORMAT_RGB565: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_RGB565); break; case RTGRAPHIC_PIXEL_FORMAT_BGR565: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BGR565); break; case RTGRAPHIC_PIXEL_FORMAT_RGB888: FILLRECT(rt_uint32_t, DRAW_SETPIXEL_RGB888); break; case RTGRAPHIC_PIXEL_FORMAT_ARGB888: FILLRECT(rt_uint32_t, DRAW_SETPIXEL_ARGB8888); break; } }
static void rtgui_dc_buffer_fill_rect(struct rtgui_dc *self, struct rtgui_rect *dst_rect) { struct rtgui_dc_buffer *dst; unsigned r, g, b, a; rtgui_rect_t _r, *rect; dst = (struct rtgui_dc_buffer *)self; _r = *dst_rect; /* parameter checking */ if (_r.x1 > dst->width) _r.x1 = dst->width; if (_r.x2 > dst->width) _r.x2 = dst->width; if (_r.y1 > dst->height) _r.y1 = dst->height; if (_r.y2 > dst->height) _r.y2 = dst->height; rect = &_r; r = RTGUI_RGB_R(dst->gc.foreground); g = RTGUI_RGB_G(dst->gc.foreground); b = RTGUI_RGB_B(dst->gc.foreground); a = RTGUI_RGB_A(dst->gc.foreground); switch (dst->pixel_format) { case RTGRAPHIC_PIXEL_FORMAT_RGB565: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_RGB565); break; case RTGRAPHIC_PIXEL_FORMAT_BGR565: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_BGR565); break; case RTGRAPHIC_PIXEL_FORMAT_RGB888: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_RGB888); break; case RTGRAPHIC_PIXEL_FORMAT_ARGB888: FILLRECT(rt_uint16_t, DRAW_SETPIXEL_ARGB8888); break; } }
static void rtgui_image_png_blit(struct rtgui_image *image, struct rtgui_dc *dc, struct rtgui_rect *rect) { rt_uint16_t x, y, w, h; rtgui_color_t *ptr; struct rtgui_image_png *png; int fg_maxsample; int ialpha; float alpha; rtgui_color_t color; rtgui_color_t c, bgcolor; int fc[3], bc[3]; struct rtgui_graphic_driver *hwdev = rtgui_graphic_get_device(); RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL); RT_ASSERT(image->data != RT_NULL); png = (struct rtgui_image_png *) image->data; w = _UI_MIN(image->w, rtgui_rect_width(*rect)); h = _UI_MIN(image->h, rtgui_rect_height(*rect)); fg_maxsample = (1 << png->info_ptr->bit_depth) - 1; if (png->pixels != RT_NULL) { ptr = (rtgui_color_t *)png->pixels; bgcolor = RTGUI_DC_BC(dc); bc[0] = RTGUI_RGB_R(bgcolor); bc[1] = RTGUI_RGB_G(bgcolor); bc[2] = RTGUI_RGB_B(bgcolor); /* draw each point within dc */ for (y = 0; y < h; y ++) { for (x = 0; x < w; x++) { c = *ptr; ialpha = RTGUI_RGB_A(c); if (ialpha == 0) { /* * Foreground image is transparent hear. * If the background image is already in the frame * buffer, there is nothing to do. */ } else if (ialpha == fg_maxsample) { /* * Copy foreground pixel to frame buffer. */ rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, c); } else { /* output = alpha * foreground + (1-alpha) * background */ /* * Compositing is necessary. * Get floating-point alpha and its complement. * Note: alpha is always linear: gamma does not * affect it. */ fc[0] = RTGUI_RGB_R(c); fc[1] = RTGUI_RGB_G(c); fc[2] = RTGUI_RGB_B(c); alpha = (float) ialpha / fg_maxsample; color = RTGUI_RGB((rt_uint8_t)(fc[0] * alpha + bc[0] * (1 - alpha)), (rt_uint8_t)(fc[1] * alpha + bc[1] * (1 - alpha)), (rt_uint8_t)(fc[2] * alpha + bc[2] * (1 - alpha))); rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, color); } /* move to next color buffer */ ptr ++; } } } else { png_bytep row; png_bytep data; row = (png_bytep) rtgui_malloc(png_get_rowbytes(png->png_ptr, png->info_ptr)); if (row == RT_NULL) return ; switch (png->info_ptr->color_type) { case PNG_COLOR_TYPE_RGB: for (y = 0; y < h; y++) { png_read_row(png->png_ptr, row, png_bytep_NULL); for (x = 0; x < w; x++) { data = &(row[x * 3]); rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, RTGUI_RGB(data[0], data[1], data[2])); } } break; case PNG_COLOR_TYPE_RGBA: for (y = 0; y < h; y++) { png_read_row(png->png_ptr, row, png_bytep_NULL); for (x = 0; x < w; x++) { data = &(row[x * 4]); if (data[3] != 0) { rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, RTGUI_ARGB(data[3], data[0], data[1], data[2])); } } } break; case PNG_COLOR_TYPE_PALETTE: for (y = 0; y < h; y++) { png_read_row(png->png_ptr, row, png_bytep_NULL); for (x = 0; x < w; x++) { data = &(row[x]); rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, RTGUI_ARGB(0, png->info_ptr->palette[data[0]].red, png->info_ptr->palette[data[0]].green, png->info_ptr->palette[data[0]].blue)); } } default: break; }; rtgui_free(row); } }