Ejemplo n.º 1
0
        private static void PaintGfxContextBg(GfxContext gfx, Graphics g)
        {
            Size currentSize = gfx.destSize;

            if (gfx.img == null) // Check for null
            {
                g.FillRectangle(Brushes.Black, 0, 0, currentSize.Width, currentSize.Height);
                return;
            }

            // Draw the image along with opacity
            g.SmoothingMode   = SmoothingMode.AntiAlias;
            g.CompositingMode = CompositingMode.SourceOver;
            Rectangle destr = new Rectangle(0, 0, currentSize.Width, currentSize.Height);

            g.DrawImage(gfx.img, destr, 0, 0, gfx.img.Width, gfx.img.Height, GraphicsUnit.Pixel);
            //g.DrawImage(gfx.img, destr, 0, 0, gfx.img.Width, gfx.img.Height, GraphicsUnit.Pixel, GetIA(gfx.animImageState));
            if (gfx.opacity < 0 && gfx.opacity > -256)
            {
                g.FillRectangle(new SolidBrush(Color.FromArgb(Math.Abs(gfx.opacity), 0, 0, 0)),
                                -1, -1, currentSize.Width + 1, currentSize.Height + 1);
            }
            else if (gfx.opacity > 0 && gfx.opacity < 256)
            {
                g.FillRectangle(new SolidBrush(Color.FromArgb(Math.Abs(gfx.opacity), 255, 255, 255)),
                                -1, -1, currentSize.Width + 1, currentSize.Height + 1);
            }
        }
Ejemplo n.º 2
0
        private void SkipAnimation()
        {
            t.Stop();

            if (currentCtx != null)
            {
                currentCtx.Dispose();
            }
            this.currentCtx = endingContext.Clone();
            if (secondaryCtx != null)
            {
                secondaryCtx.Dispose();
                this.secondaryCtx = null;
            }
            if (startingContext != null)
            {
                startingContext.Dispose();
                startingContext = null;
            }
            if (endingContext != null)
            {
                endingContext.Dispose();
                endingContext = null;
            }
            this.animating = false;

            this.Invalidate();
        }
Ejemplo n.º 3
0
 // Event handlers
 protected override void OnPaint(PaintEventArgs e)
 {
     rendering = true;
     if (currentCtx == null)
     {
         currentCtx          = new GfxContext();
         currentCtx.destSize = NativeResolution.Size;
     }
     if (windowMode)
     {
         float  scaleFactorW = (float)this.Width / NativeResolution.Width;
         Matrix mx           = new Matrix(scaleFactorW, 0, 0, scaleFactorW, -(scaleFactorW), -(scaleFactorW));
         e.Graphics.Transform = mx;
     }
     if (useAnimation && animating && secondaryCtx != null)
     {
         PaintGfxContextBg(currentCtx, e.Graphics);
         PaintGfxContextContent(currentCtx, e.Graphics, false);
         PaintGfxContextContent(secondaryCtx, e.Graphics, false);
     }
     else
     {
         PaintGfxContext(currentCtx, e.Graphics, false);
     }
     rendering = false;
 }
Ejemplo n.º 4
0
        public GfxContext GetCurrentGfxContext()
        {
            GfxContext ctx = new GfxContext();

            ctx.destSize = DisplayEngine.NativeResolution.Size;
            ctx.img      = GetCurrentImage();
            ctx.opacity  = 0;
            return(ctx);
        }
Ejemplo n.º 5
0
 public static void PaintGfxContext(GfxContext gfx, Graphics g, bool forceContent)
 {
     PaintGfxContextBg(gfx, g);
     PaintGfxContextContent(gfx, g, forceContent);
     if (gfx.customPaintingHandler != null)
     {
         gfx.customPaintingHandler(gfx);
     }
 }
Ejemplo n.º 6
0
        // internal
        internal void RefreshUI()
        {
            // Update the list binding & display picture
            currentCtx = proj.GetCurrentGfxContext();
            pnlPreviewImage.Refresh();

            UpdateInfoLabel();
            UpdateNavigationButtons();
        }
Ejemplo n.º 7
0
        private void InternalHideDisplay()
        {
            this.Visible               = false;
            currentCtx                 = new GfxContext(); // Clear out context
            currentCtx.destSize        = NativeResolution.Size;
            currentCtx.animTextOpacity = 0;

            Program.Presenter.DeactiveDisplayer();
        }
Ejemplo n.º 8
0
        private void t_Tick(object sender, EventArgs e)
        {
            animationStep++;
            if (animationStep >= animationDuration)
            {
                SkipAnimation();
                animationStep = 0;
                return;
            }

            if (startingContext != null && endingContext != null)
            {
                if (secondaryCtx == null)
                {
                    secondaryCtx = endingContext.Clone();
                }

                // Calc mid image switch
                secondaryCtx.animImageState = startingContext.animImageState = (float)animationStep / animationDuration;
                if (secondaryCtx.animImageState < 0.5f)
                {
                    currentCtx.img = startingContext.img;
                }
                else
                {
                    currentCtx.img = endingContext.img;
                }

                // Calc opacity changes
                double deltaOpacity = endingContext.opacity - startingContext.opacity;
                deltaOpacity      /= animationDuration;
                currentCtx.opacity = (int)(startingContext.opacity + animationStep * deltaOpacity);

                // Calc text values
                double delta1 = ((double)startingContext.animTextOpacity / (animationDuration - animationChoke));
                double delta2 = ((double)endingContext.animTextOpacity / (animationDuration - animationChoke));
                currentCtx.animTextOpacity = (int)(startingContext.animTextOpacity - animationStep * delta1);
                currentCtx.animTextOpacity = currentCtx.animTextOpacity > 255 ? 255 : currentCtx.animTextOpacity;
                currentCtx.animTextOpacity = currentCtx.animTextOpacity < 0 ? 0 : currentCtx.animTextOpacity;
                if (animationStep > animationChoke)
                {
                    secondaryCtx.animTextOpacity = (int)(endingContext.animTextOpacity - ((animationDuration - animationStep) * delta2));
                    secondaryCtx.animTextOpacity = secondaryCtx.animTextOpacity > 255 ? 255 : secondaryCtx.animTextOpacity;
                    secondaryCtx.animTextOpacity = secondaryCtx.animTextOpacity < 0 ? 0 : secondaryCtx.animTextOpacity;
                }
                else
                {
                    secondaryCtx.animTextOpacity = 0;
                }

                // Issue invalidate
                this.Invalidate();
            }
        }
Ejemplo n.º 9
0
            public void PrepFontFit(GfxContext ctx, Dictionary <int, BibleVerse> verses, int startVerse, PresenterFont font)
            {
                Size nativeSize = DisplayEngine.NativeResolution.Size;

                //////////////////////////////////////////////////////////////////
                // Format data
                BibleVerse bv1      = verses[1];
                string     bookname = Program.BibleDS.BibleLookUp.FindByVersionIdMappingBook(bv1.RefVersion, bv1.RefBook).DisplayBook;
                string     title    = bookname + " " + bv1.RefChapter;
                string     data     = "";

                for (int i = startVerse; i <= verses.Count; i++)
                {
                    data += verses[i].RefVerse + ". " + verses[i].Text + "\r\n";
                }

                //////////////////////////////////////////////////////////////////
                // Measure
                StringFormat sf           = GetStringFormat();
                int          insideHeight = nativeSize.Height - paddingPixels * 2;
                int          insideWidth  = nativeSize.Width - paddingPixels * 2;
                int          titleHeight  = font.SizeInPoints * 2;
                RectangleF   rTitle       = new RectangleF(paddingPixels, paddingPixels, insideWidth, titleHeight);
                RectangleF   rText        = new RectangleF(paddingPixels, paddingPixels + titleHeight,
                                                           insideWidth, insideHeight - titleHeight);

                //////////////////////////////////////////////////////////////////
                // Build context
                ctx.destSize = DisplayEngine.NativeResolution.Size;
                ctx.textRegions.Clear();

                // Title text
                GfxTextRegion trTitle = new GfxTextRegion();

                ctx.textRegions.Add(trTitle);
                trTitle.font = (PresenterFont)font.Clone();
                trTitle.font.SizeInPoints = (int)(trTitle.font.SizeInPoints * 1.5);
                trTitle.message           = title;
                trTitle.bounds            = rTitle;

                // Data
                GfxTextRegion trData = new GfxTextRegion();

                ctx.textRegions.Add(trData);
                trData.font = (PresenterFont)font.Clone();
                trData.font.VerticalAlignment   = VerticalAlignment.Top;
                trData.font.HorizontalAlignment = HorizontalAlignment.Left;
                trData.fontClip = true;
                trData.message  = data;
                trData.bounds   = rText;
            }
Ejemplo n.º 10
0
        public GfxContext Clone()
        {
            GfxContext c = new GfxContext();

            c.img              = this.img;
            c.opacity          = this.opacity;
            c.destSize         = this.destSize;
            c.supportAnimation = this.supportAnimation;
            c.textRegions      = new List <GfxTextRegion>();
            foreach (GfxTextRegion tr in this.textRegions)
            {
                c.textRegions.Add(tr);
            }
            c.animTextOpacity = this.animTextOpacity;
            return(c);
        }
Ejemplo n.º 11
0
        public GfxContext GetContextFromProject()
        {
            if (proj == null || proj as ISupportGfxCtx == null)
            {
                return(null);
            }

            GfxContext receivedContext = ((ISupportGfxCtx)proj).GetCurrentGfxContext();

            // Correction for no content
            if (!paintContent)
            {
                receivedContext.animTextOpacity = 0;
            }

            return(receivedContext);
        }
Ejemplo n.º 12
0
        internal void RestoreContent()
        {
            /// Pre: previous state was black screen

            GfxContext g = GetContextFromProject();

            currentCtx.img = g.img; // Since last was black, copy image so we get fade
            if (useAnimation)
            {
                StartAnimation(currentCtx, g);
            }
            else
            {
                currentCtx = g;
                this.Invalidate();
            }
        }
Ejemplo n.º 13
0
        internal void RefreshUI()
        {
            currentCtx = proj.GetCurrentGfxContext();
            pnlPreviewImage.Refresh();

            // Update the region editing controls
            if (pnlPreviewImage.Controls.Count != proj.data.lTextRegions.Count)
            {
                DetachRegionControls();
                AttachRegionControls();
                LayoutRegionControls();
            }
            else
            {
                LayoutRegionControls();
            }
        }
Ejemplo n.º 14
0
        private void SwitchToBlack()
        {
            GfxContext g = new GfxContext();

            g.destSize        = NativeResolution.Size;
            g.animTextOpacity = 0;
            if (useAnimation)
            {
                StartAnimation(currentCtx, g);
            }
            else
            {
                currentCtx = g;
                this.Invalidate();
            }
            this.Visible = true;
            //this.BringToFront();
        }
Ejemplo n.º 15
0
        private void project_Refresh(object sender, EventArgs e)
        {
            if (proj == null)
            {
                return;
            }

            if (!blackscreen)
            {
                GfxContext receivedContext = GetContextFromProject();
                if (useAnimation && receivedContext.supportAnimation)
                {
                    StartAnimation(currentCtx, receivedContext);
                }
                else
                {
                    currentCtx = receivedContext.Clone();
                    this.Refresh();
                }
            }
        }
Ejemplo n.º 16
0
            public bool PrepSlideMultiTranslation(GfxContext ctx, VerseBreakDown data, int subIndex, PresenterFont font)
            {
                // If only one version is available then fall back
                if (data.bibleVerse.RefVersion == "" || data.bibleVerse.SecondaryVersion == "" ||
                    data.bibleVerse.Text == "" || data.bibleVerse.SecondaryText == "")
                {
                    return(false);
                }

                // Format data
                string primaryText   = subIndex > data.primaryText.Count - 1 ? data.primaryText[data.primaryText.Count - 1] : data.primaryText[subIndex];
                string secondaryText = subIndex > data.secondaryText.Count - 1 ? data.secondaryText[data.secondaryText.Count - 1] : data.secondaryText[subIndex];
                string priRef        = data.bibleVerse.ToString();
                string secRef        = data.bibleVerse.ToString(true);

                Size nativeSize = DisplayEngine.NativeResolution.Size;

                #region Measure
                StringFormat sf           = GetStringFormat();
                int          insideHeight = nativeSize.Height - paddingPixels * 2;
                int          insideWidth  = nativeSize.Width - paddingPixels * 2;
                Point        anchorTop    = new Point(paddingPixels, paddingPixels);
                Point        anchorBottom = new Point(paddingPixels, paddingPixels + (int)((double)insideHeight / 2));

                // Measure the reference blocks
                int refemSize      = (int)(font.SizeInPoints * .9); // actual drawing size is smaller than usual
                int refBlockHeight = (int)(font.SizeInPoints * 1.2);

                // Measure both strings
                RectangleF r1 = new RectangleF(anchorTop.X, anchorTop.Y, insideWidth,
                                               InternalMeasureString(primaryText, font, insideWidth, sf).Height);
                RectangleF r2 = new RectangleF(anchorBottom.X, anchorBottom.Y, insideWidth,
                                               InternalMeasureString(secondaryText, font, insideWidth, sf).Height);

                if (r1.Height + r2.Height + refBlockHeight * 2 > insideHeight)
                {
                    return(false);
                }

                #endregion

                #region Build context
                ctx.destSize = DisplayEngine.NativeResolution.Size;
                ctx.textRegions.Clear();

                // First part
                GfxTextRegion rVerse1 = new GfxTextRegion();
                ctx.textRegions.Add(rVerse1);
                rVerse1.font = font;
                rVerse1.font.HorizontalAlignment = HorizontalAlignment.Left;
                rVerse1.font.VerticalAlignment   = VerticalAlignment.Top;
                rVerse1.message = primaryText;

                // First reference
                GfxTextRegion rRef1 = new GfxTextRegion();
                ctx.textRegions.Add(rRef1);
                rRef1.font = (PresenterFont)font.Clone();
                SetRefFont(rRef1.font);
                rRef1.message = priRef;

                // Second part
                GfxTextRegion rVerse2 = new GfxTextRegion();
                ctx.textRegions.Add(rVerse2);
                rVerse2.font = font;
                rVerse2.font.HorizontalAlignment = HorizontalAlignment.Left;
                rVerse2.font.VerticalAlignment   = VerticalAlignment.Top;
                rVerse2.message = secondaryText;

                // Second reference
                GfxTextRegion rRef2 = new GfxTextRegion();
                ctx.textRegions.Add(rRef2);
                rRef2.font = (PresenterFont)font.Clone();
                SetRefFont(rRef2.font);
                rRef2.message = secRef;

                // Adjust bounds
                int standardMax = (int)((double)insideHeight / 2);
                if (r1.Height + refBlockHeight > standardMax || r2.Height + refBlockHeight > standardMax)
                {
                    rVerse1.bounds         = r1;             // First part
                    rVerse1.bounds.Height += refBlockHeight; // give some slack
                    r1.Y                  += r1.Height;      // First reference
                    rRef1.bounds           = r1;
                    rRef1.bounds.Height    = refBlockHeight;
                    r1.Y                  += refBlockHeight;             // Second part
                    rVerse2.bounds         = r1;
                    rVerse2.bounds.Height += refBlockHeight;             // give some slack
                    r1.Y                  += r2.Height + refBlockHeight; // Second reference
                    rRef2.bounds           = r1;
                    rRef2.bounds.Height    = refBlockHeight;
                }
                else
                {
                    rVerse1.bounds         = r1;                         // First part
                    rVerse1.bounds.Height += refBlockHeight;             // give some slack
                    r1.Y                  += r1.Height + refBlockHeight; // First reference
                    rRef1.bounds           = r1;
                    rRef1.bounds.Height    = refBlockHeight;
                    r1.Y                  += refBlockHeight;             // Second part
                    rVerse2.bounds         = r2;
                    rVerse2.bounds.Height += refBlockHeight;             // give some slack
                    r2.Y                  += r2.Height + refBlockHeight; // Second reference
                    rRef2.bounds           = r2;
                    rRef2.bounds.Height    = refBlockHeight;
                }
                #endregion

                return(true);
            }
Ejemplo n.º 17
0
            public bool PrepSlideDoubleVerse(GfxContext ctx, Dictionary <int, BibleVerse> bibVerses, int currentVerseNum, PresenterFont font)
            {
                #region Format data
                BibleVerse bva        = bibVerses[currentVerseNum];
                BibleVerse bvb        = bibVerses[currentVerseNum + 1];
                string     firstText  = bva.RefVerse + ". " + bva.Text;
                string     secondText = bvb.RefVerse + ". " + bvb.Text;
                string     reference  = bva.ToString() + "-" + bvb.RefVerse;
                #endregion

                Size nativeSize = DisplayEngine.NativeResolution.Size;

                #region Measure
                StringFormat sf           = GetStringFormat();
                int          insideHeight = nativeSize.Height - paddingPixels * 2;
                int          insideWidth  = nativeSize.Width - paddingPixels * 2;
                Point        anchorTop    = new Point(paddingPixels, paddingPixels);
                Point        anchorBottom = new Point(paddingPixels, paddingPixels + (int)((double)insideHeight / 2));

                // Measure the reference blocks
                int refemSize      = (int)(font.SizeInPoints * .9); // actual drawing size is smaller than usual
                int refBlockHeight = (int)(font.SizeInPoints * 1.2);

                // Determine top of rectangle
                // Measure both strings
                RectangleF r = new RectangleF(paddingPixels, 0, insideWidth,
                                              InternalMeasureString(firstText, font, insideWidth, sf).Height);
                int h1      = (int)r.Height; // Get the size of the verse so we can fix the reference at the bottom
                int h2      = (int)InternalMeasureString(secondText, font, insideWidth, sf).Height;
                int offsetY = (int)(((double)insideHeight - h1 - h2 - refBlockHeight) / 2);
                if (font.VerticalAlignment == VerticalAlignment.Top)
                {
                    r.Y = paddingPixels;
                }
                else if (font.VerticalAlignment == VerticalAlignment.Middle)
                {
                    r.Y = offsetY;
                }
                else
                {
                    r.Y = nativeSize.Height - paddingPixels * 2 - h1 - h2 - refBlockHeight;
                }

                // Size check
                int standardMax = (int)((double)insideHeight / 2);
                if (h1 + h2 + refBlockHeight > standardMax)
                {
                    return(false);
                }
                #endregion

                #region Build context

                ctx.destSize = DisplayEngine.NativeResolution.Size;
                ctx.textRegions.Clear();

                // Draw the first part
                GfxTextRegion rVerse = new GfxTextRegion();
                ctx.textRegions.Add(rVerse);
                rVerse.font = font;
                rVerse.font.HorizontalAlignment = HorizontalAlignment.Left;
                rVerse.message = firstText;
                rVerse.bounds  = r;

                GfxTextRegion rVerse2 = new GfxTextRegion();
                ctx.textRegions.Add(rVerse2);
                rVerse2.font    = font;
                rVerse2.message = secondText;
                r.Y            += h1 + refemSize;
                r.Height        = h2;
                rVerse2.bounds  = r;

                // Reference
                GfxTextRegion rRef = new GfxTextRegion();
                ctx.textRegions.Add(rRef);
                rRef.font = (PresenterFont)font.Clone();
                SetRefFont(rRef.font);
                rRef.message       = reference;
                r.Y               += h2 + refBlockHeight - refemSize; // Move to the bottom of the rectangle
                rRef.bounds        = r;
                rRef.bounds.Height = refBlockHeight;

                #endregion

                return(true);
            }
Ejemplo n.º 18
0
            public void PrepSlideSingleVerse(GfxContext ctx, VerseBreakDown data, int subIndex, PresenterFont font)
            {
                #region Format data
                string txt;
                string reference;
                if (data.bibleVerse.RefVersion != "")
                {
                    reference = data.bibleVerse.ToString();
                    txt       = data.primaryText[subIndex];
                }
                else
                {
                    reference = data.bibleVerse.ToString(true);
                    txt       = data.secondaryText[subIndex];
                }
                #endregion

                Size nativeSize = DisplayEngine.NativeResolution.Size;

                #region Measure
                StringFormat sf           = GetStringFormat();
                int          insideHeight = nativeSize.Height - paddingPixels * 2;
                int          insideWidth  = nativeSize.Width - paddingPixels * 2;
                Point        anchorTop    = new Point(paddingPixels, paddingPixels);
                Point        anchorBottom = new Point(paddingPixels, paddingPixels + (int)((double)insideHeight / 2));

                // Measure the reference blocks
                int refemSize      = (int)(font.SizeInPoints * .9); // actual drawing size is smaller than usual
                int refBlockHeight = (int)(font.SizeInPoints * 1.2);
                #endregion

                #region Build context

                ctx.destSize = DisplayEngine.NativeResolution.Size;
                ctx.textRegions.Clear();

                // Primary text
                GfxTextRegion rVerse = new GfxTextRegion();
                ctx.textRegions.Add(rVerse);
                rVerse.font    = font;
                rVerse.message = txt;

                RectangleF r1 = new RectangleF(paddingPixels, 0, insideWidth,
                                               InternalMeasureString(txt, font, insideWidth, sf).Height);
                if (font.VerticalStringAlignment == StringAlignment.Near)
                {
                    r1.Y = paddingPixels;
                }
                else if (font.VerticalStringAlignment == StringAlignment.Center)
                {
                    r1.Y = (float)(((double)insideHeight - r1.Height) / 2) + paddingPixels;
                }
                else
                {
                    r1.Y = nativeSize.Height - r1.Height - refBlockHeight - paddingPixels * 2;
                }
                rVerse.bounds         = r1;
                rVerse.bounds.Height += refBlockHeight; // give some slack

                // Reference
                GfxTextRegion rRef = new GfxTextRegion();
                ctx.textRegions.Add(rRef);
                rRef.font = (PresenterFont)font.Clone();
                SetRefFont(rRef.font);
                rRef.message = reference;

                r1.Y              += r1.Height + refBlockHeight; // +refemSize; // relocate the box
                rRef.bounds        = r1;
                rRef.bounds.Height = refBlockHeight;

                #endregion
            }
Ejemplo n.º 19
0
        // Animation support
        private void StartAnimation(GfxContext startContext, GfxContext endContext)
        {
            if (animating) // If already animating
            {
                if (endContext != null)
                {
                    endingContext = endContext.Clone();
                }
                SkipAnimation(); // jumps to end without animating
                return;
            }

            // Check input
            if (endContext == null)
            {
                endContext          = new GfxContext(); // empty context (paint black)
                endContext.destSize = NativeResolution.Size;
                endContext.opacity  = -255;
            }
            if (startContext == null)
            {
                startContext                 = new GfxContext();
                startContext.destSize        = NativeResolution.Size;
                startContext.animTextOpacity = 0;
            }

            // Check image to correct ramp
            if (startContext.img == null)
            {
                startContext.img     = endContext.img;
                startContext.opacity = -255;
            }
            if (endContext.img == null)
            {
                endContext.img     = startContext.img;
                endContext.opacity = -255;
            }

            // Release previous resources
            if (startingContext != null)
            {
                startingContext.Dispose();
            }
            if (endingContext != null)
            {
                endingContext.Dispose();
            }

            // Adjust animation duration and choke
            if (startContext.animTextOpacity == 0 || endContext.animTextOpacity == 0)
            {
                animationDuration = 10;
                animationChoke    = 0;
            }
            else
            {
                animationDuration = 20;
                animationChoke    = 7;
            }

            this.animating       = true;
            this.startingContext = startContext.Clone();
            this.endingContext   = endContext.Clone();
            t.Start();
        }
Ejemplo n.º 20
0
        private static void PaintGfxContextContent(GfxContext gfx, Graphics g, bool forceContent)
        {
            Size currentSize = gfx.destSize;

            // Paint the text
            foreach (GfxTextRegion textReg in gfx.textRegions)
            {
                // Build the path
                GraphicsPath pth = new GraphicsPath();
                StringFormat sf  = new StringFormat(StringFormatFlags.FitBlackBox);
                if (!textReg.fontClip)
                {
                    sf.Trimming = (StringTrimming.None | sf.Trimming);
                }
                sf.Trimming      = StringTrimming.None;
                sf.Alignment     = textReg.font.HorizontalStringAlignment;
                sf.LineAlignment = textReg.font.VerticalStringAlignment;
                pth.AddString(textReg.message, textReg.font.FontFamily, (int)textReg.font.FontStyle,
                              textReg.font.SizeInPoints, textReg.bounds, sf);

                // Shadow support
                if (textReg.font.Shadow)
                {
                    if (!gfx.imgShadowCache.ContainsKey(textReg.id))
                    {
                        // Calc color for shadow
                        Color cshadow = Color.FromArgb(130, textReg.font.ShadowColor);
                        if (textReg.font.Color == Color.Transparent)
                        {
                            Color c = gfx.opacity > 0 ? Color.White : Color.Black;
                            cshadow = Color.FromArgb(130, c);
                        }

                        // Create pen and fill
                        Pen p = new Pen(cshadow);
                        p.LineJoin = LineJoin.Round;

                        Bitmap   imgShadowCache = new Bitmap(currentSize.Width / 5, currentSize.Height / 5);
                        Graphics g2             = Graphics.FromImage(imgShadowCache);
                        Matrix   mx             = new Matrix(1.0f / 5, 0, 0, 1.0f / 5, -(1.0f / 5), -(1.0f / 5));
                        g2.SmoothingMode = SmoothingMode.AntiAlias;
                        g2.Transform     = mx;

                        g2.DrawPath(p, pth); // Draw

                        // Store in cache
                        gfx.imgShadowCache[textReg.id] = imgShadowCache;
                    }

                    if (gfx.animTextOpacity == 255)
                    {
                        Image shadow = gfx.imgShadowCache[textReg.id];
                        //g.CompositingMode = CompositingMode.SourceOver;
                        //g.CompositingQuality = CompositingQuality.AssumeLinear;
                        g.DrawImage(shadow, new Rectangle(0, 0, currentSize.Width, currentSize.Height),
                                    0, 0, shadow.Width, shadow.Height, GraphicsUnit.Pixel); // , GetIA((float)gfx.animTextOpacity / 255));
                    }
                }

                // Outline support
                if (textReg.font.Outline == true)
                {
                    Color clrOutline = Color.FromArgb(gfx.animTextOpacity, textReg.font.OutlineColor);
                    Pen   p          = new Pen(clrOutline, 2);
                    p.LineJoin = LineJoin.Round;
                    g.DrawPath(p, pth);
                }

                // Determine auto color
                Color clr = textReg.font.Color;
                if (textReg.font.Color == Color.Transparent)
                {
                    clr = gfx.opacity > 0 ? Color.Black : Color.White;
                }

                // Adjust text opacity
                if (!forceContent)
                {
                    clr = Color.FromArgb(gfx.animTextOpacity, clr);
                }
                Brush br = new SolidBrush(clr);
                g.FillPath(br, pth);

                // Debug boxes
                //g.DrawRectangle(Pens.Red, Rectangle.Round(textReg.bounds));
            }
        }