示例#1
0
void rtgui_dc_trans_get_new_wh(struct rtgui_dc_trans *dct,
                               int *new_wp,
                               int *new_hp)
{
    struct rtgui_rect rect;
    struct rtgui_point topleft, topright, bottomright;

    RT_ASSERT(dct);

    if (!new_wp && !new_hp)
        return;

    rtgui_dc_get_rect(dct->owner, &rect);

    /* We ignore the movement components in the matrix. */
    /* Transform result of (0, h). */
    rtgui_matrix_mul_point_nomove(&topleft, 0, rect.y2,
                                  &dct->m);
    /* Transform result of (w, h). */
    rtgui_matrix_mul_point_nomove(&topright, rect.x2, rect.y2,
                                  &dct->m);
    /* Transform result of (w, 0). */
    rtgui_matrix_mul_point_nomove(&bottomright,
                                   rect.x2, 0, &dct->m);
    /* Transform result of (0, 0) is always (0, 0). */

#define NORMALIZE(x) do { if (x < 0) x = 0; } while (0)
    if (new_wp)
    {
        int neww;

        /* Ignore the nagtive parts. */
        NORMALIZE(topright.x);
        NORMALIZE(topleft.x);
        NORMALIZE(bottomright.x);

        neww = _UI_MAX(topright.x, _UI_ABS(topleft.x - bottomright.x))
            + dct->m.m[4] + 1;
        NORMALIZE(neww);

        *new_wp = neww;
    }
    if (new_hp)
    {
        int newh;

        NORMALIZE(topright.y);
        NORMALIZE(topleft.y);
        NORMALIZE(bottomright.y);

        newh = _UI_MAX(topright.y, _UI_ABS(topleft.y - bottomright.y))
            + dct->m.m[5] + 1;
        NORMALIZE(newh);

        *new_hp = newh;
    }
#undef NORMALIZE
}
示例#2
0
static void _rtgui_plot_curve_onpaint(
    struct rtgui_dc *dc,
    struct rtgui_plot *plot,
    struct rtgui_plot_curve *curve,
    rt_uint16_t start_idx,
    rt_uint16_t stop_idx)
{
    struct rtgui_rect rect;
    rt_uint16_t height;
    int last_x, last_y;
    rtgui_color_t old_color;
    rtgui_plot_curve_dtype *x_data, *y_data;

    rtgui_dc_get_rect(dc, &rect);
    height = rtgui_rect_height(rect);

    old_color = RTGUI_DC_FC(dc);
    RTGUI_DC_FC(dc) = curve->color;

    x_data = rtgui_plot_curve_get_x(curve);
    y_data = rtgui_plot_curve_get_y(curve);
    if (x_data)
    {
        rt_size_t i;

        last_x = _rtgui_plot_curve_calc_x(plot, x_data[start_idx]);
        last_y = _rtgui_plot_curve_calc_y(plot, y_data[start_idx], height);
        for (i = start_idx + 1; i < stop_idx; i++)
        {
            int cur_x = _rtgui_plot_curve_calc_x(plot, x_data[i]);
            int cur_y = _rtgui_plot_curve_calc_y(plot, y_data[i], height);
            rtgui_dc_draw_line(dc,
                               last_x, last_y,
                               cur_x, cur_y);
            last_x = cur_x;
            last_y = cur_y;
        }
    }
    else
    {
        rt_size_t i;

        last_x = _rtgui_plot_curve_calc_x(plot, start_idx);
        last_y = _rtgui_plot_curve_calc_y(plot, y_data[start_idx], height);
        for (i = start_idx + 1; i < stop_idx; i++)
        {
            int cur_x = _rtgui_plot_curve_calc_x(plot, i);
            int cur_y = _rtgui_plot_curve_calc_y(plot, y_data[i], height);
            rtgui_dc_draw_line(dc,
                               last_x, last_y,
                               cur_x, cur_y);
            last_x = cur_x;
            last_y = cur_y;
        }
    }
    RTGUI_DC_FC(dc) = old_color;
}
示例#3
0
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;
    }
}
示例#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 (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);
		}
	}
}
示例#5
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);
        }