Пример #1
0
static void rtgui_dc_buffer_blit_line(struct rtgui_dc *self, int x1, int x2, int y, rt_uint8_t *line_data)
{
	rt_uint8_t *pixel;
    struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;

    RT_ASSERT(dc != RT_NULL);
    RT_ASSERT(line_data != RT_NULL);

    /* out of range */
    if ((x1 > dc->width) || (y > dc->height)) return;
    /* check range */
    if (x2 > dc->width) x2 = dc->width;

	pixel = _dc_get_pixel(dc,x1,y);
    rt_memcpy(pixel, line_data, (x2 - x1) * rtgui_color_get_bpp(dc->pixel_format));
}
Пример #2
0
/* blit a dc to a hardware dc */
static void rtgui_dc_buffer_blit(struct rtgui_dc *self, struct rtgui_point *dc_point, struct rtgui_dc *dest, rtgui_rect_t *rect)
{
	int pitch;
	rt_uint16_t rect_width, rect_height;
    struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;

    if (dc_point == RT_NULL) dc_point = &rtgui_empty_point;
    if (rtgui_dc_get_visible(dest) == RT_FALSE) return;

	/* get the minimal width and height */
	rect_width  = _UI_MIN(rtgui_rect_width(*rect), dc->width - dc_point->x);
	rect_height = _UI_MIN(rtgui_rect_height(*rect), dc->height - dc_point->y);

    if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
    {
		int index;
        rt_uint8_t *line_ptr, *pixels;
        rtgui_blit_line_func blit_line;
		struct rtgui_graphic_driver *hw_driver;

		hw_driver = rtgui_graphic_driver_get_default();
        /* prepare pixel line */
		pixels = _dc_get_pixel(dc, dc_point->x, dc_point->y);

        if (hw_driver->bits_per_pixel == _dc_get_bits_per_pixel(dc))
        {
			if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL)
			{
				rt_uint8_t *hw_pixels;

				pitch = rtgui_color_get_bpp(hw_driver->pixel_format) * rect_width;
				hw_pixels = (rt_uint8_t*)(hw_driver->framebuffer + rect->y1 * hw_driver->pitch + 
					rect->x1 * rtgui_color_get_bpp(hw_driver->pixel_format));
				for (index = 0; index < rect_height; index ++)
				{
					memcpy(hw_pixels, pixels, pitch);
					pixels += dc->pitch;
					hw_pixels += hw_driver->pitch;
				}
			}
			else
			{
	            /* it's the same bits per pixel, draw it directly */
	            for (index = rect->y1; index < rect->y1 + rect_height; index++)
	            {
	                dest->engine->blit_line(dest, rect->x1, rect->x1 + rect_width, index, pixels);
					pixels += dc->pitch;
	            }
			}
        }
        else
        {
            /* get blit line function */
            blit_line = rtgui_blit_line_get(_UI_BITBYTES(hw_driver->bits_per_pixel), rtgui_color_get_bpp(dc->pixel_format));
            /* calculate pitch */
            pitch = rect_width * rtgui_color_get_bpp(hw_driver->pixel_format);
            /* create line buffer */
            line_ptr = (rt_uint8_t *) rtgui_malloc(rect_width * _UI_BITBYTES(hw_driver->bits_per_pixel));

            /* draw each line */
            for (index = rect->y1; index < rect->y1 + rect_height; index ++)
            {
                /* blit on line buffer */
                blit_line(line_ptr, (rt_uint8_t *)pixels, pitch);
                pixels += dc->pitch;

                /* draw on hardware dc */
                dest->engine->blit_line(dest, rect->x1, rect->x1 + rect_width, index, line_ptr);
            }

            /* release line buffer */
            rtgui_free(line_ptr);
        }
    }
	else if (dest->type == RTGUI_DC_BUFFER)
	{
		struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest;

		if (dest_dc->pixel_format == dc->pixel_format)
		{
			int index;
			rt_uint8_t *pixels, *dest_pixels;
			
			/* get pitch */
			pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);

			pixels = _dc_get_pixel(dc, dc_point->x, dc_point->y);
			dest_pixels = _dc_get_pixel(dest_dc, rect->x1, rect->y1);

			for (index = 0; index < rect_height; index ++)
			{
				memcpy(dest_pixels, pixels, pitch);
				pixels += dc->pitch;
				dest_pixels += dest_dc->pitch;
			}
		}
	}
}
Пример #3
0
/* blit a dc to another dc */
static void rtgui_dc_buffer_blit(struct rtgui_dc *self, struct rtgui_point *dc_pt, struct rtgui_dc *dest, rtgui_rect_t *rect)
{
	int pitch;
	rt_uint16_t rect_width, rect_height;
	struct rtgui_rect _rect, *dest_rect;
    struct rtgui_point dc_point;
    struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;

    if (rtgui_dc_get_visible(dest) == RT_FALSE)
        return;

	/* use the (0,0) origin point */
    if (dc_pt == RT_NULL)
        dc_point = rtgui_empty_point;
    else
    {
        dc_point = *dc_pt;
    }

    rtgui_dc_get_rect(dest, &_rect);
	/* use the rect of dest dc */
	if (rect == RT_NULL)
	{
		dest_rect = &_rect;
	}
	else
    {
        dest_rect = rect;
        if (dest_rect->x1 > _rect.x2 || dest_rect->y1 > _rect.y2)
            return;
        if (dest_rect->x1 < 0)
        {
            if (-dest_rect->x1 > dc->width)
                return;
            dc_point.x += -dest_rect->x1;
            dest_rect->x1 = 0;
        }
        if (dest_rect->y1 < 0)
        {
            if (-dest_rect->y1 > dc->height)
                return;
            dc_point.y += -dest_rect->y1;
            dest_rect->y1 = 0;
        }
        if (dest_rect->x2 > _rect.x2)
            dest_rect->x2 = _rect.x2;
        if (dest_rect->y2 > _rect.y2)
            dest_rect->y2 = _rect.y2;
    }

    if (dc_point.x > dc->width || dc_point.y > dc->height)
        return;

	/* get the minimal width and height */
	rect_width  = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x);
	rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y);

    if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
    {
		int index;
        rt_uint8_t *line_ptr, *pixels;
        rtgui_blit_line_func blit_line;
		struct rtgui_graphic_driver *hw_driver;

		hw_driver = rtgui_graphic_driver_get_default();
        /* prepare pixel line */
		pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);

        if (hw_driver->bits_per_pixel == _dc_get_bits_per_pixel(dc))
        {
			if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL)
			{
				rt_uint8_t *hw_pixels;
				struct rtgui_dc_hw *hw;

				hw = (struct rtgui_dc_hw*)dest;

				/* NOTES: the rect of DC is the logic coordination.
				 * It should be converted to client
				 */
				if (dest_rect != &_rect)
				{
					/* use local rect */
					_rect = *dest_rect;
					dest_rect = &_rect;
				}
				rtgui_rect_moveto(dest_rect, hw->owner->extent.x1, hw->owner->extent.y1);

				pitch = rtgui_color_get_bpp(hw_driver->pixel_format) * rect_width;
				hw_pixels = (rt_uint8_t*)(hw_driver->framebuffer + dest_rect->y1 * hw_driver->pitch +
					dest_rect->x1 * rtgui_color_get_bpp(hw_driver->pixel_format));

				/* do the blit with memory copy */
				for (index = 0; index < rect_height; index ++)
				{
					rt_memcpy(hw_pixels, pixels, pitch);
					pixels += dc->pitch;
					hw_pixels += hw_driver->pitch;
				}
			}
			else
			{
	            /* it's the same bits per pixel, draw it directly */
	            for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index++)
	            {
	                dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, index, pixels);
					pixels += dc->pitch;
	            }
			}
        }
        else
        {
			struct rtgui_graphic_driver *hw_driver;

			hw_driver = rtgui_graphic_driver_get_default();

			if ((dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_ARGB888) && (dest->type == RTGUI_DC_HW) &&
				(hw_driver->framebuffer != RT_NULL) &&
				(hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565))
			{
				/* do the fast ARGB to RGB565 blit */
				struct rtgui_blit_info info;
				struct rtgui_widget *owner;

				/* blit source */
				info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
				info.src_fmt = dc->pixel_format;
				info.src_h = rect_height;
				info.src_w = rect_width;
				info.src_pitch = dc->pitch;
				info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);

				owner = ((struct rtgui_dc_hw*)dest)->owner;

				/* blit destination */
				info.dst = (rt_uint8_t*)hw_driver->framebuffer;
				info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch +
                    (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format);
				info.dst_fmt = hw_driver->pixel_format;
				info.dst_h = rect_height;
				info.dst_w = rect_width;
				info.dst_pitch = hw_driver->pitch;
				info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);

				rtgui_blit(&info);
			}
			else
			{
	            /* get blit line function */
	            blit_line = rtgui_blit_line_get(_UI_BITBYTES(hw_driver->bits_per_pixel), rtgui_color_get_bpp(dc->pixel_format));
	            /* calculate pitch */
	            pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);
	            /* create line buffer */
	            line_ptr = (rt_uint8_t *) rtgui_malloc(rect_width * _UI_BITBYTES(hw_driver->bits_per_pixel));

	            /* draw each line */
	            for (index = dest_rect->y1; index < dest_rect->y1 + rect_height; index ++)
	            {
	                /* blit on line buffer */
	                blit_line(line_ptr, (rt_uint8_t *)pixels, pitch);
	                pixels += dc->pitch;

	                /* draw on hardware dc */
	                dest->engine->blit_line(dest, dest_rect->x1, dest_rect->x1 + rect_width, index, line_ptr);
	            }

	            /* release line buffer */
	            rtgui_free(line_ptr);
			}
        }
    }
	else if (dest->type == RTGUI_DC_BUFFER)
	{
		struct rtgui_dc_buffer *dest_dc = (struct rtgui_dc_buffer*)dest;

		if (dest_dc->pixel_format == dc->pixel_format && dest_dc->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
		{
			int index;
			rt_uint8_t *pixels, *dest_pixels;

			/* get pitch */
			pitch = rect_width * rtgui_color_get_bpp(dc->pixel_format);

			pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);
			dest_pixels = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1);

			for (index = 0; index < rect_height; index ++)
			{
				rt_memcpy(dest_pixels, pixels, pitch);
				pixels += dc->pitch;
				dest_pixels += dest_dc->pitch;
			}
		}
		else /* use rtgui_blit to handle buffer blit */
		{
			/* do the fast ARGB to RGB565 blit */
			struct rtgui_blit_info info;

			/* blit source */
			info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
			info.src_fmt = dc->pixel_format;
			info.src_h = rect_height;
			info.src_w = rect_width;
			info.src_pitch = dc->pitch;
			info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);

			/* blit destination */
			info.dst = _dc_get_pixel(dest_dc, dest_rect->x1, dest_rect->y1);
			info.dst_fmt = dest_dc->pixel_format;
			info.dst_h = rect_height;
			info.dst_w = rect_width;
			info.dst_pitch = dest_dc->pitch;
			info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(dest_dc->pixel_format);

			rtgui_blit(&info);
		}
	}
}
Пример #4
0
/* blit a dc to another dc */
static void rtgui_dc_buffer_blit(struct rtgui_dc *self,
                                 struct rtgui_point *dc_pt,
                                 struct rtgui_dc *dest,
                                 rtgui_rect_t *rect)
{
    int pitch;
    rt_uint16_t rect_width, rect_height;
    struct rtgui_rect _rect, *dest_rect;
    struct rtgui_point dc_point;
    struct rtgui_dc_buffer *dc = (struct rtgui_dc_buffer *)self;

    if (rtgui_dc_get_visible(dest) == RT_FALSE)
        return;

    /* use the (0,0) origin point */
    if (dc_pt == RT_NULL)
        dc_point = rtgui_empty_point;
    else
    {
        dc_point = *dc_pt;
    }

    rtgui_dc_get_rect(dest, &_rect);
    /* use the rect of dest dc */
    if (rect == RT_NULL)
    {
        dest_rect = &_rect;
    }
    else
    {
        dest_rect = rect;
        if (dest_rect->x1 >= _rect.x2 || dest_rect->y1 >= _rect.y2)
            return;
        if (dest_rect->x1 < 0)
        {
            if (-dest_rect->x1 >= dc->width)
                return;
            dc_point.x += -dest_rect->x1;
            dest_rect->x1 = 0;
        }
        if (dest_rect->y1 < 0)
        {
            if (-dest_rect->y1 >= dc->height)
                return;
            dc_point.y += -dest_rect->y1;
            dest_rect->y1 = 0;
        }
        if (dest_rect->x2 > _rect.x2)
            dest_rect->x2 = _rect.x2;
        if (dest_rect->y2 > _rect.y2)
            dest_rect->y2 = _rect.y2;
    }

    if (dest_rect->x2 < dest_rect->x1 || dest_rect->y2 < dest_rect->y1) return;
    if (dc_point.x >= dc->width || dc_point.y >= dc->height) return;

    /* get the minimal width and height */
    rect_width  = _UI_MIN(rtgui_rect_width(*dest_rect), dc->width - dc_point.x);
    rect_height = _UI_MIN(rtgui_rect_height(*dest_rect), dc->height - dc_point.y);

    if ((dest->type == RTGUI_DC_HW) || (dest->type == RTGUI_DC_CLIENT))
    {
        int index;
        rt_uint8_t *line_ptr, *pixels;
        rtgui_blit_line_func blit_line;
        struct rtgui_graphic_driver *hw_driver;

        hw_driver = rtgui_graphic_driver_get_default();
        /* prepare pixel line */
        pixels = _dc_get_pixel(dc, dc_point.x, dc_point.y);

        if (dest->type == RTGUI_DC_HW && hw_driver->framebuffer != RT_NULL)
        {
            /* use rtgui_blit */

            struct rtgui_blit_info info = { 0 };
            struct rtgui_widget *owner;

            if (self->type == RTGUI_DC_BUFFER)
                info.a = dc->pixel_alpha;
            else
                info.a = 255;

            /* blit source */
            info.src = _dc_get_pixel(dc, dc_point.x, dc_point.y);
            info.src_fmt = dc->pixel_format;
            info.src_h = rect_height;
            info.src_w = rect_width;
            info.src_pitch = dc->pitch;
            info.src_skip = info.src_pitch - info.src_w * rtgui_color_get_bpp(dc->pixel_format);

            owner = ((struct rtgui_dc_hw*)dest)->owner;

            /* blit destination */
            info.dst = (rt_uint8_t*)hw_driver->framebuffer;
            info.dst = info.dst + (owner->extent.y1 + dest_rect->y1) * hw_driver->pitch +
                       (owner->extent.x1 + dest_rect->x1) * rtgui_color_get_bpp(hw_driver->pixel_format);
            info.dst_fmt = hw_driver->pixel_format;
            info.dst_h = rect_height;
            info.dst_w = rect_width;
            info.dst_pitch = hw_driver->pitch;
            info.dst_skip = info.dst_pitch - info.dst_w * rtgui_color_get_bpp(hw_driver->pixel_format);

            rtgui_blit(&info);
        }
        else if (dest->type == RTGUI_DC_CLIENT&& hw_driver->framebuffer != RT_NULL)
        {
            /* use rtgui_blit */
            rt_uint8_t bpp, hw_bpp;
            struct rtgui_blit_info info = { 0 };
            struct rtgui_widget *owner;
            struct rtgui_region dest_region;
            struct rtgui_rect dest_extent;
            int num_rects;
            struct rtgui_rect *rects;

            /* get owner */
            owner = RTGUI_CONTAINER_OF(dest, struct rtgui_widget, dc_type);

            dest_extent = *dest_rect;
            rtgui_widget_rect_to_device(owner, &dest_extent);

            rtgui_region_init_with_extents(&dest_region, &dest_extent);
            rtgui_region_intersect_rect(&dest_region, &(owner->clip), &dest_extent);
            bpp = rtgui_color_get_bpp(dc->pixel_format);
            hw_bpp = rtgui_color_get_bpp(hw_driver->pixel_format);

            num_rects = rtgui_region_num_rects(&dest_region);
            rects = rtgui_region_rects(&dest_region);

            /* common info */
            if (self->type == RTGUI_DC_BUFFER)
                info.a = dc->pixel_alpha;
            else
                info.a = 255;
            info.src_fmt = dc->pixel_format;
            info.src_pitch = dc->pitch;

            info.dst_fmt = hw_driver->pixel_format;
            info.dst_pitch = hw_driver->pitch;

            for (index = 0; index < num_rects; index ++)
            {
                struct rtgui_rect *r = &rects[index];

                /* blit source */
                info.src = _dc_get_pixel(dc, dc_point.x + (r->x1 - dest_extent.x1),
                                         dc_point.y + (r->y1 - dest_extent.y1));
                info.src_h = rtgui_rect_height(*r);
                info.src_w = rtgui_rect_width(*r);
                info.src_skip = info.src_pitch - info.src_w * bpp;

                /* blit destination */
                info.dst = (rt_uint8_t*)hw_driver->framebuffer + r->y1 * hw_driver->pitch +
                           r->x1 * hw_bpp;
                info.dst_h = rtgui_rect_height(*r);
                info.dst_w = rtgui_rect_width(*r);
                info.dst_skip = info.dst_pitch - info.dst_w * hw_bpp;

                rtgui_blit(&info);
            }

            rtgui_region_fini(&dest_region);
        }