openMSX
OSDRectangle.cc
Go to the documentation of this file.
1#include "OSDRectangle.hh"
2#include "SDLImage.hh"
3#include "CommandException.hh"
4#include "FileContext.hh"
5#include "FileOperations.hh"
6#include "TclObject.hh"
7#include "stl.hh"
8#include "components.hh"
9#include <cassert>
10#include <cmath>
11#include <cstdint>
12#include <memory>
13#if COMPONENT_GL
14#include "GLImage.hh"
15#endif
16
17using namespace gl;
18
19namespace openmsx {
20
22 : OSDImageBasedWidget(display_, name_)
23{
24}
25
27 Interpreter& interp, std::string_view propName, const TclObject& value)
28{
29 if (propName == "-w") {
30 float w = value.getFloat(interp);
31 if (size[0] != w) {
32 size[0] = w;
34 }
35 } else if (propName == "-h") {
36 float h = value.getFloat(interp);
37 if (size[1] != h) {
38 size[1] = h;
40 }
41 } else if (propName == "-relw") {
42 float relw = value.getFloat(interp);
43 if (relSize[0] != relw) {
44 relSize[0] = relw;
46 }
47 } else if (propName == "-relh") {
48 float relh = value.getFloat(interp);
49 if (relSize[1] != relh) {
50 relSize[1] = relh;
52 }
53 } else if (propName == "-scale") {
54 float scale2 = value.getFloat(interp);
55 if (scale != scale2) {
56 scale = scale2;
58 }
59 } else if (propName == "-image") {
60 std::string_view val = value.getString();
61 if (imageName != val) {
62 if (!val.empty()) {
63 if (auto file = systemFileContext().resolve(val);
65 throw CommandException("Not a valid image file: ", val);
66 }
67 }
68 imageName = val;
70 }
71 } else if (propName == "-bordersize") {
72 float newSize = value.getFloat(interp);
73 if (borderSize != newSize) {
74 borderSize = newSize;
76 }
77 } else if (propName == "-relbordersize") {
78 float newSize = value.getFloat(interp);
79 if (relBorderSize != newSize) {
80 relBorderSize = newSize;
82 }
83 } else if (propName == "-borderrgba") {
84 uint32_t newRGBA = value.getInt(interp);
85 if (borderRGBA != newRGBA) {
86 borderRGBA = newRGBA;
88 }
89 } else {
90 OSDImageBasedWidget::setProperty(interp, propName, value);
91 }
92}
93
94void OSDRectangle::getProperty(std::string_view propName, TclObject& result) const
95{
96 if (propName == "-w") {
97 result = size[0];
98 } else if (propName == "-h") {
99 result = size[1];
100 } else if (propName == "-relw") {
101 result = relSize[0];
102 } else if (propName == "-relh") {
103 result = relSize[1];
104 } else if (propName == "-scale") {
105 result = scale;
106 } else if (propName == "-image") {
107 result = imageName;
108 } else if (propName == "-bordersize") {
109 result = borderSize;
110 } else if (propName == "-relbordersize") {
111 result = relBorderSize;
112 } else if (propName == "-borderrgba") {
113 result = borderRGBA;
114 } else {
115 OSDImageBasedWidget::getProperty(propName, result);
116 }
117}
118
119std::string_view OSDRectangle::getType() const
120{
121 return "rectangle";
122}
123
124bool OSDRectangle::takeImageDimensions() const
125{
126 return (size == vec2()) && (relSize == vec2());
127}
128
129vec2 OSDRectangle::getSize(const OutputSurface& output) const
130{
131 if (!imageName.empty() && image && takeImageDimensions()) {
132 return vec2(image->getSize());
133 } else {
134 return (size * float(getScaleFactor(output)) * scale) +
135 (getParent()->getSize(output) * relSize);
136 }
137 //std::cout << "rectangle getWH " << getName() << " " << width << " x " << height << '\n';
138}
139
140uint8_t OSDRectangle::getFadedAlpha() const
141{
142 return uint8_t(255 * getRecursiveFadeValue());
143}
144
145template<typename IMAGE> std::unique_ptr<BaseImage> OSDRectangle::create(
146 OutputSurface& output)
147{
148 if (imageName.empty()) {
149 bool constAlpha = hasConstantAlpha();
150 if (constAlpha && ((getRGBA(0) & 0xff) == 0) &&
151 (((borderRGBA & 0xFF) == 0) || (borderSize == 0.0f))) {
152 // optimization: Sometimes it's useful to have a
153 // rectangle that will never be drawn, it only exists
154 // as a parent for sub-widgets. For those cases
155 // creating an IMAGE only wastes memory. So postpone
156 // creating it till alpha changes.
157 return nullptr;
158 }
159 vec2 sz = getSize(output);
160 auto factor = narrow<float>(getScaleFactor(output)) * scale;
161 auto bs = narrow_cast<int>(lrintf(factor * borderSize + sz[0] * relBorderSize));
162 assert(bs >= 0);
163 return std::make_unique<IMAGE>(output, round(sz), getRGBA4(), bs, borderRGBA);
164 } else {
165 auto file = systemFileContext().resolve(imageName);
166 if (takeImageDimensions()) {
167 auto factor = narrow<float>(getScaleFactor(output)) * scale;
168 return std::make_unique<IMAGE>(output, file, factor);
169 } else {
170 ivec2 iSize = round(getSize(output));
171 return std::make_unique<IMAGE>(output, file, iSize);
172 }
173 }
174}
175
176std::unique_ptr<BaseImage> OSDRectangle::createSDL(OutputSurface& output)
177{
178 return create<SDLImage>(output);
179}
180
181std::unique_ptr<BaseImage> OSDRectangle::createGL(OutputSurface& output)
182{
183#if COMPONENT_GL
184 return create<GLImage>(output);
185#else
186 (void)&output;
187 return nullptr;
188#endif
189}
190
191} // namespace openmsx
Represents the output window/screen of openMSX.
Definition: Display.hh:33
std::string resolve(std::string_view filename) const
Definition: FileContext.cc:79
uint32_t getRGBA(uint32_t corner) const
std::span< const uint32_t, 4 > getRGBA4() const
void setProperty(Interpreter &interp, std::string_view name, const TclObject &value) override
std::unique_ptr< BaseImage > image
float getRecursiveFadeValue() const override
void getProperty(std::string_view name, TclObject &result) const override
void getProperty(std::string_view name, TclObject &result) const override
Definition: OSDRectangle.cc:94
OSDRectangle(Display &display, const TclObject &name)
Definition: OSDRectangle.cc:21
void setProperty(Interpreter &interp, std::string_view name, const TclObject &value) override
Definition: OSDRectangle.cc:26
std::string_view getType() const override
int getScaleFactor(const OutputSurface &output) const
Definition: OSDWidget.cc:345
virtual gl::vec2 getSize(const OutputSurface &output) const =0
OSDWidget * getParent()
Definition: OSDWidget.hh:39
void invalidateRecursive()
Definition: OSDWidget.cc:288
float getFloat(Interpreter &interp) const
Definition: TclObject.cc:102
int getInt(Interpreter &interp) const
Definition: TclObject.cc:73
zstring_view getString() const
Definition: TclObject.cc:120
constexpr double round(double x)
Definition: cstd.hh:247
Definition: gl_mat.hh:23
vecN< 2, float > vec2
Definition: gl_vec.hh:150
bool isRegularFile(const Stat &st)
This file implemented 3 utility functions:
Definition: Autofire.cc:9
const FileContext & systemFileContext()
Definition: FileContext.cc:155