290 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Text;
 | |
| using System.Drawing;
 | |
| using iTextSharp.text.pdf;
 | |
| using iTextSharp.text;
 | |
| using VEPROMS.CSLA.Library;
 | |
| 
 | |
| namespace Volian.Print.Library
 | |
| {
 | |
| 	public partial class vlnTab : vlnText
 | |
| 	{
 | |
| 		/// <summary>
 | |
| 		/// Used to Align Tabs for numeric tabs that can go to 2 digits
 | |
| 		/// </summary>
 | |
| 		private float? _TabAlign;
 | |
| 		public float TabAlign // Offset to Last printable character
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_TabAlign == null)
 | |
| 				{
 | |
| 					_TabAlign = 0;
 | |
| 					if (Text != null)
 | |
| 					{
 | |
| 						while (_TabAlign < Text.Length && Text[(int)_TabAlign] == ' ')
 | |
| 							_TabAlign++;
 | |
| 						if (_TabAlign < Text.Length)
 | |
| 						{
 | |
| 							if ("0123456789".Contains(Text[(int)_TabAlign].ToString()))
 | |
| 							{
 | |
| 								while ("0123456789".Contains(Text[(int)_TabAlign].ToString()))
 | |
| 									_TabAlign++;
 | |
| 								_TabAlign--;
 | |
| 							}
 | |
| 						}
 | |
| 						else
 | |
| 							_TabAlign = 0;
 | |
| 					}
 | |
| 				}
 | |
| 				return (float)_TabAlign * MyFont.CharsToTwips;
 | |
| 			}
 | |
| 		}
 | |
| 		private float? _TabOffset;
 | |
| 		public float TabOffset // Offset to first printable character
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				if (_TabOffset == null)
 | |
| 				{
 | |
| 					_TabOffset = 0;
 | |
| 					if (Text != null)
 | |
| 					{
 | |
| 						while (_TabOffset<Text.Length && Text[(int)_TabOffset] == ' ')
 | |
| 							_TabOffset++;
 | |
| 					}
 | |
| 				}
 | |
| 				if (_TabOffset >= Text.Length) _TabOffset = 0;
 | |
| 				return (float)_TabOffset * MyFont.CharsToTwips;
 | |
| 			}
 | |
| 		}
 | |
| 		private vlnMacro _MyMacro;
 | |
| 		public vlnMacro MyMacro
 | |
| 		{
 | |
| 			get { return _MyMacro; }
 | |
| 			set { _MyMacro = value; }
 | |
| 		}
 | |
| 
 | |
| 		private string symblsStr = "\u25CF\u0394"; // string of possible symbol character in a tab
 | |
| 											 // add symbol characters as needed
 | |
| 											 // "\u25CF" - solid bullet
 | |
| 											 // \x0394 - delta
 | |
| 
 | |
| 		private System.Drawing.FontStyle GetSysFontStyle(VE_Font f)
 | |
| 		{
 | |
| 			if (f.Style == E_Style.Italics)
 | |
| 				return System.Drawing.FontStyle.Italic;
 | |
| 			return FontStyle.Regular;
 | |
| 		}
 | |
| 		private float GetTextWidth(VE_Font vefont, string txt, string symblFontName)
 | |
| 		{
 | |
| 			System.Drawing.Font font = new System.Drawing.Font(vefont.Family, (float)vefont.Size, GetSysFontStyle(vefont));
 | |
| 			System.Drawing.Font symbFont = new System.Drawing.Font(symblFontName, (float)vefont.Size);
 | |
| 			iTextSharp.text.Font iFont = Volian.Svg.Library.VolianPdf.GetFont(font);
 | |
| 			iTextSharp.text.Font iSymblFont = Volian.Svg.Library.VolianPdf.GetFont(symbFont);
 | |
| 			float w = 0;
 | |
| 			foreach (char c in txt)
 | |
| 			{
 | |
| 				int idx = symblsStr.IndexOf(c);
 | |
| 				if (idx >= 0) // symbol character - use symbol font to find its width
 | |
| 					w += iSymblFont.BaseFont.GetWidthPointKerned(symblsStr[idx].ToString(), (float)vefont.Size);
 | |
| 				else
 | |
| 					w += iFont.BaseFont.GetWidthPointKerned(c.ToString(), (float)vefont.Size);
 | |
| 			}
 | |
| 			//float w = iFont.BaseFont.GetWidthPointKerned(Text.Replace("\u25CF","@"), (float)vefont.Size);
 | |
| 			return w;
 | |
| 		}
 | |
| 		bool _ScriptCaution = false;
 | |
| 
 | |
| 		public bool ScriptCaution
 | |
| 		{
 | |
| 			get { return _ScriptCaution; }
 | |
| 			set { _ScriptCaution = value; }
 | |
| 		}
 | |
| 		bool _SeparateBullet = false;
 | |
| 
 | |
| 		public bool SeparateBullet
 | |
| 		{
 | |
| 			get { return _SeparateBullet; }
 | |
| 			set { _SeparateBullet = value; }
 | |
| 		}
 | |
| 		public vlnTab(PdfContentByte cb, vlnParagraph myparent, string origTab, string cleanTab, float xoffset, float yoffset, VE_Font vFont, bool doSectTab, string symblFontName, bool removedUnderline)
 | |
| 		{
 | |
| 			ScriptCaution = (origTab.Contains("Caution") && vFont.Family == "VolianScript");
 | |
| 			MyContentByte = cb;
 | |
| 			MyParent = myparent;
 | |
| 			YOffset = yoffset;
 | |
| 			Text = cleanTab;
 | |
| 			MyFont = vFont;
 | |
| 			float CCCs = GetTextWidth(MyFont, "CCCCCCCCCC", symblFontName);
 | |
| 			float IIIs = GetTextWidth(MyFont, "iiiiiiiiii", symblFontName);
 | |
| 			string origTab1 = origTab;
 | |
| 			if (ScriptCaution)
 | |
| 			{
 | |
| 				Text = origTab.Replace("Caution  ", "\uF043\uF061\uF069\uF06E\uF06F\uF074\uF075\uF020\uF020");
 | |
| 				Width = 90;
 | |
| 			}
 | |
| 			else if ((myparent.MyItemInfo.FormatStepData != null) && (myparent.MyItemInfo.FormatStepData.TabData.IdentWidth ?? 0) > 0)
 | |
| 			//if ((myparent.MyItemInfo.FormatStepData != null) && (myparent.MyItemInfo.FormatStepData.TabData.IdentWidth ?? 0) > 0)
 | |
| 				Width = (float)myparent.MyItemInfo.FormatStepData.TabData.IdentWidth;
 | |
| 			else if (CCCs != IIIs)
 | |
| 			{
 | |
| 				if (myparent.MyItemInfo.ActiveFormat.Name.ToUpper().Contains("WST"))	// Temporary for WST development. need better way to do this check
 | |
| 				{
 | |
| 					Width = 6.8f * origTab.Length;
 | |
| 				}
 | |
| 				else if (myparent.MyItemInfo.ActiveFormat.Name.ToUpper().Contains("SHE"))	// Temporary for SHE development. need better way to do this check
 | |
| 				{
 | |
| 					if (myparent.MyItemInfo.IsHigh)
 | |
| 						Width = 6 * origTab.Length;
 | |
| 					else
 | |
| 						Width = GetTextWidth(MyFont, (Text != null ? Text : origTab), symblFontName); //MyFont.CharsToTwips * (Text != null ? Text.Length : origTab.Length);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					origTab1 = origTab1.TrimStart(" ".ToCharArray());
 | |
| 					// 6 = number of points per character.  4 characters between end of tab and beginning of text
 | |
| 					//   origTab1.Trim... is number of non-space characters of the tab string.
 | |
| 					// Tested for FPL & NSP
 | |
| 					Width = 6 * (4 + origTab1.Trim(" ".ToCharArray()).Length);
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 				Width = GetTextWidth(MyFont, (Text != null ? Text : origTab), symblFontName); //MyFont.CharsToTwips * (Text != null ? Text.Length : origTab.Length);
 | |
| 			if ((myparent.MyItemInfo.FormatStepData != null) && myparent.MyItemInfo.FormatStepData.TabData.Bullet.Separate)
 | |
| 				if (myparent.MyItemInfo.MyPrevious != null || myparent.MyItemInfo.NextItem != null)
 | |
| 					SeparateBullet = true;
 | |
| 			if (origTab.Contains(@"{!"))
 | |
| 			{
 | |
| 				int mindx = origTab.IndexOf(@"{!");
 | |
| 				int meindx = origTab.IndexOf(@"}", mindx);
 | |
| 				string macro = origTab.Substring(mindx, meindx - mindx + 1);
 | |
| 				// Width for placement of macro should be position in the string where the macro was located.
 | |
| 				float lwidth = MyFont.CharsToTwips * (origTab.Length - meindx - 1);
 | |
| 				MyMacro = new vlnMacro(xoffset - lwidth, yoffset, macro.Substring(2, macro.Length - 3));
 | |
| 
 | |
| 				origTab = origTab.Replace(macro, "");
 | |
| 				cleanTab = origTab;
 | |
| 				if (CCCs != IIIs)
 | |
| 				{
 | |
| 					origTab = origTab + " ";
 | |
| 					origTab = origTab.TrimStart(" ".ToCharArray());
 | |
| 					if (mindx>2) // ouch!
 | |
| 						Width = 6f * (origTab.Length - 1); // FPL (macro is after {numeric})  FPL is good with genmac output!
 | |
| 					else
 | |
| 						Width = 3 + (6f * origTab.Length); // NSP (macro is before {numeric})
 | |
| 				}
 | |
| 				else
 | |
| 					Width = GetTextWidth(MyFont, (cleanTab != null ? cleanTab : origTab), symblFontName);//MyFont.CharsToTwips * (cleanTab != null ? cleanTab.Length : origTab.Length);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				origTab = origTab1;
 | |
| 			}
 | |
| 
 | |
| 			// if this tab was underlined, we may need to add partial underlining back in, if it was
 | |
| 			// removed when the bullet was added. This handles the case where the bullet was appended 
 | |
| 			// to the tab, for example  "NOTE:  o".  
 | |
| 			if (removedUnderline)
 | |
| 			{
 | |
| 				int sep = origTab.IndexOfAny(". ".ToCharArray());
 | |
| 				origTab = @"\ul " + origTab.Substring(0, sep-1) + @"\ulnone" + origTab.Substring(sep-1);
 | |
| 			}
 | |
| 			// if this tab is underlined, the underlining should not underline the ':'. Check for "NOTE:"
 | |
| 			// or "CAUTION:", i.e. only underline up to ':'
 | |
| 			if (myparent.MyItemInfo.IsStep && ((myparent.MyItemInfo.FormatStepData.AlwaysTab || myparent.MyItemInfo.MyPrevious == null)
 | |
| 				&& ((vFont.Style & E_Style.Underline) > 0) && (origTab.ToUpper().Contains("NOTE:") ||
 | |
| 				origTab.ToUpper().Contains("CAUTION:"))))
 | |
| 			{
 | |
| 				FontStyle style = FontStyle.Regular;
 | |
| 				if ((vFont.Style & E_Style.Bold) > 0) style |= FontStyle.Bold;
 | |
| 				if ((vFont.Style & E_Style.Italics) > 0) style |= FontStyle.Italic;
 | |
| 				vFont.WindowsFont = new System.Drawing.Font(vFont.Family, (float)vFont.Size, style);
 | |
| 				int indxC = origTab.IndexOf(":");
 | |
| 				origTab = @"\ul " + origTab.Substring(0, indxC) + @"\ulnone" + origTab.Substring(indxC);
 | |
| 			}
 | |
| 
 | |
| 			Rtf = GetRtf(origTab, vFont);
 | |
| 			Rtf = Rtf.Replace("\u0394", @"\f1\u916?\f0 ");		// delta 0x0394
 | |
| 			if (ScriptCaution)
 | |
| 			{
 | |
| 			    Rtf = GetRtf("\u25CFCaution  ", vFont);
 | |
| 				Rtf = Rtf.Replace("\u25CF", @"\f1\fs20              \u9679?\f0\par\f0\fs64 ");		// bullet 25CF // jsj- force bullet size (is different than tab text)
 | |
| 				if (myparent.MyItemInfo.FormatStepData != null && !myparent.MyItemInfo.FormatStepData.AlwaysTab && myparent.MyItemInfo.MyPrevious != null)
 | |
| 					Rtf = Rtf.Replace("Caution  ", @"\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?");
 | |
| 				else
 | |
| 				{
 | |
| 					if (myparent.MyItemInfo.FormatStepData != null && !myparent.MyItemInfo.FormatStepData.AlwaysTab && myparent.MyItemInfo.NextItem == null)
 | |
| 						Rtf = Rtf.Replace(@"\u9679?", "");
 | |
| 					Rtf = Rtf.Replace("Caution  ", @"\u61507?\u61537?\u61557?\u61556?\u61545?\u61551?\u61550?\u61472?\u61472?");
 | |
| 				}
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				if (SeparateBullet)
 | |
| 					Rtf = Rtf.Replace("\u25CF", "");
 | |
| 				else
 | |
| 					Rtf = Rtf.Replace("\u25CF", @"\f1\u9679?\f0 ");		// bullet 25CF // jsj- add space after \f0
 | |
| 				//Rtf = Rtf.Replace("\u25CF", @"\f1\fs18\b0\i0        \u9679?\f0 ");		// bullet 25CF // jsj- add space after \f0
 | |
| 				if (myparent.MyItemInfo.FormatStepData != null && !myparent.MyItemInfo.FormatStepData.AlwaysTab && myparent.MyItemInfo.MyPrevious != null)
 | |
| 				{
 | |
| 					//if (scriptCaution)
 | |
| 					//    Rtf = Rtf.Replace("CAUTION  ", @"\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?\u61472?");
 | |
| 					Rtf = Rtf.Replace("Caution:", "        ");
 | |
| 					Rtf = Rtf.Replace("Note:", "     ");
 | |
| 					Rtf = Rtf.Replace("CAUTION:", "        ");
 | |
| 					Rtf = Rtf.Replace("NOTE:", "     ");
 | |
| 					Rtf = Rtf.Replace("Caution", "       ");
 | |
| 					Rtf = Rtf.Replace("Note", "    ");
 | |
| 					Rtf = Rtf.Replace("CAUTION", "       ");
 | |
| 					Rtf = Rtf.Replace("NOTE", "    ");
 | |
| 				}
 | |
| 			}
 | |
| 			//if (ScriptCaution && Rtf.Contains("Caution"))
 | |
| 			//{
 | |
| 			//    // NSP script caution
 | |
| 			//    iTextSharp.text.Font myfont = pdf.GetFont(vFont.Family, 28, 0, iTextSharp.text.Color.BLACK);
 | |
| 			//    if (!myfont.BaseFont.CharExists(0x43)) // Capital 'C' exists as text
 | |
| 			//    {
 | |
| 			//        //VE_Font vf = new VE_Font("VolianScript", 28, E_Style.Italics, 12);
 | |
| 			//        // Capital 'C' exists as Symbol
 | |
| 			//        Rtf = Rtf.Replace("Caution  ", @"\u61507?\u61537?\u61557?\u61556?\u61545?\u61551?\u61550?\u61472?\u61472?");
 | |
| 			//    }
 | |
| 
 | |
| 			//}
 | |
| 
 | |
| 
 | |
| 			// do positioning based on whether format has locations for section 'header'.  If it's not centered, treat
 | |
| 			// it's location more like a 'tab'.
 | |
| 			if (doSectTab)
 | |
| 			{
 | |
| 				XOffset = xoffset;
 | |
| 				// the width was just a little small, so it was wrapping - but only if there were no spaces at end
 | |
| 				// so use this condition to do minimal impact  (WCN1 format, for section tabs with three places, i.e. 6.1.2
 | |
| 				if (!cleanTab.EndsWith(" "))Width += .1f;  
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				//if (MyFont.Family == "Arial" && MyFont.Size == 14)
 | |
| 				//{
 | |
| 				//    System.Drawing.Font font = new System.Drawing.Font("Arial", 14);
 | |
| 				//    iTextSharp.text.Font iFont = Volian.Svg.Library.VolianPdf.GetFont(font);
 | |
| 				//    float w = iFont.BaseFont.GetWidthPointKerned(Text, 14);
 | |
| 				//    Width = w;
 | |
| 				//}
 | |
| 				XOffset = xoffset - Width;
 | |
| 			}
 | |
| 			
 | |
| 		}
 | |
| 		public override float ToPdf(PdfContentByte cb, float yPageStart, ref float yTopMargin, ref float yBottomMargin)
 | |
| 		{
 | |
| 			if (MyParent.MyItemInfo.FormatStepData != null && MyParent.MyItemInfo.FormatStepData.StepPrintData != null) 
 | |
| 				XOffset += (float)(MyParent.MyItemInfo.FormatStepData.StepPrintData.PosAdjust ?? 0);
 | |
| 			float yLocation = CalculateYOffset(yPageStart, yTopMargin);
 | |
| 			Rtf2Pdf.TextAt(cb, IParagraph, XOffset, yLocation, Width, 100, "", yBottomMargin);
 | |
| 			return yPageStart;
 | |
| 		}
 | |
| 	}
 | |
| }
 |