簡體   English   中英

使用GemBox.Document在所有方向繪制ShapeType.Line對象

[英]Draw ShapeType.Line objects in all directions with GemBox.Document

高級業務需求:

1.)抓取用戶輸入,以創建用於構造線條,矩形, textfields對象數據。

2.)使用用戶通過GemBox.Document創建的doc模板的input (當前在此處停留GemBox.Document )3.)將工作對象合並數據攝取到doc template以填充字段,另存為圖像。

我相信我應該能夠找出矩形和文本的#2,因為對象的構造方式類似於Shape對GemBox.Document工作GemBox.Document 但是,Line的對象不同,提供的是point1和length / width,而不是point1point2

我正在對3種類型的線進行分類...

1.)扁平2.)正螺距3.)負螺距

...我已經能夠算出平坦的(沒有水平或垂直的變化量)和正的螺距(從左上角到右下角的線,或者從鏡子的右下角到左上角的線),但是卻無法找出負的螺距(從右上角到左下角的直線或它的鏡像左下角到右上角)

Shape對象將不允許負長度或具有負值的屬性,使其以我想要的方式繪制。 我看不到/想不知道是否有一種方法可以通過旋轉/翻轉等方式改變線對象。

我對各種方法GemBox.Document開放態度,但有人告訴我必須使用GemBox.Document

namespace GemBoxDocument_LineDemo
{
    using System;
    using MyModels;
    using GemBox.Document;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using GemBox.Document.Drawing;
    using System.IO;
    using System.Reflection;

    public class Program
    {
        //inputs come from a GUI window, we're working with stub/coupon/partial-page/rectangle where w > h
        private const float GUIWIDTH = 425;
        private const float GUIHEIGHT = 200;

        public static void Main(string[] args)
        {
            ComponentInfo.SetLicense("FREE-LIMITED-KEY");

            var gemDoc = new DocumentModel();

            var firstSection = new Section(gemDoc);
            gemDoc.Sections.Add(firstSection);

            var firstParagraph = new Paragraph(gemDoc);
            firstSection.Blocks.Add(firstParagraph);

            var workableWidth = firstSection.PageSetup.PageWidth - (firstSection.PageSetup.PageMargins.Left + firstSection.PageSetup.PageMargins.Right);
            //i think this needs to be -something, or * % of total page since we're partial page
            var workableHeight = firstSection.PageSetup.PageHeight - (firstSection.PageSetup.PageMargins.Top + firstSection.PageSetup.PageMargins.Bottom);

            var widthMultiplier = workableWidth / GUIWIDTH;
            //for now this has been working just fine...
            var heightMultiplier = widthMultiplier;

            //offset of 0 is whole available workable width from GUI, simulating the offset at 50 for instance will show dynamic input shrinks towards center as this increases
            //don't change it too high as it'd create dynamic negative input which isn't possible fron an input perspective. (negative width and/or height)
            var offset = 0;

            var flatOnHorizontalTOPLine = new TemplateItem()
            {
                X = 0 + offset,
                Y = 0 + offset,
                X2 = GUIWIDTH - offset,
                Y2 = 0 + offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
                TemplateItemType = TemplateItemType.Line
            };

            var flatOnHorizontalBOTTOMLine = new TemplateItem()
            {
                X = 0 + offset,
                Y = GUIHEIGHT - offset,
                X2 = GUIWIDTH - offset,
                Y2 = GUIHEIGHT - offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
                TemplateItemType = TemplateItemType.Line
            };

            var flatOnVerticalLEFTLine = new TemplateItem()
            {
                X = 0 + offset,
                Y = 0 + offset,
                X2 = 0 + offset,
                Y2 = GUIHEIGHT - offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
                TemplateItemType = TemplateItemType.Line
            };

            var flatOnVerticalRIGHTLine = new TemplateItem()
            {
                X = GUIWIDTH - offset,
                Y = 0 + offset,
                X2 = GUIWIDTH - offset,
                Y2 = GUIHEIGHT - offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
                TemplateItemType = TemplateItemType.Line
            };

            var positivePitchPoint1LessThanPoint2 = new TemplateItem()
            {
                X = 0 + offset,
                Y = 0 + offset,
                X2 = GUIWIDTH - offset,
                Y2 = GUIHEIGHT - offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Black, 1),
                TemplateItemType = TemplateItemType.Line
            };

            var positivePitchPoint1GreaterThanPoint2 = new TemplateItem()
            {
                X = 0 + offset,
                Y = 0 + offset,
                X2 = GUIWIDTH - offset,
                Y2 = GUIHEIGHT - offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Blue, 1),
                TemplateItemType = TemplateItemType.Line
            };

            //else if (templateItem.X < templateItem.X2 && templateItem.Y > templateItem.Y2)//negative pitch, point 1 below/ToLeft point 2
            var negativePitchPoint1BelowAndToLeftOfPoint2 = new TemplateItem()
            {
                X = 0 + offset,
                Y = GUIHEIGHT - offset,
                X2 = GUIWIDTH - offset,
                Y2 = 0 + offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Red, 1),
                TemplateItemType = TemplateItemType.Line
            };

            //else if (templateItem.X > templateItem.X2 && templateItem.Y < templateItem.Y2)//negative pitch, point 1 above/ToRight point 2
            var negativePitchPoint1AboveAndToRightOfPoint2 = new TemplateItem()
            {
                X = GUIWIDTH - offset,
                Y = 0 + offset,
                X2 = 0 + offset,
                Y2 = GUIHEIGHT - offset,
                Pen = new System.Drawing.Pen(System.Drawing.Color.Green, 1),
                TemplateItemType = TemplateItemType.Line
            };

            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnHorizontalTOPLine, heightMultiplier, widthMultiplier));
            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnHorizontalBOTTOMLine, heightMultiplier, widthMultiplier));
            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnVerticalLEFTLine, heightMultiplier, widthMultiplier));
            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, flatOnVerticalRIGHTLine, heightMultiplier, widthMultiplier));
            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, positivePitchPoint1LessThanPoint2, heightMultiplier, widthMultiplier));
            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, positivePitchPoint1GreaterThanPoint2, heightMultiplier, widthMultiplier));

            //cannot figure out these two 'negative pitch' instances...
            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, negativePitchPoint1BelowAndToLeftOfPoint2, heightMultiplier, widthMultiplier));
            firstParagraph.Inlines.Add(GetGemboxLineShape(gemDoc, firstSection, negativePitchPoint1AboveAndToRightOfPoint2, heightMultiplier, widthMultiplier));

            gemDoc.Save(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), $"{Assembly.GetExecutingAssembly().GetName().Name}-{DateTime.Now.ToString("yyyy-MM-dd hhmmss")}.docx"));

            Console.WriteLine("DONE");
            Console.ReadKey();
        }

        public static Shape GetGemboxLineShape(DocumentModel document, Section section, TemplateItem templateItem, double heightMultiplier, double widthMultiplier)
        {
            var verticalTranslation = Math.Abs(templateItem.Y2 - templateItem.Y) * heightMultiplier;
            var horizontalTranslation = Math.Abs(templateItem.X2 - templateItem.X) * widthMultiplier;
            var horizontalAbsolutePosition = 0.0;
            var verticalAbsolutePosition = 0.0;

            if ((templateItem.X < templateItem.X2 && templateItem.Y < templateItem.Y2) ||//positive pitch, point1 < point2
                (templateItem.X == templateItem.X2) || (templateItem.Y == templateItem.Y2))//flat on the horizontal or vertical
            {
                horizontalAbsolutePosition = templateItem.X * widthMultiplier;
                verticalAbsolutePosition = templateItem.Y * heightMultiplier;

                var gemboxLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
                                                                                                          new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
                                                                                                          new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));

                gemboxLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
                gemboxLineShape.Outline.Width = templateItem.Pen.Width;

                return gemboxLineShape;
            }
            else if (templateItem.X > templateItem.X2 && templateItem.Y > templateItem.Y2)//positive pitch, point1 > point2
            {
                //quickly found out i cannot give a negative width or height to GemBox.Document.Size
                //to account for the mirror of the above condition, AKA drawing the same object but in mirror
                //we just flip-flop the starting point / absolute position and create the shape the same way
                horizontalAbsolutePosition = templateItem.X2 * widthMultiplier;
                verticalAbsolutePosition = templateItem.Y2 * heightMultiplier;

                var gemboxLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
                                                                                                          new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
                                                                                                          new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));

                gemboxLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
                gemboxLineShape.Outline.Width = templateItem.Pen.Width;

                return gemboxLineShape;
            }
            else if (templateItem.X < templateItem.X2 && templateItem.Y > templateItem.Y2)//negative pitch, point 1 below/ToLeft point 2
            {
                horizontalAbsolutePosition = templateItem.X * widthMultiplier;
                verticalAbsolutePosition = templateItem.Y * heightMultiplier;

                //cannot set negative height for size for it to draw up
                var badLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
                                                                                                       new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
                                                                                                       new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));

                badLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
                badLineShape.Outline.Width = templateItem.Pen.Width;

                return badLineShape;
            }
            else if (templateItem.X > templateItem.X2 && templateItem.Y < templateItem.Y2)//negative pitch, point 1 above/ToRight point 2
            {
                horizontalAbsolutePosition = templateItem.X * widthMultiplier;
                verticalAbsolutePosition = templateItem.Y * heightMultiplier;

                //cannot set negative width for size for it to draw left
                var badLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(new HorizontalPosition(section.PageSetup.PageMargins.Left + horizontalAbsolutePosition, LengthUnit.Point, HorizontalPositionAnchor.LeftMargin),
                                                                                                       new VerticalPosition(section.PageSetup.PageMargins.Top + verticalAbsolutePosition, LengthUnit.Point, VerticalPositionAnchor.TopMargin),
                                                                                                       new GemBox.Document.Size(horizontalTranslation, verticalTranslation, LengthUnit.Point)));

                badLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
                badLineShape.Outline.Width = templateItem.Pen.Width;

                return badLineShape;
            }
            else
                return null;
        }
    }
}

namespace MyModels
{
    using System.Drawing;

    public enum TemplateItemType { Default, Box, Line, Text, Field }
    public class TemplateItem
    {
        public TemplateItemType TemplateItemType { get; set; }
        public Font Font { get; set; }
        public Pen Pen { get; set; }
        public float X { get; set; }
        public float Y { get; set; }
        public float X2 { get; set; }
        public float Y2 { get; set; }
        public float Width { get; set; }
        public float Height { get; set; }
        public string Text { get; set; }

        public override string ToString()
        {
            switch (this.TemplateItemType)
            {
                case TemplateItemType.Box:
                    return $"<{this.TemplateItemType.ToString("G")}Item> X<{this.X}> Y<{this.Y}> W<{this.Width}> H<{this.Height}>";
                case TemplateItemType.Line:
                    return $"<{this.TemplateItemType.ToString("G")}Item> X1<{this.X}> Y1<{this.Y}> X2<{this.X2}> Y2<{this.Y2}>";
                case TemplateItemType.Text:
                case TemplateItemType.Field:
                    return $"<{this.TemplateItemType.ToString("G")}Item> X<{this.X}> Y<{this.Y}> W<{this.Width}> H<{this.Height}> T<{this.Text}>";
            }

            return string.Empty;
        }
    }
}

從此處下載當前最新的錯誤修復版本然后嘗試使用以下版本:

badLineShape.Layout.Transform.FlipVertical = true;

關於FlipVerticalFlipHorizontal轉換,在這種情況下(線形),它們應該相同。

例如,考慮以下圖像:

畫線

使用某些photoshop應用程序(我使用過Gimp)在其上應用垂直翻轉變換會導致:

垂直翻轉線描

使用某些photoshop應用程序(我使用過Gimp)在其上應用水平翻轉變換會導致:

水平翻轉線描

您可能會注意到,生成的圖像是相同的。

關於RightMargin,我將嘗試進一步調查。

正如Mario Z提到的那樣,新的大修正版本v1099確實允許對線條進行轉換以創建我歸類為負間距線的東西...現在可以在所有方向上繪制線。

似乎有些錯誤,因為FlipVertical和FlipHorizo​​ntal似乎在不應該進行相同的准確轉換。 我還發現了一個通過RightMargin設置浮點的小錯誤,它的功能似乎與頂部/左側的功能不同(我還沒有嘗試過使用底部)。

public static Shape GetGemboxLineShape(DocumentModel document, Section section, TemplateItem templateItem, double heightMultiplier, double widthMultiplier)
{
    var size = new GemBox.Document.Size(Math.Abs(templateItem.X2 - templateItem.X) * widthMultiplier, Math.Abs(templateItem.Y2 - templateItem.Y) * heightMultiplier, LengthUnit.Point);
    var horizontal = new HorizontalPosition();
    var vertical = new VerticalPosition();
    var requiresNegativeTransform = false;

    if ((templateItem.X < templateItem.X2 && templateItem.Y < templateItem.Y2) ||//positive pitch, point1 < point2
        (templateItem.X == templateItem.X2) || (templateItem.Y == templateItem.Y2))//flat on the horizontal or vertical
    {
        horizontal = new HorizontalPosition(section.PageSetup.PageMargins.Left + (templateItem.X * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.LeftMargin);
        vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
    }
    else if (templateItem.X > templateItem.X2 && templateItem.Y > templateItem.Y2)//positive pitch, point1 > point2
    {
        //quickly found out i cannot give a negative width or height to GemBox.Document.Size
        //to account for the mirror of the above condition, AKA drawing the same object but in mirror
        //we just flip-flop the starting point / absolute position and create the shape the same way
        horizontal = new HorizontalPosition(section.PageSetup.PageMargins.Left + (templateItem.X2 * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.LeftMargin);
        vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y2 * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
    }
    else if (templateItem.X < templateItem.X2 && templateItem.Y > templateItem.Y2)//negative pitch, point 1 below/ToLeft point 2
    {
        //so for ease we're going to pick point2 at the top right and we can use Top/Right margin as our origin instead of Top/Left
        //however, this appears a bit buggy, i would assume i'd need to do -section.PageSetup.PageMargins.Right minus relative (opposite of TopLeft on the X/horizontal)
        //but it appears this wasn't accounted for on the right margin? or i'm not entirely understanding the floating/anchor functionality
        horizontal = new HorizontalPosition(-(templateItem.X2 * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.RightMargin);
        vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y2 * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
        requiresNegativeTransform = true;
    }
    else if (templateItem.X > templateItem.X2 && templateItem.Y < templateItem.Y2)//negative pitch, point 1 above/ToRight point 2
    {
        //opposite of previous in that we're going to pick point1 but everything else will be the same
        horizontal = new HorizontalPosition(-(templateItem.X * widthMultiplier), LengthUnit.Point, HorizontalPositionAnchor.RightMargin);
        vertical = new VerticalPosition(section.PageSetup.PageMargins.Top + (templateItem.Y * heightMultiplier), LengthUnit.Point, VerticalPositionAnchor.TopMargin);
        requiresNegativeTransform = true;
    }
    else
    {
        throw new ArgumentException();
    }

    var gemboxLineShape = new Shape(document, ShapeType.Line, GemBox.Document.Layout.Floating(horizontal, vertical, size));

    gemboxLineShape.Outline.Fill.SetSolid(new GemBox.Document.Color(templateItem.Pen.Color.R, templateItem.Pen.Color.G, templateItem.Pen.Color.B));
    gemboxLineShape.Outline.Width = templateItem.Pen.Width;

    //this appears to solve my problem.... however, similar to right margin appears to be
    //a bit buggy... at least in the sense that FlipVertical and FlipHorizontal should do different transformations but it doesn't
    gemboxLineShape.Layout.Transform.FlipVertical = requiresNegativeTransform;

    return gemboxLineShape;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM