Bug Summary

File:client/ui/node/ui_node_image.cpp
Location:line 181, column 26
Description:The left operand of '+' is a garbage value

Annotated Source Code

1/**
2 * @file
3 * @brief The <code>pic</code> behaviour allow to draw an image or a part of an image
4 * into the GUI. It provide some layout properties. We can use it like an active node
5 * (mouse in/out/click...) but in this case, it is better to use nodes with a semantics (like button,
6 * or checkbox).
7 * @code
8 * image aircraft_return
9 * {
10 * src ui/buttons_small
11 * pos "550 410"
12 * texl "0 32"
13 * texh "16 48"
14 * [..]
15 * }
16 * @endcode
17 */
18
19/*
20Copyright (C) 2002-2011 UFO: Alien Invasion.
21
22This program is free software; you can redistribute it and/or
23modify it under the terms of the GNU General Public License
24as published by the Free Software Foundation; either version 2
25of the License, or (at your option) any later version.
26
27This program is distributed in the hope that it will be useful,
28but WITHOUT ANY WARRANTY; without even the implied warranty of
29MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
30
31See the GNU General Public License for more details.
32
33You should have received a copy of the GNU General Public License
34along with this program; if not, write to the Free Software
35Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
36
37*/
38
39#include "../ui_nodes.h"
40#include "../ui_parse.h"
41#include "../ui_behaviour.h"
42#include "../ui_render.h"
43#include "ui_node_image.h"
44#include "ui_node_abstractnode.h"
45
46#include "../../client.h"
47
48#define EXTRADATA_TYPEimageExtraData_t imageExtraData_t
49#define EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))) UI_EXTRADATA(node, EXTRADATA_TYPE)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t))))
50#define EXTRADATACONST(node)(*((const imageExtraData_t*)((const char*)node + sizeof(uiNode_t
))))
UI_EXTRADATACONST(node, EXTRADATA_TYPE)(*((const imageExtraData_t*)((const char*)node + sizeof(uiNode_t
))))
51
52/**
53 * @brief Handled after the end of the load of the node from the script (all data and/or child are set)
54 */
55void uiImageNode::onLoaded (uiNode_t *node)
56{
57 /* update the size when its possible */
58 if (Vector2Empty(node->box.size)(((fabs((((node->box.size))[0])-((vec2_origin)[0]))<0.0000000001
)?(fabs((((node->box.size))[1])-((vec2_origin)[1]))<0.0000000001
)?1:0:0))
) {
59 if (EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texl[0] != 0 || EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texh[0]) {
60 node->box.size[0] = EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texh[0] - EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texl[0];
61 node->box.size[1] = EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texh[1] - EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texl[1];
62 } else if (EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).source) {
63 const image_t *image = UI_LoadImage(EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).source);
64 if (image) {
65 node->box.size[0] = image->width;
66 node->box.size[1] = image->height;
67 }
68 }
69 }
70#ifdef DEBUG1
71 if (Vector2Empty(node->box.size)(((fabs((((node->box.size))[0])-((vec2_origin)[0]))<0.0000000001
)?(fabs((((node->box.size))[1])-((vec2_origin)[1]))<0.0000000001
)?1:0:0))
) {
72 if (node->onClick || node->onRightClick || node->onMouseEnter || node->onMouseLeave || node->onWheelUp || node->onWheelDown || node->onWheel || node->onMiddleClick) {
73 Com_DPrintf(DEBUG_CLIENT0x20, "Node '%s' is an active image without size\n", UI_GetPath(node));
74 }
75 }
76#endif
77}
78
79/**
80 * @brief Get position of a inner box inside an outer box according to align param.
81 * @todo Generic function, move it outside.
82 * @param[in] outerBoxPos Position of the top-left corner of the outer box.
83 * @param[in] outerBoxSize Size of the outer box.
84 * @param[in] innerBoxSize Size of the inner box.
85 * @param align Alignment of the inner box inside the outer box.
86 * @param[out] innerBoxPos Position of the top-left corner of the inner box.
87 */
88static void UI_ImageAlignBoxInBox (vec2_t outerBoxPos, vec2_t outerBoxSize, vec2_t innerBoxSize, align_t align, vec2_t innerBoxPos)
89{
90 switch (align % 3) {
91 case 0: /* left */
92 innerBoxPos[0] = outerBoxPos[0];
93 break;
94 case 1: /* middle */
95 innerBoxPos[0] = outerBoxPos[0] + (outerBoxSize[0] * 0.5) - (innerBoxSize[0] * 0.5);
96 break;
97 case 2: /* right */
98 innerBoxPos[0] = outerBoxPos[0] + outerBoxSize[0] - innerBoxSize[0];
99 break;
100 }
101 switch (align / 3) {
102 case 0: /* top */
103 innerBoxPos[1] = outerBoxPos[1];
104 break;
105 case 1: /* middle */
106 innerBoxPos[1] = outerBoxPos[1] + (outerBoxSize[1] * 0.5) - (innerBoxSize[1] * 0.5);
107 break;
108 case 2: /* bottom */
109 innerBoxPos[1] = outerBoxPos[1] + outerBoxSize[1] - innerBoxSize[1];
110 break;
111 default:
112 innerBoxPos[1] = outerBoxPos[1];
113 Com_Error(ERR_FATAL0, "UI_ImageAlignBoxInBox: Align %d not supported\n", align);
114 }
115}
116
117/**
118 * @brief Draws the image node
119 * @param[in] node The UI node to draw
120 */
121void uiImageNode::draw (uiNode_t *node)
122{
123 vec2_t size;
124 vec2_t nodepos;
125 const image_t *image;
126 vec2_t imagepos;
127 vec2_t nodesize;
128
129 const char* imageName = UI_GetReferenceString(node, EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).source);
130 if (Q_strnull(imageName)((imageName) == __null || (imageName)[0] == '\0'))
1
Taking false branch
131 return;
132
133 image = UI_LoadImage(imageName);
134 if (!image)
2
Taking false branch
135 return;
136
137 /* mouse darken effect */
138 /** @todo convert all pic using mousefx into button.
139 * @todo delete mousefx
140 */
141#if 0
142 if (node->mousefx && node->state) {
143 vec4_t color;
144 VectorScale(node->color, 0.8, color)((color)[0] = (node->color)[0] * (0.8),(color)[1] = (node->
color)[1] * (0.8),(color)[2] = (node->color)[2] * (0.8))
;
145 color[3] = node->color[3];
146 R_Color(color);
147 }
148#endif
149
150 UI_GetNodeAbsPos(node, nodepos);
151 Vector2Copy(node->box.size, nodesize)((nodesize)[0]=(node->box.size)[0],(nodesize)[1]=(node->
box.size)[1])
;
152 nodesize[0] -= node->padding + node->padding;
153 if (nodesize[0] < 0)
3
Taking false branch
154 nodesize[0] = 0;
155 nodesize[1] -= node->padding + node->padding;
156 if (nodesize[1] < 0)
4
Taking false branch
157 nodesize[1] = 0;
158
159 /** @todo code is duplicated in the ekg node code */
160 if (node->box.size[0] && !node->box.size[1]) {
5
Taking false branch
161 const float scale = image->width / node->box.size[0];
162 Vector2Set(size, node->box.size[0], image->height / scale)((size)[0]=(node->box.size[0]), (size)[1]=(image->height
/ scale))
;
163 } else if (node->box.size[1] && !node->box.size[0]) {
6
Taking false branch
164 const float scale = image->height / node->box.size[1];
165 Vector2Set(size, image->width / scale, node->box.size[1])((size)[0]=(image->width / scale), (size)[1]=(node->box
.size[1]))
;
166 } else {
167 Vector2Copy(nodesize, size)((size)[0]=(nodesize)[0],(size)[1]=(nodesize)[1]);
168
169 if (EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).preventRatio) {
7
Taking false branch
170 /* maximize the image into the bounding box */
171 const float ratio = (float) image->width / (float) image->height;
172 if (size[1] * ratio > size[0]) {
173 Vector2Set(size, size[0], size[0] / ratio)((size)[0]=(size[0]), (size)[1]=(size[0] / ratio));
174 } else {
175 Vector2Set(size, size[1] * ratio, size[1])((size)[0]=(size[1] * ratio), (size)[1]=(size[1]));
176 }
177 }
178 }
179
180 UI_ImageAlignBoxInBox(nodepos, nodesize, size, (align_t) node->contentAlign, imagepos);
181 UI_DrawNormImage(false, imagepos[0] + node->padding, imagepos[1] + node->padding, size[0], size[1],
8
The left operand of '+' is a garbage value
182 EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texh[0], EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texh[1],
183 EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texl[0], EXTRADATA(node)(*((imageExtraData_t*)((char*)node + sizeof(uiNode_t)))).texl[1], image);
184
185 /** @todo convert all pic using mousefx into button.
186 * @todo delete mousefx
187 */
188#if 0
189 if (node->mousefx && node->state) {
190 R_Color(NULL__null);
191 }
192#endif
193}
194
195void UI_RegisterImageNode (uiBehaviour_t* behaviour)
196{
197 /** @todo rename it according to the function name when its possible */
198 behaviour->name = "image";
199 behaviour->manager = new uiImageNode();
200 behaviour->extraDataSize = sizeof(EXTRADATA_TYPEimageExtraData_t);
201
202 /* Do not change the image ratio. The image will be proportionally stretched. */
203 UI_RegisterExtradataNodeProperty(behaviour, "preventratio", V_BOOL, EXTRADATA_TYPE, preventRatio)UI_RegisterNodePropertyPosSize_(behaviour, "preventratio", V_BOOL
, ((size_t) &((imageExtraData_t *)(((imageExtraData_t*)((
char*)0 + sizeof(uiNode_t)))))->preventRatio), sizeof(((imageExtraData_t
*)0)->preventRatio))
;
204 /* Now this property do nothing. But we use it like a tag, to remember nodes we should convert into button...
205 * @todo delete it when its possible (use more button instead of image)
206 */
207 UI_RegisterExtradataNodeProperty(behaviour, "mousefx", V_BOOL, EXTRADATA_TYPE, mousefx)UI_RegisterNodePropertyPosSize_(behaviour, "mousefx", V_BOOL,
((size_t) &((imageExtraData_t *)(((imageExtraData_t*)((char
*)0 + sizeof(uiNode_t)))))->mousefx), sizeof(((imageExtraData_t
*)0)->mousefx))
;
208
209 /* Texture high. Optional. Define the higher corner of the texture we want to display. Used with texl to crop the image. */
210 UI_RegisterExtradataNodeProperty(behaviour, "texh", V_POS, EXTRADATA_TYPE, texh)UI_RegisterNodePropertyPosSize_(behaviour, "texh", V_POS, ((size_t
) &((imageExtraData_t *)(((imageExtraData_t*)((char*)0 + sizeof
(uiNode_t)))))->texh), sizeof(((imageExtraData_t *)0)->
texh))
;
211 /* Texture low. Optional. Define the lower corner of the texture we want to display. Used with texh to crop the image. */
212 UI_RegisterExtradataNodeProperty(behaviour, "texl", V_POS, EXTRADATA_TYPE, texl)UI_RegisterNodePropertyPosSize_(behaviour, "texl", V_POS, ((size_t
) &((imageExtraData_t *)(((imageExtraData_t*)((char*)0 + sizeof
(uiNode_t)))))->texl), sizeof(((imageExtraData_t *)0)->
texl))
;
213
214 /* Source of the image */
215 UI_RegisterExtradataNodeProperty(behaviour, "src", V_CVAR_OR_STRING, EXTRADATA_TYPE, source)UI_RegisterNodePropertyPosSize_(behaviour, "src", ((0x8000 + 0x0100
) + V_STRING), ((size_t) &((imageExtraData_t *)(((imageExtraData_t
*)((char*)0 + sizeof(uiNode_t)))))->source), sizeof(((imageExtraData_t
*)0)->source))
;
216}