using System; using System.Drawing; using System.Windows.Forms; using Microsoft.StylusInput; using Microsoft.Ink; class RealTimeDropShadow3 : Form { public static void Main() { Application.Run(new RealTimeDropShadow3()); } public RealTimeDropShadow3() { Text = "Real-Time Drop Shadow (Program 3)"; BackColor = Color.White; Size = new Size(640, 480); RealTimeStylus rts = new RealTimeStylus(this,true); // Initialize a pair of dynamic renderers, one for shadow, one for ink. DynamicRenderer drInk = new DynamicRenderer(this); DynamicRenderer drShadow = new DynamicRenderer(this); DrawingAttributes daInk = new DrawingAttributes(); daInk.Color = Color.Indigo; daInk.IgnorePressure = false; daInk.Width = daInk.Height = 500; drInk.DrawingAttributes = daInk; drInk.Enabled = true; DrawingAttributes daShadow = daInk.Clone(); daShadow.Color = TransformColor(daInk.Color); daShadow.Width = daShadow.Height = 500; daShadow.RasterOperation = RasterOperation.MaskPen; drShadow.DrawingAttributes = daShadow; drShadow.Enabled = true; // Initialize a pair of packet-transform plugins, one to move the ink // down and right, the other back up and left. System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix(); matrix.Translate(250,250); TransformerStylusPlugin xformLR = new TransformerStylusPlugin(matrix); matrix.Invert(); TransformerStylusPlugin xformUL = new TransformerStylusPlugin(matrix); // Add shadow before ink, to get proper effect -- must move the points down/right first, then back up/left. rts.SyncPluginCollection.Add(xformLR); rts.SyncPluginCollection.Add(drShadow); rts.SyncPluginCollection.Add(xformUL); rts.SyncPluginCollection.Add(drInk); rts.Enabled = true; } // Helper method to produce a MaskPen-compatible shadow color. static Color TransformColor(Color ink) { // Produce a lighter, but maskpen-compatible color. byte r = TransformColorComponent(ink.R); byte g = TransformColorComponent(ink.G); byte b = TransformColorComponent(ink.B); Color c = Color.FromArgb(r,g,b); System.Diagnostics.Debug.WriteLine( String.Format("{0},{1},{2}->{3},{4},{5}",ink.R, ink.G, ink.B, c.R,c.G,c.B)); return c; } static byte TransformColorComponent(byte c) { // For best visual results, esp when strokes intersect or overlap, // the shadow color should be a lighter mask of the ink color. We // achieve this by finding the highest-order zero bit in each R, G, // B value, and mask it on. byte b = 0x80; while (b > 0) { if ((c & b) == 0) return (byte)(c | b); b = (byte)(b>>1); } return c; } }