标签:
杂谈 |
分类: 计算机与 Internet |
为Adobe Acrobat 编写插件
在看pdf的时候,经常遇到一个烦心的问题,书签里的链接打开后,页面不是叶宽显示,而是显示的一整页,还要手动去选。专门研究了一下,写了一个JavaScript脚本,来解决这个问题。顺便说一下,Acrobat的JavaScript真烂。
1:function SetBookmarksWidthPage(bm, nLevel)
2:{
3:if(nLevel!=0)
4:{
5: console.println(bm.name+event.target.pageNum);
6: bm.execute();
7:
8: bm.setAction("this.pageNum="+event.target.pageNum+";this.zoomType = zoomtype.fitW;")
9:}
10:if (bm.children != null)
11:for (var i = 0; i < bm.children.length; i++)
12: SetBookmarksWidthPage(bm.children[i], nLevel + 1);
13:
14:}
15: app.addMenuItem({ cName: "Reset Bookmark View", cParent: "Advanced",
16: cExec: "SetBookmarksWidthPage(event.target.bookmarkRoot, 0);",
17: cEnable: "event.rc = (event.target != null);",
18: nPos: 0
19:});
会在“高级”菜单下添加一项"Reset Bookmark View"。
可是这样依然有个问题,书签里的Action显示的是Script,而不是象其他标准的显示的时Goto Destination。没办法,只好用C了。
1: ACCB1 ASBool ACCB2 MyPluginSetmenu()
2:{
3:return PluginMenuItem("Set Bookmark Fit Visable", "ADBE:BookmarkFit", false);
4:}
5:void iteratebookmark(PDBookmark bookmark,PDDoc doc)
6:{
7:
8: PDAction action = PDBookmarkGetAction(bookmark);
9: ASAtom atom = PDActionGetSubtype (action);
10:if(!strcmp(ASAtomGetString (atom),"GoTo"))
11:{
12://AVAlertNote(ASAtomGetString (atom));
13: PDViewDestination dest = PDActionGetDest(action);
14: ASInt32 pageNum;
15: ASAtom fitType;
16: ASFixedRect destRect;
17: ASFixed zoom;
18://AVAlertNote("done1");
19: PDViewDestGetAttr(dest,&pageNum,&fitType,&destRect,&zoom);
20://AVAlertNote("done2");
21: PDViewDestination newdest = PDViewDestCreate(doc,PDDocAcquirePage (doc, pageNum),ASAtomFromString("FitBV"),&destRect,PDViewDestNULL, 0);
22: PDAction newaction = PDActionNewFromDest ( doc,newdest,doc);
23: PDBookmarkSetAction ( bookmark,newaction);
24://AVAlertNote("done3");
25:}
26:if (PDBookmarkHasChildren (bookmark))
27:{
28: PDBookmark treeBookmark = PDBookmarkGetFirstChild(bookmark);
29:while (PDBookmarkIsValid (treeBookmark))
30:{
31: iteratebookmark (treeBookmark,doc);
32: treeBookmark = PDBookmarkGetNext(treeBookmark);
33:}
34:}
35:}
36: ACCB1 void ACCB2 MyPluginCommand(void *clientData)
37:{
38:// get this plugin's name for display
39: ASAtom NameAtom = ASExtensionGetRegisteredName (gExtensionID);
40:constchar * name = ASAtomGetString(NameAtom);
41:char str[256];
42: sprintf(str,"This menu item is added by plugin %s.\n", name);
43: AVDoc avDoc = AVAppGetActiveDoc();
44:
45:if(avDoc==NULL) {
46:// if no doc is loaded, make a message.
47://strcat(str,);
48: AVAlertNote("There is no PDF document loaded in Acrobat.");
49:}
50:else{
51: PDBookmark theroot;
52: PDDoc pddoc = AVDocGetPDDoc (avDoc);
53: theroot = PDDocGetBookmarkRoot(pddoc);
54: iteratebookmark(theroot,pddoc);
55:return;
56:}
57:return;
58:}
59:
60: ACCB1 ASBool ACCB2 MyPluginIsEnabled(void *clientData)
61:{
62:return AVAppGetActiveDoc()!=NULL;
63:}
依然是一个递归算法。只需要和Acrobat SDK里面的Basic Plugin的BasicPluginInit.cpp结合就可以使用了。生成的.api文件实际上是一个dll。
可是这样还是不够完美。书签属性里面,Zoom显示的是Custom,而不是Fit Width。想不出什么原因了。。。
PDViewDestCreate所使用的ASAtom,可以由以下几种String得到:FitBV,FitBH,FitH, FitV, FitR, FitB, Fit, XYZ。Acrobat的文档上竟然没有,还是从http://itext.ugent.be/library/api/com/lowagie/text/pdf/PdfDestination.html找到的。