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 >
Wrap
Text File
|
1995-06-24
|
14KB
|
587 lines
#include <A4Stuff.h>
#ifndef powerc
#pragma pointers_in_D0
#endif
#include <QDOffscreen.h>
#include <math types.h>
#include <math routines.h>
#include <graphics types.h>
#include <graphics routines.h>
#include <layout types.h>
#include <layout routines.h>
#include <layout feature constants.h>
#include "PIAbout.h"
#include "PIAcquire.h"
#include "PIExport.h"
#include "PIFilter.h"
#include "PIFormat.h"
#include "PIGeneral.h"
#include "PIProperties.h"
#include "PITypes.h"
#ifndef powerc
#pragma pointers_in_A0
#endif
#include <layout library.h>
#include <offscreen library.h>
#include <qd library.h>
#include <DialogUtilities.h>
#include <Menus.h>
#include <Dialogs.h>
#include <Controls.h>
/*****************************************************************************/
static void DoAbout();
static void DoParameters(FilterRecord* filter);
static void DoPrepare(FilterRecord* filter);
static void DoStart(FilterRecord* filter);
static void DoContinue();
static void DoFinish();
/*****************************************************************************/
typedef struct TParameters {
Str255 text;
long font;
long size;
Boolean doLigs;
Boolean antiAlias;
} TParameters, *PParameters, **HParameters;
/*****************************************************************************/
// Send this to Mike Neil
// mackid@apple.com
#define require(expression, label) \
if (expression) ; else if (1) { \
DebugStr("\pException: " #label); \
goto private_ ## label; \
resume_ ## label: ; \
} else while (1) if (1) goto label; else private_ ## label:
#define resume(label) do { goto resume_ ## label; } while (0)
/*****************************************************************************/
pascal void main(short selector, FilterRecord* filter, long* data, short* result) {
long oldA4 = SetCurrentA4(); // A4 must be set up for globals, strings, and
// inter-segment calls
OSErr error = noErr;
switch (selector) {
case filterSelectorAbout:
DoAbout();
break;
case filterSelectorParameters:
DoParameters(filter);
break;
case filterSelectorPrepare:
DoPrepare(filter);
break;
case filterSelectorStart:
DoStart(filter);
break;
case filterSelectorContinue:
DoContinue();
break;
case filterSelectorFinish:
DoFinish();
break;
default:
error = filterBadParameters;
}
*result = error;
SetA4(oldA4); // reset A4 before leaving XCMD
}
/*****************************************************************************/
void DoAbout() {
SysBeep(10);
}
/*****************************************************************************/
void DoParameters(FilterRecord* filter) {
#define dialogID 128
#define kFontMenuID 1000
enum {
doLigsItemID = 5,
antiAliasItemID = 6,
textItemID = 7,
fontItemID = 8,
sizeItemID = 9
};
OSErr error = noErr;
short item;
DialogPtr dp;
DialogTHndl dt;
short itemType;
Handle textItem;
Handle fontItem;
Handle sizeItem;
Rect box;
Str255 text;
long size;
if (!filter->parameters) {
filter->parameters = NewHandle(sizeof(TParameters));
require(filter->parameters, NewHandle) error = memFullErr;
}
dt = (DialogTHndl) GetResource ('DLOG', dialogID);
HNoPurge((Handle) dt);
dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
(void) SetDialogDefaultItem (dp, ok);
(void) SetDialogCancelItem (dp, cancel);
(void) SetDialogTracksCursor (dp, TRUE);
StuffNumber(dp, sizeItemID, 48);
SetArrowCursor();
do {
item = 0;
MoveableModalDialog (dp, filter->processEvent, nil, &item);
if (item == doLigsItemID) {
(void) ToggleCheckBoxState(dp, doLigsItemID);
}
else if (item == antiAliasItemID) {
(void) ToggleCheckBoxState(dp, antiAliasItemID);
}
} while (item != ok && item != cancel);
GetDialogItem(dp, sizeItemID, &itemType, &sizeItem, &box);
GetDialogItemText(sizeItem, text);
StringToNum(text, &size);
(*HParameters(filter->parameters))->size = size;
GetDialogItem(dp, fontItemID, &itemType, &fontItem, &box);
SInt16 menuItem = GetControlValue(ControlRef(fontItem));
MenuRef fontMenu = GetMenu(kFontMenuID);
GetMenuItemText(fontMenu, menuItem, text);
short font;
GetFNum(text, &font);
(*HParameters(filter->parameters))->font = font;
GetDialogItem(dp, textItemID, &itemType, &textItem, &box);
GetDialogItemText(textItem, text);
for (int i = 0; i < 256; ++i) {
(*HParameters(filter->parameters))->text[i] = text[i];
}
(*HParameters(filter->parameters))->doLigs = GetCheckBoxState(dp, doLigsItemID);
(*HParameters(filter->parameters))->antiAlias = GetCheckBoxState(dp, antiAliasItemID);
DisposeDialog (dp);
HPurge((Handle) dt);
if (item == cancel) {
return;
}
#undef dialogID
#undef hookItem
#undef percentItem
NewHandle:
;
}
/*****************************************************************************/
void DoPrepare(FilterRecord* filter) {
filter->bufferSpace = 1024 * 1024;
}
/*****************************************************************************/
void DoFilterRect(FilterRecord* filter) {
short count;
short plane;
unsigned8 *srcPtr = (unsigned8 *) filter->inData;
unsigned8 *dstPtr = (unsigned8 *) filter->outData;
count = filter->filterRect.right - filter->filterRect.left;
while (--count >= 0) {
if (count & 7)
for (plane = 0; plane < filter->planes; ++plane)
dstPtr [plane] = srcPtr [plane];
else
for (plane = 0; plane < filter->planes; ++plane)
dstPtr [plane] = 0x00;
srcPtr += filter->inHiPlane - filter->inLoPlane + 1;
dstPtr += filter->planes;
}
}
/*****************************************************************************/
void DoBlitOffscreen(FilterRecord* filter, PixMapHandle pixMap, short row) {
unsigned8* dstPtr = (unsigned8*)filter->outData;
// unsigned8* dstPtr = (unsigned8*)filter->outData + filter->outRowBytes * row;
int rowBytes = (*pixMap)->rowBytes & 0x3FFF;
unsigned16* srcPtr = (unsigned16*)(GetPixBaseAddr(pixMap) + ((row << 4) * rowBytes));
int bits;
unsigned16* columnPtr;
Boolean antiAlias = (*HParameters(filter->parameters))->antiAlias;
for (int count = filter->filterRect.right - filter->filterRect.left; count > 0; --count) {
bits = 0;
columnPtr = srcPtr++;
for (int rowCount = 16; rowCount > 0; --rowCount) {
for (int word = *columnPtr; word; word &= word - 1) ++bits;
columnPtr = (unsigned16*)(((unsigned8*)columnPtr) + rowBytes);
}
unsigned16 planeValue;
if (antiAlias) {
planeValue = (bits > 127) ? bits - 1 : bits;
} else {
planeValue = (bits > 127) ? 255 : 0;
}
for (short plane = 0; plane < filter->planes; ++plane) {
dstPtr[plane] = planeValue;
}
dstPtr += filter->planes;
}
}
/*****************************************************************************/
static void ClearBytes(void *block, register long length)
{
register char *b = (char *) block;
do
*b++ = 0x00;
while (--length);
}
/*****************************************************************************/
void DoStart(FilterRecord* filter) {
OSErr error = noErr;
BufferProcs* bufferProcs = filter->bufferProcs;
require(filter->advanceState, AdvanceStateAvailable);
require(bufferProcs, BufferProcsAvailable);
BufferID buffer;
const Size bufferSize = 1024 * 1024;
error = bufferProcs->allocateProc(bufferSize, &buffer);
require(error == noErr, AllocateProc);
Ptr bufferPtr = bufferProcs->lockProc(buffer, true);
gxGraphicsClient currentClient = GXGetGraphicsClient();
gxGraphicsClient client = GXNewGraphicsClient(bufferPtr, bufferSize, gxStaticHeapClient);
require(client, GXNewGraphicsClient) error = memFullErr;
GXEnterGraphics();
int32 total = filter->filterRect.bottom - filter->filterRect.top;
filter->inLoPlane = filter->outLoPlane = 0;
filter->inHiPlane = filter->outHiPlane = filter->planes - 1;
filter->inRect.left = filter->outRect.left = filter->filterRect.left;
filter->inRect.right = filter->outRect.right = filter->filterRect.right;
Rect largeRect = {
0,
0,
(filter->filterRect.bottom - filter->filterRect.top) << 4,
(filter->filterRect.right - filter->filterRect.left) << 4
};
Rect alignedRect = {
0,
0,
(largeRect.bottom + 0x001F) & 0xFFE0,
(largeRect.right + 0x001F) & 0xFFE0
};
GWorldPtr largeWorld;
CTabHandle blackWhiteColors = GetCTable(33);
gxColorSet colorSet = CTableToColorSet(blackWhiteColors);
error = NewGWorld(&largeWorld, 1, &alignedRect, blackWhiteColors, nil, keepLocal);
require(error == noErr, NewGWorld);
CGrafPtr currentPort;
GDHandle currentDevice;
GetGWorld(¤tPort, ¤tDevice);
SetGWorld(largeWorld, nil);
PixMapHandle pixMap = GetGWorldPixMap(largeWorld);
require(LockPixels(pixMap), LockPixels);
gxBitmap bitmap = {
GetPixBaseAddr(pixMap),
alignedRect.right,
alignedRect.bottom,
(*pixMap)->rowBytes & 0x3FFF,
1,
gxGraySpace,
nil,
nil
};
ClearBytes(bitmap.image, alignedRect.bottom * bitmap.rowBytes);
const gxPoint zeroPoint = { 0, 0 };
gxShape bitmapShape = GXNewBitmap(&bitmap, &zeroPoint);
offscreen gxWorld;
CreateOffscreen(&gxWorld, bitmapShape);
gxRectangle rectangle = {
0, 0 ,
IntToFixed(largeRect.right), IntToFixed(largeRect.bottom)
};
gxShape rectangleShape = GXNewRectangle(&rectangle);
if (GXGetGraphicsError(nil)) Debugger();
GXSetShapeTransform(rectangleShape, gxWorld.xform);
if (GXGetGraphicsError(nil)) Debugger();
gxColor white = { gxGraySpace, nil, 0xFFFF };
GXSetShapeColor(rectangleShape, &white);
if (GXGetGraphicsError(nil)) Debugger();
GXSetShapeFill(rectangleShape, gxSolidFill);
if (GXGetGraphicsError(nil)) Debugger();
GXDrawShape(rectangleShape);
if (GXGetGraphicsError(nil)) Debugger();
const int kTotalNumOfRunFeatures = 2;
const int kTotalNumOfPieces = 1;
Str255 sampleText;
short font;
for (int i = 0; i < 256; ++i) {
sampleText[i] = (*HParameters(filter->parameters))->text[i];
}
font = (*HParameters(filter->parameters))->font;
long size = (*HParameters(filter->parameters))->size;
gxPoint layoutPosition = { ff(size) << 4, ff(size) << 4 };
gxRunControls runControls;
gxRunFeature layoutFeatures[kTotalNumOfRunFeatures];
gxStyle layoutStyles[kTotalNumOfPieces];
gxShape tempLayoutShape;
short totalLengthOfLayout;
short lengthsArray[kTotalNumOfPieces];
short loop;
Boolean doLigs = (*HParameters(filter->parameters))->doLigs;
InitializeRunControls(&runControls);
layoutStyles[0] = NewLayoutStyle(font, 0, ff(size) << 4, 0, &runControls,
nil, 0, nil);
if (doLigs) {
layoutFeatures[0].featureType = ligaturesType;
layoutFeatures[0].featureSelector = ligatureRareOnSelector;
layoutFeatures[1].featureType = characterAlternativesType;
layoutFeatures[1].featureSelector = 1;
GXSetStyleRunFeatures(layoutStyles[0], kTotalNumOfRunFeatures, layoutFeatures);
}
lengthsArray[0] = sampleText[0];
totalLengthOfLayout = sampleText[0];
void* textPtr = &sampleText[1];
tempLayoutShape = GXNewLayout(1, &totalLengthOfLayout, &textPtr, 1,
lengthsArray, layoutStyles, 0, nil, nil, nil, &layoutPosition);
for (loop = 0; loop < kTotalNumOfPieces; loop++)
GXDisposeStyle(layoutStyles[loop]);
GXSetShapeTransform(tempLayoutShape, gxWorld.xform);
gxColor black = { gxGraySpace, nil, 0 };
GXSetShapeColor(tempLayoutShape, &black);
GXDrawShape(tempLayoutShape);
#if 0
gxLine line = {
{ 0, 0 },
{ IntToFixed(largeRect.right), IntToFixed(largeRect.bottom) }
};
gxShape lineShape = GXNewLine(&line);
if (GXGetGraphicsError(nil)) Debugger();
GXSetShapeTransform(lineShape, gxWorld.xform);
if (GXGetGraphicsError(nil)) Debugger();
gxColor black = { gxGraySpace, nil, 0 };
GXSetShapeColor(lineShape, &black);
if (GXGetGraphicsError(nil)) Debugger();
GXSetShapeFill(lineShape, gxFrameFill);
if (GXGetGraphicsError(nil)) Debugger();
GXSetShapePen(lineShape, ff(64));
if (GXGetGraphicsError(nil)) Debugger();
GXDrawShape(lineShape);
if (GXGetGraphicsError(nil)) Debugger();
#endif
DisposeOffscreen(&gxWorld);
SetGWorld(currentPort, currentDevice);
#if 0
const int kNumRows = 16;
int lastRow = filter->filterRect.top;
for (int row = lastRow; row < filter->filterRect.bottom; ) {
lastRow += kNumRows;
lastRow = (lastRow > filter->filterRect.bottom) ? filter->filterRect.bottom : lastRow;
filter->progressProc(row - filter->filterRect.top, total);
require(!filter->abortProc(), Abort);
filter->inRect.top = filter->outRect.top = row;
filter->inRect.bottom = filter->outRect.bottom = lastRow;
error = filter->advanceState();
require(error == noErr, AdvanceState);
while (row < lastRow) {
DoBlitOffscreen(filter, pixMap, row - filter->filterRect.top);
++row;
}
}
#else
for (int row = filter->filterRect.top; row < filter->filterRect.bottom; ++row) {
filter->progressProc(row - filter->filterRect.top, total);
require(!filter->abortProc(), Abort);
filter->inRect.top = filter->outRect.top = row;
filter->inRect.bottom = filter->outRect.bottom = row + 1;
error = filter->advanceState();
require(error == noErr, AdvanceState);
DoBlitOffscreen(filter, pixMap, row - filter->filterRect.top);
}
#endif
AdvanceState:
Abort:
LockPixels:
SetGWorld(currentPort, currentDevice);
// Make sure grayColors is gone
DisposeGWorld(largeWorld);
NewGWorld:
GXExitGraphics();
GXDisposeGraphicsClient(client);
if (currentClient) GXSetGraphicsClient(currentClient);
GXNewGraphicsClient:
bufferProcs->freeProc(buffer);
AllocateProc:
BufferProcsAvailable:
AdvanceStateAvailable:
SetRect(&filter->inRect, 0, 0, 0, 0);
SetRect(&filter->outRect, 0, 0, 0, 0);
}
/*****************************************************************************/
void DoContinue() {
SysBeep(10);
}
/*****************************************************************************/
void DoFinish() {
SysBeep(10);
}