mirror of https://github.com/aseprite/aseprite.git
				
				
				
			
		
			
				
	
	
		
			85 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			85 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C++
		
	
	
	
| // Aseprite Document Library
 | |
| // Copyright (c) 2024  Igara Studio S.A.
 | |
| //
 | |
| // This file is released under the terms of the MIT license.
 | |
| // Read LICENSE.txt for more information.
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include "config.h"
 | |
| #endif
 | |
| 
 | |
| #include "doc/blend_image.h"
 | |
| 
 | |
| #include "doc/blend_internals.h"
 | |
| #include "doc/image_impl.h"
 | |
| 
 | |
| namespace doc {
 | |
| 
 | |
| template<typename DstTraits,
 | |
|          typename SrcTraits>
 | |
| void blend_image_templ(Image* dst,
 | |
|                        const Image* src,
 | |
|                        const gfx::Clip& area,
 | |
|                        const Palette* pal,
 | |
|                        const int opacity,
 | |
|                        const BlendMode blendMode)
 | |
| {
 | |
|   if constexpr (DstTraits::color_mode == ColorMode::INDEXED ||
 | |
|                 SrcTraits::color_mode == ColorMode::INDEXED) {
 | |
|     ASSERT(pal != nullptr);
 | |
|     if (pal == nullptr)
 | |
|       return;
 | |
|   }
 | |
|   BlenderHelper<DstTraits, SrcTraits> blender(dst, src, pal, blendMode, true);
 | |
|   LockImageBits<DstTraits> dstBits(dst);
 | |
|   const LockImageBits<SrcTraits> srcBits(src);
 | |
|   auto dstIt = dstBits.begin_area(area.dstBounds());
 | |
|   auto srcIt = srcBits.begin_area(area.srcBounds());
 | |
|   auto dstEnd = dstBits.end_area(area.dstBounds());
 | |
|   for (; dstIt < dstEnd; ++dstIt, ++srcIt)
 | |
|     *dstIt = blender(*dstIt, *srcIt, opacity);
 | |
| }
 | |
| 
 | |
| void blend_image(Image* dst,
 | |
|                  const Image* src,
 | |
|                  gfx::Clip area,
 | |
|                  const Palette* pal,
 | |
|                  const int opacity,
 | |
|                  const BlendMode blendMode)
 | |
| {
 | |
|   if (!area.clip(dst->width(), dst->height(), src->width(), src->height()))
 | |
|     return;
 | |
| 
 | |
|   switch (dst->pixelFormat()) {
 | |
| 
 | |
|     case IMAGE_RGB:
 | |
|       switch (src->pixelFormat()) {
 | |
|         case IMAGE_RGB:       return blend_image_templ<RgbTraits, RgbTraits      >(dst, src, area, pal, opacity, blendMode);
 | |
|         case IMAGE_GRAYSCALE: return blend_image_templ<RgbTraits, GrayscaleTraits>(dst, src, area, pal, opacity, blendMode);
 | |
|         case IMAGE_INDEXED:   return blend_image_templ<RgbTraits, IndexedTraits  >(dst, src, area, pal, opacity, blendMode);
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case IMAGE_GRAYSCALE:
 | |
|       switch (src->pixelFormat()) {
 | |
|         case IMAGE_RGB:       return blend_image_templ<GrayscaleTraits, RgbTraits      >(dst, src, area, pal, opacity, blendMode);
 | |
|         case IMAGE_GRAYSCALE: return blend_image_templ<GrayscaleTraits, GrayscaleTraits>(dst, src, area, pal, opacity, blendMode);
 | |
|         case IMAGE_INDEXED:   return blend_image_templ<GrayscaleTraits, IndexedTraits  >(dst, src, area, pal, opacity, blendMode);
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case IMAGE_INDEXED:
 | |
|       switch (src->pixelFormat()) {
 | |
|         case IMAGE_RGB:       return blend_image_templ<IndexedTraits, RgbTraits      >(dst, src, area, pal, opacity, blendMode);
 | |
|         case IMAGE_GRAYSCALE: return blend_image_templ<IndexedTraits, GrayscaleTraits>(dst, src, area, pal, opacity, blendMode);
 | |
|         case IMAGE_INDEXED:   return blend_image_templ<IndexedTraits, IndexedTraits  >(dst, src, area, pal, opacity, blendMode);
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case IMAGE_TILEMAP:
 | |
|       return dst->copy(src, area);
 | |
|   }
 | |
| }
 | |
| 
 | |
| } // namespace doc
 |