I have created PdfTemplate with some contour. Now i want to duplicate it 4 times and place different shapes on each of them. What I am trying now is:
PdfTemplate[] oRTA = new PdfTemplate[4];
for(int i=0; i<4; i++)
{
oRTA[i] = (PdfTemplate)oTemplate.GetDuplicate(false);
}
Where oTemplate is my standard PdfTemplate object. Problem can be that I can't use overwritten GetDuplicate method, so i have to cast it (dunno why). I am trying this with simple points:
oRTA[iTemplateIndex].Circle(oCmp.iXLocation, oCmp.iYLocation, 0.1f);
oRTA[iTemplateIndex].Stroke();
In result I've got nothing printed. Attempt with:
oTemplate.Circle(oCmp.iXLocation, oCmp.iYLocation, 0.1f);
oTemplate.Stroke();
works.
Solution is not to duplicate your Template but to create it 4 times (4 different PdfTemplate objects) and then add what you need to every one of them. I know maybe it is now the best option but it work as it should. Solution given by Bruno Lowagie seems to be adequate too :)
Related
New programmer here. I'm trying to add a range of elements to a new list in C#. This is for a game I'm making in Unity. It's a game based on the old nokia Snake game, where each time the snake eats a fruit it gets longer. This information is stored in a list in my game. Now the thing is I'm trying to create a game element where at a certain point all the nodes from the snake (the tail basically) break away from the snake itself, and the snake has 3 elements remaining (the head, body, and a tail). I got it to work perfectly fine, except for the fact I can't get the range of nodes in the list to transfer to the newNode list for the life of me.
for (int i = 0; i < nodes.Count; i++)
{
if (nodes.Count > 3)
{
newNodes.Add(nodes[4]);
newNodes.Add(nodes[5]);
newNodes.Add(nodes[6]);
newNodes.AddRange(nodes[3], nodes.Count - 3);
nodes.RemoveRange(3, nodes.Count - 3);
}
When I run the game, the expected behavior works for the newNodes.Add (individual nodes). But what I would like is to see happen is something along the lines of newNodes.AddRange(nodes[3], nodes.Count - 3); But that doesn't work. How can I get it so it reads the nodes from 3 or 2 or whatever value to the total nodes in the list. I've been stuck on this for days! Really could use some help/input.
The code above is not complete, it's part of a coroutine actually that should get called after certain criteria has been met. It's just that I wonder if there's any way to do this?
Using the LINQ extension method Skip you can skip over the first part of a list and get the rest. As it is an extension method, you first need this near the top of your code file:
using System.Linq;
Then you can use this to add all but the first three items to the new list:
newNodes.AddRange(nodes.Skip(3));
Note: this doesn't change "nodes" in any way.
Bonus: if "nodes" contains 3 items or less, this will not fail (but of course add nothing to newNodes)
Try this :
newNodes.InsertRange(newNodes.Count - 1, nodes.GetRange(3, nodes.Count - 3));
nodes.RemoveRange(3, nodes.Count - 3);
If newNodes is empty, you need to make sure to pass 0 as index instead of
newNodes.Count - 1
As said, I'm a new programmer and have never used Stackoverflow. I'm truly overwhelmed by all the responses in such a short time, thank all for taking the time to read my question and trying to figure it out with me.
The code that seemed to work in my case was
newNodes.InsertRange(newNodes.Count, nodes.GetRange(3, nodes.Count - 3));
It basically captures all the nodes (snake bodies) in the list and releases them properly in a new list!
Again thanks!!
The problem is when you use
newNodes.AddRange(nodes[3], nodes.Count - 3);
you're only providing the single node at index 3. AddRange expects an IEnumerable, not a single object from a list. To get an IEnumerable you have to use the GetRange or LINQ methods that have already been posted by others.
I've been developing a Word-AddIn (Office 365 version 1706, Windows 10) which basically stores data in charts so they could be fed updated data from our servelets and ultimately the chart updates itself with all the data it needs.
This works perfectly fine EXCEPT when I alter the layout options for a chart from the default "In Line with Text" to "With Text Wrapping" to have multiple charts next to each other for example.
How this works, as long as you don't alter the layout options, is by accessing the Microsoft.Office.Interop.Word.Application COM object, which has a Selection object, which furthermore has InlineShapes, is like so:
var inlineShapes = Application.Selection.InlineShapes;
if(inlineShapes > 0)
{
for(var i = 1; i < inlineShapes.Count + 1; i++)
{
if (inlShape.HasChart == MsoTriState.msoTrue)
return new WordChart(inlShape);
}
}
For sake of simplicity I spared you the whole ordeal of dealing with COM objects.
Again, this works if you don't tamper with the layout options of the chart, but as soon as the layout has been altered to say "Behind Text" I can't find that chart in any InlineShape.
Has anyone experienced this before?
I've combed through the Application.Selection object and couldn't find anything.
However the InlineShape is still in the Application.InlineShapes object itself, but how would I know which one is to be selected?
I would really appreciate ANY input, because as of now I have no idea on what to do anymore.
Ok, I finally found those little charts!
This Stackoverflow post helped me:
How to check which shapes/objects are selected/active?
More details to what solved my problem:
Once I changed the the layout options (see original question) I wouldn't be able to find Charts as InlineShapes anymore.
Instead they would be listed under Selection.ShapeRange.get_Item(i) (I checked for Shapes/InlineShapes, so I didn't see items as what a chart could be).
Now you could either convert them to InlineShapes, which does exactly that, in Word as well, which you don't want, or convert that Shape to your VSTO.WordChart, which I did.
I am trying to cast AcroFields to the specific types so I can set properties on them.
When I call AcroFields.GetField(string name); all I get is a string.
When I call AcroFields.GetFieldItem(string name); I get an object but cannot cast it to the specific type.
I have also tried:
AcroFields.SetFieldProperty("myfield", "CheckType", RadioCheckField.TYPE_STAR, null);
This returned false every time.
To better explain my scenario:
I have an existing PDF ( I am NOT generating this file ).
There is a checkbox in it. I want to change the "CheckType" like this:
myRadioCheckField.CheckType = RadioCheckField.TYPE_STAR
But since I cannot cast the AcroField to the specific type I cannot access that property "CheckType".
Is there a way to achieve this?
Please provide a working sample if possible.
Thank you.
Your post contains two different questions. One question is easy to answer. The other question is impossible to answer.
Let's start with the easy question:
How to get specific types from AcroFields? Like PushButtonField, RadioCheckField, etc
This is explained in the FormInformation example, which is part of chapter 6 of my book:
PdfReader reader = new PdfReader(datasheet);
// Get the fields from the reader (read-only!!!)
AcroFields form = reader.AcroFields;
// Loop over the fields and get info about them
StringBuilder sb = new StringBuilder();
foreach (string key in form.Fields.Keys) {
sb.Append(key);
sb.Append(": ");
switch (form.GetFieldType(key)) {
case AcroFields.FIELD_TYPE_CHECKBOX:
sb.Append("Checkbox");
break;
case AcroFields.FIELD_TYPE_COMBO:
sb.Append("Combobox");
break;
case AcroFields.FIELD_TYPE_LIST:
sb.Append("List");
break;
case AcroFields.FIELD_TYPE_NONE:
sb.Append("None");
break;
case AcroFields.FIELD_TYPE_PUSHBUTTON:
sb.Append("Pushbutton");
break;
case AcroFields.FIELD_TYPE_RADIOBUTTON:
sb.Append("Radiobutton");
break;
case AcroFields.FIELD_TYPE_SIGNATURE:
sb.Append("Signature");
break;
case AcroFields.FIELD_TYPE_TEXT:
sb.Append("Text");
break;
default:
sb.Append("?");
break;
}
sb.Append(Environment.NewLine);
}
// Get possible values for field "CP_1"
sb.Append("Possible values for CP_1:");
sb.Append(Environment.NewLine);
string[] states = form.GetAppearanceStates("CP_1");
for (int i = 0; i < states.Length; i++) {
sb.Append(" - ");
sb.Append(states[i]);
sb.Append(Environment.NewLine);
}
// Get possible values for field "category"
sb.Append("Possible values for category:");
sb.Append(Environment.NewLine);
states = form.GetAppearanceStates("category");
for (int i = 0; i < states.Length - 1; i++) {
sb.Append(states[i]);
sb.Append(", ");
}
sb.Append(states[states.Length - 1]);
This code snippet stores the types of the fields in a StringBuilder, as well as the possible values of a radio field and a check box.
If you execute it on datasheet.pdf, you get form_info.txt as a result.
So far so good, but then comes the difficult question:
How do I find the check type? How do I change it?
That question reveals a lack of understanding of PDF. When we looked for the possible values of a check box (or radio button) in the previous answer, we asked for the different appearance states. These appearance states are small pieces of content that are expressed in PDF syntax.
For instance: take a look at the buttons.pdf form.
When we look at it on the outside, we see:
The check box next to "English" can be an empty square or a square with a pinkish background and a cross. Now let's take a look at the inside:
We see that this is the table check box, and we see that there are two appearance states: /Yes and /Off. What these states look like when selected, is described in a stream.
The stream of the /Off state is rather simple:
You immediately see that we are constructing a rectangle (re) and drawing it without filling it (S).
The /Yes state is slightly more complex:
We see that the fill color is being changed (rg), and that we stroke the rectangle in black and fill it using the fill color that was defined (B). Then we define two lines with moveTo (m) and lineTo (l) operations and we stroke them (S).
If you are proficient in PDF syntax, it is easy to see that we're drawing a cross inside a colored rectangle. So that answers your question on condition that you're proficient in PDF...
If you want to replace the appearance, then you have to replace the stream that draws the rectangle and the cross. That's not impossible, but it's a different question than the one you've posted.
Summarized: There is no such thing as a TYPE_STAR in the PDF reference (ISO-32000-1), nor in any PDF. If you have an existing PDF, you can not cast a check box or radio button to a RadioCheckField. You could try to reconstruct the RadioCheckField object, but if you'd want to know if a check box is visualized using a check mark, a star,... then you have to interpret the PDF syntax. If you don't want to do that, you can't create the "original" RadioCheckField object that was used to create the PDF due to the lack of ready-to-use information in the PDF.
After some research I have come to the conclusion that at this point in time, with the current version of iTextSharp v5.5.7.0:
It is NOT possible to grab an AcroField and cast it back to the original class ( RadioCheckField ) that was used to generate the field in the first place.
So the specific classes like PushButtonField and RadioCheckField are only useful for generating a new PDF but not for editing an existing PDF.
This cannot be done.
As far as I know iTextSharp does not support casting from AcroField back to the orginal class ( RadioCheckField ) that was used to generate the field.
You would have to write your own code to parse and inspect the PDF to achieve this.
May i ask if the following code i wrote is correct? Basically, i want to create an 2D array, and within each array, i want to have a list of vertices. So if tCount and pCount is 10, i would have 100 different lists storing vertices. The adding of the vertices will be done elsewhere after certain operations are done to determine which list the vertice should be added to.
List<Vertice>[,] lists = new List<Vertice>[tCount, pCount];
for (int i = 0; i < tCount; i++) {
for (int o = 0; o < pCount; o++) {
lists[i,o] = new List<Vertice>(); } }
Pardon me for posting such a simple question, because i have posted a similar qns in another forum and the replies i received kind of confused me. But thanks for reading!
Mitch Wheat- There was no error so far, but i am also not sure if the list is created properly..
Damith- I've seen that before but i do not really understand the code, so i was wondering if the code i typed was correct or not. I feel safer using a code that i understand, although i do understand the benefits of using a 1-liner.
Oberdan Nunes- I need it to be in a 2D array, as it is related to another 2D array of data which i have.
I have a school assignment, visualization of sorting algorithms (mergesort, bubblesort). I looked at libraries like Processing, JsAnim, cake and couple of others but not sure whether they will be useful for my application (visualizing sort algorithms).
I am familiar with C# and little javascript. any libraries that would be appropriate for my need?
Thanks a lot
You haven't clarified what language you want to use. I will assume its java because of your tags. If you are allowed to site outside resources you could use an object written by Dr. Robert Sedgewick and Dr. Kevin Wayne of Princeton University. It is called StdDraw and is from their book Algorithms, 4th Edition. The URL for source code is here:
http://algs4.cs.princeton.edu/stdlib/StdDraw.java.html
If you cannot use outside sources I would recommend Java Swing Package.
I had such task when was writing parallel sorting. I used C# ZedGraph library:
ZedGraph tutorial
The main idea was to represent the value of sort element like a vertical line with appropriate height( like a histogram).
This how it looks before sotring:
And after:
So we see that all elements is sorted.
To visualize every step of process I changed values of zedgraph control and refresh it. In my code it looked like:
private static void CreateGraph3(ZedGraphControl zgc)
{
// get a reference to the GraphPane
GraphPane pane = zgc.GraphPane;
// Set the Titles
pane.Title.Text = "Sorting";
//Clear current values
pane.CurveList.Clear();
// histogram high
double[] values = new double[n];
//fill values
for (int i = 0; i < n; i++)
{
values[i] = A1[i]; //A1 is an array that is currently sort
}
//create histogram
BarItem curve = pane.AddBar("Elements", null, values, Color.Blue);
pane.BarSettings.MinClusterGap = 0.0F; //set columns references
// update axis
zgc.AxisChange();
// update graph
zgc.Invalidate();
}
I call this function every time some values has been sorted, so we see a video of whole process of sorting.
To include current library to your project you need to:
1) Right click on your toolbox
2) Choose (or add) items
3) Browse, Select ZedGraph.DLL and press OK
4) ZedGraphControl will be added to your toolbox and you can use it like another controls.
So this is it, good luck
If you don't mind excluding old or crappy browsers, you could use CSS3 animations. Just set up a bunch of lis representing the items in your list, give them position:absolute and manipulate each li's top attribute to shuffle them around.
The web doesn't seem to have grown a good, definitive reference guide yet, but some examples of CSS3 animations are here.
Processing should be great for visualising sort algorithms.
An example: http://www.openprocessing.org/sketch/29208