home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks95 / Closure.sit / Closure / Sources / Closure.cp next >
Text File  |  1995-06-24  |  14KB  |  587 lines

  1.  
  2. #include <A4Stuff.h>
  3.  
  4. #ifndef powerc
  5.  #pragma pointers_in_D0                            
  6. #endif
  7.  
  8. #include <QDOffscreen.h>
  9. #include <math types.h>
  10. #include <math routines.h>
  11. #include <graphics types.h>
  12. #include <graphics routines.h>
  13. #include <layout types.h>
  14. #include <layout routines.h>
  15. #include <layout feature constants.h>
  16.  
  17. #include "PIAbout.h"
  18. #include "PIAcquire.h"
  19. #include "PIExport.h"
  20. #include "PIFilter.h"
  21. #include "PIFormat.h"
  22. #include "PIGeneral.h"
  23. #include "PIProperties.h"
  24. #include "PITypes.h"
  25.  
  26. #ifndef powerc
  27.  #pragma pointers_in_A0
  28. #endif
  29.  
  30. #include <layout library.h>
  31. #include <offscreen library.h>
  32. #include <qd library.h>
  33. #include <DialogUtilities.h>
  34.  
  35. #include <Menus.h>
  36. #include <Dialogs.h>
  37. #include <Controls.h>
  38.  
  39. /*****************************************************************************/
  40.  
  41. static void DoAbout();
  42. static void DoParameters(FilterRecord* filter);
  43. static void DoPrepare(FilterRecord* filter);
  44. static void DoStart(FilterRecord* filter);
  45. static void DoContinue();
  46. static void DoFinish();
  47.  
  48. /*****************************************************************************/
  49.  
  50. typedef struct TParameters {
  51.     Str255    text;
  52.     long    font;
  53.     long    size;
  54.     Boolean    doLigs;
  55.     Boolean    antiAlias;
  56. } TParameters, *PParameters, **HParameters;
  57.  
  58. /*****************************************************************************/
  59.  
  60. // Send this to Mike Neil
  61. // mackid@apple.com
  62.  
  63. #define require(expression, label)        \
  64.     if (expression) ; else if (1) {        \
  65.         DebugStr("\pException: " #label);    \
  66.         goto private_ ## label;            \
  67.         resume_ ## label: ;                \
  68.     } else while (1) if (1) goto label; else private_ ## label:
  69.  
  70. #define resume(label) do { goto resume_ ## label; } while (0)
  71.  
  72. /*****************************************************************************/
  73.  
  74. pascal void main(short selector, FilterRecord* filter, long* data, short* result) {
  75.  
  76.     long    oldA4 = SetCurrentA4();    // A4 must be set up for globals, strings, and 
  77.                                     // inter-segment calls 
  78.     
  79.     OSErr error = noErr;
  80.                                     
  81.     switch (selector) {
  82.     
  83.     case filterSelectorAbout:
  84.         DoAbout();
  85.         break;
  86.     case filterSelectorParameters:
  87.         DoParameters(filter);
  88.         break;
  89.     case filterSelectorPrepare:
  90.         DoPrepare(filter);
  91.         break;
  92.     case filterSelectorStart:
  93.         DoStart(filter);
  94.         break;
  95.     case filterSelectorContinue:
  96.         DoContinue();
  97.         break;
  98.     case filterSelectorFinish:
  99.         DoFinish();
  100.         break;
  101.     default:
  102.         error = filterBadParameters;
  103.     
  104.     }
  105.     
  106.     *result = error;
  107.     
  108.     SetA4(oldA4);                    // reset A4 before leaving XCMD
  109. }
  110.  
  111. /*****************************************************************************/
  112.  
  113. void DoAbout() {
  114.     SysBeep(10);
  115. }
  116.  
  117. /*****************************************************************************/
  118.  
  119. void DoParameters(FilterRecord* filter) {
  120.  
  121.     #define dialogID    128
  122.     #define kFontMenuID    1000
  123.  
  124.     enum {
  125.         doLigsItemID     = 5,
  126.         antiAliasItemID = 6,
  127.         textItemID         = 7,
  128.         fontItemID         = 8,
  129.         sizeItemID         = 9
  130.     };
  131.         
  132.     OSErr error = noErr;
  133.     
  134.     short item;
  135.     DialogPtr dp;
  136.     DialogTHndl dt;
  137.     
  138.     short    itemType;
  139.     Handle    textItem;
  140.     Handle    fontItem;
  141.     Handle    sizeItem;
  142.     Rect    box;
  143.     Str255    text;
  144.     long    size;
  145.  
  146.     if (!filter->parameters) {
  147.  
  148.         filter->parameters = NewHandle(sizeof(TParameters));
  149.         
  150.         require(filter->parameters, NewHandle) error = memFullErr;
  151.  
  152.     }
  153.  
  154.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  155.     HNoPurge((Handle) dt);
  156.  
  157.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  158.  
  159.     (void) SetDialogDefaultItem (dp, ok);
  160.     (void) SetDialogCancelItem (dp, cancel);
  161.     (void) SetDialogTracksCursor (dp, TRUE);
  162.     
  163.     StuffNumber(dp, sizeItemID, 48);
  164.         
  165.     SetArrowCursor();
  166.  
  167.     do {
  168.         item = 0;
  169.         
  170.         MoveableModalDialog (dp, filter->processEvent, nil, &item);
  171.         
  172.         if (item == doLigsItemID) {
  173.             (void) ToggleCheckBoxState(dp, doLigsItemID);
  174.         }
  175.         else if (item == antiAliasItemID) {
  176.             (void) ToggleCheckBoxState(dp, antiAliasItemID);
  177.         }
  178.     } while (item != ok && item != cancel);
  179.     
  180.     GetDialogItem(dp, sizeItemID, &itemType, &sizeItem, &box);
  181.     GetDialogItemText(sizeItem, text);
  182.     StringToNum(text, &size);
  183.     
  184.     (*HParameters(filter->parameters))->size = size;
  185.     
  186.     GetDialogItem(dp, fontItemID, &itemType, &fontItem, &box);
  187.     SInt16 menuItem = GetControlValue(ControlRef(fontItem));
  188.     
  189.     MenuRef fontMenu = GetMenu(kFontMenuID);
  190.     GetMenuItemText(fontMenu, menuItem, text);
  191.     
  192.     short font;
  193.     GetFNum(text, &font);
  194.     
  195.     (*HParameters(filter->parameters))->font = font;
  196.     
  197.     GetDialogItem(dp, textItemID, &itemType, &textItem, &box);
  198.     GetDialogItemText(textItem, text);
  199.     
  200.     for (int i = 0; i < 256; ++i) {
  201.         (*HParameters(filter->parameters))->text[i] = text[i];
  202.     }    
  203.  
  204.     (*HParameters(filter->parameters))->doLigs = GetCheckBoxState(dp, doLigsItemID);
  205.     (*HParameters(filter->parameters))->antiAlias = GetCheckBoxState(dp, antiAliasItemID);
  206.  
  207.     DisposeDialog (dp);
  208.     HPurge((Handle) dt);
  209.  
  210.     if (item == cancel) {
  211.         return;
  212.     }
  213.  
  214.     #undef dialogID
  215.     #undef hookItem
  216.     #undef percentItem
  217.  
  218. NewHandle:
  219.     ;
  220.     
  221. }
  222.  
  223. /*****************************************************************************/
  224.  
  225. void DoPrepare(FilterRecord* filter) {
  226.     filter->bufferSpace = 1024 * 1024;
  227. }
  228.  
  229. /*****************************************************************************/
  230.  
  231. void DoFilterRect(FilterRecord* filter) {
  232.  
  233.     short count;
  234.     short plane;
  235.     unsigned8 *srcPtr = (unsigned8 *) filter->inData;
  236.     unsigned8 *dstPtr = (unsigned8 *) filter->outData;
  237.         
  238.     count = filter->filterRect.right - filter->filterRect.left;
  239.     
  240.     while (--count >= 0) {
  241.                 
  242.         if (count & 7)
  243.             for (plane = 0; plane < filter->planes; ++plane)
  244.                 dstPtr [plane] = srcPtr [plane];
  245.         else        
  246.             for (plane = 0; plane < filter->planes; ++plane)
  247.                 dstPtr [plane] = 0x00;
  248.                                 
  249.         srcPtr += filter->inHiPlane - filter->inLoPlane + 1;
  250.         dstPtr += filter->planes;
  251.  
  252.     }
  253.  
  254. }
  255.  
  256. /*****************************************************************************/
  257.  
  258. void DoBlitOffscreen(FilterRecord* filter, PixMapHandle pixMap, short row) {
  259.  
  260.     unsigned8*    dstPtr        = (unsigned8*)filter->outData;
  261.     // unsigned8*    dstPtr        = (unsigned8*)filter->outData + filter->outRowBytes * row;
  262.  
  263.     int            rowBytes    = (*pixMap)->rowBytes & 0x3FFF;
  264.     
  265.     unsigned16*    srcPtr        = (unsigned16*)(GetPixBaseAddr(pixMap) + ((row << 4) * rowBytes));
  266.         
  267.     int            bits;
  268.     unsigned16*    columnPtr;
  269.     Boolean        antiAlias    = (*HParameters(filter->parameters))->antiAlias;
  270.     
  271.     
  272.     for (int count = filter->filterRect.right - filter->filterRect.left; count > 0; --count) {
  273.         bits = 0;
  274.         
  275.         columnPtr = srcPtr++;
  276.         
  277.         for (int rowCount = 16; rowCount > 0; --rowCount) {
  278.             
  279.             for (int word = *columnPtr; word; word &= word - 1) ++bits;
  280.             
  281.             columnPtr = (unsigned16*)(((unsigned8*)columnPtr) + rowBytes);
  282.         }
  283.         
  284.         unsigned16 planeValue;
  285.         
  286.         if (antiAlias) {
  287.             planeValue = (bits > 127) ? bits - 1 : bits;
  288.         } else {
  289.             planeValue = (bits > 127) ? 255 : 0;
  290.         }
  291.         
  292.         for (short plane = 0; plane < filter->planes; ++plane) {
  293.             dstPtr[plane] = planeValue;
  294.         }
  295.         
  296.         dstPtr += filter->planes;
  297.     }
  298. }
  299.  
  300. /*****************************************************************************/
  301.  
  302. static void ClearBytes(void *block, register long length)
  303. {
  304.     register char *b = (char *) block;
  305.     
  306.     do
  307.         *b++ = 0x00;
  308.     while (--length);
  309. }
  310.  
  311. /*****************************************************************************/
  312.  
  313. void DoStart(FilterRecord* filter) {
  314.  
  315.     OSErr error = noErr;
  316.     
  317.     BufferProcs* bufferProcs = filter->bufferProcs;
  318.     
  319.     require(filter->advanceState, AdvanceStateAvailable);
  320.     require(bufferProcs, BufferProcsAvailable);
  321.         
  322.     BufferID buffer;
  323.     const Size bufferSize = 1024 * 1024;
  324.     
  325.     error = bufferProcs->allocateProc(bufferSize, &buffer);
  326.     require(error == noErr, AllocateProc);
  327.     
  328.     Ptr bufferPtr = bufferProcs->lockProc(buffer, true);
  329.     
  330.     gxGraphicsClient currentClient = GXGetGraphicsClient();
  331.     
  332.     gxGraphicsClient client = GXNewGraphicsClient(bufferPtr, bufferSize, gxStaticHeapClient);
  333.     require(client, GXNewGraphicsClient) error = memFullErr;
  334.     
  335.     GXEnterGraphics();
  336.     
  337.     int32 total = filter->filterRect.bottom - filter->filterRect.top;
  338.                 
  339.     filter->inLoPlane = filter->outLoPlane = 0;
  340.     filter->inHiPlane = filter->outHiPlane = filter->planes - 1;
  341.     
  342.     filter->inRect.left = filter->outRect.left = filter->filterRect.left;
  343.     filter->inRect.right = filter->outRect.right = filter->filterRect.right;
  344.     
  345.     Rect largeRect = {
  346.         0,
  347.         0,
  348.         (filter->filterRect.bottom - filter->filterRect.top) << 4,
  349.         (filter->filterRect.right - filter->filterRect.left) << 4
  350.     };
  351.     
  352.     Rect alignedRect = {
  353.         0,
  354.         0,
  355.         (largeRect.bottom + 0x001F) & 0xFFE0,
  356.         (largeRect.right + 0x001F) & 0xFFE0
  357.     };
  358.     
  359.     GWorldPtr largeWorld;
  360.     
  361.     CTabHandle blackWhiteColors = GetCTable(33);
  362.     
  363.     gxColorSet colorSet = CTableToColorSet(blackWhiteColors);
  364.     
  365.     error = NewGWorld(&largeWorld, 1, &alignedRect, blackWhiteColors, nil, keepLocal);
  366.     require(error == noErr, NewGWorld);
  367.     
  368.     CGrafPtr currentPort;
  369.     GDHandle currentDevice;
  370.  
  371.     GetGWorld(¤tPort, ¤tDevice);
  372.     SetGWorld(largeWorld, nil);
  373.         
  374.     PixMapHandle pixMap = GetGWorldPixMap(largeWorld);
  375.     require(LockPixels(pixMap), LockPixels);
  376.     
  377.     gxBitmap bitmap = {
  378.         GetPixBaseAddr(pixMap),
  379.         alignedRect.right,
  380.         alignedRect.bottom,
  381.         (*pixMap)->rowBytes & 0x3FFF,
  382.         1,
  383.         gxGraySpace,
  384.         nil,
  385.         nil
  386.     };
  387.     
  388.     
  389.     ClearBytes(bitmap.image, alignedRect.bottom * bitmap.rowBytes);
  390.     
  391.     const gxPoint zeroPoint = { 0, 0 };
  392.     
  393.     gxShape bitmapShape = GXNewBitmap(&bitmap, &zeroPoint);
  394.     
  395.     offscreen gxWorld;
  396.     CreateOffscreen(&gxWorld, bitmapShape);
  397.     
  398.     gxRectangle rectangle = {
  399.         0, 0 ,
  400.         IntToFixed(largeRect.right), IntToFixed(largeRect.bottom)
  401.     };
  402.     
  403.     gxShape rectangleShape = GXNewRectangle(&rectangle);
  404.     if (GXGetGraphicsError(nil)) Debugger();
  405.     
  406.     GXSetShapeTransform(rectangleShape, gxWorld.xform);
  407.     if (GXGetGraphicsError(nil)) Debugger();
  408.     
  409.     gxColor white = { gxGraySpace, nil, 0xFFFF };
  410.     GXSetShapeColor(rectangleShape, &white);
  411.     if (GXGetGraphicsError(nil)) Debugger();
  412.     
  413.     GXSetShapeFill(rectangleShape, gxSolidFill);
  414.     if (GXGetGraphicsError(nil)) Debugger();
  415.     
  416.     GXDrawShape(rectangleShape);
  417.     if (GXGetGraphicsError(nil)) Debugger();
  418.     
  419.     const int kTotalNumOfRunFeatures = 2;
  420.     const int kTotalNumOfPieces = 1;
  421.     
  422.     Str255            sampleText;
  423.     short            font;
  424.     
  425.     for (int i = 0; i < 256; ++i) {
  426.         sampleText[i] = (*HParameters(filter->parameters))->text[i];
  427.     }
  428.     
  429.     font = (*HParameters(filter->parameters))->font;
  430.     
  431.     long size = (*HParameters(filter->parameters))->size;
  432.  
  433.     gxPoint            layoutPosition = { ff(size) << 4, ff(size) << 4 };
  434.     gxRunControls    runControls;
  435.     gxRunFeature    layoutFeatures[kTotalNumOfRunFeatures];
  436.     gxStyle            layoutStyles[kTotalNumOfPieces];
  437.     gxShape            tempLayoutShape;
  438.     short            totalLengthOfLayout;
  439.     short            lengthsArray[kTotalNumOfPieces];
  440.     short            loop;
  441.     Boolean            doLigs = (*HParameters(filter->parameters))->doLigs;
  442.     
  443.     InitializeRunControls(&runControls);
  444.     
  445.     layoutStyles[0] = NewLayoutStyle(font, 0, ff(size) << 4, 0, &runControls,
  446.         nil, 0, nil);
  447.     
  448.     
  449.     if (doLigs) {
  450.         layoutFeatures[0].featureType = ligaturesType;
  451.         layoutFeatures[0].featureSelector = ligatureRareOnSelector;
  452.         layoutFeatures[1].featureType = characterAlternativesType;
  453.         layoutFeatures[1].featureSelector = 1;
  454.         
  455.         GXSetStyleRunFeatures(layoutStyles[0], kTotalNumOfRunFeatures, layoutFeatures);
  456.     }
  457.     
  458.     lengthsArray[0] = sampleText[0];
  459.     totalLengthOfLayout = sampleText[0];
  460.     
  461.     void* textPtr =  &sampleText[1];
  462.     
  463.     tempLayoutShape = GXNewLayout(1, &totalLengthOfLayout, &textPtr, 1,
  464.         lengthsArray, layoutStyles, 0, nil, nil, nil, &layoutPosition);
  465.     
  466.     for (loop = 0; loop < kTotalNumOfPieces; loop++)
  467.         GXDisposeStyle(layoutStyles[loop]);
  468.     
  469.     GXSetShapeTransform(tempLayoutShape, gxWorld.xform);
  470.     
  471.     gxColor black = { gxGraySpace, nil, 0 };
  472.     GXSetShapeColor(tempLayoutShape, &black);
  473.     
  474.     GXDrawShape(tempLayoutShape);
  475.     
  476.     #if 0
  477.     
  478.     gxLine line = {
  479.         { 0, 0 },
  480.         { IntToFixed(largeRect.right), IntToFixed(largeRect.bottom) }
  481.     };
  482.     
  483.     gxShape lineShape = GXNewLine(&line);
  484.     if (GXGetGraphicsError(nil)) Debugger();
  485.     
  486.     GXSetShapeTransform(lineShape, gxWorld.xform);
  487.     if (GXGetGraphicsError(nil)) Debugger();
  488.     
  489.     gxColor black = { gxGraySpace, nil, 0 };
  490.     GXSetShapeColor(lineShape, &black);
  491.     if (GXGetGraphicsError(nil)) Debugger();
  492.     
  493.     GXSetShapeFill(lineShape, gxFrameFill);
  494.     if (GXGetGraphicsError(nil)) Debugger();
  495.     
  496.     GXSetShapePen(lineShape, ff(64));
  497.     if (GXGetGraphicsError(nil)) Debugger();
  498.     
  499.     GXDrawShape(lineShape);
  500.     if (GXGetGraphicsError(nil)) Debugger();
  501.     
  502.     #endif
  503.         
  504.     DisposeOffscreen(&gxWorld);
  505.         
  506.     SetGWorld(currentPort, currentDevice);
  507.     
  508.     #if 0
  509.     
  510.     const int kNumRows = 16;
  511.     
  512.     int lastRow = filter->filterRect.top;
  513.         
  514.     for (int row = lastRow; row < filter->filterRect.bottom; ) {
  515.     
  516.         lastRow += kNumRows;
  517.     
  518.         lastRow = (lastRow > filter->filterRect.bottom) ? filter->filterRect.bottom : lastRow;
  519.                 
  520.         filter->progressProc(row - filter->filterRect.top, total);
  521.         
  522.         require(!filter->abortProc(), Abort);
  523.                     
  524.         filter->inRect.top = filter->outRect.top = row;
  525.         filter->inRect.bottom = filter->outRect.bottom = lastRow;
  526.         
  527.         error = filter->advanceState();
  528.         require(error == noErr, AdvanceState);
  529.                         
  530.         while (row < lastRow) {
  531.             DoBlitOffscreen(filter, pixMap, row - filter->filterRect.top);
  532.             ++row;
  533.         }
  534.         
  535.     }
  536.     
  537.     #else
  538.     
  539.     for (int row = filter->filterRect.top; row < filter->filterRect.bottom; ++row) {
  540.     
  541.         filter->progressProc(row - filter->filterRect.top, total);
  542.         
  543.         require(!filter->abortProc(), Abort);
  544.                     
  545.         filter->inRect.top = filter->outRect.top = row;
  546.         filter->inRect.bottom = filter->outRect.bottom = row + 1;
  547.         
  548.         error = filter->advanceState();
  549.         require(error == noErr, AdvanceState);
  550.                         
  551.         DoBlitOffscreen(filter, pixMap, row - filter->filterRect.top);
  552.         
  553.     }
  554.     #endif
  555.     
  556. AdvanceState:
  557. Abort:
  558. LockPixels:
  559.     SetGWorld(currentPort, currentDevice);
  560.     // Make sure grayColors is gone
  561.     DisposeGWorld(largeWorld);
  562. NewGWorld:
  563.     GXExitGraphics();
  564.     GXDisposeGraphicsClient(client);
  565.     if (currentClient) GXSetGraphicsClient(currentClient);
  566. GXNewGraphicsClient:
  567.     bufferProcs->freeProc(buffer);
  568. AllocateProc:
  569. BufferProcsAvailable:
  570. AdvanceStateAvailable:
  571.     SetRect(&filter->inRect, 0, 0, 0, 0);
  572.     SetRect(&filter->outRect, 0, 0, 0, 0);
  573.  
  574. }
  575.  
  576. /*****************************************************************************/
  577.  
  578. void DoContinue() {
  579.     SysBeep(10);
  580. }
  581.  
  582. /*****************************************************************************/
  583.  
  584. void DoFinish() {
  585.     SysBeep(10);
  586. }
  587.