Ejemplo n.º 1
0
        // draws a single Paper Wallet in to a PdfSharp XForm
        private PdfSharp.Drawing.XForm getSingleWallet(PdfDocument doc, WalletBundle b, XImage imgArtwork, string address, string privkey, int numberWithinBatch, bool layoutDebugging)
        {
            WalletTemplate t = b.template;

            double width  = t.widthMM;
            double height = t.heightMM;

            XUnit walletSizeWide = XUnit.FromMillimeter(width);
            XUnit walletSizeHigh = XUnit.FromMillimeter(height);

            PdfSharp.Drawing.XForm form = new PdfSharp.Drawing.XForm(doc, walletSizeWide, walletSizeHigh);


            using (XGraphics formGfx = XGraphics.FromForm(form))
            {
                XGraphicsState state = formGfx.Save();

                bool interpolateArtwork = true;
                bool interpolateQRcodes = false;

                // XImage imgArtwork is now provided by caller, so this process only has to be done ONCE - because the artwork does not change between Wallets in a run!
                //XImage imgArtwork = XImage.FromGdiPlusImage(b.getArtworkImage());
                imgArtwork.Interpolate = interpolateArtwork;

                formGfx.DrawImage(imgArtwork, new RectangleF(0f, 0f, (float)walletSizeWide.Point, (float)walletSizeHigh.Point));

                // draw the QR codes and legible-text things

                // Address
                // QR
                Bitmap bmpAddress = BtcAddress.QR.EncodeQRCode(address);
                XImage imgAddress = XImage.FromGdiPlusImage(bmpAddress);
                imgAddress.Interpolate = interpolateQRcodes;

                XUnit addressQrLeft = XUnit.FromMillimeter(t.addressQrLeftMM);
                XUnit addressQrTop  = XUnit.FromMillimeter(t.addressQrTopMM);
                XUnit addressQrSize = XUnit.FromMillimeter(t.addressQrSizeMM);

                // only print Address QR if called for
                if (t.addressQrSizeMM > 0.1)
                {
                    XRect addressQrRect = new XRect(addressQrLeft.Point, addressQrTop.Point, addressQrSize.Point, addressQrSize.Point);
                    formGfx.DrawImage(imgAddress, addressQrRect);
                }

                // text address
                string         addressSplitForLines = addressOrReferencePrep(address, t.addressTextCharsPerLine, t.addressTextContentVariant, numberWithinBatch);
                XFont          fontAddress          = new XFont(t.addressTextFontName, t.addressTextFontSize, t.addressTextFontStyle);
                XTextFormatter tf = new XTextFormatter(formGfx);

                XUnit addressTxtLeft   = XUnit.FromMillimeter(t.addressTextLeftMM);
                XUnit addressTxtTop    = XUnit.FromMillimeter(t.addressTextTopMM);
                XUnit addressTxtWidth  = XUnit.FromMillimeter(t.addressTextWidthMM);
                XUnit addressTxtHeight = XUnit.FromMillimeter(t.addressTextHeightMM);

                XRect addressRect = new XRect(addressTxtLeft.Point, addressTxtTop.Point, addressTxtWidth.Point, addressTxtHeight.Point);
                tf.Alignment = XParagraphAlignment.Center;

                TextRotation addressTxtRotation        = t.addressTextRotation;
                double       addressTxtRotationDegrees = RotationMarkerToDegrees(addressTxtRotation);

                if (layoutDebugging)
                {
                    formGfx.DrawRectangle(XBrushes.PowderBlue, addressRect);
                }

                XPoint rotateCentre      = new XPoint(addressTxtLeft + (addressTxtWidth / 2), addressTxtTop + (addressTxtHeight / 2));
                XPoint matrixRotatePoint = new XPoint(addressRect.X + (addressRect.Width / 2), addressRect.Y + (addressRect.Height / 2));

                XMatrix rotateMatrix = new XMatrix();
                rotateMatrix.RotateAtAppend(addressTxtRotationDegrees, rotateCentre);
                addressRect.Transform(rotateMatrix);

                if (layoutDebugging)
                {
                    // draw a little tracer dot for where the centre of rotation is going to be
                    double rotateDotSize = 2.0;
                    formGfx.DrawEllipse(XBrushes.Red, rotateCentre.X - (rotateDotSize / 2), rotateCentre.Y - (rotateDotSize / 2), rotateDotSize, rotateDotSize);
                }

                // maybe even do some rotation of the lovely text!
                formGfx.Save();

                formGfx.RotateAtTransform(addressTxtRotationDegrees, rotateCentre);
                if (layoutDebugging)
                {
                    formGfx.DrawRectangle(XPens.OrangeRed, addressRect);
                }

                if (t.addressTextWidthMM > 0.1)
                {
                    tf.DrawString(addressSplitForLines, fontAddress, t.GetBrushAddress, addressRect);
                }
                formGfx.Restore();

                // Privkey
                // QR
                Bitmap bmpPrivkey = BtcAddress.QR.EncodeQRCode(privkey);
                XImage imgPrivkey = XImage.FromGdiPlusImage(bmpPrivkey);
                imgPrivkey.Interpolate = interpolateQRcodes;

                XUnit privkeyQrLeft = XUnit.FromMillimeter(t.privkeyQrLeftMM);
                XUnit privkeyQrTop  = XUnit.FromMillimeter(t.privkeyQrTopMM);
                XUnit privkeyQrSize = XUnit.FromMillimeter(t.privkeyQrSizeMM);

                XRect privkeyQrRect = new XRect(privkeyQrLeft.Point, privkeyQrTop.Point, privkeyQrSize.Point, privkeyQrSize.Point);

                // only print privkey QR if specified - but you'd have to be an UTTER IDIOT to want to exclude this. Still, user input comes first!
                if (t.privkeyQrSizeMM > 0.1)
                {
                    formGfx.DrawImage(imgPrivkey, privkeyQrRect);
                }

                // legible
                string privkeySplitForLines = lineSplitter(privkey, t.privkeyTextCharsPerLine);

                XFont fontPrivkey = new XFont(t.privkeyTextFontName, t.privkeyTextFontSize, t.privkeyTextFontStyle);

                XUnit privkeyTxtLeft   = XUnit.FromMillimeter(t.privkeyTextLeftMM);
                XUnit privkeyTxtTop    = XUnit.FromMillimeter(t.privkeyTextTopMM);
                XUnit privkeyTxtWidth  = XUnit.FromMillimeter(t.privkeyTextWidthMM);
                XUnit privkeyTxtHeight = XUnit.FromMillimeter(t.privkeyTextHeightMM);

                TextRotation privkeyTxtRotation        = t.privkeyTextRotation;
                double       privkeyTxtRotationDegrees = RotationMarkerToDegrees(privkeyTxtRotation);

                XRect privkeyRect = new XRect(privkeyTxtLeft.Point, privkeyTxtTop.Point, privkeyTxtWidth.Point, privkeyTxtHeight.Point);

                if (layoutDebugging)
                {
                    // draw a tracer rectangle for the original un-rotated text rectangle
                    formGfx.DrawRectangle(XBrushes.PowderBlue, privkeyRect);
                }

                // rotate that lovely text around its middle when drawing!
                rotateCentre = new XPoint(privkeyTxtLeft + (privkeyTxtWidth / 2), privkeyTxtTop + (privkeyTxtHeight / 2));

                matrixRotatePoint = new XPoint(privkeyRect.X + (privkeyRect.Width / 2), privkeyRect.Y + (privkeyRect.Height / 2));

                rotateMatrix = new XMatrix();
                rotateMatrix.RotateAtAppend(privkeyTxtRotationDegrees, rotateCentre);
                privkeyRect.Transform(rotateMatrix);

                if (layoutDebugging)
                {
                    // draw a little tracer dot for where the centre of rotation is going to be
                    double rotateDotSize = 2.0;
                    formGfx.DrawEllipse(XBrushes.Red, rotateCentre.X - (rotateDotSize / 2), rotateCentre.Y - (rotateDotSize / 2), rotateDotSize, rotateDotSize);
                }

                formGfx.Save();

                formGfx.RotateAtTransform(privkeyTxtRotationDegrees, rotateCentre);

                if (layoutDebugging)
                {
                    formGfx.DrawRectangle(XPens.OrangeRed, privkeyRect);
                }

                // only print privkey text if specified.
                if (t.privkeyTextWidthMM > 0.1)
                {
                    tf.DrawString(privkeySplitForLines, fontPrivkey, t.GetBrushPrivkey, privkeyRect);
                }

                formGfx.Restore();
            }



            return(form);
        }