1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:47:44 +00:00

WindowServer: Implement scaled backgrounds and scaled blitting function

This commit is contained in:
Christopher Dumas 2019-06-05 09:23:27 -07:00 committed by Andreas Kling
parent c72953cf06
commit 90d924a97c
3 changed files with 35 additions and 5 deletions

View file

@ -104,10 +104,10 @@ void WSCompositor::compose()
} else if (m_wallpaper_mode == WallpaperMode::Tile) {
m_back_painter->blit_tiled(dirty_rect.location(), *m_wallpaper, dirty_rect);
} else {
// FIXME: Does not work: offset rect creates trails.
m_back_painter->draw_scaled_bitmap(dirty_rect, *m_wallpaper,
{ dirty_rect.location(),
m_wallpaper->size() });
float hscale = (float)m_wallpaper->size().width() / (float)ws.size().width();
float vscale = (float)m_wallpaper->size().height() / (float)ws.size().height();
m_back_painter->blit_scaled(dirty_rect.location(), *m_wallpaper, dirty_rect, hscale, vscale);
}
}
}

View file

@ -204,6 +204,36 @@ void Painter::draw_bitmap(const Point& p, const GlyphBitmap& bitmap, Color color
}
}
void Painter::blit_scaled(const Point& position, const GraphicsBitmap& source, const Rect& src_rect, float hscale, float vscale)
{
auto dst_rect = Rect(position, src_rect.size()).translated(translation());
auto clipped_rect = dst_rect.intersected(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());
RGBA32* dst = m_target->scanline(clipped_rect.y()) + clipped_rect.x();
const size_t dst_skip = m_target->pitch() / sizeof(RGBA32);
int x_start = first_column + src_rect.left();
for (int row = first_row; row <= last_row; ++row) {
int sr = (row + src_rect.top()) * vscale;
if (sr >= source.size().height() || sr < 0) {
dst += dst_skip;
continue;
}
const RGBA32* sl = source.scanline(sr);
for (int x = x_start; x < clipped_rect.width() + x_start; ++x) {
int sx = x * hscale;
if (sx < source.size().width() && sx >= 0)
dst[x - x_start] = sl[sx];
}
dst += dst_skip;
}
return;
}
void Painter::blit_with_opacity(const Point& position, const GraphicsBitmap& source, const Rect& src_rect, float opacity)
{
ASSERT(!m_target->has_alpha_channel());

View file

@ -29,7 +29,7 @@ public:
void blit_dimmed(const Point&, const GraphicsBitmap&, const Rect& src_rect);
void blit_tiled(const Point&, const GraphicsBitmap&, const Rect& src_rect);
void blit_offset(const Point&, const GraphicsBitmap&, const Rect& src_rect, const Point&);
void blit_scaled(const Point&, const GraphicsBitmap&, const Rect& src_rect, const Size&);
void blit_scaled(const Point&, const GraphicsBitmap&, const Rect&, float, float);
void draw_text(const Rect&, const StringView&, const Font&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
void draw_text(const Rect&, const StringView&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None);
void draw_glyph(const Point&, char, Color);