lipsync/trunk/LipSync/Editor/Character.cs

301 lines
9.4 KiB
C#

/*
* Character.cs
* Copyright (c) 2007-2009 kbinani
*
* This file is part of LipSync.
*
* LipSync is free software; you can redistribute it and/or
* modify it under the terms of the BSD License.
*
* LipSync 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.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace LipSync {
public enum CharacterType {
def,
plugin
}
[Serializable]
public class Character : IDisposable {
public CharacterType type;
string m_Name;
public PluginConfig m_pluginConfig;
public Size m_plugin_drawarea;
[Obsolete]
public Image Base;
[Obsolete]
public Image a;
[Obsolete]
public Image aa;
[Obsolete]
public Image i;
[Obsolete]
public Image u;
[Obsolete]
public Image e;
[Obsolete]
public Image o;
[Obsolete]
public Image xo;
[Obsolete]
public Image nn;
public List<ImageEntry> Images;
[NonSerialized]
private Bitmap m_cache = null;
[NonSerialized]
private string m_cache_draw = "";
[OptionalField]
public string version;//setDefaultで変更するので、readonlyにしたいけどできん
[OptionalField]
public Size m_size;
[OptionalField]
public Bitmap m_preview = null;
[NonSerialized]
bool internal_operation = false;
[OnDeserializing]
private void onDeserializing( StreamingContext sc ) {
version = "0";
m_size = new Size( 0, 0 );
}
[OnSerialized]
private void onSerialized( StreamingContext sc ) {
if ( m_size.Equals( new Size( 0, 0 ) ) ) {
foreach ( ImageEntry img in Images ) {
if ( img.title == "base" ) {
if ( img.Image != null ) {
m_size = new Size( img.Image.Width, img.Image.Height );
break;
}
}
}
}
}
[OnDeserialized]
private void onDeserialized( StreamingContext sc ){
// 古いバージョンの*.lseとの互換性を保つため。
// base, a, ..., nnのデータをImagesに移動させる
if ( nn != null ) {
Images.Insert( 0, new ImageEntry( "nn", nn, "口", false ) );
nn.Dispose();
}
if ( xo != null ) {
Images.Insert( 0, new ImageEntry( "xo", xo, "口", false ) );
xo.Dispose();
}
if ( o != null ) {
Images.Insert( 0, new ImageEntry( "o", o, "口", false ) );
o.Dispose();
}
if ( e != null ) {
Images.Insert( 0, new ImageEntry( "e", e, "口", false ) );
e.Dispose();
}
if ( u != null ) {
Images.Insert( 0, new ImageEntry( "u", u, "口", false ) );
u.Dispose();
}
if ( i != null ) {
Images.Insert( 0, new ImageEntry( "i", i, "口", false ) );
i.Dispose();
}
if ( aa != null ) {
Images.Insert( 0, new ImageEntry( "aa", aa, "口", false ) );
aa.Dispose();
}
if ( a != null ) {
Images.Insert( 0, new ImageEntry( "a", a, "口", false ) );
a.Dispose();
}
if ( Base != null ) {
Images.Insert( 0, new ImageEntry( "base", Base, "本体", true ) );
Base.Dispose();
}
if ( version == "0" ) {
for ( int k = 0; k < Images.Count; k++ ) {
if ( Images[k].title == "base" ) {
Images[k].IsDefault = true;
m_size = Images[k].Image.Size;
version = "2";
}
}
}
if ( m_size.Width <= 0 || m_size.Height <= 0 ) {
int max_x = 0;
int max_y = 0;
foreach ( ImageEntry img in Images ) {
if ( img.Image != null ) {
max_x = Math.Max( max_x, img.Image.Width + img.XOffset );
max_y = Math.Max( max_y, img.Image.Height + img.YOffset );
}
}
m_size = new Size( max_x, max_y );
}
}
public void Dispose() {
m_Name = null;
m_pluginConfig = null;
if ( Base != null ) {
Base.Dispose();
}
if ( a != null ) {
a.Dispose();
}
if ( aa != null ) {
aa.Dispose();
}
if ( i != null ) {
i.Dispose();
}
if ( u != null ) {
u.Dispose();
}
if ( e != null ) {
e.Dispose();
}
if ( o != null ) {
o.Dispose();
}
if ( xo != null ) {
xo.Dispose();
}
if ( nn != null ) {
nn.Dispose();
}
Images.Clear();
}
public void Write( Stream stream ) {
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize( stream, this );
}
public string GetMD5() {
System.Security.Cryptography.MD5CryptoServiceProvider mcsp = new System.Security.Cryptography.MD5CryptoServiceProvider();
using ( MemoryStream ms = new MemoryStream() ) {
this.Write( ms );
byte[] dat = mcsp.ComputeHash( ms );
string res = "";
foreach ( byte b in dat ) {
res += b.ToString( "x2" );
}
return res;
}
return "";
}
public static Character FromFile( Stream stream ) {
Character result = null;
BinaryFormatter bf = new BinaryFormatter();
result = (Character)bf.Deserialize( stream );
bf = null;
return result;
}
public static Character FromFile( string filepath ) {
Character result = null;
if ( File.Exists( filepath ) ) {
using ( FileStream fs = new FileStream( filepath, FileMode.Open ) ) {
result = FromFile( fs );
}
}
return result;
}
public int Width {
get {
return m_size.Width;
}
}
public int Height {
get {
return m_size.Height;
}
}
public string Name {
get {
return m_Name;
}
set {
m_Name = value;
}
}
public Bitmap DefaultFace {
get {
string type = "";
foreach ( ImageEntry img in this.Images ) {
if ( img.IsDefault ) {
type += img.title + "\n";
}
}
Bitmap res = Face( type );
#if DEBUG
if ( res == null ) {
Common.DebugWriteLine( "Character.DefaultFace.get(); res==null" );
Common.DebugWriteLine( " Width=" + Width );
Common.DebugWriteLine( " Height=" + Height );
Common.DebugWriteLine( " type=" + type );
}
#endif
return res;
}
}
public Bitmap Face( string type ) {
if ( Width <= 0 || Height <= 0 ) {
return null;
}
if ( m_cache != null ) {
if ( m_cache_draw == type ) {
return (Bitmap)m_cache.Clone();
}
}
Bitmap bmp = new Bitmap( Width, Height );
string[] spl = type.Split( "\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries );
using ( Graphics g = Graphics.FromImage( bmp ) ) {
//Image drawing;
for ( int i = 0; i < spl.Length; i++ ) {
for ( int index = 0; index < Images.Count; index++ ) {
if ( Images[index].title == spl[i] ) {
//drawing = Images[index].image;
Images[index].DrawTo( g );
break;
}
}
}
}
m_cache_draw = type;
if ( m_cache != null ) {
m_cache.Dispose();
}
m_cache = (Bitmap)bmp.Clone();
return bmp;
}
}
}