/********************************************************************************************* * Copyright 2010 - Volian Enterprises, Inc. All rights reserved. * Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE *********************************************************************************************/ using System; using System.Xml; using System.Drawing; using System.Text; namespace VG { /// /// VG is the class representing vector graphics. It provides objects for: /// Line, Rectangle, Text, Ellipse, Bitmaps, etc. /// VG provides constructors for these objects from coordinate system locations /// (such as starting x,y ending x,y, etc), xml and svg. /// VG data is stored in TWIPS (1440 per inch) /// // Temporary page class to store portrait/landscape, Left Margin, Vertical offset, etc public class Page { private bool _Portrait = true; public bool Portrait { get { return _Portrait; } set { _Portrait = value; } } private float _LeftMargin = 0; public float LeftMargin { get { return _LeftMargin; } set { _LeftMargin = value; } } private float _TopMargin = 0; public float TopMargin { get { return _TopMargin; } set { _TopMargin = value; } } private float _RightMargin = 0; public float RightMargin { get { return _RightMargin; } set { _RightMargin = value; } } private float _BottomMargin = 0; public float BottomMargin { get { return _BottomMargin; } set { _BottomMargin = value; } } public Page(bool portrait, float leftMargin, float topMargin, float rightMargin, float bottomMargin) { _Portrait = portrait; _LeftMargin = leftMargin; _TopMargin = topMargin; _RightMargin = rightMargin; _BottomMargin = bottomMargin; } public Page(bool portrait, float leftMargin, float topMargin) { _Portrait = portrait; _LeftMargin = leftMargin; _TopMargin = topMargin; } } public class VG { private static Brush _BlackBrush = Brushes.Black; public static Brush BlackBrush { get { return _BlackBrush; } set { _BlackBrush = value; } } private static Color _BlackColor = Color.Black; public static Color BlackColor { get { return _BlackColor; } set { _BlackColor = value; _BlackBrush = new SolidBrush(value); } } // Values of vector graphics items are stored as twips (1440 twips in an inch) public int cx; public int cy; public int dx; public int dy; public float lnwid; public Page pg; public bool MoveAbsolute; // TODO: Not sure what to do with this. public VG() { cx = 0; cy = 0; dx = 0; dy = 0; MoveAbsolute = false; pg = null; } public VG(int sx, int sy, int ex, int ey, bool ima, Page ipg) { cx = sx; cy = sy; dx = ex; dy = ey; MoveAbsolute = ima; pg = ipg; } public float ToPoints(float twip) { float r = ((float)twip) * 0.05f; return r; } public void UpdatePageInfo(Page pa) { pg.LeftMargin = pa.LeftMargin; pg.Portrait = pa.Portrait; // RHM 20081003 - This had been pg.portrait=pg.portrait pg.TopMargin = pa.TopMargin; // RHM 20081003 - This had been pg.VertOffset=pg.VertOffset } public string AddRTFBUI(string origStr, string bold, string underline, string italics) { if (bold == "" && underline == "" && italics == "") return origStr; StringBuilder sb = new StringBuilder(); if (bold == "bold") sb.Append("{\\b"); if (underline == "underline") sb.Append("{\\u"); if (italics == "italics") sb.Append("{\\i"); sb.Append(" "); sb.Append(origStr); if (bold == "bold") sb.Append("}"); if (underline == "underline") sb.Append("}"); if (italics == "italics") sb.Append("}"); return sb.ToString(); } public static Pen CreatePen(Color color, float wid, float scale) { Pen pn; float scaleWid = wid * scale; float colorFraction = (float)Math.Sqrt(scaleWid); if (scaleWid < .5F) { //Console.WriteLine("Width = {0}", wid); int R1 = (int)(colorFraction * color.R); int R2 = (int)((1 - colorFraction) * Color.White.R); int G1 = (int)(colorFraction * color.G); int G2 = (int)((1 - colorFraction) * Color.White.G); int B1 = (int)(colorFraction * color.B); int B2 = (int)((1 - colorFraction) * Color.White.B); pn = new Pen(Color.FromArgb(R1 + R2, G1 + G2, B1 + B2), scaleWid); //pn = new Pen(color, wid*wid); } else pn = new Pen(color, scaleWid); return pn; } } public class VG_Line : VG { // Line is defined as starting & ending points. public VG_Line(int sx, int sy, int ex, int ey, int w, Page ipg) { cx = sx; cy = sy; dx = ex; dy = ey; lnwid = w; pg = ipg; } public VG_Line(XmlElement svg, Page ipg) { cx = System.Convert.ToInt32(svg.GetAttribute("x1")); cy = System.Convert.ToInt32(svg.GetAttribute("y1")); dx = System.Convert.ToInt32(svg.GetAttribute("x2")); dy = System.Convert.ToInt32(svg.GetAttribute("y2")); lnwid = System.Convert.ToInt32(svg.GetAttribute("stroke-width")); pg = ipg; } public void Draw(IVGOutput vgOutput) { float startx = pg.Portrait ? (cx + pg.LeftMargin) : (pg.TopMargin + cy); float starty = pg.Portrait ? (cy + pg.TopMargin) : (pg.LeftMargin - cx); float endx = pg.Portrait ? (dx + pg.LeftMargin) : (pg.TopMargin + dy); float endy = pg.Portrait ? (dy + pg.TopMargin) : (pg.LeftMargin - dx); Pen pn = VG.CreatePen(VG.BlackColor, ToPoints(lnwid), vgOutput.Scale); vgOutput.DrawLine(pn, ToPoints(startx), ToPoints(starty), ToPoints(endx), ToPoints(endy)); } } public class VG_Rect : VG { // Rectangle is defined as starting point & length/width public VG_Rect(int sx, int sy, int ex, int ey, int w, Page ipg) { cx = sx; cy = sy; dx = ex; dy = ey; lnwid = w; pg = ipg; } public VG_Rect(XmlElement svg, Page ipg) { cx = System.Convert.ToInt32(svg.GetAttribute("x")); cy = System.Convert.ToInt32(svg.GetAttribute("y")); dx = System.Convert.ToInt32(svg.GetAttribute("width")); dy = System.Convert.ToInt32(svg.GetAttribute("height")); lnwid = System.Convert.ToInt32(svg.GetAttribute("stroke-width")); pg = ipg; } public void Draw(IVGOutput vgOutput) { Pen pn = new Pen(VG.BlackBrush, ToPoints(lnwid)); float startx = pg.Portrait ? (cx + pg.LeftMargin) : (pg.TopMargin + cy); float starty = pg.Portrait ? (cy + pg.TopMargin) : (pg.LeftMargin - cx); float endx = pg.Portrait ? dx : dy; float endy = pg.Portrait ? dy : dx; RectangleF rc = new RectangleF(ToPoints(startx), ToPoints(starty), ToPoints(endx), ToPoints(endy)); vgOutput.DrawRectangle(pn, rc); } } public class VG_Image : VG { private int Scale; private string FileName; // Image is defined as starting point, scale factor (defaults to 1) & image file name public VG_Image(int sx, int sy, int iscale, string fname) { cx = sx; cy = sy; Scale = 1; FileName = fname; } public VG_Image(XmlElement svg, Page ipg) { cx = System.Convert.ToInt32(svg.GetAttribute("x")); cy = System.Convert.ToInt32(svg.GetAttribute("y")); Scale = 1; if (svg.HasAttribute("scale")) Scale = System.Convert.ToInt32(svg.GetAttribute("scale")); FileName = svg.GetAttribute("bname"); pg = ipg; } public void Draw(IVGOutput vgOutput) { Pen pn = new Pen(VG.BlackBrush, lnwid); Bitmap bm = new Bitmap(FileName); RectangleF rc = new RectangleF(); rc.Height = ToPoints((bm.Height * Scale) * 4.8f); rc.Width = ToPoints((bm.Width * Scale) * 4.8f); rc.X = ToPoints(pg.LeftMargin + cx); rc.Y = ToPoints(pg.TopMargin + cy); // TODO: grfx.DrawImage(bm, rc, ContentAlignment.MiddleCenter, ImageSizeModeEnum.Scale); } } public class VG_Ellipse : VG { // Ellipse (circle) is defined by a bounding rectangle specified by a coordinate pair, a width, and a height public VG_Ellipse(int sx, int sy, int ex, int ey, int w, Page ipg) { cx = sx; cy = sy; dx = ex; dy = ey; lnwid = w; pg = ipg; } public VG_Ellipse(XmlElement svg, Page ipg) { cx = System.Convert.ToInt32(svg.GetAttribute("cx")); cy = System.Convert.ToInt32(svg.GetAttribute("cy")); dx = System.Convert.ToInt32(svg.GetAttribute("rx")); dy = System.Convert.ToInt32(svg.GetAttribute("ry")); lnwid = System.Convert.ToInt32(svg.GetAttribute("stroke-width")); pg = ipg; } public void Draw(IVGOutput vgOutput) { Pen pn = new Pen(VG.BlackBrush, ToPoints(lnwid)); vgOutput.DrawEllipse(pn, ToPoints(pg.LeftMargin + cx), ToPoints(pg.TopMargin + cy), ToPoints(dx), ToPoints(dy)); } } public class VG_Text : VG { private string FontName; private int FontSize; private string Bold; private string Underline; private string Italics; private string Text; // Text is defined by a starting location, attributes & the string public VG_Text(int sx, int sy, int fs, string txt, string fn, string ibold, string iunder, string iitalics, Page ipg) { cx = sx; cy = sy; FontSize = fs; FontName = fn; Text = txt; Bold = ibold; Underline = iunder; Italics = iitalics; pg = ipg; // TODO: The following were in the 16-bit code - we may need to use these, wait and see // strokeWidth = stroke; // strokeWidthBold = strokebold; // ULOffset = UnderlineOffset; // ULWidth = UnderlineWidth; } public VG_Text(XmlElement svg, Page ipg) { cx = System.Convert.ToInt32(svg.GetAttribute("x")); cy = System.Convert.ToInt32(svg.GetAttribute("y")); FontSize = System.Convert.ToInt32(svg.GetAttribute("font-size")); Bold = svg.GetAttribute("font-weight"); Underline = svg.GetAttribute("text-decoration"); Italics = svg.GetAttribute("font-style"); FontName = svg.GetAttribute("font-family"); Text = svg.InnerText; pg = ipg; } public void Draw(IVGOutput vgOutput) { // TODO: Font myfont = new Font(FontName, (FontSize*9)/10); Font myfont = new Font(FontName, FontSize * vgOutput.FontSizeAdjust); // TODO: Trying 80% RectangleF rc = new RectangleF(); // the returned value from c1 grfx code is already in points, // so need to convert the size. rc.Size = vgOutput.MeasureString(Text, myfont); // TODO: 500 or pagewidth, or what //rc.Size = grfx.MeasureString(Text, myfont, 500); // TODO: 500 or pagewidth, or what rc.X = ToPoints(pg.LeftMargin + cx); rc.Y = ToPoints(pg.TopMargin + cy) - FontSize; rc.Height *= 1.0000001F; // Small factor to make text visible. // add bold, underline & italics for entire object. // TODO: string rtfout = AddRTFBUI(Text, Bold, Underline, Italics); //using(Pen pn = new Pen(Color.DarkBlue, .1F)) // grfx.DrawRectangle(pn, rc.X,rc.Y,rc.Width,rc.Height); vgOutput.DrawString(Text, myfont, VG.BlackBrush, rc); //grfx.DrawString(Text, myfont, VG.BlackBrush, rc); } } public class VG_Arc : VG { public Single sweepAngle; public Single startAngle; public float stX, stY; public float rWid, rHgt; // Arc is defined by a bounding rectangle specified by a coordinate pair, a width, and a height public VG_Arc(float sx, float sy, float width, float hight, float stAngle, float swpAngle, int w, Page ipg) { if (width > 0) { stX = sx; rWid = width; } else { stX = sx + width; rWid = -width; } if (hight > 0) { stY = sy; rHgt = hight; } else { stY = sy + hight; rHgt = -hight; } startAngle = stAngle; // startAngle = 90; sweepAngle = swpAngle; // sweepAngle = -45; lnwid = w; pg = ipg; } //#if DEBUG //public static int iColor = 0; //public Color[] myColors = { Color.Red, Color.Green, Color.OrangeRed, Color.Cyan, Color.Orange, Color.Blue, Color.Yellow, Color.Indigo, Color.YellowGreen, Color.Violet }; ////public Color[] myColors ={ Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Blue, Color.BlueViolet, Color.Violet }; //#endif public void Draw(IVGOutput vgOutput) { //#if DEBUG // Pen pn = new Pen(myColors[iColor % myColors.Length], ToPoints(lnwid)); //iColor++; //if (iColor >= myColors.Length) iColor = 0; //#else Pen pn = new Pen(VG.BlackBrush, ToPoints(lnwid)); //#endif float startx = pg.Portrait ? (stX + pg.LeftMargin) : (pg.TopMargin + stY); float starty = pg.Portrait ? (stY + pg.TopMargin) : (pg.LeftMargin - stX); RectangleF rc = new RectangleF(ToPoints(startx), ToPoints(starty), ToPoints(rWid), ToPoints(rHgt)); //Console.WriteLine("{0},'{1}',{2},{3},{4},{5},{6},{7}", iColor, pn.Color, rc.X, rc.Y, rc.Width, rc.Height, startAngle, sweepAngle); //if (iColor == 7 || iColor == 8) return; //if (iColor == 6) return; //if (iColor == 4 || iColor == 6) //{ // using (Pen lightPen = new Pen(myColors[iColor % myColors.Length], .01F)) //{ // vgOutput.DrawEllipse(lightPen, rc.X, rc.Y, rc.Width, rc.Height); // float xc = rc.X + (rc.Width / 2); // float yc = rc.Y + (rc.Height / 2); // vgOutput.DrawEllipse(lightPen, xc - .5F, yc - .5F, 1F, 1F); //} //} if (sweepAngle > 0) vgOutput.DrawArc(pn, rc, startAngle, sweepAngle); else vgOutput.DrawArc(pn, rc, startAngle + sweepAngle, -sweepAngle); } } }