summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-02-10 07:46:29 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-02-10 07:46:29 +0100
commit4a7120afe197c94aabfdc2613d88c47eb8c6d0e5 (patch)
tree021108e8cce9adb3aa6306bd28f3c863b1f2d33f
parentf7831f8c765f9f898a8113a8b276b25cbcfde0a2 (diff)
downloadserenity-4a7120afe197c94aabfdc2613d88c47eb8c6d0e5.zip
SharedGraphics: Fix blitting GraphicsBitmaps with clipping enabled.
-rw-r--r--SharedGraphics/Painter.cpp114
1 files changed, 61 insertions, 53 deletions
diff --git a/SharedGraphics/Painter.cpp b/SharedGraphics/Painter.cpp
index 8f7ead9c21..fe2ee5448f 100644
--- a/SharedGraphics/Painter.cpp
+++ b/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());