@@ -150,17 +150,16 @@ public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectan
150150 /// <param name="font">The font.</param>
151151 /// <param name="brush">The text brush.</param>
152152 /// <param name="layoutRectangle">The layout rectangle.</param>
153- /// <param name="format">The format. Must be <c>XStringFormat.TopLeft</c></param>
154- public void DrawString ( string text , XFont font , XBrush brush , XRect layoutRectangle , XStringFormat format , XUnit ? lineHeight = null )
153+ /// <param name="lineHeight">The height of each line</param>
154+ public XRect GetLayout ( string text , XFont font , XBrush brush , XRect layoutRectangle ,
155+ XUnit ? lineHeight = null )
155156 {
156157 if ( text == null )
157158 throw new ArgumentNullException ( "text" ) ;
158159 if ( font == null )
159160 throw new ArgumentNullException ( "font" ) ;
160161 if ( brush == null )
161162 throw new ArgumentNullException ( "brush" ) ;
162- if ( format . Alignment != XStringAlignment . Near || format . LineAlignment != XLineAlignment . Near )
163- throw new ArgumentException ( "Only TopLeft alignment is currently implemented." ) ;
164163
165164 Text = text ;
166165 Font = font ;
@@ -169,36 +168,78 @@ public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectan
169168 _lineHeight = lineHeight ? . Point ?? _lineSpace ;
170169
171170 if ( text . Length == 0 )
172- return ;
171+ return new XRect ( layoutRectangle . Location . X , layoutRectangle . Location . Y , 0 , 0 ) ;
173172
174173 CreateBlocks ( ) ;
175174
176175 CreateLayout ( ) ;
177176
177+ return _layoutRectangle ;
178+ }
179+
180+ /// <summary>
181+ /// Draws the text.
182+ /// </summary>
183+ /// <param name="text">The text to be drawn.</param>
184+ /// <param name="font">The font.</param>
185+ /// <param name="brush">The text brush.</param>
186+ /// <param name="layoutRectangle">The layout rectangle.</param>
187+ /// <param name="format">The format. Must be <c>XStringFormat.TopLeft</c></param>
188+ /// <param name="lineHeight">The height of each line</param>
189+ public void DrawString ( string text , XFont font , XBrush brush , XRect layoutRectangle , XStringFormat format ,
190+ XUnit ? lineHeight = null )
191+ {
192+ if ( format == null )
193+ throw new ArgumentNullException ( nameof ( format ) ) ;
194+
195+ if ( text . Length == 0 )
196+ return ;
197+
198+ GetLayout ( text , font , brush , layoutRectangle , lineHeight ) ;
199+
200+ SetAlignment ( new TextFormatAlignment ( )
201+ {
202+ Horizontal = GetHorizontalAlignmentFromFormat ( format ) ,
203+ Vertical = GetVerticalAlignmentFromFormat ( format )
204+ } ) ;
205+
178206 double dx = layoutRectangle . Location . X ;
179- double dy = layoutRectangle . Location . Y + _cyAscent ;
180-
207+ double dy = layoutRectangle . Location . Y ;
208+
209+ var lines = GetLines ( _blocks ) . ToArray ( ) ;
210+
181211 if ( VerticalAlignment == XVerticalAlignment . Middle )
182212 {
183- dy += layoutRectangle . Height / 2 - _layoutRectangle . Height / 2 - _cyDescent ;
213+ dy += ( layoutRectangle . Height - _layoutRectangle . Height + _lineHeight ) / 2 ;
184214 }
185215 else if ( VerticalAlignment == XVerticalAlignment . Bottom )
186216 {
187- dy = layoutRectangle . Location . Y + layoutRectangle . Height - _layoutRectangle . Height + _lineHeight - _cyDescent ;
217+ dy = layoutRectangle . Location . Y + layoutRectangle . Height - _layoutRectangle . Height + _lineHeight -
218+ _cyDescent ;
188219 }
189-
220+
190221 int count = _blocks . Count ;
191- for ( int idx = 0 ; idx < count ; idx ++ )
222+ foreach ( var line in lines )
192223 {
193- Block block = _blocks [ idx ] ;
194- if ( block . Stop )
195- break ;
196- if ( block . Type == BlockType . LineBreak )
197- continue ;
198- _gfx . DrawString ( block . Text , font , brush , dx + block . Location . X , dy + block . Location . Y ) ;
224+ if ( Alignment != XParagraphAlignment . Justify )
225+ {
226+ var enumerable = line as Block [ ] ?? line . ToArray ( ) ;
227+ var lineText = string . Join ( " " , enumerable . Select ( l => l . Text ) ) ;
228+ var locationX = dx ;
229+ if ( format . Alignment == XStringAlignment . Center )
230+ locationX = dx + layoutRectangle . Width / 2 ;
231+ if ( format . Alignment == XStringAlignment . Far )
232+ locationX += layoutRectangle . Width ;
233+ _gfx . DrawString ( lineText , font , brush , locationX , dy + enumerable . First ( ) . Location . Y , format ) ;
234+ }
199235 }
200236 }
201237
238+ private static IEnumerable < IEnumerable < Block > > GetLines ( List < Block > blocks )
239+ {
240+ return blocks . GroupBy ( b => b . Location . Y ) ;
241+ }
242+
202243 void CreateBlocks ( )
203244 {
204245 _blocks . Clear ( ) ;
@@ -378,6 +419,36 @@ void HorizontalAlignLine(int firstIndex, int lastIndex, double layoutWidth)
378419 // - underline and strike-out variation
379420 // - super- and sub-script
380421 // - ...
422+
423+ private static XParagraphAlignment GetHorizontalAlignmentFromFormat ( XStringFormat format )
424+ {
425+ switch ( format . Alignment )
426+ {
427+ case XStringAlignment . Center :
428+ return XParagraphAlignment . Center ;
429+ case XStringAlignment . Near :
430+ return XParagraphAlignment . Left ;
431+ case XStringAlignment . Far :
432+ return XParagraphAlignment . Right ;
433+ }
434+
435+ return XParagraphAlignment . Justify ;
436+ }
437+
438+ private static XVerticalAlignment GetVerticalAlignmentFromFormat ( XStringFormat format )
439+ {
440+ switch ( format . LineAlignment )
441+ {
442+ case XLineAlignment . Center :
443+ return XVerticalAlignment . Middle ;
444+ case XLineAlignment . BaseLine :
445+ case XLineAlignment . Far :
446+ return XVerticalAlignment . Bottom ;
447+ case XLineAlignment . Near :
448+ default :
449+ return XVerticalAlignment . Top ;
450+ }
451+ }
381452 }
382453
383454 public class TextFormatAlignment
0 commit comments