home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / AppleScript for Acrobat plug-in / SOURCES / STAMPAH.C < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-24  |  19.1 KB  |  620 lines

  1. /******************************************************************************
  2.  
  3. StampAH.c
  4.  
  5. This file is furnished to you by Adobe Systems Incorporated 
  6. under the terms of the Acrobat(r) Plug-ins Software 
  7. Development Kit License Agreement.
  8.  
  9. Copyright (C) 1994-1997, Adobe Systems Inc.  All Rights Reserved.
  10.  
  11.  
  12. Implementation of the Stamper's annotation-related routines.
  13.  
  14. ******************************************************************************/
  15.  
  16. #include "stampah.h"
  17. #include "stamper.h"
  18. #include "stamppr.h"
  19.  
  20. #include "ASCalls.h"
  21. #include "AVCalls.h"
  22. #include "CorCalls.h"
  23. #include "PDCalls.h"
  24. #include "CosCalls.h"
  25.  
  26. #include "debugger.h"  
  27. extern HFT gDebuggerWindowHFT;
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <Dialogs.h>
  32. #include "AcrobatAppleScript.h"
  33.  
  34. ASAtom State_K;
  35. ASAtom Appearance_K;
  36. ASAtom FaceNormal_K;
  37. ASAtom FaceRollover_K;
  38. ASAtom FaceDown_K;
  39. ASAtom Flags_K;
  40. ASAtom Length_K;
  41.  
  42. /* stamperAH
  43. ** This is the annotation handler object for all Stamper annotations.
  44. */
  45. AVAnnotHandlerRec stamperAH;
  46.  
  47. /* PDAnnotGetState
  48. ** Returns the current state specified by the AS key in the annotation's
  49. ** dictionary.  Returns ASAtomNull if no AS key found.
  50. */
  51. extern ASAtom PDAnnotGetState(PDAnnot pdan);
  52. ASAtom PDAnnotGetState(PDAnnot pdan)
  53. {
  54.     ASAtom asaState = ASAtomNull;
  55.  
  56.     if (PDAnnotIsValid(pdan)) {
  57.         DURING 
  58.             CosObj co = PDAnnotGetCosObj(pdan);
  59.             if (CosDictKnown(co, State_K)) {
  60.                 co = CosDictGet(co, State_K);
  61.                 asaState = CosNameValue(co);
  62.             }
  63.         HANDLER
  64.             asaState = ASAtomNull;
  65.         END_HANDLER
  66.     }
  67.     else
  68.         asaState = ASAtomNull;
  69.     return asaState;
  70. }
  71.  
  72. /* PDAnnotGetApppearance
  73. ** Returns the appearance CosStream for the annotation in question.  asaFace
  74. ** indicates which face (Normal, Rollover, Down, etc.) is to be used, and asaSubFace
  75. ** indicates which subface to use.  If asaSubFace is ASAtomNull, then the asaFace
  76. ** is assumed to only have one face and therefore it is returned as a CosStream.
  77. */
  78.  
  79. extern CosObj PDAnnotGetAppearance(PDAnnot pdan, ASAtom asaFace, ASAtom asaSubFace);
  80. CosObj PDAnnotGetAppearance(PDAnnot pdan, ASAtom asaFace, ASAtom asaSubFace)
  81. {
  82.     /* We handle two forms here. In the simple case there is a single face for
  83.      * each state (e.g. N, R, D, X are streams). In the complex case, there are 
  84.      * several faces for each appearance, referenced by name inside the 
  85.      * N, R, D, and X dicts. You can get the sub-face name by using PDAnnotGetState().
  86.      */
  87.     CosObj co;
  88.     ASBool bOk = false;
  89.  
  90.     if (PDAnnotIsValid(pdan) && asaFace != ASAtomNull) {
  91.         DURING
  92.             co = PDAnnotGetCosObj(pdan);
  93.             if (CosDictKnown(co, Appearance_K)) {
  94.                 co = CosDictGet(co, Appearance_K);
  95.                 if (CosDict == CosObjGetType(co) && CosDictKnown(co, asaFace)) {
  96.                     co = CosDictGet(co, asaFace);
  97.                     if (asaSubFace != ASAtomNull) {
  98.                         if (CosObjGetType(co) == CosDict &&    CosDictKnown(co, asaSubFace)) {
  99.                             bOk = true;
  100.                             co = CosDictGet(co, asaSubFace);
  101.                         } else if (CosObjGetType(co) == CosStream)
  102.                             bOk = true;
  103.                     } else
  104.                         bOk = true;
  105.                 }
  106.             }
  107.         HANDLER
  108.             bOk = false;
  109.         END_HANDLER
  110.     }
  111.     else
  112.         bOk = false;
  113.     
  114.     return bOk ? co : CosNewNull();
  115. }
  116.  
  117.  
  118. /* AnnotIsSelected
  119. ** Returns true if the given annotation is selected in the AVDoc
  120. ** corresponding to the given AVPageView.
  121. */
  122. static ASBool AnnotIsSelected(AVPageView pageView, PDAnnot annot)
  123. {
  124.     AVDoc doc = AVPageViewGetAVDoc(pageView);
  125.     ASAtom selType = AVDocGetSelectionType(doc);
  126.     ASBool result = false;
  127.     
  128.     /* Make sure the selection is of the right type
  129.     */
  130.     if (selType == Annotation_K)
  131.     {
  132.         PDAnnot *selection = (PDAnnot *)AVDocGetSelection(doc);
  133.         if (selection)
  134.             /* Compare the selection.  Don't compare objects directly,
  135.             ** use the provided comparison functions instead!
  136.             */
  137.             result = PDAnnotEqual(annot, *selection);
  138.     }
  139.     
  140.     return result;
  141. }
  142.     
  143. /* AVRectSet
  144. ** Utility routine for setting the fields of an AVRect.
  145. */
  146. static void AVRectSet(AVRect *avRect, Int16 left, Int16 top, Int16 right,
  147.     Int16 bottom)
  148. {
  149.     avRect->left = left;
  150.     avRect->top = top;
  151.     avRect->right = right;
  152.     avRect->bottom = bottom;
  153. }
  154.  
  155. /* AVRectEqual
  156. ** Utility routine for comparing two AVRects.
  157. */
  158. static ASBool AVRectEqual(const AVRect *avr1, const AVRect *avr2)
  159. {
  160.     return (avr1->left == avr2->left) && (avr1->top == avr2->top)
  161.         && (avr1->right == avr2->right) && (avr1->bottom == avr2->bottom);
  162. }
  163.  
  164. /* FixedRectSet
  165. ** Utility routine for setting the fields of a FixedRect.
  166. */
  167. static void FixedRectSet(FixedRect *fixedRect, Fixed left, Fixed top, Fixed right,
  168.     Fixed bottom)
  169. {
  170.     fixedRect->left = left;
  171.     fixedRect->top = top;
  172.     fixedRect->right = right;
  173.     fixedRect->bottom = bottom;
  174. }
  175.  
  176. /* StamperGetViewBBox
  177. ** Returns the rectangle (in device space) of a given Stamper annotation.
  178. */
  179. static ACCB1 void ACCB2 StamperGetViewBBox(AVAnnotHandler annotHandler,
  180.     AVPageView pageView, PDAnnot annot, AVRect *bbox)
  181. {
  182.     FixedRect pdRect;
  183.     
  184.     if (gDebuggerWindowHFT){
  185.         ShowDebuggerWindow();
  186.         DebuggerEmitString("AVAnnotHandlerGetAnnotViewBBoxProc\r\n");
  187.     }
  188.     
  189.     PDAnnotGetRect(annot, &pdRect);
  190.     AVPageViewRectToDevice(pageView, &pdRect, bbox);
  191. }
  192.  
  193. /*
  194. ** StamperDraw - Updated for Acrobat 3.0 annotations
  195. ** AVAnnotHandler callback for drawing the Stamper annotation.  Calls
  196. ** PDAnnotGetState() to get the current state of the Annotation (from the
  197. ** AS key), then calls PDAnnotGetAppearance() to get the current appearance
  198. ** from the AP key), then gets the annotation rectangle with AVPageViewGetAnnotRect()
  199. ** and draws the annotation from the data stored in the annotations appearance
  200. ** dictionary with AVPageViewDrawCosObj();
  201. */
  202. static ACCB1 void ACCB2 StamperDraw(AVAnnotHandler handler, PDAnnot annot,
  203.     AVPageView pageView)
  204. {
  205.     ASAtom coState;
  206.     CosObj coApp;
  207.     AVRect avr;
  208.  
  209.     if(gDebuggerWindowHFT){
  210.         ShowDebuggerWindow();
  211.         DebuggerEmitString("AVAnnotHandlerDrawProc\r\n");
  212.     }
  213.  
  214.     coState = PDAnnotGetState(annot);
  215.     coApp = PDAnnotGetAppearance(annot, FaceNormal_K, coState);
  216.     AVPageViewGetAnnotRect(pageView, annot, &avr);
  217.     AVPageViewDrawCosObj(pageView, coApp, &avr);
  218. }
  219.  
  220. /* StamperGetType
  221. ** Returns the Stamper annotation handler's annotation subtype
  222. */
  223. static ACCB1 ASAtom ACCB2 StamperGetType(AVAnnotHandler handler)
  224. {
  225.     if (gDebuggerWindowHFT){
  226.         ShowDebuggerWindow();
  227.         DebuggerEmitString("AVAnnotHandlerGetTypeProc\r\n");
  228.     }
  229.     return Stamper_K;
  230. }
  231.  
  232. /* StamperAdjustCursor
  233. ** if the cursor is over a Stamper annotation, set it to the default
  234. ** (arrow) cursor.
  235. */
  236. static ACCB1 ASBool ACCB2 StamperAdjustCursor(AVAnnotHandler handler,
  237.     PDAnnot annot, AVPageView pageView, Int16 x, Int16 y)
  238. {
  239.     if (gDebuggerWindowHFT){
  240.         ShowDebuggerWindow();
  241.         DebuggerEmitString("AVAnnotHandlerAdjustCursorProc\r\n");
  242.     }
  243.     
  244.     AVSysSetCursor(NULL);
  245.     
  246.     /* Returning true here indicates that the Stamper annotation
  247.     ** does indeed care about the cursor's appearance, and did
  248.     ** set it accordingly.
  249.     */
  250.     return true;
  251. }
  252. /* StamperGetLayer
  253. ** What layer is the stamp at?
  254. */
  255. static ACCB1 Fixed ACCB2 StamperGetLayer(AVAnnotHandler annotHandler, PDAnnot annot)
  256. {
  257.     if (gDebuggerWindowHFT){
  258.         ShowDebuggerWindow();
  259.         DebuggerEmitString("AVAnnotHandlerGetLayerProc\r\n");
  260.     }
  261.  
  262.     return LINK_LAYER;
  263. }
  264.  
  265.  
  266. /* StamperDoClick
  267. ** A click was detected in the Stamper annotation.  Select it if
  268. ** it was not already selected, and drag it around if the user
  269. ** holds the mouse down.
  270. */
  271. static ACCB1 ASBool ACCB2 StamperDoClick(AVAnnotHandler handler,
  272.     PDAnnot annot, AVPageView pageView, Int16 x, Int16 y,
  273.     Int16 flags, Int16 clickNo)
  274. {
  275.  
  276.     char    theScript[kScriptBufferSize];
  277.     KeyMap    keysPressed;    
  278.  
  279.     /* clear out the script buffer */
  280.     memset(&theScript, 0, sizeof(theScript));
  281.  
  282.     if (gDebuggerWindowHFT){
  283.         ShowDebuggerWindow();
  284.         DebuggerEmitString("AVAnnotHandlerDoClickProc\r\n");
  285.     }
  286.     
  287.     /* Only select the annotation if it isn't already selected.
  288.     */
  289.     if (!AnnotIsSelected(pageView, annot))
  290.     {
  291.         PDAnnot *anAnnot = (PDAnnot *)ASmalloc(sizeof(annot));
  292.         
  293.         *anAnnot = annot;
  294.         AVDocSetSelection(AVPageViewGetAVDoc(pageView),
  295.             Annotation_K, anAnnot, true);
  296.     }
  297.     
  298.     GetScriptFromAnnot( annot, theScript );
  299.     
  300.     /* if > 0, then it's safe to say there's a script in there... */
  301.     if( strlen( theScript ) > 0 )
  302.         DoScript( theScript );
  303.     
  304.     return true;
  305. }
  306.  
  307. /* StamperDoRightClick
  308.  
  309. */
  310. static ACCB1 ASBool ACCB2 StamperDoRightClick(AVAnnotHandler handler,
  311.     PDAnnot annot, AVPageView pageView, Int16 x, Int16 y,
  312.     Int16 flags, Int16 clickNo)
  313. {
  314.     if (gDebuggerWindowHFT){
  315.         ShowDebuggerWindow();
  316.         DebuggerEmitString("AVAnnotHandlerDoClickProc\r\n");
  317.     }
  318.     
  319.     /* Only select the annotation if it isn't already selected.
  320.     */
  321.     if (!AnnotIsSelected(pageView, annot))
  322.     {
  323.         PDAnnot *anAnnot = (PDAnnot *)ASmalloc(sizeof(annot));
  324.         
  325.         *anAnnot = annot;
  326.         AVDocSetSelection(AVPageViewGetAVDoc(pageView),
  327.             Annotation_K, anAnnot, true);
  328.     }
  329.  
  330.     if( IsKeyDown( 58 ) == true )
  331.     {
  332.         PDPage     pdPage;    
  333.         CosDoc    cdoc;
  334.         CosObj    cAnnotObj, scriptObj, cObj;
  335.         char    theScript[kScriptBufferSize];
  336.  
  337.         memset(&theScript, 0, sizeof(theScript));            
  338.         GetScriptFromAnnot( annot, theScript );
  339.         AddModifyScriptDialog( theScript );
  340.  
  341.         pdPage = AVPageViewGetPage(pageView);
  342.         cAnnotObj = PDAnnotGetCosObj(annot);
  343.         cdoc = PDDocGetCosDoc(PDPageGetDoc(pdPage));    
  344.     
  345.         scriptObj = CosNewDict( cdoc, true, 1L );
  346.         cObj = CosNewName( cdoc, false, ASAtomFromString( "AppleScript" ));
  347.         CosDictPut( scriptObj, ASAtomFromString("Type"), cObj );
  348.         
  349.         /* saves the script as a string in the cos object */
  350.         cObj = CosNewString( cdoc, false, theScript, strlen( theScript ));
  351.         CosDictPut( scriptObj, ASAtomFromString("TheScript"), cObj );
  352.         
  353.         CosDictPut( cAnnotObj, ASAtomFromString("AppleScript"), scriptObj );
  354.  
  355.     } else {
  356.     
  357.         /* Don't enter the drag loop if the user has already let go of the mouse
  358.         */
  359.         if (AVSysMouseIsStillDown())
  360.         {
  361.             AVRect oldLocation, newLocation;
  362.             
  363.             /* Get the old location of the annotation in device space.  This
  364.             ** is needed by AVPageViewDragRect to know where to begin dragging.
  365.             ** It is also used to determine the size of the rectangle to be
  366.             ** dragged.
  367.             */
  368.             StamperGetViewBBox(handler, pageView, annot, &oldLocation);
  369.             
  370.             /* Call AVPageViewDragRect.  This tracks the mouse position, dragging
  371.             ** a gray rect around underneath it while the mouse button is still down.
  372.             ** The selector code 0 (there should be a macro, but there isn't yet)
  373.             ** indicates we are moving the entire rectangle, rather than simply
  374.             ** dragging a corner.  Since dragging is constrained only by the bounds
  375.             ** of the AVPageView, we can pass NULL for the extrema.
  376.             */
  377.             AVPageViewDragRect(pageView, x, y, &oldLocation, &newLocation, 0, NULL);
  378.             
  379.             /* If oldLocation == newLocation, there is no need to change the annotation's
  380.             ** position.
  381.             */
  382.             if (!AVRectEqual(&oldLocation, &newLocation))
  383.             {
  384.                 FixedRect newPDLocation;
  385.                 
  386.                 /* Convert the newLocation (in device space) to user space, and call
  387.                 ** PDAnnotSetRect.  The viewer takes care of the screen update.
  388.                 */
  389.                 AVPageViewDeviceRectToPage(pageView, &newLocation, &newPDLocation);
  390.                 PDAnnotSetRect(annot, &newPDLocation);
  391.             }
  392.         }
  393.     }
  394.         
  395.     return true;
  396. }
  397.  
  398. /* StamperNotifyAddedToSelection
  399. ** Draw the knobs on the selected annotation.
  400. */
  401. static ACCB1 void ACCB2 StamperNotifyAddedToSelection(AVAnnotHandler handler,
  402.     PDAnnot annot, AVPageView pageView)
  403. {
  404.     /* We might have been selected programatically, so we shouldn't assume
  405.     ** the annotation is on the current page.  The easy way to check for this
  406.     ** is to ask for the PDPage's index of this PDAnnot.
  407.     */
  408.     PDPage pdPage = AVPageViewGetPage(pageView);
  409.     Int32 index = PDPageGetAnnotIndex(pdPage, annot);
  410.     
  411.     if (gDebuggerWindowHFT){
  412.         ShowDebuggerWindow();
  413.         DebuggerEmitString("AVAnnotHandlerNotifyAnnotAddedToSelectionProc\r\n");
  414.     }
  415.     
  416.     
  417.     /* if index == -1, the annot is not on this page.  Don't draw anything.
  418.     */
  419.     if (index != -1)
  420.     {
  421.         AVRect annotRect;
  422.         StamperGetViewBBox(handler, pageView, annot, &annotRect);
  423.         DrawKnobs(pageView, &annotRect);
  424.     }
  425. }
  426.  
  427. /* StamperNotifyRemovedFromSelection
  428. ** Erase the knobs on the selected annotation.
  429. */
  430. static ACCB1 void ACCB2 StamperNotifyRemovedFromSelection(AVAnnotHandler handler,
  431.     PDAnnot annot, AVPageView pageView)
  432. {
  433.     PDPage pdPage = AVPageViewGetPage(pageView);
  434.     Int32 index = PDPageGetAnnotIndex(pdPage, annot);
  435.     
  436.     if (gDebuggerWindowHFT){
  437.         ShowDebuggerWindow();
  438.         DebuggerEmitString("AVAnnotHandlerNotifyAnnotRemovedFromSelectionProc\r\n");
  439.     }
  440.  
  441.     /* Make sure the annotation is on the current page.
  442.     */
  443.     if (index != -1)
  444.     {
  445.         AVRect annotRect;
  446.         StamperGetViewBBox(handler, pageView, annot, &annotRect);
  447.         EraseKnobs(pageView, &annotRect);
  448.     }
  449. }
  450.     
  451. void SetUpStamperAnnotHandler(void)
  452. {
  453.     State_K = ASAtomFromString("AS");
  454.     Appearance_K = ASAtomFromString("AP");
  455.     FaceNormal_K = ASAtomFromString("N");
  456.     FaceRollover_K = ASAtomFromString("R");
  457.     FaceDown_K = ASAtomFromString("D");
  458.     Flags_K = ASAtomFromString("F");
  459.     Length_K = ASAtomFromString("Length");
  460.     
  461.     /* zero out the unused fields of the Stamper annotation handler */
  462.     memset(&stamperAH, 0, sizeof(stamperAH));
  463.     
  464.     /* Set up the size field of the Stamper annotation.  If you don't do
  465.     ** this your plug-in won't load with future versions of the viewer!
  466.     */
  467.     stamperAH.size = sizeof(stamperAH);
  468.     
  469.     /* Stamper annotations appear in the same layer as link annotations.
  470.     */
  471.     stamperAH.flags = LINK_LAYER;
  472.     
  473.     /* Set up the callbacks */
  474.     stamperAH.GetType = ASCallbackCreateProto(AVAnnotHandlerGetTypeProc, &StamperGetType);
  475.     stamperAH.Draw = ASCallbackCreateProto(AVAnnotHandlerDrawProc, &StamperDraw);
  476.     stamperAH.GetAnnotViewBBox = ASCallbackCreateProto(AVAnnotHandlerGetAnnotViewBBoxProc,
  477.         &StamperGetViewBBox);
  478.     stamperAH.AdjustCursor = ASCallbackCreateProto(AVAnnotHandlerAdjustCursorProc,
  479.         &StamperAdjustCursor);
  480.     stamperAH.DoClick = ASCallbackCreateProto( AVAnnotHandlerDoClickProc, &StamperDoClick );
  481.     stamperAH.DoRightClick = ASCallbackCreateProto(AVAnnotHandlerDoClickProc, &StamperDoRightClick);
  482.     stamperAH.NotifyAnnotAddedToSelection = ASCallbackCreateProto(AVAnnotHandlerNotifyAnnotAddedToSelectionProc,
  483.         &StamperNotifyAddedToSelection);
  484.     stamperAH.NotifyAnnotRemovedFromSelection = ASCallbackCreateProto(AVAnnotHandlerNotifyAnnotRemovedFromSelectionProc,
  485.         &StamperNotifyRemovedFromSelection);
  486.     stamperAH.GetLayer = ASCallbackCreateProto(AVAnnotHandlerGetLayerProc, &StamperGetLayer);
  487.     /* Register the annotation handler */
  488.     AVAppRegisterAnnotHandler(&stamperAH);
  489. }
  490.     
  491. /* CreateAppleScriptAnnotationAt
  492. ** Clients may call this to create a stamp annotation centered on the given coordinates.
  493. */
  494. ASBool CreateAppleScriptAnnotationAt(AVPageView pageView, Int16 x, Int16 y)
  495. {
  496.     FixedRect pdLocation;
  497.     FixedPoint center;
  498.     PDAnnot annot;
  499.     CosObj cAnnotObj, cIntObj, cStmObj, attributesDict, LengthEntry, cNullObj;
  500.     CosObj cAPDictObj, cStmDictObj, cBBoxObj, cProcSetObj, cResObj;
  501.     CosObj fontResObj, fontResObj2, scriptObj, cObj;
  502.     CosDoc cdoc;
  503.     ASStm stm;
  504.     char buf[kScriptBufferSize];
  505.     PDPage pdPage;
  506.     ASUns32 s;
  507.     
  508.     memset(&buf, 0, sizeof(buf));
  509.     
  510.     /* if user hits "cancel" button, return false and don't add the annotation */
  511.     if( AddModifyScriptDialog( buf ) == false )
  512.         return( false );
  513.     
  514. DURING
  515.     pdPage = AVPageViewGetPage(pageView);
  516.     
  517.     AVPageViewDevicePointToPage(pageView, x, y, ¢er);
  518.     FixedRectSet(&pdLocation, center.h - FixedDiv(fixedHundred, fixedTwo),
  519.         center.v + FixedDiv(fixedHundred, fixedTwo),
  520.         center.h + FixedDiv(fixedHundred, fixedTwo),
  521.         center.v - FixedDiv(fixedHundred, fixedTwo));
  522.  
  523. /*
  524. ** Add the new annotation on page 1 of the document
  525. */
  526.     annot = PDPageAddNewAnnot(pdPage, -1, Stamper_K, &pdLocation);
  527.     
  528.     cAnnotObj = PDAnnotGetCosObj(annot);
  529.     cdoc = PDDocGetCosDoc(PDPageGetDoc(pdPage));    
  530.  
  531.     scriptObj = CosNewDict( cdoc, true, 1L );
  532.     cObj = CosNewName( cdoc, false, ASAtomFromString( "AppleScript" ));
  533.     CosDictPut( scriptObj, ASAtomFromString("Type"), cObj );
  534.     
  535.     /* saves the script as a string in the cos object */
  536.     cObj = CosNewString( cdoc, false, buf, strlen( buf ));
  537.     CosDictPut( scriptObj, ASAtomFromString("TheScript"), cObj );
  538.     
  539.     CosDictPut( cAnnotObj, ASAtomFromString("AppleScript"), scriptObj );
  540.     
  541.  
  542. /*
  543. ** Bit Position Semantics from table 6.4a on Flags
  544. */
  545.     cIntObj = CosNewInteger (cdoc, false, 4L);
  546.     CosDictPut(cAnnotObj, Flags_K, cIntObj);
  547.  
  548.     cAPDictObj = CosNewDict(cdoc, false, 1L);
  549.     cNullObj = CosNewNull();
  550.  
  551. /*
  552. ** Read in the stream for the appearance key
  553. */
  554.     memset(&buf, 0, sizeof(buf));
  555.     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");
  556.     s = (ASUns32)strlen(buf);
  557.     stm = ASMemStmRdOpen(buf, s);
  558.     
  559.     attributesDict    = CosNewDict(cdoc, false, 5);
  560.     LengthEntry = CosNewInteger(cdoc, false, s);
  561.     CosDictPut(attributesDict, Length_K, LengthEntry);
  562.     
  563.     cStmObj = CosNewStream(cdoc, true, stm, 0, true, attributesDict, cNullObj, s);
  564.     cStmDictObj = CosStreamDict(cStmObj);
  565.     
  566.     CosDictPut(cStmDictObj, ASAtomFromString("Type"), CosNewName(cdoc, false, ASAtomFromString("XObject")));
  567.     
  568.     CosDictPut(cStmDictObj, ASAtomFromString("Subtype"), CosNewName(cdoc, false, ASAtomFromString("Form")));
  569.     
  570.     CosDictPut(cStmDictObj, ASAtomFromString("FormType"), CosNewInteger(cdoc, false, 1L));
  571.     
  572.     cBBoxObj = CosNewArray(cdoc, false, 4L);
  573.     CosArrayInsert(cBBoxObj, 0L, CosNewInteger(cdoc, false, 0L));
  574.     CosArrayInsert(cBBoxObj, 1L, CosNewInteger(cdoc, false, 0L));
  575.     CosArrayInsert(cBBoxObj, 2L, CosNewInteger(cdoc, false, 100L));
  576.     CosArrayInsert(cBBoxObj, 3L, CosNewInteger(cdoc, false, 100L));
  577.     CosDictPut(cStmDictObj, ASAtomFromString("BBox"), cBBoxObj);
  578.  
  579.   /* Create Resource dictionary for XObject */
  580.   cResObj = CosNewDict(cdoc, false, 5L);
  581.  
  582.   /* Add Font resource to Resources dictionary */
  583.   fontResObj = CosNewDict(cdoc, true, 1L);
  584.   fontResObj2 = CosNewDict(cdoc, true, 5L);
  585.   cObj = CosNewName(cdoc, false, ASAtomFromString("Font"));
  586.   CosDictPut(fontResObj2, ASAtomFromString("Type"), cObj);
  587.   cObj = CosNewName(cdoc, false, ASAtomFromString("Type1"));
  588.   CosDictPut(fontResObj2, ASAtomFromString("Subtype"), cObj);
  589.   cObj = CosNewName(cdoc, false, ASAtomFromString("STAMPR"));
  590.   CosDictPut(fontResObj2, ASAtomFromString("Name"), cObj);
  591.   cObj = CosNewName(cdoc, false, ASAtomFromString("Helvetica"));
  592.   CosDictPut(fontResObj2, ASAtomFromString("BaseFont"), cObj);
  593.   CosDictPut(fontResObj, ASAtomFromString("STAMPR"), fontResObj2);
  594.   CosDictPut(cResObj, ASAtomFromString("Font"), fontResObj);
  595.   
  596.     /* Set up ProcSet Resources */
  597.     cProcSetObj = CosNewArray(cdoc, false, 2L);
  598.     CosArrayPut(cProcSetObj, 0L, CosNewName(cdoc, false, ASAtomFromString("PDF")));
  599.     CosArrayPut(cProcSetObj, 1L, CosNewName(cdoc, false, ASAtomFromString("Text")));
  600.     CosDictPut(cResObj, ASAtomFromString("ProcSet"), cProcSetObj);
  601.     
  602.     /* Put Resources dictionary in XObject's stream dictionary. */
  603.     CosDictPut(cStmDictObj, ASAtomFromString("Resources"), cResObj);
  604.  
  605. /*
  606. ** Set the stream object (now a Forms XObject) as the normal (N) key and add to the appearance (AP)
  607. ** key
  608. */
  609.     CosDictPut(cAPDictObj, FaceNormal_K, cStmObj);
  610.     CosDictPut(cAnnotObj, Appearance_K, cAPDictObj);
  611.     
  612. HANDLER
  613.     AVAlertNote(ASGetErrorString(ERRORCODE, buf, sizeof(buf)));
  614. END_HANDLER
  615.     
  616.     //StampSound();
  617.     
  618.     return true;
  619. }
  620.