Procházet zdrojové kódy

SharedGraphics: Fix blitting GraphicsBitmaps with clipping enabled.

Andreas Kling před 6 roky
rodič
revize
4a7120afe1
1 změnil soubory, kde provedl 61 přidání a 53 odebrání
  1. 61 53
      SharedGraphics/Painter.cpp

+ 61 - 53
SharedGraphics/Painter.cpp

@@ -212,15 +212,15 @@ void Painter::draw_bitmap(const Point& p, const CharacterBitmap& bitmap, Color c
 
 void Painter::draw_bitmap(const Point& p, const GlyphBitmap& bitmap, Color color)
 {
-    Rect rect { p, bitmap.size() };
-    rect.move_by(m_translation);
-    auto clipped_rect = Rect::intersection(rect, m_clip_rect);
+    Rect dst_rect { p, bitmap.size() };
+    dst_rect.move_by(m_translation);
+    auto clipped_rect = Rect::intersection(dst_rect, m_clip_rect);
     if (clipped_rect.is_empty())
         return;
-    const int first_row = clipped_rect.top() - rect.top();
-    const int last_row = clipped_rect.bottom() - rect.top();
-    const int first_column = clipped_rect.left() - rect.left();
-    const int last_column = clipped_rect.right() - rect.left();
+    const int first_row = clipped_rect.top() - dst_rect.top();
+    const int last_row = clipped_rect.bottom() - dst_rect.top();
+    const int first_column = clipped_rect.left() - dst_rect.left();
+    const int last_column = clipped_rect.right() - dst_rect.left();
     RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x();
     const size_t dst_skip = m_target->width();
 
@@ -233,6 +233,60 @@ void Painter::draw_bitmap(const Point& p, const GlyphBitmap& bitmap, Color color
     }
 }
 
+void Painter::blit_with_alpha(const Point& position, const GraphicsBitmap& source, const Rect& src_rect)
+{
+    Rect dst_rect(position, src_rect.size());
+    dst_rect.move_by(m_translation);
+    auto clipped_rect = Rect::intersection(dst_rect, m_clip_rect);
+    if (clipped_rect.is_empty())
+        return;
+    const int first_row = clipped_rect.top() - dst_rect.top();
+    const int last_row = clipped_rect.bottom() - dst_rect.top();
+    const int first_column = clipped_rect.left() - dst_rect.left();
+    const int last_column = clipped_rect.right() - dst_rect.left();
+    RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x();
+    const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column;
+    const size_t dst_skip = m_target->width();
+    const unsigned src_skip = source.width();
+
+    for (int row = first_row; row <= last_row; ++row) {
+        for (int x = 0; x <= (last_column - first_column); ++x) {
+            byte alpha = Color(src[x]).alpha();
+            if (alpha == 0xff)
+                dst[x] = src[x];
+            else if (!alpha)
+                continue;
+            else
+                dst[x] = Color(dst[x]).blend(src[x]).value();
+        }
+        dst += dst_skip;
+        src += src_skip;
+    }
+}
+
+void Painter::blit(const Point& position, const GraphicsBitmap& source, const Rect& src_rect)
+{
+    Rect dst_rect(position, src_rect.size());
+    dst_rect.move_by(m_translation);
+    auto clipped_rect = Rect::intersection(dst_rect, m_clip_rect);
+    if (clipped_rect.is_empty())
+        return;
+    const int first_row = clipped_rect.top() - dst_rect.top();
+    const int last_row = clipped_rect.bottom() - dst_rect.top();
+    const int first_column = clipped_rect.left() - dst_rect.left();
+    const int last_column = clipped_rect.right() - dst_rect.left();
+    RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x();
+    const RGBA32* src = source.scanline(src_rect.top() + first_row) + src_rect.left() + first_column;
+    const size_t dst_skip = m_target->width();
+    const unsigned src_skip = source.width();
+
+    for (int row = first_row; row <= last_row; ++row) {
+        fast_dword_copy(dst, src, dst_rect.width());
+        dst += dst_skip;
+        src += src_skip;
+    }
+}
+
 FLATTEN void Painter::draw_glyph(const Point& point, char ch, Color color)
 {
     draw_bitmap(point, font().glyph_bitmap(ch), color);
@@ -365,52 +419,6 @@ void Painter::draw_focus_rect(const Rect& rect)
     draw_rect(focus_rect, Color(96, 96, 192));
 }
 
-void Painter::blit(const Point& position, const GraphicsBitmap& source, const Rect& src_rect)
-{
-    Rect dst_rect(position, src_rect.size());
-    dst_rect.move_by(m_translation);
-    dst_rect.intersect(m_clip_rect);
-
-    RGBA32* dst = m_target->scanline(dst_rect.y()) + dst_rect.x();
-    const RGBA32* src = source.scanline(src_rect.top()) + src_rect.left();
-
-    const unsigned dst_skip = m_target->width();
-    const unsigned src_skip = source.width();
-
-    for (int i = dst_rect.height() - 1; i >= 0; --i) {
-        fast_dword_copy(dst, src, dst_rect.width());
-        dst += dst_skip;
-        src += src_skip;
-    }
-}
-
-void Painter::blit_with_alpha(const Point& position, const GraphicsBitmap& source, const Rect& src_rect)
-{
-    Rect dst_rect(position, src_rect.size());
-    dst_rect.move_by(m_translation);
-    dst_rect.intersect(m_clip_rect);
-
-    RGBA32* dst = m_target->scanline(dst_rect.y()) + dst_rect.x();
-    const RGBA32* src = source.scanline(src_rect.top()) + src_rect.left();
-
-    const unsigned dst_skip = m_target->width();
-    const unsigned src_skip = source.width();
-
-    for (int i = dst_rect.height() - 1; i >= 0; --i) {
-        for (int x = 0; x < dst_rect.width(); ++x) {
-            byte alpha = Color(src[x]).alpha();
-            if (alpha == 0xff)
-                dst[x] = src[x];
-            else if (!alpha)
-                continue;
-            else
-                dst[x] = Color(dst[x]).blend(src[x]).value();
-        }
-        dst += dst_skip;
-        src += src_skip;
-    }
-}
-
 void Painter::set_clip_rect(const Rect& rect)
 {
     m_clip_rect = Rect::intersection(rect, m_target->rect());