コード例 #1
0
        public static byte[] AppendImageToPdf(byte[] pdf, byte[] img, Point position, double scale)
        {
            using (System.IO.MemoryStream msPdf = new System.IO.MemoryStream(pdf))
            {
                using (System.IO.MemoryStream msImg = new System.IO.MemoryStream(img))
                {
                    System.Drawing.Image       image    = System.Drawing.Image.FromStream(msImg);
                    PdfSharp.Pdf.PdfDocument   document = PdfSharp.Pdf.IO.PdfReader.Open(msPdf);
                    PdfSharp.Pdf.PdfPage       page     = document.Pages[0];
                    PdfSharp.Drawing.XGraphics gfx      = PdfSharp.Drawing.XGraphics.FromPdfPage(page);
                    PdfSharp.Drawing.XImage    ximg     = PdfSharp.Drawing.XImage.FromGdiPlusImage(image);

                    gfx.DrawImage(
                        ximg,
                        position.X,
                        position.Y,
                        ximg.Width * scale,
                        ximg.Height * scale
                        );

                    using (System.IO.MemoryStream msFinal = new System.IO.MemoryStream())
                    {
                        document.Save(msFinal);
                        return(msFinal.ToArray());
                    }
                }
            }
        }
コード例 #2
0
ファイル: PdfImageTable.cs プロジェクト: Core2D/PDFsharp
            /// <summary>
            /// Initializes a new instance of ImageSelector from an XImage.
            /// </summary>
            public ImageSelector(XImage image)
            {
                // HACK: implement a way to identify images when they are reused
                // TODO 4STLA Implementation that calculates MD5 hashes for images generated for the images can be found here: http://forum.pdfsharp.net/viewtopic.php?p=6959#p6959
                if (image._path == null)
                    image._path = "*" + Guid.NewGuid().ToString("B");

                // HACK: just use full path to identify
                _path = image._path.ToLowerInvariant();
            }
コード例 #3
0
ファイル: DoubleBar.cs プロジェクト: Nodgez/PDFReporter
        public void Draw(XPoint basePoint, XRect baseRect, XImage img)
        {
            XFont headerFont = new XFont("Arial", 16);
            XFont subfont = new XFont("Arial", 10);
            char degree = Convert.ToChar('\u00b0');
            gfx.DrawString(parameterLeft.Name.Substring(5, parameterLeft.Name.Length - 5), headerFont, XBrushes.Black, basePoint, XStringFormats.Center);
            gfx.DrawString(parameterLeft.Value.ToString() + degree, subfont, XBrushes.Black, basePoint + new XPoint(-15, baseRect.Height * 0.05),XStringFormats.Center);
            gfx.DrawString(parameterRight.Value.ToString() + degree, subfont, XBrushes.Black, basePoint + new XPoint(20, baseRect.Height * 0.05), XStringFormats.Center);

            XBrush brush = XBrushes.Black;

            brush = DrawingUtil.Instance.ChooseBrushColor(parameterLeft.LSI, 49, 74);

            XRect r = new XRect(basePoint + new XPoint(-baseRect.Width * 0.05, baseRect.Height * 0.075),
                new XSize(baseRect.Width * 0.1, baseRect.Height * 0.075));

            DrawingUtil.DrawOutlineRect(r, gfx, new XSize(10, 10));

            gfx.DrawRoundedRectangle(brush, r, new XSize(10,10));
            gfx.DrawString(parameterLeft.LSI.ToString("0") + "%",
                subfont,
                XBrushes.Black,
                basePoint + new XPoint(baseRect.Width * -0.025, baseRect.Height * 0.125));

            XSolidBrush blue = new XSolidBrush(XColor.FromArgb(127, 0, 0, 255));
            XSolidBrush yellow = new XSolidBrush(XColor.FromArgb(127, 255, 255, 0));

            XPoint top = new XPoint(basePoint.X - 20,Math.Ceiling( basePoint.Y + baseRect.Height * 0.2));
            XPoint bottom = new XPoint(basePoint.X - 20, Math.Ceiling(basePoint.Y + baseRect.Height * 0.8));

            XPoint leftRectPoint = Interpolate(bottom, top, -parameterLeft.Percentage);
            XRect leftBar = new XRect(leftRectPoint, new XSize(20, bottom.Y - leftRectPoint.Y  ));
            gfx.DrawRectangle(blue, leftBar);

            XPoint rigthRectPoint = Interpolate(bottom, top, -parameterRight.Percentage);
            XRect rightBar = new XRect(rigthRectPoint + new XPoint(30,0), new XSize(20, bottom.Y - rigthRectPoint.Y));
            gfx.DrawRectangle(yellow, rightBar);

            XPoint offset = new XPoint(25, 0);
            gfx.DrawLine(XPens.Green, top + offset, bottom + offset);
            gfx.DrawLine(XPens.Yellow, Interpolate(bottom, top, - parameterLeft.AmberVal) + offset, bottom + offset);
            gfx.DrawLine(XPens.Red, Interpolate(bottom, top, -parameterLeft.RedVal) + offset, bottom + offset);

            gfx.DrawString("L", subfont, XBrushes.Black, bottom + new XPoint(5, -2));
            gfx.DrawString("R", subfont, XBrushes.Black, bottom + new XPoint(35, -2));

            double wRatio = (double)img.PixelWidth / (double)img.PixelHeight;

            gfx.DrawImage(img, new XRect(new XPoint(bottom.X, bottom.Y), new XSize(wRatio * 50, 50)));
            img.Dispose();
        }
コード例 #4
0
    void RealizeImageBrush(ImageBrush brush, ref XForm xform, ref XImage xImage)
    {
      //Debug.Assert(xform != null);

      //xform = new XForm(this.writer.Owner, new XRect(brush.Viewbox.X * 3 / 4, brush.Viewbox.Y * 3 / 4, brush.Viewbox.Width * 3 / 4, brush.Viewbox.Height * 3 / 4));

      //string imageUri = brush.ImageSource;


      FixedPage fpage = brush.GetParent<FixedPage>();
      if (fpage == null)
        Debug.Assert(false);

      FixedPayload payload = fpage.Document.Payload;

      // Get the font object.
      // Important: font.PdfFont is not yet defined here on the first call
      string uriString = brush.ImageSource;
      BitmapSource image = payload.GetImage(uriString);

      //      int factor = 1;
      //int width = (int)(100 * factor);
      //int height = (int)(100 * factor);
      //DrawingVisual visual = new DrawingVisual();
      //DrawingContext vdc = visual.RenderOpen();
      //vdc.DrawRectangle(Brushes.GreenYellow, null, new Rect(0, 0, width, height));
      //vdc.DrawLine(new Pen(Brushes.Red, 3), new Point(0, 0), new Point(100, 100));
      //vdc.DrawLine(new Pen(Brushes.Red, 3), new Point(100, 0), new Point(0, 100));
      //vdc.Close();
      //RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 72 * factor, 72 * factor, PixelFormats.Default);
      //rtb.Render(visual);

      //BitmapImage bitmapImage = new BitmapImage(

      xImage = XImage.FromBitmapSource(image);



      //XGraphics gfx = XGraphics.FromForm(xform);
      //gfx.DrawRectangle(XBrushes.Firebrick, new XRect(0, 0, 100, 100));


      //PdfContentWriter formWriter = new PdfContentWriter(xform, RenderMode.Default);

      ////formWriter.Size = brush.Viewport.Size;
      //formWriter.BeginContent(false);

      ////formWriter.WriteElement(visual);
      //formWriter.EndContent();
    }
コード例 #5
0
ファイル: DoubleBar.cs プロジェクト: Nodgez/Redback
        public void Draw(XPoint basePoint, XRect baseRect, XImage image)
        {
            XFont headerFont = new XFont("Arial", 16);
            XFont subfont = new XFont("Arial", 10);
            char degree = Convert.ToChar('\u00b0');
            gfx.DrawString(parameterLeft.Name.Substring(5, parameterLeft.Name.Length - 5), headerFont, XBrushes.Black, basePoint, XStringFormats.Center);
            gfx.DrawString(parameterLeft.Value.ToString() + degree, subfont, XBrushes.Black, basePoint + new XPoint(-25, baseRect.Height * 0.05),XStringFormats.Center);
            gfx.DrawString(parameterRight.Value.ToString() + degree, subfont, XBrushes.Black, basePoint + new XPoint(25, baseRect.Height * 0.05), XStringFormats.Center);

            XBrush brush = XBrushes.Black;

            if (parameterLeft.LSI >= 75)
                brush = XBrushes.Green;
            else
                brush = XBrushes.Gold;

            gfx.DrawRoundedRectangle(brush,
                new XRect(basePoint + new XPoint(-baseRect.Width * 0.05, baseRect.Height * 0.075),
                new XSize(baseRect.Width * 0.1, baseRect.Height * 0.075)),
                new XSize(10,10));
            gfx.DrawString(parameterLeft.LSI.ToString("0") + "%",
                subfont,
                XBrushes.Black,
                basePoint + new XPoint(baseRect.Width * -0.025, baseRect.Height * 0.125));

            XSolidBrush blue = new XSolidBrush(XColor.FromArgb(127, 0, 0, 255));
            XSolidBrush yellow = new XSolidBrush(XColor.FromArgb(127, 255, 255, 0));

            XPoint top = new XPoint(basePoint.X - 20, basePoint.Y + baseRect.Height * 0.2);
            XPoint bottom = new XPoint(basePoint.X - 20, basePoint.Y + baseRect.Height * 0.8);

            XPoint leftRectPoint = Interpolate(bottom, top, -parameterLeft.Percentage);
            XRect leftBar = new XRect(leftRectPoint, new XSize(20, bottom.Y - leftRectPoint.Y  ));
            gfx.DrawRectangle(blue, leftBar);

            XPoint rigthRectPoint = Interpolate(bottom, top, -parameterRight.Percentage);
            XRect rightBar = new XRect(rigthRectPoint + new XPoint(30,0), new XSize(20, bottom.Y - rigthRectPoint.Y));
            gfx.DrawRectangle(yellow, rightBar);

            gfx.DrawString("L", subfont, XBrushes.Black, bottom + new XPoint(5, -2));
            gfx.DrawString("R", subfont, XBrushes.Black, bottom + new XPoint(35, -2));

            gfx.DrawImage(image, new XRect(bottom.X, bottom.Y, 50, 50));
            image.Dispose();
        }
コード例 #6
0
ファイル: PdfImageTable.cs プロジェクト: Core2D/PDFsharp
        /// <summary>
        /// Gets a PdfImage from an XImage. If no PdfImage already exists, a new one is created.
        /// </summary>
        public PdfImage GetImage(XImage image)
        {
            ImageSelector selector = image._selector;
            if (selector == null)
            {
                selector = new ImageSelector(image);
                image._selector = selector;
            }
            PdfImage pdfImage;
            if (!_images.TryGetValue(selector, out pdfImage))
            {
                pdfImage = new PdfImage(Owner, image);
                //pdfImage.Document = _document;
                Debug.Assert(pdfImage.Owner == Owner);
                _images[selector] = pdfImage;
 }
            return pdfImage;
        }
コード例 #7
0
ファイル: PdfImage.cs プロジェクト: Sl0vi/PDFsharp
        /// <summary>
        /// Initializes a new instance of PdfImage from an XImage.
        /// </summary>
        public PdfImage(PdfDocument document, XImage image)
            : base(document)
        {
            Elements.SetName(Keys.Type, "/XObject");
            Elements.SetName(Keys.Subtype, "/Image");

            _image = image;

#if !SILVERLIGHT
            ////// TODO: identify multiple used images. If the image already exists use the same XRef.
            ////_defaultName = PdfImageTable.NextImageName;

            switch (_image.Format.Guid.ToString("B").ToUpper())
            {
                // Pdf supports Jpeg, therefore we can write what we've read:
                case "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}":  //XImageFormat.Jpeg
                    InitializeJpeg();
                    break;

                // All other image formats are converted to PDF bitmaps:
                case "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}":  //XImageFormat.Png
                case "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}":  //XImageFormat.Gif
                case "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}":  //XImageFormat.Tiff
                case "{B96B3CB5-0728-11D3-9D7B-0000F81EF32E}":  //XImageFormat.Icon
                    // TODO: possible optimization for PNG (do not decompress/recompress)???
                    // TODO: try Jpeg for size optimization???
                    InitializeNonJpeg();
                    break;

                case "{84570158-DBF0-4C6B-8368-62D6A3CA76E0}":  //XImageFormat.Pdf:
                    Debug.Assert(false, "XPdfForm not expected here.");
                    break;

                default:
                    Debug.Assert(false, "Unexpected image type.");
                    break;
            }
#else
            InitializeAg();
#endif
        }
コード例 #8
0
 /// <summary>
 /// Gets a PdfImage from an XImage. If no PdfImage already exists, a new one is created.
 /// </summary>
 public PdfImage GetImage(XImage image)
 {
   PdfImageTable.ImageSelector selector = image.selector;
   if (selector == null)
   {
     selector = new ImageSelector(image);
     image.selector = selector;
   }
   PdfImage pdfImage;
   if (!this.images.TryGetValue(selector, out pdfImage))
   {
     pdfImage = new PdfImage(this.owner, image);
     //pdfImage.Document = this.document;
     Debug.Assert(pdfImage.Owner == this.owner);
     this.images[selector] = pdfImage;
     //if (this.document.EarlyWrite)
     //{
     //  //pdfFont.Close(); delete 
     //  //pdfFont.AssignObjID(ref this.document.ObjectID); // BUG just test code!!!!
     //  //pdfFont.WriteObject(null);
     //}
   }
   return pdfImage;
 }
コード例 #9
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
 /// <summary>
 /// Draws the specified image.
 /// </summary>
 public void DrawImage(XImage image, RectangleF rect)
 {
   DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
 }
コード例 #10
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
 /// <summary>
 /// Draws the specified image.
 /// </summary>
 public void DrawImage(XImage image, Rectangle rect)
 {
   DrawImage(image, (double)rect.X, (double)rect.Y, (double)rect.Width, (double)rect.Height);
 }
コード例 #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:System.Object"/> class.
 /// </summary>
 public ImageAdapter(XImage image)
 {
     _image = image;
 }
コード例 #12
0
ファイル: PdfPage.cs プロジェクト: Sl0vi/PDFsharp
 /// <summary>
 /// Gets the resource name of the specified image within this page.
 /// </summary>
 internal string GetImageName(XImage image)
 {
     PdfImage pdfImage = _document.ImageTable.GetImage(image);
     Debug.Assert(pdfImage != null);
     string name = Resources.AddImage(pdfImage);
     return name;
 }
コード例 #13
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
    /// <summary>
    /// Draws the specified image.
    /// </summary>
    public void DrawImage(XImage image, XRect destRect, XRect srcRect, XGraphicsUnit srcUnit)
    {
      if (image == null)
        throw new ArgumentNullException("image");

      CheckXPdfFormConsistence(image);

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          if (image.gdiImage != null)
          {
            InterpolationMode interpolationMode = InterpolationMode.Invalid;
            if (!image.Interpolate)
            {
              interpolationMode = gfx.InterpolationMode;
              gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
            }

            RectangleF destRectF = new RectangleF((float)destRect.X, (float)destRect.Y, (float)destRect.Width, (float)destRect.Height);
            RectangleF srcRectF = new RectangleF((float)srcRect.X, (float)srcRect.Y, (float)srcRect.Width, (float)srcRect.Height);
            this.gfx.DrawImage(image.gdiImage, destRectF, srcRectF, GraphicsUnit.Pixel);

            if (!image.Interpolate)
              gfx.InterpolationMode = interpolationMode;
          }
          else
          {
            DrawMissingImageRect(new XRect(destRect.x, destRect.y, destRect.width, destRect.height));
            //this.gfx.DrawRectangle(Pens.Red, (float)destRect.X, (float)destRect.Y,
            //  (float)destRect.Width, (float)destRect.Height);
            //this.gfx.DrawLine(Pens.Red, (float)destRect.X, (float)destRect.Y, (float)(destRect.X + destRect.Width), (float)(destRect.Y + destRect.Height));
            //this.gfx.DrawLine(Pens.Red, (float)(destRect.X + destRect.Width), (float)destRect.Y, (float)destRect.X, (float)(destRect.Y + destRect.Height));
          }
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          if (image.wpfImage != null)
          {
            //InterpolationMode interpolationMode = InterpolationMode.Invalid;
            //if (!image.Interpolate)
            //{
            //  interpolationMode = gfx.InterpolationMode;
            //  //gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
            //}

            // HACK: srcRect is ignored
            double x = destRect.x;
            double y = destRect.y;
            this.dc.DrawImage(image.wpfImage, new System.Windows.Rect(destRect.x, destRect.y, destRect.width, destRect.height));

            //if (!image.Interpolate)
            //  gfx.InterpolationMode = interpolationMode;
          }
          else
          {
            DrawMissingImageRect(destRect);
          }
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawImage(image, destRect, srcRect, srcUnit);
    }
コード例 #14
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
    /// <summary>
    /// Draws the specified image.
    /// </summary>
    public void DrawImage(XImage image, double x, double y, double width, double height)
    {
      if (image == null)
        throw new ArgumentNullException("image");

      CheckXPdfFormConsistence(image);

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          if (image.gdiImage != null)
          {
            InterpolationMode interpolationMode = InterpolationMode.Invalid;
            if (!image.Interpolate)
            {
              interpolationMode = gfx.InterpolationMode;
              gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
            }

            this.gfx.DrawImage(image.gdiImage, (float)x, (float)y, (float)width, (float)height);

            if (!image.Interpolate)
              gfx.InterpolationMode = interpolationMode;
          }
          else
          {
            XImage placeholder = null;
            if (image is XPdfForm)
            {
              XPdfForm pf = image as XPdfForm;
              if (pf.PlaceHolder != null)
                placeholder = pf.PlaceHolder;
            }
            if (placeholder != null)
              this.gfx.DrawImage(placeholder.gdiImage, (float)x, (float)y, (float)width, (float)height);
            else
            {
              DrawMissingImageRect(new XRect(x, y, width, height));
              //this.gfx.DrawRectangle(Pens.Red, (float)x, (float)y, (float)width, (float)height);
              //this.gfx.DrawLine(Pens.Red, (float)x, (float)y, (float)(x + width), (float)(y + height));
              //this.gfx.DrawLine(Pens.Red, (float)(x + width), (float)y, (float)x, (float)(y + height));
            }
          }
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          if (image.wpfImage != null)
          {
            //InterpolationMode interpolationMode = InterpolationMode.Invalid;
            //if (!image.Interpolate)
            //{
            //  interpolationMode = gfx.InterpolationMode;
            //  gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
            //}

            this.dc.DrawImage(image.wpfImage, new Rect(x, y, width, height));

            //if (!image.Interpolate)
            //  gfx.InterpolationMode = interpolationMode;
          }
          else
          {
            XImage placeholder = null;
            if (image is XPdfForm)
            {
              XPdfForm pf = image as XPdfForm;
              if (pf.PlaceHolder != null)
                placeholder = pf.PlaceHolder;
            }
            if (placeholder != null)
              this.dc.DrawImage(placeholder.wpfImage, new Rect(x, y, width, height));
            else
              DrawMissingImageRect(new XRect(x, y, width, height));
          }
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawImage(image, x, y, width, height);
    }
コード例 #15
0
ファイル: Render.cs プロジェクト: Matt--/travellermap
        public static void RenderTile(RenderContext ctx)
        {
            DateTime dtStart = DateTime.Now;
            List<Timer> timers = new List<Timer>();

            if (ctx.resourceManager == null)
                throw new ArgumentNullException("resourceManager");

            if (ctx.graphics == null)
                throw new ArgumentNullException("graphics");

            if (ctx.selector == null)
                throw new ArgumentNullException("selector");

            XSolidBrush solidBrush = new XSolidBrush();
            XPen pen = new XPen(XColor.Empty);

            using (var fonts = new FontCache(ctx.styles))
            {
                #region resources
                lock (s_imageInitLock)
                {
                    if (ctx.styles.useBackgroundImage && s_backgroundImage == null)
                        s_backgroundImage = XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Nebula.png"));

                    if (ctx.styles.showRifts && s_riftImage == null)
                        s_riftImage = new ImageHolder(Image.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Rifts.png")));

                    if (ctx.styles.useGalaxyImage && s_galaxyImage == null) {
                        s_galaxyImage = new ImageHolder(Image.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Galaxy.png")));
                        s_galaxyImageGray = new ImageHolder(Image.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Galaxy_Gray.png")));
                    }

                    if (ctx.styles.useWorldImages && s_worldImages == null)
                    {
                        s_worldImages = new Dictionary<string, XImage> {
                            { "Hyd0", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd0.png")) },
                            { "Hyd1", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd1.png")) },
                            { "Hyd2", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd2.png")) },
                            { "Hyd3", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd3.png")) },
                            { "Hyd4", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd4.png")) },
                            { "Hyd5", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd5.png")) },
                            { "Hyd6", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd6.png")) },
                            { "Hyd7", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd7.png")) },
                            { "Hyd8", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd8.png")) },
                            { "Hyd9", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Hyd9.png")) },
                            { "HydA", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/HydA.png")) },
                            { "Belt", XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/Candy/Belt.png")) }
                        };
                    }

                    if (ctx.silly && s_sillyImageColor == null)
                    {
                        // Happy face c/o http://bighappyfaces.com/
                        s_sillyImageColor = XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/AprilFools/Starburst.png"));
                        s_sillyImageGray = XImage.FromFile(ctx.resourceManager.Server.MapPath(@"~/res/AprilFools/Starburst_Gray.png"));
                    }
                }
                #endregion

                timers.Add(new Timer("preload"));
                //////////////////////////////////////////////////////////////
                //
                // Image-Space Rendering
                //
                //////////////////////////////////////////////////////////////

                using (Maps.Rendering.RenderUtil.SaveState(ctx.graphics))
                {
                    if (ctx.clipPath != null)
                    {
                        XMatrix m = ctx.ImageSpaceToWorldSpace;
                        ctx.graphics.MultiplyTransform(m);
                        ctx.graphics.IntersectClip(ctx.clipPath);
                        m.Invert();
                        ctx.graphics.MultiplyTransform(m);
                    }

                    // Fill
                    ctx.graphics.SmoothingMode = XSmoothingMode.HighSpeed;
                    solidBrush.Color = ctx.styles.backgroundColor;
                    ctx.graphics.DrawRectangle(solidBrush, 0, 0, ctx.tileSize.Width, ctx.tileSize.Height);

                    //// Draw tile #
                    //using( var font = new Font( FontFamily.GenericSansSerif, 10 ) )
                    //{
                    //  graphics.DrawString( String.Format( "({0},{1})", x, y ), font, foregroundBrush, 0, 0 );
                    //  graphics.DrawString( String.Format( "{0},{1}-{2}x{3}", tileRect.X, tileRect.Y, tileRect.Width, tileRect.Height ), font, foregroundBrush, 0, 20 );
                    //}

                    // Frame it
                    //graphics.DrawRectangle( Pens.Green, 0, 0, tileSize.Width-1, tileSize.Height-1 );
                }

                timers.Add(new Timer("imagespace"));
                //////////////////////////////////////////////////////////////
                //
                // World-Space Rendering
                //
                //////////////////////////////////////////////////////////////

                // Transform from image-space to world-space. Set up a reverse transform as well.
                XMatrix imageSpaceToWorldSpace = ctx.ImageSpaceToWorldSpace;

                XMatrix worldSpaceToImageSpace = imageSpaceToWorldSpace;
                worldSpaceToImageSpace.Invert();

                ctx.graphics.MultiplyTransform(imageSpaceToWorldSpace);

                using (Maps.Rendering.RenderUtil.SaveState(ctx.graphics))
                {

                    //------------------------------------------------------------
                    // Explicit Clipping
                    //------------------------------------------------------------

                    if (ctx.clipPath != null)
                        ctx.graphics.IntersectClip(ctx.clipPath);

                    //ctx.styles.showPseudoRandomStars = true;
                    //------------------------------------------------------------
                    // Backgrounds
                    //------------------------------------------------------------

                    RectangleF galacticBounds = new RectangleF(-14598.67f, -23084.26f, 29234.1133f, 25662.4746f); // TODO: Don't hardcode
                    Rectangle galaxyImageRect = new Rectangle(-18257, -26234, 36551, 32462); // Chosen to match T5 pp.416

                    // This transforms the Linehan galactic structure to the Mikesh galactic structure
                    // See http://travellermap.blogspot.com/2009/03/galaxy-scale-mismatch.html
                    Matrix xformLinehanToMikesh = new Matrix(0.9181034f, 0.0f, 0.0f, 0.855192542f, 120.672432f, 86.34569f);
                    timers.Add(new Timer("prep"));

                    //------------------------------------------------------------
                    // Local background (Nebula)
                    //------------------------------------------------------------
                    #region nebula-background

                    // NOTE: Since alpha texture brushes aren't supported without
                    // creating a new image (slow!) we render the local background
                    // first, then overlay the deep background over it, for
                    // basically the same effect since the alphas sum to 1.

                    if (ctx.styles.useBackgroundImage && galacticBounds.IntersectsWith(ctx.tileRect))
                    {
                        // Image-space rendering, so save current context
                        using (RenderUtil.SaveState(ctx.graphics))
                        {
                            // Never fill outside the galaxy
                            ctx.graphics.IntersectClip(galacticBounds);

                            // Map back to image space so it scales/tiles nicely
                            ctx.graphics.MultiplyTransform(worldSpaceToImageSpace);

                            const float backgroundImageScale = 2.0f;

                            lock (s_backgroundImage)
                            {
                                // Scaled size of the background
                                double w = s_backgroundImage.PixelWidth * backgroundImageScale;
                                double h = s_backgroundImage.PixelHeight * backgroundImageScale;

                                // Offset of the background, relative to the canvas
                                double ox = (float)(-ctx.tileRect.Left * ctx.scale * Astrometrics.ParsecScaleX) % w;
                                double oy = (float)(-ctx.tileRect.Top * ctx.scale * Astrometrics.ParsecScaleY) % h;
                                if (ox > 0) ox -= w;
                                if (oy > 0) oy -= h;

                                // Number of copies needed to cover the canvas
                                int nx = 1 + (int)Math.Floor(ctx.tileSize.Width / w);
                                int ny = 1 + (int)Math.Floor(ctx.tileSize.Height / h);
                                if (ox + nx * w < ctx.tileSize.Width) nx += 1;
                                if (oy + ny * h < ctx.tileSize.Height) ny += 1;

                                for (int x = 0; x < nx; ++x)
                                {
                                    for (int y = 0; y < ny; ++y)
                                    {
                                        ctx.graphics.DrawImage(s_backgroundImage, ox + x * w, oy + y * h, w + 1, h + 1);
                                        //ctx.graphics.DrawRectangle( XPens.Orange, ox + x * w, oy + y * h, w, h );
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                    timers.Add(new Timer("background (nebula)"));

                    //------------------------------------------------------------
                    // Deep background (Galaxy)
                    //------------------------------------------------------------
                    #region galaxy-background
                    if (ctx.styles.useGalaxyImage && ctx.styles.deepBackgroundOpacity > 0f)
                    {
                        using (RenderUtil.SaveState(ctx.graphics))
                        {
                            ctx.graphics.MultiplyTransform(xformLinehanToMikesh);
                            ImageHolder galaxyImage = ctx.styles.lightBackground ? s_galaxyImageGray : s_galaxyImage;
                            lock (galaxyImage)
                            {
                                RenderUtil.DrawImageAlpha(ctx.graphics, ctx.styles.deepBackgroundOpacity, galaxyImage, galaxyImageRect);
                            }
                        }
                    }
                    #endregion
                    timers.Add(new Timer("background (galaxy)"));

                    //------------------------------------------------------------
                    // Pseudo-Random Stars
                    //------------------------------------------------------------
                    #region pseudorandom-stars

                    if (ctx.styles.pseudoRandomStars.visible)
                    {
                        // Render pseudorandom stars based on the tile # and
                        // scale factor. Note that these are positioned in
                        // screen space, not world space.

                        //const int nStars = 75;
                        int nMinStars = ctx.tileSize.Width * ctx.tileSize.Height / 300;
                        int nStars = ctx.scale >= 1 ? nMinStars : (int)(nMinStars / ctx.scale);

                        // NOTE: For performance's sake, three different cases are considered:
                        // (1) Tile is entirely within charted space (most common) - just render
                        //     the pseudorandom stars into the tile
                        // (2) Tile intersects the galaxy bounds - render pseudorandom stars
                        //     into a texture, then fill the galaxy vector with it
                        // (3) Tile is entire outside the galaxy - don't render stars

                        using (RenderUtil.SaveState(ctx.graphics))
                        {
                            ctx.graphics.SmoothingMode = XSmoothingMode.HighQuality;
                            solidBrush.Color = ctx.styles.pseudoRandomStars.fillColor;

                            Random rand = new Random((((int)ctx.tileRect.Left) << 8) ^ (int)ctx.tileRect.Top);
                            for (int i = 0; i < nStars; i++)
                            {
                                float starX = (float)rand.NextDouble() * ctx.tileRect.Width + ctx.tileRect.X;
                                float starY = (float)rand.NextDouble() * ctx.tileRect.Height + ctx.tileRect.Y;
                                float d = (float)rand.NextDouble() * 2;

                                //ctx.graphics.DrawRectangle( fonts.foregroundBrush, starX, starY, (float)( d / ctx.scale * Astrometrics.ParsecScaleX ), (float)( d / ctx.scale * Astrometrics.ParsecScaleY ) );
                                ctx.graphics.DrawEllipse(solidBrush, starX, starY, (float)(d / ctx.scale * Astrometrics.ParsecScaleX), (float)(d / ctx.scale * Astrometrics.ParsecScaleY));
                            }
                        }
                    }
                    #endregion
                    timers.Add(new Timer("pseudorandom"));

                    //------------------------------------------------------------
                    // Rifts in Charted Space
                    //------------------------------------------------------------
                    #region rifts

                    if (ctx.styles.showRifts && ctx.styles.riftOpacity > 0f)
                    {
                        Rectangle riftImageRect;
                        riftImageRect = new Rectangle(-1374, -827, 2769, 1754); // Correct
                        lock (s_riftImage)
                        {
                            RenderUtil.DrawImageAlpha(ctx.graphics, ctx.styles.riftOpacity, s_riftImage, riftImageRect);
                        }
                    }
                    #endregion
                    timers.Add(new Timer("rifts"));

                    //------------------------------------------------------------
                    // April Fool's Day
                    //------------------------------------------------------------
                    #region april-fools

                    if (ctx.silly)
                    {
                        using (RenderUtil.SaveState(ctx.graphics))
                        {
                            // Render in image-space
                            ctx.graphics.MultiplyTransform(worldSpaceToImageSpace);

                            XImage sillyImage = ctx.styles.grayscale ? s_sillyImageGray : s_sillyImageColor;

                            lock (sillyImage)
                            {
                                ctx.graphics.DrawImage(sillyImage, 0, 0, ctx.tileSize.Width, ctx.tileSize.Height);
                            }
                        }
                        timers.Add(new Timer("silly"));
                    }

                    #endregion

                    //------------------------------------------------------------
                    // Macro: Borders object
                    //------------------------------------------------------------
                    #region macro-borders
                    if (ctx.styles.macroBorders.visible)
                    {
                        ctx.styles.macroBorders.pen.Apply(ref pen);
                        ctx.graphics.SmoothingMode = XSmoothingMode.AntiAlias;
                        foreach (var vec in borderFiles
                            .Select(file => ctx.resourceManager.GetXmlFileObject(file, typeof(VectorObject)))
                            .OfType<VectorObject>()
                            .Where(vec => (vec.MapOptions & ctx.options & MapOptions.BordersMask) != 0))
                        {
                            vec.Draw(ctx.graphics, ctx.tileRect, ctx.options, pen);
                        }

                    }
                    #endregion
                    timers.Add(new Timer("macro-borders"));

                    //------------------------------------------------------------
                    // Macro: Route object
                    //------------------------------------------------------------
                    #region macro-routes

                    if (ctx.styles.macroRoutes.visible)
                    {
                        ctx.styles.macroRoutes.pen.Apply(ref pen);
                        ctx.graphics.SmoothingMode = XSmoothingMode.AntiAlias;
                        foreach (var vec in routeFiles
                            .Select(file => ctx.resourceManager.GetXmlFileObject(file, typeof(VectorObject)))
                            .OfType<VectorObject>()
                            .Where(vec => (vec.MapOptions & ctx.options & MapOptions.BordersMask) != 0))
                        {
                            vec.Draw(ctx.graphics, ctx.tileRect, ctx.options, pen);
                        }
                    }
                    #endregion
                    timers.Add(new Timer("macro-routes"));

                    //------------------------------------------------------------
                    // Sector Grid
                    //------------------------------------------------------------
                    #region sector-grid

                    ctx.graphics.SmoothingMode = XSmoothingMode.HighSpeed;

                    if (ctx.styles.sectorGrid.visible)
                    {
                        const int gridSlop = 10;
                        ctx.styles.sectorGrid.pen.Apply(ref pen);

                        for (float h = ((float)(Math.Floor((ctx.tileRect.Left) / Astrometrics.SectorWidth) - 1) - Astrometrics.ReferenceSector.X) * Astrometrics.SectorWidth - Astrometrics.ReferenceHex.X; h <= ctx.tileRect.Right + Astrometrics.SectorWidth; h += Astrometrics.SectorWidth)
                            ctx.graphics.DrawLine(pen, h, ctx.tileRect.Top - gridSlop, h, ctx.tileRect.Bottom + gridSlop);

                        for (float v = ((float)(Math.Floor((ctx.tileRect.Top) / Astrometrics.SectorHeight) - 1) - Astrometrics.ReferenceSector.Y) * Astrometrics.SectorHeight - Astrometrics.ReferenceHex.Y; v <= ctx.tileRect.Bottom + Astrometrics.SectorHeight; v += Astrometrics.SectorHeight)
                            ctx.graphics.DrawLine(pen, ctx.tileRect.Left - gridSlop, v, ctx.tileRect.Right + gridSlop, v);
                    }

                    #endregion
                    timers.Add(new Timer("sector grid"));

                    //------------------------------------------------------------
                    // Subsector Grid
                    //------------------------------------------------------------
                    #region subsector-grid
                    ctx.graphics.SmoothingMode = XSmoothingMode.HighSpeed;
                    if (ctx.styles.subsectorGrid.visible)
                    {
                        const int gridSlop = 10;
                        ctx.styles.subsectorGrid.pen.Apply(ref pen);

                        int hmin = (int)Math.Floor(ctx.tileRect.Left / Astrometrics.SubsectorWidth) - 1 - Astrometrics.ReferenceSector.X,
                            hmax = (int)Math.Ceiling((ctx.tileRect.Right + Astrometrics.SubsectorWidth + Astrometrics.ReferenceHex.X) / Astrometrics.SubsectorWidth);
                        for (int hi = hmin; hi <= hmax; ++hi)
                        {
                            if (hi % 4 == 0) continue;
                            float h = hi * Astrometrics.SubsectorWidth - Astrometrics.ReferenceHex.X;
                            ctx.graphics.DrawLine(pen, h, ctx.tileRect.Top - gridSlop, h, ctx.tileRect.Bottom + gridSlop);
                        }

                        int vmin = (int)Math.Floor(ctx.tileRect.Top / Astrometrics.SubsectorHeight) - 1 - Astrometrics.ReferenceSector.Y,
                            vmax = (int)Math.Ceiling((ctx.tileRect.Bottom + Astrometrics.SubsectorHeight + Astrometrics.ReferenceHex.Y) / Astrometrics.SubsectorHeight);
                        for (int vi = vmin; vi <= vmax; ++vi)
                        {
                            if (vi % 4 == 0) continue;
                            float v = vi * Astrometrics.SubsectorHeight - Astrometrics.ReferenceHex.Y;
                            ctx.graphics.DrawLine(pen, ctx.tileRect.Left - gridSlop, v, ctx.tileRect.Right + gridSlop, v);
                        }
                    }
                    #endregion
                    timers.Add(new Timer("subsector grid"));

                    //------------------------------------------------------------
                    // Parsec Grid
                    //------------------------------------------------------------
                    #region parsec-grid
                    // TODO: Optimize - timers indicate this is slow
                    ctx.graphics.SmoothingMode = XSmoothingMode.HighQuality;
                    if (ctx.styles.parsecGrid.visible)
                    {
                        const int parsecSlop = 1;

                        int hx = (int)Math.Floor(ctx.tileRect.Left);
                        int hw = (int)Math.Ceiling(ctx.tileRect.Width);
                        int hy = (int)Math.Floor(ctx.tileRect.Top);
                        int hh = (int)Math.Ceiling(ctx.tileRect.Height);

                        ctx.styles.parsecGrid.pen.Apply(ref pen);

                        switch (ctx.styles.hexStyle)
                        {
                            case HexStyle.Square:
                                for (int px = hx - parsecSlop; px < hx + hw + parsecSlop; px++)
                                {
                                    float yOffset = ((px % 2) != 0) ? 0.0f : 0.5f;
                                    for (int py = hy - parsecSlop; py < hy + hh + parsecSlop; py++)
                                    {
                                        // TODO: use RenderUtil.(Square|Hex)Edges(X|Y) arrays
                                        const float inset = 0.1f;
                                        ctx.graphics.DrawRectangle(pen, px + inset, py + inset + yOffset, 1 - inset * 2, 1 - inset * 2);
                                    }
                                }
                                break;

                            case HexStyle.Hex:
                                XPoint[] points = new XPoint[4];
                                for (int px = hx - parsecSlop; px < hx + hw + parsecSlop; px++)
                                {
                                    double yOffset = ((px % 2) != 0) ? 0.0 : 0.5;
                                    for (int py = hy - parsecSlop; py < hy + hh + parsecSlop; py++)
                                    {
                                        points[0] = new XPoint(px + -RenderUtil.HEX_EDGE, py + 0.5 + yOffset);
                                        points[1] = new XPoint(px + RenderUtil.HEX_EDGE, py + 1.0 + yOffset);
                                        points[2] = new XPoint(px + 1.0 - RenderUtil.HEX_EDGE, py + 1.0 + yOffset);
                                        points[3] = new XPoint(px + 1.0 + RenderUtil.HEX_EDGE, py + 0.5 + yOffset);
                                        ctx.graphics.DrawLines(pen, points);
                                    }
                                }
                                break;
                            case HexStyle.None:
                                // none
                                break;
                        }

                        if (ctx.styles.numberAllHexes &&
                            ctx.styles.worldDetails.HasFlag(WorldDetails.Hex))
                        {
                            solidBrush.Color = ctx.styles.hexNumber.textColor;
                            for (int px = hx - parsecSlop; px < hx + hw + parsecSlop; px++)
                            {
                                double yOffset = ((px % 2) != 0) ? 0.0 : 0.5;
                                for (int py = hy - parsecSlop; py < hy + hh + parsecSlop; py++)
                                {
                                    Location loc = Astrometrics.CoordinatesToLocation(px + 1, py + 1);
                                    string hex;
                                    switch (ctx.styles.hexCoordinateStyle)
                                    {
                                        default:
                                        case Stylesheet.HexCoordinateStyle.Sector: hex = loc.HexString; break;
                                        case Stylesheet.HexCoordinateStyle.Subsector: hex = loc.SubsectorHexString; break;
                                    }
                                    using (RenderUtil.SaveState(ctx.graphics))
                                    {
                                        XMatrix matrix = new XMatrix();
                                        matrix.TranslatePrepend(px + 0.5f, py + yOffset);
                                        matrix.ScalePrepend(ctx.styles.hexContentScale / Astrometrics.ParsecScaleX, ctx.styles.hexContentScale / Astrometrics.ParsecScaleY);
                                        ctx.graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend);
                                        ctx.graphics.DrawString(hex, ctx.styles.hexNumber.Font, solidBrush, 0, 0, RenderUtil.StringFormatTopCenter);
                                    }
                                }
                            }
                        }
                    }
                    #endregion
                    timers.Add(new Timer("parsec grid"));

                    //------------------------------------------------------------
                    // Subsector Names
                    //------------------------------------------------------------
                    #region subsector-names

                    if (ctx.styles.subsectorNames.visible)
                    {
                        solidBrush.Color = ctx.styles.subsectorNames.textColor;
                        foreach (Sector sector in ctx.selector.Sectors)
                        {
                            for (int i = 0; i < 16; i++)
                            {
                                int ssx = i % 4;
                                int ssy = i / 4;

                                Subsector ss = sector[i];
                                if (ss == null || String.IsNullOrEmpty(ss.Name))
                                    continue;

                                Point center = sector.SubsectorCenter(i);
                                RenderUtil.DrawLabel(ctx.graphics, ss.Name, center, ctx.styles.subsectorNames.Font, solidBrush, ctx.styles.subsectorNames.textStyle);
                            }
                        }
                    }

                    #endregion
                    timers.Add(new Timer("subsector names"));

                    //------------------------------------------------------------
                    // Micro: Borders
                    //------------------------------------------------------------
                    #region micro-borders
                    if (ctx.styles.microBorders.visible)
                    {
                        if (ctx.styles.fillMicroBorders)
                            DrawMicroBorders(ctx, BorderLayer.Fill);
                        DrawMicroBorders(ctx, BorderLayer.Stroke);
                    }
                    #endregion
                    timers.Add(new Timer("micro-borders"));

                    //------------------------------------------------------------
                    // Micro: Routes
                    //------------------------------------------------------------
                    #region micro-routes

                    if (ctx.styles.microRoutes.visible)
                        DrawRoutes(ctx, fonts);

                    #endregion
                    timers.Add(new Timer("micro-routes"));

                    //------------------------------------------------------------
                    // Sector Names
                    //------------------------------------------------------------
                    #region sector-names

                    if (ctx.styles.showSomeSectorNames || ctx.styles.showAllSectorNames)
                    {
                        foreach (Sector sector in ctx.selector.Sectors
                            .Where(sector => ctx.styles.showAllSectorNames || (ctx.styles.showSomeSectorNames && sector.Selected))
                            .Where(sector => sector.Names.Any() || sector.Label != null))
                        {
                            solidBrush.Color = ctx.styles.sectorName.textColor;
                            string name = sector.Label ?? sector.Names[0].Text;

                            RenderUtil.DrawLabel(ctx.graphics, name, sector.Center, ctx.styles.sectorName.Font, solidBrush, ctx.styles.sectorName.textStyle);
                        }
                    }

                    #endregion
                    timers.Add(new Timer("sector names"));

                    //------------------------------------------------------------
                    // Mega: Galaxy-Scale Labels
                    //------------------------------------------------------------
                    #region mega-names
                    if (ctx.styles.megaNames.visible)
                    {
                        solidBrush.Color = ctx.styles.megaNames.textColor;
                        foreach (var label in megaLabels)
                        {
                            using (RenderUtil.SaveState(ctx.graphics))
                            {
                                XMatrix matrix = new XMatrix();
                                matrix.ScalePrepend(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY);
                                matrix.TranslatePrepend(label.position.X, label.position.Y);
                                ctx.graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend);

                                XFont font = label.minor ? ctx.styles.megaNames.SmallFont : ctx.styles.megaNames.Font;
                                XSize size = ctx.graphics.MeasureString(label.text, font);
                                ctx.graphics.TranslateTransform(-size.Width / 2, -size.Height / 2); // Center the text
                                RectangleF textBounds = new RectangleF(0, 0, (float)size.Width * 1.01f, (float)size.Height * 2); // *2 or it gets cut off at high sizes
                                XTextFormatter formatter = new XTextFormatter(ctx.graphics);
                                formatter.Alignment = XParagraphAlignment.Center;
                                formatter.DrawString(label.text, font, solidBrush, textBounds);
                            }
                        }
                    }
                    #endregion
                    timers.Add(new Timer("mega names"));

                    //------------------------------------------------------------
                    // Macro: Government / Rift / Route Names
                    //------------------------------------------------------------
                    #region government-rift-names
                    if (ctx.styles.macroNames.visible)
                    {
                        foreach (var vec in borderFiles
                            .Select(file => ctx.resourceManager.GetXmlFileObject(file, typeof(VectorObject)))
                            .OfType<VectorObject>()
                            .Where(vec => (vec.MapOptions & ctx.options & MapOptions.NamesMask) != 0))
                        {
                            bool major = vec.MapOptions.HasFlag(MapOptions.NamesMajor);
                            LabelStyle labelStyle = new LabelStyle();
                            labelStyle.Uppercase = major;
                            XFont font = major ? ctx.styles.macroNames.Font : ctx.styles.macroNames.SmallFont;
                            solidBrush.Color = major ? ctx.styles.macroNames.textColor : ctx.styles.macroNames.textHighlightColor;
                            vec.DrawName(ctx.graphics, ctx.tileRect, ctx.options, font, solidBrush, labelStyle);
                        }

                        foreach (var vec in riftFiles
                            .Select(file => ctx.resourceManager.GetXmlFileObject(file, typeof(VectorObject)))
                            .OfType<VectorObject>()
                            .Where(vec => (vec.MapOptions & ctx.options & MapOptions.NamesMask) != 0))
                        {
                            bool major = vec.MapOptions.HasFlag(MapOptions.NamesMajor);
                            LabelStyle labelStyle = new LabelStyle();
                            labelStyle.Rotation = 35;
                            labelStyle.Uppercase = major;
                            XFont font = major ? ctx.styles.macroNames.Font : ctx.styles.macroNames.SmallFont;
                            solidBrush.Color = major ? ctx.styles.macroNames.textColor : ctx.styles.macroNames.textHighlightColor;
                            vec.DrawName(ctx.graphics, ctx.tileRect, ctx.options, font, solidBrush, labelStyle);
                        }

                        if (ctx.styles.macroRoutes.visible)
                        {
                            foreach (var vec in routeFiles
                                .Select(file => ctx.resourceManager.GetXmlFileObject(file, typeof(VectorObject)))
                                .OfType<VectorObject>()
                                .Where(vec => (vec.MapOptions & ctx.options & MapOptions.NamesMask) != 0))
                            {
                                bool major = vec.MapOptions.HasFlag(MapOptions.NamesMajor);
                                LabelStyle labelStyle = new LabelStyle();
                                labelStyle.Uppercase = major;
                                XFont font = major ? ctx.styles.macroNames.Font : ctx.styles.macroNames.SmallFont;
                                solidBrush.Color = major ? ctx.styles.macroRoutes.textColor : ctx.styles.macroRoutes.textHighlightColor;
                                vec.DrawName(ctx.graphics, ctx.tileRect, ctx.options, font, solidBrush, labelStyle);
                            }
                        }

                        if (ctx.options.HasFlag(MapOptions.NamesMinor))
                        {
                            XFont font = ctx.styles.macroNames.MediumFont;
                            solidBrush.Color = ctx.styles.macroRoutes.textHighlightColor;
                            foreach (var label in labels)
                            {
                                using (RenderUtil.SaveState(ctx.graphics))
                                {
                                    XMatrix matrix = new XMatrix();
                                    matrix.ScalePrepend(1.0f / Astrometrics.ParsecScaleX, 1.0f / Astrometrics.ParsecScaleY);
                                    matrix.TranslatePrepend(label.position.X, label.position.Y);
                                    ctx.graphics.MultiplyTransform(matrix, XMatrixOrder.Prepend);

                                    XSize size = ctx.graphics.MeasureString(label.text, font);
                                    ctx.graphics.TranslateTransform(-size.Width / 2, -size.Height / 2); // Center the text
                                    RectangleF textBounds = new RectangleF(0, 0, (float)size.Width, (float)size.Height * 2); // *2 or it gets cut off at high sizes
                                    XTextFormatter formatter = new XTextFormatter(ctx.graphics);
                                    formatter.Alignment = XParagraphAlignment.Center;
                                    formatter.DrawString(label.text, font, solidBrush, textBounds);
                                }
                            }

                        }
                    }

                    #endregion
                    timers.Add(new Timer("macro names"));

                    //------------------------------------------------------------
                    // Macro: Capitals & Home Worlds
                    //------------------------------------------------------------
                    #region capitals-homeworlds

                    if (ctx.styles.capitals.visible && (ctx.options & MapOptions.WorldsMask) != 0)
                    {
                        WorldObjectCollection worlds = ctx.resourceManager.GetXmlFileObject(@"~/res/Worlds.xml", typeof(WorldObjectCollection)) as WorldObjectCollection;
                        if (worlds != null)
                        {
                            solidBrush.Color = ctx.styles.capitals.textColor;
                            foreach (WorldObject world in worlds.Worlds.Where(world => (world.MapOptions & ctx.options) != 0))
                            {
                                world.Paint(ctx.graphics, ctx.tileRect, ctx.options, ctx.styles.capitals.fillColor,
                                    solidBrush, ctx.styles.macroNames.SmallFont);
                            }
                        }
                    }

                    #endregion
                    timers.Add(new Timer("macro worlds"));

                    //------------------------------------------------------------
                    // Micro: Border Labels & Explicit Labels
                    //------------------------------------------------------------
                    #region micro-border-labels

                    if (ctx.styles.showMicroNames)
                        DrawLabels(ctx, fonts);

                    #endregion
                    timers.Add(new Timer("micro-border labels"));
                }

                // End of clipping, so world names are not clipped in jumpmaps.

                //------------------------------------------------------------
                // Worlds
                //------------------------------------------------------------
                #region worlds
                if (ctx.styles.worlds.visible)
                {
                    // TODO: selector may be expensive
                    foreach (World world in ctx.selector.Worlds) { DrawWorld(ctx, fonts, world, WorldLayer.Background); }
                    foreach (World world in ctx.selector.Worlds) { DrawWorld(ctx, fonts, world, WorldLayer.Foreground); }
                }
                #endregion
                timers.Add(new Timer("worlds"));

                //------------------------------------------------------------
                // Unofficial
                //------------------------------------------------------------
                #region unofficial

                if (ctx.styles.dimUnofficialSectors && ctx.styles.worlds.visible)
                {
                    solidBrush.Color = Color.FromArgb(128, ctx.styles.backgroundColor);
                    foreach (Sector sector in ctx.selector.Sectors
                        .Where(sector => !sector.Tags.Contains("Official") && !sector.Tags.Contains("Preserve") && !sector.Tags.Contains("InReview")))
                        ctx.graphics.DrawRectangle(solidBrush, sector.Bounds);
                }

                #endregion

            #if SHOW_TIMING
                using( RenderUtil.SaveState( ctx.graphics ) )
                {
                    XFont font = new XFont( FontFamily.GenericSansSerif, 12, XFontStyle.Regular, new XPdfFontOptions(PdfSharp.Pdf.PdfFontEncoding.Unicode) );
                    ctx.graphics.MultiplyTransform( worldSpaceToImageSpace );
                    double cursorX = 20.0, cursorY = 20.0;
                    DateTime last = dtStart;
                    foreach( Timer s in timers )
                    {
                        TimeSpan ts = s.dt - last;
                        last = s.dt;
                        for( int dx = -1; dx <= 1; ++dx )
                        {
                            for( int dy = -1; dy <= 1; ++dy )
                            {

                                ctx.graphics.DrawString( String.Format( "{0} {1}", Math.Round( ts.TotalMilliseconds ), s.label ), font, XBrushes.Black, cursorX + dx, cursorY + dy );
                            }
                        }
                        ctx.graphics.DrawString( String.Format("{0} {1}", Math.Round(ts.TotalMilliseconds), s.label), font, XBrushes.Yellow, cursorX, cursorY );
                        cursorY += 14;
                    }
                }
            #endif

            }
        }
コード例 #16
0
ファイル: XForm.cs プロジェクト: AnthonyNystrom/Pikling
 /// <summary>
 /// Gets the resource name of the specified image within this form.
 /// </summary>
 internal string GetImageName(XImage image)
 {
   Debug.Assert(IsTemplate, "This function is for form templates only.");
   PdfImage pdfImage = this.document.ImageTable.GetImage(image);
   Debug.Assert(pdfImage != null);
   string name = Resources.AddImage(pdfImage);
   return name;
 }
コード例 #17
0
    public void RealizeFill(Brush brush, double opacity, ref XForm xform, ref XImage ximage) // PdfColorMode colorMode)
    {
      SolidColorBrush sbrush;
      LinearGradientBrush lbrush;
      RadialGradientBrush rbrush;
      ImageBrush ibrush;
      VisualBrush vbrush;
      if ((sbrush = brush as SolidColorBrush) != null)
      {
        Color color = sbrush.Color;
        //color = ColorSpaceHelper.EnsureColorMode(colorMode, color);

        this.writer.WriteRgb(color, " rg\n");

        //if (this.renderer.Owner.Version >= 14 && this.realizedStrokeColor.A != color.A)
        //if (this.realizedFillColor.ScA != color.ScA)
        {
          PdfExtGState extGState = this.writer.Owner.ExtGStateTable.GetExtGStateNonStroke(color.ScA);
          string gs = this.writer.Resources.AddExtGState(extGState);
          this.writer.WriteLiteral("{0} gs\n", gs);

          // Must create transparany group
          if (color.ScA < 1)
            this.writer.CreateDefaultTransparencyGroup();
        }
        this.realizedFillColor = color;

        //if (colorMode != PdfColorMode.Cmyk)
        //{
        //  if (this.realizedFillColor.Rgb != color.Rgb)
        //  {
        //    this.renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Rgb));
        //    this.renderer.Append(" rg\n");
        //  }
        //}
        //else
        //{
        //  if (!ColorSpaceHelper.IsEqualCmyk(this.realizedFillColor, color))
        //  {
        //    this.renderer.Append(PdfEncoders.ToString(color, PdfColorMode.Cmyk));
        //    this.renderer.Append(" k\n");
        //  }
        //}

        //if (this.renderer.Owner.Version >= 14 && this.realizedFillColor.A != color.A)
        //{
        //  PdfExtGState extGState = this.renderer.Owner.ExtGStateTable.GetExtGStateNonStroke(color.A);
        //  string gs = this.renderer.Resources.AddExtGState(extGState);
        //  this.renderer.AppendFormat("{0} gs\n", gs);

        //  // Must create transparany group
        //  if (this.renderer.page != null && color.A < 1)
        //    this.renderer.page.transparencyUsed = true;
        //}
        //this.realizedFillColor = color;
      }
      else if ((lbrush = brush as LinearGradientBrush) != null)
      {
        // NOT IN USE ANYMORE
        //RealizeLinearGradientBrush(lbrush, xform);
      }
      else if ((rbrush = brush as RadialGradientBrush) != null)
      {
        // NOT IN USE ANYMORE
        //RealizeRadialGradientBrush(rbrush, xform);
      }
      else if ((ibrush = brush as ImageBrush) != null)
      {
        // NOT IN USE ANYMORE
        //RealizeImageBrush(ibrush, ref xform, ref ximage);
      }
      else if ((vbrush = brush as VisualBrush) != null)
      {
        // NOT IN USE ANYMORE
        //RealizeVisualBrush(vbrush, ref xform);
      }
      else
      {
        //return new SolidColorBrush(Colors//
        //Debugger.Break();
      }
    }
コード例 #18
0
    ///// <summary>
    ///// Makes the specified pen and brush to the current graphics objects.
    ///// </summary>
    //void Realize(Pen pen, XBrush brush)
    //{
    //  BeginPage();
    //  BeginGraphic();
    //  RealizeTransform();

    //  if (pen != null)
    //    this.gfxState.RealizePen(pen, this.colorMode); // this.page.document.Options.ColorMode);

    //  if (brush != null)
    //    this.gfxState.RealizeBrush(brush, this.colorMode); // this.page.document.Options.ColorMode);
    //}

    /// <summary>
    /// Makes the specified brush to the current graphics object.
    /// </summary>
    public void RealizeFill(Brush brush, ref XForm xform, ref XImage ximage)
    {
      this.graphicsState.RealizeFill(brush, 1, ref xform, ref ximage);
    }
コード例 #19
0
ファイル: PdfSharpImage.cs プロジェクト: asgerhallas/DomFx
 PdfSharpImage(XImage source)
 {
     this.source = source;
 }
コード例 #20
0
 string IContentStream.GetImageName(XImage image)
 {
   throw new NotImplementedException();
 }
コード例 #21
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
 /// <summary>
 /// Draws the specified image.
 /// </summary>
 public void DrawImage(XImage image, XRect rect)
 {
   DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
 }
コード例 #22
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
 /// <summary>
 /// Draws the specified image.
 /// </summary>
 public void DrawImage(XImage image, int x, int y, int width, int height)
 {
   DrawImage(image, (double)x, (double)y, (double)width, (double)height);
 }
コード例 #23
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
    //public SizeF MeasureString(string text, XFont font, SizeF layoutArea);
    //public SizeF MeasureString(string text, XFont font, int width);
    //public SizeF MeasureString(string text, XFont font, PointF origin, XStringFormat stringFormat);
    //public SizeF MeasureString(string text, XFont font, SizeF layoutArea, XStringFormat stringFormat);
    //public SizeF MeasureString(string text, XFont font, int width, XStringFormat format);
    //public SizeF MeasureString(string text, XFont font, SizeF layoutArea, XStringFormat stringFormat, out int charactersFitted, out int linesFilled);

    // ----- DrawImage ----------------------------------------------------------------------------

#if GDI
    /// <summary>
    /// Draws the specified image.
    /// </summary>
    public void DrawImage(XImage image, System.Drawing.Point point)
    {
      DrawImage(image, (double)point.X, (double)point.Y);
    }
コード例 #24
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
 /// <summary>
 /// Draws the specified image.
 /// </summary>
 public void DrawImage(XImage image, RectangleF destRect, RectangleF srcRect, XGraphicsUnit srcUnit)
 {
   XRect destRectX = new XRect(destRect.X, destRect.Y, destRect.Width, destRect.Height);
   XRect srcRectX = new XRect(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height);
   DrawImage(image, destRectX, srcRectX, srcUnit);
 }
コード例 #25
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
 /// <summary>
 /// Draws the specified image.
 /// </summary>
 public void DrawImage(XImage image, XPoint point)
 {
   DrawImage(image, point.X, point.Y);
 }
コード例 #26
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
    /// <summary>
    /// Checks whether drawing is allowed and disposes the XGraphics object, if necessary.
    /// </summary>
    void CheckXPdfFormConsistence(XImage image)
    {
      XForm xForm = image as XForm;
      XGraphicsPdfRenderer renderer;
      if (xForm != null)
      {
        // Force disposing of XGraphics that draws the content
        xForm.Finish();

        if (this.renderer != null && (renderer = this.renderer as XGraphicsPdfRenderer) != null)
        {
          if (xForm.Owner != null && xForm.Owner != ((XGraphicsPdfRenderer)this.renderer).Owner)
            throw new InvalidOperationException(
              "A XPdfForm object is always bound to the document it was created for and cannot be drawn in the context of another document.");

          if (xForm == ((XGraphicsPdfRenderer)this.renderer).form)
            throw new InvalidOperationException(
              "A XPdfForm cannot be drawn on itself.");
        }
      }
    }
コード例 #27
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
    //TODO trapezoid transformation
    ////public void DrawImage(XImage image, Point[] destPoints);
    ////public void DrawImage(XImage image, PointF[] destPoints);
    ////public void DrawImage(XImage image, XPoint[] destPoints);

    /// <summary>
    /// Draws the specified image.
    /// </summary>
    public void DrawImage(XImage image, int x, int y)
    {
      DrawImage(image, (double)x, (double)y);
    }
コード例 #28
0
ファイル: PdfPage.cs プロジェクト: Sl0vi/PDFsharp
 /// <summary>
 /// Implements the interface because the primary function is internal.
 /// </summary>
 string IContentStream.GetImageName(XImage image)
 {
     return GetImageName(image);
 }
コード例 #29
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
    /// <summary>
    /// Draws the specified image.
    /// </summary>
    public void DrawImage(XImage image, double x, double y)
    {
      if (image == null)
        throw new ArgumentNullException("image");

      CheckXPdfFormConsistence(image);

      double width = image.PointWidth;
      double height = image.PointHeight;

      if (this.drawGraphics)
      {
#if GDI
        if (this.targetContext == XGraphicTargetContext.GDI)
        {
          if (image.gdiImage != null)
          {
            InterpolationMode interpolationMode = InterpolationMode.Invalid;
            if (!image.Interpolate)
            {
              interpolationMode = gfx.InterpolationMode;
              gfx.InterpolationMode = InterpolationMode.NearestNeighbor;
            }

            this.gfx.DrawImage(image.gdiImage, (float)x, (float)y, (float)width, (float)height);

            if (!image.Interpolate)
              gfx.InterpolationMode = interpolationMode;
          }
          else
          {
            DrawMissingImageRect(new XRect(x, y, width, height));
            //this.gfx.DrawRectangle(Pens.Red, (float)x, (float)y, (float)width, (float)height);
            //this.gfx.DrawLine(Pens.Red, (float)x, (float)y, (float)(x + width), (float)(y + height));
            //this.gfx.DrawLine(Pens.Red, (float)(x + width), (float)y, (float)x, (float)(y + height));
          }
        }
#endif
#if WPF
        if (this.targetContext == XGraphicTargetContext.WPF)
        {
          if (image.wpfImage != null)
          {
            this.dc.DrawImage(image.wpfImage, new Rect(x, y, image.PointWidth, image.PointHeight));
          }
          else
          {
            DrawMissingImageRect(new XRect(x, y, width, height));
          }
        }
#endif
      }

      if (this.renderer != null)
        this.renderer.DrawImage(image, x, y, image.PointWidth, image.PointHeight);
      //image.Width * 72 / image.HorizontalResolution,
      //image.Height * 72 / image.HorizontalResolution);
    }
コード例 #30
0
ファイル: XGraphics.cs プロジェクト: Davincier/openpetra
 /// <summary>
 /// Draws the specified image.
 /// </summary>
 public void DrawImage(XImage image, System.Windows.Point point)
 {
   DrawImage(image, (double)point.X, (double)point.Y);
 }
コード例 #31
0
 public static void DrawImage(XGraphics gfx, XImage image, XUnit x, XUnit y, XUnit width, XUnit height)
 {
     gfx.DrawImage(image, x, y, width, height);
 }