mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:22:46 +00:00 
			
		
		
		
	PixelPaint: Allow copying arbitrary selections
This replaces the naive copy algorithm that only supported rectangular and 100% opaque selections with a more general approach that supports any shape and alpha value. Note that we now make a brand new bitmap with a hardcoded format instead of just cropping the layer's existing bitmap. This is done to ensure that the final clipboard image will have an alpha channel.
This commit is contained in:
		
							parent
							
								
									e58f78e667
								
							
						
					
					
						commit
						20b2c46019
					
				
					 1 changed files with 30 additions and 3 deletions
				
			
		|  | @ -92,9 +92,36 @@ void Layer::set_name(String name) | ||||||
| 
 | 
 | ||||||
| RefPtr<Gfx::Bitmap> Layer::try_copy_bitmap(Selection const& selection) const | RefPtr<Gfx::Bitmap> Layer::try_copy_bitmap(Selection const& selection) const | ||||||
| { | { | ||||||
|     auto bounding_rect = selection.bounding_rect().translated(-m_location); |     auto selection_rect = selection.bounding_rect(); | ||||||
|     // FIXME: This needs to be smarter once we add more complex selections.
 | 
 | ||||||
|     return m_bitmap->cropped(bounding_rect); |     auto result = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, selection_rect.size()); | ||||||
|  |     VERIFY(result->has_alpha_channel()); | ||||||
|  | 
 | ||||||
|  |     for (int y = selection_rect.top(); y <= selection_rect.bottom(); y++) { | ||||||
|  |         for (int x = selection_rect.left(); x <= selection_rect.right(); x++) { | ||||||
|  | 
 | ||||||
|  |             Gfx::IntPoint image_point { x, y }; | ||||||
|  |             auto layer_point = image_point - m_location; | ||||||
|  |             auto result_point = image_point - selection_rect.top_left(); | ||||||
|  | 
 | ||||||
|  |             if (!m_bitmap->physical_rect().contains(layer_point)) { | ||||||
|  |                 result->set_pixel(result_point, Gfx::Color::Transparent); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             auto pixel = m_bitmap->get_pixel(layer_point); | ||||||
|  | 
 | ||||||
|  |             // Widen to int before multiplying to avoid overflow issues
 | ||||||
|  |             auto pixel_alpha = static_cast<int>(pixel.alpha()); | ||||||
|  |             auto selection_alpha = static_cast<int>(selection.get_selection_alpha(image_point)); | ||||||
|  |             auto new_alpha = (pixel_alpha * selection_alpha) / 0xFF; | ||||||
|  |             pixel.set_alpha(static_cast<u8>(clamp(new_alpha, 0, 0xFF))); | ||||||
|  | 
 | ||||||
|  |             result->set_pixel(result_point, pixel); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Davipb
						Davipb