Aegisub/devel/SSATool/Style.cs

215 lines
9.9 KiB
C#

/*
SSATool - A collection of utilities for Advanced Substation Alpha
Copyright (C) 2007 Dan Donovan
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; ONLY under version 2
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
using System;
using System.Drawing;
using System.Windows.Forms;
namespace SSATool {
/// <summary>
/// (A)SSA style (copied/adapted from VSFilter)
/// </summary>
public class Style : ICloneable {
public double outlineWidth;
public double shadowDepth;
public double fontScaleX, fontScaleY; // percent
public double fontSpacing; // +/- pixels
public double fontAngleZ, fontAngleX, fontAngleY;
public float fontSize;
public string name, fontName;
public Color[] colors; //pri,sec,outline/bg,shadow
public int marginl, marginr, margint, marginb;
public int charset;
public int scrAlignment; // 1 - 9: as on the numpad, 0: default
public int borderStyle; // 0: outline, 1: opaque box
public bool fBlur, fBold, fItalic, fUnderline, fStrikeOut;
public bool enabled;
public byte relativeTo;
public Style() {
// Set default values
name = "Default";
fontName = "Arial";
fontSize = 20;
colors = new System.Drawing.Color[4];
colors[0] = System.Drawing.Color.White;
colors[1] = System.Drawing.Color.FromArgb(0,0xFF,0xFF,0);
colors[2] = System.Drawing.Color.Black;
colors[3] = System.Drawing.Color.Black;
marginl = marginr = margint = marginb = 30;
scrAlignment = 2;
borderStyle = 0;
outlineWidth = 2;
shadowDepth = 3;
fontScaleX = fontScaleY = 100.0;
fontSpacing = 0;
fBlur = fBold = fItalic = fUnderline = false;
fontAngleZ = fontAngleX = fontAngleY = 0;
enabled = true;
}
public Style(string Name) : this() {
this.name=Name;
}
public Object Clone() {
return this.MemberwiseClone();
}
public Font GetFont() {
float size = (float)fontSize;
Font prelim = new Font(fontName, size);
FontFamily ff = prelim.FontFamily;
FontStyle fs = FontStyle.Regular;
if (fBold) fs |= FontStyle.Bold;
if (fItalic) fs |= FontStyle.Italic;
if (fUnderline) fs |= FontStyle.Underline;
if (fStrikeOut) fs |= FontStyle.Strikeout;
bool vsfilter=true;
bool scaledpi=false;
if (vsfilter)
size *= ff.GetEmHeight(fs) / (ff.GetCellAscent(fs) + ff.GetCellDescent(fs));
if (scaledpi)
size*=(72.0f/Form1.listSSAg.DpiY);
return new System.Drawing.Font(fontName, size, fs);
}
public Rectangle GetMarginRect() {
if (Form1.sver <= 5) marginb = margint;
return new Rectangle(marginl,marginr,Form1.ResX-(marginl+marginr),Form1.ResY-(margint+marginb));
}
public override bool Equals(object obj) {
if (obj is Style) {
Style s = (Style)obj;
return ((String.Equals(this.fontName, s.fontName, StringComparison.OrdinalIgnoreCase)) &&
(this.fontSize.Equals(s.fontSize)) &&
(this.fItalic.Equals(s.fItalic)) &&
(this.fUnderline.Equals(s.fUnderline)) &&
(this.fStrikeOut.Equals(s.fStrikeOut)) &&
(this.colors[0].Equals(s.colors[0])) &&
(this.colors[1].Equals(s.colors[1])) &&
(this.colors[2].Equals(s.colors[2])) &&
(this.colors[3].Equals(s.colors[3])) &&
(this.scrAlignment == s.scrAlignment) &&
(this.borderStyle == s.borderStyle) &&
(this.outlineWidth == s.outlineWidth) &&
(this.shadowDepth == s.shadowDepth) &&
(this.fontScaleX == s.fontScaleX) &&
(this.fontScaleY == s.fontScaleY) &&
(this.fontSpacing == s.fontSpacing) &&
(this.fBold == s.fBold) &&
(this.fBlur == s.fBlur) &&
(this.fontAngleZ == s.fontAngleZ) &&
(this.fontAngleX == s.fontAngleX) &&
(this.fontAngleY == s.fontAngleY));
}
else if (obj is string) return (String.Equals(this.name, (string)obj, StringComparison.OrdinalIgnoreCase));
else return false;
}
public override int GetHashCode() {
return base.GetHashCode ();
}
public override string ToString() {
uint andMask = (Form1.sver==4)?0xFFFFFF:0xFFFFFFFF; // cut out alpha if v4 with this and
string retStr = String.Format("Style: {0},{1},{2},&H{3:X6}&,&H{4:X6}&,&H{5:X6}&,&H{6:X6}&,{7},{8},",
this.name, this.fontName, this.fontSize, this.colors[0].ToArgb()&andMask,
this.colors[1].ToArgb()&andMask, this.colors[2].ToArgb()&andMask,
this.colors[3].ToArgb()&andMask, (this.fBold ? "-1" : "0"), (this.fItalic ? "-1" : "0"));
if (Form1.sver >= 5) {
retStr = String.Format("{0}{1},{2},{3},{4},{5},{6},",
retStr,
(this.fUnderline ? "-1" : "0"),
(this.fStrikeOut ? "-1" : "0"),
this.fontScaleX, this.fontScaleY,
this.fontSpacing, this.fontAngleZ);
}
retStr += String.Format("{0},{1},{2},{3},{4:G4},{5:G4},{6:G4},",
this.borderStyle, this.outlineWidth, this.shadowDepth,
this.scrAlignment, this.marginl, this.marginr, this.margint);
if (Form1.sver >= 6) retStr += Convert.ToString(this.marginb,Util.cfi) + ",";
else if (Form1.sver == 4) retStr += Convert.ToString(this.colors[0].A,Util.cfi) + ",";
retStr += Convert.ToString(this.charset,Util.cfi);
if (Form1.sver >= 6) retStr += "," + this.relativeTo.ToString(Util.cfi);
return retStr;
}
public static Style ParseStyle(string inStr) {
return ParseStyle(inStr, Form1.sver);
}
public static Style ParseStyle(string inStr, int scriptVer) {
int startpos = inStr.IndexOf(':')+1;
string[] xInfo = inStr.Substring(startpos,inStr.Length-startpos).TrimStart().Split(",".ToCharArray());
Style style = new Style();
int index;
uint alpha = (scriptVer != 4 ? 0 : (Util.ReadColor(xInfo[16]) << 24));
style.name = xInfo[0];
style.fontName = xInfo[1];
style.fontSize = float.Parse(xInfo[2]);
style.colors[0] = Util.uintToColor(Util.ReadColor(xInfo[3])+alpha);
style.colors[1] = Util.uintToColor(Util.ReadColor(xInfo[4])+alpha);
style.colors[2] = Util.uintToColor(Util.ReadColor(xInfo[5])+alpha);
style.colors[3] = Util.uintToColor(Util.ReadColor(xInfo[6])+alpha);
style.fBold = !String.Equals(xInfo[7], "0", StringComparison.Ordinal);
style.fItalic = !String.Equals(xInfo[index=8], "0", StringComparison.Ordinal);
if (scriptVer >= 5) {
style.fUnderline = !String.Equals(xInfo[++index], "0", StringComparison.Ordinal);
style.fStrikeOut = !String.Equals(xInfo[++index], "0", StringComparison.Ordinal);
style.fontScaleX = double.Parse(xInfo[++index]);
style.fontScaleY = double.Parse(xInfo[++index]);
style.fontSpacing = double.Parse(xInfo[++index]);
style.fontAngleZ = double.Parse(xInfo[++index]);
}
style.borderStyle = int.Parse(xInfo[++index]);
style.outlineWidth = double.Parse(xInfo[++index]);
style.shadowDepth = double.Parse(xInfo[++index]);
style.scrAlignment = int.Parse(xInfo[++index]);
style.marginl = int.Parse(xInfo[++index]);
style.marginr = int.Parse(xInfo[++index]);
style.margint = int.Parse(xInfo[++index]);
if (scriptVer >= 6) style.marginb = int.Parse(xInfo[++index]);
if (scriptVer == 4) index++; //alphaLevel is in v4 only and is taken care of at the top (uint alpha), so just advance the index
style.charset = int.Parse(xInfo[++index]);
if (scriptVer >= 6) style.relativeTo = byte.Parse(xInfo[++index]);
//Following is code from VSFilter, but since we're not interpreting this, merely spitting it back out the way it came in, we don't currently need it
//if (sver <= 4) style.scrAlignment = ((style.scrAlignment & 4) == 1) ? ((style.scrAlignment & 3) + 6) // top
// : ((style.scrAlignment & 8) == 1) ? ((style.scrAlignment & 3) + 3) // mid
// : (style.scrAlignment & 3); // bottom
return style;
}
}
}