home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
-
- StampAH.c
-
- This file is furnished to you by Adobe Systems Incorporated
- under the terms of the Acrobat(r) Plug-ins Software
- Development Kit License Agreement.
-
- Copyright (C) 1994-1997, Adobe Systems Inc. All Rights Reserved.
-
-
- Implementation of the Stamper's annotation-related routines.
-
- ******************************************************************************/
-
- #include "stampah.h"
- #include "stamper.h"
- #include "stamppr.h"
-
- #include "ASCalls.h"
- #include "AVCalls.h"
- #include "CorCalls.h"
- #include "PDCalls.h"
- #include "CosCalls.h"
-
- #include "debugger.h"
- extern HFT gDebuggerWindowHFT;
-
- #include <stdio.h>
- #include <string.h>
- #include <Dialogs.h>
- #include "AcrobatAppleScript.h"
-
- ASAtom State_K;
- ASAtom Appearance_K;
- ASAtom FaceNormal_K;
- ASAtom FaceRollover_K;
- ASAtom FaceDown_K;
- ASAtom Flags_K;
- ASAtom Length_K;
-
- /* stamperAH
- ** This is the annotation handler object for all Stamper annotations.
- */
- AVAnnotHandlerRec stamperAH;
-
- /* PDAnnotGetState
- ** Returns the current state specified by the AS key in the annotation's
- ** dictionary. Returns ASAtomNull if no AS key found.
- */
- extern ASAtom PDAnnotGetState(PDAnnot pdan);
- ASAtom PDAnnotGetState(PDAnnot pdan)
- {
- ASAtom asaState = ASAtomNull;
-
- if (PDAnnotIsValid(pdan)) {
- DURING
- CosObj co = PDAnnotGetCosObj(pdan);
- if (CosDictKnown(co, State_K)) {
- co = CosDictGet(co, State_K);
- asaState = CosNameValue(co);
- }
- HANDLER
- asaState = ASAtomNull;
- END_HANDLER
- }
- else
- asaState = ASAtomNull;
- return asaState;
- }
-
- /* PDAnnotGetApppearance
- ** Returns the appearance CosStream for the annotation in question. asaFace
- ** indicates which face (Normal, Rollover, Down, etc.) is to be used, and asaSubFace
- ** indicates which subface to use. If asaSubFace is ASAtomNull, then the asaFace
- ** is assumed to only have one face and therefore it is returned as a CosStream.
- */
-
- extern CosObj PDAnnotGetAppearance(PDAnnot pdan, ASAtom asaFace, ASAtom asaSubFace);
- CosObj PDAnnotGetAppearance(PDAnnot pdan, ASAtom asaFace, ASAtom asaSubFace)
- {
- /* We handle two forms here. In the simple case there is a single face for
- * each state (e.g. N, R, D, X are streams). In the complex case, there are
- * several faces for each appearance, referenced by name inside the
- * N, R, D, and X dicts. You can get the sub-face name by using PDAnnotGetState().
- */
- CosObj co;
- ASBool bOk = false;
-
- if (PDAnnotIsValid(pdan) && asaFace != ASAtomNull) {
- DURING
- co = PDAnnotGetCosObj(pdan);
- if (CosDictKnown(co, Appearance_K)) {
- co = CosDictGet(co, Appearance_K);
- if (CosDict == CosObjGetType(co) && CosDictKnown(co, asaFace)) {
- co = CosDictGet(co, asaFace);
- if (asaSubFace != ASAtomNull) {
- if (CosObjGetType(co) == CosDict && CosDictKnown(co, asaSubFace)) {
- bOk = true;
- co = CosDictGet(co, asaSubFace);
- } else if (CosObjGetType(co) == CosStream)
- bOk = true;
- } else
- bOk = true;
- }
- }
- HANDLER
- bOk = false;
- END_HANDLER
- }
- else
- bOk = false;
-
- return bOk ? co : CosNewNull();
- }
-
-
- /* AnnotIsSelected
- ** Returns true if the given annotation is selected in the AVDoc
- ** corresponding to the given AVPageView.
- */
- static ASBool AnnotIsSelected(AVPageView pageView, PDAnnot annot)
- {
- AVDoc doc = AVPageViewGetAVDoc(pageView);
- ASAtom selType = AVDocGetSelectionType(doc);
- ASBool result = false;
-
- /* Make sure the selection is of the right type
- */
- if (selType == Annotation_K)
- {
- PDAnnot *selection = (PDAnnot *)AVDocGetSelection(doc);
- if (selection)
- /* Compare the selection. Don't compare objects directly,
- ** use the provided comparison functions instead!
- */
- result = PDAnnotEqual(annot, *selection);
- }
-
- return result;
- }
-
- /* AVRectSet
- ** Utility routine for setting the fields of an AVRect.
- */
- static void AVRectSet(AVRect *avRect, Int16 left, Int16 top, Int16 right,
- Int16 bottom)
- {
- avRect->left = left;
- avRect->top = top;
- avRect->right = right;
- avRect->bottom = bottom;
- }
-
- /* AVRectEqual
- ** Utility routine for comparing two AVRects.
- */
- static ASBool AVRectEqual(const AVRect *avr1, const AVRect *avr2)
- {
- return (avr1->left == avr2->left) && (avr1->top == avr2->top)
- && (avr1->right == avr2->right) && (avr1->bottom == avr2->bottom);
- }
-
- /* FixedRectSet
- ** Utility routine for setting the fields of a FixedRect.
- */
- static void FixedRectSet(FixedRect *fixedRect, Fixed left, Fixed top, Fixed right,
- Fixed bottom)
- {
- fixedRect->left = left;
- fixedRect->top = top;
- fixedRect->right = right;
- fixedRect->bottom = bottom;
- }
-
- /* StamperGetViewBBox
- ** Returns the rectangle (in device space) of a given Stamper annotation.
- */
- static ACCB1 void ACCB2 StamperGetViewBBox(AVAnnotHandler annotHandler,
- AVPageView pageView, PDAnnot annot, AVRect *bbox)
- {
- FixedRect pdRect;
-
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerGetAnnotViewBBoxProc\r\n");
- }
-
- PDAnnotGetRect(annot, &pdRect);
- AVPageViewRectToDevice(pageView, &pdRect, bbox);
- }
-
- /*
- ** StamperDraw - Updated for Acrobat 3.0 annotations
- ** AVAnnotHandler callback for drawing the Stamper annotation. Calls
- ** PDAnnotGetState() to get the current state of the Annotation (from the
- ** AS key), then calls PDAnnotGetAppearance() to get the current appearance
- ** from the AP key), then gets the annotation rectangle with AVPageViewGetAnnotRect()
- ** and draws the annotation from the data stored in the annotations appearance
- ** dictionary with AVPageViewDrawCosObj();
- */
- static ACCB1 void ACCB2 StamperDraw(AVAnnotHandler handler, PDAnnot annot,
- AVPageView pageView)
- {
- ASAtom coState;
- CosObj coApp;
- AVRect avr;
-
- if(gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerDrawProc\r\n");
- }
-
- coState = PDAnnotGetState(annot);
- coApp = PDAnnotGetAppearance(annot, FaceNormal_K, coState);
- AVPageViewGetAnnotRect(pageView, annot, &avr);
- AVPageViewDrawCosObj(pageView, coApp, &avr);
- }
-
- /* StamperGetType
- ** Returns the Stamper annotation handler's annotation subtype
- */
- static ACCB1 ASAtom ACCB2 StamperGetType(AVAnnotHandler handler)
- {
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerGetTypeProc\r\n");
- }
- return Stamper_K;
- }
-
- /* StamperAdjustCursor
- ** if the cursor is over a Stamper annotation, set it to the default
- ** (arrow) cursor.
- */
- static ACCB1 ASBool ACCB2 StamperAdjustCursor(AVAnnotHandler handler,
- PDAnnot annot, AVPageView pageView, Int16 x, Int16 y)
- {
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerAdjustCursorProc\r\n");
- }
-
- AVSysSetCursor(NULL);
-
- /* Returning true here indicates that the Stamper annotation
- ** does indeed care about the cursor's appearance, and did
- ** set it accordingly.
- */
- return true;
- }
- /* StamperGetLayer
- ** What layer is the stamp at?
- */
- static ACCB1 Fixed ACCB2 StamperGetLayer(AVAnnotHandler annotHandler, PDAnnot annot)
- {
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerGetLayerProc\r\n");
- }
-
- return LINK_LAYER;
- }
-
-
- /* StamperDoClick
- ** A click was detected in the Stamper annotation. Select it if
- ** it was not already selected, and drag it around if the user
- ** holds the mouse down.
- */
- static ACCB1 ASBool ACCB2 StamperDoClick(AVAnnotHandler handler,
- PDAnnot annot, AVPageView pageView, Int16 x, Int16 y,
- Int16 flags, Int16 clickNo)
- {
-
- char theScript[kScriptBufferSize];
- KeyMap keysPressed;
-
- /* clear out the script buffer */
- memset(&theScript, 0, sizeof(theScript));
-
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerDoClickProc\r\n");
- }
-
- /* Only select the annotation if it isn't already selected.
- */
- if (!AnnotIsSelected(pageView, annot))
- {
- PDAnnot *anAnnot = (PDAnnot *)ASmalloc(sizeof(annot));
-
- *anAnnot = annot;
- AVDocSetSelection(AVPageViewGetAVDoc(pageView),
- Annotation_K, anAnnot, true);
- }
-
- GetScriptFromAnnot( annot, theScript );
-
- /* if > 0, then it's safe to say there's a script in there... */
- if( strlen( theScript ) > 0 )
- DoScript( theScript );
-
- return true;
- }
-
- /* StamperDoRightClick
-
- */
- static ACCB1 ASBool ACCB2 StamperDoRightClick(AVAnnotHandler handler,
- PDAnnot annot, AVPageView pageView, Int16 x, Int16 y,
- Int16 flags, Int16 clickNo)
- {
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerDoClickProc\r\n");
- }
-
- /* Only select the annotation if it isn't already selected.
- */
- if (!AnnotIsSelected(pageView, annot))
- {
- PDAnnot *anAnnot = (PDAnnot *)ASmalloc(sizeof(annot));
-
- *anAnnot = annot;
- AVDocSetSelection(AVPageViewGetAVDoc(pageView),
- Annotation_K, anAnnot, true);
- }
-
- if( IsKeyDown( 58 ) == true )
- {
- PDPage pdPage;
- CosDoc cdoc;
- CosObj cAnnotObj, scriptObj, cObj;
- char theScript[kScriptBufferSize];
-
- memset(&theScript, 0, sizeof(theScript));
- GetScriptFromAnnot( annot, theScript );
- AddModifyScriptDialog( theScript );
-
- pdPage = AVPageViewGetPage(pageView);
- cAnnotObj = PDAnnotGetCosObj(annot);
- cdoc = PDDocGetCosDoc(PDPageGetDoc(pdPage));
-
- scriptObj = CosNewDict( cdoc, true, 1L );
- cObj = CosNewName( cdoc, false, ASAtomFromString( "AppleScript" ));
- CosDictPut( scriptObj, ASAtomFromString("Type"), cObj );
-
- /* saves the script as a string in the cos object */
- cObj = CosNewString( cdoc, false, theScript, strlen( theScript ));
- CosDictPut( scriptObj, ASAtomFromString("TheScript"), cObj );
-
- CosDictPut( cAnnotObj, ASAtomFromString("AppleScript"), scriptObj );
-
- } else {
-
- /* Don't enter the drag loop if the user has already let go of the mouse
- */
- if (AVSysMouseIsStillDown())
- {
- AVRect oldLocation, newLocation;
-
- /* Get the old location of the annotation in device space. This
- ** is needed by AVPageViewDragRect to know where to begin dragging.
- ** It is also used to determine the size of the rectangle to be
- ** dragged.
- */
- StamperGetViewBBox(handler, pageView, annot, &oldLocation);
-
- /* Call AVPageViewDragRect. This tracks the mouse position, dragging
- ** a gray rect around underneath it while the mouse button is still down.
- ** The selector code 0 (there should be a macro, but there isn't yet)
- ** indicates we are moving the entire rectangle, rather than simply
- ** dragging a corner. Since dragging is constrained only by the bounds
- ** of the AVPageView, we can pass NULL for the extrema.
- */
- AVPageViewDragRect(pageView, x, y, &oldLocation, &newLocation, 0, NULL);
-
- /* If oldLocation == newLocation, there is no need to change the annotation's
- ** position.
- */
- if (!AVRectEqual(&oldLocation, &newLocation))
- {
- FixedRect newPDLocation;
-
- /* Convert the newLocation (in device space) to user space, and call
- ** PDAnnotSetRect. The viewer takes care of the screen update.
- */
- AVPageViewDeviceRectToPage(pageView, &newLocation, &newPDLocation);
- PDAnnotSetRect(annot, &newPDLocation);
- }
- }
- }
-
- return true;
- }
-
- /* StamperNotifyAddedToSelection
- ** Draw the knobs on the selected annotation.
- */
- static ACCB1 void ACCB2 StamperNotifyAddedToSelection(AVAnnotHandler handler,
- PDAnnot annot, AVPageView pageView)
- {
- /* We might have been selected programatically, so we shouldn't assume
- ** the annotation is on the current page. The easy way to check for this
- ** is to ask for the PDPage's index of this PDAnnot.
- */
- PDPage pdPage = AVPageViewGetPage(pageView);
- Int32 index = PDPageGetAnnotIndex(pdPage, annot);
-
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerNotifyAnnotAddedToSelectionProc\r\n");
- }
-
-
- /* if index == -1, the annot is not on this page. Don't draw anything.
- */
- if (index != -1)
- {
- AVRect annotRect;
- StamperGetViewBBox(handler, pageView, annot, &annotRect);
- DrawKnobs(pageView, &annotRect);
- }
- }
-
- /* StamperNotifyRemovedFromSelection
- ** Erase the knobs on the selected annotation.
- */
- static ACCB1 void ACCB2 StamperNotifyRemovedFromSelection(AVAnnotHandler handler,
- PDAnnot annot, AVPageView pageView)
- {
- PDPage pdPage = AVPageViewGetPage(pageView);
- Int32 index = PDPageGetAnnotIndex(pdPage, annot);
-
- if (gDebuggerWindowHFT){
- ShowDebuggerWindow();
- DebuggerEmitString("AVAnnotHandlerNotifyAnnotRemovedFromSelectionProc\r\n");
- }
-
- /* Make sure the annotation is on the current page.
- */
- if (index != -1)
- {
- AVRect annotRect;
- StamperGetViewBBox(handler, pageView, annot, &annotRect);
- EraseKnobs(pageView, &annotRect);
- }
- }
-
- void SetUpStamperAnnotHandler(void)
- {
- State_K = ASAtomFromString("AS");
- Appearance_K = ASAtomFromString("AP");
- FaceNormal_K = ASAtomFromString("N");
- FaceRollover_K = ASAtomFromString("R");
- FaceDown_K = ASAtomFromString("D");
- Flags_K = ASAtomFromString("F");
- Length_K = ASAtomFromString("Length");
-
- /* zero out the unused fields of the Stamper annotation handler */
- memset(&stamperAH, 0, sizeof(stamperAH));
-
- /* Set up the size field of the Stamper annotation. If you don't do
- ** this your plug-in won't load with future versions of the viewer!
- */
- stamperAH.size = sizeof(stamperAH);
-
- /* Stamper annotations appear in the same layer as link annotations.
- */
- stamperAH.flags = LINK_LAYER;
-
- /* Set up the callbacks */
- stamperAH.GetType = ASCallbackCreateProto(AVAnnotHandlerGetTypeProc, &StamperGetType);
- stamperAH.Draw = ASCallbackCreateProto(AVAnnotHandlerDrawProc, &StamperDraw);
- stamperAH.GetAnnotViewBBox = ASCallbackCreateProto(AVAnnotHandlerGetAnnotViewBBoxProc,
- &StamperGetViewBBox);
- stamperAH.AdjustCursor = ASCallbackCreateProto(AVAnnotHandlerAdjustCursorProc,
- &StamperAdjustCursor);
- stamperAH.DoClick = ASCallbackCreateProto( AVAnnotHandlerDoClickProc, &StamperDoClick );
- stamperAH.DoRightClick = ASCallbackCreateProto(AVAnnotHandlerDoClickProc, &StamperDoRightClick);
- stamperAH.NotifyAnnotAddedToSelection = ASCallbackCreateProto(AVAnnotHandlerNotifyAnnotAddedToSelectionProc,
- &StamperNotifyAddedToSelection);
- stamperAH.NotifyAnnotRemovedFromSelection = ASCallbackCreateProto(AVAnnotHandlerNotifyAnnotRemovedFromSelectionProc,
- &StamperNotifyRemovedFromSelection);
- stamperAH.GetLayer = ASCallbackCreateProto(AVAnnotHandlerGetLayerProc, &StamperGetLayer);
- /* Register the annotation handler */
- AVAppRegisterAnnotHandler(&stamperAH);
- }
-
- /* CreateAppleScriptAnnotationAt
- ** Clients may call this to create a stamp annotation centered on the given coordinates.
- */
- ASBool CreateAppleScriptAnnotationAt(AVPageView pageView, Int16 x, Int16 y)
- {
- FixedRect pdLocation;
- FixedPoint center;
- PDAnnot annot;
- CosObj cAnnotObj, cIntObj, cStmObj, attributesDict, LengthEntry, cNullObj;
- CosObj cAPDictObj, cStmDictObj, cBBoxObj, cProcSetObj, cResObj;
- CosObj fontResObj, fontResObj2, scriptObj, cObj;
- CosDoc cdoc;
- ASStm stm;
- char buf[kScriptBufferSize];
- PDPage pdPage;
- ASUns32 s;
-
- memset(&buf, 0, sizeof(buf));
-
- /* if user hits "cancel" button, return false and don't add the annotation */
- if( AddModifyScriptDialog( buf ) == false )
- return( false );
-
- DURING
- pdPage = AVPageViewGetPage(pageView);
-
- AVPageViewDevicePointToPage(pageView, x, y, ¢er);
- FixedRectSet(&pdLocation, center.h - FixedDiv(fixedHundred, fixedTwo),
- center.v + FixedDiv(fixedHundred, fixedTwo),
- center.h + FixedDiv(fixedHundred, fixedTwo),
- center.v - FixedDiv(fixedHundred, fixedTwo));
-
- /*
- ** Add the new annotation on page 1 of the document
- */
- annot = PDPageAddNewAnnot(pdPage, -1, Stamper_K, &pdLocation);
-
- cAnnotObj = PDAnnotGetCosObj(annot);
- cdoc = PDDocGetCosDoc(PDPageGetDoc(pdPage));
-
- scriptObj = CosNewDict( cdoc, true, 1L );
- cObj = CosNewName( cdoc, false, ASAtomFromString( "AppleScript" ));
- CosDictPut( scriptObj, ASAtomFromString("Type"), cObj );
-
- /* saves the script as a string in the cos object */
- cObj = CosNewString( cdoc, false, buf, strlen( buf ));
- CosDictPut( scriptObj, ASAtomFromString("TheScript"), cObj );
-
- CosDictPut( cAnnotObj, ASAtomFromString("AppleScript"), scriptObj );
-
-
- /*
- ** Bit Position Semantics from table 6.4a on Flags
- */
- cIntObj = CosNewInteger (cdoc, false, 4L);
- CosDictPut(cAnnotObj, Flags_K, cIntObj);
-
- cAPDictObj = CosNewDict(cdoc, false, 1L);
- cNullObj = CosNewNull();
-
- /*
- ** Read in the stream for the appearance key
- */
- memset(&buf, 0, sizeof(buf));
- strcat(buf, "BT /STAMPR 24 Tf 10 40 TD ( Fancy)Tj ET q 10 w 1 0 0 RG 5 5 90 90 re S Q");
- s = (ASUns32)strlen(buf);
- stm = ASMemStmRdOpen(buf, s);
-
- attributesDict = CosNewDict(cdoc, false, 5);
- LengthEntry = CosNewInteger(cdoc, false, s);
- CosDictPut(attributesDict, Length_K, LengthEntry);
-
- cStmObj = CosNewStream(cdoc, true, stm, 0, true, attributesDict, cNullObj, s);
- cStmDictObj = CosStreamDict(cStmObj);
-
- CosDictPut(cStmDictObj, ASAtomFromString("Type"), CosNewName(cdoc, false, ASAtomFromString("XObject")));
-
- CosDictPut(cStmDictObj, ASAtomFromString("Subtype"), CosNewName(cdoc, false, ASAtomFromString("Form")));
-
- CosDictPut(cStmDictObj, ASAtomFromString("FormType"), CosNewInteger(cdoc, false, 1L));
-
- cBBoxObj = CosNewArray(cdoc, false, 4L);
- CosArrayInsert(cBBoxObj, 0L, CosNewInteger(cdoc, false, 0L));
- CosArrayInsert(cBBoxObj, 1L, CosNewInteger(cdoc, false, 0L));
- CosArrayInsert(cBBoxObj, 2L, CosNewInteger(cdoc, false, 100L));
- CosArrayInsert(cBBoxObj, 3L, CosNewInteger(cdoc, false, 100L));
- CosDictPut(cStmDictObj, ASAtomFromString("BBox"), cBBoxObj);
-
- /* Create Resource dictionary for XObject */
- cResObj = CosNewDict(cdoc, false, 5L);
-
- /* Add Font resource to Resources dictionary */
- fontResObj = CosNewDict(cdoc, true, 1L);
- fontResObj2 = CosNewDict(cdoc, true, 5L);
- cObj = CosNewName(cdoc, false, ASAtomFromString("Font"));
- CosDictPut(fontResObj2, ASAtomFromString("Type"), cObj);
- cObj = CosNewName(cdoc, false, ASAtomFromString("Type1"));
- CosDictPut(fontResObj2, ASAtomFromString("Subtype"), cObj);
- cObj = CosNewName(cdoc, false, ASAtomFromString("STAMPR"));
- CosDictPut(fontResObj2, ASAtomFromString("Name"), cObj);
- cObj = CosNewName(cdoc, false, ASAtomFromString("Helvetica"));
- CosDictPut(fontResObj2, ASAtomFromString("BaseFont"), cObj);
- CosDictPut(fontResObj, ASAtomFromString("STAMPR"), fontResObj2);
- CosDictPut(cResObj, ASAtomFromString("Font"), fontResObj);
-
- /* Set up ProcSet Resources */
- cProcSetObj = CosNewArray(cdoc, false, 2L);
- CosArrayPut(cProcSetObj, 0L, CosNewName(cdoc, false, ASAtomFromString("PDF")));
- CosArrayPut(cProcSetObj, 1L, CosNewName(cdoc, false, ASAtomFromString("Text")));
- CosDictPut(cResObj, ASAtomFromString("ProcSet"), cProcSetObj);
-
- /* Put Resources dictionary in XObject's stream dictionary. */
- CosDictPut(cStmDictObj, ASAtomFromString("Resources"), cResObj);
-
- /*
- ** Set the stream object (now a Forms XObject) as the normal (N) key and add to the appearance (AP)
- ** key
- */
- CosDictPut(cAPDictObj, FaceNormal_K, cStmObj);
- CosDictPut(cAnnotObj, Appearance_K, cAPDictObj);
-
- HANDLER
- AVAlertNote(ASGetErrorString(ERRORCODE, buf, sizeof(buf)));
- END_HANDLER
-
- //StampSound();
-
- return true;
- }
-