Bug Summary

File:home/HaikuArchives/ArtPaint/artpaint/tools/BrushEditor.cpp
Warning:line 474, column 8
Value stored to 'angle' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-haiku -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name BrushEditor.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /boot/system/lib/clang/12.0.1 -iquote ./ -iquote artpaint/ -iquote artpaint/Utilities/ -iquote artpaint/application/ -iquote artpaint/controls/ -iquote artpaint/layers/ -iquote artpaint/paintwindow/ -iquote artpaint/tools/ -iquote artpaint/viewmanipulators/ -iquote artpaint/windows/ -iquote objects_artpaint/ -isystem /boot/system/develop/headers/private/interface -internal-isystem /system/develop/headers/c++ -internal-isystem /system/develop/headers/c++/x86_64-unknown-haiku -internal-isystem /system/develop/headers/c++/backward -O3 -fdeprecated-macro -fdebug-compilation-dir /boot/home/HaikuArchives/ArtPaint -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2022-06-19-103017-1294-1 -x c++ artpaint/tools/BrushEditor.cpp
1/*
2 * Copyright 2003, Heikki Suhonen
3 * Copyright 2009, Karsten Heimrich
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 * Heikki Suhonen <heikki.suhonen@gmail.com>
8 * Karsten Heimrich <host.haiku@gmx.de>
9 * Dale Cieslak <dcieslak@yahoo.com>
10 *
11 */
12
13#include "BrushEditor.h"
14
15#include "BrushStoreWindow.h"
16#include "HSPolygon.h"
17#include "FloatSliderControl.h"
18#include "NumberSliderControl.h"
19#include "UtilityClasses.h"
20
21
22#include <Button.h>
23#include <Catalog.h>
24#include <CheckBox.h>
25#include <GridLayoutBuilder.h>
26#include <GroupLayout.h>
27#include <GroupLayoutBuilder.h>
28#include <RadioButton.h>
29#include <SeparatorView.h>
30
31
32#include <math.h>
33
34
35#undef B_TRANSLATION_CONTEXT"Tools"
36#define B_TRANSLATION_CONTEXT"Tools" "Tools"
37
38
39enum {
40 kExtraEdge = 4,
41 kBrushAltered = 'kbal',
42 kBrushSizeChanged = 'kbsz',
43 kBrushRatioChanged = 'kbrc',
44 kBrushFadeChanged = 'kbfc',
45 kBrushShapeChanged = 'kbsc',
46 kBrushStoreRequest = 'kbsr',
47 kBrushResetRequest = 'kbrr',
48 kBrushAngleChanged = 'kbac',
49};
50
51
52BrushEditor* BrushEditor::fBrushEditor = NULL__null;
53using ArtPaint::Interface::NumberSliderControl;
54
55
56BrushEditor::BrushEditor(Brush* brush)
57 : BBox(B_FANCY_BORDER, NULL__null)
58 , fBrush(brush)
59 , fBrushInfo(fBrush->GetInfo())
60{
61 float height = BRUSH_PREVIEW_HEIGHT64 - kExtraEdge;
62 float width = BRUSH_PREVIEW_WIDTH64 - kExtraEdge;
63
64 fBrushView = new BrushView(BRect(kExtraEdge, kExtraEdge, width, height),
65 fBrush);
66
67 BMessage* message = new BMessage(kBrushShapeChanged);
68 message->AddInt32("shape", HS_RECTANGULAR_BRUSH);
69
70 fRectangle = new BRadioButton(B_TRANSLATE("Rectangle")BLocaleRoster::Default()->GetCatalog()->GetString(("Rectangle"
), "Tools")
,
71 message);
72
73 message = new BMessage(kBrushShapeChanged);
74 message->AddInt32("shape", HS_ELLIPTICAL_BRUSH);
75
76 fEllipse = new BRadioButton(B_TRANSLATE("Ellipse")BLocaleRoster::Default()->GetCatalog()->GetString(("Ellipse"
), "Tools")
,
77 message);
78
79 fStoreBrush = new BButton(B_TRANSLATE("Store brush")BLocaleRoster::Default()->GetCatalog()->GetString(("Store brush"
), "Tools")
,
80 new BMessage(kBrushStoreRequest));
81
82 fResetBrush = new BButton(B_TRANSLATE("Reset brush")BLocaleRoster::Default()->GetCatalog()->GetString(("Reset brush"
), "Tools")
,
83 new BMessage(kBrushResetRequest));
84
85 message = new BMessage(kBrushSizeChanged);
86 message->AddInt32("value", int32(fBrushInfo.width));
87
88 fBrushSize =
89 new NumberSliderControl(B_TRANSLATE("Size:")BLocaleRoster::Default()->GetCatalog()->GetString(("Size:"
), "Tools")
, "0",
90 message, 1, 500, false, true, B_NO_BORDER, B_TRIANGLE_THUMB, true);
91
92 message = new BMessage(kBrushRatioChanged);
93 message->AddFloat("value", 0);
94
95 fBrushRatio =
96 new FloatSliderControl(B_TRANSLATE("Aspect:")BLocaleRoster::Default()->GetCatalog()->GetString(("Aspect:"
), "Tools")
, "0",
97 message, -10., 10., false);
98
99 fBrushRatio->Slider()->SetHashMarks(B_HASH_MARKS_BOTTOM);
100 fBrushRatio->Slider()->SetHashMarkCount(5);
101
102 message = new BMessage(kBrushAngleChanged);
103 message->AddInt32("value", int32(fBrushInfo.angle));
104
105 fBrushAngle =
106 new NumberSliderControl(B_TRANSLATE("Angle:")BLocaleRoster::Default()->GetCatalog()->GetString(("Angle:"
), "Tools")
, "0",
107 message, -90, 90, false);
108
109 fBrushAngle->Slider()->SetHashMarks(B_HASH_MARKS_BOTTOM);
110 fBrushAngle->Slider()->SetHashMarkCount(5);
111
112 message = new BMessage(kBrushFadeChanged);
113 message->AddInt32("value", int32(fBrushInfo.hardness));
114
115 fBrushFade =
116 new NumberSliderControl(B_TRANSLATE("Hardness:")BLocaleRoster::Default()->GetCatalog()->GetString(("Hardness:"
), "Tools")
, "0",
117 message, 0, 100, false);
118
119 BSeparatorView* view = new BSeparatorView(B_HORIZONTAL, B_FANCY_BORDER);
120 view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
121
122 BGridLayout* gridLayout = BGridLayoutBuilder(5.0, 5.0)
123 .Add(fBrushSize, 0, 0, 0, 0)
124 .Add(fBrushSize->LabelLayoutItem(), 0, 0)
125 .Add(fBrushSize->TextViewLayoutItem(), 1, 0)
126 .Add(fBrushSize->Slider(), 2, 0)
127 .Add(fBrushRatio, 0, 1, 0, 0)
128 .Add(fBrushRatio->LabelLayoutItem(), 0, 1)
129 .Add(fBrushRatio->TextViewLayoutItem(), 1, 1)
130 .Add(fBrushRatio->Slider(), 2, 1)
131 .Add(fBrushAngle, 0, 2, 0, 0)
132 .Add(fBrushAngle->LabelLayoutItem(), 0, 2)
133 .Add(fBrushAngle->TextViewLayoutItem(), 1, 2)
134 .Add(fBrushAngle->Slider(), 2, 2)
135 .Add(fBrushFade, 0, 3, 0, 0)
136 .Add(fBrushFade->LabelLayoutItem(), 0, 3)
137 .Add(fBrushFade->TextViewLayoutItem(), 1, 3)
138 .Add(fBrushFade->Slider(), 2, 3);
139 gridLayout->SetMaxColumnWidth(1, StringWidth("1000"));
140 gridLayout->SetMinColumnWidth(2, StringWidth("SLIDERSLIDERSLIDERSLIDER"));
141
142 SetLayout(new BGroupLayout(B_VERTICAL));
143 AddChild(BGroupLayoutBuilder(B_VERTICAL, 5.0)
144 .AddGroup(B_HORIZONTAL, 5.0)
145 .AddStrut(5.0)
146 .Add(fBrushView)
147 .AddGroup(B_VERTICAL, 5.0)
148 .Add(fEllipse)
149 .Add(fRectangle)
150 .AddGlue()
151 .End()
152 .AddGlue()
153 .End()
154 .AddStrut(1.0)
155 .Add(view)
156 .AddStrut(1.0)
157 .Add(gridLayout->View())
158 .AddStrut(1.0)
159 .AddGroup(B_HORIZONTAL)
160 .Add(fResetBrush)
161 .AddGlue()
162 .Add(fStoreBrush)
163 .End()
164 );
165}
166
167
168BrushEditor::~BrushEditor()
169{
170 fBrushEditor = NULL__null;
171}
172
173
174BView*
175BrushEditor::CreateBrushEditor(Brush* brush)
176{
177 if (fBrushEditor)
178 return NULL__null;
179
180 fBrushEditor = new BrushEditor(brush);
181 return fBrushEditor;
182}
183
184
185void
186BrushEditor::BrushModified()
187{
188 if (fBrushEditor) {
189 BWindow* window = fBrushEditor->Window();
190
191 bool locked = false;
192 if (window && window->Lock())
193 locked = true;
194
195 fBrushEditor->fBrushView->BrushModified();
196
197 if (window)
198 window->PostMessage(kBrushAltered, fBrushEditor);
199
200 if (window && locked)
201 window->Unlock();
202 }
203}
204
205
206void
207BrushEditor::AttachedToWindow()
208{
209 fBrushFade->SetTarget(this);
210 fBrushSize->SetTarget(this);
211 fBrushRatio->SetTarget(this);
212 fBrushAngle->SetTarget(this);
213
214 fEllipse->SetTarget(this);
215 fRectangle->SetTarget(this);
216 fStoreBrush->SetTarget(this);
217 fResetBrush->SetTarget(this);
218
219 if (fBrushInfo.shape == HS_RECTANGULAR_BRUSH)
220 fRectangle->SetValue(B_CONTROL_ON);
221
222 if (fBrushInfo.shape == HS_ELLIPTICAL_BRUSH)
223 fEllipse->SetValue(B_CONTROL_ON);
224}
225
226
227void
228BrushEditor::MessageReceived(BMessage* message)
229{
230 switch (message->what) {
231 case kBrushSizeChanged: {
232 int32 value;
233 if (message->FindInt32("value", &value) == B_OK((int)0)) {
234 float ratio = fBrushRatio->Value();
235
236 float realRatio = 1.0 / (0.9 * fabs(ratio) + 1.);
237
238 if (value < 0) {
239 fBrushInfo.width = max_c(value, 1)((value)>(1)?(value):(1));
240 fBrushInfo.height = max_c(value / realRatio, 1)((value / realRatio)>(1)?(value / realRatio):(1));
241 } else {
242 fBrushInfo.width = max_c(value / realRatio, 1)((value / realRatio)>(1)?(value / realRatio):(1));
243 fBrushInfo.height = max_c(value, 1)((value)>(1)?(value):(1));
244 }
245
246 fBrush->ModifyBrush(fBrushInfo);
247 fBrushView->BrushModified();
248
249 bool final;
250 if (message->FindBool("final", &final) == B_OK((int)0) && final)
251 fBrush->CreateDiffBrushes();
252 }
253 } break;
254
255 case kBrushRatioChanged: {
256 float value;
257 if (message->FindFloat("value", &value) == B_OK((int)0)) {
258 float realRatio = 1.0 / (0.9 * fabs(value) + 1.);
259
260 if (value < 0) {
261 fBrushInfo.width = max_c(fBrushSize->Value(), 1)((fBrushSize->Value())>(1)?(fBrushSize->Value()):(1)
)
;
262 fBrushInfo.height = max_c(fBrushSize->Value() / realRatio, 1)((fBrushSize->Value() / realRatio)>(1)?(fBrushSize->
Value() / realRatio):(1))
;
263 } else {
264 fBrushInfo.width = max_c(fBrushSize->Value() / realRatio, 1)((fBrushSize->Value() / realRatio)>(1)?(fBrushSize->
Value() / realRatio):(1))
;
265 fBrushInfo.height = max_c(fBrushSize->Value(), 1)((fBrushSize->Value())>(1)?(fBrushSize->Value()):(1)
)
;
266 }
267
268 fBrush->ModifyBrush(fBrushInfo);
269 fBrushView->BrushModified();
270
271 bool final;
272 if (message->FindBool("final", &final) == B_OK((int)0) && final)
273 fBrush->CreateDiffBrushes();
274 }
275 } break;
276
277 case kBrushAngleChanged: {
278 int32 value;
279 if (message->FindInt32("value", &value) == B_OK((int)0)) {
280 fBrushInfo.angle = value;
281 fBrush->ModifyBrush(fBrushInfo);
282 fBrushView->BrushModified();
283
284 bool final;
285 if (message->FindBool("final", &final) == B_OK((int)0) && final)
286 fBrush->CreateDiffBrushes();
287 }
288 } break;
289
290 case kBrushFadeChanged: {
291 int32 value;
292 if (message->FindInt32("value",&value) == B_OK((int)0)) {
293 fBrushInfo.hardness = value;
294 fBrush->ModifyBrush(fBrushInfo);
295 fBrushView->BrushModified();
296
297 bool final;
298 if (message->FindBool("final", &final) == B_OK((int)0) && final)
299 fBrush->CreateDiffBrushes();
300 }
301 } break;
302
303 case kBrushShapeChanged: {
304 int32 value;
305 if (message->FindInt32("shape", &value) == B_OK((int)0)) {
306 fBrushInfo.shape = value;
307 fBrush->ModifyBrush(fBrushInfo);
308 fBrush->CreateDiffBrushes();
309 fBrushView->BrushModified();
310 }
311 } break;
312
313 case kBrushAltered: {
314 // Here something has altered the brush and we should reflect it
315 // in our controls and such things.
316 fBrushInfo = fBrush->GetInfo();
317 float ratio = (float)(fBrushInfo.width / fBrushInfo.height);
318
319 if (ratio < 1.0) {
320 ratio = -1.0 / ratio;
321 fBrushSize->SetValue((int32)fBrushInfo.height);
322 } else
323 fBrushSize->SetValue((int32)fBrushInfo.width);
324
325 if (ratio == 1.0)
326 ratio = 0;
327
328 fBrushRatio->SetValue((int32)ratio);
329
330 fBrushAngle->SetValue(int32(fBrushInfo.angle));
331 fBrushFade->SetValue(int32(fBrushInfo.hardness));
332 fBrushView->BrushModified();
333
334 if (fBrushInfo.shape == HS_RECTANGULAR_BRUSH)
335 fRectangle->SetValue(B_CONTROL_ON);
336
337 if (fBrushInfo.shape == HS_ELLIPTICAL_BRUSH)
338 fEllipse->SetValue(B_CONTROL_ON);
339 } break;
340
341 case kBrushStoreRequest: {
342 BrushStoreWindow::AddBrush(fBrush);
343 } break;
344
345 case kBrushResetRequest: {
346 fBrushSize->SetValue(30);
347 fBrushRatio->SetValue(0);
348 fBrushAngle->SetValue(0);
349 fBrushFade->SetValue(2);
350 fRectangle->SetValue(B_CONTROL_OFF);
351 fEllipse->SetValue(B_CONTROL_ON);
352
353 fBrushInfo.shape = HS_ELLIPTICAL_BRUSH;
354 fBrushInfo.width = 30;
355 fBrushInfo.height = 30;
356 fBrushInfo.angle = 0;
357 fBrushInfo.hardness = 2;
358 fBrush->ModifyBrush(fBrushInfo);
359 fBrush->CreateDiffBrushes();
360
361 fBrushView->BrushModified();
362 } break;
363
364 default: {
365 BView::MessageReceived(message);
366 } break;
367 }
368}
369
370
371// #pragma mark -- BrushView
372
373
374BrushView::BrushView(BRect frame, Brush* brush)
375 : BView(frame, "brush view", B_FOLLOW_NONE0, B_WILL_DRAW)
376 , fDrawControls(false)
377 , fBrush(brush)
378 , fBrushPreview(NULL__null)
379{
380 SetExplicitMinSize(BSize(frame.Width(), frame.Height()));
381 SetExplicitMaxSize(BSize(frame.Width(), frame.Height()));
382
383 SetToolTip(B_TRANSLATE("Hold shift key to snap to 45° angles")BLocaleRoster::Default()->GetCatalog()->GetString(("Hold shift key to snap to 45° angles"
), "Tools")
);
384
385 frame.InsetBy(1.0, 1.0);
386 fBrushPreview = new BBitmap(BRect(0.0, 0.0, frame.Width() - 1.0,
387 frame.Height() - 1.0), B_RGBA32);
388 fBrush->PreviewBrush(fBrushPreview);
389}
390
391
392BrushView::~BrushView()
393{
394 delete fBrushPreview;
395}
396
397
398void
399BrushView::Draw(BRect)
400{
401 DrawBitmap(fBrushPreview, BPoint(1.0, 1.0));
402
403 SetPenSize(1);
404 SetHighColor(0, 0, 0, 255);
405 StrokeRect(Bounds());
406
407 if (fDrawControls) {
408 float r1 = Bounds().Width()/2;
409 float r2 = Bounds().Height()/2;
410 BPoint point_list[12];
411 point_list[0] = BPoint(0,r2-2);
412 point_list[1] = BPoint(0,0);
413 point_list[2] = BPoint(-r1*.5,0);
414 point_list[3] = BPoint(0,0);
415 point_list[4] = BPoint(0,-r2+7);
416 point_list[5] = BPoint(-2,-r2+7);
417 point_list[6] = BPoint(0,-r2+2);
418 point_list[7] = BPoint(2,-r2+7);
419 point_list[8] = BPoint(0,-r2+7);
420 point_list[9] = BPoint(0,0);
421 point_list[10] = BPoint(r1*.5,0);
422 point_list[11] = BPoint(0,0);
423
424 HSPolygon poly(point_list, 12);
425 poly.Rotate(BPoint(0, 0), fBrush->GetInfo().angle);
426 poly.TranslateBy(int32(r1 - 1), int32(r2 - 1));
427
428 BPolygon* bpoly = poly.GetBPolygon();
429
430 SetHighColor(150, 0, 0, 255);
431 StrokePolygon(bpoly, false);
432 FillPolygon(bpoly);
433
434 delete bpoly;
435 }
436}
437
438
439void
440BrushView::MessageReceived(BMessage* message)
441{
442// switch (message->what) {
443// case HS_BRUSH_DRAGGED: {
444// int32 size;
445// brush_info* info;
446// message->FindData("brush data",B_ANY_TYPE,(const void**)&info,&size);
447// if (size == sizeof(brush_info)) {
448// fBrush->ModifyBrush(*info);
449// fBrush->PreviewBrush(fBrushPreview);
450// Invalidate();
451// fBrush->CreateDiffBrushes();
452// if (Window() && Parent())
453// Window()->PostMessage(kBrushAltered, Parent());
454// }
455// break;
456//
457// default: {
458 BView::MessageReceived(message);
459// } break;
460// }
461}
462
463
464void
465BrushView::MouseDown(BPoint point)
466{
467 BPoint c;
468 c.x = Bounds().Width() / 2.0;
469 c.y = Bounds().Height() / 2.0;
470 brush_info info = fBrush->GetInfo();
471 uint32 buttons;
472
473 GetMouse(&point,&buttons);
474 float angle = info.angle;
Value stored to 'angle' during its initialization is never read
475 float prev_angle;
476 if (point.x == c.x)
477 angle = 0;
478 else if (point.y == c.y)
479 angle = 90;
480 else {
481 angle = atan2(point.x-c.x,c.y-point.y) * 180 / M_PI3.14159265358979323846;
482 }
483 prev_angle = angle;
484
485 if (true /*buttons == B_PRIMARY_MOUSE_BUTTON*/) {
486 while (buttons) {
487 if (angle != prev_angle) {
488 fBrush->ModifyBrush(info);
489 fBrush->PreviewBrush(fBrushPreview);
490 Window()->Lock();
491 Draw(Bounds());
492 Window()->Unlock();
493 prev_angle = angle;
494 }
495 Window()->Lock();
496 GetMouse(&point,&buttons);
497 Window()->Unlock();
498 if (point.x == c.x)
499 angle = 0;
500 else if (point.y == c.y)
501 angle = 90;
502 else {
503 angle = atan2(point.x-c.x,c.y-point.y)*180/M_PI3.14159265358979323846;
504 }
505 if (angle > 90)
506 angle = -(90. - ((int32)angle % 90));
507 if (angle < -90)
508 angle = 90. - ((int32)-angle % 90);
509
510 if (modifiers() & B_LEFT_SHIFT_KEY) {
511 if (angle < 22 && angle > -22)
512 angle = 0;
513 else if (angle > 22 && angle < 75)
514 angle = 45;
515 else if (angle < -22 && angle > -75)
516 angle = -45;
517 else if (angle > 75)
518 angle = 90;
519 else if (angle < -75)
520 angle = -90;
521 }
522
523 info.angle = angle;
524 snooze(20000);
525 }
526
527 fBrush->CreateDiffBrushes();
528 Window()->PostMessage(kBrushAltered, Parent());
529 } /* else {
530 info = fBrush->GetInfo();
531 BMessage* message = new BMessage(HS_BRUSH_DRAGGED);
532 message->AddData("brush data",B_ANY_TYPE,&info,sizeof(brush_info));
533 DragMessage(message,BRect(0,0,fBrushPreview_WIDTH-1,fBrushPreview_HEIGHT-1));
534 delete message;
535 } */
536}
537
538
539void
540BrushView::MouseMoved(BPoint where, uint32 transit, const BMessage* message)
541{
542 if (Window() && Window()->Lock()) {
543 switch (transit) {
544 default: break;
545 case B_ENTERED_VIEW: {
546 fDrawControls = true;
547 Draw(Bounds());
548 } break;
549
550 case B_EXITED_VIEW: {
551 fDrawControls = false;
552 Draw(Bounds());
553 } break;
554 }
555
556 Window()->Unlock();
557 }
558}
559
560
561void
562BrushView::BrushModified()
563{
564 fBrush->PreviewBrush(fBrushPreview);
565 Draw(Bounds());
566}