@@ -138,29 +138,32 @@ public void SetAlignment(TextFormatAlignment alignments)
138138 /// <param name="font">The font.</param>
139139 /// <param name="brush">The text brush.</param>
140140 /// <param name="layoutRectangle">The layout rectangle.</param>
141+ /// <param name="lineHeight">The line height.</param>
141142 public void DrawString ( string text , XFont font , XBrush brush , XRect layoutRectangle , XUnit ? lineHeight = null )
142143 {
143- DrawString ( text , font , brush , layoutRectangle , XStringFormats . TopLeft , lineHeight ) ;
144+ DrawString ( text , font , brush , layoutRectangle , new TextFormatAlignment ( )
145+ {
146+ Horizontal = XParagraphAlignment . Justify , Vertical = XVerticalAlignment . Top
147+ } , lineHeight ) ;
144148 }
145149
146150 /// <summary>
147- /// Draws the text .
151+ /// Get the layout rectangle required .
148152 /// </summary>
149153 /// <param name="text">The text to be drawn.</param>
150154 /// <param name="font">The font.</param>
151155 /// <param name="brush">The text brush.</param>
152156 /// <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 )
157+ /// <param name="lineHeight">The height of each line</param>
158+ public XRect GetLayout ( string text , XFont font , XBrush brush , XRect layoutRectangle ,
159+ XUnit ? lineHeight = null )
155160 {
156161 if ( text == null )
157162 throw new ArgumentNullException ( "text" ) ;
158163 if ( font == null )
159164 throw new ArgumentNullException ( "font" ) ;
160165 if ( brush == null )
161166 throw new ArgumentNullException ( "brush" ) ;
162- if ( format . Alignment != XStringAlignment . Near || format . LineAlignment != XLineAlignment . Near )
163- throw new ArgumentException ( "Only TopLeft alignment is currently implemented." ) ;
164167
165168 Text = text ;
166169 Font = font ;
@@ -169,36 +172,84 @@ public void DrawString(string text, XFont font, XBrush brush, XRect layoutRectan
169172 _lineHeight = lineHeight ? . Point ?? _lineSpace ;
170173
171174 if ( text . Length == 0 )
172- return ;
175+ return new XRect ( layoutRectangle . Location . X , layoutRectangle . Location . Y , 0 , 0 ) ;
173176
174177 CreateBlocks ( ) ;
175178
176179 CreateLayout ( ) ;
177180
181+ return _layoutRectangle ;
182+ }
183+
184+ /// <summary>
185+ /// Draws the text.
186+ /// </summary>
187+ /// <param name="text">The text to be drawn.</param>
188+ /// <param name="font">The font.</param>
189+ /// <param name="brush">The text brush.</param>
190+ /// <param name="layoutRectangle">The layout rectangle.</param>
191+ /// <param name="alignments">The alignments.</c></param>
192+ /// <param name="lineHeight">The height of each line.</param>
193+ public void DrawString ( string text , XFont font , XBrush brush , XRect layoutRectangle , TextFormatAlignment alignments ,
194+ XUnit ? lineHeight = null )
195+ {
196+ if ( alignments == null )
197+ throw new ArgumentNullException ( nameof ( alignments ) ) ;
198+
199+ if ( text . Length == 0 )
200+ return ;
201+
202+ GetLayout ( text , font , brush , layoutRectangle , lineHeight ) ;
203+
204+ SetAlignment ( alignments ) ;
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 ) / 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+ var lineBlocks = line as Block [ ] ?? line . ToArray ( ) ;
225+ if ( Alignment == XParagraphAlignment . Justify )
226+ {
227+ var locationX = dx ;
228+ var gapSize = ( layoutRectangle . Width - lineBlocks . Select ( l => l . Width ) . Sum ( ) ) / ( lineBlocks . Count ( ) - 1 ) ;
229+ foreach ( var block in lineBlocks )
230+ {
231+ _gfx . DrawString ( block . Text . Trim ( ) , font , brush , locationX , dy + lineBlocks . First ( ) . Location . Y , XStringFormats . TopLeft ) ;
232+ locationX += block . Width + gapSize ;
233+ }
234+ }
235+ else
236+ {
237+ var lineText = string . Join ( " " , lineBlocks . Select ( l => l . Text ) ) ;
238+ var locationX = dx ;
239+ if ( Alignment == XParagraphAlignment . Center )
240+ locationX = dx + layoutRectangle . Width / 2 ;
241+ if ( Alignment == XParagraphAlignment . Right )
242+ locationX += layoutRectangle . Width ;
243+ _gfx . DrawString ( lineText , font , brush , locationX , dy + lineBlocks . First ( ) . Location . Y , GetXStringFormat ( ) ) ;
244+ }
199245 }
200246 }
201247
248+ private static IEnumerable < IEnumerable < Block > > GetLines ( List < Block > blocks )
249+ {
250+ return blocks . GroupBy ( b => b . Location . Y ) ;
251+ }
252+
202253 void CreateBlocks ( )
203254 {
204255 _blocks . Clear ( ) ;
@@ -378,6 +429,22 @@ void HorizontalAlignLine(int firstIndex, int lastIndex, double layoutWidth)
378429 // - underline and strike-out variation
379430 // - super- and sub-script
380431 // - ...
432+
433+ private XStringFormat GetXStringFormat ( )
434+ {
435+ switch ( Alignment )
436+ {
437+ case XParagraphAlignment . Center :
438+ return XStringFormats . TopCenter ;
439+ case XParagraphAlignment . Right :
440+ return XStringFormats . TopRight ;
441+ case XParagraphAlignment . Default :
442+ case XParagraphAlignment . Justify :
443+ case XParagraphAlignment . Left :
444+ default :
445+ return XStringFormats . TopLeft ;
446+ }
447+ }
381448 }
382449
383450 public class TextFormatAlignment
0 commit comments