home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / gfx / misc / imagefx_sdk / sas / examples / xstyle / panto.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-15  |  13.2 KB  |  596 lines

  1. /*
  2.  * A Pantograph Enhanced Drawing Mode for ImageFX 2.0
  3.  *
  4.  */
  5.  
  6. #include <exec/types.h>
  7. #include <scan/modall.h>
  8. #include <scan/drawinfo.h>
  9. #include <string.h>
  10. #include "common.h"
  11.  
  12.  
  13. /**********************************************************************\
  14.  
  15.                              Static Variables
  16.  
  17. \**********************************************************************/
  18.  
  19. static struct Buffer *panto_buf = NULL;
  20. static LONG panto_mode = 0;
  21. static BOOL delta_not_set = TRUE;
  22.  
  23. /**********************************************************************\
  24.  
  25.                              Support Functions
  26.  
  27. \**********************************************************************/
  28.  
  29. void InitPantoDraw (void)
  30. {
  31.    struct Buffer *buf;
  32.    UBYTE *red, *grn, *blu, *pred, *pgrn, *pblu;
  33.    int j;
  34.  
  35.    buf = ScanBase->MainBuffer;
  36.    if (panto_buf = AllocBuffer(NULL, buf->Width, buf->Height, buf->Depth, 8, 0)) {
  37.       for (j = 0; j < buf->Height; j++) {
  38.          if (!GetBufLine(buf, &red, &grn, &blu, j)) break;
  39.          if (!GetBufLine(panto_buf, &pred, &pgrn, &pblu, j)) break;
  40.          memcpy(pred, red, buf->Width);
  41.          if (buf->Depth > 1) {
  42.             memcpy(pgrn, grn, buf->Width);
  43.             memcpy(pblu, blu, buf->Width);
  44.          }
  45.          if (!PutBufLine(panto_buf)) break;
  46.       }
  47.    }
  48. }
  49.  
  50. void CleanupPantoDraw (void)
  51. {
  52.    if (panto_buf) KillBuffer(panto_buf);
  53.    panto_buf = NULL;
  54. }
  55.  
  56.  
  57. static short oldx, oldy;
  58.  
  59. void MovePantograph (int x, int y)
  60. {
  61.    DrawBoxOnPreview2(oldx - 4, oldy - 4, oldx + 4, oldy + 4);
  62.    oldx = x;
  63.    oldy = y;
  64.    DrawBoxOnPreview2(oldx - 4, oldy - 4, oldx + 4, oldy + 4);
  65. }
  66.  
  67. void InitPantograph (int x, int y)
  68. {
  69.    oldx = x;
  70.    oldy = y;
  71.    DrawBoxOnPreview2(oldx - 4, oldy - 4, oldx + 4, oldy + 4);
  72. }
  73.  
  74. void CleanupPantograph (void)
  75. {
  76.    DrawBoxOnPreview2(oldx - 4, oldy - 4, oldx + 4, oldy + 4);
  77. }
  78.  
  79.  
  80. static short coldx = -1, coldy = -1;
  81.  
  82. void MovePantoCenter (void)
  83. {
  84.    DrawBoxOnPreview2(coldx - 3, coldy - 3, coldx + 3, coldy + 3);
  85.    coldx = ScanBase->sb_PantoCX;
  86.    coldy = ScanBase->sb_PantoCY;
  87.    DrawBoxOnPreview2(coldx - 3, coldy - 3, coldx + 3, coldy + 3);
  88. }
  89.  
  90. void InitPantoCenter (void)
  91. {
  92.    coldx = ScanBase->sb_PantoCX;
  93.    coldy = ScanBase->sb_PantoCY;
  94.    DrawBoxOnPreview2(coldx - 3, coldy - 3, coldx + 3, coldy + 3);
  95. }
  96.  
  97. void CleanupPantoCenter (void)
  98. {
  99.    if (coldx >= 0) {
  100.       DrawBoxOnPreview2(coldx - 3, coldy - 3, coldx + 3, coldy + 3);
  101.       coldx = -1;
  102.    }
  103. }
  104.  
  105. /**********************************************************************\
  106.  
  107.                                 Library Vectors
  108.  
  109. \**********************************************************************/
  110.  
  111. /*
  112.  * XDM_Attr:
  113.  *
  114.  * Return to ImageFX some information about the Drawing Style (eg.
  115.  * whether Options are needed, whether we work on greyscale or
  116.  * color, etc.).  Called when ImageFX first scans the drawing
  117.  * style directory.
  118.  *
  119.  */
  120. ULONG __saveds __asm XDS_Attr (register __a0 struct XDrawAttr *attr)
  121. {
  122.    attr->Flags = XDMF_AreOptions | XDMF_MouseTrap | XDMF_RedrawTrap;
  123.    attr->Priority = 122;
  124.    return(0);
  125. }
  126.  
  127. /*
  128.  * XDS_Begin:
  129.  *
  130.  * Prepare before a pixel affecting operation.
  131.  *
  132.  */
  133. int __saveds __asm XDS_Begin (register __a0 struct IDrawInfo *di)
  134. {
  135.    di->SPrivate = (APTR)ScanBase->MainBuffer;
  136.    InitPantoDraw();
  137.    return(1);
  138. }
  139.  
  140. /*
  141.  * XDS_End:
  142.  *
  143.  * Cleanup after a pixel affecting operation.
  144.  *
  145.  */
  146. void __saveds __asm XDS_End (register __a0 struct IDrawInfo *di)
  147. {
  148.    CleanupPantoDraw();
  149. }
  150.  
  151. /*
  152.  * XDS_Get:
  153.  *
  154.  *
  155.  */
  156. int __saveds __asm XDS_Get (register __a0 struct IDrawInfo *di)
  157. {
  158.    struct Buffer *buf;
  159.    UBYTE *sr, *sg, *sb;
  160.    UBYTE *dr, *dg, *db;
  161.    UBYTE *red, *grn, *blu;
  162.    int i, j;
  163.    int w, h;
  164.    int x, y;
  165.  
  166.    GetFromBuf((struct Buffer *)di->SPrivate, di);
  167.  
  168. #ifdef USE_BUFFERS
  169.  
  170.    /*
  171.     * Only copy if space has been allocated for us.  Some drawing
  172.     * modes may not require this information, so the buffers may
  173.     * not be allocated to save time & space.
  174.     */
  175.  
  176.    if (di->BPen)
  177.    {
  178.  
  179.       buf = (panto_buf) ? panto_buf : (struct Buffer *)di->SPrivate;
  180.       if (!buf) return(0);
  181.  
  182.       y = di->TE + ScanBase->sb_PantoDY;
  183.  
  184.       w = di->Width;
  185.       h = di->Height;
  186.  
  187.       for (j = 0; j < h; j++, y++)
  188.       {
  189.  
  190.          GetBufLine(di->BPen, &dr, &dg, &db, j);
  191.  
  192.          x = di->LE + ScanBase->sb_PantoDX;
  193.  
  194.          if ((y >= 0) && (y < buf->Height))
  195.          {
  196.             if (GetBufLine(buf, &red, &grn, &blu, y))
  197.             {
  198.                sr = red + x;
  199.                sg = grn + x;
  200.                sb = blu + x;
  201.                for (i = 0; i < w; i++, x++) {
  202.                   if ((x < 0) || (x >= buf->Width)) {
  203.                      dr[i] = dg[i] = db[i] = 0;
  204.                   }
  205.                   else {
  206.                      dr[i] = sr[i];
  207.                      dg[i] = sg[i];
  208.                      db[i] = sb[i];
  209.                   }
  210.                }
  211.             }
  212.          }
  213.          else
  214.          {
  215.             /* outside bounds of image is black */
  216.             memset(dr, 0, w);
  217.             memset(dg, 0, w);
  218.             memset(db, 0, w);
  219.          }
  220.  
  221.          PutBufLine(di->BPen);
  222.  
  223.       }
  224.  
  225.    }
  226.  
  227. #else
  228.  
  229.    /*
  230.     * Only copy if space has been allocated for us.  Some drawing
  231.     * modes may not require this information, so the buffers may
  232.     * not be allocated to save time & space.
  233.     */
  234.  
  235.    if (di->PenR && di->PenG && di->PenB)
  236.    {
  237.  
  238.       buf = (panto_buf) ? panto_buf : (struct Buffer *)di->SPrivate;
  239.       if (!buf) return(0);
  240.  
  241.       y = di->TE + ScanBase->sb_PantoDY;
  242.  
  243.       w = di->Width;
  244.       h = di->Height;
  245.  
  246.       dr = di->PenR;
  247.       dg = di->PenG;
  248.       db = di->PenB;
  249.  
  250.       for (j = 0; j < h; j++, y++)
  251.       {
  252.  
  253.          x = di->LE + ScanBase->sb_PantoDX;
  254.  
  255.          if ((y >= 0) && (y < buf->Height))
  256.          {
  257.             if (GetBufLine(buf, &red, &grn, &blu, y))
  258.             {
  259.                sr = red + x;
  260.                sg = grn + x;
  261.                sb = blu + x;
  262.                for (i = 0; i < w; i++, x++) {
  263.                   if ((x < 0) || (x >= buf->Width)) {
  264.                      dr[i] = dg[i] = db[i] = 0;
  265.                   }
  266.                   else {
  267.                      dr[i] = sr[i];
  268.                      dg[i] = sg[i];
  269.                      db[i] = sb[i];
  270.                   }
  271.                }
  272.             }
  273.          }
  274.          else
  275.          {
  276.             /* outside bounds of image is black */
  277.             memset(dr, 0, w);
  278.             memset(dg, 0, w);
  279.             memset(db, 0, w);
  280.          }
  281.  
  282.          dr += di->Width;
  283.          dg += di->Width;
  284.          db += di->Width;
  285.  
  286.       }
  287.  
  288.    }
  289.  
  290. #endif
  291.  
  292.    return(1);
  293. }
  294.  
  295. /*
  296.  * XDS_Put:
  297.  *
  298.  *
  299.  */
  300. int __saveds __asm XDS_Put (register __a0 struct IDrawInfo *di)
  301. {
  302.    struct Buffer *buf = (struct Buffer *)di->SPrivate;
  303.  
  304.    PutToBuf(buf, di);
  305.  
  306.    return(1);
  307. }
  308.  
  309. #include "panto_strings.h"
  310.  
  311. #define WID    300
  312. #define HT     58
  313.  
  314. enum {
  315.    ID_Okay = 2,
  316.    ID_Cancel,
  317.    ID_Mode,
  318. };
  319.  
  320. long mode;
  321. long ModeArray[] = { G_Mode1, G_Mode2, -1 };
  322.  
  323. struct NewGad newGads[] = {
  324.    { Scale_ID },
  325.  
  326.    { Button_ID,  ID_Okay,     8,HT-16,100,12, G_Okay, NULL,0, NULL, ID_Okay,0,0,0 },
  327.    { Button_ID,  ID_Cancel,   WID-100-8,HT-16,100,12, G_Cancel, NULL,0,NULL, ID_Cancel,0,0,0 },
  328.    { Cycle_ID,   ID_Mode,     80,20,(WID-16-80),12, G_Mode, NULL,0,&mode, (long)ModeArray,0,0,0 },
  329.  
  330.    { Text_ID,    0,           WID/2,4,0,0, L_Title, NULL,0,NULL, 2,0,2,0 },
  331.  
  332.    { Border_ID,  0,           0,0,WID,HT, 0, NULL,0,NULL, 0,1,0,0 },
  333.    { Border_ID,  0,           8,13,WID-16,HT-31, 0, NULL,0,NULL, 1,0,0,0 },
  334.  
  335.    { End_ID }
  336. };
  337.  
  338. struct NewWindow newWindow = {
  339.      0,0,WID,HT,
  340.      0,1,
  341.      GADGETDOWN|GADGETUP|VANILLAKEY,
  342.      BORDERLESS|ACTIVATE|NOCAREREFRESH|SMART_REFRESH|RMBTRAP,
  343.      NULL, /* FirstGadget - Filled later */
  344.      NULL,
  345.      NULL,
  346.      NULL,
  347.      NULL,
  348.      0,0,0,0,
  349.      WBENCHSCREEN
  350. };
  351.  
  352. /*
  353.  * XDS_Options:
  354.  *
  355.  * Present a window to the user allowing him to adjust drawing style
  356.  * options.  Arguments may optionally be passed from an Arexx command.
  357.  *
  358.  */
  359. int __saveds __asm XDS_Options (register __a0 LONG *args)
  360. {
  361.    int action;
  362.  
  363.    if (args)
  364.    {
  365.       CleanupPantoCenter();
  366.       if (args[0]) ScanBase->sb_PantoCX = atoi((char *)args[0]);
  367.       if (args[1]) ScanBase->sb_PantoCY = atoi((char *)args[1]);
  368.       if (args[2]) panto_mode = 0;
  369.       if (args[3]) panto_mode = 1;
  370.       InitPantoCenter();
  371.       return(0);
  372.    }
  373.  
  374.    newGads[ID_Mode-1].Data4 = panto_mode;
  375.  
  376.    PrepareNW(&newWindow, WID, HT, TRUE);
  377.  
  378.    action = GedWin(&newWindow, newGads, 0, NULL, NULL, ModuleBase->Text ? ModuleBase->Text : Default_Strings);
  379.    if (action == ID_Okay)
  380.    {
  381.       panto_mode = mode;
  382.       delta_not_set = TRUE;
  383.       Learn("DrawStyle ARGS %ls", panto_mode ? "Absolute" : "Relative");
  384.    }
  385.  
  386.    return(0);
  387. }
  388.  
  389. /*
  390.  * XDS_LoadPrefs:
  391.  *
  392.  * Set preferences according to information loaded from disk.
  393.  *
  394.  */
  395. int __saveds __asm XDS_LoadPrefs (register __a0 void *prefs)
  396. {
  397.    return(1);
  398. }
  399.  
  400. /*
  401.  * XDS_SavePrefs:
  402.  *
  403.  * Request preferences settings that are about to be saved to disk.
  404.  *
  405.  */
  406. int __saveds __asm XDS_SavePrefs (register __a0 void *prefs)
  407. {
  408.    return(1);
  409. }
  410.  
  411. /*
  412.  * XDS_HandleMButton:
  413.  *
  414.  * Handle a mousebutton event from the main window.
  415.  *
  416.  */
  417. int __saveds __asm XDS_HandleMButton (register __a0 struct IntuiMessage *msg)
  418. {
  419.    short px, py;
  420.    short x, y;
  421.  
  422.    if (msg->Code == SELECTDOWN)
  423.    {
  424.  
  425.       GetVCoords(msg, &x, &y);
  426.       if (msg->Qualifier & (IEQUALIFIER_LALT | IEQUALIFIER_RALT))
  427.       {
  428.          ScanBase->sb_PantoCX = x;
  429.          ScanBase->sb_PantoCY = y;
  430.          delta_not_set = TRUE;
  431.  
  432.          MovePantoCenter();
  433.          ScanBase->sb_NewFlags &= ~SBF_BUTTONDOWN;
  434.  
  435.          return(1);
  436.       }
  437.  
  438.       if (!(ScanBase->sb_NewFlags & SBF_BUTTONDOWN))
  439.       {
  440.          if (panto_mode == 0)
  441.          {
  442.             /* relative - reset delta each time we click */
  443.             ScanBase->sb_PantoDX = ScanBase->sb_PantoCX - x;
  444.             ScanBase->sb_PantoDY = ScanBase->sb_PantoCY - y;
  445.          }
  446.          else if (panto_mode == 1)
  447.          {
  448.             /* absolute - only set delta the FIRST time we click */
  449.             if (delta_not_set)
  450.             {
  451.                ScanBase->sb_PantoDX = ScanBase->sb_PantoCX - x;
  452.                ScanBase->sb_PantoDY = ScanBase->sb_PantoCY - y;
  453.                delta_not_set = FALSE;
  454.             }
  455.          }
  456.          px = x + ScanBase->sb_PantoDX;
  457.          py = y + ScanBase->sb_PantoDY;
  458.          InitPantograph(px, py);
  459.       }
  460.  
  461.    }
  462.    else if (msg->Code == SELECTUP)
  463.    {
  464.  
  465.       if (ScanBase->sb_NewFlags & SBF_BUTTONDOWN)
  466.       {
  467.          CleanupPantograph();
  468.       }
  469.  
  470.    }
  471.  
  472.    return(0);
  473. }
  474.  
  475. /*
  476.  * XDS_HandleMMove:
  477.  *
  478.  * Handle a mousemove event from the main window.
  479.  *
  480.  */
  481. int __saveds __asm XDS_HandleMMove (register __a0 struct IntuiMessage *msg)
  482. {
  483.    short px, py;
  484.    short x, y;
  485.  
  486.    if (ScanBase->sb_NewFlags & SBF_BUTTONDOWN)
  487.    {
  488.       GetVCoords (msg, &x, &y);
  489.       px = x + ScanBase->sb_PantoDX;
  490.       py = y + ScanBase->sb_PantoDY;
  491.       MovePantograph(px, py);
  492.    }
  493.  
  494.    return(0);
  495. }
  496.  
  497.  
  498. int __saveds __asm XDS_Init (void)
  499. {
  500.    if (!pWindow) return(0);
  501.    InitPantoCenter();
  502.    delta_not_set = TRUE;
  503.    return(1);
  504. }
  505.  
  506. void __saveds __asm XDS_Cleanup (void)
  507. {
  508.    CleanupPantoCenter();
  509. }
  510.  
  511. void __saveds __asm XDS_Redraw (register __d0 int left,
  512.                                 register __d1 int top,
  513.                                 register __d2 int right,
  514.                                 register __d3 int bottom)
  515. {
  516.    CleanupPantoCenter();
  517.    RedrawArea(left, top, right, bottom);
  518.    InitPantoCenter();
  519. }
  520.  
  521.  
  522. RXCMD RxCmd = { NULL, NULL, "CenterX/N,CenterY/N,Relative/S,Absolute/S" };
  523.  
  524.  
  525. /**********************************************************************\
  526.  
  527.                          Library Initialization Stuff
  528.  
  529. \**********************************************************************/
  530.  
  531. /*
  532.  * This is the table of all the functions that can be called in this
  533.  * module.  The first four (Open, Close, Expunge, and Null) are reserved
  534.  * for system use and MUST be specified in the order shown.  The actual
  535.  * functions are in the standard module startup code.
  536.  */
  537. ULONG FuncTable[] = {
  538.    /* These four MUST be present in this order */
  539.    (ULONG) LibOpen,
  540.    (ULONG) LibClose,
  541.    (ULONG) LibExpunge,
  542.    (ULONG) LibNull,
  543.  
  544.    /* Specific to the module */
  545.    (ULONG) XDS_Attr,
  546.    (ULONG) XDS_Begin,
  547.    (ULONG) XDS_End,
  548.    (ULONG) XDS_Get,
  549.    (ULONG) XDS_Put,
  550.    (ULONG) XDS_Options,
  551.    (ULONG) XDS_LoadPrefs,
  552.    (ULONG) XDS_SavePrefs,
  553.    (ULONG) XDS_HandleMButton,
  554.    (ULONG) XDS_HandleMMove,
  555.    (ULONG) XDS_Init,
  556.    (ULONG) XDS_Cleanup,
  557.    (ULONG) XDS_Redraw,
  558.  
  559.    /* End with -1L */
  560.    (ULONG) -1L
  561. };
  562.  
  563. /*
  564.  * These are used by the standard module startup code.
  565.  * LibraryName is the name of the library, and LibraryID is a short
  566.  * description of the library.  Both of these are largely irrelavent,
  567.  * but they are included just for completeness.
  568.  */
  569. UBYTE LibraryID[]    = "$VER: Pantograph Drawing Style 2.0.29 (15.2.95)";
  570. UBYTE LibraryType    = NT_XDRAWSTYLE;
  571.  
  572. /*
  573.  * This is called by the standard module startup code when Image Scan
  574.  * first opens the module.  Here we should fill in the NumGads,
  575.  * NewGad, Language, and LangCount fields of the provided ModuleBase
  576.  * structure if necessary.
  577.  */
  578. long  __asm UserOpen (register __a6 struct ModuleBase *modbase)
  579. {
  580.    modbase->Language = "Style_Pantograph";
  581.    modbase->LangCount = TXT_COUNT;
  582.    modbase->CmdTable = &RxCmd;
  583.    return(TRUE);
  584. }
  585.  
  586. /*
  587.  * This is called by the standard module startup code when Image Scan
  588.  * closes the module.  It should cleanup anything allocated or obtained
  589.  * in the UserOpen() function.
  590.  */
  591. long  __asm UserClose (register __a6 struct ModuleBase *modbase)
  592. {
  593.    return(TRUE);
  594. }
  595.  
  596.