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