Author: spouliot
Date: 2007-10-31 08:51:32 -0500 (Wed, 31 Oct 2007)
New Revision: 88553

Modified:
   trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog
   trunk/mcs/class/System.Drawing/System.Drawing/ImageAnimator.cs
Log:
2007-10-31  Sebastien Pouliot  <[EMAIL PROTECTED]>

        * ImageAnimator.cs: Fix delay == 0 to match most browser (imaginative)
        definitions of "0". Don't throw on null images. Synchronize hashtable.
        Remove unrequired loops.



Modified: trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog
===================================================================
--- trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog     2007-10-31 
13:14:49 UTC (rev 88552)
+++ trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog     2007-10-31 
13:51:32 UTC (rev 88553)
@@ -1,3 +1,9 @@
+2007-10-31  Sebastien Pouliot  <[EMAIL PROTECTED]>
+
+       * ImageAnimator.cs: Fix delay == 0 to match most browser (imaginative)
+       definitions of "0". Don't throw on null images. Synchronize hashtable.
+       Remove unrequired loops.
+
 2007-10-17  Geoff Norton  <[EMAIL PROTECTED]>
 
        * Graphics.cs: Only synchronize the display on Flush when we actually 
have

Modified: trunk/mcs/class/System.Drawing/System.Drawing/ImageAnimator.cs
===================================================================
--- trunk/mcs/class/System.Drawing/System.Drawing/ImageAnimator.cs      
2007-10-31 13:14:49 UTC (rev 88552)
+++ trunk/mcs/class/System.Drawing/System.Drawing/ImageAnimator.cs      
2007-10-31 13:51:32 UTC (rev 88553)
@@ -1,12 +1,13 @@
 //
 // System.Drawing.ImageAnimator.cs
 //
-// Author:
-//   Dennis Hayes ([EMAIL PROTECTED])
-//   Sanjay Gupta ([EMAIL PROTECTED])
+// Authors:
+//     Dennis Hayes ([EMAIL PROTECTED])
+//     Sanjay Gupta ([EMAIL PROTECTED])
+//     Sebastien Pouliot  <[EMAIL PROTECTED]>
 //
 // (C) 2002 Ximian, Inc
-// Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2004,2006-2007 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -28,191 +29,146 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System.Collections;
 using System.Drawing.Imaging;
 using System.Threading;
-using System.Collections;
 
-namespace System.Drawing
-{
-       //AnimateEventArgs class
-       class AnimateEventArgs : EventArgs 
-       {  
+namespace System.Drawing {
+
+       class AnimateEventArgs : EventArgs {
+
                private int frameCount;
-               private int activeFrameCount = 0;
+               private int activeFrame;
                private Thread thread;
-      
-               //Constructor.
-               //
-               public AnimateEventArgs(Image img)
+
+               public AnimateEventArgs (Image image)
                {
-                       Guid[] dimensionList = img.FrameDimensionsList;
-                       int length = dimensionList.Length;
-                       for (int i=0; i<length; i++) {
-                               if (dimensionList 
[i].Equals(FrameDimension.Time.Guid))
-                                       this.frameCount = img.GetFrameCount 
(FrameDimension.Time);
-                       }                       
+                       frameCount = image.GetFrameCount (FrameDimension.Time);
                }
       
-               public int FrameCount {     
-                       get { 
-                               return frameCount;
-                       }      
+               public Thread RunThread {
+                       get { return thread; }
+                       set { thread = value; }
                }
-      
-               public int ActiveFrameCount {
-                       get {
-                               return activeFrameCount;
-                       }
 
-                       set {
-                               activeFrameCount = value;
-                       }
-               }
+               public int GetNextFrame ()
+               {
+                       if (activeFrame < frameCount - 1)
+                               activeFrame++;
+                       else
+                               activeFrame = 0;
 
-               public Thread RunThread{
-                       get {
-                               return thread;
-                       }
-
-                       set {
-                               thread = value;
-                       }
+                       return activeFrame;
                }
        }
 
-       /// <summary>
-       /// Summary description for ImageAnimator.
-       /// </summary>
-       /// 
-       [MonoTODO]
-       public sealed class ImageAnimator
-       {
-               static Hashtable ht = new Hashtable (); 
-               
+       public sealed class ImageAnimator {
+
+               static Hashtable ht = Hashtable.Synchronized (new Hashtable ());
+
                private ImageAnimator ()
                {
-                       //
-                       // TODO: Add constructor logic here
-                       //
                }
 
-               public static void Animate (Image img, EventHandler 
onFrameChangeHandler)
+               public static void Animate (Image image, EventHandler 
onFrameChangeHandler)
                {
-                       if (img == null)
-                               throw new System.NullReferenceException 
("Object reference not set to an instance of an object.");
-                       
-                       if (!ht.ContainsKey (img)) {
-                               AnimateEventArgs evtArgs = new AnimateEventArgs 
(img);
-                               int delay;
-                               try {
-                                       PropertyItem item = img.GetPropertyItem 
(0x5100); // FrameDelay in libgdiplus
-                                       // Time is in 1/100th of a second
-                                       delay = (item.Value [0] + item.Value 
[1] * 256) * 10;
-                               } catch {
-                                       delay = 200;
-                               }
+                       // must be non-null and contain animation time frames
+                       if (!CanAnimate (image))
+                               return;
 
-                               WorkerThread WT = new WorkerThread 
(onFrameChangeHandler, evtArgs, delay);
-                               ThreadStart TS = new 
ThreadStart(WT.LoopHandler);       
-                               Thread thread = new Thread(TS);
-                               thread.IsBackground = true;
-                               evtArgs.RunThread = thread;
-                               ht.Add (img, evtArgs);
-                               
-                               thread.Start();                         
+                       // is animation already in progress ?
+                       if (ht.ContainsKey (image))
+                               return;
+
+                       PropertyItem item = image.GetPropertyItem (0x5100); // 
FrameDelay in libgdiplus
+                       byte[] value = item.Value;
+                       int[] delay = new int [(value.Length >> 2)];
+                       for (int i=0, n=0; i < value.Length; i += 4, n++) {
+                               int d = BitConverter.ToInt32 (value, i) * 10;
+                               // follow worse case (Opera) see 
http://news.deviantart.com/article/27613/
+                               delay [n] = d < 100 ? 100 : d;
                        }
+
+                       AnimateEventArgs aea = new AnimateEventArgs (image);
+                       WorkerThread wt = new WorkerThread 
(onFrameChangeHandler, aea, delay);
+                       Thread thread = new Thread (new ThreadStart 
(wt.LoopHandler));
+                       thread.IsBackground = true;
+                       aea.RunThread = thread;
+                       ht.Add (image, aea);
+                       thread.Start ();
                }
 
-               public static bool CanAnimate (Image img)
+               public static bool CanAnimate (Image image)
                {
-                       //An image can animate if it has multiple frame in
-                       //time based FrameDimension else return false
-                       //Doubt what if the image has multiple frame in page
-                       //based FrameDimension
-                       if (img == null)
+                       if (image == null)
                                return false;
 
-                       //Need to check whether i can do this without iterating
-                       //within the FrameDimensionsList, ie just call 
GetFrameCount
-                       //with parameter FrameDimension.Time
-                       Guid[] dimensionList = img.FrameDimensionsList;
-                       int length = dimensionList.Length;
-                       int frameCount;
-                       for (int i=0; i<length; i++) 
-                       {
-                               if (dimensionList 
[i].Equals(FrameDimension.Time.Guid)) 
-                               {
-                                       frameCount = img.GetFrameCount 
(FrameDimension.Time);
-                                       if (frameCount > 1)
-                                               return true;
-                               }
-                       }                       
-
-                       return false;           
+                       return (image.GetFrameCount (FrameDimension.Time) > 1);
                }
 
-               public static void StopAnimate (Image img, EventHandler 
onFrameChangeHandler)
+               public static void StopAnimate (Image image, EventHandler 
onFrameChangeHandler)
                {
-                       if (img == null)
-                               throw new System.NullReferenceException 
("Object reference not set to an instance of an object.");                      
+                       if (image == null)
+                               return;
 
-                       if (ht.ContainsKey (img)) {
-                               AnimateEventArgs evtArgs = (AnimateEventArgs) 
ht [img];
+                       if (ht.ContainsKey (image)) {
+                               AnimateEventArgs evtArgs = (AnimateEventArgs) 
ht [image];
                                evtArgs.RunThread.Abort ();
-                               ht.Remove (img);
-                       }                               
+                               ht.Remove (image);
+                       }
                }
 
                public static void UpdateFrames ()
                {
-                       foreach (Image img in ht.Keys) {
-                               UpdateFrames (img);
-                       }
+                       foreach (Image image in ht.Keys)
+                               UpdateImageFrame (image);
                }
-               
-               public static void UpdateFrames (Image img)
+
+
+               public static void UpdateFrames (Image image)
                {
-                       if (img == null)
-                               throw new System.NullReferenceException 
("Object reference not set to an instance of an object.");
+                       if (image == null)
+                               return;
 
-                       if (ht.ContainsKey (img)){
-                               //Need a way to get the delay during animation
-                               AnimateEventArgs evtArgs = (AnimateEventArgs) 
ht [img];
-                               if (evtArgs.ActiveFrameCount < 
evtArgs.FrameCount-1){
-                                       evtArgs.ActiveFrameCount ++;
-                                       img.SelectActiveFrame 
(FrameDimension.Time, evtArgs.ActiveFrameCount);
-                               } 
-                               else
-                                       evtArgs.ActiveFrameCount = 0;
-                               ht [img] = evtArgs;
-                       }                       
+                       if (ht.ContainsKey (image))
+                               UpdateImageFrame (image);
                }
+
+               // this method avoid checks that aren't requied for 
UpdateFrames()
+               private static void UpdateImageFrame (Image image)
+               {
+                       AnimateEventArgs aea = (AnimateEventArgs) ht [image];
+                       image.SelectActiveFrame (FrameDimension.Time, 
aea.GetNextFrame ());
+               }
        }
 
-       class WorkerThread
-       {
-               EventHandler frameChangeHandler;
-               AnimateEventArgs animateEventArgs;
-               int delay;
-                               
-               public WorkerThread (EventHandler frmChgHandler, 
AnimateEventArgs aniEvtArgs, int delay)
+       class WorkerThread {
+
+               private EventHandler frameChangeHandler;
+               private AnimateEventArgs animateEventArgs;
+               private int[] delay;
+
+               public WorkerThread (EventHandler frmChgHandler, 
AnimateEventArgs aniEvtArgs, int[] delay)
                {
                        frameChangeHandler = frmChgHandler;
                        animateEventArgs = aniEvtArgs;
                        this.delay = delay;
                }
-    
-               public void LoopHandler()
+
+               public void LoopHandler ()
                {
                        try {
+                               int n = 0;
                                while (true) {
-                                       Thread.Sleep (delay);
+                                       Thread.Sleep (delay [n++]);
                                        frameChangeHandler (null, 
animateEventArgs);
-                               }                               
-                       } catch (ThreadAbortException) { 
+                                       if (n == delay.Length)
+                                               n = 0;
+                               }
+                       }
+                       catch (ThreadAbortException) {
                                Thread.ResetAbort (); // we're going to finish 
anyway
                        }
                }
        }
 }
-

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to