<commit_before>package openfl._internal.renderer.canvas;


import lime.graphics.utils.ImageCanvasUtil;
import openfl.display.BitmapData;
import openfl.display.CanvasRenderer;
import openfl.display.TileContainer;
import openfl.display.Tilemap;
import openfl.display.Tileset;
import openfl.geom.Matrix;
import openfl.geom.Rectangle;

@:access(lime.graphics.ImageBuffer)
@:access(openfl.display.BitmapData)
@:access(openfl.display.Tile)
@:access(openfl.display.TileContainer)
@:access(openfl.display.Tilemap)
@:access(openfl.display.Tileset)
@:access(openfl.geom.Matrix)
@:access(openfl.geom.Rectangle)


class CanvasTilemap {
	
	
	public static inline function render (tilemap:Tilemap, renderer:CanvasRenderer):Void {
		
		#if (js && html5)
		if (!tilemap.__renderable || tilemap.__group.__tiles.length == 0 || tilemap.__worldAlpha <= 0) return;
		
		var context = renderer.context;
		
		renderer.__setBlendMode (tilemap.__worldBlendMode);
		renderer.__pushMaskObject (tilemap);
		
		var rect = Rectangle.__pool.get ();
		rect.setTo (0, 0, tilemap.__width, tilemap.__height);
		renderer.__pushMaskRect (rect, tilemap.__renderTransform);
		
		if (!renderer.__allowSmoothing || !tilemap.smoothing) {
			
			untyped (context).mozImageSmoothingEnabled = false;
			//untyped (context).webkitImageSmoothingEnabled = false;
			untyped (context).msImageSmoothingEnabled = false;
			untyped (context).imageSmoothingEnabled = false;
			
		}
		
		renderTileContainer (tilemap.__group, renderer, tilemap.__renderTransform, tilemap.__tileset, (renderer.__allowSmoothing && tilemap.smoothing), tilemap.tileAlphaEnabled, tilemap.__worldAlpha, null, null, rect);
		
		if (!renderer.__allowSmoothing || !tilemap.smoothing) {
			
			untyped (context).mozImageSmoothingEnabled = true;
			//untyped (context).webkitImageSmoothingEnabled = true;
			untyped (context).msImageSmoothingEnabled = true;
			untyped (context).imageSmoothingEnabled = true;
			
		}
		
		renderer.__popMaskRect ();
		renderer.__popMaskObject (tilemap);
		
		Rectangle.__pool.release (rect);
		#end
		
	}
	
	
	private static function renderTileContainer (group:TileContainer, renderer:CanvasRenderer, parentTransform:Matrix, defaultTileset:Tileset, smooth:Bool, alphaEnabled:Bool, worldAlpha:Float, cacheBitmapData:BitmapData, source:Dynamic, rect:Rectangle):Void {
		
		#if (js && html5)
		var context = renderer.context;
		var roundPixels = renderer.__roundPixels;
		
		var tileTransform = Matrix.__pool.get ();
		
		var tiles = group.__tiles;
		var length = group.__length;
		
		var tile, tileset, alpha, visible, id, tileData, tileRect, bitmapData;
		
		for (i in 0...length) {
			
			tile = tiles[i];
			
			tileTransform.setTo (1, 0, 0, 1, -tile.originX, -tile.originY);
			tileTransform.concat (tile.matrix);
			tileTransform.concat (parentTransform);
			
			if (roundPixels) {
				
				tileTransform.tx = Math.round (tileTransform.tx);
				tileTransform.ty = Math.round (tileTransform.ty);
				
			}
			
			tileset = tile.tileset != null ? tile.tileset : defaultTileset;
			
			alpha = tile.alpha * worldAlpha;
			visible = tile.visible;
			if (!visible || alpha <= 0) continue;
			
			if (!alphaEnabled) alpha = 1;
			
			if (tile.__length > 0) {
				
				renderTileContainer (cast tile, renderer, tileTransform, tileset, smooth, alphaEnabled, alpha, cacheBitmapData, source, rect);
				
			} else {
				
				if (tileset == null) continue;
				
				id = tile.id;
				
				if (id == -1) {
					
					tileRect = tile.rect;
					if (tileRect == null || tileRect.width <= 0 || tileRect.height <= 0) continue;
					
				} else {
					
					tileData = tileset.__data[id];
					if (tileData == null) continue;
					
					rect.setTo (tileData.x, tileData.y, tileData.width, tileData.height);
					tileRect = rect;
					
				}
				
				bitmapData = tileset.__bitmapData;
				if (bitmapData == null) continue;
				
				if (bitmapData != cacheBitmapData) {
					
					if (bitmapData.image.buffer.__srcImage == null) {
						
						ImageCanvasUtil.convertToCanvas (bitmapData.image);
						
					}
					
					source = bitmapData.image.src;
					cacheBitmapData = bitmapData;
					
				}
				
				context.globalAlpha = alpha;
				
				renderer.setTransform (tileTransform, context);
				context.drawImage (source, tileRect.x, tileRect.y, tileRect.width, tileRect.height, 0, 0, tileRect.width, tileRect.height);
				
			}
			
		}
		
		Matrix.__pool.release (tileTransform);
		#end
		
	}
	
	
}<commit_msg>Add blend mode support for tiles on Canvas<commit_after>package openfl._internal.renderer.canvas;


import lime.graphics.utils.ImageCanvasUtil;
import openfl.display.BitmapData;
import openfl.display.BlendMode;
import openfl.display.CanvasRenderer;
import openfl.display.TileContainer;
import openfl.display.Tilemap;
import openfl.display.Tileset;
import openfl.geom.Matrix;
import openfl.geom.Rectangle;

@:access(lime.graphics.ImageBuffer)
@:access(openfl.display.BitmapData)
@:access(openfl.display.Tile)
@:access(openfl.display.TileContainer)
@:access(openfl.display.Tilemap)
@:access(openfl.display.Tileset)
@:access(openfl.geom.Matrix)
@:access(openfl.geom.Rectangle)


class CanvasTilemap {
	
	public static inline function render (tilemap:Tilemap, renderer:CanvasRenderer):Void {
		
		#if (js && html5)
		if (!tilemap.__renderable || tilemap.__group.__tiles.length == 0 || tilemap.__worldAlpha <= 0) return;
		
		var context = renderer.context;
		
		renderer.__setBlendMode (tilemap.__worldBlendMode);
		renderer.__pushMaskObject (tilemap);
		
		var rect = Rectangle.__pool.get ();
		rect.setTo (0, 0, tilemap.__width, tilemap.__height);
		renderer.__pushMaskRect (rect, tilemap.__renderTransform);
		
		if (!renderer.__allowSmoothing || !tilemap.smoothing) {
			
			untyped (context).mozImageSmoothingEnabled = false;
			//untyped (context).webkitImageSmoothingEnabled = false;
			untyped (context).msImageSmoothingEnabled = false;
			untyped (context).imageSmoothingEnabled = false;
			
		}
		
		var blendMode = null;
		renderTileContainer (tilemap.__group, renderer, tilemap.__renderTransform, tilemap.__tileset, (renderer.__allowSmoothing && tilemap.smoothing), tilemap.tileAlphaEnabled, tilemap.__worldAlpha, tilemap.tileBlendModeEnabled, blendMode, null, null, rect);
		
		if (!renderer.__allowSmoothing || !tilemap.smoothing) {
			
			untyped (context).mozImageSmoothingEnabled = true;
			//untyped (context).webkitImageSmoothingEnabled = true;
			untyped (context).msImageSmoothingEnabled = true;
			untyped (context).imageSmoothingEnabled = true;
			
		}
		
		renderer.__popMaskRect ();
		renderer.__popMaskObject (tilemap);
		
		Rectangle.__pool.release (rect);
		#end
		
	}
	
	
	private static function renderTileContainer (group:TileContainer, renderer:CanvasRenderer, parentTransform:Matrix, defaultTileset:Tileset, smooth:Bool, alphaEnabled:Bool, worldAlpha:Float, blendModeEnabled:Bool, defaultBlendMode:BlendMode, cacheBitmapData:BitmapData, source:Dynamic, rect:Rectangle):Void {
		
		#if (js && html5)
		var context = renderer.context;
		var roundPixels = renderer.__roundPixels;
		
		var tileTransform = Matrix.__pool.get ();
		
		var tiles = group.__tiles;
		var length = group.__length;
		
		var tile, tileset, alpha, visible, id, tileData, tileRect, bitmapData;
		
		var tileBlendMode:BlendMode = defaultBlendMode;
		
		for (i in 0...length) {
			
			tile = tiles[i];
			
			tileTransform.setTo (1, 0, 0, 1, -tile.originX, -tile.originY);
			tileTransform.concat (tile.matrix);
			tileTransform.concat (parentTransform);
			
			if (roundPixels) {
				
				tileTransform.tx = Math.round (tileTransform.tx);
				tileTransform.ty = Math.round (tileTransform.ty);
				
			}
			
			tileset = tile.tileset != null ? tile.tileset : defaultTileset;
			
			alpha = tile.alpha * worldAlpha;
			visible = tile.visible;
			if (!visible || alpha <= 0) continue;
			
			if (!alphaEnabled) alpha = 1;
			
			tileBlendMode = null;
			
			if (blendModeEnabled) {
				
				tileBlendMode = (tile.__blendMode != null) ? tile.__blendMode : defaultBlendMode;
				
			}
			
			if (tile.__length > 0) {
				
				renderTileContainer (cast tile, renderer, tileTransform, tileset, smooth, alphaEnabled, alpha, blendModeEnabled, tileBlendMode, cacheBitmapData, source, rect);
				
			} else {
				
				if (tileset == null) continue;
				
				id = tile.id;
				
				if (id == -1) {
					
					tileRect = tile.rect;
					if (tileRect == null || tileRect.width <= 0 || tileRect.height <= 0) continue;
					
				} else {
					
					tileData = tileset.__data[id];
					if (tileData == null) continue;
					
					rect.setTo (tileData.x, tileData.y, tileData.width, tileData.height);
					tileRect = rect;
					
				}
				
				bitmapData = tileset.__bitmapData;
				if (bitmapData == null) continue;
				
				if (bitmapData != cacheBitmapData) {
					
					if (bitmapData.image.buffer.__srcImage == null) {
						
						ImageCanvasUtil.convertToCanvas (bitmapData.image);
						
					}
					
					source = bitmapData.image.src;
					cacheBitmapData = bitmapData;
					
				}
				
				context.globalAlpha = alpha;
				
				if (blendModeEnabled) {
					
					renderer.__setBlendMode (tileBlendMode);
					
				}
				
				renderer.setTransform (tileTransform, context);
				context.drawImage (source, tileRect.x, tileRect.y, tileRect.width, tileRect.height, 0, 0, tileRect.width, tileRect.height);
				
			}
			
		}
		
		Matrix.__pool.release (tileTransform);
		#end
		
	}
	
	
}
{'fraction_non_alphanumeric': 0.11560509554140128, 'fraction_numerical': 0.0040339702760084925, 'mean_word_length': 3.52063339731286, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4760116', 'n_tokens_mistral': 3725, 'n_tokens_neox': 2955, 'n_words': 596}