diff --git a/PDFsharp/code/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs b/PDFsharp/code/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs
index 70f6c8e..18627e6 100644
--- a/PDFsharp/code/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs
+++ b/PDFsharp/code/PdfSharp/PdfSharp.Drawing.Pdf/XGraphicsPdfRenderer.cs
@@ -415,9 +415,43 @@ public void DrawPath(XPen pen, XBrush brush, XGraphicsPath path)
// ----- DrawString ---------------------------------------------------------------------------
public void DrawString(string s, XFont font, XBrush brush, XRect rect, XStringFormat format)
- {
+ {
Realize(font, brush, 0);
+ // Handle XStringFormat TabStops
+ float firstTabOffset;
+ float[] tabs = format.GetTabStops(out firstTabOffset);
+ string[] sSplit = s.Split('\t');
+
+ if (tabs.Length > 0 && sSplit.Length > 1)
+ {
+ // Calculate absolute xOffset
+ float[] xOffset = new float[tabs.Length+1];
+ xOffset[0] = firstTabOffset;
+ for (int i = 0; i < tabs.Length; i++)
+ {
+ xOffset[i+1] = xOffset[i]+tabs[i];
+ }
+
+ // Draw each Tab-Part of the String as an individual-String on xOffset Position
+ for (int i = 0; i < sSplit.Length; i++)
+ {
+ XRect xRect = new XRect(rect.X, rect.Y, rect.Width, rect.Height);
+
+ if (i < xOffset.Length)
+ {
+ xRect.X += xOffset[i];
+ }
+ else
+ {
+ xRect.X += xOffset[xOffset.Length - 1];
+ }
+ DrawString(sSplit[i], font, brush, xRect, XStringFormats.TopLeft);
+ }
+ return;
+ }
+
+
double x = rect.X;
double y = rect.Y;
diff --git a/PDFsharp/code/PdfSharp/PdfSharp.Drawing/XStringFormat.cs b/PDFsharp/code/PdfSharp/PdfSharp.Drawing/XStringFormat.cs
index 93f75ea..cc35aa3 100644
--- a/PDFsharp/code/PdfSharp/PdfSharp.Drawing/XStringFormat.cs
+++ b/PDFsharp/code/PdfSharp/PdfSharp.Drawing/XStringFormat.cs
@@ -1,251 +1,275 @@
-#region PDFsharp - A .NET library for processing PDF
-//
-// Authors:
-// Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
-//
-// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
-//
-// http://www.pdfsharp.com
-// http://sourceforge.net/projects/pdfsharp
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-// DEALINGS IN THE SOFTWARE.
-#endregion
-
-using System;
-using System.IO;
-#if GDI
-using System.Drawing;
-using System.Drawing.Drawing2D;
-#endif
-#if WPF
-using System.Windows.Media;
-#endif
-using PdfSharp.Internal;
-
-namespace PdfSharp.Drawing
-{
- ///
- /// Not used in this implementation.
- ///
- [Flags]
- public enum XStringFormatFlags
- {
- //DirectionRightToLeft = 0x0001,
- //DirectionVertical = 0x0002,
- //FitBlackBox = 0x0004,
- //DisplayFormatControl = 0x0020,
- //NoFontFallback = 0x0400,
- ///
- /// The default value.
- ///
- MeasureTrailingSpaces = 0x0800,
- //NoWrap = 0x1000,
- //LineLimit = 0x2000,
- //NoClip = 0x4000,
- }
-
- ////public enum StringTrimming
- ////{
- //// None = 0,
- //// Character = 1,
- //// Word = 2,
- //// EllipsisCharacter = 3,
- //// EllipsisWord = 4,
- //// EllipsisPath = 5,
- ////}
-
- ///
- /// Represents the text layout information.
- ///
- public class XStringFormat
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public XStringFormat()
- {
-#if GDI
- // We must clone GenericTypographic, otherwise we change the original!
- this.stringFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
-#endif
- }
-
- //TODO public StringFormat(StringFormat format);
- //public StringFormat(StringFormatFlags options);
- //public StringFormat(StringFormatFlags options, int language);
- //public object Clone();
- //public void Dispose();
- //private void Dispose(bool disposing);
- //protected override void Finalize();
- //public float[] GetTabStops(out float firstTabOffset);
- //public void SetDigitSubstitution(int language, StringDigitSubstitute substitute);
- //public void SetMeasurableCharacterRanges(CharacterRange[] ranges);
- //public void SetTabStops(float firstTabOffset, float[] tabStops);
- //public override string ToString();
-
- ///
- /// Gets or sets horizontal text alignment information.
- ///
- public XStringAlignment Alignment
- {
- get {return this.alignment;}
- set
- {
- this.alignment = value;
-#if GDI
- this.stringFormat.Alignment = (StringAlignment)value;
-#endif
- }
- }
- XStringAlignment alignment;
-
- //public int DigitSubstitutionLanguage { get; }
- //public StringDigitSubstitute DigitSubstitutionMethod { get; }
- //public StringFormatFlags FormatFlags { get; set; }
- //public static StringFormat GenericDefault { get; }
- //public static StringFormat GenericTypographic { get; }
- //public HotkeyPrefix HotkeyPrefix { get; set; }
-
- ///
- /// Gets or sets the line alignment.
- ///
- public XLineAlignment LineAlignment
- {
- get {return this.lineAlignment;}
- set
- {
- this.lineAlignment = value;
-#if GDI
- if (value == XLineAlignment.BaseLine)
- this.stringFormat.LineAlignment = StringAlignment.Near;
- else
- this.stringFormat.LineAlignment = (StringAlignment)value;
-#endif
- }
- }
- XLineAlignment lineAlignment;
-
- //public StringTrimming Trimming { get; set; }
-
- ///
- /// Gets a new XStringFormat object that aligns the text left on the base line.
- ///
- [Obsolete("Use XStringFormats.Default. (Note plural in class name.)")]
- public static XStringFormat Default
- {
- get
- {
- XStringFormat format = new XStringFormat();
- format.LineAlignment = XLineAlignment.BaseLine;
- return format;
- }
- }
-
- ///
- /// Gets a new XStringFormat object that aligns the text top left of the layout rectangle.
- ///
- [Obsolete("Use XStringFormats.Default. (Note plural in class name.)")]
- public static XStringFormat TopLeft
- {
- get
- {
- XStringFormat format = new XStringFormat();
- format.Alignment = XStringAlignment.Near;
- format.LineAlignment = XLineAlignment.Near;
- return format;
- }
- }
-
- ///
- /// Gets a new XStringFormat object that centers the text in the middle of the layout rectangle.
- ///
- [Obsolete("Use XStringFormats.Center. (Note plural in class name.)")]
- public static XStringFormat Center
- {
- get
- {
- XStringFormat format = new XStringFormat();
- format.Alignment = XStringAlignment.Center;
- format.LineAlignment = XLineAlignment.Center;
- return format;
- }
- }
-
- ///
- /// Gets a new XStringFormat object that centers the text at the top of the layout rectangle.
- ///
- [Obsolete("Use XStringFormats.TopCenter. (Note plural in class name.)")]
- public static XStringFormat TopCenter
- {
- get
- {
- XStringFormat format = new XStringFormat();
- format.Alignment = XStringAlignment.Center;
- format.LineAlignment = XLineAlignment.Near;
- return format;
- }
- }
-
- ///
- /// Gets a new XStringFormat object that centers the text at the bottom of the layout rectangle.
- ///
- [Obsolete("Use XStringFormats.BottomCenter. (Note plural in class name.)")]
- public static XStringFormat BottomCenter
- {
- get
- {
- XStringFormat format = new XStringFormat();
- format.Alignment = XStringAlignment.Center;
- format.LineAlignment = XLineAlignment.Far;
- return format;
- }
- }
-
- ///
- /// Gets or sets flags with format information.
- ///
- public XStringFormatFlags FormatFlags
- {
- get {return this.formatFlags;}
- set
- {
- this.formatFlags = value;
-#if GDI
- this.stringFormat.FormatFlags = (StringFormatFlags)value;
-#endif
- }
- }
- private XStringFormatFlags formatFlags;
-
-#if GDI
- internal StringFormat RealizeGdiStringFormat()
- {
- if (this.stringFormat == null)
- {
- this.stringFormat = StringFormat.GenericTypographic; //.GenericDefault;
- this.stringFormat.Alignment = (StringAlignment)this.alignment;
- this.stringFormat.LineAlignment = (StringAlignment)this.lineAlignment;
- this.stringFormat.FormatFlags = (StringFormatFlags)this.formatFlags;
- }
- return this.stringFormat;
- }
- StringFormat stringFormat;
-#endif
- }
-}
+#region PDFsharp - A .NET library for processing PDF
+//
+// Authors:
+// Stefan Lange (mailto:Stefan.Lange@pdfsharp.com)
+//
+// Copyright (c) 2005-2009 empira Software GmbH, Cologne (Germany)
+//
+// http://www.pdfsharp.com
+// http://sourceforge.net/projects/pdfsharp
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.IO;
+#if GDI
+using System.Drawing;
+using System.Drawing.Drawing2D;
+#endif
+#if WPF
+using System.Windows.Media;
+#endif
+using PdfSharp.Internal;
+
+namespace PdfSharp.Drawing
+{
+ ///
+ /// Not used in this implementation.
+ ///
+ [Flags]
+ public enum XStringFormatFlags
+ {
+ //DirectionRightToLeft = 0x0001,
+ //DirectionVertical = 0x0002,
+ //FitBlackBox = 0x0004,
+ //DisplayFormatControl = 0x0020,
+ //NoFontFallback = 0x0400,
+ ///
+ /// The default value.
+ ///
+ MeasureTrailingSpaces = 0x0800,
+ //NoWrap = 0x1000,
+ //LineLimit = 0x2000,
+ //NoClip = 0x4000,
+ }
+
+ ////public enum StringTrimming
+ ////{
+ //// None = 0,
+ //// Character = 1,
+ //// Word = 2,
+ //// EllipsisCharacter = 3,
+ //// EllipsisWord = 4,
+ //// EllipsisPath = 5,
+ ////}
+
+ ///
+ /// Represents the text layout information.
+ ///
+ public class XStringFormat
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public XStringFormat()
+ {
+#if GDI
+ // We must clone GenericTypographic, otherwise we change the original!
+ this.stringFormat = (StringFormat)StringFormat.GenericTypographic.Clone();
+#endif
+ }
+
+ //TODO public StringFormat(StringFormat format);
+ //public StringFormat(StringFormatFlags options);
+ //public StringFormat(StringFormatFlags options, int language);
+ //public object Clone();
+ //public void Dispose();
+ //private void Dispose(bool disposing);
+ //protected override void Finalize();
+ //public void SetDigitSubstitution(int language, StringDigitSubstitute substitute);
+ //public void SetMeasurableCharacterRanges(CharacterRange[] ranges);
+ //public override string ToString();
+
+ ///
+ /// Sets tab stops for this XStringFormat object
+ ///
+ /// The number of spaces between the beginning of a line of text and the first tab stop.
+ /// An array of distances between tab stops in the units specified by the XGraphics.PageUnit property.
+ public void SetTabStops(float firstTabOffset, float[] tabStops)
+ {
+#if GDI
+ this.stringFormat.SetTabStops(firstTabOffset, tabStops);
+#endif
+ }
+
+ ///
+ /// Gets the tab stops for this StringFormat object
+ ///
+ /// The number of spaces between the beginning of a text line and the first tab stop.
+ /// An array of distances (in number of spaces) between tab stops.
+ public float[] GetTabStops(out float firstTabOffset)
+ {
+ float[] result;
+#if GDI
+ result = this.stringFormat.GetTabStops(out firstTabOffset);
+#endif
+ return result;
+ }
+
+ ///
+ /// Gets or sets horizontal text alignment information.
+ ///
+ public XStringAlignment Alignment
+ {
+ get {return this.alignment;}
+ set
+ {
+ this.alignment = value;
+#if GDI
+ this.stringFormat.Alignment = (StringAlignment)value;
+#endif
+ }
+ }
+ XStringAlignment alignment;
+
+ //public int DigitSubstitutionLanguage { get; }
+ //public StringDigitSubstitute DigitSubstitutionMethod { get; }
+ //public StringFormatFlags FormatFlags { get; set; }
+ //public static StringFormat GenericDefault { get; }
+ //public static StringFormat GenericTypographic { get; }
+ //public HotkeyPrefix HotkeyPrefix { get; set; }
+
+ ///
+ /// Gets or sets the line alignment.
+ ///
+ public XLineAlignment LineAlignment
+ {
+ get {return this.lineAlignment;}
+ set
+ {
+ this.lineAlignment = value;
+#if GDI
+ if (value == XLineAlignment.BaseLine)
+ this.stringFormat.LineAlignment = StringAlignment.Near;
+ else
+ this.stringFormat.LineAlignment = (StringAlignment)value;
+#endif
+ }
+ }
+ XLineAlignment lineAlignment;
+
+ //public StringTrimming Trimming { get; set; }
+
+ ///
+ /// Gets a new XStringFormat object that aligns the text left on the base line.
+ ///
+ [Obsolete("Use XStringFormats.Default. (Note plural in class name.)")]
+ public static XStringFormat Default
+ {
+ get
+ {
+ XStringFormat format = new XStringFormat();
+ format.LineAlignment = XLineAlignment.BaseLine;
+ return format;
+ }
+ }
+
+ ///
+ /// Gets a new XStringFormat object that aligns the text top left of the layout rectangle.
+ ///
+ [Obsolete("Use XStringFormats.Default. (Note plural in class name.)")]
+ public static XStringFormat TopLeft
+ {
+ get
+ {
+ XStringFormat format = new XStringFormat();
+ format.Alignment = XStringAlignment.Near;
+ format.LineAlignment = XLineAlignment.Near;
+ return format;
+ }
+ }
+
+ ///
+ /// Gets a new XStringFormat object that centers the text in the middle of the layout rectangle.
+ ///
+ [Obsolete("Use XStringFormats.Center. (Note plural in class name.)")]
+ public static XStringFormat Center
+ {
+ get
+ {
+ XStringFormat format = new XStringFormat();
+ format.Alignment = XStringAlignment.Center;
+ format.LineAlignment = XLineAlignment.Center;
+ return format;
+ }
+ }
+
+ ///
+ /// Gets a new XStringFormat object that centers the text at the top of the layout rectangle.
+ ///
+ [Obsolete("Use XStringFormats.TopCenter. (Note plural in class name.)")]
+ public static XStringFormat TopCenter
+ {
+ get
+ {
+ XStringFormat format = new XStringFormat();
+ format.Alignment = XStringAlignment.Center;
+ format.LineAlignment = XLineAlignment.Near;
+ return format;
+ }
+ }
+
+ ///
+ /// Gets a new XStringFormat object that centers the text at the bottom of the layout rectangle.
+ ///
+ [Obsolete("Use XStringFormats.BottomCenter. (Note plural in class name.)")]
+ public static XStringFormat BottomCenter
+ {
+ get
+ {
+ XStringFormat format = new XStringFormat();
+ format.Alignment = XStringAlignment.Center;
+ format.LineAlignment = XLineAlignment.Far;
+ return format;
+ }
+ }
+
+ ///
+ /// Gets or sets flags with format information.
+ ///
+ public XStringFormatFlags FormatFlags
+ {
+ get {return this.formatFlags;}
+ set
+ {
+ this.formatFlags = value;
+#if GDI
+ this.stringFormat.FormatFlags = (StringFormatFlags)value;
+#endif
+ }
+ }
+ private XStringFormatFlags formatFlags;
+
+#if GDI
+ internal StringFormat RealizeGdiStringFormat()
+ {
+ if (this.stringFormat == null)
+ {
+ this.stringFormat = StringFormat.GenericTypographic; //.GenericDefault;
+ this.stringFormat.Alignment = (StringAlignment)this.alignment;
+ this.stringFormat.LineAlignment = (StringAlignment)this.lineAlignment;
+ this.stringFormat.FormatFlags = (StringFormatFlags)this.formatFlags;
+ }
+ return this.stringFormat;
+ }
+ StringFormat stringFormat;
+#endif
+ }
+}