Font is showing up too small or large when using .DrawString - vb.net

I need to add a half inch of white space at the bottom of an image and the draw a string to the bottom left and bottom right (within the newly added white space). Everything seems to work fine but the font sometime appears way too small or too large.
I think I need to somehow scale the drawstring font to the size of the image? I have exhausted myself trying to figure this out... Please help!!
See code below ----
Imports System.IO
Imports System.Drawing.Graphics
Imports System.Drawing
Imports System.Drawing.Bitmap
Imports System.Drawing.Imaging
Public Class Form1
Dim ofilepath As String = "C:\temp\20141022\TEST0000001.tif"
Dim nfilepath As String = "C:\temp\20141022\new.tif"
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim newbm As New Bitmap(AddBorderAndStamp(Bitmap.FromFile(ofilepath), Color.White, 50, Path.GetFileNameWithoutExtension(ofilepath), "CONFIDENTIAL"))
newbm.Save(nfilepath, Imaging.ImageFormat.Tiff)
Me.Close()
End Sub
Public Function AddBorderAndStamp(ByVal bm As Bitmap, ByVal borderColor As System.Drawing.Color, ByVal borderWidthInPixels As Integer, ByVal bates As String, ByVal designation As String) As Bitmap
Dim voffset As Integer = 75
Dim hoffset As Integer = 15
Dim newBitmap As New Bitmap(bm.Width, bm.Height + (borderWidthInPixels * 2))
Dim mfont As Font = New Font("Arial", 32, FontStyle.Bold)
For x As Integer = 0 To newBitmap.Width - 1
For y As Integer = newBitmap.Height - 1 To (newBitmap.Height - 1) - borderWidthInPixels Step -1
newBitmap.SetPixel(x, y, borderColor)
Next
Next
Dim gr As System.Drawing.Graphics = Graphics.FromImage(newBitmap)
gr.Clear(Color.White)
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
Dim textSize As SizeF = gr.MeasureString(bates, mfont)
gr.DrawString(bates, mfont, Brushes.Black, bm.Width - textSize.Width - hoffset, newBitmap.Height - voffset)
gr.DrawString(designation, mfont, Brushes.Black, hoffset, newBitmap.Height - voffset)
gr.Dispose()
Return newBitmap
End Function
End Class

When you're about to know the size (width) of your bates string at this line :
Dim textSize As SizeF = gr.MeasureString(bates, mfont)
and before drawing your string on the bitmap, you'll have to compute the scaling to perform on your font size to make sure your text gets shrinked (if too long) or stretched (if too narrow) while not excessively stretched in height-mean to be drawn over the image.
Then, only when you have a valid font size, you draw your text as you do with the following lines
gr.DrawString(bates, mfont, Brushes.Black, bm.Width - textSize.Width - hoffset, newBitmap.Height - voffset)
gr.DrawString(designation, mfont, Brushes.Black, hoffset, newBitmap.Height - voffset)
To know what's the correct font size to use, have a look on this SO Question Page.
I know it's C#, but this is basically what you'll have to do before drawing your bates and designation text. The difference lies in two points :
you have two String to scale in a clip rectangle (bates and designation) instead of one.
you have to take account of a (default) separation between designation on the left, and bates on the right.
But these two points can be easily worked around. This also means that your question could be a duplicate (StackOverflow doesn't recommend multiple variants of the same question as the purpose of SO is to bring you directly to a page asking a question AND its answer - if answered - but not to flood you with dozens copies of the same subject)
But IMHO, the two-string (designation and bates) is enough to consider this as a new question, because the code handling that is not covered by the other topics.
Here is saeed's function converted to vb.Net
Private Function FindFont( _
ByRef rg As Graphics, _
ByVal testString as String, _
ByVal clipRoom As Size, _
ByVal preferedFont As Font) As Font
' You should perform some scale functions...
Dim realSize As SizeF = rg.MeasureString(testString, PreferedFont)
Dim heightScaleRatio As Double = clipRoom.Height / realSize.Height
Dim widthScaleRatio As Double = clipRoom.Width / realSize.Width
Dim scaleRatio As Double
Dim newFontSize As Single ' I'm used to declare everything on top.
If heightScaleRatio < widthScaleRatio Then
scaleRatio = heightScaleRatio
Else
scaleRatio = widthScaleRatio
End If
newFontSize = CSng(preferedFont.Size * ScaleRatio)
Return New Font(preferedFont.FontFamily, newFontSize, preferedFont.Style)
End Function
Credits goes to saeed first for providing the code, but if saeed used code from someone else that I'm not aware of, credits to original author supersede saeed's.
The required parameters for that Function to work are :
rg As Graphics. You already have it, namely rg in your AddBorderAndStamp Function.
testString As String. You also have it, it is simply testString = designation + bates
clipRoom As Size. You don't have that variable yet. You'll have to declare it in your AddBorderAndStamp Function, and use some logic to define its .Width and .Height values.
and preferedFont As Font. You also have that already, which is mfont As Font = New Font("Arial", 32, FontStyle.Bold)
The declarations to add to your AddBorderAndStamp Function are :
Dim clipRoom As Size ' Declare it.
Dim stampSeparation As Integer = 80 ' why 80 ? dunno ! it's an arbitrary value..
stampSeparation is an arbitraty variable that represents the Width IN
PIXELs between designation and bates. Basically, it looks like this :
'< - - - - - - - total Bitmap width - - - - - - - >
'| |designation|_____________|bates| |
'| | | | | ^ Right Image boder
'| | | | ^ Right margin
'| | | ^ Left plot of your bates String
'| | <-------------> Length or Width of stampSeparation
'| ^ Left plot of your designation String
'^ Left image border
Your available room to write text is the sum of
designation.Width
bates.Width
stampSeparation
But because you want designation and bates beeing separated by stampSeparation, stampSeparation must be substracted from the available clip width. So :
clipRoom.Width = newBitmap.Width - (hOffset * 2) - stampSeparation
' newBitmap.Width - 30 - 80
' newBitmap.Width - 110
' CAREFULL !!! clipRoom.Width MUST be positive !!!
' Check your bm is wide enough, say at least 200 pixels Width...
The room you have at the bottom is a sightly different story : Your AddBorderAndStamp Function has one borderWidthInPixels (as Integer) parameter that define the room you add in top/bottom mean. Then you use voffset (as Integer) variable to shift your stamp upward.. That means your available room in terms of heigth at the bottom of your image to plot text in is :
clipRoom.Height = vOffset ' ?
' 75 ?
' (CAREFULL !!! clipRoom.Height MUST be positive !!!)
If I were you, I would dynamically define clipRoom.Height based on a fraction of AddBorderAndStamp and dynamically calculate vOffset after knowing the final heigth of designation and bates heights using MeasureString... But that would be an overkill...
' perhaps one simple logic like the following would suffice
' clipRoom.Height = CInt(vOffset * 4 / 5)
Now you have clipRoom and everything else required to call FindFont(...) Function.
So :
Public Function AddBorderAndStamp(...) As Bitmap
' Dim vOffset ' ...
' Dim hOffset ' ...
' ...
' add the following declarations :
Dim clipRoom As Size
Dim stampSeparation As Integer = 80 ' or 60 as you like but small enough
' ...
' ... your function block code goes here until the following line :
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' Calculate the available clip room...
clipRoom.Width = newBitmap.Width - (hOffset * 2) - stampSeparation
clipRoom.Height = vOffset
' ^^ remember : the logic to handle valid Width and Height is up to you
' I know how to handle that, but you should aswell, or try at least.
' Now, update the size of your font...
mFont = FindFont(rg, designation + bates, clipRoom, mFont)
' then continue with the rest of the code...
Dim textSize As SizeF = gr.MeasureString(bates, mfont)
gr.DrawString(bates, mfont, Brushes.Black, bm.Width - textSize.Width - hoffset, newBitmap.Height - voffset)
gr.DrawString(designation, mfont, Brushes.Black, hoffset, newBitmap.Height - voffset)
gr.Dispose()
Return newBitmap
End Function
by the way :
Hello. You should add [vb.Net] tag to the post and either remove
[image] or [bitmap] since those are synonyms.
It's hard to spot code typos without the formatting. But since you're new on StackOverflow (SO) I don't want to downvote or flag you, but I insist : update the tags of your question.
Remark 1 :
You wrote :
For x As Integer = 0 To newBitmap.Width - 1
For y As Integer = newBitmap.Height - 1 To (newBitmap.Height - 1) - borderWidthInPixels Step -1
newBitmap.SetPixel(x, y, borderColor)
Next
Next
Dim gr As System.Drawing.Graphics = Graphics.FromImage(newBitmap)
gr.Clear(Color.White)
You're changing the color of newBitmap pixel by pixel from the bottom. I'm OK with that but there are better ways to achieve that.
However, you're declaring a Graphics to handle drawings on newBitmap, then you call gr.Clear(Color.White) ???
Isn't that supposed to entirely paint your newBitmap with white, thus, destroing the purpose of your SetPixel loop just above ?
I don't understand. Perhaps you want the function to waste time, so just use
System.Threading.Thread.Sleep(X) ' where X is an Integer variable in miliseconds
Otherwise, I would recommend you to get rid of the SetPixel and its encosing For loops, and just fill a Rectangle using your gr Graphics :
' ...
Dim gr As System.Drawing.Graphics = Graphics.FromImage(newBitmap)
gr.Clear(Color.White)
gr.FillRectangle( _
New SolidBrush(borderColor), _
0, newBitmap.Height - borderWidthInPixels, _
newBitmap.Width, borderWidthInPixels)
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' ...
Remark 2 :
' you've set newBitmap to have
' bm.Heigth expanded by two times the value of borderWidthInPixels
Dim newBitmap As New Bitmap(bm.Width, bm.Height + (borderWidthInPixels * 2))
' ...
' Then you plot bm at the very top of newBitmap
gr.DrawImage(bm, 0, 0, bm.Width, bm.Height)
' that means you have a blank space at the bottom
' that height twice the value of borderWidthInPixels
' ...
' But you plot bates and designation
' at a fixed vOffset from the bottom of newBitmap
gr.DrawString(bates, , , , newBitmap.Height - voffset)
gr.DrawString(designation, , , , newBitmap.Height - voffset)
The relation between borderWidthInPixels and voffset remains unclear to me, that may mislead the formulation of clipRoom.Height above.
However, I think I've given enough material to get you where you want, and even if the clipRoom.Height formulation above is wrong, it would be very easy to fix it.
You also have to understand that I used saeed approach by default, but by reading the post I linked, you'll find other approaches, iteratives ones, which I don't like much because they are iterations CPU heavy without always beeing more precise. You can even find hints about TextToBitmap; have a try if more suitable for you, but it's more complex too.. For what you're doing, I think one or two pixels displaced outputs is not a problem.
For the vertical placement, you said ".. but the font sometime appears way too small or too large.." That's not precise enough to get a full picture of the issue. You should have posted two images samples of the "too small" case and the "too large" case. Since you didn't change Font Size in your code, I assumed the too small problem was a too large space between designation and bates, and the too large is overlapping text. There is not a single reference to a possible vertical laying out issue, so my answer doesn't elaborate on that side. That's why I don't introduce multiline logic here, which would stand for another question (if none available on SO)

Related

iTextsharp - draw a line at the end and start of a page with tables

Selecting records from a table I create iTextsharp's Tables one for every first letter of the records
On the picture a table for the "G" letter:
"G" is a row of 6 cells
Then a row of 6 cells with the "headers"
and then rows with records
The cells of the rows only need left and right border.
But I need to draw or "close" the line for the last row of the page and also draw or "open" the line of the first row of the next page.
I read a lot of post but I can't figure it out the solution
I know how to draw a graphic line and how to find the coords or how to set bottom or top border, but I don´t know how to detect the page break or if I can manage this situation with forced footers or headers only on cases like the one of the picture.
The code of the class adapated to VB
Thanks to COeDev for the support
Now I only need to resolve the Rectangle (or draw a line) because is not the same on VB.NET (Lines marked as comment)
Imports iTextSharp.text.pdf
Public Class LineaBottom
Implements IPdfPTableEvent
Public Sub TableLayout(table As PdfPTable, widths As Single()(), heights() As Single, headerRows As Integer, rowStart As Integer, canvases() As PdfContentByte) Implements IPdfPTableEvent.TableLayout
'Throw New NotImplementedException()
Dim columns As Integer
Dim rect As Rectangle
Dim footer As Integer = widths.Length - table.FooterRows
Dim header As Integer = table.HeaderRows - table.FooterRows + 1
Dim ultima As Integer = footer - 1
If ultima <> -1 Then
columns = widths(ultima).Length - 1
rect = New Rectangle(widths(ultima)(0), heights(ultima), widths(footer - 1)(columns), heights(ultima + 1))
'rect.BorderColor = BaseColor.BLACK
'rect.BorderWidth = 1
'rect.Border = Rectangle.TOP_BORDER
'canvases(PdfPTable.BASECANVAS).Rectangle(rect)
End If
End Sub
I hope this code will serve other people because there is not much information on the Internet
This should be helpful for you: itextsharp: how to show the bottom line of a table with property HeaderRows=1 if border bottom of the row is not set?
You will need to add some code to draw an additional header line, too
e.g.:
columns = widths[0].Length - 1;
rect = new Rectangle(widths[0][0], heights[0], widths[0][columns], heights[0]);
rect.BorderColor = Color.BLACK;
rect.BorderWidth = 1;
rect.Border = Rectangle.TOP_BORDER;
canvases[PdfPTable.BASECANVAS].Rectangle(rect);
4.1.6.0
I found the solution, no new class required
Dim heightActualLetter, verticalSpaceAvailable As Integer
heightActualLetter = table.TotalHeight
verticalSpaceAvailable = pdfWrite.GetVerticalPosition(False) - pdfDoc.BottomMargin
If heightActualLetter > verticalSpaceAvailable Then
Dim finalLine As PdfContentByte
finalLine = pdfWrite.DirectContent
Dim curY As Int32
curY = pdfWrite.GetVerticalPosition(False)
finalLine.SetLineWidth(0.5)
finalLine.MoveTo(xStart, curY)
finalLine.LineTo(xEnd + 1, curY)
finalLine.Stroke()
End If
I don´t know why I need the +1 on xEnd + 1 but maybe is because of the other lines being 0.5 I need to rounded up

Photoshop crop from vb.net

I assumed that cropping an image would be an extremely easy thing to do from .net. But no matter what I try I just cannot seem to get the thing to work.
The documentation is somewhat vague -
'The first parameter is an array of four coordinates that mark the portion remaining after cropping'
That could mean an array of four numbers, or it could mean an array of four arrays of two numbers (a coordinate after all consists of two numbers). the 'portion remaining after cropping' I take to mean 'the portion of the image designated to remain after cropping'.
Since the select function takes an array of coordinate arrays -- {{x1,y1}, y2, y2}, {x3,y3}, {x4, y4}} -- I had hoped crop would work the same way. No dice.
Next, I tried the really simple approach, assume that 'left, top, right, bottom' really mean just that. So, I plugged in perfectly reasonable values and ... no dice.
In every case, PS throws a dialog box saying ' Could not complete the command because the affected area is empty or does not overlap the canvas'.
Here is a code snippet:
Dim PSDapp
PSDapp = CreateObject("Photoshop.Application")
Dim psarray As Object = {20, 20, 120, 120}
Dim PSDcurrentDoc
PSDapp.preferences.rulerUnits = 1
PSDcurrentDoc = PSDapp.open("c:\cat.bmp")
PSDapp.activeDocument = PSDapp.documents.item(1)
PSDcurrentDoc.crop(psarray)
What is even more strange is that if I take the above code and port it to a script, it runs just fine. Can someone (anyone!) please please post a minimal working example of using the crop feature using COM (not scripting)?
I've never used Photoshop, but an array of coordinates could be written like this:
Dim psarray() As Point = {
New Point(20, 20),
New Point(120, 20),
New Point(120, 120),
New Point(20, 120)
}
PSDcurrentDoc.crop(psarray)
So you tried something like this already?
Dim psarray() As Integer = {20, 20, 120, 120}
PSDcurrentDoc.crop(psarray)
If that doesn't work, try "pinning" it:
Dim psarray() As Integer = {20, 20, 120, 120}
Dim gch As System.Runtime.InteropServices.GCHandle
gch = System.Runtime.InteropServices.GCHandle.Alloc(psarray, Runtime.InteropServices.GCHandleType.Pinned)
PSDcurrentDoc.crop(gch.AddrOfPinnedObject)
gch.Free()
Solved, with a work-around.
I used a selection as a work-around. The code is longer than it really should have to be since I must first make a selection, but it does work.
Below is the full working subroutine connected to a button. I hope it is of use to somebody that might face this issue as well.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim x As Integer = 100 ' The x-coordinate of the upper-left corner (pixel units).
Dim y As Integer = 100 ' The y-coordinate of the upper-left corner (pixel units).
Dim w As Integer = 200 ' The width of the selection/crop (pixel units).
Dim h As Integer = 200 ' The height of the selection/crop (pixel units).
Dim psArray1() As Object = {x, y}
Dim psArray2() As Object = {x, y + h}
Dim psArray3() As Object = {x + w, y + h}
Dim psArray4() As Object = {x + w, y}
Dim psArray() As Object = {psArray1, psArray2, psArray3, psArray4} ' A concatenated object consisting of an array of coordinates.
Dim PSDapp As Object = CreateObject("Photoshop.Application")
Dim PSDcurrentDoc As Object = PSDapp.open("c:\cat.bmp") ' Could be any document of course.
PSDapp.preferences.rulerUnits = 1
PSDcurrentDoc.selection.select(psArray)
Dim selectArray As Object = PSDcurrentDoc.selection.bounds
PSDcurrentDoc = PSDcurrentDoc.crop(selectArray) ' This is key. PSDcurrentDoc.crop is read-only, so it must be assigned.
End Sub

Color as background using rgb codes that will constantly change according to time

Public Class Form1
Private Sub Timer1_Tick() Handles Timer1.Tick
Label1.Text = TimeOfDay
Label2.Text = System.DateTime.Now.ToString("MM/d/yyy")
Me.BackColor = ColorTranslator.FromHtml("#" & DateAndTime.Now.ToString("HHmmss"))
Label1.ForeColor = Color.White
Label2.ForeColor = Color.White
End Sub
End Class
In my code above, the background color changes to a hex color code depending on what the time is. However, I would like to change this because the colors that come with these codes are too dark.
Instead I am looking for the code to make the background color the % in red, green, and blue containers. (RGB colors)
For ex, if the time is 11:22:33, then I would like the background color to be 11% red, 22% green and 33% blue. Does this make sense? I am a beginner, and any help is much appreciated.
You need to interpolate between 0 and 255 and use the interpolated value as either red, green or blue value, instead of using the time component directly, if you want to use the full color range. This is because the color components are represented 1 Byte each.
You basically stretch your 0-24 hours to values of 0-255, where Hour=0 corresponds to Red=0 and Hour=24 corresponds to Red=255.
Dim R As Byte = CByte(Date.Now.Hour / 23 * 255)
This is quite similar to your "11% Red" approach.
The other parts would be defined similar,
Dim G As Byte = CByte(Date.Now.Minute / 59 * 255)
Dim B As Byte = CByte(Date.Now.Second / 59 * 255)
The linear interpolation formula in general is
New_Value = (Value - Min) / (Max - Min) * (New_Max - New_Min) + New_Min
Here Min and New_Min is 0, which simplifies the formula somewhat.
To actually assign the color you don't need to set it through construction of a HTML color. You simply can use the Color.FromArgb function. Just type it in in Visual Studio. For some reason IntelliSense (the feature that shows you what methods there are available while typing in the IDE) hides the function in some cases.
Me.BackColor = Color.FromArgb(R, G, B)
This is nothing different than your HTML approach, just simpler (the #321224 value is just a representation of three bytes in hexadecimal, in the form of #RRGGBB).
In the strictest sense the answer above is not exactly what you wanted to use. To use your percentage based approach you would construct the RGB values as
Dim R As Byte = CByte(Date.Now.Hour / 100 * 255)
Dim G As Byte = CByte(Date.Now.Minute / 100 * 255)
Dim B As Byte = CByte(Date.Now.Second / 100 * 255)
but this would not yield you the full color range as well (even 59% of 255 is only 150, so you would never see values between 150 and 255). Linear interpolation is the way to go.

Find total overlap percent of multiple rectangles overlapping the same rectangle?

I've got a list of System.Drawing.RectangleF objects that all overlap the same RectangleF object. In my picture below, the 3 overlapping rectangles would be the pink, yellow, and red rectangles. My main rectangle in question is the light blue rectangle.
Second Image:
I know that with RectangleF objects I can use the Intersect() method that will return me another RectangleF object representing the overlap. But as far as I can tell, this only really works when comparing two rectangles.
My question is: How could I determine the TOTAL area/percentage (i.e. the combined total overlap of the red, yellow, and pink rectangles when compared to the light blue rectangle - but it would need to be smart enough to not count the area in which the red and yellow overlaps twice, and same for the pink and yellow)?
NOTE: The green lines represent the area I'm looking for, just the total area of the blue rectangle that is not visible.
UPDATE: I've added a 2nd image to further demonstrate what I'm looking for. In the second image, the presence of the burgundy rectangle should have no affect on the total percent covered because that area is already covered by the yellow and green rectangles.
OK I think I found a solution using a Region that seems to be working for both of my example images above:
Private Function TotalCoveredAreaPercent(ByVal oRectToCheck As RectangleF, ByVal oOverlappingRects As List(Of RectangleF)) As Double
Dim oRegion As New Region(oRectToCheck)
Dim dTotalVisibleArea As Double = 0
Dim dTotalCoveredArea As Double = 0
'now we need to exclude the intersection of our
'overlapping rectangles with our main rectangle:
For Each oOverlappingRect As RectangleF In oOverlappingRects
oRegion.Exclude(RectangleF.Intersect(oRectToCheck, oOverlappingRect))
Next
'now we have access to the non-overlapping
'rectangles that make up the visible area of our main rectangle:
Dim oVisibleRects As RectangleF()
oVisibleRects = oRegion.GetRegionScans(New Drawing2D.Matrix())
'add the area of the visible rectangles together
'to find the total visible area of our main rectangle:
For Each oVisibleRect As RectangleF In oVisibleRects
dTotalVisibleArea += AreaOf(oVisibleRect)
Next
Dim dPercentVisible As Double = dTotalVisibleArea / AreaOf(oRectToCheck) * 100
'percent covered is 100 - the visible percentage:
Return (100 - dPercentVisible)
End Function
This seems to be working pretty well, and is quite simple.
Here is my algorithm. The key point is that we are subtracting out overlaps of overlaps.
Dim baseRect As New RectangleF(10, 10, 20, 20)
Dim otherRectList As New List(Of RectangleF)
otherRectList.Add(New RectangleF(5, 5, 10, 10))
otherRectList.Add(New RectangleF(20, 20, 10, 10))
otherRectList.Add(New RectangleF(10, 5, 10, 10))
Dim overlapRectList As New List(Of RectangleF)
For Each otherRect As RectangleF In otherRectList
If RectangleF.Intersect(otherRect, baseRect) <> RectangleF.Empty Then
overlapRectList.Add(RectangleF.Intersect(otherRect, baseRect))
End If
Next
Dim totalArea As Single = 0
For Each overlapRect As RectangleF In overlapRectList
totalArea += overlapRect.Width * overlapRect.Height
Next
'Subtract out any overlaps that overlap each other
For i = 0 To overlapRectList.Count - 2
For j = i+1 To overlapRectList.Count - 1
If i <> j Then
If RectangleF.Intersect(overlapRectList(i), overlapRectList(j)) <> RectangleF.Empty Then
Dim dupeRect As RectangleF = RectangleF.Intersect(overlapRectList(i), overlapRectList(j))
totalArea -= dupeRect.Width * dupeRect.Height
End If
End If
Next
Next
I amended the code to take into account tcarvin's note. However, I have not plotted out the results on graph paper to see if this is fully correct. I will look at it as soon as I have additional time. Also note that I have not included any code to handle a situation with less than 2 intersections.

A less memory intensive way to estimate size of a testbox in vb.net

I am currently using following code to estimate the size of the textbox:
Dim i As Integer, j As Integer, pGr As Graphics, sz As SizeF
For i = 1 To pNumRows
For j = 1 To pWidth
sb.Append("W")
Next
If pNumRows > 1 Then
sb.Append(vbCrLf)
End If
Next
pGr = txtTextBox.CreateGraphics
sz = pGr.MeasureString(sb.ToString, pTextFont, New SizeF(10000, 10000))
pGr.Dispose()
txtTextBox.SetSize(CInt(sz.Width), CInt(sz.Height) + 80)
txtTextBox.Size = New Size(CInt(sz.Width) + 20, CInt(sz.Height) + 100)
I was wondering if there is any way to remove the for-loops and do away entirely with the pGr (textbox.CreateGraphics) method and still correctly estimate the size of the textbox. Any help will be greatly appreciated.
If you're wondering why I am (actually the person who wrote the code) is looping through all the 'W', it's because (I think) 'W' has the biggest width and height in the entire character set, so the person (who wrote the code) is trying to guess the maximum area needed.
This eliminates your loops (and replaces with them loops in the framework, hopefully faster ones). Not sure about performance.
Dim i As Integer, j As Integer, pGr As Graphics, sz As SizeF
sb.Append(new String("W", pWidth))
If pNumRows > 1 Then
sb.Append(new String(vbLf, pWidth)) ' may want to use vbCR instead
End If
pGr = txtTextBox.CreateGraphics
sz = pGr.MeasureString(sb.ToString, pTextFont, New SizeF(10000, 10000))
pGr.Dispose()
txtTextBox.SetSize(CInt(sz.Width), CInt(sz.Height) + 80)
txtTextBox.Size = New Size(CInt(sz.Width) + 20, CInt(sz.Height) + 100)