protected override double EvalVariable(string variable) { var m = Regex.Match(variable, @"^([A-Za-z0-9_\-]+)\.(\w+)$"); if (!m.Success) { return(base.EvalVariable(variable)); } var layerId = m.Groups[1].Value; var layerProperty = m.Groups[2].Value; BitmapBase varImg; if (layerId == "this") { varImg = _layer; } else { var varLayer = _renderTask.Style.Layers.FirstOrDefault(x => x.Id == layerId); if (varLayer == null) { throw NewParseException(App.Translation.Calculator.Err_NoLayerWithId.Fmt(layerId)); } if (_renderTask.IsLayerAlreadyReferenced(varLayer)) { throw NewParseException(App.Translation.Calculator.Err_RecursiveLayerReference.Fmt(layerId)); } varImg = _renderTask.RenderLayer(varLayer); } var pixels = varImg.PreciseSize(); switch (layerProperty.ToLower()) { case "width": return(pixels.Width); case "height": return(pixels.Height); case "top": return(pixels.Top); case "left": return(pixels.Left); case "right": return(pixels.Right); case "bottom": return(pixels.Bottom); case "centerhorz": return(pixels.CenterHorzD); case "centervert": return(pixels.CenterVertD); default: throw NewParseException(App.Translation.Calculator.Err_UnknownLayerProperty.Fmt(layerProperty)); } }
public unsafe override BitmapBase Apply(RenderTask renderTask, BitmapBase layer) { Tank tank = renderTask.Tank; LayerBase maskLayer; if (string.IsNullOrEmpty(MaskLayerId)) { return(layer); } maskLayer = renderTask.Style.Layers.FirstOrDefault(x => x.Id == MaskLayerId); if (maskLayer == null) { throw new StyleUserError(App.Translation.EffectMaskLayer.ErrorInvalidId.Fmt(MaskLayerId)); } if (renderTask.IsLayerAlreadyReferenced(maskLayer)) { throw new StyleUserError(App.Translation.EffectMaskLayer.ErrorRecursiveLayerReference.Fmt(MaskLayerId)); } var maskImg = renderTask.RenderLayer(maskLayer); using (layer.UseWrite()) { using (maskImg.UseRead()) { for (int i = 0; i < layer.Width; ++i) { for (int j = 0; j < layer.Height; ++j) { decimal alpha = 0; if (i < maskImg.Width && j < maskImg.Height) { switch (MaskMode) { case Effects.MaskMode.Opacity: alpha = maskImg.Data[i * 4 + maskImg.Stride * j + 3]; break; case Effects.MaskMode.Grayscale: alpha = (maskImg.Data[i * 4 + maskImg.Stride * j] + maskImg.Data[i * 4 + maskImg.Stride * j + 1] + maskImg.Data[i * 4 + maskImg.Stride * j + 2] ) / 3; break; case Effects.MaskMode.Combined: alpha = (maskImg.Data[i * 4 + maskImg.Stride * j] + maskImg.Data[i * 4 + maskImg.Stride * j + 1] + maskImg.Data[i * 4 + maskImg.Stride * j + 2] ) / 3 * maskImg.Data[i * 4 + maskImg.Stride * j + 3] / 255m; break; } } if (Invert) { alpha = 255m - alpha; } var opacity = layer.Data[i * 4 + layer.Stride * j + 3] * (alpha / 255m); layer.Data[i * 4 + layer.Stride * j + 3] = (byte)opacity; } } } } return(layer); }