Hi Carlos,<br> <br> Thank you for helping me.<br> I made the changes suggested by you. Please check the patch. Let me know for any more changes.<br><br>Thanks<br>--<br>A Srinivas<br><br><div class="gmail_quote">
On Thu, Mar 24, 2011 at 12:30 AM, <span dir="ltr"><<a href="mailto:poppler-request@lists.freedesktop.org">poppler-request@lists.freedesktop.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Send poppler mailing list submissions to<br>
<a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
<a href="http://lists.freedesktop.org/mailman/listinfo/poppler" target="_blank">http://lists.freedesktop.org/mailman/listinfo/poppler</a><br>
or, via email, send a message with subject or body 'help' to<br>
<a href="mailto:poppler-request@lists.freedesktop.org">poppler-request@lists.freedesktop.org</a><br>
<br>
You can reach the person managing the list at<br>
<a href="mailto:poppler-owner@lists.freedesktop.org">poppler-owner@lists.freedesktop.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of poppler digest..."<br>
<br>
<br>
Today's Topics:<br>
<br>
1. Re: poppler Digest, Vol 73, Issue 27 (Carlos Garcia Campos)<br>
2. Plans to get Javascript support in Poppler.<br>
(<a href="mailto:jose.aliste@gmail.com">jose.aliste@gmail.com</a>)<br>
<br>
<br>
----------------------------------------------------------------------<br>
<br>
Message: 1<br>
Date: Wed, 23 Mar 2011 15:18:41 +0100<br>
From: Carlos Garcia Campos <<a href="mailto:carlosgc@gnome.org">carlosgc@gnome.org</a>><br>
Subject: Re: [poppler] poppler Digest, Vol 73, Issue 27<br>
To: srinivas adicherla <<a href="mailto:srinivas.adicherla@gmail.com">srinivas.adicherla@gmail.com</a>><br>
Cc: poppler <<a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a>><br>
Message-ID: <1300886015-sup-4220@charizard><br>
Content-Type: text/plain; charset="utf8"<br>
<br>
Excerpts from srinivas adicherla's message of mi? mar 23 08:30:32 +0100 2011:<br>
> Hi Carlos,<br>
<br>
Hi,<br>
<br>
> Thank you for your valuable suggestions. I made the changes<br>
> according to that. I attached a new patch with this.<br>
<br>
Thanks!<br>
<br>
> - I have some doubt when setting a 'Rendition' action, we have two options<br>
> one is to set 'OP' other one is 'JS'. I am asking the user to pass the<br>
> Javascript and set it as a stream here.<br>
<br>
Since both options are required when the other one is not present, I<br>
would add two constructors, one for OP, and another one for JS.<br>
<br>
LinkRendition::LinkRendition(XRef *xrefA, MediaRendition *rendition, int operation, Annot *annot);<br>
LinkRendition::LinkRendition(XRef *xrefA, Object *js);<br>
<br>
> - One more is i wrote a new function 'get_file_name_from_path' is it fine?<br>
> what is the good place to add this function.<br>
<br>
yes, just rename it to follow poppler coding style to something like:<br>
<br>
getFileNameFromPath();<br>
<br>
> Please give suggestions again.<br>
<br>
See comments below<br>
<br>
> Thanks<br>
<br>
Index: poppler-0.16.2/poppler/Link.cc<br>
===================================================================<br>
--- poppler-0.16.2/poppler/Link.cc (revision 12)<br>
+++ poppler-0.16.2/poppler/Link.cc (working copy)<br>
@@ -44,6 +44,7 @@<br>
#include "Sound.h"<br>
#include "FileSpec.h"<br>
#include "Rendition.h"<br>
+#include "XRef.h"<br>
<br>
//------------------------------------------------------------------------<br>
// LinkAction<br>
@@ -738,6 +739,32 @@<br>
}<br>
}<br>
<br>
+LinkRendition::LinkRendition(Annot *annot, const char *video_file,Object *obj) {<br>
<br>
This method should receive the XRef, and the MediaRendition object<br>
already created. See the contructors I suggested above.<br>
<br>
+ Object obj1;<br>
+ XRef *xref = annot->getXRef();<br>
+ renditionObj.initDict(xref);<br>
+ Ref annotref = annot->getRef();<br>
+ renditionObj.dictSet("Type", obj1.initName("Action"));<br>
+ renditionObj.dictSet("S", obj1.initName("Rendition"));<br>
+ if (obj->isInt()) {<br>
+ renditionObj.dictSet("OP", obj);<br>
+ renditionObj.dictSet("AN", obj1.initRef(annotref.num, annotref.gen));<br>
+ }<br>
+ else {<br>
+ renditionObj.dictSet("JS", obj);<br>
+ }<br>
+<br>
+ // Media Rendition<br>
+ Object MRendition;<br>
+ MediaRendition *MR = new MediaRendition(annot, video_file);<br>
+ MRendition = MR->getMediaRendition();<br>
+<br>
+ Ref newRef;<br>
+ newRef = xref->addIndirectObject(&MRendition);<br>
+ obj->initRef(newRef.num, newRef.gen);<br>
+ renditionObj.dictSet("R", &obj1);<br>
+}<br>
+<br>
LinkRendition::~LinkRendition() {<br>
renditionObj.free();<br>
screenRef.free();<br>
<br>
Index: poppler-0.16.2/poppler/Rendition.cc<br>
===================================================================<br>
--- poppler-0.16.2/poppler/Rendition.cc (revision 12)<br>
+++ poppler-0.16.2/poppler/Rendition.cc (working copy)<br>
@@ -24,6 +24,7 @@<br>
<br>
#include <math.h><br>
#include "Rendition.h"<br>
+#include "XRef.h"<br>
#include "FileSpec.h"<br>
<br>
MediaWindowParameters::MediaWindowParameters() {<br>
@@ -366,6 +367,40 @@<br>
tmp2.free();<br>
}<br>
<br>
+MediaRendition::MediaRendition(Annot *annot, const char *mediafile) {<br>
<br>
Pass the XRef directly instead of passing the annot object just to get<br>
the XRef<br>
<br>
+ Object obj1, obj2;<br>
+<br>
+ XRef *xref = annot->getXRef();<br>
+ mediaRendition.initDict(xref);<br>
+ mediaRendition.dictSet("S", obj1.initName("MR"));<br>
+<br>
+ // Media Clip Dictionary<br>
+ Object MClipDict;<br>
+ MClipDict.initDict(xref);<br>
+ MClipDict.dictSet("S", obj1.initName("MCD"));<br>
+<br>
+ //if (mimetype)<br>
+ //MClipDict.dictSet("CT", obj3.initString(new GooString(mimetype)));<br>
<br>
There's a contentType variable for this, so make sure it's updated so<br>
that MediaRendition::getContentType() will work. Why is this commented?<br>
<br>
+ obj1.initString(new GooString("TEMPACCESS"));<br>
+ obj2.initDict(xref);<br>
+ obj2.dictSet("TF", &obj1);<br>
+ MClipDict.dictSet("P", &obj2);<br>
<br>
The Permissions dictionary is optional, why are you hardcoding<br>
TEMPACCESS here? We are not even parsing TF when creating a<br>
MediaRendition from an existing dictionary.<br>
<br>
+ // File Specification Dictionary<br>
+ Object *fsDict;<br>
+ fsDict = annot->createFilespec(mediafile);<br>
<br>
As Pino suggested this should probably be moved to FileSpec.cc since<br>
it's not specific to annotations.<br>
<br>
+<br>
+ Ref newRef;<br>
+ newRef = xref->addIndirectObject(fsDict);<br>
+ obj2.initRef(newRef.num, newRef.gen);<br>
+ MClipDict.dictSet("D", &obj2);<br>
<br>
You should initialize the fileName, isEmbedded and embeddedStream variables,<br>
maybe it's the time to add a FileSpec class so that this methos just<br>
receives a FileSpec object instead of a filename.<br>
<br>
+ newRef = xref->addIndirectObject(&MClipDict);<br>
+ obj2.initRef(newRef.num, newRef.gen);<br>
+ mediaRendition.dictSet("C", &obj2);<br>
<br>
ok variable should be initialized to gTrue.<br>
<br>
+}<br>
+<br>
void MediaRendition::outputToFile(FILE* fp) {<br>
if (!isEmbedded)<br>
return;<br>
Index: poppler-0.16.2/poppler/Rendition.h<br>
===================================================================<br>
--- poppler-0.16.2/poppler/Rendition.h (revision 12)<br>
+++ poppler-0.16.2/poppler/Rendition.h (working copy)<br>
@@ -25,6 +25,7 @@<br>
#define _RENDITION_H_<br>
<br>
#include "Object.h"<br>
+#include "Annot.h"<br>
<br>
struct MediaWindowParameters {<br>
<br>
@@ -118,6 +119,7 @@<br>
class MediaRendition {<br>
public:<br>
MediaRendition(Object *obj);<br>
+ MediaRendition(Annot *annot, const char *mediafile);<br>
~MediaRendition();<br>
<br>
GBool isOk () { return ok; }<br>
@@ -128,6 +130,7 @@<br>
GooString* getContentType() { return contentType; }<br>
GooString* getFileName() { return fileName; }<br>
<br>
+ Object getMediaRendition() {return mediaRendition;}<br>
GBool getIsEmbedded() { return isEmbedded; }<br>
Stream* getEmbbededStream() { return embeddedStream; }<br>
// write embedded stream to file<br>
@@ -145,6 +148,7 @@<br>
<br>
GBool isEmbedded;<br>
<br>
+ Object mediaRendition;<br>
<br>
mediaRendition should be initilized in the other constructor too,<br>
simply copy the given object:<br>
<br>
obj->copy(&mediaRendition);<br>
<br>
<br>
GooString* contentType;<br>
<br>
// if it's embedded<br>
<br>
Index: poppler-0.16.2/poppler/Annot.cc<br>
===================================================================<br>
--- poppler-0.16.2/poppler/Annot.cc (revision 12)<br>
+++ poppler-0.16.2/poppler/Annot.cc (working copy)<br>
<br>
+void AnnotScreen::setTitle(GooString *title) {<br>
+ if (title)<br>
+ title = new GooString(title);<br>
+ else<br>
+ title = new GooString();<br>
<br>
save the title as a class attr, and add getTitle() method. Make sure<br>
the string is correctly encoded, see Annot::setContents() for example.<br>
<br>
+ Object obj1;<br>
+ obj1.initString(title->copy());<br>
+ update ("T", &obj1);<br>
+ delete(title);<br>
+}<br>
<br>
<br>
+GBool AnnotScreen::setAction(const char* video_file, const char* mimetype, const char* img_file, const char* js) {<br>
<br>
A screen annot can be used to trigger any action type, not only<br>
rendition actions, so this should be something like:<br>
<br>
GBool AnnotScreen::setAction(LinkAction *actionA);<br>
<br>
+ if (!video_file) {<br>
+ error(-1, "Need to pass the video file");<br>
+ return gFalse;<br>
+ }<br>
+<br>
+ // Extract the video name from the file uri<br>
+ const char *video_name = get_file_name_from_path (video_file);<br>
+<br>
+ Object obj1, obj2, obj3, obj4;<br>
+<br>
+ GooString *title = new GooString(video_name);<br>
+ setTitle(title);<br>
+ setContents(title);<br>
+ delete(title);<br>
<br>
title and contents should be set by the caller, the frontends in this<br>
case.<br>
<br>
+ Ref imgRef;<br>
+ Object imgXObj;<br>
+ imgXObj.initDict(xref);<br>
+ imgXObj.dictSet("Type", obj1.initName("XObject"));<br>
+ imgXObj.dictSet("Subtype", obj2.initName("Image"));<br>
+<br>
+ if (img_file) {<br>
+ FILE *imgfp;<br>
+ if (!(imgfp = fopen(img_file, "rb"))) {<br>
+ error(-1, "Couldn't open file: %s",img_file);<br>
+ return gFalse;<br>
+ }<br>
+ unsigned char h[10];<br>
+ fread(h, 1, 10, imgfp);<br>
+ fseek(imgfp, 0, SEEK_SET);<br>
+<br>
+ MemStream *imgStream = NULL;<br>
+ // Load the stream from the png file<br>
+ if (h[0] == 0x89 && h[1] == 0x50 && h[2] == 0x4E && h[3] == 0x47)<br>
+ imgStream = load_from_png (imgfp, &imgXObj);<br>
+ // Load the stream from the jpeg file<br>
+ else if(h[0] == 0xFF && h[1] == 0xD8 && h[6] == 0x4A && h[7] == 0x46 && h[8] == 0x49 && h[9] == 0x46)<br>
+ imgStream = load_from_jpeg (imgfp, &imgXObj);<br>
+ else {<br>
+ error(-1, "Image format cannot be supported, only png/jpeg\n");<br>
+ return gFalse;<br>
+ }<br>
+<br>
+ if (imgStream) {<br>
+ obj2.initStream(imgStream);<br>
+ appearBuf = new GooString("/Im1 Do");<br>
+ double bbox[4];<br>
+ bbox[0] = bbox[1] = 0;<br>
+ bbox[2] = bbox[3] = 1;<br>
+ createResourcesDict("Im1", &obj2, "GS0", 1.0, NULL, &obj4);<br>
+ createForm(bbox, gFalse, &obj4, &obj1);<br>
+<br>
+ Ref appRef = xref->addIndirectObject(&obj1);<br>
+ obj2.initDict(xref);<br>
+ obj2.dictSet("N", obj3.initRef(appRef.num, appRef.gen));<br>
+ annotObj.dictSet("AP", &obj2);<br>
+<br>
+ obj2.initStream(imgStream);<br>
+ createResourcesDict("Im1", &obj2, "GS0", 1.0, NULL, &obj1);<br>
+ createForm(bbox, gFalse, &obj1, &obj4);<br>
+ appRef = xref->addIndirectObject(&obj4);<br>
+<br>
+ obj2.initDict(xref); // MK dictionary<br>
+ obj2.dictSet("I", obj3.initRef(appRef.num, appRef.gen));<br>
+ annotObj.dictSet("MK", &obj2);<br>
+ }<br>
+ }<br>
<br>
I think it would be better to add a generic mehtod to set the annot<br>
appearance stream from an image, something like<br>
Annot::setAppearanceFromFile() and call it from the frontends instead<br>
of doing it here.<br>
<br>
+ if (js == NULL)<br>
+ obj1.initInt(0);<br>
+ else {<br>
+ obj2.initDict(xref);<br>
+ obj2.dictSet("Length", obj3.initInt(strlen(js)));<br>
+ MemStream *jsstream = new MemStream(copyString((char*)js), 0, strlen(js), &obj2);<br>
+ obj1.initStream(jsstream);<br>
+ }<br>
+<br>
+ LinkRendition *rendition = new LinkRendition(this, video_file, &obj1);<br>
<br>
You should update the action variable instead.<br>
<br>
+ Object *renditionObj = rendition->getRenditionObject();<br>
+ Ref newRef = xref->addIndirectObject(renditionObj);<br>
+ obj1.initRef(newRef.num, newRef.gen);<br>
<br>
rendition object should be added by the MediaRendition constructor<br>
like we currently does for annotations, and here you only need to get<br>
the Ref.<br>
<br>
+ annotObj.dictSet("A", &obj1);<br>
+<br>
+ return gTrue;<br>
+}<br>
+<br>
//------------------------------------------------------------------------<br>
// AnnotStamp<br>
//------------------------------------------------------------------------<br>
Index: poppler-0.16.2/glib/poppler-annot.cc<br>
===================================================================<br>
--- poppler-0.16.2/glib/poppler-annot.cc (revision 12)<br>
+++ poppler-0.16.2/glib/poppler-annot.cc (working copy)<br>
@@ -332,7 +332,52 @@<br>
return poppler_annot;<br>
}<br>
<br>
+/**<br>
+ * poppler_annot_screen_new:<br>
+ * @doc: a #PopplerDocument<br>
+ * @rect: a #PopplerRectangle<br>
+ *<br>
+ * Creates a new Screen annotation that will be<br>
+ * located on @rect when added to a page. See<br>
+ * poppler_page_add_annot()<br>
+ *<br>
+ * Return value: A newly created #PopplerAnnotScreen annotation<br>
+ *<br>
+ */<br>
+PopplerAnnot *<br>
+poppler_annot_screen_new (PopplerDocument *doc,<br>
+ PopplerRectangle *rect)<br>
+{<br>
+ Annot *annot;<br>
+ PDFRectangle pdf_rect(rect->x1, rect->y1,<br>
+ rect->x2, rect->y2);<br>
<br>
+ annot = new AnnotScreen (doc->doc->getXRef(), &pdf_rect, doc->doc->getCatalog());<br>
+ return _poppler_annot_screen_new (annot);<br>
+}<br>
+<br>
+/**<br>
+ * poppler_annot_screen_set_action:<br>
+ * @poppler_annot: a #PopplerAnnot<br>
+ * @video_file: pass the path of the video to be embed<br>
+ * @mimetype: pass the mimetype of the video to put in the Media Clip Dictionary<br>
+ * @img_file: pass png/jpeg image file for poster<br>
+ * @js: set the JS as this javascript stream in rendition action else if it is null set OP<br>
+<br>
+ * Set the action for the screen annotation specified @poppler_annot<br>
+ *<br>
+ */<br>
+void<br>
+poppler_annot_screen_set_action (PopplerAnnot *poppler_annot,<br>
+ const char* video_file,<br>
+ const char* mimetype,<br>
+ const char* img_file,<br>
+ const char* js)<br>
<br>
This is still wrong, you should be able to set any action type to a<br>
screen annotation.<br>
<br>
--<br>
Carlos Garcia Campos<br>
PGP key: <a href="http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462" target="_blank">http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462</a><br>
-------------- next part --------------<br>
A non-text attachment was scrubbed...<br>
Name: signature.asc<br>
Type: application/pgp-signature<br>
Size: 198 bytes<br>
Desc: not available<br>
URL: <<a href="http://lists.freedesktop.org/archives/poppler/attachments/20110323/094c9927/attachment-0001.pgp" target="_blank">http://lists.freedesktop.org/archives/poppler/attachments/20110323/094c9927/attachment-0001.pgp</a>><br>
<br>
------------------------------<br>
<br>
Message: 2<br>
Date: Wed, 23 Mar 2011 13:25:27 -0400<br>
From: "<a href="mailto:jose.aliste@gmail.com">jose.aliste@gmail.com</a>" <<a href="mailto:jose.aliste@gmail.com">jose.aliste@gmail.com</a>><br>
Subject: [poppler] Plans to get Javascript support in Poppler.<br>
To: <a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a><br>
Cc: Ryan Lewis <<a href="mailto:me@ryanlewis.net">me@ryanlewis.net</a>><br>
Message-ID:<br>
<<a href="mailto:AANLkTin98WAdRNo5OfMjs31zHCdWr2X5rXCVXjwtJRZn@mail.gmail.com">AANLkTin98WAdRNo5OfMjs31zHCdWr2X5rXCVXjwtJRZn@mail.gmail.com</a>><br>
Content-Type: text/plain; charset=ISO-8859-1<br>
<br>
Hi list,<br>
<br>
So we are discussing how we can join efforts to start adding poppler<br>
support for Javascript in poppler. With Carlos and Pino, we got some<br>
agreements that I want to share with you so you can add comments/<br>
regards/ questions/ etc. These are by no mean sealed plans, I only try<br>
to account for a summary of the discussion we had yesterday in IRC.<br>
The basic plan is:<br>
<br>
1. To start a "plain core js" API in C++ that will use poppler core<br>
API and will follow as close as possible the PDF JS API [1]<br>
2. Each frontend, glib and qt, can then decide how they will bind<br>
these API to their frontends.<br>
<br>
Notes:<br>
a) Of course, will coding 1, we will need to add functionality to core<br>
poppler that is not there yet, like for instance, support for<br>
Javascript Actions.<br>
b) the plain core js api in 1 should be probably very easy, as it<br>
should wrap more or less directly from the core poppler, but we choose<br>
this way so the code can be shared by Okular and Evince.<br>
c) Just for completness, I give more details about the glib frontend,<br>
in which I plan to hack: Our idea in 2) is to wrap the "plain core<br>
js" api into a GObject API, and then use the automatic<br>
GObject-Javascript glue that (will be) is provided to us by Seed using<br>
gobject-introspection (BTW, in this case the Javascript engine comes<br>
from Webkit).<br>
<br>
That's more or less it. Comments/questions/rants/patches welcome.<br>
<br>
Greets<br>
<br>
Jos?<br>
<br>
<br>
@Carlos, Pino, if I forget something (or I got something wrong),<br>
please add it here.<br>
<br>
<br>
------------------------------<br>
<br>
_______________________________________________<br>
poppler mailing list<br>
<a href="mailto:poppler@lists.freedesktop.org">poppler@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/poppler" target="_blank">http://lists.freedesktop.org/mailman/listinfo/poppler</a><br>
<br>
<br>
End of poppler Digest, Vol 73, Issue 35<br>
***************************************<br>
</blockquote></div><br>