Skip to content

Commit 7099f14

Browse files
committed
Added fit image to available space option.
1 parent 5db445d commit 7099f14

File tree

2 files changed

+68
-18
lines changed

2 files changed

+68
-18
lines changed

lib/include/elements/element/image.hpp

+12-3
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,17 @@ namespace cycfi { namespace elements
2222
class image : public element
2323
{
2424
public:
25+
26+
struct fit_enum{};
27+
28+
// Use `fit` as constructor param to allow the image to fit available
29+
// space while keeping source image aspect ratio.
30+
static constexpr auto fit = fit_enum{};
31+
2532
image(fs::path const& path, float scale = 1);
26-
image(image_ptr pixmap_, float scale = 1);
33+
image(image_ptr img, float scale = 1);
34+
image(fs::path const& path, fit_enum);
35+
image(image_ptr pixmap_, fit_enum);
2736

2837
virtual point size() const;
2938
float scale() const { return _scale; }
@@ -33,11 +42,11 @@ namespace cycfi { namespace elements
3342

3443
protected:
3544

36-
artist::image& pixmap() const { return *_pixmap.get(); }
45+
artist::image& get_image() const { return *_image.get(); }
3746

3847
private:
3948

40-
image_ptr _pixmap;
49+
image_ptr _image;
4150
float _scale;
4251
};
4352

lib/src/element/image.cpp

+56-15
Original file line numberDiff line numberDiff line change
@@ -14,42 +14,83 @@ namespace cycfi { namespace elements
1414
// image implementation
1515
////////////////////////////////////////////////////////////////////////////
1616
image::image(fs::path const& path, float scale)
17-
: _pixmap(std::make_shared<artist::image>(path))
17+
: _image(std::make_shared<artist::image>(path))
1818
, _scale(scale)
1919
{
20-
if (!_pixmap->impl())
20+
if (!_image->impl())
2121
throw std::runtime_error{"Error: Invalid image."};
2222
}
2323

24-
image::image(image_ptr pixmap_, float scale)
25-
: _pixmap(pixmap_)
24+
image::image(image_ptr image_, float scale)
25+
: _image(image_)
2626
, _scale(scale)
2727
{
28-
if (!_pixmap->impl())
28+
if (!_image->impl())
2929
throw std::runtime_error{"Error: Invalid image."};
3030
}
3131

32+
image::image(fs::path const& path, fit_enum)
33+
: image{path, -1}
34+
{
35+
}
36+
37+
image::image(image_ptr image_, fit_enum)
38+
: image{image_, -1}
39+
{
40+
}
41+
3242
point image::size() const
3343
{
34-
auto s = _pixmap->size();
35-
return {s.x * _scale, s.y * _scale};
44+
auto s = _image->size();
45+
if (_scale > 0)
46+
return {s.x * _scale, s.y * _scale};
47+
else // fit
48+
return {-1, -1}; // We do not know the actual size
3649
}
3750

3851
rect image::source_rect(context const& ctx) const
3952
{
40-
return {0, 0, ctx.bounds.width() / _scale, ctx.bounds.height() / _scale};
53+
if (_scale > 0)
54+
{
55+
return {0, 0, ctx.bounds.width() / _scale, ctx.bounds.height() / _scale};
56+
}
57+
else // fit
58+
{
59+
auto s = _image->size();
60+
return {0, 0, s.x, s.y};
61+
}
4162
}
4263

4364
view_limits image::limits(basic_context const& /* ctx */) const
4465
{
45-
auto size_ = size();
46-
return {{size_.x, size_.y}, {size_.x, size_.y}};
66+
if (_scale > 0)
67+
{
68+
auto size_ = size();
69+
return {{size_.x, size_.y}, {size_.x, size_.y}};
70+
}
71+
else // fit
72+
{
73+
return full_limits;
74+
}
4775
}
4876

4977
void image::draw(context const& ctx)
5078
{
5179
auto src = source_rect(ctx);
52-
ctx.canvas.draw(pixmap(), src, ctx.bounds);
80+
if (_scale > 0)
81+
{
82+
ctx.canvas.draw(get_image(), src, ctx.bounds);
83+
}
84+
else
85+
{
86+
float aspect_ratio = src.width() / src.height();
87+
auto dest = ctx.bounds;
88+
if (auto h = dest.width() / aspect_ratio; h <= ctx.bounds.height())
89+
dest.height(dest.width() / aspect_ratio);
90+
else
91+
dest.width(dest.height() * aspect_ratio);
92+
ctx.canvas.draw(get_image(), src, center(dest, ctx.bounds));
93+
}
5394
}
5495

5596
basic_sprite::basic_sprite(fs::path const& path, float height, float scale)
@@ -60,13 +101,13 @@ namespace cycfi { namespace elements
60101

61102
view_limits basic_sprite::limits(basic_context const& /* ctx */) const
62103
{
63-
auto width = pixmap().size().x;
104+
auto width = get_image().size().x;
64105
return {{width * scale(), _height}, {width * scale(), _height}};
65106
}
66107

67108
std::size_t basic_sprite::num_frames() const
68109
{
69-
return (pixmap().size().y * scale()) / _height;
110+
return (get_image().size().y * scale()) / _height;
70111
}
71112

72113
void basic_sprite::index(std::size_t index_)
@@ -77,13 +118,13 @@ namespace cycfi { namespace elements
77118

78119
point basic_sprite::size() const
79120
{
80-
return {pixmap().size().x * scale(), _height};
121+
return {get_image().size().x * scale(), _height};
81122
}
82123

83124
rect basic_sprite::source_rect(context const& /* ctx */) const
84125
{
85126
auto sc = scale();
86-
auto width = pixmap().size().x;
127+
auto width = get_image().size().x;
87128
return rect{0, (_height/sc) * _index, width, (_height/sc) * (_index + 1)};
88129
}
89130
}}

0 commit comments

Comments
 (0)