Can width/height of a powerpoint presentation be calculated on iPad - iphone

I have an ipad app, which displays a powerpoint presentation from an NSData, within a UIWebView, and I need to know the width/height of a single slide so I know how far to scroll when advancing to the next slide.
In PDF, I can calculate it using CGPDFDocumentRef, as below, but I can't find a corresponding API for powerpoint, and since it's a microsoft format, I doubt it even exists.
I can use javascript to determine the width/height of the ENTIRE presentation, but that doesn't help me know how far to advance to go one single slide,
Code to do what I need to for a PDF:
CFDataRef myPDFData = (CFDataRef)presentationContent;
CGDataProviderRef provider = CGDataProviderCreateWithCFData(myPDFData);
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithProvider(provider);
CGPDFPageRef page = CGPDFDocumentGetPage(pdf, 1);
CGRect pageRect = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
int pageHeight=(int)pageRect.size.height;
int pageWidth=(int)pageRect.size.width;
//now I can advance to the proper page by doing a scrollto pageHeight*currentPage

Figured it out.
In this case, the UIWebView acts as if it's an iFrame on an HTML page, which has a source of some powerpoint file. So, there are certain things you can do to it, and certain properties that are exposed.
I found that document.all (an array) has elements - LOTS of elements. My 20 page powerpoint test file had over 300 elements. Looking at width / height of them was not overly helpful - some were the dimensions of the iframe itself, some were the dimensions from top-left pixel of slide 1 to bottom-right pixel of slide N, some were 0x0, and some (burried in the middle) were the dimensions of a slide. The pattern I found was that you have to skip the first element in document.all, and iterate through until you found one with non-zero width/height, who have identical values for clientHeight, offsetHeight, scrollHeight, as well as identical values for clientWidth, offsetWidth, and scrollWidth. The first one of these will give you the height/width of a single slide, and you can go from there. And, of course, because you're using a UIWebView, and only have stringByEvaluatingJavaScriptFromString to work with, you need to do this all in one line of javascript that returns the value.
So, to extract width/height of a powerpoint presentation, you can write:
NSString *w=[webview stringByEvaluatingJavaScriptFromString:#"function x(){var rtn='';for (var i=1;i<document.all.length;i++){var a=document.all[i];if (((a.clientWidth>0)&&(a.clientHeight>0))&&(a.scrollHeight.toString()==a.offsetHeight.toString())&&(a.offsetHeight.toString()==a.clientHeight.toString())){return ''+a.offsetWidth; }}return rtn;};x();"];
NSString *h=[webview stringByEvaluatingJavaScriptFromString:#"function x(){var rtn='';for (var i=1;i<document.all.length;i++){var a=document.all[i];if (((a.clientWidth>0)&&(a.clientHeight>0))&&(a.scrollHeight.toString()==a.offsetHeight.toString())&&(a.offsetHeight.toString()==a.clientHeight.toString())){return ''+a.offsetHeight; }}return rtn;};x();"];
and do whatever you need to with width/height from that point on.
Oh, and document.all isn't populated immediately once your document is loaded - UIWebView seems to need a few milliseconds to gather that and make it available. I run this 1 second after my webview has finished loading, and it works great on both ppt and pptx files. it does NOT work on pdf, though.

amongst others, these objects contain width and height properties:
Sub Test()
Dim A As Application
Set A = Application
Debug.Print A.Width, A.Height
Debug.Print A.Windows(1).Width, A.Windows(1).Height
Debug.Print A.SlideShowWindows(1).Width, A.SlideShowWindows(1).Height
End Sub
The most suitable for you seems to be the last one.
Results for a 1680 x 1050 screen
PPT in full-screen
1266 793,5
1245,75 699,75
1260 787,5
PPT in ca. 1/2 of screen
711,75 551,25
691,5 457,5
1260 787,5 <-- same as above as slideshows always go full-screan at the selected aspect ratio

Related

Drawing graphical objects (boxes and lines) inside a structured iText(Sharp) document (Chapters and Sections)

I'm creating a PDF document using iTextSharp, what I'm doing is generating all of my content in a c# List<Chapter> where the Chapters contain one or more Sections, and the Chapters have not yet been added to the document. I then enumerate through my List<Chapter> to generate a table of contents at the start of the document, and then add the Chapters to the document after my TOC.
That works great when my Sections contain text and images, but now I need to generate a Section containing boxes and lines. I don't want to draw my boxes and lines into an image and drop the image into the Section, that won't look as good as if I have actual PDF boxes and lines.
The Sections containing graphical elements can be intermixed with Sections containing text, so I need a way to add some kind of element to a Section such that that graphical Section works like text Sections in terms of going onto a new page only if necessary.
What's the best way to do this? I feel like it somehow involves PdfTemplates but I'm not sure how. Or maybe I need to create a PdfPTable and create my graphical elements in an IPdfPCellEvent?
You are on the right track when you want to involve PdfTemplate elements. PdfTemplate is an iText object that corresponds with the concept of Form XObjects in the PDF specification. We chose another name because the word Form is somewhat misleading (people confuse it with form fields, interactive forms, etc).
The content stream of a page in PDF is a sequence of PDF syntax, consisting of operands and operators. An XObject is an object that is external to this content stream. The content of an XObject is stored inside the PDF document only once, but it can be reused many times on the same page, on different pages.
There are different types of XObjects, but Image XObjects and Form XObjects are the most important ones.
Image XObjects are used when we work with raster images. You are absolutely right when you write: *"I don't want to draw my boxes and lines into an image and drop the image into the Section, that won't look as good as if I have actual PDF boxes and lines."
Form XObjects are used when we want to reuse PDF syntax. This is what you need: you want to define moveTo(), lineTo(), curveTo(), stroke(), fill(),... operations, and you want these lines and shapes to be stored as vector data.
The solution to your problem is to draw lines and shapes to a PdfTemplate object and to wrap the PdfTemplate object inside an Image object. When you add that Image object to a Section or a Chapter, it will be added as a Form XObject. You don't have to feat that it will be degraded into a raster image.
You can find some examples of this technique on the official web site. For instance in the answer to the question
How to generate 2D barcode as vector image?
Here we create a PdfTemplate with a bar code and we return it as an Image object. The screen shot that shows you the internals of the resulting PDF proves that the bar code is added as a vector image.
public Image createBarcode(PdfContentByte cb, String text,
float mh, float mw) throws BadElementException {
BarcodePDF417 pf = new BarcodePDF417();
pf.setText("BarcodePDF417 barcode");
Rectangle size = pf.getBarcodeSize();
PdfTemplate template = cb.createTemplate(
mw * size.getWidth(), mh * size.getHeight());
pf.placeBarcode(template, BaseColor.BLACK, mh, mw);
return Image.getInstance(template);
}
To create a PdfTemplate object, you need a PdfContentByte instance (e.g. using writer.getDirectContent()) and use the createTemplate() method passing a width and a height as parameters. Then you draw content to the PdfTemplate and turn it into an Image object using Image.getInstance().
You'll find more info on drawing lines and shapes in the chapter on Absolute positioning of lines and shapes and in the example section of Chapter 3 and Chapter 14 of my book.

iTextSharp - Scaling and positioning page

I am reading an existing PDF file into a new PDF file, and scaling the first page based on the page dimensions. The page gets scaled to 90-95% in order to make room for some footer text. The problem I have is that the resulting scaled page leaves white space at the top of the page, NOT the bottom. Is there a way to control the results so that they start in the top left of the page and not the bottom left?
Here's my code that adds the scaled page:
cb.AddTemplate(importedPage, scaleSize, 0, 0, scaleSize, 5, 20);
Object "cb" is a PDFContentByte class, while "scaleSize" is a float set to .9 or .95. The scaling works great, but the positioning is an issue. Thanks!
figured it out: the value of "20" for the final parameter was incorrect. A value of 100 is far more suitable for my purposes, and now I understand far better the coordinate system in PDF/iText. For those interested, the 0, 0 point for a PDF document is the lower left corner.

FastPDFKit get document size

I might be overlooking this, but how can one get the size of a PDF if you're using FastPDFKit?
I'm trying to create PNG's from a pdf, but without knowing the actual dimensions of the page it's rather hard to get it right.
EDIT:
I searching in the documentation before, but all I found was this method:
- (void)getCropbox:(CGRect *)cropbox andRotation:(int *)rotation forPageNumber:(NSInteger)pageNumber withBuffer:(BOOL)withOrWithout
But I have no idea how to use it, it doesn't return anything.
Not sure how familiar you are with PDF, but each page specifies a number of "boxes" that are various rectangles of interest (crop, media, etc)
Most apps using PDF elect to use the crop box which defines the region of the page that should be displayed. (See section 10.10.1 of the PDF 1.7 specification: http://www.adobe.com/devnet/pdf/pdf_reference_archive.html)
Also of note is that a page can specify a rotation angle of 0, 90, 180, or 270 which you need to apply to the crop box yourself. (see /Rotate in table TABLE 3.27 of the PDF 1.7 spec)
So using the above API you would call it like so:
[somePDFDoc getCropbox:&cropbox andRotation:&rotation forPageNumber:10 withBuffer:NO];
This would give you the cropbox rect and it's rotation.
NOTE: I have never used FastPDFKit
NOTE2: If the value of cropbox is CGRectZero, you want to use one of the other rects. Most viewers use the media box instead.

get the exact position of text from image in tesseract

Using GetHOCRText(0) method in tesseract I'm able to retrieve the text in html and on presenting the html in webview i'm able get the text but the postion of text in image is different from the output. Any idea is highly helpful.
tesseract->SetInputName("word");
tesseract->SetOutputName("xyz");
tesseract->Recognize(NULL);
char *utf8Text=tesseract->GetHOCRText(0);
and output image
If you have the hocr output, you should have a tag for each word. These tags should have class="ocrx_word" and name="bbox x1 y1 x2 y2" where the x and y are the top left and bottom right corner of the bounding box around the word. I don't think it's possible to automatically use this information to format a text document - would require translating pixel differences to number of tabs/spaces. But, you should be able to render text in the given location.
GetBoxText() method will return exact position of each characters in an array.
char *boxtext = _tesseract->GetBoxText(0);
NSString* aBoxText = [NSString stringWithUTF8String:boxtext];

iOS wrapping text around an image

I've got a few short paragraphs of text that I'd like to place wrapped around an image in my app's view. Typically, the image will be on the left side of the text and the text would flow as you normally expect. The image has varying height and width and size-wise, 4-30kb png files. The text has varying length and can be anywhere between 2 sentences to a few paragraphs. There's markup with text so different lines can be formatted accordingly.
I've been using UIWebView within my UIView to do this in the quickest manner but what I've noticed is that even though my text and images are local, there's a noticeable delay in when the UIWebView loads and shows the image and text. Basically, you see the view area blank and then a short moment later, you see the image load. Most of the time, the text is shown as loaded before the image.
I'm using UIWebView's 'loadHTMLString' to load the local html text and images.
What I want to achieve would look like:
| [ ] | Some text starts here and is long enough to fil until the end of the line. Then
| [image] | the text continues so it wraps around a few more lines to fit the entire
| [ ] | height of the image.
Eventually, we'll show the text below the image, just like you see in a newspaper.
The content would continue at variable length for the rest of the screen.
Is there a better way to display formatted text with images? If there's something better than UIWebView, I'd love to move to that.
I think your basic strategy should be (1) try to get the performance of UIWebView to an acceptable level and (2) if that fails, and it's really important, roll your own text layout code.
Some ideas:
Try to load content into the UIWebView class as early as possible, before it is displayed on screen.
See if using inline styles (instead of a linked stylesheet) improves load time.
See if using inline images (by using <img src="data:...") improves load time.
If none of that works, and you want to roll your own, you're going to have to write your own text layout code. You could probably do this by using NSString's UIKit additions: split the text into words, compute the size of each word (using sizeWithFont:), and lay out the text line by line. You should probably compute on a word-by-word basis, but actually draw a whole line at a time, that should perform better. Or you might be able to make a new string with newlines inserted at the right places and draw the whole thing in one go.
Good luck!
Try the following .This is without CoreText and Html
UIBezierPath * imgRect = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 100, 100)];
UIImageView *imageView= [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 100, 100)];
imageView.image=[UIImage imageNamed:#"defaultImage"];
[self.textView addSubview:imageView];
self.textView.textContainer.exclusionPaths = #[imgRect];