Esempio n. 1
0
        private void MakeWordsCentered(clsEPLDriver epl, int iLayout, int maxLineWidth)
        {
            int wordcount  = 0;
            int firstword  = 0;
            int widthsofar = 0;

            for (int i = iLayout; i >= 0; --i)
            {
                firstword = i;
                if (layout[i].lineNumber != layout[iLayout].lineNumber)
                {
                    firstword = i + 1;
                    break;
                }
                else
                {
                    widthsofar += layout[i].Width(epl);
                    wordcount++;
                }
            }
            /* add the spaces to the width */
            widthsofar += (wordcount - 1) * epl.TextWidth(epl.Font, epl.MultiplierHoriz, epl.MultiplierVert, " ");
            System.Diagnostics.Debug.Assert(wordcount >= 2);
            int wordofst = (maxLineWidth - widthsofar) / 2;

            /* centers a couple of words in a line */
            for (int i = firstword; i <= iLayout; ++i)
            {
                if (layout[i].isContent)
                {
                    layout[i].Box = new Rectangle(layout[i].Box.X + wordofst, layout[i].Box.Y, layout[i].Box.Width, layout[i].Box.Height);
                }
            }
        }
Esempio n. 2
0
        public void Render(clsEPLDriver epl)
        {
            if (!bLayoutPrepared)
            {
                return;
            }
            Rectangle box;

            /* renders plainly */
            for (int i = 0; i < layout.Length; ++i)
            {
                /* stop if we are already out of bounds */
                if (layout[i].lineNumber >= lines_rendered)
                {
                    break;
                }
                /* translate them to their intended location (so far, they're zero-based in the top-left corner of logical space) */
                box = new Rectangle(layout[i].Box.Location, layout[i].Box.Size);
                box.Offset(userBounds.Location);
                /* output them, outlined in debugging mode, unadorned in productive builds */
                epl.LabelText(
                    box.X,
                    box.Y,
                    0,
                    epl.Font,
                    epl.MultiplierHoriz,
                    epl.MultiplierVert,
                    false,
                    layout[i].sX
                    );
            }
        }
Esempio n. 3
0
 public int Height(clsEPLDriver epl)
 {
     if (!gotBoundary)
     {
         Measure(epl);
     }
     return(Box.Height);
 }
Esempio n. 4
0
 public int Width(clsEPLDriver epl)
 {
     if (!gotBoundary)
     {
         Measure(epl);
     }
     return(Box.Width);
 }
Esempio n. 5
0
        private void MakeWordCentered(clsEPLDriver epl, int iLayout, int maxLineWidth)
        {
            int curwidth = layout[iLayout].Width(epl);
            int wordofst = (maxLineWidth - curwidth) / 2;

            layout[iLayout].Box = new Rectangle(
                layout[iLayout].Box.X + wordofst,
                layout[iLayout].Box.Y,
                layout[iLayout].Box.Width,
                layout[iLayout].Box.Height
                );
        }
Esempio n. 6
0
 private void Measure(clsEPLDriver epl)
 {
     /* measures the word */
     if (isContent)
     {
         Box = new Rectangle(
             0,
             0,
             epl.TextWidth(epl.Font, epl.MultiplierHoriz, epl.MultiplierVert, sX),
             epl.TextHeight(epl.Font, epl.MultiplierHoriz, epl.MultiplierVert, sX)
             );
     }
     gotBoundary = true;
 }
Esempio n. 7
0
        private void subTokenize(string sX, clsEPLDriver epl)
        {
            bool   inWord  = false;
            string curWord = "";
            int    iStart  = 0;

            /* splits the paragraph up into words and whitespace designators */
            for (int I = 1; I <= sX.Length + 1; ++I) /* the +1 will trigger the "" case below and mark the end of the string; mid$ is one-based! */
            {
                string cX;
                if (I > sX.Length)
                {
                    cX = "";
                }
                else
                {
                    cX = sX.Substring(I - 1, 1);
                }
                switch (cX)
                {
                case " ":
                    /* a space, end of word */
                    if (inWord)
                    {
                        AddWord(false, false, iStart, I - 1, curWord);
                        inWord  = false;
                        curWord = "";
                    }
                    AddWord(true, false, I, I, cX);
                    break;

                case "-":
                    /* a primordial hyphen ends a word, thus presenting an opportunity to break, but it will remain part of the syllable to its left */
                    if (inWord)
                    {
                        AddWord(false, false, iStart, I, curWord + cX);
                        inWord  = false;
                        curWord = "";
                    }
                    else
                    {
                        /* a standalone hyphen will add to the current word */
                        if (!inWord)
                        {
                            iStart = I;
                            inWord = true;
                        }
                        curWord += cX;
                    }
                    break;

                case "":
                    /* end of string, end of word */
                    if (inWord)
                    {
                        AddWord(false, false, iStart, I - 1, curWord);
                        inWord  = false;
                        curWord = "";
                    }
                    break;

                case "\n":
                    /* a line break */
                    if (inWord)
                    {
                        AddWord(false, false, iStart, I - 1, curWord);
                        inWord  = false;
                        curWord = "";
                    }
                    AddWord(false, true, I, I, cX);
                    break;

                default:
                    /* we're in a word */
                    if (!inWord)
                    {
                        iStart = I;
                        inWord = true;
                    }
                    curWord += cX;
                    break;
                }
            }
            /* a line break is always added after the very last line to ensure the last line of justified text is not stretched */
            AddWord(false, true, -1, -1, "\n"); /* -1 indicating this line break is artificial and has no representation in the original source string */
            /* push all the tokens onto the stack for the convenience of the linebreaker algo */
            for (int I = ctWords - 1; I >= 0; --I)
            {
                if (!words[I].isWhiteSpace)
                {
                    tokens.Push(words[I]);
                }
            }
        }
Esempio n. 8
0
        public void CalculateLayout(string sX, clsEPLDriver epl, Rectangle Boundary)
        {
            /* trivia: */
            ResetLayout();
            if (sX == null || sX.Length <= 0)
            {
                return;
            }
            sX = sX.Replace(Environment.NewLine, new string(new char[] { '\n' }));
            /* first shalt thou create arrays of words */
            ctWords = 0;
            subTokenize(sX, epl);
            if (ctWords <= 0)
            {
                return;
            }
            /* then shalt thou create thy font's formatting rules: */
            userBounds = new Rectangle(Boundary.Location, Boundary.Size);
            Rectangle absBounds = new Rectangle(Boundary.Location, Boundary.Size);
            /* determine the height of a line of text and the width of a standard space */
            Rectangle stdBox = new Rectangle(
                0,
                0,
                epl.TextWidth(epl.Font, epl.MultiplierHoriz, epl.MultiplierVert, " "),
                epl.TextHeight(epl.Font, epl.MultiplierHoriz, epl.MultiplierVert, " ")
                );
            int spaceWidth = stdBox.Width;

            lineHeight = stdBox.Height;
            int maxLineWidth = absBounds.Width;
            /* prepare a hyphenator to be at our disposal when we need it */
            var hypX = new sherm.core.hyphenation.cdoHyphenation();

            //_hyphenatedversion = _hyphenationservice.HyphenateFailsafe(ContentToRender);

            /* then we make a non-prefetching, non-readahead flow layout */
            int curLine = 0;         /* line numbers start with 0 */

            lines_rendered = 1;      /* real-world line numbers start with 1 */
            int  runningWidth = 0;   /* the space that is currently taken up in the current line */
            int  runningOfst  = 0;   /* the offset where the next word is to start on the current line */
            int  widthToAdd;
            int  wordsInCurLine = 0; /* the number of words (not counting spaces) in the current line */
            word curword;
            int  distribution;

            //bool apply_inline_distribution=true;
            while (tokens.Count > 0)
            {
                /* ponder about the variants for this line...how many words are we going to fill in */
                /* 1. get a word into the current line */
                curword = tokens.Pop();
                if (curword.isContent)
                {
                    /* try to add this word to the current line */
                    widthToAdd = ((wordsInCurLine > 0) ? spaceWidth : 0) + curword.Width(epl);
                    if (runningWidth + widthToAdd > maxLineWidth)
                    {
                        /* we need to break this word at the end of line
                         * (or, in extreme case, at the beginning of the line, if this word alone takes up more space than the scanline can provide) */
                        distribution = maxLineWidth - runningWidth;
                        if (distribution > maxLineWidth * cstHyphenationTreshold)
                        {
                            /* leaving as is would create too much white space. try fit the first hyphenation of the current word */
                            string[] parts    = hypX.Hyphenate(curword.sX);
                            word     hyphtok  = new word();
                            string   shyphtok = "";
                            bool     bsolved;
                            bsolved           = false;
                            hyphtok.isContent = true;
                            for (int i = 0; i < parts.Length; ++i)
                            {
                                /* try to fit this. */
                                shyphtok  += parts[i];
                                hyphtok.sX = shyphtok + "-";
                                /* is it too much? then revert to hard-breaking (see stmts after end of loop) */
                                if (runningWidth + hyphtok.Width(epl) > maxLineWidth)
                                {
                                    //apply_inline_distribution = false; /* this does the trick of not line-spanning the word(s) immedately before a forced break */
                                    break;
                                }
                                /* it it too narrow still? then take the next syllable if there's one */
                                distribution = maxLineWidth - (runningWidth + hyphtok.Width(epl));
                                if (distribution <= maxLineWidth * cstHyphenationTreshold)
                                {
                                    /* yep, this does it. employ it */
                                    expandlayoutarray(layout.Length + 1);
                                    layout[layout.Length - 1] = hyphtok.Clone();
                                    layout[layout.Length - 1].Offset(runningOfst, curLine, lineHeight);
                                    wordsInCurLine++;
                                    /* now our current word is the remainder of the hyphenated string */
                                    shyphtok = "";
                                    for (int j = i + 1; j < parts.Length; ++j)
                                    {
                                        shyphtok += parts[j];
                                    }
                                    curword.sX = shyphtok;
                                    bsolved    = true;
                                    break;
                                }
                                else
                                {
                                    /* if this is not yet enough, and we have another hyphen in the word, we continue the loop */
                                }
                            }

                            /* the hyphenation approach could not make amends -
                            * thy foe the unbreakable word who, by not obeying the laws of clean type setting,
                            * being naughty in My sight, shall now snuff it. */
                            if ((!bsolved) && (wordsInCurLine <= 0))
                            {
                                /* forced breaking is done with maximum fit, ie., we start chopping off glyphs from the right */
                                word breaktok = new word();
                                breaktok.isContent = true;
                                for (int i = curword.sX.Length; i >= 0; --i)
                                {
                                    /* try to fit this. */
                                    breaktok.sX = curword.sX.Substring(0, Math.Max(i - 1, 1));
                                    /* is it still too much? then take one glyph less, but take one at least */
                                    if ((i <= 0) || (runningWidth + breaktok.Width(epl) <= maxLineWidth))
                                    {
                                        /* yep, this does it. employ it */
                                        expandlayoutarray(layout.Length + 1);
                                        layout[layout.Length - 1] = breaktok.Clone();
                                        layout[layout.Length - 1].Offset(runningOfst, curLine, lineHeight);
                                        wordsInCurLine++;
                                        /* now our current word is the remainder of the broken string */
                                        curword.sX = curword.sX.Substring(i);
                                        break;
                                    }
                                    else
                                    {
                                        /* if this is not yet narrow enough, and we have glyphs left to remove, we continue the loop */
                                    }
                                }
                            }
                        }
                        /* the distribution must always take place, accidental perfect fit can be assumed to be too rare to optimise for it */
                        if (wordsInCurLine == 1)
                        {
                            /* center the word */
                            MakeWordCentered(epl, layout.Length - 1, maxLineWidth);
                        }
                        else if (wordsInCurLine > 1) /* && apply_inline_distribution removed [dlatikay 20081106] */
                        /* center the line */
                        {
                            MakeWordsCentered(epl, layout.Length - 1, maxLineWidth);
                        }
                        /* for the next line, we will again presume that in-line-distribution is applicable */
                        //apply_inline_distribution = true;
                        /* in this branch, in spite of what exactly we're devising above, we'll always cue with a new line */
                        curLine++;
                        if (lines_rendered * lineHeight < userBounds.Height)
                        {
                            lines_rendered++;
                        }
                        runningWidth   = 0;
                        runningOfst    = 0;
                        wordsInCurLine = 0;
                        /* the rest of the word, or the entire word in case we invoked a word-span-line, is returned to the donator stack */
                        tokens.Push(curword);
                    }
                    else
                    {
                        /* add the word as is */
                        expandlayoutarray(layout.Length + 1);
                        layout[layout.Length - 1]            = curword.Clone();
                        layout[layout.Length - 1].lineNumber = curLine;
                        layout[layout.Length - 1].Box.Offset(new Point(runningOfst, curLine * lineHeight));
                        runningWidth += widthToAdd;
                        runningOfst  += curword.Width(epl) + spaceWidth;
                        wordsInCurLine++;
                    }
                }
                else if (curword.isLineBreak)
                {
                    /* immediately go to the next line. if there is nothing to come, stop layouting
                     * spaces are not in! */
                    if (tokens.Count <= 0)
                    {
                        /* we are at the end */
                        if (wordsInCurLine == 1)
                        {
                            /* center the word */
                            MakeWordCentered(epl, layout.Length - 1, maxLineWidth);
                        }
                        else if (wordsInCurLine > 1) /* && apply_inline_distribution removed [dlatikay 20081106] */
                        /* center the line */
                        {
                            MakeWordsCentered(epl, layout.Length - 1, maxLineWidth);
                        }
                        break;
                    }
                    else
                    {
                        /* realise the return of the carriage and the feeding of the line */
                        curLine++;
                        if (lines_rendered * lineHeight < userBounds.Height)
                        {
                            lines_rendered++;
                        }
                        runningWidth   = 0;
                        runningOfst    = 0;
                        wordsInCurLine = 0;
                    }
                }
                else
                {
                    /* spaces are not allowed in this place */
                    System.Diagnostics.Debug.Assert(false);
                }
            }
            /* complete */
            effHeight       = lines_rendered * lineHeight;
            bLayoutPrepared = true;
        }
Esempio n. 9
0
 public void JustifyText(string sX, clsEPLDriver epl, Rectangle boundary)
 {
     CalculateLayout(sX, epl, boundary);
     /* when the step number three, being the third step, be reached, then renderest thou thy utterings utterly onto the screen */
     Render(epl);
 }
Esempio n. 10
0
        public bool SHEQPrintSDSLabel(clsLabelDetails label, labelprinterdrivers driver, string OSprintername, int number_of_copies)
        {
            bool inverse_images;

            /* idle? */
            if (number_of_copies <= 0)
            {
                return(true);
            }
            try
            {
                /* does the driver exist? */
                if (driver == labelprinterdrivers.lpd_zebratlp2844_orange)
                {
                    inverse_images = false;
                }
                else if (driver == labelprinterdrivers.lpd_zebratlp2844_white)
                {
                    inverse_images = true;
                }
                else
                {
                    /* format not supported */
                    throw new ArgumentOutOfRangeException("driver", driver, "The label format specified is not supported by this version of the printer driver.");
                }
                /* treat the pictures */
                int      ctpictures  = 0;
                Bitmap[] pictures    = new Bitmap[max_pics_per_label];
                Bitmap[] monochromes = new Bitmap[max_pics_per_label];
                byte[][] rasters     = new byte[max_pics_per_label][] { new byte[] { }, new byte[] { }, new byte[] { } };
                if (label.Pictures == null)
                {
                    ctpictures = 0;
                }
                else
                {
                    ctpictures = label.Pictures.Length;
                }
                if (ctpictures > max_pics_per_label)
                {
                    /* too many pictures */
                    throw new ArgumentOutOfRangeException("ctpictures", ctpictures, "This layout does not permit to print more than three pictures on a form.");
                }
                else
                {
                    /* make them smoothly smaller */
                    for (int i = 0; i < ctpictures; ++i)
                    {
                        pictures[i] = new Bitmap(160, 160, PixelFormat.Format24bppRgb);
                        using (var gfxX = Graphics.FromImage(pictures[i]))
                        {
                            gfxX.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            gfxX.DrawImage(label.Pictures[i], new Rectangle(0, 0, 160, 160), 0, 0, label.Pictures[i].Width, label.Pictures[i].Height, GraphicsUnit.Pixel);
                        }
                    }
                }
                /* convert any pictures we got */
                for (int i = 0; i < ctpictures; ++i)
                {
                    /* a. increase brightness */
                    for (int y = 0; y < pictures[i].Height; ++y)
                    {
                        for (int x = 0; x < pictures[i].Width; ++x)
                        {
                            if (pictures[i].GetPixel(x, y).GetBrightness() > 0)
                            {
                                pictures[i].SetPixel(x, y, Color.White);
                            }
                        }
                    }
                    /* b. from color to monochrome */
                    monochromes[i] = CopyToBpp(pictures[i], 1);
                    /* c. from bmp to EPL raster */
                    rasters[i] = BitmapToEPLRaster(monochromes[i], inverse_images);
                }
                /* compose the EPL sequence */
                const int    width  = 800;
                const int    height = 560;
                clsEPLDriver epl    = new clsEPLDriver();
                epl.LabelStart(height, 19, width, "A", 49);
                /* 1. print the header */
                epl.LabelText(30, 8, 0, 2, 1, 1, false, label.Clientcompany);
                epl.LabelTextRAlign(773, 8, 0, 2, 1, 1, false, label.Clientbusiness);
                epl.LabelLine(30, 25, 743, 3);
                /* 2. print the substance name */
                int ypos       = 50;
                int lineheight = epl.TextHeight(4, 2, 3, label.Name);
                epl.Font            = 4;
                epl.MultiplierHoriz = 2;
                epl.MultiplierVert  = 3;
                var renderer = new clsWordbreaker();
                renderer.JustifyText(label.Name, epl, new Rectangle(10, ypos, width - 20, lineheight * 2));
#if DEBUG
                //epl.LabelLine(10,ypos+10,width-20,10);
#endif
                ypos += renderer.effHeight;
                /* 3. print the manufacturer */
                epl.LabelTextHCenter(width / 2, ypos, 0, 4, 1, 2, false, label.Manufacturer);

                /* frameborder for debugging purposes:
                 *  epl.LabelLine(0,0,width,20);
                 *  epl.LabelLine(0,height-20,width,20);
                 *  epl.LabelLine(0,0,20,height);
                 *  epl.LabelLine(width-20,0,20,height);
                 */
                /* 4. fill the orange rectangles with the pictures and their subscripts */
                epl.Font            = 1;
                epl.MultiplierHoriz = 1;
                epl.MultiplierVert  = 1;
                int posfact = 225;
                int posofst = 92;
                for (int i = 0; i < ctpictures; ++i)
                {
                    int xco = posofst + i * posfact;
                    epl.LabelBitmap(
                        xco,
                        315,
                        rasters[i],
                        monochromes[i].Width / 8
                        );
                    lineheight = epl.TextHeight(1, 1, 1, label.Subscripts[i]);
                    renderer   = new clsWordbreaker();
                    renderer.JustifyText(label.Subscripts[i], epl, new Rectangle(xco, 480, monochromes[i].Width, lineheight * 2));
                }
                epl.LabelEnd(number_of_copies);
                /* send to the printer */
                byte[] sequence = epl.ToPrinter;
                int    hresult;
                bool   result = clsDirectPrinting.SendByteArrayToPrinter(OSprintername, label.Name, sequence, out hresult);
                /* evaluate the result */
                if (result)
                {
                    return(true);
                }
                else
                {
                    throw new Exception(String.Format("An error occurred whilst sending the print job \"{0}\" to the device \"{1}\".", label.Name, OSprintername));
                }
            }
            catch (Exception ex)
            {
                /* some error */
                throw new Exception(String.Format("An error occurred whilst preparing the print job \"{0}\".", label.Name), ex);
            }
        }