I load pdfdoc, by:
PdfReader pdfReader = new PdfReader(byteArray);
LocationTextExtractionStrategyEx st3 = new LocationTextExtractionStrategyEx();
PdfTextExtractor.GetTextFromPage(pdfReader, 1, st3);
Now I can get list of page elements from st3.TextLocationInfo. Every element has property TopLeft and BottomRight, they are Vector.
How can I get element position if I don't know max value of scale. I know that vector start on left bottom page corner but I don't know where is end because I don't know page size in the same scale like vector.
I can run
var pageSize = pdfReader.GetPageSize(1)
But values from vectors are bigger than pageSize Width and Height
On the other hand, can I load every char position on page?
LocationTextExtractionStrategyEx is not part of iTextSharp. I assume, therefore, you talk about the class provided in this answer. That class does nothing fancy with the positions. Thus, to respond to your issue:
I know that vector start on left bottom page corner but I don't know where is end because I don't know page size in the same scale like vector.
I can run
var pageSize = pdfReader.GetPageSize(1)
But values from vectors are bigger than pageSize Width and Height
First of all: the coordinates you get from LocationTextExtractionStrategyEx.TextLocationInfo indeed are to be interpreted in the context of pdfReader.GetPageSize.
There are two major causes why the vector values can be beyond Width and Height of the latter:
The rectangle returned by pdfReader.GetPageSize does not need to be based in (0,0). It could e.g. have x coordinates in 301..400 and y coordinates in 501..600. In that case height and width would both be 100 but all coordinates of points in that rectangle would be higher.
Thus, do not look at Width and Height but instead at Left, Bottom, Right, and Top.
Text may actually be outside the visible page and, therefore, have coordinates outside of pdfReader.GetPageSize.
For a final verdict please supply the PDF in question.
I read page size by
var pageSize = pdfReader.GetPageSize(1)
next I created
TextInfoLocation textLocation = new TextInfoLocation(textLine.TopLeft, textLine.BottomRight, this.PdfFilePageSize);
Properties .TopLeft and .BottomRight are vectors.
textLine is LocationTextExtractionStrategyEx.TextInfo object read from pdfReader by strategy.
Now text position in pixels form vectores I can get from:
double leftMargin = textLocation.LeftMargin;
Related
it is possible that my table "itextsharp" can take the total width of the document ??
As seen in the picture my board starts farther from the edge.
The default width of a table is 80% of the available width. You can change the by using:
table.WidthPercentage = 100;
Of course: this still isn't the full width of the page. If you want to use the full width of the page, you have to set the left and right margin to 0.
I have a list of objects which form a mathematical set. So I want to display them in an ellipse like this:
If I then add a new object, the ellipse should grow and the 6th element should be placed inside the ellipse.
I thought I could solve this problem with an iteration. At first place object1 and the Name of set and draw the ellipse. Secondly add object2 and let the ellipse grow, and so on.
But I already struggled to find a proper solution for the arrangement of the first step, not to mention the growth of the ellipse in the second step. My problem with the first step is, that the ellipse should be smaller when Name of set and object1 have a small string representation. And the ellipse should be bigger, if Name of set and object1 have a longer string representation.
Or did I get somewhere on the wrong track? Maybe there is already a (framework?) solution for this problem, which I overlook.
Create an integer property called MyCount.
Create integer constants OriginalWidth and OriginalHeight.
Create integer variables ScaledWidth and ScaledHeight.
When your set is created add mySet.Name.Count() to MyCount.
When you add an object, add myObject.SomeProperty.ToString().Count() to MyCount.
When you remove an object, subtract myObject.SomeProperty.ToString().Count() from MyCount.
When MyCount is changed, recalculate ScaledWidth and ScaledHeight - something like ScaledWidth = OriginalWidth * (MyCount * [insert number here])
In order to keep your ellipse in the correct perspective your Ellipse's Height and Width will be based on constant values multiplied by a scaling factor, which is MyCount. You need 4 integer values: OriginalWidth, OriginalHeight, ScaledWidth and ScaledHeight. OriginalWidth and OriginalHeight are integer constants defining the minimum width and height of your Ellipse. ScaledWidth and ScaledHeight are integer variables which your Ellipse's Height and Width properties are bound to.
Every time a new object is added or removed to/from your set the number of characters in its SomeProperty is added to MyCount. Every time MyCount changes it triggers the recalculation of ScaledWidth and ScaledHeight. Binding your Ellipse's Width and Height properties to ScaledWidth and ScaledHeight, and implementing INotifyPropertyChanged on these properties, should scale your Ellipse accordingly.
UPDATE
The algorithm posted here: http://programming.nullanswer.com/forum/11925 would appear to address placing your child elements within your parent ellipse. I've substituted ellipse for square/circle where appropriate:
Pick a random point inside the [parent ellipse] & instance a [very low Width/Height ellipse] at that point.
Grow the radius of that [ellipse] till it satisfies these criteria:
does not overlap any of the other chosen [ellipses].
does not extend outside the [parent ellipse].
Choose the [ellipse] if it satisfies these criteria.
Hi Mathmeticians out there.
I am a little stumped and I was wondering if there was any sort of algorithm that could help me.
First the conceptual problem, Lets say I have a bunch of boxes that lie along an X axis. I want to be able to choose an arbitrary point A on the axis and have everything on the left scaled to 95% of its original width and position and to compensate, everything on the right will have to be scaled to 105%. The width of the resulting boxes is easy to calculate since it is the original width times the scale. The problem I am having is how to calculate the gap which has now been created at point A so that I can shift the second part left to close that gap.
Furthermore, I would like to not only select a point A, but also a B and C, etc.. as well and be able to close their gaps likewise.
--The real reason I am asking--
Now for the actual problem (in case anyone else out there has gone through this.) I have a control in a C# Winforms app that was made by some programmer before I got here. The control can contain any number of child controls that each have their own relative coordinates as a percentage of the Width or Height (i.e. A control with a relative X coordinate of 0.5 will be placed halfway across the parent container.
We desperately need to support multiple monitors and the problem that I am having is that if you dock a control or toolbar next to our proprietary control then the ClientRectangle is smaller so it shifts around the child borders like so
My boss doesn't like that the lines shift over monitor boundaries and wants me to only mess with the lines on the same monitor where the window was docked. I have been able to get 90% of the way using the concept above, but I can't seem to get the re-spacing calculation right.
Here is a Mathematical model of what I think for calculating the gap.
Let's say that you have a starting point A, and lets define it as xA.
Now, let's define the boxes
//Box{x0,x1}
Boxes = {[B1]{0,100},[B2]{100,200},[B3]{200,400},[B4]{400,450},[B5]{450,700}}
Now we have 5 boxes on the X axis.
Let's define;
A = xA = 370;
TotalLength = 700;
If you divide 700 by 2, that makes 350 which makes the mid point, and 370 is bigger than the mid point value. So that is being said, in this case you would need to shift the elements on the left to right. The calculation of the gap is as the following;
IF(Midpoint < A)
Gap = ((A- Midpoint) * 100 ) / TotalLength //This is the gap in percent
ELSE
Gap = ((Midpoint - A) * 100) / TotalLength
This way, you can find the gap. The Axis you need to shift towards will need to be decided based on the point you are selecting, if the selected point less than the Mid point then shift to right, if higher shift to left (to the positive axis route).
I hope this helps.
Thank you for your help Surgeon. Unfortunately I wasn't able to find a solution using your method. On the bright side, I was able to find a solution. The trick was to treat the X coordinate as the width between the Client Rectangle's left edge and the X coordinate's position and calculate it similarly to the child width.
For more specifics, here's the algorithm I have come up with for dealing with the docking problem:
var clientOriginalWidth = what the width of the Client rectangle would be without docks
var clientCompressedWidth = the width of the client now
//Calculate the Compression Ratio for each screen as follows
foreach(var screen in Screens){
var widthOfClientRectOnScreenNow = how much of the client rectangle is on this screen
var widthOfClientRectOnScreenWithoutDocks = how much of the client rectangle was on the screen before the docks were there
var compressionRatio = (widthOfClientRectOnScreenNow / clientCompressedWidth) /
(widthOfClientRectOnScreenWithoutDocks / clientOriginalWidth);
//Assuming control.xScale and control.widthScale are initially 0
foreach(var control in ParentControl){
var controlBounds = where the control was when the client was full width
if(controlBounds.X > screen.right){
var percentOfXPositionOnScreen = screen.right - screen.left / control.x;
controlBounds.xScale += percentOfPositionOnScreen * compressionRatio;
}
else if(control.X > screen.left){
var percentOfXPositionOnScreen = control.x - screen.left / control.x;
controlBounds.xScale += percentOfPositionOnScreen * compressionRatio;
}
if(screen.intersects(controlBounds){
var percentControlIsOnScreen = what percent of the control's width was on this screen
control.widthScale += percentControlIsOnScreen * compressionRatio;
}
}
}
The position is then found by multiplying the original X coordinate by the scale (same for the width). Once the docks are removed, recalculate the scale. When all docks are removed, the scale should be 1.
I have left out some specifics to make it more of a generalized algorithm, but one should be able to work through this on their own system.
I've been trying to implement pinch-and-zoom using the ViewportControl class in a Windows Phone 8 Silverlight app for quite some time without any success. There are some great samples out there, such as this one, but I haven't been able to map the examples that I found to my scenario.
Pinching and zooming works fine, the problem I'm having is with the alignment of the viewport with the content, after the manipulation has completed.
The main problem I'm facing is that after my manipulation has completed, I've been unable to align the scaled content (a XAML canvas and sub tree which is the child of the ViewportControl) to the viewport. This results in the effective bounds of the viewport (the scrollable area) being offset from my content, resulting in part of my content being unreachable/unscrollable.
Here is my algorithm for the manipulation:
Pinch manipulation starts.
Apply render transform to canvas' sub tree during pinch.
Manipulation completes.
Scale main canvas to the effective size of
the render-transformed sub tree (this works as expected and the canvas is aligned with the render-transformed sub tree).
Obtain a transform between the canvas inside the ViewportControl and the viewport control itself.
Use the transform to obtain a bounding rect which (I expect) should represent a rect which overlays the content I want to scroll inside the ViewportControl,
but in the coordinate space of the hosting ViewportControl.
Apply this rect as the viewport bounds of the ViewportControl.
Set the origin of the viewport to the translated top-left coordinates of the canvas
Here is where I calculate and apply the new bounds, after the manipulation has completed:
// Obtain transform between canvas and ViewportControl
GeneralTransform gt = m_MainCanvas.TransformToVisual(m_ViewportControl);
Rect newBounds = gt.TransformBounds(new Rect(0, 0, m_MainCanvas.Width, m_MainCanvas.Height));
m_ViewportControl.Bounds = newBounds;
// set the origin of the viewport again
m_ViewportControl.SetViewportOrigin(gt.Transform(new Point(0, 0)));
This is resulting in my content being misaligned with the viewport.
Try, try as I might, I haven't been able to figure out what I'm doing wrong here... even after looking at tutorials that show how to solve this... :|
I figure that what is happening is that my rect that I'm setting the bounds to is sized correctly, but it's X and Y coordinates are off. I was hoping that this would be addressed by using the transform between the canvas and the ViewportControl itself, but apparently not.
Question: How do I go about setting the origin of the ViewportControl correctly (how do I calculate the point to pass to the SetViewportOrigin method? Can someone please explain this ratio that people are using between the scaled contents and the viewport that I see in other examples of how to crack this?
7/8/2014 Update
I made some headway here. My approach of getting a transform between the content in the ViewportControl and the control itself, then using this to obtain a rect in the control's space to use as the bounds for the viewport wasn't working. My workaround was to simply wrap the render-transformed content in a canvas which I resized the effective (render transformed) size. Then I set the bounds to that size and I finally had the nice bounce-back effect working.
The problem I'm facing now is that when I resize the canvas and reset the bounds for the viewport, the content snaps to the top-left corner of the viewport, and is no longer centered around the pinch area that the user provided.
Can anyone help me understand how the SetViewportOrigin method works on ViewportControl? I'm seeing some really odd data for the Viewport vs. the canvas after a pinch manipulation:
Canvas Size = 1025.69, 1641.11
Bounds = 0,0,1025.69,1641.11
viewport = -56,41.00,480,698
Why is the viewport offset with non-zero values (x,y = -56,41) when I don't even call SetViewportOrigin(Point)?
Here is how I'm thinking the SetViewportOrigin(Point) method works: let's say my Viewport control itself was sized to 400 x 400 pixels, and my content was 800 x 800 pixels. If I set the origin of the viewport to 100, 100 the content would be scrolled such that the first 100 vertical and 100 horizontal pixels would be clipped/masked/offscreen. Is this not how the ViewportControl works?
I figured this out and am a happy camper now. It turned out that I was setting the viewport origin to a point using the wrong coordinate space. I was thinking that if I wanted to move the content to a certain place, that I would provide that point in the coordinate space of the viewport and the content would scroll (setting the upper-left point of the content). What I figured out is that the Point data that the SetViewportOrigin method takes is in the coordinate space of the content. For example: if your content is 500 x 500 pixels wide, your viewport is 400 x 400 pixels wide, and you'd like the first 100 vertical and 100 horizontal pixels to be masked by the viewport (showing the bottom-right corner of the content), you would set the origin to be 100,100, not -100,100.
I was doing a bunch of useless conversion between coordinate spaces, trying to pass the viewport a point in its coordinate system.
I am trying to set the width of an image dynamically using MonoTouch. I have added the image to the view using Xcode Interface Builder.
What I want to do is keep the X and Y values of the image exactly the same. I just want the width of the image to change depending on a float value.
Example: If I placed the the image on the view at X = 50 and Y = 50 and the image size is W = 100 and H = 100 then I want to change the width dynamically based on conditions. I have tried to set the images' width dynamically like this:
img.Bounds.Width = 150;
and like this
img.Bounds.Size.Width = 150;
I have also tried to create a new RectangleF and setting the bounds equal to that Rectangle like this
RectangleF fillrect = new RectangleF(50, 50,
150, img.Bounds.Height);
and then setting the image bounds to that rectangle like this:
img.Bounds = fillrect;
The above method sizes the image but then moves the image to the incorrect place (X and Y values).
I have also tried various methods using SizeF but to no avail.
How can I just set the width of the image and keep it in the same place I placed it on interface builder?
And also how to change the X and Y values so that I can move another image based on the growth of the aforementioned image.
Seems like changing of Bounds applies around the Center of the view.
Try to set new Frame instead:
img.Frame = fillrect;
Location will be the same, but Size will be changed.