Sfoglia il codice sorgente

Merge pull request #51 from yangfasheng/master

  update blit.c
yangfasheng 7 anni fa
parent
commit
f8f4012aa6
4 ha cambiato i file con 202 aggiunte e 8 eliminazioni
  1. 6 6
      include/rtgui/rtgui_config.h
  2. 194 0
      src/blit.c
  3. 1 1
      src/dc_buffer.c
  4. 1 1
      src/image_jpg.c

+ 6 - 6
include/rtgui/rtgui_config.h

@@ -67,12 +67,12 @@
 
 #define GUIENGIN_USING_VFRAMEBUFFER
 
-#ifndef PKG_USING_RGB888_PIXEL_BITS_32
-#ifndef PKG_USING_RGB888_PIXEL_BITS_24
-#define PKG_USING_RGB888_PIXEL_BITS_32
-#define PKG_USING_RGB888_PIXEL_BITS 32
-#endif
-#endif
+//#ifndef PKG_USING_RGB888_PIXEL_BITS_32
+//#ifndef PKG_USING_RGB888_PIXEL_BITS_24
+//#define PKG_USING_RGB888_PIXEL_BITS_32
+//#define PKG_USING_RGB888_PIXEL_BITS 32
+//#endif
+//#endif
 
 #ifdef DEBUG_MEMLEAK
 #define rtgui_malloc     rt_malloc

+ 194 - 0
src/blit.c

@@ -1457,6 +1457,185 @@ static void BlitAlphatoARGB888PixelAlpha(struct rtgui_blit_info *info)
     }
 }
 
+/* alpha color -> RGB565 blending with alpha */
+static void BlitAlphaColortoRGB565PixelAlpha(struct rtgui_blit_info * info)
+{
+    rt_uint32_t srcR, srcG, srcB, srcA;
+    rt_uint32_t height = info->dst_h;
+    rt_uint16_t *dst = (rt_uint16_t *)info->dst;
+    rt_uint32_t dst_skip = info->dst_skip >> 1;
+
+    srcA = info->a;
+    srcR = info->r;
+    srcG = info->g;
+    srcB = info->b;
+
+    while (height--)
+    {
+        rt_uint32_t width = info->dst_w;
+        while (width--)
+        {
+            /* not do alpha blend */
+            if ((srcA >> 3) == (0xFFU >> 3))
+            {
+                RGB565_FROM_RGB(*dst, srcR, srcG, srcB);
+            }
+            else if ((srcA >> 3) == 0)
+            {
+                /* keep original pixel data */
+            }
+            else
+            {
+                rt_uint32_t dstR, dstG, dstB;
+                rt_uint32_t inverse_alpha = 255 - srcA;
+
+                RGB_FROM_RGB565(*dst, dstR, dstG, dstB);
+
+                dstR = ((srcR * srcA) + (inverse_alpha * dstR)) >> 8;
+                dstG = ((srcG * srcA) + (inverse_alpha * dstG)) >> 8;
+                dstB = ((srcB * srcA) + (inverse_alpha * dstB)) >> 8;
+
+                RGB565_FROM_RGB(*dst, dstR, dstG, dstB);
+            }
+            dst++;
+        }
+        dst += dst_skip;
+    }
+}
+
+/* alpha color -> RGB888 blending with alpha */
+static void BlitAlphaColortoRGB888PixelAlpha(struct rtgui_blit_info *info)
+{
+    rt_uint32_t srcR, srcG, srcB, srcA;
+    rt_uint32_t height = info->dst_h;
+#ifdef PKG_USING_RGB888_PIXEL_BITS_32
+    rt_uint32_t *dst = (rt_uint32_t *)info->dst;
+    rt_uint32_t dst_skip = info->dst_skip >> 2;
+#else
+    rt_uint8_t *dst = (rt_uint8_t *)info->dst;
+    rt_uint32_t dst_skip = info->dst_skip;
+#endif
+
+    srcA = info->a;
+    srcR = info->r;
+    srcG = info->g;
+    srcB = info->b;
+
+    while (height--)
+    {
+        int width = info->dst_w;
+        while (width--)
+        {
+            /* not do alpha blend */
+            if ((srcA >> 3) == (0xFFU >> 3))
+            {
+                if (PKG_USING_RGB888_PIXEL_BITS == 32)
+                {
+                    RGB888_FROM_RGB(*dst, srcR, srcG, srcB);
+                    dst++;
+                }
+                else
+                {
+                    *dst++ = srcR;
+                    *dst++ = srcG;
+                    *dst++ = srcB;
+                }
+            }
+            else if ((srcA >> 3) == 0)
+            {
+                /* keep original pixel data */
+            }
+            else
+            {
+                rt_uint32_t dstR, dstG, dstB;
+                rt_uint32_t inverse_alpha = 255 - srcA;
+
+                if (PKG_USING_RGB888_PIXEL_BITS == 32)
+                {
+                    RGB_FROM_RGB888(*dst, dstR, dstG, dstB);
+                }
+                else
+                {
+                    dstR = *dst;
+                    dstG = *(dst + 1);
+                    dstB = *(dst + 2);
+                }
+
+                dstR = ((srcR * srcA) + (inverse_alpha * dstR)) >> 8;
+                dstG = ((srcG * srcA) + (inverse_alpha * dstG)) >> 8;
+                dstB = ((srcB * srcA) + (inverse_alpha * dstB)) >> 8;
+
+                if (PKG_USING_RGB888_PIXEL_BITS == 32)
+                {
+                    RGB888_FROM_RGB(*dst, dstR, dstG, dstB);
+                    dst++;
+                }
+                else
+                {
+                    *dst++ = dstR;
+                    *dst++ = dstG;
+                    *dst++ = dstB;
+                }
+            }
+        }
+
+        dst += dst_skip;
+    }
+}
+
+/* alpha color -> ARGB888 blending with alpha */
+static void BlitAlphaColortoARGB888PixelAlpha(struct rtgui_blit_info *info)
+{
+    rt_uint32_t srcR, srcG, srcB, srcA;
+    rt_uint32_t height = info->dst_h;
+    rt_uint32_t *dst = (rt_uint32_t *)info->dst;
+    rt_uint32_t dst_skip = info->dst_skip >> 2;
+
+    srcA = info->a;
+    srcR = info->r;
+    srcG = info->g;
+    srcB = info->b;
+
+    while (height--)
+    {
+        rt_uint32_t width = info->dst_w;
+        while (width--)
+        {
+            /* not do alpha blend */
+            if ((srcA >> 3) == (0xFFU >> 3))
+            {
+                ARGB8888_FROM_RGBA(*dst, srcR, srcG, srcB, 0xFFU);
+            }
+            else if ((srcA >> 3) == 0)
+            {
+                /* keep original pixel data */
+            }
+            else
+            {
+                rt_uint32_t dstR, dstG, dstB, dstA;
+                rt_uint32_t inverse_alpha = 0xFFU - srcA;
+
+                RGBA_FROM_ARGB8888(*dst, dstR, dstG, dstB, dstA);
+                if (dstA)
+                {
+                    dstR = ((srcR * srcA) + (inverse_alpha * dstR)) >> 8;
+                    dstG = ((srcG * srcA) + (inverse_alpha * dstG)) >> 8;
+                    dstB = ((srcB * srcA) + (inverse_alpha * dstB)) >> 8;
+                    dstA = srcA + ((0xFFU - srcA) * dstA) / 0xFFU;
+
+                    ARGB8888_FROM_RGBA(*dst, dstR, dstG, dstB, dstA);
+                }
+                else
+                {
+                    ARGB8888_FROM_RGBA(*dst, srcR, srcG, srcB, srcA);
+                }
+            }
+            dst++;
+        }
+        dst += dst_skip;
+    }
+}
+
 void rtgui_blit(struct rtgui_blit_info *info)
 {
     if (info->src_h == 0 ||
@@ -1542,6 +1721,21 @@ void rtgui_blit(struct rtgui_blit_info *info)
             break;
         }
     }
+    else if (info->src_fmt == RTGRAPHIC_PIXEL_FORMAT_COLOR)
+    {
+        switch (info->dst_fmt)
+        {
+        case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+            BlitAlphaColortoRGB565PixelAlpha(info);
+            break;
+        case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+            BlitAlphaColortoRGB888PixelAlpha(info);
+            break;
+        case RTGRAPHIC_PIXEL_FORMAT_ARGB888:
+            BlitAlphaColortoARGB888PixelAlpha(info);
+            break;
+        }
+    }
 }
 RTM_EXPORT(rtgui_blit);
 

+ 1 - 1
src/dc_buffer.c

@@ -684,7 +684,7 @@ static void rtgui_dc_buffer_blit_line(struct rtgui_dc *self, int x1, int x2, int
     if (x1 < 0)
         x1 = 0;
     if (x2 >= dc->width)
-        x2 = dc->width-1;
+        x2 = dc->width;
 
     pixel = _dc_get_pixel(dc,x1,y);
     memcpy(pixel, line_data, (x2 - x1) * rtgui_color_get_bpp(dc->pixel_format));

+ 1 - 1
src/image_jpg.c

@@ -930,7 +930,7 @@ static void rtgui_image_jpeg_blit(struct rtgui_image *image,
     {
         if ((rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB888 && jpeg->tjpgd.format == 0) ||
                 (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_RGB565 && jpeg->tjpgd.format == 1) ||
-                (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_ARGB888 && jpeg->tjpgd.format == 0))
+                (rtgui_dc_get_pixel_format(dc) == RTGRAPHIC_PIXEL_FORMAT_ARGB888 && jpeg->tjpgd.format == 0 && PKG_USING_RGB888_PIXEL_BITS == 32))
         {
             rt_uint16_t imageWidth = image->w * jpeg->byte_per_pixel;
             rt_uint8_t *src = jpeg->pixels + yoff * imageWidth + xoff * jpeg->byte_per_pixel;