/// <summary>
		/// Returns Image with <paramref name="str"/> drawn wrapped to given <paramref name="width"/>.
		/// </summary>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="width">Width that string will be wrapped to.</param>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> used to draw the <see cref="string"/>. </param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> used to draw the <see cref="string"/>. </param>
		/// <returns><see cref="Image"/> with given <paramref name="str"/> drawn.</returns>
		public Image DrawWrappedString(string str, float width,
		                               CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph)
		{
			float height = GetWrappedHeight(DummyGraphics, str, fmtCharacter, width);
			ParagraphFormat pf2 = fmtParagraph.ShallowCopy();
			pf2.MultiLine = true;
			pf2.ShowIncompleteLines = true;
			pf2.VerticalAlignment = ParagraphVerticalAlignment.Top;
			return DrawStringInRectangle(str, new SizeF(width, height), fmtCharacter, fmtParagraph);
		}
		/// <summary>
		/// Draws string with given character format at given <paramref name="pnt"/>.
		/// </summary>
		/// <param name="img"><see cref="Image"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="pnt">Top-left <see cref="Point"/> of the drawn string.</param>
		/// <param name="fmt"><see cref="CharacterFormat"/> used to draw the <see cref="string"/>. </param>
		/// <remarks>There's a problem while drawing strings using ClearType on transparent 
		/// background. Resulting text is going to look thick and jagged. If this applies to you, use
		/// rather Image DrawString(string, CharacterFormat) or 
		/// Image DrawStringInRectangle(string, SizeF, CharacterFormat, ParagraphFormat) where the 
		/// problem is corrected (at cost of a slight performance loss).</remarks>
		public void DrawString(Image img, string str, PointF pnt,
		                       CharacterFormat fmt)
		{
			Graphics gr = Graphics.FromImage(img);
			DrawString(gr, str, pnt, fmt);
			gr.Dispose();
		}
		/// <summary>
		/// Returns <see cref="Image"/> object with <paramref name="str"/> drawn.
		/// </summary>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="fmt"><see cref="CharacterFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <returns><see cref="Image"/> with given <paramref name="str"/> drawn. The image is sized
		/// just to fit the string.</returns>
		public Image DrawString(string str, CharacterFormat fmt)
		{
			/*Size size=Size.Ceiling(dummyGraphics.MeasureString(str, fmt.Font));
			Image res=new Bitmap(size.Width, size.Height);
			DrawString(res, str, new Point(0,0), fmt);
			return res;*/
			ParagraphFormat pf = new ParagraphFormat(ParagraphAlignment.Left, ParagraphVerticalAlignment.Top,
			                                         false, true, StringTrimming.None, null);
			SizeF sz = MeasureStringExactly(dummyGraphics, str, fmt, new ParagraphFormat(), true);
			sz.Width += 2*GetMeasureStringVerticalGap(dummyGraphics, fmt.Font);
			sz.Height += 2*GetMeasureStringHorizontalGap(dummyGraphics, fmt.Font);

			if ((fmt.Font.Style & FontStyle.Italic) != 0)
				sz.Width += 4;
			else
				sz.Width += 2;


			return DrawStringInRectangle(str, sz, fmt, pf);
		}
		/// <summary>
		/// Draws string with given formating and width at specified point.
		/// </summary>
		/// <param name="img"><see cref="Image"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="width">Width that string will be wrapped to.</param>
		/// <param name="ofs">Top-left point of the drawn string.</param>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> used to draw the <see cref="string"/>. </param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> used to draw the <see cref="string"/>. </param>
		public void DrawWrappedString(Image img, string str, PointF ofs, float width,
			CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph)
		{
			Graphics gr = Graphics.FromImage(img);
			DrawWrappedString(gr, str, ofs, width, fmtCharacter, fmtParagraph);
			gr.Dispose();
		}
		/// <summary>
		/// Draws string with given formating into given rectangle.
		/// </summary>
		/// <param name="img"><see cref="Image"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="rect"><see cref="Rectangle"/> that string is drawn into.</param>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <remarks>There's a problem while drawing strings using ClearType on transparent 
		/// background. Resulting text is going to look thick and jagged. If this applies to you, use
		/// rather Image DrawString(string, CharacterFormat) or 
		/// Image DrawStringInRectangle(string, SizeF, CharacterFormat, ParagraphFormat) where the 
		/// problem is corrected (at cost of a slight performance loss).</remarks>
		public void DrawStringInRectangle(Image img, string str, RectangleF rect,
		                                  CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph)
		{
			Graphics gr = Graphics.FromImage(img);
			DrawStringInRectangle(gr, str, rect, fmtCharacter, fmtParagraph);
			gr.Dispose();
		}
		/// <summary>
		/// Adds string with given format to the end of this formatted string.
		/// </summary>
		/// <param name="str"></param>
		/// <param name="fmt"></param>
		private void AddFormattedPiece(string str, CharacterFormat fmt)
		{
			//No reason for storing empty pieces (and lots against it)
			if(str.Length==0)
				return;
			//Rotation is matter of global format, piece formats doesn't implement
			//it (so it angle to be zero)
			Debug.Assert(fmt.Angle==0);
			m_strings.Add(str);
			m_formats.Add(fmt);
		}
		/// <summary>
		/// Returns <see cref="StringFormat"/> object that fits best to given <see cref="CharacterFormat"/>
		/// and <see cref="ParagraphFormat"/> objects.
		/// </summary>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> object</param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> object</param>
		/// <returns><see cref="StringFormat"/> object</returns>
		internal StringFormat GetStringFormat(CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph)
		{
			StringFormat sf = (StringFormat) StringFormat.GenericDefault.Clone();
			sf.Alignment = ParAl2StrAl(fmtParagraph.Alignment);
			sf.LineAlignment = ParVertAl2StrAl(fmtParagraph.VerticalAlignment);
			sf.HotkeyPrefix = fmtCharacter.HotkeyPrefix;
			sf.Trimming = fmtParagraph.Trimming;
			if (!fmtParagraph.ShowIncompleteLines)
				sf.FormatFlags |= StringFormatFlags.LineLimit;
			if (!fmtParagraph.MultiLine)
				sf.FormatFlags |= StringFormatFlags.NoWrap;
			return sf;
		}
		/// <summary>
		/// Draws string with given formating and width at specified point.
		/// </summary>
		/// <param name="gr"><see cref="Graphics"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="width">Width that string will be wrapped to.</param>
		/// <param name="ofs">Top-left point of the drawn string.</param>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> used to draw the <see cref="string"/>. </param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> used to draw the <see cref="string"/>. </param>
		public void DrawWrappedString(Graphics gr, string str, PointF ofs, float width,
			CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph)
		{
			float height=GetWrappedHeight(gr, str, fmtCharacter, width);
			ParagraphFormat pf2=fmtParagraph.ShallowCopy();
			pf2.MultiLine=true;
			pf2.ShowIncompleteLines=true;
			pf2.VerticalAlignment=ParagraphVerticalAlignment.Top;
			DrawStringInRectangle(gr, str, new RectangleF(ofs, 
				new SizeF(width, height)),fmtCharacter, fmtParagraph);
		}
		/// <summary>
		/// Draws string with given formating into given <paramref name="rectangle"/>.
		/// </summary>
		/// <param name="gr"><see cref="Graphics"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="rectangle"><see cref="Rectangle"/> that string is drawn into.</param>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> used to draw the <see cref="string"/>. </param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> used to draw the <see cref="string"/>. </param>
		public void DrawStringInRectangle(Graphics gr, string str, RectangleF rectangle,
		                                  CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph)
		{
			Matrix trOld = gr.Transform.Clone();
			gr.TranslateTransform(rectangle.X, rectangle.Y);
			gr.RotateTransform(fmtCharacter.Angle);
			gr.TranslateTransform(-rectangle.X, -rectangle.Y);

			if (fmtParagraph.BackgroundBrush != null)
				gr.FillRectangle(fmtParagraph.BackgroundBrush, rectangle);

			CharacterFormat cf = fmtCharacter.ShallowCopy();
			cf.Angle = 0;
			ParagraphFormat pf = fmtParagraph.ShallowCopy();
			pf.BackgroundBrush = null;

			if (fmtCharacter.Formatted)
			{
				SDUFormattedString fmts = new SDUFormattedString(str, cf);
				if (pf.MultiLine)
					fmts.WrapLines(gr, rectangle.Width);
				fmts.DrawStringInRectangle(gr, rectangle, pf);
			}
			else if (fmtCharacter.FilledBounds)
				gr.FillRectangle(fmtCharacter.Brush, rectangle);
			else
			{
				if (fmtParagraph.Alignment == ParagraphAlignment.Full && fmtParagraph.MultiLine && rectangle.Width > 0)
				{
					DrawFullAlignedStringInRectangle(gr, str, rectangle, cf, fmtParagraph);
				}
				else
				{
					StringFormat sf = GetStringFormat(fmtCharacter, fmtParagraph);

					gr.DrawString(str, fmtCharacter.Font, fmtCharacter.Brush, rectangle, sf);

				}
			}

			gr.Transform = trOld;

		}
Exemple #10
0
		/// <summary>
		/// Returns height of the text when wrapping to given <paramref name="width"/> is performed.
		/// </summary>
		/// <param name="gr">Graphics object used for measurement.</param>
		/// <param name="str">String to be measured.</param>
		/// <param name="cf"><see cref="CharacterFormat"/> of given string.</param>
		/// <param name="width">Maximum width of resulting text.</param>
		/// <returns>Returns height of the text when wrapping to given <paramref name="width"/> 
		/// is performed.</returns>
		public float GetWrappedHeight(Graphics gr, string str, CharacterFormat cf, float width)
		{
			CharacterFormat cf2=cf.ShallowCopy();
			cf2.Angle=0;
			SDUFormattedString fmts = new SDUFormattedString(str, cf);
			fmts.WrapLines(gr, width);
			return fmts.GetTotalHeight(gr);

		}
Exemple #11
0
		/// <summary>
		/// Returns (more or less) exact size of given string.
		/// </summary>
		/// <param name="gr">Graphics where the size should be measured.</param>
		/// <param name="str">String to be measured.</param>
		/// <param name="cf">CharacterFormat of the string.</param>
		/// <param name="pf">ParagraphFormat of the string.</param>
		/// <param name="includeTrailingSpaces">Specifies whether trailing 
		/// spaces should be included into measurement.</param>
		/// <returns>Returns size of given text at specified conditions.</returns>
		/// <remarks>
		/// Returned value is not affected by any gaps and inaccurancies which appear
		/// while using Graphics.MeasureString as we use Graphics.MeasureCharacterRanges.
		/// </remarks>
		public SizeF MeasureStringExactly(Graphics gr, string str, CharacterFormat cf, ParagraphFormat pf,
		                                  bool includeTrailingSpaces)
		{
			StringFormat sf = GetStringFormat(cf, pf);

			if (includeTrailingSpaces)
				sf.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;


			sf.SetMeasurableCharacterRanges(new CharacterRange[] {new CharacterRange(0, str.Length)});
			sf.FormatFlags |= StringFormatFlags.NoWrap;

			SizeF bound = gr.MeasureString(str, (cf).Font, 0, sf);
			bound.Width += 10;
			bound.Height += 10;
			RectangleF rect = new RectangleF(new PointF(0, 0), bound);

			//RectangleF rect=new RectangleF(0,0,0,0);

			bool useOriginalGraphics = gr.DpiX != dummyGraphics.DpiX ||
				gr.DpiY != dummyGraphics.DpiY ||
				gr.PageScale != dummyGraphics.PageScale ||
				gr.PageUnit != dummyGraphics.PageUnit;

			Region[] rgn;

			if (useOriginalGraphics)
				rgn = gr.MeasureCharacterRanges(str, cf.Font, rect, sf);
			else
				rgn = dummyGraphics.MeasureCharacterRanges(str, cf.Font, rect, sf);

			sf.Dispose();

			SizeF size;

			if (useOriginalGraphics)
				size = rgn[0].GetBounds(gr).Size;
			else
				size = rgn[0].GetBounds(dummyGraphics).Size;

			rgn[0].Dispose();

			return size;
		}
Exemple #12
0
		/// <summary>
		/// Draws full aligned string into given rectangle.
		/// </summary>
		/// <param name="gr"><see cref="Graphics"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="rect"><see cref="Rectangle"/> that string is drawn into.</param>
		/// <param name="cf"><see cref="CharacterFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <param name="pf"><see cref="ParagraphFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <remarks>As this method isn't to be exposed as public, there are 
		/// several limitations:<br/>
		/// <see cref="Rectangle.Width"/> has to be non-zero.<br/>
		/// <see cref="CharacterFormat.Angle"/> has to be zero.<br/>
		/// <see cref="ParagraphFormat.MultiLine"/> has to be false.<br/>
		/// <see cref="ParagraphFormat.Alignment"/> has to be <see cref="ParagraphAlignment.Full"/>.<br/>
		/// <see cref="ParagraphFormat.BackgroundBrush"/> has to be null.<br/>
		/// If not satisfied, results might be not as expected.</remarks>
		private void DrawFullAlignedStringInRectangle(Graphics gr, string str, RectangleF rect,
		                                              CharacterFormat cf, ParagraphFormat pf)
		{
			Region oldClip = gr.Clip.Clone();
			gr.IntersectClip(rect);

			float yofs = rect.Y;

			StringFormat sfLeft; //StringFormat for drawing left-aligned lines
			{
				ParagraphFormat pf2 = pf.ShallowCopy();
				pf2.Alignment = ParagraphAlignment.Left;
				pf2.VerticalAlignment = ParagraphVerticalAlignment.Top;
				pf2.MultiLine = false;
				pf2.ShowIncompleteLines = true;
				sfLeft = GetStringFormat(cf, pf2);
			}


			//lineHeight & borders retrieving
			float lineHeight = GetLineHeight(gr, cf.Font);

			int lineCount;

			//lineCount retrieving
			{
				StringFormat sf = GetStringFormat(cf, pf);
				int charfit;
				gr.MeasureString(str, cf.Font, new SizeF(rect.Width, rect.Height), sf,
				                 out charfit, out lineCount);
			}


			//VerticalAlignment business
			switch (pf.VerticalAlignment)
			{
				case ParagraphVerticalAlignment.Bottom:
					yofs += rect.Height - lineHeight*lineCount;
					break;
				case ParagraphVerticalAlignment.Center:
					yofs += (rect.Height - lineHeight*lineCount)/2;
					break;
			}


			int flc = 0; //first line character
			int llc = flc; //last line character (actually the one after last)
			int lineIndex = 0;
			while (lineIndex < lineCount - 1 && flc < str.Length)
			{
				lineIndex++;

				llc = flc;

				//add spaces at the beginneing
				while (llc < str.Length && Char.IsWhiteSpace(str, llc))
					llc++;

				//add words until the line is full
				int pllc = llc; //potential last line character
				while (llc == pllc && llc < str.Length)
				{
					pllc++;
					while (pllc < str.Length && !Char.IsWhiteSpace(str, pllc))
						pllc++;
					if (gr.MeasureString(str.Substring(flc, pllc - flc), cf.Font).Width < rect.Width)
						llc = pllc;
				}

				//If nothing was added before, add single characters (rect.Width is too small)
				if (llc == flc)
					do
					{ //always at least one character per line
						llc++;
					} while (llc < str.Length && gr.MeasureString(str.Substring(flc, llc - flc + 1), cf.Font).Width < rect.Width);

				string line = str.Substring(flc, llc - flc);

				//Newline fotmatting
				int nlindex = line.IndexOf('\n');
				if (nlindex >= 0)
				{
					//Newline may be just "\n" or "\r\n"
					if (nlindex > 1 && line[nlindex - 1] == '\r')
						line = line.Substring(0, nlindex - 1);
					else
						line = line.Substring(0, nlindex);

					DrawString(gr, line, new PointF(rect.X, yofs), cf);

					flc += nlindex + 1;
				}
				else
				{
					DrawFullAlignedLine(gr, line, new PointF(rect.X, yofs), rect.Width, cf);

					flc = llc;
					//skip spaces at the end of line (just like Graphics.DrawString does)
					while (flc < str.Length && Char.IsWhiteSpace(str, flc))
						flc++;
				}

				yofs += lineHeight;

			}

			//And here comes the last line - it's always drawn left-aligned
			//(also, we have to get rid of newlines or they will sometimes show
			//in the bottom)

			gr.DrawString(str.Substring(flc), cf.Font, cf.Brush,
			              new RectangleF(rect.X, yofs, rect.Width, lineHeight), sfLeft);

			//Set back the original clipping region
			gr.Clip = oldClip;

		}
Exemple #13
0
		/// <summary>
		/// Draws one full aligned line of text (ie. spaces are expanded to fill 
		/// exactly the given <paramref name="width"/>.
		/// </summary>
		/// <param name="gr"><see cref="Graphics"/> object to draw into.</param>
		/// <param name="line"><see cref="string"/> that is to be drawn.</param>
		/// <param name="pnt">Top-left <see cref="Point"/> of the line.</param>
		/// <param name="width">Width of the line.</param>
		/// <param name="cf"><see cref="CharacterFormat"/> used to draw the line. <br/>
		/// </param>
		/// <remarks>As this method isn't to be exposed as public, there are 
		/// several limitations:<br/>
		/// <see cref="CharacterFormat.Angle"/> has to be zero.<br/>
		/// Given string has to fit into given width. <br/>
		/// If not satisfied, results might be not as expected.</remarks>
		private void DrawFullAlignedLine(Graphics gr, string line, PointF pnt, float width,
		                                 CharacterFormat cf)
		{
			if (line.Length == 0)
				return;
			int whtcnt = 0; //count of white spaces
			for (int i = 0; i < line.Length; i++)
				if (Char.IsWhiteSpace(line, i))
					whtcnt++;

			if (whtcnt == 0)
				DrawString(gr, line, pnt, cf);
			else
			{
				float lnowhtwidth = 0; //width of line without white spaces
				int fwc = 0; //first word character
				for (int i = 0; i < line.Length; i++)
				{
					if (Char.IsWhiteSpace(line, i))
					{
						if (i > 0 && !Char.IsWhiteSpace(line, i - 1))
							lnowhtwidth += gr.MeasureString(line.Substring(fwc, i - fwc), cf.Font).Width;
					}
					else if (i > 0 && Char.IsWhiteSpace(line, i - 1))
						fwc = i;
				}
				if (!Char.IsWhiteSpace(line, line.Length - 1))
					lnowhtwidth += gr.MeasureString(line.Substring(fwc), cf.Font).Width;


				float whtxofs = (width - lnowhtwidth)/whtcnt;
				float xofs = pnt.X;
				fwc = 0;
				for (int i = 0; i < line.Length; i++)
				{
					if (Char.IsWhiteSpace(line, i))
					{
						if (i > 0 && !Char.IsWhiteSpace(line, i - 1))
						{
							string word = line.Substring(fwc, i - fwc);
							DrawString(gr, word, new PointF(xofs, pnt.Y), cf);
							xofs += gr.MeasureString(word, cf.Font).Width;
						}
						xofs += whtxofs;

					}
					else if (i > 0 && Char.IsWhiteSpace(line, i - 1))
						fwc = i;
				}
				if (!Char.IsWhiteSpace(line, line.Length - 1))
					DrawString(gr, line.Substring(fwc), new PointF(xofs, pnt.Y), cf);
			}
		}
Exemple #14
0
		/// <summary>
		/// Returns an image with given string drawn. As in this method is not present the
		/// ClearType bug correction, it's only to be used with solid background brush.<br/>
		/// Merit of this method is that it can properly handle rotated text.
		/// </summary>
		private Image DrawSolidBackgroundStringInRectangle(string str, SizeF size,
		                                                   CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph, out PointF topLeftOffset)
		{
			float angle = fmtCharacter.Angle%360;
			float nAngle = (float) ((angle%90)*Math.PI/180); //normalized angle in RADIANS!
			PointF nOfs;
			SizeF nSize;
			if (nAngle == 0 || fmtCharacter.Angle == 0)
			{
				nOfs = new PointF(0, 0);
				nSize = size;
			}
			else
			{
				nOfs = new PointF((float) Math.Sin(nAngle)*size.Height, 0);
				nSize = new SizeF(
					(float) (Math.Cos(nAngle)*size.Width + Math.Sin(nAngle)*size.Height),
					(float) (Math.Sin(nAngle)*size.Width + Math.Cos(nAngle)*size.Height));
			}

			PointF rOfs; //Rotated top-left point
			SizeF rSize; //Rotated size
			if (angle < 90f)
			{
				rSize = nSize;
				rOfs = nOfs;
			}
			else if (angle < 180f)
			{
				rSize = new SizeF(nSize.Height, nSize.Width); //yes, width=height and height=width
				rOfs = new PointF(rSize.Width, nOfs.X);
			}
			else if (angle < 270f)
			{
				rSize = nSize;
				rOfs = new PointF(rSize.Width - nOfs.X, rSize.Height);
			}
			else
			{
				rSize = new SizeF(nSize.Height, nSize.Width); //yes, width=height and height=width
				rOfs = new PointF(0, rSize.Height - nOfs.X);
			}

			topLeftOffset = rOfs;

			Bitmap res = new Bitmap(Size.Ceiling(rSize).Width, Size.Ceiling(rSize).Height);

			Graphics gr = Graphics.FromImage(res);
			DrawStringInRectangle(gr, str, new RectangleF(rOfs, size), fmtCharacter, fmtParagraph);
			gr.Dispose();
			return res;
		}
Exemple #15
0
		/// <summary>
		/// Returns Image with <paramref name="str"/> drawn into rectangle of given size.
		/// </summary>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="size">Size of rectangle string will be drawn into and also of the 
		/// returned image.</param>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <param name="topLeftOffset">Out parameter which receives top-left point of the rotated string. </param>
		/// <returns><see cref="Image"/> with given <paramref name="str"/> drawn.</returns>
		public Image DrawStringInRectangle(string str, SizeF size,
		                                   CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph,
		                                   out PointF topLeftOffset)
		{
			//Prepare mask
			CharacterFormat mcf = fmtCharacter.ShallowCopy();
			ParagraphFormat mpf = fmtParagraph.ShallowCopy();
			mcf.Brush = new SolidBrush(Color.Black);
			mpf.BackgroundBrush = new SolidBrush(Color.White);
			mcf.IgnoreColorFormatting = true;
			Bitmap bMask = (Bitmap) DrawSolidBackgroundStringInRectangle(str, size, mcf,
			                                                             mpf, out topLeftOffset);

			//Prepare foreground
			CharacterFormat fgcf = fmtCharacter.ShallowCopy();
			ParagraphFormat fgpf = fmtParagraph.ShallowCopy();
			fgcf.FilledBounds = true;
			fgpf.BackgroundBrush = null;

			Bitmap bFg = (Bitmap) DrawSolidBackgroundStringInRectangle(str, size, fgcf,
			                                                           fgpf, out topLeftOffset);

			//And blend it together
			CopyIntensityAsAlpha(bMask, bFg);

			bMask.Dispose();

			//Using background
			if (fmtParagraph.BackgroundBrush != null)
			{
				Bitmap bRes = new Bitmap(bFg.Width, bFg.Height);
				Graphics rsgr = Graphics.FromImage(bRes); //resulting bitmap's graphics


				if (fmtCharacter.Angle == 0)
					rsgr.FillRectangle(fmtParagraph.BackgroundBrush, 0, 0, size.Width, size.Height);
				else
				{
					Matrix trOld = rsgr.Transform.Clone();
					rsgr.TranslateTransform(topLeftOffset.X, topLeftOffset.Y);
					rsgr.RotateTransform(fmtCharacter.Angle);

					rsgr.FillRectangle(fmtParagraph.BackgroundBrush, 0, 0, size.Width, size.Height);

					rsgr.Transform = trOld;
				}

				rsgr.DrawImage(bFg, 0, 0);
				rsgr.Dispose();
				bFg.Dispose();
				return bRes;
			}
			else
			{
				return bFg;
			}
		}
Exemple #16
0
		/// <summary>
		/// Draws string with given character format and alignment at given <see cref="Point"/>.
		/// </summary>
		/// <param name="gr"><see cref="Graphics"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="pnt"><see cref="Point"/> where the string will be drawn.</param>
		/// <param name="fmt"><see cref="CharacterFormat"/> used to draw the <see cref="string"/>. </param>
		/// <param name="align">Specifies whether the <paramref name="pnt"/> is at left, right 
		/// or in the center of the string. (<see cref="ParagraphAlignment.Full"/> means the same
		/// as <see cref="ParagraphAlignment.Left"/>.)</param>
		public void DrawString(Graphics gr, string str, PointF pnt,
		                       CharacterFormat fmt, ParagraphAlignment align)
		{
			StringFormat sf = (StringFormat) StringFormat.GenericDefault.Clone();
			sf.Alignment = ParAl2StrAl(align);
			sf.HotkeyPrefix = fmt.HotkeyPrefix;

			Matrix trOld = null;
			if (fmt.Angle != 0)
			{
				trOld = gr.Transform.Clone();
				gr.TranslateTransform(pnt.X, pnt.Y);
				gr.RotateTransform(fmt.Angle);
				gr.TranslateTransform(-pnt.X, -pnt.Y);
			}

			if (fmt.Formatted)
			{
				CharacterFormat cf = fmt.ShallowCopy();
				cf.Angle = 0;
				SDUFormattedString fs = new SDUFormattedString(str, cf);
				SizeF sz = fs.Measure(gr, true);
				sz.Height += GetMeasureStringVerticalGap(gr, cf.Font);

				PointF ofs = pnt;
				switch (align)
				{
					case ParagraphAlignment.Right:
						ofs.X -= sz.Width;
						break;
					case ParagraphAlignment.Center:
						ofs.X -= sz.Width/2;
						break;
				}

				ParagraphFormat pf = new ParagraphFormat();
				pf.MultiLine = false;
				pf.Alignment = align;
				fs.DrawStringInRectangle(gr, new RectangleF(ofs, sz), pf);


			}
			else if (fmt.FilledBounds)
			{
				ParagraphFormat pf = new ParagraphFormat();
				//pf.Alignment=align;
				SizeF sz = MeasureStringExactly(gr, str, fmt, pf, false);

				sz.Width += GetMeasureStringHorizontalGap(gr, fmt.Font);
				pnt.X += GetMeasureStringHorizontalGap(gr, fmt.Font)/2;
				pnt.Y += GetMeasureStringVerticalGap(gr, fmt.Font);

				gr.FillRectangle(fmt.Brush, new RectangleF(pnt, sz));
			}
			else
				gr.DrawString(str, fmt.Font, fmt.Brush, pnt, sf);

			if (trOld != null)
				gr.Transform = trOld;
		}
Exemple #17
0
		/// <summary>
		/// Paint the node text
		/// </summary>
		/// <param name="oNode"></param>
		/// <param name="oGraphics"></param>
		/// <param name="nX"></param>
		/// <param name="nY"></param>		
		private void PaintNodeText(Node oNode, Graphics oGraphics, int nX, int nY, 
			ref Hashtable m_mapRectToItemCheck, ref Hashtable m_mapItemCheckToRect)
		{
			int nAlpha = oNode.TreeView.GetNodeAlpha(oNode);
			Font oFont = oNode.GetFont();

			if (oNode.Flash == true)
				nAlpha = 255;

			//if (oNode.GetShowPlusMinus() == false)
			//	nX -= 15;
			
			SizeF oTextSize = oGraphics.MeasureString(oNode.GetText(), oNode.GetFont(), oNode.GetTreeView().GetDrawWidth() - nX - 8);
			if (m_oTreeView.Multiline == false)
				oTextSize = oGraphics.MeasureString(oNode.GetText(), oFont);

			oNode.Top = nY + (int)oTextSize.Height + 2;

			int nTextWidth = (int)oTextSize.Width;
			oNode.TextWidth = nTextWidth;

			if (oTextSize.Height == 0)
			{
				oTextSize.Height = oNode.GetFont().Height;
			}
			
			// draw check boxes
			if (oNode.GetCheckBoxes() == true && oNode.CheckBoxVisible == true)
			{												
				Pen oPen = null;		
			
				if (oNode.Flash == true)
					nAlpha = 255;

				#region draw check background
				if (oNode.GetCheckBackColor() != Color.Transparent)
				{
					if (oNode.Parent == null || oNode.Parent.SubNodesCheckExclusive == false)
					{
						Rectangle rectCheckBack = new Rectangle(nX + 4, nY + 2, 11, 11);
						Color backColor = Color.FromArgb(nAlpha, oNode.GetCheckBackColor());

						Brush brush = new SolidBrush(backColor);

						if (oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.XP)
						{					
							Color fadeColor = oNode.GetCheckBackColor();
							if (fadeColor == Color.White)
								fadeColor = Color.LightGray;

							brush = new LinearGradientBrush
								(
								rectCheckBack,
								Color.FromArgb(nAlpha == 255 ? 255 : 48, fadeColor),
								Color.White,
								LinearGradientMode.ForwardDiagonal						
								);  
						}

						oGraphics.FillRectangle(brush, rectCheckBack);
						brush.Dispose();
						brush = null;
					}
					else
					{
						Rectangle rectCheckBack = new Rectangle(nX + 4, nY + 2, 11, 11);
						Color backColor = Color.FromArgb(nAlpha, oNode.GetCheckBackColor());

						Brush brush = new SolidBrush(backColor);

						if (oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.XP)
						{					
							Color fadeColor = oNode.GetCheckBackColor();
							if (fadeColor == Color.White)
								fadeColor = Color.LightGray;

							brush = new LinearGradientBrush
								(
								rectCheckBack,
								Color.FromArgb(nAlpha == 255 ? 255 : 48, fadeColor),
								Color.White,
								LinearGradientMode.ForwardDiagonal						
								);  
						}

						GraphicsPath path = new GraphicsPath();
						path.AddEllipse(nX + 4, nY + 2, 10, 10);
						Region region = new Region(path);
						
						oGraphics.Clip = region;
						oGraphics.FillRectangle(brush, rectCheckBack);
						oGraphics.Clip = new Region(new Rectangle(0, 0, m_oTreeView.Width, m_oTreeView.Height));

						brush.Dispose();
						brush = null;
					}
				}
				#endregion

				oPen = new Pen(Color.FromArgb(nAlpha, oNode.GetCheckBorderColor()), 1);																	
				Rectangle rectCheck = new Rectangle(nX + 3, nY + 1, 12, 12);

				#region draw check rectangle

				if (oNode.Parent == null || oNode.Parent.SubNodesCheckExclusive == false)
				{
					if (oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.Solid || oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.XP)
						oGraphics.DrawRectangle(oPen, rectCheck);

					if (oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.Dot)
					{
						oPen.DashStyle = DashStyle.Dot;
						oGraphics.DrawRectangle(oPen, rectCheck);
					}
				}
				else
				{
					if (oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.Dot)					
						oPen.DashStyle = DashStyle.Dot;

					if (oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.Solid || oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.XP
						|| oNode.GetCheckBorderStyle() == CheckBoxBorderStyle.Dot)
						oGraphics.DrawEllipse(oPen, nX + 4, nY + 2, 10, 10);
				}

				oPen.DashStyle = DashStyle.Solid;
				#endregion

				m_mapItemCheckToRect.Add(oNode, rectCheck);
				m_mapRectToItemCheck.Add(rectCheck, oNode);

				if (oNode.Checked == true)
				{
					if (oNode.Parent == null || oNode.Parent.SubNodesCheckExclusive == false)
					{
						oPen.Color = Color.FromArgb(nAlpha, oNode.GetCheckCheckColor());
					
						oGraphics.DrawLine(oPen, nX + 6, nY + 6, nX + 6, nY + 8);
						oGraphics.DrawLine(oPen, nX + 7, nY + 7, nX + 7, nY + 9);
						oGraphics.DrawLine(oPen, nX + 8, nY + 8, nX + 8, nY + 10);
						oGraphics.DrawLine(oPen, nX + 9, nY + 7, nX + 9, nY + 9);
						oGraphics.DrawLine(oPen, nX + 10, nY + 6, nX + 10, nY + 8);
						oGraphics.DrawLine(oPen, nX + 11, nY + 5, nX + 11, nY + 7);
						oGraphics.DrawLine(oPen, nX + 12, nY + 4, nX + 12, nY + 6);
					}
					else
					{
						oPen.Color = Color.FromArgb(nAlpha, oNode.GetCheckCheckColor());

						oGraphics.DrawEllipse(oPen, nX + 6, nY + 4, 6, 6);
						oGraphics.DrawEllipse(oPen, nX + 7, nY + 5, 4, 4);
						oGraphics.DrawEllipse(oPen, nX + 8, nY + 6, 2, 2);						
						oGraphics.DrawEllipse(oPen, nX + 9, nY + 7, 1, 1);
						oGraphics.DrawRectangle(oPen, nX + 8, nY + 6, 2, 2);
					}
				}

				oPen.Dispose();

				nX += 17;
			}

			// paint the picture first if needed then draw the text
			if (oNode.Image != null)
			{								
				oGraphics.DrawImage(oNode.Image, 
					nX + 4, 
					nY + (int)(oTextSize.Height / 2.0) - (int)((float)oNode.Image.Height / 2.0) + 1,
					oNode.Image.Width, oNode.Image.Height);

				nX += oNode.Image.Width + 2;
			}
			else
			{
				if (oNode.ImageIndex != -1 && oNode.TreeView.ImageList != null 
					&& oNode.ImageIndex < oNode.TreeView.ImageList.Images.Count)
				{					
					oNode.TreeView.ImageList.Draw(oGraphics, nX + 2, 
						nY + (int)(oTextSize.Height / 2.0) - (int)((float)oNode.TreeView.ImageList.ImageSize.Height / 2.0), 
						oNode.TreeView.ImageList.ImageSize.Width,
						oNode.TreeView.ImageList.ImageSize.Height,
						oNode.ImageIndex);

					nX += oNode.TreeView.ImageList.ImageSize.Width;
				}
			}

			// get the right side of the text. if it is more far away than the width of the TreeView, truncate the text
			string sText = oNode.GetText();

			// render the text
			SolidBrush oTextBrush = new SolidBrush(Color.FromArgb(nAlpha, oNode.GetForeColor()));						

			// when draging the mouse over nodes, test if the node is being highlighted
			if (oNode == oNode.TreeView.HighlightedNode)
				oTextBrush.Color = oNode.GetHighlightedForeColor();

			Rectangle textRect = new Rectangle(nX + 2, nY, oNode.GetTreeView().GetDrawWidth() - nX - 15, 
				(int)oNode.GetTreeView().Height);

			SizeF textSize = oGraphics.MeasureString(StringDrawUtils.GetInstance().GetTextFromFormattedString(sText), oFont, 
				oNode.GetTreeView().GetDrawWidth() - nX - 15);			

			// clear the truncated flag
			oNode.TextTruncated = false;
 
			if (m_oTreeView.Multiline)
			{
				if (oNode.UseFormatting == true)
				{
					CharacterFormat chrFormat = new CharacterFormat(
						oFont, 
						oTextBrush, 
						0, 
						HotkeyPrefix.None, 
						true);

					ParagraphFormat paraFormat = new ParagraphFormat(
						ParagraphAlignment.Left, 
						ParagraphVerticalAlignment.Top, 
						true, 
						true, 
						StringTrimming.None, 
						Brushes.Transparent);

					StringDrawUtils.GetInstance().DrawStringInRectangle(oGraphics, sText, textRect, 
						chrFormat, paraFormat);
				}
				else
					oGraphics.DrawString(sText, oFont, oTextBrush, textRect);
			}
			else
			{
				sText = oNode.GetText();

				oTextSize = oGraphics.MeasureString(StringDrawUtils.GetInstance().GetTextFromFormattedString(sText), oFont);
				nTextWidth = (int)oTextSize.Width;

				if (nX + 2 + nTextWidth > m_oTreeView.m_LastNX)
					m_oTreeView.m_LastNX = nX + 2 + nTextWidth;

				if (nX + nTextWidth > oNode.GetTreeView().GetDrawWidth() - 15)
				{
					sText = StringDrawUtils.GetInstance().GetTextFromFormattedString(sText);

					float fChar = oTextSize.Width / float.Parse(sText.Length.ToString());

					int nChar = (int)((float)(nX + nTextWidth - oNode.GetTreeView().GetDrawWidth() + 15) / fChar) + 4;

					if (nChar < 0)
						nChar = 0;

					int nLength = sText.Length - nChar;
					if (nLength < 0)
						nLength = 0;

					sText = sText.Substring(0, nLength) + "...";
					oNode.TextTruncated = true;
				}
				
				// draw string (text) of the node in the proper system, based on the information whether it has formatting or not
				if (oNode.UseFormatting == true)
				{
					CharacterFormat chrFormat = new CharacterFormat(
						oFont, 
						oTextBrush, 
						0, 
						HotkeyPrefix.None, 
						true);

					StringDrawUtils.GetInstance().DrawString(oGraphics, sText,  new PointF(nX + 2, nY), 
						chrFormat, ParagraphAlignment.Left);
				}
				else
					oGraphics.DrawString(sText, oFont, oTextBrush, nX + 2, nY);				
			}

			if (m_oTreeView.Multiline == false)
				textSize = oGraphics.MeasureString(StringDrawUtils.GetInstance().GetTextFromFormattedString(sText), oFont);

			oTextBrush.Dispose();			

			// create the expand icon if specified
			if (oNode.GetShowSubitemsIndicator() == true && oNode.Nodes.Count > 0 && oNode.IsExpanded == false)
			{	
				int nIconX = (int)textRect.Left + (int)textSize.Width + 4;

				Pen oIndicatorPen = new Pen(Color.FromArgb(nAlpha, oNode.GetForeColor()), 1);
				oGraphics.DrawLine(oIndicatorPen, nIconX, nY + textSize.Height - 4, nIconX + 3, nY + textSize.Height - 4);
				oGraphics.DrawLine(oIndicatorPen, nIconX + 1, nY + textSize.Height - 5, nIconX + 3, nY + textSize.Height - 5);
				oGraphics.DrawLine(oIndicatorPen, nIconX + 2, nY + textSize.Height - 6, nIconX + 3, nY + textSize.Height - 6);
				oGraphics.DrawLine(oIndicatorPen, nIconX + 3, nY + textSize.Height - 6, nIconX + 3, nY + textSize.Height - 7);
				oIndicatorPen.Dispose();
			}

			if (oNode.Underline == true)
				PaintNodeUnderline(oNode, sText, oGraphics, nX, nY);
		}
Exemple #18
0
		/// <summary>
		/// Draws string with given character format at given <see cref="Point"/>.
		/// </summary>
		/// <param name="gr"><see cref="Graphics"/> object to draw into.</param>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="pnt">Top-left <see cref="Point"/> of the drawn string.</param>
		/// <param name="fmt"><see cref="CharacterFormat"/> used to draw the <see cref="string"/>. </param>
		public void DrawString(Graphics gr, string str, PointF pnt,
		                       CharacterFormat fmt)
		{
			DrawString(gr, str, pnt, fmt, ParagraphAlignment.Left);
		}
		/// <summary>
		/// Initializes a new SDUFormattedString object with given string and
		/// initial CharacterFormat.<br/>
		/// Format string definition is at documentation for 
		/// <see cref="CharacterFormat.Formatted"/> member.
		/// </summary>
		/// <param name="str"></param>
		/// <param name="initFmt"></param>
		public SDUFormattedString(string str, CharacterFormat initFmt)
		{
			if(sdu==null)
				sdu=StringDrawUtils.GetInstance();

			m_strings=new ArrayList();
			m_formats=new ArrayList();
			m_softbreaks=new Hashtable();
			m_initialFormat=initFmt;

			Debug.Assert(initFmt.Angle==0);

			CharacterFormat curfmt=initFmt.ShallowCopy();
			curfmt.Angle=0;
			curfmt.Formatted=false;

			if(!initFmt.Formatted)
			{
				AddFormattedPiece(str,curfmt);
			} 
			else
			{
				Stack brushes=new Stack();

				string curstr="";
				for (int i = 0; i < str.Length; i++)
				{
					if(str[i]!='#') 
						curstr+=str[i];
					else if(str[i+1]=='#') 
					{
						curstr+='#';
						i++;
					} 
					else 
					{ 
						if(curstr.Length>0)
						{
							AddFormattedPiece(curstr,curfmt);
							curstr="";
							curfmt=curfmt.ShallowCopy();
						}
						switch(str[i+1])
						{
							case 'C':
								if(str.Length > i + 2 && str[i+2]=='-')
								{
									if(!initFmt.IgnoreColorFormatting)
									{
										if(brushes.Count==0)
											throw new ArgumentException("Invalid format string","str");

										curfmt.Brush=(Brush) brushes.Pop();
									}
									i+=2;
								} 
								else if(str.Length > i + 7)
								{
									string colstr=str.Substring(i+2,6);
									if(colstr.Length<6)
										throw new ArgumentException("Invalid format string","str");
									int colint;
									try
									{
										colint=Int32.Parse(colstr,NumberStyles.HexNumber);
									} 
									catch(FormatException)
									{
										throw new ArgumentException("Invalid format string","str");
									}
									Color clr=Color.FromArgb( (255<<24) + colint );

									if(!initFmt.IgnoreColorFormatting) 
									{
										brushes.Push(curfmt.Brush);
										curfmt.Brush=new SolidBrush(clr);
									}
									i+=7;
								}
								break;
							case 'B':
							switch(str[i+2])
							{
								case '+':
									curfmt.Font=new Font(curfmt.Font,curfmt.Font.Style|FontStyle.Bold);
									break;
								case '-':
									curfmt.Font=new Font(curfmt.Font,curfmt.Font.Style & ~FontStyle.Bold);
									break;
								default:
									throw new ArgumentException("Invalid format string","str");
							}
								i+=2;
								break;
							case 'I':
							switch(str[i+2])
							{
								case '+':
									curfmt.Font=new Font(curfmt.Font,curfmt.Font.Style|FontStyle.Italic);
									break;
								case '-':
									curfmt.Font=new Font(curfmt.Font,curfmt.Font.Style & ~FontStyle.Italic);
									break;
								default:
									throw new ArgumentException("Invalid format string","str");
							}
								i+=2;
								break;
							case 'U':
							switch(str[i+2])
							{
								case '+':
									curfmt.Font=new Font(curfmt.Font,curfmt.Font.Style|FontStyle.Underline);
									break;
								case '-':
									curfmt.Font=new Font(curfmt.Font,curfmt.Font.Style & ~FontStyle.Underline);
									break;
								default:
									throw new ArgumentException("Invalid format string","str");
							}
								i+=2;
								break;
							default:
								throw new ArgumentException("Invalid format string","str");
						}
					}
				
				}
				if(curstr.Length>0)
					AddFormattedPiece(curstr,curfmt);
			}

		}
Exemple #20
0
		/// <summary>
		/// Returns Image with <paramref name="str"/> drawn into rectangle of given size.
		/// </summary>
		/// <param name="str"><see cref="string"/> to be drawn.</param>
		/// <param name="size">Size of rectangle string will be drawn into and also of the 
		/// returned image.</param>
		/// <param name="fmtCharacter"><see cref="CharacterFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <param name="fmtParagraph"><see cref="ParagraphFormat"/> used to draw the <paramref name="str"/>. </param>
		/// <returns><see cref="Image"/> with given <paramref name="str"/> drawn.</returns>
		public Image DrawStringInRectangle(string str, SizeF size,
		                                   CharacterFormat fmtCharacter, ParagraphFormat fmtParagraph)
		{
			PointF tmp;
			return DrawStringInRectangle(str, size, fmtCharacter, fmtParagraph, out tmp);
		}