/// <summary>
        /// Draws the image cropped based on alignment. The image is always drawn in proper aspect ratio by this method.
        /// </summary>
        /// <param name="zGraphics"></param>
        /// <param name="zBmp"></param>
        /// <param name="zElement"></param>
        private static void DrawGraphicOriginalSize(Graphics zGraphics, Bitmap zBmp, ProjectLayoutElement zElement)
        {
            var nSourceX = 0;
            var nSourceY = 0;

            var nX = 0;
            var nY = 0;

            // determine if the update is needed for drawing source X or target X
            if (zBmp.Width > zElement.width)
            {
                UpdateAlignmentValue(zElement.GetHorizontalAlignment(), ref nSourceX, zBmp.Width, zElement.width);
            }
            else
            {
                UpdateAlignmentValue(zElement.GetHorizontalAlignment(), ref nX, zElement.width, zBmp.Width);
            }
            // determine if the update is needed for drawing source Y or target Y
            if (zBmp.Height > zElement.height)
            {
                UpdateAlignmentValue(zElement.GetVerticalAlignment(), ref nSourceY, zBmp.Height, zElement.height);
            }
            else
            {
                UpdateAlignmentValue(zElement.GetVerticalAlignment(), ref nY, zElement.height, zBmp.Height);
            }
            zGraphics.DrawImage(zBmp, nX, nY, new Rectangle(nSourceX, nSourceY, zElement.width, zElement.height), GraphicsUnit.Pixel);
        }
示例#2
0
        private static void DrawGraphic(Graphics zGraphics, string sFile, ProjectLayoutElement zElement)
        {
            string sPath = sFile;

            if (sPath.Equals("none", StringComparison.CurrentCultureIgnoreCase))
            {
                return;
            }
            if (!File.Exists(sPath))
            {
                sPath = ProjectManager.Instance.ProjectPath + sFile;
            }
            if (File.Exists(sPath))
            {
                var zBmp = 255 != zElement.opacity
                    ? LoadOpacityImageFromCache(sPath, zElement)
                    : LoadImageFromCache(sPath);

                int nWidth  = zElement.width;
                int nHeight = zElement.height;

                if (zElement.keeporiginalsize)
                {
                    DrawGraphicOriginalSize(zGraphics, zBmp, zElement);
                    return;
                }

                if (zElement.lockaspect)
                {
                    var fAspect = (float)zBmp.Tag;

                    var nTargetHeight = (int)((float)nWidth / fAspect);
                    if (nTargetHeight < nHeight)
                    {
                        nHeight = (int)((float)nWidth / fAspect);
                    }
                    else
                    {
                        nWidth = (int)((float)nHeight * fAspect);
                    }
                }

                int nX = 0;
                int nY = 0;

                // standard alignment adjustment
                UpdateAlignmentValue(zElement.GetHorizontalAlignment(), ref nX, zElement.width, nWidth);
                UpdateAlignmentValue(zElement.GetVerticalAlignment(), ref nY, zElement.height, nHeight);

                zGraphics.DrawImage(zBmp, nX, nY, nWidth, nHeight);
            }
            else
            {
                IssueManager.Instance.FireAddIssueEvent("Image file not found: " + sFile);
            }
            // draw nothing
        }
示例#3
0
        /// <summary>
        /// Updates the alignment of all alignable markups
        /// </summary>
        /// <param name="zElement"></param>
        /// <param name="listAllMarkups"></param>
        public static void UpdateAlignment(ProjectLayoutElement zElement, IEnumerable <MarkupBase> listAllMarkups)
        {
            var listAlignedMarkups = listAllMarkups.Where(x => x.Aligns).ToList();

            if (0 == listAlignedMarkups.Count)
            {
                return;
            }

            var fVertAlignOffset = s_dictionaryVerticalAlignmentProcessors[zElement.GetVerticalAlignment()]
                                   .GetVerticalAlignOffset(zElement, listAlignedMarkups);

            // if the vertical alignment is so far negative that it is outside the bounds adjust it to chop off at the bottom
            if (0 > listAlignedMarkups[0].TargetRect.Y + fVertAlignOffset)
            {
                fVertAlignOffset = -listAlignedMarkups[0].TargetRect.Y;
            }

            // process horizontal alignment (and add the offset for the vertical alignment)
            // build a list of the index of the first markup of each line
            var listFirstMarkupIndexOfLine = new List <int>();
            var nCurrentLineNumber         = -1;

            for (var nMarkupIdx = 0; nMarkupIdx < listAlignedMarkups.Count; nMarkupIdx++)
            {
                if (nCurrentLineNumber != listAlignedMarkups[nMarkupIdx].LineNumber)
                {
                    listFirstMarkupIndexOfLine.Add(nMarkupIdx);
                    nCurrentLineNumber = listAlignedMarkups[nMarkupIdx].LineNumber;
                }
            }

            // iterate over the list of indices of the first markup of each line and align the entire line
            for (var nIdx = 0; nIdx < listFirstMarkupIndexOfLine.Count; nIdx++)
            {
                var bLastLine = nIdx + 1 >= listFirstMarkupIndexOfLine.Count;
                UpdateLineAlignment(
                    listFirstMarkupIndexOfLine[nIdx],
                    bLastLine ? listAlignedMarkups.Count - 1 : listFirstMarkupIndexOfLine[nIdx + 1] - 1,
                    bLastLine,
                    zElement,
                    listAlignedMarkups,
                    fVertAlignOffset,
                    listAllMarkups);
            }
        }
示例#4
0
        public void DrawText(Graphics zGraphics, ProjectLayoutElement zElement, string sInput)
        {
            var zFont     = zElement.GetElementFont();
            var colorFont = zElement.GetElementColor();

            if (null == zFont) // default to something!
            {
                // font will show up in red if it's not yet set
                zFont = FontLoader.DefaultFont;
            }
            var zFormat = new StringFormat
            {
                LineAlignment = zElement.GetVerticalAlignment(),
                Alignment     = zElement.GetHorizontalAlignment()
            };

            var zBrush = 255 == zElement.opacity
                ? new SolidBrush(colorFont)
                : new SolidBrush(Color.FromArgb(zElement.opacity, colorFont));

            if (zElement.autoscalefont)
            {
                SizeF zSize = zGraphics.MeasureString(sInput, zFont, new SizeF(zElement.width, int.MaxValue), zFormat);

                if (zSize.Height > zElement.height || zSize.Width > zElement.width)
                {
                    float newSizeRatio;
                    if ((zSize.Height - zElement.height) > (zSize.Width - zElement.width))
                    {
                        newSizeRatio = (float)zElement.height / (float)zSize.Height;
                    }
                    else
                    {
                        newSizeRatio = (float)zElement.width / (float)zSize.Width;
                    }

                    var scaledFont = FontLoader.GetFont(zFont.FontFamily, newSizeRatio * zFont.Size, zFont.Style);
                    //Support.IO.Logger.AddLogLine(scaledFont.Size + " was [" + zFont.Size + "]");
                    zFont = scaledFont;

#if true            // the preprocessing above will get the font size close but not perfect, the slow code below further refines the size
                    // slow mode - but perfect precision (well arguably with the Graphics.MeasureString)
                    bool bUpscaled = false;
                    if (0 < sInput.Trim().Length)
                    {
                        while (true)
                        {
                            zSize = zGraphics.MeasureString(sInput, zFont, new SizeF(zElement.width, int.MaxValue), zFormat);
                            if (zSize.Height > zElement.height || zSize.Width > zElement.width)
                            {
                                if (zFont.Size == 1)
                                {
                                    break;
                                }
                                zFont = FontLoader.GetFont(zFont.FontFamily, zFont.Size - 1, zFont.Style);
                                if (bUpscaled)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                zFont     = FontLoader.GetFont(zFont.FontFamily, zFont.Size + 1, zFont.Style);
                                bUpscaled = true;
                            }
                        }
                        //Support.IO.Logger.AddLogLine("[" + zFont.Size + "]");
                    }
#endif
                }
                // else -- font size is fine for this element
            }
            else
            {
                zFormat.Trimming = StringTrimming.EllipsisCharacter;
            }

            var fEmSize = zFont.Size;

            switch (zFont.Unit)
            {
            case GraphicsUnit.Point:
                fEmSize = zGraphics.DpiY * (zFont.Size / 72f);
                break;

            default:
                Logger.AddLogLine("This font is using the Unit: {0} (not currently supported)".FormatString(zFont.Unit.ToString()));
                break;
            }

            if (0 == zElement.outlinethickness)
            {
                try
                {
                    zGraphics.DrawString(sInput, zFont, zBrush,
                                         new RectangleF(0, 0, zElement.width, zElement.height), zFormat);
                }
                catch (Exception)
                {
                    Logger.AddLogLine("Unable to render text (font issue?)");
                }
            }
            else
            {
                try
                {
                    var zPath = new GraphicsPath();
                    zPath.AddString(sInput, zFont.FontFamily, (int)zFont.Style, fEmSize, new RectangleF(0, 0, zElement.width, zElement.height), zFormat);
                    CardRenderer.DrawElementPath(zElement, zGraphics, zPath, zBrush);
                }
                catch (Exception)
                {
                    Logger.AddLogLine("Unable to render text (font issue?)");
                }
            }
        }
        public void DrawGraphicFile(Graphics zGraphics, string sFile, ProjectLayoutElement zElement, int nXGraphicOffset = 0, int nYGraphicOffset = 0)
        {
            var sPath = sFile;

            if (string.IsNullOrEmpty(sFile) ||
                sPath.Equals("none", StringComparison.CurrentCultureIgnoreCase))
            {
                return;
            }
            if (sPath.StartsWith(APPLICATION_FOLDER_MARKER))
            {
                sPath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location),
                                     sPath.Replace(APPLICATION_FOLDER_MARKER, string.Empty));
            }
            if (!File.Exists(sPath))
            {
                sPath = ProjectManager.Instance.ProjectPath + sFile;
            }
            if (!File.Exists(sPath))
            {
                IssueManager.Instance.FireAddIssueEvent("Image file not found: " + sFile);
                return;
            }

            var zBmp = ImageCache.LoadCustomImageFromCache(sPath, zElement);

            var nWidth  = zElement.width;
            var nHeight = zElement.height;

            // TODO: sub processor methods (at a minimum)

            if (!string.IsNullOrWhiteSpace(zElement.tilesize) &&
                zElement.tilesize.Trim() != "-")
            {
                var zMatch = regexImageTile.Match(zElement.tilesize);
                if (zMatch.Success)
                {
                    var nTileWidth  = Math.Max(-1, ParseUtil.ParseDefault(zMatch.Groups[1].Value, -1));
                    var nTileHeight = Math.Max(-1, ParseUtil.ParseDefault(zMatch.Groups[3].Value, -1));
                    GetAspectRatioHeight(zBmp, nTileWidth, nTileHeight, out nTileWidth, out nTileHeight);
                    // paranoia...
                    nTileWidth  = Math.Max(1, nTileWidth);
                    nTileHeight = Math.Max(1, nTileHeight);

                    zBmp = ImageCache.LoadCustomImageFromCache(sFile, zElement, nTileWidth, nTileHeight);
                }
                using (var zTextureBrush = new TextureBrush(zBmp, WrapMode.Tile))
                {
                    // backup the transform
                    var zOriginalTransform = zGraphics.Transform;
                    // need to translate so the tiling starts with a full image if offset
                    zGraphics.TranslateTransform(nXGraphicOffset, nYGraphicOffset);
                    zGraphics.FillRectangle(zTextureBrush, 0, 0, nWidth, nHeight);
                    zGraphics.Transform = zOriginalTransform;
                }
                return;
            }

            if (zElement.keeporiginalsize)
            {
                DrawGraphicOriginalSize(zGraphics, zBmp, zElement);
                return;
            }

            if (zElement.lockaspect)
            {
                GetSizeFromAspectRatio((float)zBmp.Tag, nWidth, nHeight, out nWidth, out nHeight);
            }

            var nX = 0;
            var nY = 0;

            // standard alignment adjustment
            UpdateAlignmentValue(zElement.GetHorizontalAlignment(), ref nX, zElement.width, nWidth);
            UpdateAlignmentValue(zElement.GetVerticalAlignment(), ref nY, zElement.height, nHeight);
            zGraphics.DrawImage(zBmp, nX + nXGraphicOffset, nY + nYGraphicOffset, nWidth, nHeight);
        }
        public void DrawText(Graphics zGraphics, ProjectLayoutElement zElement, string sInput)
        {
            var zFont     = zElement.GetElementFont();
            var colorFont = zElement.GetElementColor();

            if (null == zFont) // default to something!
            {
                // font will show up in red if it's not yet set
                zFont = FontLoader.DefaultFont;
            }

            var zBrush = 255 == zElement.opacity
                ? new SolidBrush(colorFont)
                : new SolidBrush(Color.FromArgb(zElement.opacity, colorFont));

            TextFormatFlags zFormatFlags =
                TextFormatFlags.WordBreak
                | TextFormatFlags.NoClipping;

            switch (zElement.GetVerticalAlignment())
            {
            case StringAlignment.Center:
                zFormatFlags |= TextFormatFlags.VerticalCenter;
                break;

            case StringAlignment.Far:
                zFormatFlags |= TextFormatFlags.Bottom;
                break;
            }

            switch (zElement.GetHorizontalAlignment())
            {
            case StringAlignment.Center:
                zFormatFlags |= TextFormatFlags.HorizontalCenter;
                break;

            case StringAlignment.Far:
                zFormatFlags |= TextFormatFlags.Right;
                break;
            }

#warning TextRenderer apparently does not support opactiy?!
            Bitmap zOpacityBitmap = null;
            if (255 != zElement.opacity)
            {
                zOpacityBitmap = new Bitmap(zElement.width, zElement.height, PixelFormat.Format32bppArgb);
                zOpacityBitmap.SetResolution(zGraphics.DpiY, zGraphics.DpiY);
            }

            if (zElement.autoscalefont)
            {
                var zSize = TextRenderer.MeasureText(sInput, zFont, new Size(zElement.width, int.MaxValue), zFormatFlags);

                if (zSize.Height > zElement.height || zSize.Width > zElement.width)
                {
                    float newSizeRatio;
                    if ((zSize.Height - zElement.height) > (zSize.Width - zElement.width))
                    {
                        newSizeRatio = (float)zElement.height / (float)zSize.Height;
                    }
                    else
                    {
                        newSizeRatio = (float)zElement.width / (float)zSize.Width;
                    }

                    //var scaledFont = new Font(zFont.FontFamily, newSizeRatio * zFont.Size, zFont.Style);
                    var scaledFont = new Font(zFont.FontFamily, newSizeRatio * zFont.Size, zFont.Style);
                    //Logger.AddLogLine(scaledFont.Size + " was [" + zFont.Size + "]");
                    zFont = scaledFont;

#if true            // the preprocessing above will get the font size close but not perfect, the slow code below further refines the size
                    // slow mode - but perfect precision (well arguably with the Graphics.MeasureString)
                    bool        bUpscaled         = false;
                    const float FONT_SCALE_ADJUST = 0.25f;
                    if (0 < sInput.Trim().Length)
                    {
                        while (true)
                        {
                            zSize = TextRenderer.MeasureText(sInput, zFont, new Size(zElement.width, int.MaxValue), zFormatFlags);
                            if (zSize.Height > zElement.height || zSize.Width > zElement.width)
                            {
                                if (zFont.Size <= 1)
                                {
                                    break;
                                }
                                zFont = new Font(zFont.FontFamily, zFont.Size - FONT_SCALE_ADJUST, zFont.Style);
                                //Logger.AddLogLine("ADJ A [" + zFont.Size + "]");
                                if (bUpscaled)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                zFont = new Font(zFont.FontFamily, zFont.Size + FONT_SCALE_ADJUST, zFont.Style);
                                //Logger.AddLogLine("ADJ B [" + zFont.Size + "]");
                                bUpscaled = true;
                            }
                        }
                    }
#endif
                }
                // else -- font size is fine for this element
            }
            else
            {
                zFormatFlags |= TextFormatFlags.EndEllipsis;
            }

            Logger.AddLogLine("[" + zFont.Size + "]");

            var arrayDrawLines = new string[] { sInput };
            var nLineOffset    = 0;

            var fEmSize = zFont.Size;

            switch (zFont.Unit)
            {
            case GraphicsUnit.Point:
                fEmSize = zGraphics.DpiY * (zFont.Size / 72f);
                break;

            default:
                Logger.AddLogLine("This font is using the Unit: {0} (not currently supported)".FormatString(zFont.Unit.ToString()));
                break;
            }

            foreach (var sLine in arrayDrawLines)
            {
                if (0 == zElement.outlinethickness)
                {
                    try
                    {
                        // https://stackoverflow.com/questions/849531/textrenderer-drawtext-in-bitmap-vs-onpaintbackground/1578056#1578056
                        if (null != zOpacityBitmap)
                        {
                            zFont = new Font("SkyScrappers Regular", zFont.Size);

                            // TODO: https://stackoverflow.com/questions/18838037/drawing-text-to-a-bitmap-with-textrenderer

#warning too bad this makes the font look terrible
#if false
                            var image = new Bitmap(zElement.width, zElement.height, PixelFormat.Format32bppArgb);

                            // create memory buffer from desktop handle that supports alpha channel
                            IntPtr dib;
                            var    memoryHdc = CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib);
                            try
                            {
                                // create memory buffer graphics to use for HTML rendering
                                using (var memoryGraphics = Graphics.FromHdc(memoryHdc))
                                {
                                    // must not be transparent background
                                    memoryGraphics.Clear(Color.White);

                                    TextRenderer.DrawText(memoryGraphics, sLine, zFont, new Rectangle(0, 0, zElement.width, zElement.height), colorFont, zFormatFlags);
                                }

                                // copy from memory buffer to image
                                using (var imageGraphics = Graphics.FromImage(image))
                                {
                                    var imgHdc = imageGraphics.GetHdc();
                                    BitBlt(imgHdc, 0, 0, image.Width, image.Height, memoryHdc, 0, 0, 0x00CC0020);
                                    imageGraphics.ReleaseHdc(imgHdc);
                                }
                            }
                            finally
                            {
                                // release memory buffer
                                DeleteObject(dib);
                                DeleteDC(memoryHdc);
                            }
                            zGraphics.DrawImageUnscaled(image, 0, 0);
#else
#if false
                            using (Bitmap buffer = new Bitmap(zElement.width, zElement.height, System.Drawing.Imaging.PixelFormat.Format32bppArgb))
                            {
                                using (Graphics graphics = Graphics.FromImage(buffer))
                                {
                                    graphics.FillRectangle(Brushes.Transparent, 0, 0, zElement.width, zElement.height);
                                    // Produces the result below
                                    //graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
                                    // Produces clean text, but I'd really like ClearType!
                                    graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                                    TextRenderer.DrawText(graphics, sLine, zFont, new Rectangle(0, 0, zElement.width, zElement.height), colorFont, zFormatFlags);
                                }
                                zGraphics.DrawImageUnscaled(buffer, 0, 0);
                            }
#else
                            var zGraphicsTemp = Graphics.FromImage(zOpacityBitmap);
                            zGraphicsTemp.SmoothingMode     = SmoothingMode.AntiAlias;
                            zGraphicsTemp.TextRenderingHint = TextRenderingHint.AntiAlias;

                            TextRenderer.DrawText(zGraphicsTemp, sLine, zFont, new Rectangle(0, 0, zElement.width, zElement.height), colorFont, zFormatFlags);

                            var zColor = new ColorMatrix
                            {
                                Matrix33 = (float)zElement.opacity / 255.0f
                            };
                            var zAttrib = new ImageAttributes();
                            zAttrib.SetColorMatrix(zColor);
                            var zBitmap    = new Bitmap(zOpacityBitmap.Width, zOpacityBitmap.Height); // target image
                            var zGraphicsX = Graphics.FromImage(zBitmap);
                            // draw the source image into the destination with the desired opacity
                            zGraphicsX.DrawImage(zOpacityBitmap, new Rectangle(0, 0, zBitmap.Width, zBitmap.Height), 0, 0, zBitmap.Width, zBitmap.Height, GraphicsUnit.Pixel,
                                                 zAttrib);

                            /**
                             *
                             *             var zImageAttributes = new ImageAttributes();
                             * if (255 != zElement.opacity)
                             * {
                             * var zColor = new ColorMatrix
                             * {
                             * Matrix33 = (float)zElement.opacity / 255.0f
                             * };
                             * zImageAttributes.SetColorMatrix(zColor);
                             * }
                             *
                             * zDestinationBitmap = new Bitmap(nTargetWidth, nTargetHeight); // target image
                             * var zGraphics = Graphics.FromImage(zDestinationBitmap);
                             * // draw the source image into the destination with the desired opacity
                             * zGraphics.DrawImage(zSourceBitmap, new Rectangle(0, 0, nTargetWidth, nTargetHeight), 0, 0, zSourceBitmap.Width, zSourceBitmap.Height, GraphicsUnit.Pixel,
                             * zImageAttributes);
                             * */


                            zGraphics.DrawImageUnscaled(zBitmap, 0, 0);
#endif
#endif
                        }
                        else
                        {
                            TextRenderer.DrawText(zGraphics, sLine, zFont, new Rectangle((int)zGraphics.Transform.OffsetX, (int)zGraphics.Transform.OffsetY, zElement.width,
                                                                                         zElement.height), colorFont, zFormatFlags);
                        }
                    }
                    catch (Exception)
                    {
                        Logger.AddLogLine("Unable to render text (font issue?)");
                    }
                }
                else
                {
                    // prepare to draw text
                    var zPath = new GraphicsPath();

                    try
                    {
#warning is there a path based text renderer thing to use?
                        var zFormat = new StringFormat
                        {
                            LineAlignment = zElement.GetVerticalAlignment(),
                            Alignment     = zElement.GetHorizontalAlignment(),
                            Trimming      = StringTrimming.None,
                            FormatFlags   = StringFormatFlags.NoClip
                        };

                        zPath.AddString(sLine, zFont.FontFamily, (int)zFont.Style, fEmSize, new RectangleF(0, nLineOffset, zElement.width, zElement.height), zFormat);
                        CardRenderer.DrawPathOutline(zElement, zGraphics, zPath);
                    }
                    catch (Exception)
                    {
                        Logger.AddLogLine("Unable to render text (font issue?)");
                    }

                    // fill in the outline
                    zGraphics.FillPath(zBrush, zPath);
                }
                nLineOffset += zElement.lineheight;
            }
        }