Ejemplo n.º 1
0
        /// <summary>
        /// Draws the QR code to the specified graphics context (canvas). The QR code will
        /// always be 46 mm by 46 mm.
        /// </summary>
        /// <param name="graphics">The graphics context.</param>
        /// <param name="offsetX">The x offset.</param>
        /// <param name="offsetY">The y offset.</param>
        internal void Draw(ICanvas graphics, double offsetX, double offsetY)
        {
            QrCode qrCode = QrCode.EncodeText(_embeddedText, QrCode.Ecc.Medium);

            bool[,] modules = CopyModules(qrCode);
            ClearSwissCrossArea(modules);

            int modulesPerSide = modules.GetLength(0);

            graphics.SetTransformation(offsetX, offsetY, 0, Size / modulesPerSide / 25.4 * 72, Size / modulesPerSide / 25.4 * 72);
            graphics.StartPath();
            DrawModulesPath(graphics, modules);
            graphics.FillPath(0);
            graphics.SetTransformation(offsetX, offsetY, 0, 1, 1);

            // Swiss cross
            graphics.StartPath();
            graphics.AddRectangle(20, 20, 6, 6);
            graphics.FillPath(0);
            const double barWidth  = 7 / 6.0;
            const double barLength = 35 / 9.0;

            graphics.StartPath();
            graphics.AddRectangle(23 - barWidth / 2, 23 - barLength / 2, barWidth, barLength);
            graphics.AddRectangle(23 - barLength / 2, 23 - barWidth / 2, barLength, barWidth);
            graphics.FillPath(0xffffff);
        }
Ejemplo n.º 2
0
        // Simple algorithms to reduce the number of rectangles for drawing the QR code
        // and reduce SVG size
        private static void DrawLargestRectangle(ICanvas graphics, bool[,] modules, int x, int y)
        {
            int size = modules.GetLength(0);

            int bestW   = 1;
            int bestH   = 1;
            int maxArea = 1;

            int xLimit = size;
            int iy     = y;

            while (iy < size && modules[iy, x])
            {
                int w = 0;
                while (x + w < xLimit && modules[iy, x + w])
                {
                    w++;
                }

                int area = w * (iy - y + 1);
                if (area > maxArea)
                {
                    maxArea = area;
                    bestW   = w;
                    bestH   = iy - y + 1;
                }
                xLimit = x + w;
                iy++;
            }

            double unit = 25.4 / 72;

            graphics.AddRectangle(x * unit, (size - y - bestH) * unit, bestW * unit, bestH * unit);
            ClearRectangle(modules, x, y, bestW, bestH);
        }
        /// <summary>
        /// Produces a mapping to a sprite that has given maximum dimensions.
        /// If the mapping can not be done inside those dimensions, returns null.
        /// </summary>
        /// <param name="images">
        /// List of image infos.
        ///
        /// This method will not sort this list.
        /// All images in this collection will be used, regardless of size.
        /// </param>
        /// <param name="maxWidth">
        /// The sprite won't be wider than this.
        /// </param>
        /// <param name="maxHeight">
        /// The generated sprite won't be higher than this.
        /// </param>
        /// <param name="canvasStats">
        /// The statistics produced by the canvas. These numbers are since the last call to its SetCanvasDimensions method.
        /// </param>
        /// <param name="lowestFreeHeightDeficitTallestRightFlushedImage">
        /// The lowest free height deficit for the images up to and including the tallest rectangle whose right hand border sits furthest to the right
        /// of all images.
        ///
        /// This is the minimum amount by which the height of the canvas needs to be increased to accommodate that rectangle.
        /// if the width of the canvas is decreased to one less than the width now taken by images.
        ///
        /// Note that providing the additional height might get some other (not right flushed) image to be placed higher, thereby
        /// making room for the flushed right image.
        ///
        /// This will be set to Int32.MaxValue if there was never any free height deficit.
        /// </param>
        /// <returns>
        /// The generated sprite.
        ///
        /// null if not all the images could be placed within the size limitations.
        /// </returns>
        protected virtual S MappingRestrictedBox(
            IOrderedEnumerable <IImageInfo> images,
            int maxWidth, int maxHeight, ICanvasStats canvasStats,
            out int lowestFreeHeightDeficitTallestRightFlushedImage)
        {
            lowestFreeHeightDeficitTallestRightFlushedImage = 0;
            _canvas.SetCanvasDimensionsbis(maxWidth, maxHeight);

            S   spriteInfo = new S();
            int heightHighestRightFlushedImage = 0;
            int furthestRightEdge = 0;

            foreach (IImageInfo image in images)
            {
                int xOffset;
                int yOffset;
                int lowestFreeHeightDeficit;
                if (!_canvas.AddRectangle(
                        image.Width, image.Height,
                        out xOffset, out yOffset,
                        out lowestFreeHeightDeficit))
                {
                    // Not enough room on the canvas to place the rectangle
                    spriteInfo = null;
                    break;
                }

                MappedImageInfo imageLocation = new MappedImageInfo(xOffset, yOffset, image);
                spriteInfo.AddMappedImage(imageLocation);

                // Update the lowestFreeHeightDeficitTallestRightFlushedImage
                int rightEdge = image.Width + xOffset;
                if ((rightEdge > furthestRightEdge) ||
                    ((rightEdge == furthestRightEdge) && (image.Height > heightHighestRightFlushedImage)))
                {
                    // The image is flushed the furthest right of all images, or it is flushed equally far to the right
                    // as the furthest flushed image but it is taller.

                    lowestFreeHeightDeficitTallestRightFlushedImage = lowestFreeHeightDeficit;
                    heightHighestRightFlushedImage = image.Height;
                    furthestRightEdge = rightEdge;
                }
            }

            _canvas.GetStatistics(canvasStats);

            return(spriteInfo);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Draws the QR code to the specified graphics context (canvas). The QR code will
        /// always be 46 mm by 46 mm.
        /// </summary>
        /// <param name="graphics">The graphics context.</param>
        /// <param name="offsetX">The x offset.</param>
        /// <param name="offsetY">The y offset.</param>
        internal void Draw(ICanvas graphics, double offsetX, double offsetY)
        {
            var qrCode = QrCode.EncodeText(_embeddedText, QrCode.Ecc.Medium);

            var modules = CopyModules(qrCode);

            ClearSwissCrossArea(modules);

            var modulesPerSide = modules.GetLength(0);

            graphics.SetTransformation(offsetX, offsetY, 0, Size / modulesPerSide / 25.4 * 72, Size / modulesPerSide / 25.4 * 72);
            graphics.StartPath();
            DrawModulesPath(graphics, modules);
            graphics.FillPath(0, false);
            graphics.SetTransformation(offsetX, offsetY, 0, 1, 1);

            // Swiss cross
            graphics.StartPath();
            graphics.AddRectangle(20, 20, 6, 6);
            graphics.FillPath(0, false);
            const double barWidth  = 7 / 6.0;
            const double barLength = 35 / 9.0;

            graphics.StartPath();
            //       A----B
            //       |    |
            //       |    |
            // K-----L    C-----D
            // |                |
            // |                |
            // J-----I    F-----E
            //       |    |
            //       |    |
            //       H----G

            // Center is (23;23)
            // Start in A
            graphics.MoveTo(23 - barWidth / 2, 23 - barLength / 2);

            // Line to B
            graphics.LineTo(23 + barWidth / 2, 23 - barLength / 2);

            // Line to C
            graphics.LineTo(23 + barWidth / 2, 23 - barWidth / 2);

            // Line to D
            graphics.LineTo(23 + barLength / 2, 23 - barWidth / 2);

            // Line to E
            graphics.LineTo(23 + barLength / 2, 23 + barWidth / 2);

            // Line to F
            graphics.LineTo(23 + barWidth / 2, 23 + barWidth / 2);

            // Line to G
            graphics.LineTo(23 + barWidth / 2, 23 + barLength / 2);

            // Line to H
            graphics.LineTo(23 - barWidth / 2, 23 + barLength / 2);

            // Line to I
            graphics.LineTo(23 - barWidth / 2, 23 + barWidth / 2);

            // Line to J
            graphics.LineTo(23 - barLength / 2, 23 + barWidth / 2);

            // Line to K
            graphics.LineTo(23 - barLength / 2, 23 - barWidth / 2);

            // Line to K
            graphics.LineTo(23 - barWidth / 2, 23 - barWidth / 2);

            graphics.FillPath(0xffffff, false);
        }