Archive Browser
Download AdobeSwatchExchangeLoader-v2.zip version 2.0.0.0, last updated 21/10/2015 (72.79 KB)
Download- md5: 3591debc1f6749c23ad9bbd113dd760a
- sha1: 9b8b0e53179b0b8d04c14324125ae5452df58305
- sha256: 152c5051abec694120031b4b0ed923608627b0081994f99cf6d043cc1663ed20
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
// Writing Adobe Swatch Exchange (ase) files using C#
// http://www.cyotek.com/blog/writing-adobe-swatch-exchange-ase-files-using-csharp
namespace AdobeSwatchExchangeLoader
{
[DefaultEvent("TopRowChanged")]
internal sealed class AseHexViewer : Control
{
#region Constants
private const TextFormatFlags _flags =
TextFormatFlags.Left | TextFormatFlags.SingleLine | TextFormatFlags.NoPrefix | TextFormatFlags.NoPadding;
private readonly List<ByteGroup> _groups;
private readonly VScrollBar _scrollBar;
#endregion
#region Fields
private int _cellOffset;
private Size _cellSize;
private int _columns;
private string _fileName;
private int _topRow;
private int _totalBytes;
#endregion
#region Constructors
public AseHexViewer()
{
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.Selectable | ControlStyles.StandardClick | ControlStyles.StandardDoubleClick, false);
_groups = new List<ByteGroup>();
_scrollBar = new VScrollBar();
_scrollBar.Scroll += this.ScrollBarScrollHandler;
_scrollBar.ValueChanged += this.ScrollBarScrollHandler;
this.Controls.Add(_scrollBar);
this.BackColor = SystemColors.Window;
this.Font = new Font("Courier New", 9.75F);
this.Padding = this.DefaultPadding;
this.DefineCellSize();
}
#endregion
#region Events
/// <summary>
/// Occurs when the TopRow property value changes
/// </summary>
[Category("Property Changed")]
public event EventHandler TopRowChanged;
#endregion
#region Properties
/// <summary>
/// Gets or sets the background color for the control.
/// </summary>
/// <returns>
/// A <see cref="T:System.Drawing.Color"/> that represents the background color of the control. The default is the value of the <see cref="P:System.Windows.Forms.Control.DefaultBackColor"/> property.
/// </returns>
/// <PermissionSet><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/></PermissionSet>
[DefaultValue(typeof(Color), "Window")]
public override Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
[Browsable(false)]
public string FileName
{
get { return _fileName; }
set
{
_fileName = value;
this.Load();
}
}
/// <summary>
/// Gets or sets the font of the text displayed by the control.
/// </summary>
/// <returns>
/// The <see cref="T:System.Drawing.Font"/> to apply to the text displayed by the control. The default is the value of the <see cref="P:System.Windows.Forms.Control.DefaultFont"/> property.
/// </returns>
/// <PermissionSet><IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence"/><IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/></PermissionSet>
[DefaultValue(typeof(Font), "Courier New, 9.75pt")]
public override Font Font
{
get { return base.Font; }
set { base.Font = value; }
}
[DefaultValue(typeof(Padding), "6, 6, 6, 6")]
public new Padding Padding
{
get { return base.Padding; }
set { base.Padding = value; }
}
[Browsable(false)]
public int Rows { get; private set; }
[Browsable(false)]
public int TopRow
{
get { return _topRow; }
set
{
if (this.TopRow != value)
{
_topRow = value;
this.OnTopRowChanged(EventArgs.Empty);
}
}
}
/// <summary>
/// Gets the internal spacing, in pixels, of the contents of a control.
/// </summary>
/// <returns>
/// A <see cref="T:System.Windows.Forms.Padding"/> that represents the internal spacing of the contents of a control.
/// </returns>
protected override Padding DefaultPadding
{
get { return new Padding(6); }
}
#endregion
#region Methods
/// <summary>
/// Releases the unmanaged resources used by the <see cref="T:System.Windows.Forms.Control"/> and its child controls and optionally releases the managed resources.
/// </summary>
/// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources. </param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.Controls.Remove(_scrollBar);
_scrollBar.Scroll -= this.ScrollBarScrollHandler;
_scrollBar.ValueChanged -= this.ScrollBarScrollHandler;
_scrollBar.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.FontChanged"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data. </param>
protected override void OnFontChanged(EventArgs e)
{
base.OnFontChanged(e);
this.DefineCellSize();
this.Invalidate();
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.MouseWheel"/> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.MouseEventArgs"/> that contains the event data. </param>
protected override void OnMouseWheel(MouseEventArgs e)
{
int value;
base.OnMouseWheel(e);
value = _scrollBar.Value + -e.Delta;
if (value < 0)
{
value = 0;
}
if (value > _scrollBar.Maximum)
{
value = _scrollBar.Maximum;
}
_scrollBar.Value = value;
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.PaddingChanged"/> event.
/// </summary>
/// <param name="e">A <see cref="T:System.EventArgs"/> that contains the event data.</param>
protected override void OnPaddingChanged(EventArgs e)
{
base.OnPaddingChanged(e);
this.Invalidate();
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Paint"/> event.
/// </summary>
/// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data. </param>
protected override void OnPaint(PaintEventArgs e)
{
Point location;
base.OnPaint(e);
e.Graphics.Clear(this.BackColor);
location = new Point(this.Padding.Left, this.Padding.Top + -(_cellSize.Height * this.TopRow));
foreach (ByteGroup group in _groups)
{
location = this.PaintGroup(e.Graphics, group, location);
if (location.Y > this.ClientSize.Height)
{
// simple control, no scrolling so just abort if painting off-screen
break;
}
}
e.Graphics.DrawRectangle(SystemPens.ControlDark, 0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1);
}
/// <summary>
/// Raises the <see cref="E:System.Windows.Forms.Control.Resize"/> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data. </param>
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (_scrollBar != null)
{
int w;
Size size;
w = SystemInformation.VerticalScrollBarWidth;
size = this.ClientSize;
_scrollBar.SetBounds(size.Width - (w + 1), 1, w, size.Height - 2);
}
this.DefineRowsAndColumns();
this.Invalidate();
}
private void DefineCellSize()
{
using (Graphics g = this.CreateGraphics())
{
_cellSize = TextRenderer.MeasureText(g, "9", this.Font, Size.Empty, _flags);
_cellOffset = TextRenderer.MeasureText(g, " ", this.Font, Size.Empty, _flags).
Width;
}
}
private void DefineRowsAndColumns()
{
Size size;
int visibleRows;
size = this.ClientSize;
visibleRows = (size.Height - this.Padding.Vertical) / _cellSize.Height;
if (_totalBytes > 0)
{
_columns = (size.Width - (SystemInformation.VerticalScrollBarWidth + this.Padding.Horizontal)) /
(_cellSize.Width + (_cellOffset * 2));
this.Rows = _totalBytes / _columns;
if (this.Rows > visibleRows)
{
_scrollBar.Maximum = this.Rows - visibleRows;
}
}
else
{
this.Rows = 0;
}
_scrollBar.LargeChange = visibleRows;
_scrollBar.Enabled = this.Rows > visibleRows;
}
private int GetUInt16(IList<byte> buffer)
{
return (buffer[0] << 8) | buffer[1];
}
private int GetUInt32(IList<byte> buffer)
{
return (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];
}
private void Load()
{
_groups.Clear();
if (!string.IsNullOrEmpty(_fileName))
{
using (Stream stream = File.OpenRead(_fileName))
{
byte[] signature;
byte[] majorVersion;
byte[] minorVersion;
signature = this.Read(stream, 4);
majorVersion = this.Read(stream, 2);
minorVersion = this.Read(stream, 2);
if (signature[0] == 'A' && signature[1] == 'S' && signature[2] == 'E' && signature[3] == 'F' &&
this.GetUInt16(majorVersion) == 1 && this.GetUInt16(minorVersion) == 0)
{
byte[] blockCount;
int trailingDataLength;
// ase file
_groups.Add(new ByteGroup(Color.Black, Color.White, signature));
_groups.Add(new ByteGroup(Color.Navy, Color.White, majorVersion));
_groups.Add(new ByteGroup(Color.Navy, Color.White, minorVersion));
blockCount = this.Read(stream, 4);
_groups.Add(new ByteGroup(Color.Orange, Color.White, blockCount));
for (int i = 0; i < this.GetUInt32(blockCount); i++)
{
BlockType actualBlockType;
byte[] blockType;
byte[] blockLength;
int offset;
int otherLength;
int actualBlockLength;
blockType = this.Read(stream, 2);
blockLength = this.Read(stream, 4);
actualBlockType = (BlockType)this.GetUInt16(blockType);
actualBlockLength = this.GetUInt32(blockLength);
offset = 0;
_groups.Add(new ByteGroup(Color.LightGray, Color.Black, blockType));
_groups.Add(new ByteGroup(Color.Gold, Color.Black, blockLength));
if (actualBlockType == BlockType.Color || actualBlockType == BlockType.GroupStart)
{
byte[] nameLength;
byte[] name;
nameLength = this.Read(stream, 2);
name = this.Read(stream, this.GetUInt16(nameLength) * 2);
_groups.Add(new ByteGroup(Color.Yellow, Color.Black, nameLength));
_groups.Add(new ByteGroup(Color.YellowGreen, Color.Black, name));
offset += (name.Length + nameLength.Length);
}
if (actualBlockType == BlockType.Color)
{
byte[] colorModel;
byte[] colorType;
string actualColorModel;
int valueCount;
colorModel = this.Read(stream, 4);
actualColorModel = Encoding.ASCII.GetString(colorModel);
_groups.Add(new ByteGroup(Color.Tomato, Color.Black, colorModel));
switch (actualColorModel)
{
case "RGB ":
case "LAB ":
valueCount = 3;
break;
case "Gray":
valueCount = 1;
break;
case "CMYK":
valueCount = 1;
break;
default:
valueCount = 0;
break;
}
for (int j = 0; j < valueCount; j++)
{
byte[] value;
value = this.Read(stream, 4);
offset += value.Length;
_groups.Add(new ByteGroup(Color.LightSalmon, Color.Black, value));
}
colorType = this.Read(stream, 2);
_groups.Add(new ByteGroup(Color.PaleVioletRed, Color.Black, colorType));
offset += (colorModel.Length + colorType.Length);
}
otherLength = actualBlockLength - offset;
if (otherLength > 0)
{
byte[] other;
other = this.Read(stream, otherLength);
_groups.Add(new ByteGroup(Color.White, Color.LightGray, other));
}
}
// stuff at end of file?
trailingDataLength = (int)(stream.Length - stream.Position);
if (trailingDataLength != 0)
{
byte[] trailingData;
trailingData = this.Read(stream, trailingDataLength);
_groups.Add(new ByteGroup(Color.White, Color.LightGray, trailingData));
}
}
else
{
// some other file
_groups.Add(new ByteGroup(Color.White, Color.LightGray, File.ReadAllBytes(_fileName)));
}
}
}
_totalBytes = _groups.Sum(group => group.Data.Length);
this.DefineRowsAndColumns();
this.Invalidate();
}
/// <summary>
/// Raises the <see cref="TopRowChanged" /> event.
/// </summary>
/// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
private void OnTopRowChanged(EventArgs e)
{
EventHandler handler;
_scrollBar.Value = this.TopRow;
this.Invalidate();
handler = this.TopRowChanged;
handler?.Invoke(this, e);
}
private Point PaintGroup(Graphics graphics, ByteGroup group, Point location)
{
int x;
int y;
int w;
int h;
int offset;
Font font;
Size size;
size = this.ClientSize;
x = location.X;
y = location.Y;
offset = _cellSize.Width + _cellOffset;
w = size.Width - this.Padding.Horizontal;
h = size.Height;
font = this.Font;
using (Brush brush = new SolidBrush(group.BackColor))
{
for (int i = 0; i < group.Data.Length; i++)
{
Rectangle bounds;
bounds = new Rectangle(x, y, offset, _cellSize.Height);
if (bounds.Bottom > 0)
{
graphics.FillRectangle(brush, bounds);
TextRenderer.DrawText(graphics, group.Data[i].ToString("X2"), font, bounds, group.ForeColor, group.BackColor,
_flags);
if (i < group.Data.Length - 1 && x + offset + _cellOffset + _cellSize.Width < w)
{
graphics.FillRectangle(brush, x + offset, y, _cellOffset, _cellSize.Height);
}
}
x += offset + _cellOffset;
if (x + _cellSize.Width >= w)
{
y += _cellSize.Height;
x = this.Padding.Left;
if (y > h)
{
break;
}
}
}
}
return new Point(x, y);
}
private byte[] Read(Stream stream, int length)
{
byte[] buffer;
buffer = new byte[length];
stream.Read(buffer, 0, length);
return buffer;
}
private void ScrollBarScrollHandler(object sender, EventArgs e)
{
this.TopRow = _scrollBar.Value;
}
#endregion
#region Nested type: ByteGroup
private sealed class ByteGroup
{
#region Constructors
public ByteGroup(Color backColor, Color foreColor, byte[] data)
{
this.BackColor = backColor;
this.ForeColor = foreColor;
this.Data = data;
}
#endregion
#region Properties
public Color BackColor { get; set; }
public byte[] Data { get; set; }
public Color ForeColor { get; set; }
#endregion
}
#endregion
}
}
Donate
This software may be used free of charge, but as with all free software there are costs involved to develop and maintain.
If this site or its services have saved you time, please consider a donation to help with running costs and timely updates.
Donate