/// <summary>
        /// parses BarcodeItem. Indents are ignored(March 2007)
        /// </summary>
        /// <param name="barcode"></param>
        /// <returns>printer command for barcodeItem</returns>
        private StringBuilder ParseBarCodeItem(BarCodeItem barcode)
        {
            StringBuilder bcData = new StringBuilder();

            if (barcode.AlignmentSpecified)
            {
                bcData.Append(printer.Align(barcode.Alignment));
            }
            if (barcode.HeightSpecified)
            {
                bcData.Append(printer.BarCodeHeight(barcode.Height));
            }
            if (barcode.WidthSpecified)
            {
                bcData.Append(printer.BarCodeWidth(barcode.Width));
            }
            if (barcode.HRIPosSpecified)
            {
                bcData.Append(printer.BarCodeHRI(barcode.HRIPos));
            }
            if (barcode.FontSpecified)
            {
                bcData.Append(printer.BarCodeFont(barcode.Font));
            }

            if (barcode.TypeSpecified)
            {
                bcData.Append(printer.BarCode(barcode.Type, barcode.Value));
            }
            else
            {
                return(null);
            }
            bcData.Append(printer.Align(Alignment.Left));               //reset Alignment
            return(bcData);
        }
        private TextBlock ParseLine(Line line, double width, double margin)
        {
            double    newWidth = width - (margin);
            TextBlock tb       = new TextBlock()
            {
                Width = newWidth
            };

            tb.Margin = new Thickness(0, 0, 0, 0);
            if (line.Items == null || line.Items.Length <= 0)
            {
                return(null);
            }

            int numItems = 0;

            foreach (Object item in line.Items)
            {
                numItems++;
            }
            foreach (Object item in line.Items)
            {
                string text = "";
                numItems--;
                TextBlock tbItem = new TextBlock();
                if (item.GetType() == typeof(ImageItem))
                {
                    try
                    {
                        string fileName = ConfigurationManager.AppSettings["logoFile"]; //"Images/bs-logo.jpg"
                        //if (File.Exists("PrintLogo.jpg")) {
                        if (File.Exists(fileName))
                        {
                            BitmapImage btm;
                            using (MemoryStream ms = new MemoryStream(System.IO.File.ReadAllBytes(fileName)))
                            {
                                btm = new BitmapImage();
                                btm.BeginInit();
                                btm.StreamSource = ms;
                                // Below code for caching is crucial.
                                btm.CacheOption = BitmapCacheOption.OnLoad;
                                btm.EndInit();
                                btm.Freeze();
                            }

                            Image i = new Image();
                            i.Margin = new Thickness(0, 0, 4, 0);
                            //BitmapImage imageSource = new BitmapImage(new Uri(Path.GetFullPath(fileName)));
                            i.Source  = btm;
                            i.Stretch = Stretch.Fill;
                            tbItem.Inlines.Add(i);
                        }
                    }
                    catch (Exception ex)
                    {
                        Image i = new Image();
                        i.Stretch = Stretch.Fill;
                        tbItem.Inlines.Add(i);
                    }
                }
                else if (item.GetType() == typeof(BarCodeItem))
                {
                    BarCodeItem    bci = item as BarCodeItem;
                    BarCodeCreator bcc = new BarCodeCreator();
                    Canvas         c   = bcc.BarCode128(bci.Value);

                    tbItem.HorizontalAlignment = HorizontalAlignment.Center;
                    tbItem.TextAlignment       = TextAlignment.Center;
                    tbItem.Inlines.Add(c);
                }
                else if (item.GetType() == typeof(TextItem))
                {
                    TextItem txt = item as TextItem;

                    ParseTextFontStyle(txt, ref tbItem);
                    tbItem.Margin = new Thickness(0, 0, 0, 0);
                    Run run = new Run()
                    {
                        Text = txt.Value
                    };
                    if (line.UnderlineSpecified && line.Underline == true)
                    {
                        tbItem.Inlines.Add(new Underline(run));
                    }
                    else
                    {
                        tbItem.Inlines.Add(run);
                    }
                    text = txt.Value;
                }
                else if (item.GetType() == typeof(FillItem))
                {
                    string filltext = "";
                    for (int i = 0; i < 100; i++)
                    {
                        filltext += ((FillItem)item).Value;
                    }
                    tbItem.Inlines.Add(new Run()
                    {
                        FontSize   = 10,
                        FontFamily = new FontFamily("Arial"),
                        Text       = filltext
                    });
                }
                System.Drawing.FontStyle style = System.Drawing.FontStyle.Regular;
                if (tbItem.FontWeight == FontWeights.Bold)
                {
                    style = System.Drawing.FontStyle.Bold;
                }
                IEnumerator <string> enumerator = tbItem.FontFamily.FamilyNames.Values.GetEnumerator();
                enumerator.Reset();
                enumerator.MoveNext();
                int    fontsize = (int)tbItem.FontSize - 3;
                string val      = enumerator.Current;
                System.Drawing.Size textSize = System.Windows.Forms.TextRenderer.MeasureText(text, new System.Drawing.Font(
                                                                                                 new System.Drawing.FontFamily(val), fontsize, style));
                if (numItems > 0)
                {
                    newWidth    -= textSize.Width;
                    tbItem.Width = textSize.Width;
                }
                else
                {
                    if (newWidth < textSize.Width)
                    {
                        newWidth = width - margin;
                        tb.Inlines.Add(new Run()
                        {
                            Text = "\n"
                        });
                    }
                    tbItem.Width = newWidth;
                }

                tb.Inlines.Add(tbItem);
            }
            return(tb);
        }
        /// <summary>
        /// parses a Line, Lien can consist of (one or more) TextItem, FillItem, BarcodeItem or ImageItem
        /// </summary>
        /// <param name="line"></param>
        /// <returns>printer command for Line-part of SPF-object</returns>
        private StringBuilder ParseLine(Line line)
        {
            if (line.Items == null || line.Items.Length <= 0)
            {
                return(null);
            }

            StringBuilder lineData        = new StringBuilder();
            List <object> textAndFillItem = new List <object>();
            List <int>    textWidth       = new List <int>();
            int           txtWidthSum     = 0;
            int           numFillItems    = 0;

            int  recurrence = 0;
            bool underline  = false;

            if (line.RecurrenceSpecified)
            {
                recurrence = line.Recurrence;
            }
            if (line.UnderlineSpecified)
            {
                underline = line.Underline;
            }

            lineData.Append(printer.LineFeed());

            if (line.LineSpacingSpecified)
            {
                lineData.Append(printer.LineSpacing(line.LineSpacing));
            }
            else
            {
                lineData.Append(printer.LineSpacingDefault());
            }
            if (underline)
            {
                lineData.Append(printer.UnderlineOn());
            }


            foreach (Object item in line.Items)
            {
                if (item.GetType() == typeof(ImageItem))
                {
                    ImageItem image = item as ImageItem;
                    lineData.Append(ParseImageItem(image));
                }
                if (item.GetType() == typeof(BarCodeItem))
                {
                    BarCodeItem bc = item as BarCodeItem;
                    lineData.Append(ParseBarCodeItem(bc));
                    lineData.Append(printer.AbsoluteHorizontalPosition(0));
                }
                if (item.GetType() == typeof(TextItem))
                {
                    TextItem txt = item as TextItem;
                    ParseTextItem(txt);                 //set some properties oft txt TextItem
                    textAndFillItem.Add(txt);
                    //textWidth.Add(txt.TextWidth);
                    txtWidthSum += txt.TextWidth;
                    //lineData.Append(ParseTextItem(txt));
                }
                if (item.GetType() == typeof(FillItem))
                {
                    FillItem fill = item as FillItem;
                    textAndFillItem.Add(fill);
                    numFillItems++;
                    //lineData.Append(ParseFillItem(fill));
                }
            }

            #region Append printer command for text and fill items (stored in textAndFillItem List).
            // quite simple when there are no fill items (else condition). Mixed lists will be parsed until the first
            // textItem with special position (indent, align center|right), appended and this is repeated with the remaining list items.
            if (numFillItems > 0)
            {
                Font   fillFont = printer.DefaultFont; //fill font will be font of previous text item or defaultfont
                int    i = 0, old_i = 0, remain = textAndFillItem.Count;
                int    leftPosAfter = 0;               //!?
                double fullSpace    = 0.0;
                int    specialTextPosInd;
                int    fillWidth   = 0;
                int    unusedWidth = 0;         //should always be 0 except when mixing fonts or fontB with Indent

                do
                {                       //try to arragne mixture fo text and fill items
                    specialTextPosInd = textAndFillItem.GetRange(old_i, remain).FindIndex(IsSpecialPosTextItem) + old_i;
                    if (specialTextPosInd < 0)
                    {                                              //no special positioned text in line
                        specialTextPosInd = textAndFillItem.Count; //parse all
                        fullSpace         = printer.DotsPerLine - leftPosAfter;
                    }
                    else
                    {
                        int leftPosTmp = ((TextItem)textAndFillItem[specialTextPosInd]).LeftPos;
                        fullSpace    = leftPosTmp - leftPosAfter;
                        leftPosAfter = leftPosTmp + ((TextItem)textAndFillItem[specialTextPosInd]).TextWidth;
                        txtWidthSum  = 0;
                        foreach (object item in textAndFillItem.GetRange(old_i, specialTextPosInd - old_i).FindAll(IsTextItem))
                        {
                            txtWidthSum += ((TextItem)item).TextWidth;
                        }
                        numFillItems = textAndFillItem.GetRange(old_i, specialTextPosInd - old_i).FindAll(delegate(object o) { return(o.GetType() == typeof(FillItem)); }).Count;
                    }

                    float fillSpace = ((float)fullSpace - txtWidthSum) / numFillItems + unusedWidth;//standard fill
                    //foreach (object item in textAndFillItem) {
                    for (i = old_i; i <= specialTextPosInd && i < textAndFillItem.Count; i++)
                    {
                        if (textAndFillItem[i].GetType() == typeof(TextItem))
                        {
                            TextItem txtItem = textAndFillItem[i] as TextItem;
                            lineData.Append(txtItem.TextPrinterData);
                            if (txtItem.FontSpecified)
                            {
                                fillFont = txtItem.Font;
                            }
                        }
                        else if (textAndFillItem[i].GetType() == typeof(FillItem))
                        {
                            lineData.Append(ParseFillItem((FillItem)textAndFillItem[i], (int)fillSpace, fillFont, out fillWidth));
                            unusedWidth = (int)fillSpace - fillWidth;
                        }
                    }
                    //if fillWidth < fillSpace (due to FontB in special cases) filling is not 100% excat

                    old_i  = specialTextPosInd + 1;             //first not printed item
                    remain = textAndFillItem.Count - i;
                } while (specialTextPosInd < textAndFillItem.Count && remain > 0);
            }
            else
            {                           //no fillitems
                if (textAndFillItem != null)
                {
                    int leftPos = 0;
                    foreach (Object item in textAndFillItem)
                    {
                        if (item.GetType() == typeof(TextItem))
                        {  //must be
                            TextItem txtItem = item as TextItem;
                            if (txtItem.LeftPos > 0)
                            {
                                txtItem.LeftPos = LeftPosText(leftPos, txtItem);
                                lineData.Append(printer.AbsoluteHorizontalPosition(txtItem.LeftPos));
                            }
                            lineData.Append(txtItem.TextPrinterData);
                            leftPos += txtItem.LeftPos + txtItem.TextWidth;
                        }
                    }
                }

                if (underline)
                {               //only fillitem free lines have to be underlined 'manually'
                    lineData.Append(printer.AbsoluteHorizontalPosition(0));
                    lineData.Append(printer.CharacterFont(printer.DefaultFont));
                    for (int i = 0; i < printer.MaxTab - 1; i++)
                    {
                        lineData.Append(" ");
                    }
                }
            }
            #endregion

            if (underline)
            {
                lineData.Append(printer.UnderlineOff());
            }

            if (recurrence > 0)
            {
                StringBuilder manyLines = new StringBuilder(lineData.Length * recurrence);
                for (int j = 0; j < recurrence; j++)
                {
                    manyLines.Append(lineData);
                }
                lineData.Append(manyLines);
            }

            return(lineData);
        }