/* * Copyright 2019 faddenSoft * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using System.Text; using System.Windows.Media; using System.Windows.Media.Imaging; using CommonUtil; using PluginCommon; namespace SourceGen { public class Visualization { /// /// Unique user-specified tag. Contents are arbitrary, but may not be empty. /// public string Tag { get; private set; } /// /// Name of visualization generator (extension script function). /// public string VisGenIdent { get; private set; } /// /// Parameters passed to the visualization generator. /// public Dictionary VisGenParams { get; private set; } /// /// Cached reference to thumbnail. /// /// /// Because the underlying data never changes, we only need to regenerate the /// thumbnail if the set of active plugins changes. /// private BitmapSource Thumbnail { get; set; } // TODO - 64x64(?) bitmap /// /// Constructor. /// /// Unique identifier. /// Visualization generator identifier. /// Parameters for visualization generator. public Visualization(string tag, string visGenIdent, Dictionary visGenParams) { Tag = tag; VisGenIdent = visGenIdent; VisGenParams = visGenParams; } /// /// Trims a tag, removing leading/trailing whitespace, and checks it for validity. /// /// Tag to trim and validate. /// Set to true if the tag is valid. /// Trimmed tag string. Returns an empty string if tag is null. public static string TrimAndValidateTag(string tag, out bool isValid) { if (tag == null) { isValid = false; return string.Empty; } string trimTag = tag.Trim(); if (trimTag.Length < 2) { isValid = false; } else { isValid = true; } return trimTag; } /// /// Converts an IVisualization2d to a BitmapSource for display. /// public static BitmapSource ConvertToBitmapSource(IVisualization2d vis2d) { // Create indexed color palette. int[] intPal = vis2d.GetPalette(); List colors = new List(intPal.Length); foreach (int argb in intPal) { Color col = Color.FromArgb((byte)(argb >> 24), (byte)(argb >> 16), (byte)(argb >> 8), (byte)argb); colors.Add(col); } BitmapPalette palette = new BitmapPalette(colors); // indexed-color; see https://stackoverflow.com/a/15272528/294248 for direct color BitmapSource image = BitmapSource.Create( vis2d.Width, vis2d.Height, 96.0, 96.0, PixelFormats.Indexed8, palette, vis2d.GetPixels(), vis2d.Width); return image; } /// /// Finds a plugin that provides the named visualization generator. /// /// Project with script manager. /// Visualization generator identifier. /// A plugin that matches, or null if none found. public static IPlugin_Visualizer FindPluginByVisGenIdent(DisasmProject proj, string visGenIdent, out VisDescr visDescr) { List plugins = proj.GetActivePlugins(); foreach (IPlugin chkPlug in plugins) { if (!(chkPlug is IPlugin_Visualizer)) { continue; } IPlugin_Visualizer vplug = (IPlugin_Visualizer)chkPlug; foreach (VisDescr descr in vplug.GetVisGenDescrs()) { if (descr.Ident == visGenIdent) { visDescr = descr; return vplug; } } } visDescr = null; return null; } public override string ToString() { return "[Vis: " + Tag + " (" + VisGenIdent + ") count=" + VisGenParams.Count + "]"; } public static bool operator ==(Visualization a, Visualization b) { if (ReferenceEquals(a, b)) { return true; // same object, or both null } if (ReferenceEquals(a, null) || ReferenceEquals(b, null)) { return false; // one is null } // All fields must be equal. if (a.Tag != b.Tag || a.VisGenIdent != b.VisGenIdent || a.Thumbnail != b.Thumbnail) { return false; } // Compare the vis gen parameter lists. if (a.VisGenParams == b.VisGenParams) { return true; } if (a.VisGenParams.Count != b.VisGenParams.Count) { return false; } return Container.CompareDicts(a.VisGenParams, b.VisGenParams); } public static bool operator !=(Visualization a, Visualization b) { return !(a == b); } public override bool Equals(object obj) { return obj is Visualization && this == (Visualization)obj; } public override int GetHashCode() { // TODO(maybe): hash code should include up VisGenParams items return Tag.GetHashCode() ^ VisGenIdent.GetHashCode() ^ VisGenParams.Count; } } }