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.x != w) {
28 size.x = w;
30 }
31 } else if (propName == "-h") {
32 float h = value.getFloat(interp);
33 if (size.y != h) {
34 size.y = h;
36 }
37 } else if (propName == "-relw") {
38 float relw = value.getFloat(interp);
39 if (relSize.x != relw) {
40 relSize.x = relw;
42 }
43 } else if (propName == "-relh") {
44 float relh = value.getFloat(interp);
45 if (relSize.y != relh) {
46 relSize.y = 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.x;
94 } else if (propName == "-h") {
95 result = size.y;
96 } else if (propName == "-relw") {
97 result = relSize.x;
98 } else if (propName == "-relh") {
99 result = relSize.y;
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}
134
135uint8_t OSDRectangle::getFadedAlpha() const
136{
137 return uint8_t(255 * getRecursiveFadeValue());
138}
139
140std::unique_ptr<GLImage> OSDRectangle::create(OutputSurface& output)
141{
142 if (imageName.empty()) {
143 if (hasConstantAlpha() && ((getRGBA(0) & 0xff) == 0) &&
144 (((borderRGBA & 0xFF) == 0) || (borderSize == 0.0f))) {
145 // optimization: Sometimes it's useful to have a
146 // rectangle that will never be drawn, it only exists
147 // as a parent for sub-widgets. For those cases
148 // creating an IMAGE only wastes memory. So postpone
149 // creating it till alpha changes.
150 return nullptr;
151 }
152 vec2 sz = getSize(output);
153 auto factor = narrow<float>(getScaleFactor(output)) * scale;
154 auto bs = narrow_cast<int>(lrintf(factor * borderSize + sz.x * relBorderSize));
155 assert(bs >= 0);
156 return std::make_unique<GLImage>(round(sz), getRGBA4(), bs, borderRGBA);
157 } else {
158 auto file = systemFileContext().resolve(imageName);
159 if (takeImageDimensions()) {
160 auto factor = narrow<float>(getScaleFactor(output)) * scale;
161 return std::make_unique<GLImage>(file, factor);
162 } else {
163 ivec2 iSize = round(getSize(output));
164 return std::make_unique<GLImage>(file, iSize);
165 }
166 }
167}
168
169} // namespace openmsx
Represents the output window/screen of openMSX.
Definition Display.hh:31
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:283
virtual gl::vec2 getSize(const OutputSurface &output) const =0
OSDWidget * getParent()
Definition OSDWidget.hh:41
void invalidateRecursive()
Definition OSDWidget.cc:246
float getFloat(Interpreter &interp) const
Definition TclObject.cc:107
int getInt(Interpreter &interp) const
Definition TclObject.cc:69
zstring_view getString() const
Definition TclObject.cc:141
constexpr double round(double x)
Definition cstd.hh:247
Definition gl_mat.hh:23
vecN< 2, float > vec2
Definition gl_vec.hh:382
bool isRegularFile(const Stat &st)
This file implemented 3 utility functions:
Definition Autofire.cc:11
const FileContext & systemFileContext()