2020-03-09 16:09:22 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2020, Till Mayer <till.mayer@web.de>
|
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-03-09 16:09:22 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "Card.h"
|
|
|
|
#include <LibGUI/Widget.h>
|
|
|
|
#include <LibGfx/Font.h>
|
2020-12-29 18:25:13 +01:00
|
|
|
#include <LibGfx/FontDatabase.h>
|
2020-03-09 16:09:22 +01:00
|
|
|
|
2021-05-20 13:01:14 +02:00
|
|
|
namespace Cards {
|
2021-05-05 09:42:59 -04:00
|
|
|
|
2020-03-09 16:09:22 +01:00
|
|
|
static const NonnullRefPtr<Gfx::CharacterBitmap> s_diamond = Gfx::CharacterBitmap::create_from_ascii(
|
|
|
|
" # "
|
|
|
|
" ### "
|
|
|
|
" ##### "
|
|
|
|
" ####### "
|
|
|
|
"#########"
|
|
|
|
" ####### "
|
|
|
|
" ##### "
|
|
|
|
" ### "
|
|
|
|
" # ",
|
|
|
|
9, 9);
|
|
|
|
|
|
|
|
static const NonnullRefPtr<Gfx::CharacterBitmap> s_heart = Gfx::CharacterBitmap::create_from_ascii(
|
|
|
|
" # # "
|
|
|
|
" ### ### "
|
|
|
|
"#########"
|
|
|
|
"#########"
|
|
|
|
"#########"
|
|
|
|
" ####### "
|
|
|
|
" ##### "
|
|
|
|
" ### "
|
|
|
|
" # ",
|
|
|
|
9, 9);
|
|
|
|
|
|
|
|
static const NonnullRefPtr<Gfx::CharacterBitmap> s_spade = Gfx::CharacterBitmap::create_from_ascii(
|
|
|
|
" # "
|
|
|
|
" ### "
|
|
|
|
" ##### "
|
|
|
|
" ####### "
|
|
|
|
"#########"
|
|
|
|
"#########"
|
|
|
|
" ## # ## "
|
|
|
|
" ### "
|
|
|
|
" ### ",
|
|
|
|
9, 9);
|
|
|
|
|
|
|
|
static const NonnullRefPtr<Gfx::CharacterBitmap> s_club = Gfx::CharacterBitmap::create_from_ascii(
|
|
|
|
" ### "
|
|
|
|
" ##### "
|
|
|
|
" ##### "
|
|
|
|
" ## ### ## "
|
|
|
|
"###########"
|
|
|
|
"###########"
|
|
|
|
"#### # ####"
|
|
|
|
" ## ### ## "
|
|
|
|
" ### ",
|
|
|
|
11, 9);
|
|
|
|
|
|
|
|
static RefPtr<Gfx::Bitmap> s_background;
|
2021-05-26 09:22:19 +02:00
|
|
|
static RefPtr<Gfx::Bitmap> s_background_inverted;
|
2020-03-09 16:09:22 +01:00
|
|
|
|
|
|
|
Card::Card(Type type, uint8_t value)
|
2020-06-10 10:57:59 +02:00
|
|
|
: m_rect(Gfx::IntRect({}, { width, height }))
|
2021-06-03 22:19:58 +02:00
|
|
|
, m_front(*Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { width, height }))
|
2020-03-09 16:09:22 +01:00
|
|
|
, m_type(type)
|
|
|
|
, m_value(value)
|
|
|
|
{
|
2021-02-23 20:42:32 +01:00
|
|
|
VERIFY(value < card_count);
|
2020-06-10 10:57:59 +02:00
|
|
|
Gfx::IntRect paint_rect({ 0, 0 }, { width, height });
|
2020-03-09 16:09:22 +01:00
|
|
|
|
|
|
|
if (s_background.is_null()) {
|
2021-06-03 22:19:58 +02:00
|
|
|
s_background = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, { width, height });
|
2020-03-09 16:09:22 +01:00
|
|
|
Gfx::Painter bg_painter(*s_background);
|
|
|
|
|
2021-05-20 13:01:14 +02:00
|
|
|
auto image = Gfx::Bitmap::load_from_file("/res/icons/cards/buggie-deck.png");
|
2021-02-23 20:42:32 +01:00
|
|
|
VERIFY(!image.is_null());
|
2020-03-09 16:09:22 +01:00
|
|
|
|
|
|
|
float aspect_ratio = image->width() / static_cast<float>(image->height());
|
2020-06-10 10:57:59 +02:00
|
|
|
auto target_size = Gfx::IntSize(static_cast<int>(aspect_ratio * (height - 5)), height - 5);
|
2020-03-09 16:09:22 +01:00
|
|
|
|
2021-06-04 07:40:16 -04:00
|
|
|
bg_painter.fill_rect_with_rounded_corners(paint_rect, Color::Black, card_radius);
|
2021-06-04 09:16:24 +02:00
|
|
|
auto inner_paint_rect = paint_rect.shrunken(2, 2);
|
2021-06-04 07:40:16 -04:00
|
|
|
bg_painter.fill_rect_with_rounded_corners(inner_paint_rect, Color::White, card_radius - 1);
|
2021-06-03 22:19:58 +02:00
|
|
|
|
2020-03-09 16:09:22 +01:00
|
|
|
bg_painter.draw_scaled_bitmap(
|
|
|
|
{ { (width - target_size.width()) / 2, (height - target_size.height()) / 2 }, target_size },
|
|
|
|
*image, image->rect());
|
2021-05-26 09:22:19 +02:00
|
|
|
|
|
|
|
s_background_inverted = invert_bitmap(*s_background);
|
2020-03-09 16:09:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Gfx::Painter painter(m_front);
|
2021-05-20 18:40:48 +02:00
|
|
|
auto& font = Gfx::FontDatabase::default_font().bold_variant();
|
2020-03-09 16:09:22 +01:00
|
|
|
|
|
|
|
auto label = labels[value];
|
2021-06-04 07:40:16 -04:00
|
|
|
painter.fill_rect_with_rounded_corners(paint_rect, Color::Black, card_radius);
|
2021-06-03 22:19:58 +02:00
|
|
|
paint_rect.shrink(2, 2);
|
2021-06-04 07:40:16 -04:00
|
|
|
painter.fill_rect_with_rounded_corners(paint_rect, Color::White, card_radius - 1);
|
2021-06-03 22:19:58 +02:00
|
|
|
|
2020-03-09 16:09:22 +01:00
|
|
|
paint_rect.set_height(paint_rect.height() / 2);
|
|
|
|
paint_rect.shrink(10, 6);
|
|
|
|
|
2021-05-22 11:55:08 +02:00
|
|
|
auto text_rect = Gfx::IntRect { 4, 6, font.width("10"), font.glyph_height() };
|
|
|
|
painter.draw_text(text_rect, label, font, Gfx::TextAlignment::Center, color());
|
2020-03-09 16:09:22 +01:00
|
|
|
|
|
|
|
NonnullRefPtr<Gfx::CharacterBitmap> symbol = s_diamond;
|
|
|
|
switch (m_type) {
|
|
|
|
case Diamonds:
|
|
|
|
symbol = s_diamond;
|
|
|
|
break;
|
|
|
|
case Clubs:
|
|
|
|
symbol = s_club;
|
|
|
|
break;
|
|
|
|
case Spades:
|
|
|
|
symbol = s_spade;
|
|
|
|
break;
|
|
|
|
case Hearts:
|
|
|
|
symbol = s_heart;
|
|
|
|
break;
|
|
|
|
default:
|
2021-02-23 20:42:32 +01:00
|
|
|
VERIFY_NOT_REACHED();
|
2020-03-09 16:09:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
painter.draw_bitmap(
|
2021-05-22 11:55:08 +02:00
|
|
|
{ text_rect.x() + (text_rect.width() - symbol->size().width()) / 2, text_rect.bottom() + 5 },
|
2020-03-09 16:09:22 +01:00
|
|
|
symbol, color());
|
|
|
|
|
|
|
|
for (int y = height / 2; y < height; ++y) {
|
|
|
|
for (int x = 0; x < width; ++x) {
|
|
|
|
m_front->set_pixel(x, y, m_front->get_pixel(width - x - 1, height - y - 1));
|
|
|
|
}
|
|
|
|
}
|
2021-05-26 09:22:19 +02:00
|
|
|
|
|
|
|
m_front_inverted = invert_bitmap(*m_front);
|
2020-03-09 16:09:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Card::~Card()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Card::draw(GUI::Painter& painter) const
|
|
|
|
{
|
2021-02-23 20:42:32 +01:00
|
|
|
VERIFY(!s_background.is_null());
|
2021-05-26 09:22:19 +02:00
|
|
|
if (m_inverted)
|
|
|
|
painter.blit(position(), m_upside_down ? *s_background_inverted : *m_front_inverted, m_front_inverted->rect());
|
|
|
|
else
|
|
|
|
painter.blit(position(), m_upside_down ? *s_background : *m_front, m_front->rect());
|
2020-03-09 16:09:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Card::clear(GUI::Painter& painter, const Color& background_color) const
|
|
|
|
{
|
2021-05-22 07:13:31 +02:00
|
|
|
painter.fill_rect({ old_position(), { width, height } }, background_color);
|
2020-03-09 16:09:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Card::save_old_position()
|
|
|
|
{
|
|
|
|
m_old_position = m_rect.location();
|
|
|
|
m_old_position_valid = true;
|
|
|
|
}
|
|
|
|
|
2020-10-26 19:34:46 +01:00
|
|
|
void Card::clear_and_draw(GUI::Painter& painter, const Color& background_color)
|
2020-03-09 16:09:22 +01:00
|
|
|
{
|
|
|
|
if (is_old_position_valid())
|
|
|
|
clear(painter, background_color);
|
|
|
|
|
|
|
|
draw(painter);
|
|
|
|
save_old_position();
|
|
|
|
}
|
2021-05-05 09:42:59 -04:00
|
|
|
|
2021-05-26 09:22:19 +02:00
|
|
|
NonnullRefPtr<Gfx::Bitmap> Card::invert_bitmap(Gfx::Bitmap& bitmap)
|
|
|
|
{
|
|
|
|
auto inverted_bitmap = bitmap.clone();
|
|
|
|
VERIFY(inverted_bitmap);
|
|
|
|
for (int y = 0; y < inverted_bitmap->height(); y++) {
|
|
|
|
for (int x = 0; x < inverted_bitmap->width(); x++) {
|
|
|
|
inverted_bitmap->set_pixel(x, y, inverted_bitmap->get_pixel(x, y).inverted());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return *inverted_bitmap;
|
|
|
|
}
|
|
|
|
|
2021-05-05 09:42:59 -04:00
|
|
|
}
|