Flip text in Vb.net - vb.net

I have a problem in flipping text in VB.NET
It is flipped but with no line brake
See the Link:
http://www.spider-news.net/Flip_Text_question.JPG
Imports System.Drawing.Drawing2D
Imports System.Drawing
Public Class Form1
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
' Draw the text and the surrounding rectangle START.
Dim text1 As String = RichTextBox1.Text
Dim font1 As New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point)
Try
Dim rect1 As New Rectangle(10, 10, 1000, 140)
' Create a StringFormat object with the each line of text, and the block
' of text centered on the page.
Dim stringFormat As New StringFormat()
stringFormat.Alignment = StringAlignment.Center
stringFormat.LineAlignment = StringAlignment.Center
' Draw the text and the surrounding rectangle.
e.Graphics.DrawString(text1, font1, Brushes.Blue, rect1, stringFormat)
e.Graphics.DrawRectangle(Pens.Black, rect1)
Finally
font1.Dispose()
End Try
' Draw the text and the surrounding rectangle END.
'' FLIP TEXT ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Draw Flipped Text the text surrounding rectangle START.
Using the_font As New Font("Arial", 20, FontStyle.Bold, GraphicsUnit.Point)
DrawFlippedText(e.Graphics, the_font, Brushes.Black, 10, 10, RichTextBox1.Text, True, False)
Dim txt_size As SizeF
txt_size = e.Graphics.MeasureString(RichTextBox1.Text, the_font)
e.Graphics.DrawRectangle(Pens.Red, 10, 10, txt_size.Width, txt_size.Height)
End Using
' Draw Flipped Text the text surrounding rectangle END.
'' FLIP TEXT ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
End Sub
Public Sub DrawFlippedText(ByVal gr As Graphics, ByVal the_font As Font, ByVal the_brush As Brush, ByVal x As Integer, ByVal y As Integer, ByVal txt As String, ByVal flip_x As Boolean, ByVal flip_y As Boolean)
' Save the current graphics state.
Dim state As GraphicsState = gr.Save()
' Set up the transformation.
Dim scale_x As Integer = IIf(flip_x, -1, 1)
Dim scale_y As Integer = IIf(flip_y, -1, 1)
gr.ResetTransform()
gr.ScaleTransform(scale_x, scale_y)
' Figure out where to draw.
Dim txt_size As SizeF = gr.MeasureString(txt, the_font)
If flip_x Then x = -x - RichTextBox1.Size.Width
If flip_y Then y = -y - RichTextBox1.Size.Height
Dim rect1 As New Rectangle(10, 10, 1000, 140)
Dim stringFormat As New StringFormat()
stringFormat.Alignment = StringAlignment.Center
stringFormat.LineAlignment = StringAlignment.Center
' Draw.
gr.DrawString(txt, the_font, the_brush, x, y)
' Restore the original graphics state.
gr.Restore(state)
End Sub
End Class
Please HELP

My guess is that if the linebreaks are not there you have to split the string into single words.
Then concatenate the words one by one and measure the lenght. if it exceeds your line width draw this string and continue with the next words.
The next draw should be on y-coordinate + your line-height.
I did this in a pdf where i place a text to an absolute position which could be more than 1 line:
Dim splitted As String() = text.Split()
Dim tempchunk As Chunk = New Chunk("", pdfFont)
Dim count As Integer = 0
For Each s As String In splitted
Dim chunk2 As Chunk
chunk2 = New Chunk(tempchunk.Content, pdfFont)
chunk2.Append(" " & s)
If chunk2.GetWidthPoint() > 155 Then
cb.SaveState()
cb.BeginText()
cb.MoveText(x, y - (13 * count))
cb.SetFontAndSize(bfont, 11)
cb.ShowText(tempchunk.Content.Trim())
cb.EndText()
cb.RestoreState()
tempchunk = New Chunk(s, pdfFont)
count += 1
Else
tempchunk.Append(" " & s)
End If
Next
If tempchunk.Content <> "" Then
cb.SaveState()
cb.BeginText()
cb.MoveText(x, y - (13 * count))
cb.SetFontAndSize(bfont, 11)
cb.ShowText(tempchunk.Content.Trim())
cb.EndText()
cb.RestoreState()
End If
Its the code for the pdf but maybe it helps

Try this.
I created a bitmap, draw the string and rectangle there, flipped it, then draw the bitmap (with flipped text) on the Form.
Public Class Form1
Private Sub RichTextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RichTextBox1.TextChanged
Dim b As New Bitmap(300, 100)
Dim g As Graphics = Graphics.FromImage(b)
Dim d As Graphics = Me.CreateGraphics
Dim r As New Rectangle(0, 0, b.Width - 1, b.Height - 1)
Dim f As New StringFormat
f.Alignment = StringAlignment.Center
f.LineAlignment = StringAlignment.Center
g.Clear(BackColor)
g.DrawRectangle(Pens.Red, r)
g.DrawString(RichTextBox1.Text, RichTextBox1.Font, Brushes.Blue, r, f)
b.RotateFlip(RotateFlipType.RotateNoneFlipX)
d.DrawImageUnscaled(b, 10, 10)
g.Dispose()
b.Dispose()
d.Dispose()
End Sub
End Class

Related

Display list of colors and their names in a combobox

I'm trying to display a list of colors in a combobox. Each item in the box contains the name of a color suffixed by a rectangle filled with the corresponding color as shown in a project here.
The project is written in c#. I don't understand c# so I've converted the codes to vb .net as shown below.
Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
Dim ColorList As ArrayList = New ArrayList()
Dim colorType As Type = GetType(System.Drawing.Color)
Dim propInfoList As PropertyInfo() = colorType.GetProperties(BindingFlags.[Static] Or BindingFlags.DeclaredOnly Or BindingFlags.[Public])
For Each c As PropertyInfo In propInfoList
ComboBox1.Items.Add(c.Name)
Next
End Sub
Private Sub Combobox1_DrawItem(ByVal sender As Object, ByVal e As DrawItemEventArgs) Handles ComboBox1.DrawItem
Dim g As Graphics = e.Graphics
Dim rect As Rectangle = e.Bounds
If e.Index >= 0 Then
Dim n As String = (CType(sender, ComboBox)).Items(e.Index).ToString()
Dim f As Font = New Font("Arial", 9, FontStyle.Regular)
Dim c As Color = Color.FromName(n)
Dim b As Brush = New SolidBrush(c)
g.DrawString(n, f, Brushes.Black, rect.X, rect.Top)
g.FillRectangle(Brushes.Blue, rect.X + 110, rect.Y + 5, rect.Width - 10, rect.Height - 10)
End If
End Sub
When I execute the above code, the combo box Combobox1 displays items with only the names of the color. The colored rectangles are not displayed as show in the project I've linked above.
What's causing the rectangles not be displayed?
I've tried setting Combobox1's DrawMode to all available DrawModes. Nothing worked.
Note, I've used Telerik's code converter to convert the c# code to vb .net code.
Dim N As String = (CType(sender, ComboBox)).Items(e.Index).ToString()
Dim F As Font = New Font("Arial", 10, FontStyle.Regular)
Dim B As Brush = New SolidBrush(e.ForeColor)
Dim C As Color = Color.FromName(N)
Dim P As Brush = New SolidBrush(C)
Dim L As Pen = New Pen(e.ForeColor)
Dim R1 As Rectangle = New Rectangle(e.Bounds.Left + 2, e.Bounds.Top + 2, 50, e.Bounds.Height - 4)
Dim R2 As Rectangle = New Rectangle(e.Bounds.Left + 3, e.Bounds.Top + 3, 48, e.Bounds.Height - 6)
Dim R3 As Rectangle = New Rectangle(e.Bounds.Left + 2, e.Bounds.Top + 2, 50, e.Bounds.Height - 4)
Dim R4 As Rectangle = New Rectangle(e.Bounds.Left + 2, e.Bounds.Top + 2, 50, e.Bounds.Height - 4)
e.Graphics.DrawRectangle(L, R1)
e.Graphics.FillRectangle(P, R2)
e.Graphics.DrawString(N, F, B, e.Bounds.Left + 65, e.Bounds.Top + 2)
e.DrawFocusRectangle()

VB.NET - how to add a title on top of printed page in datagridview?

I have a windows application on VB.net 2010 and a datagridview inside,
all works fine and the printing also, but I would like to add a Title on the printed page! from textbox that I have, is it possible?
Please replay as soon as you can, and this is my PrintDocument code attached!
With DataGridView1
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = e.MarginBounds.Top
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
If (newpage) Then
e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages = True
mRow -= 1
newpage = True
Exit Sub
End If
Loop
mRow = 0
End With
And also, can I adjust the space from the top of the page?
Thanx in advance ^^
This code might works , try it . But it is a little bit different from your code.
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
With Printer
Printer.Title = "Your Title" 'You can change this by TextBox1.text
Printer.SubTitle = "Your Subtitle" 'You can change this by TextBox2.text
Printer.SubTitleFormatFlags = StringFormatFlags.LineLimit Or _
StringFormatFlags.NoClip
Printer.PageNumbers = True
Printer.PageNumberInHeader = False
Printer.PorportionalColumns = True
Printer.HeaderCellAlignment = StringAlignment.Near
Printer.Footer = "Your Footer"
Printer.FooterSpacing = 15
Printer.PrintDataGridView(Me.DataGridView1)
End With
End Sub
If the above code doesn't work , you can try this one.
Private PrintGrid As DataGridViewPrint
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
Dim fpr As New frmPrint()
With fpr
.Title = DataGridView1.CaptionText
.ShowDialog()
If .Result > 0 Then
PrintGrid = New DataGridViewPrint(PrintDocument1, DataGridView1, .bBlackWhite)
PrintGrid.PrintTitle = .bTitle
PrintGrid.Title = .Title
Select Case .Result
Case 1 ' Print
' The Print method prints the DataGridView without using a print dialog.
' Use a PrintDialog when you want to offer the user the ability to choose print settings.
If PrintDialog1.ShowDialog() = DialogResult.OK Then PrintDocument1.Print()
Case 2 ' Page Setup
PageSetupDialog1.ShowDialog()
Case 3 ' Preview
PrintPreviewDialog1.Icon = fpr.Icon
PrintPreviewDialog1.ShowDialog()
End Select
End If
End With
End Sub
' Specify the output to print by handling the PrintPage event
' and by using the Graphics included in the PrintPageEventArgs.
Private Sub printDocument1_PrintPage(ByVal sender As Object, ByVal e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
' Print method of DataGridViewPrint class starts the custom DataGridView's printing process.
e.HasMorePages = PrintGrid.Print(e.Graphics)
End Sub
I've found this solution useful!
Try to add this into Printducoment method:
' Create string to draw.
Dim drawString As [String] = "Sample Text"
' Create font and brush.
Dim drawFont As New Font("Arial", 16)
Dim drawBrush As New SolidBrush(Color.Black)
' Create rectangle for drawing.
Dim x As Single = 150.0F
Dim y As Single = 150.0F
Dim width As Single = 200.0F
Dim height As Single = 50.0F
Dim drawRect As New RectangleF(x, y, width, height)
' Draw rectangle to screen.
Dim blackPen As New Pen(Color.Black)
e.Graphics.DrawRectangle(blackPen, x, y, width, height)
' Set format of string.
Dim drawFormat As New StringFormat
drawFormat.Alignment = StringAlignment.Center
' Draw string to screen.
e.Graphics.DrawString(drawString, drawFont, drawBrush, _
drawRect, drawFormat)
And it worked just fine as drawing a text on top of my Datagrideview page ^^
Thanks 'mark ashraf' for your answers <3

How to prevent graphics from resetting [duplicate]

I need to put some graphics in one section of a TableLayoutPanel.
I'm doing this by creating a PictureBox in one cell of the TLP.
Can't get two things to work:
1) The initial display is blank! Drawing appears only when you resize the form
2) The resize event doesn't fire equally when expanding the size as compared contracting.
Any suggestions to improve the above two problems would be great!
Here is my code. The form has a 2x2 TableLayoutPanel in it, and one cell of the TLP has a PictureBox in it. Both the TLP and the PictureBox are set to Fill Parent:
Imports System.Drawing.Drawing2D
Public Class Form1
Private g As Graphics
Dim n As Integer = 0
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Debug.Print(String.Format("{0}{0}Form1_Load at {1}", vbCrLf, Now()))
Me.SetDesktopLocation(800, 200)
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
n += 1
Debug.Print(String.Format("MyBase.Paint: {0}", n))
DisplayMyStuff()
End Sub
Private Sub PictureBox1_Resize(sender As Object, e As EventArgs) Handles Pict ureBox1.Resize
n += 1
Debug.Print(String.Format("PictureBox1.Resize: {0} PictureBoxSize = {1} / {2}", n, PictureBox1.Width, PictureBox1.Height))
If g IsNot Nothing Then
g.Dispose()
End If
g = PictureBox1.CreateGraphics()
End Sub
Private Sub DisplayMyStuff()
Dim rect1 As Rectangle
Dim rect2 As Rectangle
Dim pt1 As New Point(50, 50)
Dim pt2 As New Point(100, 100)
Dim pt3 As New Point(150, 150)
Dim brR As New SolidBrush(Color.Red)
Dim linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
Dim pictBoxSize As Size
Dim sz As Size
Dim width, height As Integer
pictBoxSize = New Size(CType(PictureBox1.Size, Point))
width = CInt(pictBoxSize.Width / 2)
height = CInt(pictBoxSize.Height / 2)
sz = New Size(width, height)
n += 1
Debug.Print(String.Format("DisplayMyStuff: {0}, Half-Size = {1} / {2}", n, width, height))
g.Clear(Color.Bisque)
rect1 = New Rectangle(pt1, sz)
rect2 = New Rectangle(pt2, sz)
g.FillRectangle(brR, rect1)
g.FillRectangle(linGradBr, rect2)
brR.Dispose()
linGradBr.Dispose()
End Sub
End Class
Apparently, you are trying to draw to a picturebox (g = PictureBox1.CreateGraphics())
The reason stuff disappears is that when the size changes, or something passes over the window, the controls and form need to be repainted. This happens in the Paint event, so your code needs to do the drawing there. Unlike a PictureBox image, items drawn to a form or control are not persistent on their own, that is done by drawing in the Paint event.
This is essentially your DrawMyStuff procedure relocated to the Picbox's Paint event.
Private Sub PictureBox1_Paint(sender As Object,
e As PaintEventArgs) Handles PictureBox1.Paint
Dim pt1 As New Point(50, 50)
Dim pt2 As New Point(100, 100)
Dim pt3 As New Point(150, 150)
Dim sz As New Size(CInt(PictureBox1.Size.Width / 2),
CInt(PictureBox1.Size.Height / 2))
n += 1
Debug.Print(String.Format("DisplayMyStuff: {0},
Half-Size = {1} / {2}", n, sz.Width, sz.Height))
Dim rect1 As New Rectangle(New Point(50, 50), sz)
Dim rect2 As New Rectangle(New Point(100, 100), sz)
Using linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
e.Graphics.Clear(Color.Bisque)
e.Graphics.DrawRectangle(Pens.Black, rect1)
e.Graphics.DrawRectangle(Pens.Black, rect2)
e.Graphics.FillRectangle(Brushes.Red, rect1)
e.Graphics.FillRectangle(linGradBr, rect2)
End Using
End Sub
If you are actually trying to paint on the Form, then Grim's answer is the solution. There you respond to the Form Paint event. In either case, use the Graphics object provided by Windows as an EventArg.
Above, you are using the Graphics object for the PictureBox (via event args) so output is to the PictureBox.
Windows wont know you are drawing something in the Paint event, so you need to tell it that the image needs to be updated at certain times such as when the PictureBox is resized. In the resize event, add:
PictureBox1.Invalidate ' tell windows it needs to be redrawn
' or
PictureBox1.Refresh ' redraw now
Me.Refresh is a bit of overkill because the entire form likely does not need to be repainted.
As Hans Passant says. First get rid of;
Private g As Graphics
and the whole of the PictureBox1_Resize(...)... routine. Then change the following routines to be like so;
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
DisplayMyStuff(e.Graphics)
End Sub
and
Private Sub DisplayMyStuff(pGraphics As Graphics)
Dim pt1 As New Point(50, 50)
Dim pt2 As New Point(100, 100)
Dim pt3 As New Point(150, 150)
Dim pictBoxSize As New Size(CType(PictureBox1.Size, Point))
Dim width As Integer = CInt(pictBoxSize.Width / 2)
Dim height As Integer = CInt(pictBoxSize.Height / 2)
Dim sz As New Size(width, height)
pGraphics.Clear(Color.Bisque)
Dim rect1 As New Rectangle(pt1, sz)
Dim rect2 As New Rectangle(pt2, sz)
Using linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
pGraphics.FillRectangle(Brushes.Red, rect1)
pGraphics.FillRectangle(linGradBr, rect2)
End Using
End Sub
.. then test. Please report back to tell me that you've learned something!! Especially.. that you don't need to create a new red brush - all 'standard' colours are built in - and that using the graphics object properly leads to better, smoother displays.

A Graphics object cannot be created from an image that has an indexed pixel format

I have a program that when you click on picturebox1, it transfers the image inside it to picturebox2. Then I have an interpolation code to modify it to a nearestneighbor pixel rendering. It also draws a pixel grid on picturebox2 to line up around the pixels. I have picturebox2 set to stretch image. I tried 2 different methods of drawing on the picturebox2. I am having a problem converting the image back to the right size to transfer it back to picturebox1 after its been edited with the paintbrush.
CODE:
Imports System.Windows.Forms
Imports System.Drawing
Imports System
Imports System.IO
Public Class Form1
Dim Brush = Brushes.Black
Dim COLOR1 As Color
Dim BMP As Bitmap
Dim Draw As Boolean
CODE: when you click on the picturebox1(topleft) it transfers its image to picturebox2(canvaseditor) does the grid draw, interpolate mode etc.
Private Sub topleft_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles topleft.Click
tiledcanvas.BackgroundImage = topleft.Image
Label1.Text = "Top-Left"
'CANVAS PIXEL GRID CODE
If topleft.Image Is Nothing Then
Else
canvaseditor.Image = Nothing
canvaseditor.Image = topleft.Image
canvaseditor.Width = topleft.Width * 8 + 1
canvaseditor.Height = topleft.Height * 8 + 1
'load and draw the image(s) once
BackgroundImage1 = New Bitmap(topleft.Image)
bmpNew = New Bitmap(canvaseditor.Width * scaleFactor, canvaseditor.Height * scaleFactor)
Using g As Graphics = Graphics.FromImage(bmpNew)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half
g.DrawImage(BackgroundImage1, 0, 0, bmpNew.Width, bmpNew.Height)
End Using
canvaseditor.Focus()
GroupBox13.Focus()
End If
End Sub
CODE: the paintbrush code, the mousedown, mousemove, and mouseup events on picturebox2(canvaseditor)
Private Sub canvaseditor_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseMove
If Draw = True Then
PaintBrush(e.X, e.Y)
Else
End If
'If down = True Then
'canvaseditor.CreateGraphics.FillRectangle(Brush, e.X, e.Y, 8, 8)
'End If
' LocalMousePosition = canvaseditor.PointToClient(Cursor.Position)
'Dim X As Integer
'Dim Y As Integer
'If LocalMousePosition.X > 0 And LocalMousePosition.X < 9 Then
'X = 1
' ElseIf LocalMousePosition.X > 8 And LocalMousePosition.X < 17 Then
'X = 2
'ElseIf LocalMousePosition.X > 16 And LocalMousePosition.X < 25 Then
'X = 3
'End If
'Label6.Text = (X & ", " & Y)
End Sub
Private Sub PaintBrush(ByVal X As Integer, ByVal Y As Integer)
Using g As Graphics = Graphics.FromImage(canvaseditor.Image)
g.FillRectangle(New SolidBrush(Color.Black), New Rectangle(X, Y, 6, 6))
End Using
canvaseditor.Refresh()
End Sub
Private Sub canvaseditor_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseDown
'down = True
'If down = True Then
'Dim NEWBMP As New Bitmap(topleft.Width, topleft.Height)
'Dim graph As Graphics = Graphics.FromImage(NEWBMP)
' graph.FillRectangle(Brush, e.X, e.Y, 8, 8)
'topleft.Image = NEWBMP
'End If
'down = True
'If down = True Then
'canvaseditor.CreateGraphics.FillRectangle(Brush, e.X, e.Y, 8, 8)
'End If
Draw = True
PaintBrush(e.X, e.Y)
End Sub
Private Sub canvaseditor_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles canvaseditor.MouseUp
Draw = False
End Sub
and heres the first paint sub i made:
Private Sub canvaseditor_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles canvaseditor.Paint
If Not bmpNew Is Nothing Then
e.Graphics.DrawImage(bmpNew, 0, 0)
End If
Dim g As Graphics = e.Graphics
Dim pn As New Pen(Color.DimGray) '~~~ color of the lines
Dim x As Integer
Dim y As Integer
Dim intSpacing As Integer = 8 '~~~ spacing between adjacent lines
'~~~ Draw the horizontal lines
x = canvaseditor.Width
For y = 0 To canvaseditor.Height Step intSpacing
g.DrawLine(pn, New Point(0, y), New Point(x, y))
Next
'~~~ Draw the vertical lines
y = canvaseditor.Height
For x = 0 To canvaseditor.Width Step intSpacing
g.DrawLine(pn, New Point(x, 0), New Point(x, y))
Next
End Sub
hoping this is understandable so someone can point me in the right direction. thanks.

vb.net 2010 PrintDocument Margins not working even if I set the margins

I am reading from a text file and then printing the string using printdocument via vb.net 2010.
Here is my code :
Public Class myPrinter
Friend TextToBePrinted As String
Public Sub prt(ByVal text As String)
Dim psize As New System.Drawing.Printing.PaperSize("Custom Paper Size", 850, 550)
Dim newMargins As New System.Drawing.Printing.Margins(0, 0, 0, 0)
TextToBePrinted = text
Dim prn As New Printing.PrintDocument
Using (prn)
prn.PrinterSettings.PrinterName = frmStockOut.printer
prn.PrinterSettings.Copies = frmStockOut.copies
prn.PrinterSettings.DefaultPageSettings.PaperSize = psize
prn.PrinterSettings.DefaultPageSettings.Margins = newMargins
prn.DefaultPageSettings.PaperSize = psize
prn.DefaultPageSettings.Margins = newMargins
AddHandler prn.PrintPage, _
AddressOf Me.PrintPageHandler
prn.Print()
RemoveHandler prn.PrintPage, _
AddressOf Me.PrintPageHandler
End Using
End Sub
Private Sub PrintPageHandler(ByVal sender As Object, _
ByVal args As Printing.PrintPageEventArgs)
Dim myFont As New Font("Courier New", 11)
args.Graphics.DrawString(TextToBePrinted, _
New Font(myFont, FontStyle.Regular), _
Brushes.Black, 50, 50)
End Sub
End Class
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim charactersOnPage As Integer = 0
Dim linesPerPage As Integer = 0
' Sets the value of charactersOnPage to the number of characters
' of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, Me.Font, e.MarginBounds.Size, _
StringFormat.GenericTypographic, charactersOnPage, linesPerPage)
' Draws the string within the bounds of the page
e.Graphics.DrawString(stringToPrint, Me.Font, Brushes.Black, _
e.MarginBounds, StringFormat.GenericTypographic)
' Remove the portion of the string that has been printed.
stringToPrint = stringToPrint.Substring(charactersOnPage)
' Check to see if more pages are to be printed.
e.HasMorePages = stringToPrint.Length > 0
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
ReadFile() ' will read text file and store in a string
Dim Print As New myPrinter
Dim myprintdialog As New PrintDialog
With myprintdialog
If .ShowDialog = Windows.Forms.DialogResult.OK Then
printer = .PrinterSettings.PrinterName
copies = .PrinterSettings.Copies
Print.prt(stringToPrint)
End If
End With
End Sub
The problem is even after I set the left margin and top margin to 0, it seems nothing has changed, it is still printing almost 3/4 inch for top margins and 1 inch for the left margin. This is also the output when I didn't set the margins. However, when I prn.OriginAtMargins = True , the output becomes a little different, left margin is now almost 1/2 inch but top margin remains the same. Something wrong with my code?
What I want to accomplish is the top margin can be set at approximately 20 pixels (assuming 100 pixels is equal to 1 inch) and left margin be set at 20 pixels too. Hope somebody can help me.