views:

419

answers:

1

I'm trying to dynamically write text to an image, but I would like to boldface a selected word in the sentence. What I did is separate the string into three strings, the first part, the word to be boldfaced, and the remainder of the sentence. When I attempt to draw them onto the image (.DrawString()), however, they don't concatenate, but rather overwrite one another. Is there any way I can reconstruct a sentence (boldfacing a middle word) on an image?

Thanks!

EDIT: Example code:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 Dim w As Word = Word.GetLastPublishedWord()
 Dim wordForm As String = Word.FindWordForm(w.Word, w.Sentence, Word.RegexOutputType.StandardString)
 Dim firstPart As String = Left(w.Sentence, w.Sentence.IndexOf(wordForm))
 Dim lastPart As String = Right(w.Sentence, (w.Sentence.Length - firstPart.Length - wordForm.Length))

 Dim sig As Image = Image.FromFile(Server.MapPath(ResolveUrl("~/images/sig.jpg")))
 Dim text As Graphics = Graphics.FromImage(sig)
 text.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
 Dim sentenceRec As New RectangleF(0, 0, 400, 75)
 Dim tagRec As New RectangleF(250, 75, 150, 25)
 text.DrawString(firstPart, New Font("Arial", 12, FontStyle.Regular), SystemBrushes.WindowText, sentenceRec)
 text.DrawString(wordForm, New Font("Arial", 12, FontStyle.Bold), SystemBrushes.WindowText, sentenceRec)
 text.DrawString(lastPart, New Font("Arial", 12, FontStyle.Regular), SystemBrushes.WindowText, sentenceRec)

 Response.ContentType = "image/jpeg"
 sig.Save(Response.OutputStream, ImageFormat.Jpeg)
 sig.Dispose()
 text.Dispose()
End Sub
+1  A: 

You need to increment the insertion point as you write out the text to the graphics object.

PointF insertionPoint;
SizeF textWidth = g.MeasureString("First ", normalFont);

g.DrawString("First ", normalFont, Brushes.Black, insertionPoint);

insertionPoint.X += textWidth.Width;
textWidth = g.MeasureString("bolded", boldFont);
g.DrawString("bolded", boldFont, Brushes.Black, insertionPoint);

insertionPoint.X += textWidth.Width;
g.DrawString(" and remaining.", normalFont, Brushes.Black, insertionPoint);
Robert Paulson
the only problem with this is that the text will wrap... that's why i included the RectangleF, which is a layout rectangle. Any other suggestion?
Jason
ie, i want the text to be able to wrap at 400px
Jason
Unfortunately there's nothing in GDI+ to handle 'rich text' automagically. You'll have to roll your own logic to handle wrapping. As a reference, you should take a look at http://www.codeproject.com/KB/GDI-plus/HtmlRenderer.aspx which creates an html CSS2 renderer that uses GDI+ entirely.
Robert Paulson
that sucks... it would be doable if they would let me set a bounding box PLUS the insertion point, or if the graphics object would respect the .Clip() property, but oh well...
Jason