Example #1
0
        // Layout a course onto one or more pages.
        List <CoursePage> LayoutCourse(CourseDesignator courseDesignator)
        {
            List <CoursePage> pageList = new List <CoursePage>();

            // Get the area of the map we want to print, in map coordinates, and the ratio between print scale and map scale.
            float      scaleRatio;
            bool       landscape;
            PaperSize  paperSize;
            string     description;
            int        margins;
            RectangleF mapArea = GetPrintAreaForCourse(courseDesignator, out landscape, out paperSize, out margins, out scaleRatio, out description);

            // Get the available page size on the page.
            RectangleF printableArea     = GetPrintablePageArea(landscape, paperSize, margins);
            SizeF      pageSizeAvailable = printableArea.Size;

            // Layout both page dimensions, iterate through them to get all the pages we have.
            foreach (DimensionLayout verticalLayout in LayoutPageDimension(mapArea.Top, mapArea.Height, printableArea.Top, printableArea.Height, scaleRatio))
            {
                foreach (DimensionLayout horizontalLayout in LayoutPageDimension(mapArea.Left, mapArea.Width, printableArea.Left, printableArea.Width, scaleRatio))
                {
                    CoursePage page = new CoursePage();
                    page.courseDesignator = courseDesignator;
                    page.description      = description;
                    page.landscape        = landscape;
                    page.paperSize        = paperSize;
                    page.mapRectangle     = new RectangleF(horizontalLayout.startMap, verticalLayout.startMap, horizontalLayout.lengthMap, verticalLayout.lengthMap);
                    page.printRectangle   = new RectangleF(horizontalLayout.startPage, verticalLayout.startPage, horizontalLayout.lengthPage, verticalLayout.lengthPage);
                    pageList.Add(page);
                }
            }

            return(pageList);
        }
Example #2
0
        // Split up a course page into bands, so that each band is
        //    a) exactly the same size
        //    b) no more than maxPixels in size
        //    c) goes top to bottom for portraint, left to right for landscape.
        List <CoursePage> BandPageToLimitBitmapSize(CoursePage page, float dpi, long maxPixels)
        {
            List <CoursePage> list = new List <CoursePage>();
            bool landscape         = page.landscape;

            // Figure out how many bands we need to limit the pixel size of each band.
            long pixelsOnPage = (long)Math.Round(page.printRectangle.Width * dpi / 100F) * (long)Math.Round(page.printRectangle.Height * dpi / 100F);
            int  numBands     = (int)Math.Ceiling((double)pixelsOnPage / (double)maxPixels);

            // Calculate the band size.
            float mapBandSize, printBandSize;

            if (landscape)
            {
                mapBandSize   = page.mapRectangle.Width / numBands;
                printBandSize = page.printRectangle.Width / numBands;
            }
            else
            {
                mapBandSize   = page.mapRectangle.Height / numBands;
                printBandSize = page.printRectangle.Height / numBands;
            }

            // Create the bands.
            for (int i = 0; i < numBands; ++i)
            {
                CoursePage band = new CoursePage();
                band.landscape        = landscape;
                band.courseDesignator = page.courseDesignator;

                if (landscape)
                {
                    band.mapRectangle   = new RectangleF(page.mapRectangle.Left + i * mapBandSize, page.mapRectangle.Top, mapBandSize, page.mapRectangle.Height);
                    band.printRectangle = new RectangleF(page.printRectangle.Left + i * printBandSize, page.printRectangle.Top, printBandSize, page.printRectangle.Height);
                }
                else
                {
                    band.mapRectangle   = new RectangleF(page.mapRectangle.Left, page.mapRectangle.Top + (numBands - 1 - i) * mapBandSize, page.mapRectangle.Width, mapBandSize);
                    band.printRectangle = new RectangleF(page.printRectangle.Left, page.printRectangle.Top + i * printBandSize, page.printRectangle.Width, printBandSize);
                }

                list.Add(band);
            }

            // Return the list of bands.
            return(list);
        }
Example #3
0
        // The core printing routine.
        void DrawPage(IGraphicsTarget graphicsTarget, CoursePage page)
        {
            // Get the course view for the course we are printing.
            CourseView courseView = CourseView.CreatePrintingCourseView(eventDB, page.courseDesignator);

            // Get the correct purple color to print the course in.
            short ocadId;
            float purpleC, purpleM, purpleY, purpleK;
            bool  purpleOverprint;

            FindPurple.GetPurpleColor(mapDisplay, appearance, out ocadId, out purpleC, out purpleM, out purpleY, out purpleK, out purpleOverprint);

            // Create a course layout from the view.
            CourseLayout layout = new CourseLayout();

            layout.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false);
            layout.SetLayerColor(CourseLayer.MainCourse, ocadId, NormalCourseAppearance.courseColorName, purpleC, purpleM, purpleY, purpleK, purpleOverprint);
            CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, layout, CourseLayer.MainCourse);

            // Set the course layout into the map display
            mapDisplay.SetCourse(layout);
            mapDisplay.SetPrintArea(null);

            // Set the transform, and the clip.
            Matrix transform = Geometry.CreateInvertedRectangleTransform(page.mapRectangle, page.printRectangle);

            PushRectangleClip(graphicsTarget, page.printRectangle);
            graphicsTarget.PushTransform(transform);
            // Determine the resolution in map coordinates.
            Matrix inverseTransform = transform.Clone();

            inverseTransform.Invert();
            float minResolutionPage = 100F / 2400F;  // Assume 2400 DPI as the base resolution, to get very accurate print.
            float minResolutionMap  = Geometry.TransformDistance(minResolutionPage, inverseTransform);

            // And draw.
            mapDisplay.Draw(graphicsTarget, page.mapRectangle, minResolutionMap);

            graphicsTarget.PopTransform();
            graphicsTarget.PopClip();
        }
Example #4
0
        // Layout a course onto one or more pages.
        List<CoursePage> LayoutCourse(CourseDesignator courseDesignator)
        {
            List<CoursePage> pageList = new List<CoursePage>();

            // Get the area of the map we want to print, in map coordinates, and the ratio between print scale and map scale.
            float scaleRatio;
            bool landscape;
            PaperSize paperSize;
            string description;
            int margins;
            RectangleF mapArea = GetPrintAreaForCourse(courseDesignator, out landscape, out paperSize, out margins, out scaleRatio, out description);

            // Get the available page size on the page.
            RectangleF printableArea = GetPrintablePageArea(landscape, paperSize, margins);
            SizeF pageSizeAvailable = printableArea.Size;

            // Layout both page dimensions, iterate through them to get all the pages we have.
            foreach (DimensionLayout verticalLayout in LayoutPageDimension(mapArea.Top, mapArea.Height, printableArea.Top, printableArea.Height, scaleRatio))
                foreach (DimensionLayout horizontalLayout in LayoutPageDimension(mapArea.Left, mapArea.Width, printableArea.Left, printableArea.Width, scaleRatio)) {
                    CoursePage page = new CoursePage();
                    page.courseDesignator = courseDesignator;
                    page.description = description;
                    page.landscape = landscape;
                    page.paperSize = paperSize;
                    page.mapRectangle = new RectangleF(horizontalLayout.startMap, verticalLayout.startMap, horizontalLayout.lengthMap, verticalLayout.lengthMap);
                    page.printRectangle = new RectangleF(horizontalLayout.startPage, verticalLayout.startPage, horizontalLayout.lengthPage, verticalLayout.lengthPage);
                    pageList.Add(page);
                }

            return pageList;
        }
Example #5
0
        // Create a single PDF file
        void CreateOnePdfFile(string fileName, IEnumerable <CourseDesignator> courseDesignators)
        {
            List <CoursePage> pages     = LayoutPages(courseDesignators);
            PdfWriter         pdfWriter = new PdfWriter(Path.GetFileNameWithoutExtension(fileName), coursePdfSettings.ColorModel == ColorModel.CMYK);

            foreach (CoursePage page in pages)
            {
                CoursePage pageToDraw = page;

                SizeF paperSize = new SizeF(pageToDraw.paperSize.Width / 100F, pageToDraw.paperSize.Height / 100F);
                if (pageToDraw.landscape)
                {
                    paperSize = new SizeF(paperSize.Height, paperSize.Width);
                }

                if (controller.UpdateProgressDialog(string.Format(MiscText.CreatingFile, Path.GetFileName(fileName)), (double)currentPage / (double)totalPages))
                {
                    throw new Exception(MiscText.CancelledByUser);
                }

                IGraphicsTarget grTarget;
                PdfImporter     pdfImporter = null;

                if (IsPdfMap)
                {
                    // We need to re-obtain a PdfImporter every time, or else very strange bugs start to crop up.

                    pdfImporter = new PdfImporter(sourcePdfMapFileName);

                    float scaleRatio = CourseView.CreatePrintingCourseView(eventDB, page.courseDesignator).ScaleRatio;
                    if (scaleRatio == 1.0)
                    {
                        // If we're doing a PDF at scale 1, we just copy the page directly.
                        grTarget   = pdfWriter.BeginCopiedPage(pdfImporter, 0);
                        pageToDraw = PdfNonScaledPage(page.courseDesignator);
                    }
                    else
                    {
                        Matrix     transform = Geometry.CreateInvertedRectangleTransform(page.printRectangle, page.mapRectangle);
                        RectangleF printedPortionInMapCoords = Geometry.TransformRectangle(transform, new RectangleF(0, 0, paperSize.Width * 100F, paperSize.Height * 100F));
                        RectangleF printedPortionInInches    = new RectangleF(
                            Geometry.InchesFromMm(printedPortionInMapCoords.Left),
                            Geometry.InchesFromMm(mapBounds.Height - printedPortionInMapCoords.Bottom),
                            Geometry.InchesFromMm(printedPortionInMapCoords.Width),
                            Geometry.InchesFromMm(printedPortionInMapCoords.Height));

                        grTarget = pdfWriter.BeginCopiedPartialPage(pdfImporter, 0, paperSize, printedPortionInInches);
                    }

                    // Don't draw the map normally.
                    mapDisplay.SetMapFile(MapType.None, null);
                }
                else
                {
                    grTarget = pdfWriter.BeginPage(paperSize);
                }

                DrawPage(grTarget, pageToDraw);
                pdfWriter.EndPage(grTarget);
                grTarget.Dispose();

                if (pdfImporter != null)
                {
                    pdfImporter.Dispose();
                    pdfImporter = null;
                }

                currentPage += 1;
            }

            pdfWriter.Save(fileName);
        }
Example #6
0
        // The core printing routine. The origin of the graphics is the upper-left of the margins,
        // and the printArea in the size to draw into (in hundreths of an inch).
        protected override void DrawPage(IGraphicsTarget graphicsTarget, int pageNumber, SizeF printArea, float dpi)
        {
            CoursePage page = pages[pageNumber];

            // Get the course view for the course we are printing.
            CourseView courseView = CourseView.CreatePrintingCourseView(eventDB, page.courseDesignator);

            // Get the correct purple color to print the course in.
            short ocadId;
            float purpleC, purpleM, purpleY, purpleK;
            bool  purpleOverprint;

            FindPurple.GetPurpleColor(mapDisplay, appearance, out ocadId, out purpleC, out purpleM, out purpleY, out purpleK, out purpleOverprint);

            // Create a course layout from the view.
            CourseLayout layout = new CourseLayout();

            layout.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false);
            layout.SetLayerColor(CourseLayer.MainCourse, ocadId, NormalCourseAppearance.courseColorName, purpleC, purpleM, purpleY, purpleK, purpleOverprint);
            CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, layout, CourseLayer.MainCourse);

            // Set the course layout into the map display
            mapDisplay.SetCourse(layout);
            this.mapDisplay.SetPrintArea(null);

            // Collecting garbage should make out of memory less common.
            GC.Collect();

            if (graphicsTarget is GDIPlus_GraphicsTarget)
            {
                // We print to intermediate bands of bitmaps. This is the only way to get purple blending correct.
                // Other code ensure that if purple blending is on, we always take this code path.

                GDIPlus_GraphicsTarget gdiGraphicsTarget = ((GDIPlus_GraphicsTarget)graphicsTarget);
                Graphics g = gdiGraphicsTarget.Graphics;
                // Save and restore state so we can mess with stuff.
                GraphicsState graphicsState = g.Save();

                // Printing via a bitmap. Works best with some print drivers.
                dpi = AdjustDpi(dpi);

                const long        MAX_PIXELS_PER_BAND = 20000000; // 20M pixels = 60M bytes (3 bytes per pixel).
                List <CoursePage> bands = BandPageToLimitBitmapSize(page, dpi, MAX_PIXELS_PER_BAND);

                // Create the bitmap. Can do this once because each band is the same size.
                int    bitmapWidth  = (int)Math.Round(bands[0].printRectangle.Width * dpi / 100F);
                int    bitmapHeight = (int)Math.Round(bands[0].printRectangle.Height * dpi / 100F);
                Bitmap bitmap       = new Bitmap(bitmapWidth, bitmapHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                foreach (CoursePage band in bands)
                {
                    // Set the transform
                    Matrix transform = Geometry.CreateInvertedRectangleTransform(band.mapRectangle, new RectangleF(0, 0, bitmapWidth, bitmapHeight));
                    mapDisplay.Draw(bitmap, transform);

                    try {
                        // Draw the bitmap on the printer.
                        g.DrawImage(bitmap, band.printRectangle);
                    }
                    catch (Exception) { }
                }

                // restore state.
                g.Restore(graphicsState);
                bitmap.Dispose();
            }
            else
            {
                // Print directly. Used only when prerasterization is off.
                // Set the transform, and the clip.
                Matrix transform = Geometry.CreateInvertedRectangleTransform(page.mapRectangle, page.printRectangle);
                PushRectangleClip(graphicsTarget, page.printRectangle);
                graphicsTarget.PushTransform(transform);
                // Determine the resolution in map coordinates.
                Matrix inverseTransform = transform.Clone();
                inverseTransform.Invert();
                float minResolutionPage = 100F / dpi;
                float minResolutionMap  = Geometry.TransformDistance(minResolutionPage, inverseTransform);

                // And draw.
                mapDisplay.Draw(graphicsTarget, page.mapRectangle, minResolutionMap);

                graphicsTarget.PopTransform();
                graphicsTarget.PopClip();
            }
        }
Example #7
0
        // The core printing routine.
        void DrawPage(IGraphicsTarget graphicsTarget, CoursePage page)
        {
            // Get the course view for the course we are printing.
            CourseView courseView = CourseView.CreatePrintingCourseView(eventDB, page.courseDesignator);

            // Get the correct purple color to print the course in.
            short ocadId;
            float purpleC, purpleM, purpleY, purpleK;
            bool purpleOverprint;
            FindPurple.GetPurpleColor(mapDisplay, appearance, out ocadId, out purpleC, out purpleM, out purpleY, out purpleK, out purpleOverprint);

            // Create a course layout from the view.
            CourseLayout layout = new CourseLayout();
            layout.SetLayerColor(CourseLayer.Descriptions, NormalCourseAppearance.blackColorOcadId, NormalCourseAppearance.blackColorName, NormalCourseAppearance.blackColorC, NormalCourseAppearance.blackColorM, NormalCourseAppearance.blackColorY, NormalCourseAppearance.blackColorK, false);
            layout.SetLayerColor(CourseLayer.MainCourse, ocadId, NormalCourseAppearance.courseColorName, purpleC, purpleM, purpleY, purpleK, purpleOverprint);
            CourseFormatter.FormatCourseToLayout(symbolDB, courseView, appearance, layout, CourseLayer.MainCourse);

            // Set the course layout into the map display
            mapDisplay.SetCourse(layout);
            mapDisplay.SetPrintArea(null);

            // Set the transform, and the clip.
            Matrix transform = Geometry.CreateInvertedRectangleTransform(page.mapRectangle, page.printRectangle);
            PushRectangleClip(graphicsTarget, page.printRectangle);
            graphicsTarget.PushTransform(transform);
            // Determine the resolution in map coordinates.
            Matrix inverseTransform = transform.Clone();
            inverseTransform.Invert();
            float minResolutionPage = 100F / 2400F;  // Assume 2400 DPI as the base resolution, to get very accurate print.
            float minResolutionMap = Geometry.TransformDistance(minResolutionPage, inverseTransform);

            // And draw.
            mapDisplay.Draw(graphicsTarget, page.mapRectangle, minResolutionMap);

            graphicsTarget.PopTransform();
            graphicsTarget.PopClip();
        }
Example #8
0
        // Split up a course page into bands, so that each band is
        //    a) exactly the same size
        //    b) no more than maxPixels in size
        //    c) goes top to bottom for portraint, left to right for landscape.
        List<CoursePage> BandPageToLimitBitmapSize(CoursePage page, float dpi, long maxPixels)
        {
            List<CoursePage> list = new List<CoursePage>();
            bool landscape = page.landscape;

            // Figure out how many bands we need to limit the pixel size of each band.
            long pixelsOnPage = (long) Math.Round(page.printRectangle.Width * dpi / 100F) * (long) Math.Round(page.printRectangle.Height * dpi / 100F);
            int numBands = (int) Math.Ceiling((double)pixelsOnPage / (double) maxPixels);

            // Calculate the band size.
            float mapBandSize, printBandSize;
            if (landscape) {
                mapBandSize = page.mapRectangle.Width / numBands;
                printBandSize = page.printRectangle.Width / numBands;
            }
            else {
                mapBandSize = page.mapRectangle.Height / numBands;
                printBandSize = page.printRectangle.Height / numBands;
            }

            // Create the bands.
            for (int i = 0; i < numBands; ++i) {
                CoursePage band = new CoursePage();
                band.landscape = landscape;
                band.courseDesignator = page.courseDesignator;

                if (landscape) {
                    band.mapRectangle = new RectangleF(page.mapRectangle.Left + i * mapBandSize, page.mapRectangle.Top, mapBandSize, page.mapRectangle.Height);
                    band.printRectangle = new RectangleF(page.printRectangle.Left + i * printBandSize, page.printRectangle.Top, printBandSize, page.printRectangle.Height);
                }
                else {
                    band.mapRectangle = new RectangleF(page.mapRectangle.Left, page.mapRectangle.Top + (numBands - 1 - i) * mapBandSize, page.mapRectangle.Width, mapBandSize);
                    band.printRectangle = new RectangleF(page.printRectangle.Left, page.printRectangle.Top + i * printBandSize, page.printRectangle.Width, printBandSize);
                }

                list.Add(band);
            }

            // Return the list of bands.
            return list;
        }