Skip to content

Commit addb47e

Browse files
committed
Selection: support alpha in selections
1 parent f8625dc commit addb47e

17 files changed

+384
-150
lines changed

artpaint/Utilities/BitmapUtilities.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,7 @@ BitmapUtilities::ConvertToMask(BBitmap* inBitmap, uint8 color)
149149
for (int32 y = 0; y < out_map->Bounds().IntegerHeight() + 1; y++) {
150150
for (int32 x = 0; x < out_map->Bounds().IntegerWidth() + 1; x++) {
151151
c.word = *(in_bits + x + y * in_bpr);
152-
// revert this change when the rest of ArtPaint understands
153-
// selections with alpha
154-
float alpha = 0;
155-
if (c.bytes[3] > 0x00)
156-
alpha = 1;
152+
float alpha = (float)c.bytes[3] / 255.;
157153

158154
*(out_bits + x + y * out_bpr) = (uint8)((float)color * alpha);
159155
}

artpaint/Utilities/ScaleUtilities.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,14 +193,18 @@ ScaleUtilities::ScaleVerticallyGray(float width, float height, BPoint offset, BB
193193
uint8* source_bits = (uint8*)source->Bits();
194194
int32 source_bpr = source->BytesPerRow();
195195

196-
for (int32 y = 0; y <= (int32)height; y++) {
196+
int32 max_width = width;
197+
int32 max_height = height;
198+
199+
for (int32 y = 0; y <= (int32)max_height; y++) {
197200
int32 low = floor(ratio * y);
198201
int32 high = ceil(ratio * y);
199202
float weight = (ratio * y) - low;
203+
200204
uint8* src_bits_low = source_bits + (int32)offset.x + (low + (int32)ceil(offset.y + 0.5)) * source_bpr;
201205
uint8* src_bits_high = source_bits + (int32)offset.x + (high + (int32)ceil(offset.y + 0.5)) * source_bpr;
202206

203-
for (int32 x = 0; x <= width; x++) {
207+
for (int32 x = 0; x <= max_width; x++) {
204208
*(target_bits + x + y * target_bpr)
205209
= linear_interpolation(*(src_bits_low + x),
206210
*(src_bits_high + x), weight);

artpaint/application/PixelOperations.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,12 @@ inline uint32 linear_interpolation(uint32 p1, uint32 p2, float t)
715715
}
716716

717717

718+
inline uint8 linear_interpolation(uint8 p1, uint8 p2, float t)
719+
{
720+
return (p1 * (1.0 - t)) + (p2 * t);
721+
}
722+
723+
718724
inline uint32 mitchell_netravali(uint32 p0, uint32 p1, uint32 p2, uint32 p3,
719725
float t, float B, float C)
720726
{

artpaint/application/Selection.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -824,7 +824,12 @@ Selection::Invert()
824824
uint8* bits = (uint8*)selection_map->Bits();
825825
int32 bits_length = selection_map->BitsLength();
826826
for (int32 i = 0; i < bits_length; i++) {
827-
*bits = ~(*bits);
827+
union color_conversion pixel;
828+
pixel.word = *bits;
829+
for (int i = 0; i < 4; ++i)
830+
pixel.bytes[i] = 255 - pixel.bytes[i];
831+
832+
*bits = pixel.word;
828833
++bits;
829834
}
830835
selection_bounds = BRect(0, 0, -1, -1);

artpaint/application/Selection.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ class Selection {
185185
// GetBoundingRect-function.
186186
inline bool ContainsPoint(BPoint);
187187
inline bool ContainsPoint(int32, int32);
188+
189+
inline uint8 Value(BPoint);
190+
inline uint8 Value(int32, int32);
188191
};
189192

190193

@@ -207,6 +210,26 @@ Selection::ContainsPoint(int32 x, int32 y)
207210
}
208211

209212

213+
uint8
214+
Selection::Value(BPoint p)
215+
{
216+
return Value((int32)p.x, (int32)p.y);
217+
}
218+
219+
220+
uint8
221+
Selection::Value(int32 x, int32 y)
222+
{
223+
if (x < 0 || y < 0)
224+
return 0;
225+
226+
if (selection_bits == NULL || image_bounds.Contains(BPoint(x, y)) == false)
227+
return 0;
228+
229+
return *(selection_bits + y * selection_bpr + x);
230+
}
231+
232+
210233
// This class contains the vital data that describe selection. A selection
211234
// can be archived with such data and selection can also be modified to
212235
// represent the same selection as the SelectionData represents.

artpaint/paintwindow/ImageView.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,7 +1797,12 @@ ImageView::ManipulatorMouseTrackerThread()
17971797
if (LockLooper() == TRUE) {
17981798
gui_manipulator->MouseDown(point, buttons, this, first_call_to_mouse_down);
17991799
first_call_to_mouse_down = FALSE;
1800+
if (show_selection == true)
1801+
selection->StopDrawing();
18001802
preview_quality = gui_manipulator->PreviewBitmap(FALSE, updated_region);
1803+
if (show_selection == true)
1804+
selection->StartDrawing(this, magnify_scale);
1805+
18011806
if (preview_quality != DRAW_NOTHING) {
18021807
if ((preview_quality != DRAW_ONLY_GUI) && (updated_region->Frame().IsValid())) {
18031808
if (manipulated_layers != HS_MANIPULATE_ALL_LAYERS) {
@@ -2114,9 +2119,6 @@ ImageView::ManipulatorFinisherThread()
21142119
the_image->SetImageSize();
21152120
the_image->Render();
21162121

2117-
// also recalculate the selection
2118-
selection->Recalculate();
2119-
21202122
// Change the selection for the undo-queue if necessary.
21212123
if ((new_event != NULL)
21222124
&& !(undo_queue->ReturnSelectionMap() == selection->ReturnSelectionMap())) {

artpaint/tools/BitmapDrawer.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,10 @@ BitmapDrawer::SetPixel(
12161216
BPoint location, uint32 color, Selection* sel, uint32 (*composite_func)(uint32, uint32))
12171217
{
12181218
if (sel == NULL || sel->ContainsPoint(location)) {
1219+
float sel_alpha = 1.0;
1220+
if (sel != NULL && sel->IsEmpty() == false)
1221+
sel_alpha = sel->Value(location) / 255.;
1222+
12191223
if (bitmap_bounds.Contains(location)) {
12201224
if (composite_func) {
12211225
union {
@@ -1224,14 +1228,24 @@ BitmapDrawer::SetPixel(
12241228
} norm_color, target_color;
12251229

12261230
norm_color.word = color;
1231+
norm_color.bytes[3] *= sel_alpha;
12271232

12281233
uint32 target = GetPixel(location);
12291234
target_color.word = target;
12301235

12311236
*(bitmap_bits + (int32)location.x + (int32)location.y * bitmap_bpr)
12321237
= (*composite_func)(target_color.word, norm_color.word);
1233-
} else
1234-
*(bitmap_bits + (int32)location.x + (int32)location.y * bitmap_bpr) = color;
1238+
} else {
1239+
union {
1240+
unsigned char bytes[4];
1241+
uint32 word;
1242+
} norm_color;
1243+
1244+
norm_color.word = color;
1245+
norm_color.bytes[3] *= sel_alpha;
1246+
1247+
*(bitmap_bits + (int32)location.x + (int32)location.y * bitmap_bpr) = norm_color.word;
1248+
}
12351249

12361250
return B_OK;
12371251
} else

artpaint/tools/Brush.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,11 +491,16 @@ Brush::draw(BBitmap* buffer, BPoint point, Selection* selection)
491491
target_bits = bits + (y + py) * bpr + left;
492492
for (int32 x = left; x <= right; ++x) {
493493
if (selection->IsEmpty() || selection->ContainsPoint(x, y + py)) {
494+
float sel_alpha = 1.0;
495+
if (selection->IsEmpty() == false && selection->ContainsPoint(x, y + py))
496+
sel_alpha = selection->Value(x, y + py) / 255.;
497+
494498
union color_conversion brush_color, target_color, result;
495499
brush_color.word = *(brush_bits + (x - px) + y * brush_bpr);
496500
brush_color.bytes[0] = 0xFF;
497501
brush_color.bytes[1] = 0xFF;
498502
brush_color.bytes[2] = 0xFF;
503+
brush_color.bytes[3] *= sel_alpha;
499504

500505
target_color.word = *target_bits;
501506

artpaint/tools/FillTool.cpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ FillTool::NormalFill(ImageView* view, uint32 buttons, BPoint start, Selection* s
197197
if ((sel == NULL || sel->IsEmpty() == true || sel->ContainsPoint(x, y))
198198
&& compare_2_pixels_with_variance(
199199
old_color, drawer->GetPixel(x, y), tolerance)) {
200-
drawer->SetPixel(x, y, color);
200+
drawer->SetPixel(x, y, color, sel);
201201
}
202202
}
203203
}
@@ -246,7 +246,7 @@ FillTool::CheckSpans(BPoint span_start, BitmapDrawer* drawer, PointStack& stack,
246246
} else if (binary_bits != NULL)
247247
*(binary_bits + y * binary_bpr + (x / 8)) |= (0x01 << (7 - x % 8));
248248

249-
drawer->SetPixel(x, y, new_color);
249+
drawer->SetPixel(x, y, new_color, sel);
250250

251251
if (spans == BOTH || spans == LOWER) {
252252
if ((inside_lower_span == FALSE)
@@ -303,7 +303,7 @@ FillTool::CheckSpans(BPoint span_start, BitmapDrawer* drawer, PointStack& stack,
303303
} else if (binary_bits != NULL)
304304
*(binary_bits + y * binary_bpr + (x / 8)) |= (0x01 << (7 - x % 8));
305305

306-
drawer->SetPixel(x, y, new_color);
306+
drawer->SetPixel(x, y, new_color, sel);
307307

308308
if (spans == BOTH || spans == LOWER) {
309309
if ((inside_lower_span == FALSE)
@@ -364,7 +364,7 @@ FillTool::FillSpan(BPoint span_start, BitmapDrawer* drawer, int32 min_x, int32 m
364364
// Then go from start towards the left side of the bitmap.
365365
while ((sel == NULL || sel->IsEmpty() || sel->ContainsPoint(x, y)) && (x >= min_x)
366366
&& (compare_2_pixels_with_variance(drawer->GetPixel(x, y), old_color, tolerance))) {
367-
drawer->SetPixel(x, y, new_color);
367+
drawer->SetPixel(x, y, new_color, sel);
368368
if (binary_bits != NULL)
369369
*(binary_bits + y * binary_bpr + (x / 8))
370370
= *(binary_bits + y * binary_bpr + (x / 8)) | (0x01 << (7 - x % 8));
@@ -375,7 +375,7 @@ FillTool::FillSpan(BPoint span_start, BitmapDrawer* drawer, int32 min_x, int32 m
375375
x = start_x + 1;
376376
while ((sel == NULL || sel->IsEmpty() || sel->ContainsPoint(x, y)) && (x <= max_x)
377377
&& (compare_2_pixels_with_variance(drawer->GetPixel(x, y), old_color, tolerance))) {
378-
drawer->SetPixel(x, y, new_color);
378+
drawer->SetPixel(x, y, new_color, sel);
379379
if (binary_bits != NULL)
380380
*(binary_bits + y * binary_bpr + (x / 8))
381381
= *(binary_bits + y * binary_bpr + (x / 8)) | (0x01 << (7 - x % 8));
@@ -523,16 +523,16 @@ FillTool::GradientFill(
523523

524524
if (fToolSettings.shape == GRADIENT_CONIC) {
525525
FillGradientConic(drawer, binary_map, start, new_point, min_x, max_x, min_y,
526-
max_y, color, gradient_color);
526+
max_y, color, gradient_color, 2, sel);
527527
} else if (fToolSettings.shape == GRADIENT_RADIAL) {
528528
FillGradientRadial(drawer, binary_map, start, new_point, min_x, max_x,
529-
min_y, max_y, color, gradient_color, 2);
529+
min_y, max_y, color, gradient_color, 2, sel);
530530
} else if (fToolSettings.shape == GRADIENT_SQUARE) {
531531
FillGradientSquare(drawer, binary_map, start, new_point, min_x, max_x,
532-
min_y, max_y, color, gradient_color, 2);
532+
min_y, max_y, color, gradient_color, 2, sel);
533533
} else {
534534
FillGradientLinear(drawer, binary_map, start, new_point, min_x, max_x,
535-
min_y, max_y, color, gradient_color, 2);
535+
min_y, max_y, color, gradient_color, 2, sel);
536536
}
537537

538538
bitmap->Lock();
@@ -560,16 +560,16 @@ FillTool::GradientFill(
560560
// Here calculate the final gradient.
561561
if (fToolSettings.shape == GRADIENT_CONIC) {
562562
FillGradientConic(drawer, binary_map, start, new_point, min_x, max_x, min_y, max_y,
563-
color, gradient_color);
563+
color, gradient_color, 1, sel);
564564
} else if (fToolSettings.shape == GRADIENT_RADIAL) {
565565
FillGradientRadial(drawer, binary_map, start, new_point, min_x, max_x, min_y, max_y,
566-
color, gradient_color);
566+
color, gradient_color, 1, sel);
567567
} else if (fToolSettings.shape == GRADIENT_SQUARE) {
568568
FillGradientSquare(drawer, binary_map, start, new_point, min_x, max_x, min_y, max_y,
569-
color, gradient_color);
569+
color, gradient_color, 1, sel);
570570
} else {
571571
FillGradientLinear(drawer, binary_map, start, new_point, min_x, max_x, min_y, max_y,
572-
color, gradient_color);
572+
color, gradient_color, 1, sel);
573573
}
574574
// Update the image-view.
575575
bitmap->Lock();
@@ -773,7 +773,7 @@ FillTool::MakeFloodBinaryMap(BitmapDrawer* drawer, int32 min_x, int32 max_x, int
773773
void
774774
FillTool::FillGradientLinear(BitmapDrawer* drawer, BBitmap* binary_map, BPoint start, BPoint end,
775775
int32 min_x, int32 max_x, int32 min_y, int32 max_y, uint32 new_color, uint32 gradient_color,
776-
uint8 skip)
776+
uint8 skip, Selection* sel)
777777
{
778778
uchar* binary_bits = (uchar*)binary_map->Bits();
779779
int32 binary_bpr = binary_map->BytesPerRow();
@@ -838,7 +838,7 @@ FillTool::FillGradientLinear(BitmapDrawer* drawer, BBitmap* binary_map, BPoint s
838838

839839
for (int dy = 0; dy < skip; ++dy) {
840840
for (int dx = 0; dx < skip; ++dx)
841-
drawer->SetPixel(x + dx, y + dy, out_color.word);
841+
drawer->SetPixel(x + dx, y + dy, out_color.word, sel);
842842
}
843843
}
844844
}
@@ -849,7 +849,7 @@ FillTool::FillGradientLinear(BitmapDrawer* drawer, BBitmap* binary_map, BPoint s
849849
void
850850
FillTool::FillGradientRadial(BitmapDrawer* drawer, BBitmap* binary_map, BPoint start, BPoint end,
851851
int32 min_x, int32 max_x, int32 min_y, int32 max_y, uint32 new_color, uint32 gradient_color,
852-
uint8 skip)
852+
uint8 skip, Selection* sel)
853853
{
854854
uchar* binary_bits = (uchar*)binary_map->Bits();
855855
int32 binary_bpr = binary_map->BytesPerRow();
@@ -901,7 +901,7 @@ FillTool::FillGradientRadial(BitmapDrawer* drawer, BBitmap* binary_map, BPoint s
901901

902902
for (int dy = 0; dy < skip; ++dy) {
903903
for (int dx = 0; dx < skip; ++dx)
904-
drawer->SetPixel(x + dx, y + dy, out_color.word);
904+
drawer->SetPixel(x + dx, y + dy, out_color.word, sel);
905905
}
906906
}
907907
}
@@ -912,7 +912,7 @@ FillTool::FillGradientRadial(BitmapDrawer* drawer, BBitmap* binary_map, BPoint s
912912
void
913913
FillTool::FillGradientSquare(BitmapDrawer* drawer, BBitmap* binary_map, BPoint start, BPoint end,
914914
int32 min_x, int32 max_x, int32 min_y, int32 max_y, uint32 new_color, uint32 gradient_color,
915-
uint8 skip)
915+
uint8 skip, Selection* sel)
916916
{
917917
uchar* binary_bits = (uchar*)binary_map->Bits();
918918
int32 binary_bpr = binary_map->BytesPerRow();
@@ -971,7 +971,7 @@ FillTool::FillGradientSquare(BitmapDrawer* drawer, BBitmap* binary_map, BPoint s
971971

972972
for (int dy = 0; dy < skip; ++dy) {
973973
for (int dx = 0; dx < skip; ++dx)
974-
drawer->SetPixel(x + dx, y + dy, out_color.word);
974+
drawer->SetPixel(x + dx, y + dy, out_color.word, sel);
975975
}
976976
}
977977
}
@@ -982,7 +982,7 @@ FillTool::FillGradientSquare(BitmapDrawer* drawer, BBitmap* binary_map, BPoint s
982982
void
983983
FillTool::FillGradientConic(BitmapDrawer* drawer, BBitmap* binary_map, BPoint start, BPoint end,
984984
int32 min_x, int32 max_x, int32 min_y, int32 max_y, uint32 new_color, uint32 gradient_color,
985-
uint8 skip)
985+
uint8 skip, Selection* sel)
986986
{
987987
uchar* binary_bits = (uchar*)binary_map->Bits();
988988
int32 binary_bpr = binary_map->BytesPerRow();
@@ -1043,7 +1043,7 @@ FillTool::FillGradientConic(BitmapDrawer* drawer, BBitmap* binary_map, BPoint st
10431043

10441044
for (int dy = 0; dy < skip; ++dy) {
10451045
for (int dx = 0; dx < skip; ++dx)
1046-
drawer->SetPixel(x + dx, y + dy, out_color.word);
1046+
drawer->SetPixel(x + dx, y + dy, out_color.word, sel);
10471047
}
10481048
}
10491049
}

artpaint/tools/FillTool.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,16 @@ class FillTool : public DrawingTool {
8383
Selection* = NULL);
8484
void FillGradientLinear(BitmapDrawer*, BBitmap*, BPoint,
8585
BPoint, int32, int32, int32, int32, uint32,
86-
uint32, uint8 skip = 1);
86+
uint32, uint8 skip = 1, Selection* sel = NULL);
8787
void FillGradientRadial(BitmapDrawer*, BBitmap*, BPoint,
8888
BPoint, int32, int32, int32, int32, uint32,
89-
uint32, uint8 skip = 1);
89+
uint32, uint8 skip = 1, Selection* sel = NULL);
9090
void FillGradientSquare(BitmapDrawer*, BBitmap*, BPoint,
9191
BPoint, int32, int32, int32, int32, uint32,
92-
uint32, uint8 skip = 1);
92+
uint32, uint8 skip = 1, Selection* sel = NULL);
9393
void FillGradientConic(BitmapDrawer*, BBitmap*, BPoint,
9494
BPoint, int32, int32, int32, int32, uint32,
95-
uint32, uint8 skip = 1);
95+
uint32, uint8 skip = 1, Selection* sel = NULL);
9696

9797
BRect calcBinaryMapBounds(BBitmap *boolean_map);
9898
};

0 commit comments

Comments
 (0)