Below is a Method which prints Testing string. I am unable to figure out why this gives unlimited new pages with same contents. I need to print a new page after 30th round.
private void PrintSetup(Graphics g, System.Drawing.Printing.PrintPageEventArgs e)
{
float linesPerPage = 0;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
float rightMargin = e.MarginBounds.Right;
float bottomMargin = e.MarginBounds.Bottom;
float Height = e.MarginBounds.Height;
float Width = e.MarginBounds.Width;
float FontHeight = NormalFont.GetHeight();
linesPerPage = Height / NormalFont.GetHeight(e.Graphics);
while (count < linesPerPage)
{
g.DrawString("Test " + count, NormalFont, BlackBrush, leftMargin, topMargin + Line(count));
if (count > 30)
{
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
}
count++;
}
}
You never reset count once you reached 30.
Thank you Everyone for Answering me... After long long time i founded what happened.. and the below code works fine.
Which will Create a new page if the count goes out of bounds.
Hope this will help for the beginners. thanks
_Line = 0;
void printDocument1_PrintPage( object sender, System.Drawing.Printing.PrintPageEventArgs e )
{
float lineHeight = NormalFont.GetHeight(e.Graphics) + 4;
float yLineTop = e.MarginBounds.Top;
yLineTop = yLineTop + 100;
for ( ; _Line <= 100 ; _Line++ )
{
if ( yLineTop + lineHeight > e.MarginBounds.Bottom )
{
e.HasMorePages = true;
return;
}
e.Graphics.DrawString( "TEST: " + _Line, NormalFont, Brushes.Black, new PointF( e.MarginBounds.Left, yLineTop ) );
yLineTop += lineHeight;
}
e.HasMorePages = false;
}
Related
I want to fix OnGUI method inside in a script to a panel. Especially what I want to do is, In free aspect, when I change the size of game screen, also my text which is writen with onGUI changes depending on size of the game screen.
public HumanBodyVisualizer bodyVisualizer;
public GameObject text;
Vector2 scrollPosition = Vector2.zero;
float scrollPosition_y = 30;
private void OnGUI()
{
//Debug.Log(text.transform.position.y);
int subPartsSpacing = 0;
float spacing = 30;
float x = 7 + spacing;
float y = text.transform.position.y;
HumanBodyPart mainBodyPart = bodyVisualizer.BodyData.Body.SubParts[0];
List<HumanBodyPart> nextPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
List<HumanBodyPart> allPartsToRender = new List<HumanBodyPart>(new HumanBodyPart[] { mainBodyPart });
scrollPosition = GUI.BeginScrollView(new Rect(7, 68, 236, 426), scrollPosition, new Rect(7, 68, 500, scrollPosition_y));
GUI.backgroundColor = Color.clear;
while (nextPartsToRender.Count > 0)
{
HumanBodyPart currentPart = nextPartsToRender[0];
nextPartsToRender.RemoveAt(0);
if(GUI.Button(new Rect(currentPart.DrawDepth * spacing + x + subPartsSpacing, y, 200, 20), currentPart.EnglishTitle))
{
HumanBodyVisualizer.ShowMode showModeFullBody = HumanBodyVisualizer.ShowMode.Invisible;
bodyVisualizer.ShowBody(showModeFullBody);
List<HumanBodyPart> AllSubPartsAndRoot = new List<HumanBodyPart>();
AllSubPartsAndRoot.Insert(0, currentPart);
allSubPartsOfClickButton(currentPart, AllSubPartsAndRoot, 1);
HumanBodyVisualizer.ShowMode showModeCurrentPart = HumanBodyVisualizer.ShowMode.LowTransparent;
//bodyVisualizer.ShowBodyPart(showModeCurrentPart, currentPart);
for (int i = 0; i < AllSubPartsAndRoot.Count; i++)
{
bodyVisualizer.ShowBodyPart(showModeCurrentPart,AllSubPartsAndRoot[i]);
}
/*
List<String> modelList = currentPart.ModelList;
for(int i = 0; i < modelList.Count; i++)
{
Debug.Log(modelList[i]);
}
*/
}
if (currentPart.SubParts.Count != 0)
{
if (GUI.Button(new Rect(x - spacing + currentPart.DrawDepth * spacing + subPartsSpacing, y, 20, 20), "+"))
{
if (!currentPart.IsExpanded)
{
currentPart.IsExpanded = true;
subPartsSpacing += 20;
}
else
currentPart.IsExpanded = false;
}
if (currentPart.IsExpanded)
{
nextPartsToRender.InsertRange(0, currentPart.SubParts);
allPartsToRender.InsertRange(allPartsToRender.Count - 1, currentPart.SubParts);
scrollPosition_y = allPartsToRender.Count * spacing ;
}
}
y += spacing;
}
// End the scroll view that we began above.
GUI.EndScrollView();
}
private void allSubPartsOfClickButton(HumanBodyPart root, List<HumanBodyPart> AllSubparts,int a)
{
AllSubparts.Insert(a, root);
a++;
for(int i = 0; i < root.SubParts.Count; i++)
{
allSubPartsOfClickButton(root.SubParts[i], AllSubparts, a);
}
}
When I run like that, even I change the size of game screen, OnGUI text(Buttons , labels and scrollview) stay constant on the screen.
I can not use Unity UI. I have to handle this problem with using onGUI.
I have an issue with my WinForms project. I need to display image of created maze and i use bitmap. But empty bitmap(9990, 9990) takes 400MB+. Is there way to decrease this memory consumption or i need to change bitmap to anything else?
Bitmap bm = new Bitmap(9990, 9990);
Thank you for your help.
The cell and wall have one size 10x10 px.
https://i.stack.imgur.com/yj9CA.png
I decreased the memory usage by using a custom PixelFormat;
It reduced memory consumption by 2-4 times.
var format = System.Drawing.Imaging.PixelFormat.Format16bppRgb565;
inBm = new Bitmap(
CellWid * (maze.finish.X + 2),
CellHgt * (maze.finish.Y + 2), format);
Is there a way to decrease memory consumption? As long as you do not need the whole maze rendered at once there is. You use 10*10*4 = 400B to store information about one cell. Chances are, you only need to know if the cell is a wall or not. That is 1 bit. You can reduce 400MB to 125kB to store information about the whole maze. And render only the part you actually need. Here is some code to play with, this draws 999x999 cells "maze" you can move by mouse
BitArray maze = null;
int mazeWidth = 999;
int mazeHeight = 999;
int xPos = 0;
int yPos = 0;
int cellSize = 10;
private void Form1_Load(object sender, EventArgs e)
{
maze = new BitArray(mazeWidth * mazeHeight);
Random rnd = new Random();
for (int i = 0; i < maze.Length; ++i)
{
maze[i] = rnd.Next(4) == 0;
}
xPos = -Width / 2;
yPos = -Height / 2;
DoubleBuffered = true;
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
for (int y = Math.Max(0, yPos / cellSize); y < mazeHeight; ++y)
{
int yDraw = y * cellSize - yPos;
if (yDraw > Height) { return; }
for (int x = Math.Max(0, xPos / cellSize); x < mazeWidth; ++x)
{
if (maze[x + y * mazeWidth])
{
int xDraw = x * cellSize - xPos;
if (xDraw > Width) { break; }
e.Graphics.FillRectangle(
Brushes.Black,
xDraw,
yDraw,
cellSize,
cellSize
);
}
}
}
}
public static int Clamp(int value, int min, int max)
{
if (value < min) { return min; }
if (value > max) { return max; }
return value;
}
int fromX;
int fromY;
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
fromX = e.X;
fromY = e.Y;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
int w2 = Width / 2;
int h2 = Height / 2;
xPos = Clamp(xPos + fromX - e.X, -w2, mazeWidth * cellSize - w2);
yPos = Clamp(yPos + fromY - e.Y, -h2, mazeHeight * cellSize - h2);
fromX = e.X;
fromY = e.Y;
Invalidate();
}
}
I want to print 50 labels per sheet (5 columns and 10 rows). When it goes to the 11th row it should switch to the next page. I have tried e.hasMorePages in several ways, but sometimes it gets overlapped on the same page.
Here is my code:
private void MakingLabel(int curentIndex,List<BarcodesSpecs> List)
{
int ListRows = List.Count;
BarcodesSpecs barcodesSpecs = List.ElementAt(curentIndex);
BarCode_ItemCode = barcodesSpecs.ItemCodeMain;
BarCode_Description = barcodesSpecs.Description;
BarCode_SalePrice = barcodesSpecs.SalePrice;
BarCode_Size = barcodesSpecs.Size;
BarCode_Colour = barcodesSpecs.Colour;
barCode_LabelToPrint = Convert.ToInt16(barcodesSpecs.QtyToPrint);
}
int xCord = 0, yCord = 0;
int CurentIndex = 0;
int MaxCharactersInString = 26;
private void printBarcodes_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
for (CurentIndex = 0; CurentIndex < BcList.Count; CurentIndex++)
{
MakingLabel(CurentIndex, BcList);
for (int i = 0; i < barCode_LabelToPrint; i++) //// making Copies means How many Labels Of this Item Needed
{
if (xCord >= 750)
{
xCord = 0;
yCord += 115;
}
if (BarCode_Description.Length > MaxCharactersInString)
{
BarCode_Description = BarCode_Description.Substring(0, MaxCharactersInString);
}
e.Graphics.DrawString("ALPIAL SUITING", new Font("Arial", 10, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 10));
e.Graphics.DrawString("Rs" + BarCode_SalePrice + "/-", new Font("Arial", 14, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 21));
e.Graphics.DrawString("Size: " + BarCode_Size + " Colour: " + BarCode_Colour, new Font("Arial", 07, FontStyle.Regular), Brushes.Black, new Point(xCord, yCord + 42));
e.Graphics.DrawString(BarCode_Description, new Font("Arial", 07, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 52));
e.Graphics.DrawString(BarCode_ItemCode, new Font("Arial", 06, FontStyle.Bold), Brushes.Black, new Point(xCord, yCord + 62));
Zen.Barcode.Code128BarcodeDraw barcode = Zen.Barcode.BarcodeDrawFactory.Code128WithChecksum;
e.Graphics.DrawImage(barcode.Draw(BarCode_ItemCode, 25), xCord, yCord + 72);
xCord += 160;
}
}
}
The result I am getting is in the picture, any help will be appreciated thanks!
Somewhere along the line, you will need to check if yCord is beyond the bottom of the page. If it is, you need to set HasMorePages to true and exit the PrintPage handler. It will be called again for the next page. You'll have to keep track of which labels you have already printed outside the PrintPage handler and continue from that point.
Here's a sample I did to simulate labels printing. I only drew a square to represent the label. I had to do a little math to figure out the spacing so you will likely have to adjust this for your situation.
private static void doPrintPreview()
{
var pd = new PrintDocument();
pd.PrintPage += pd_PrintPage;
var prv = new PrintPreviewDialog();
prv.Document = pd;
prv.ShowDialog();
}
//Units are in 1/100 of an inch
private static float leftMargin = 100f; //Page margins
private static float rightMargin = 750f;
private static float topMargin = 100f;
private static float bottomMargin = 1000f;
private static int numLabelsToPrint = 200; //How many we want to print
private static int numLabelsPrinted = 0; //How many we have already printed
private static float labelSizeX = 75; //Label size
private static float labelSizeY = 75f;
private static float labelGutterX = 7.14f; //Space between labels
private static float labelGutterY = 7.5f;
static void pd_PrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.PageUnit = GraphicsUnit.Display; //Units are 1/100 of an inch
//start at the left and top margin of the page for a new page
float xPos = leftMargin;
float yPos = topMargin;
using (var p2 = new Pen(Brushes.Red, 3.0f))
{
//While there are still labels to print
while (numLabelsPrinted < numLabelsToPrint)
{
//Draw the label (i just drew a square)
e.Graphics.DrawRectangle(Pens.Red, xPos, yPos, labelSizeX, labelSizeY);
numLabelsPrinted++;
//Set the x position for the next label
xPos += (labelSizeX + labelGutterX);
//If the label will be printed beyond the right margin
if ((xPos + labelSizeX) > rightMargin)
{
//Reset the x position back to the left margin
xPos = leftMargin;
//Set the y position for the next row of labels
yPos += (labelSizeY + labelGutterY);
//If the label will be printed beyond the bottom margin
if ((yPos + labelSizeY) > bottomMargin)
{
//Reset the y position back to the top margin
yPos = topMargin;
//If we still have labels to print
if (numLabelsPrinted < numLabelsToPrint)
{
//Tell the print engine we have more labels and then exit.
e.HasMorePages = true;
//Notice after setting HasMorePages to true, we need to exit from the method.
//The print engine will call the PrintPage method again so we can continue
//printing on the next page.
break; //you could also just use return here
}
}
}
}
}
}
please some one help me , i have to print a document in multiple pages in c#, i went through internet then used this code but not working, (loop is again start after printing one page )
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
try
{
Graphics graphic = e.Graphics;
SolidBrush brush = new SolidBrush(Color.Black);
Font font = new Font("Courier New", 12);
float pageWidth = e.PageSettings.PrintableArea.Width;
float pageHeight = e.PageSettings.PrintableArea.Height;
float fontHeight = font.GetHeight();
int startX = 40;
int startY = 30;
int offsetY = 40;
for (int i = 0; i < 100; i++ )
{
graphic.DrawString("Line: " + i, font, brush, startX, startY + offsetY);
offsetY += (int)fontHeight;
if (offsetY >= pageHeight)
{
e.HasMorePages = true;
offsetY = 0;
return;
}
else
{
e.HasMorePages = false;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Whenever you set e.HasMorePages = true, it will just fire the printDocument1_PrintPage() event handler again. You need to keep a class variable for i, so that it won't restart at 0 every time the next page prints. Don't declare it locally inside the event handler.
private class MyPrinter
{
private int i = 0;
private void Print()
{
i = 0;
printDocument1.Print();
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
.....
.....
.....
while (i < 100)
{
graphic.DrawString("Line: " + i, font, brush, startX, startY + offsetY);
offsetY += (int)fontHeight;
if (offsetY >= pageHeight)
{
e.HasMorePages = true;
offsetY = 0;
return;
}
else
{
e.HasMorePages = false;
}
i = i + 1;
}
}
}
Although there are some tutorials on web, I'm still lost on why this doesn't print multiple pages correctly. What am I doing wrong?
public static void printTest()
{
PrintDialog printDialog1 = new PrintDialog();
PrintDocument printDocument1 = new PrintDocument();
printDialog1.Document = printDocument1;
printDocument1.PrintPage +=
new PrintPageEventHandler(printDocument1_PrintPage);
DialogResult result = printDialog1.ShowDialog();
if (result == DialogResult.OK)
{
printDocument1.Print();
}
}
static void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics graphic = e.Graphics;
SolidBrush brush = new SolidBrush(Color.Black);
Font font = new Font("Courier New", 12);
e.PageSettings.PaperSize = new PaperSize("A4", 850, 1100);
float pageWidth = e.PageSettings.PrintableArea.Width;
float pageHeight = e.PageSettings.PrintableArea.Height;
float fontHeight = font.GetHeight();
int startX = 40;
int startY = 30;
int offsetY = 40;
for (int i = 0; i < 100; i++)
{
graphic.DrawString("Line: " + i, font, brush, startX, startY + offsetY);
offsetY += (int)fontHeight;
if (offsetY >= pageHeight)
{
e.HasMorePages = true;
offsetY = 0;
}
else {
e.HasMorePages = false;
}
}
}
You can find an example of this code's printed result here: Printed Document
You never return from the loop. Change it to:
if (offsetY >= pageHeight)
{
e.HasMorePages = true;
offsetY = 0;
return; // you need to return, then it will go into this function again
}
else {
e.HasMorePages = false;
}
In addition you need to change the loop to start at the current number on the 2nd page instead of restarting with i=0 again.