/* PgColorX. */ /* PgColorX XCMD Drawer */ /* (c)ぷご 2003-2004 */ /* */ /* PugoStation */ /* http://hp.vector.co.jp/authors/VA019519/ */ #include #include #include #include //EqualString #include // PICT resource #include // GWorld #include // LMGetWindowList #include #include #include //tablet #include "pgx_base.h" #include "PgColorX.h" #include "PgWindowX.h" /* globals */ #if TARGET == REALbasic PCXDataPtr PCXData; #endif void CopyBits2(BitMap *src, BitMap *dst, Rect *sr, Rect *dr, int mode, RgnHandle rgn) { #pragma unused dst PCXDataPtr thePCXPtr = GetPCXPtr(NULL,true); //if(thePCXPtr) thePCXPtr->isMyDraw = true; //置き換えたstdbitsを使わないようにフラグを立てる StdBits(src, sr, dr, mode, rgn); //CopyBits(src, dst, sr, dr, mode, rgn); //if(thePCXPtr) thePCXPtr->isMyDraw = false; } //新規バッファを確保 void myNewBuffer(XCmdPtr paramPtr,Boolean isPixMap,Boolean isMono){ Point theSize; Rect theRect; Str255 tmpStr; int theDepth,thePlaneNo; PCXDataPtr thePCXPtr; PicHandle thePict; int theResId; //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); thePlaneNo = myStrToNum(paramPtr,tmpStr); if(thePlaneNo < 0 || thePlaneNo >= PLANE_MAX){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Buffer ID is out of (0-127)"); return; } thePCXPtr = GetPCXPtr(paramPtr,false); if(thePCXPtr == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Cannot create new window"); return; } if(thePCXPtr->gp[thePlaneNo] != NULL){ if(-1 == xKillBuffer(paramPtr,thePCXPtr,thePlaneNo)) { paramPtr->returnValue=PasToZero(paramPtr,"\pError:"); } } //size抽出 thePict = NULL; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(NULL != (thePict = (PicHandle)GetNamedResource('PICT',tmpStr))){ /* PICTの名前と一致する */ } else if(IsRect(tmpStr) == false && IsPoint(tmpStr) == false && 32768 > (theResId = myStrToNum(paramPtr,tmpStr)) && NULL != (thePict = (PicHandle)GetResource('PICT',theResId)) ){ /* PICTのIDと一致する */ } else if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); OffsetRect(&theRect,-theRect.left,-theRect.top); }else{ myStrToPoint(paramPtr,tmpStr,&theSize); theRect.left = 0; theRect.top = 0; theRect.right = theSize.h; theRect.bottom = theSize.v; } //depth抽出 if(paramPtr->paramCount <= 3){ theDepth = 0; } else{ ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(EqualString(tmpStr,"\pvram",false,true)) theDepth = -1; else theDepth = myStrToNum(paramPtr,tmpStr); } /* バッファ作成 */ if(NULL != thePict){ CGrafPtr saveGrafPort; GDHandle saveGDHandle; GWorldPtr screenBuf; HLock((Handle)thePict); theRect = (*thePict)->picFrame; OffsetRect(&theRect,-theRect.left,-theRect.top); xNewBuffer(paramPtr,isPixMap,isMono,thePCXPtr,&theRect,thePlaneNo,theDepth); //GWorldにPICTを描画 screenBuf = thePCXPtr->gp[thePlaneNo]; GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); DrawPicture(thePict, &theRect); SetGWorld(saveGrafPort, saveGDHandle); ReleaseResource((Handle)thePict); } else{ xNewBuffer(paramPtr,isPixMap,isMono,thePCXPtr,&theRect,thePlaneNo,theDepth); } } // int xNewBuffer(XCmdPtr paramPtr,Boolean isPixMap,Boolean isMono, PCXDataPtr thePCXPtr,Rect *pRect,short thePlaneNo,short theDepth) { CGrafPtr saveGrafPort; GDHandle saveGDHandle; GWorldPtr screenBuf; OSErr err; short opt; if(isPixMap){ if (isMono){ if (thePCXPtr->cTable == NULL){ CTabPtr ct = NULL; int i; thePCXPtr->cTable = (CTabHandle)NewHandle(sizeof(ColorTable)+256*sizeof(ColorSpec)); ct = *thePCXPtr->cTable; ct->ctSeed = 0; //逆引きデータ再構築 ct->ctFlags = 0; //フラグ ct->ctSize = 255; //テーブルサイズ(Max-1) for(i=0; i<255; i++){ ct->ctTable[i].value = i; ct->ctTable[i].rgb.red = i*256; ct->ctTable[i].rgb.green = i*256; ct->ctTable[i].rgb.blue = i*256; } ct->ctTable[i].value = i; ct->ctTable[i].rgb.red = 65535; ct->ctTable[i].rgb.green = 65535; ct->ctTable[i].rgb.blue = 65535; } } //VRAMオプション if(theDepth == -1) { opt = useDistantHdwrMem; theDepth = 0; } else opt = 0; //GWorld作成 if(isMono) err = NewGWorld(&screenBuf, 8, pRect, thePCXPtr->cTable, NULL, 0); else { err = NewGWorld(&screenBuf, theDepth, pRect, NULL, NULL, opt); if(err != noErr && opt != 0){ err = NewGWorld(&screenBuf, theDepth, pRect, NULL, NULL, useLocalHdwrMem); } if(err != noErr && opt != 0){ err = NewGWorld(&screenBuf, theDepth, pRect, NULL, NULL, 0); } if(err != noErr){ err = NewGWorld(&screenBuf, theDepth, pRect, NULL, NULL, useTempMem); //テンポラリも使ってみる } } if(err != noErr){ //Str255 tmpStr; //NumToStr(paramPtr,err,tmpStr); //paramPtr->returnValue=PasToZero(paramPtr,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,"\pError:Buffer allocation error"); return -1; } //GWorldをクリア GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); EraseRect(&screenBuf->portRect); SetGWorld(saveGrafPort, saveGDHandle); xKillBuffer(paramPtr, thePCXPtr, thePlaneNo); if(thePlaneNo >= 0){ thePCXPtr->gp[thePlaneNo] = screenBuf; } else if(thePlaneNo == -1){ thePCXPtr->primary = screenBuf; } else if(thePlaneNo == -2){ thePCXPtr->secondary = screenBuf; } else if(thePlaneNo == -3){ thePCXPtr->alpha = screenBuf; } else return -1; if(thePlaneNo < 0) { /* 確保したバッファのPixMapを消して */ /* 新たに静的なブロックを作る */ /* kill buffer時に注意 */ /* と思ったが、何かと無理がある様子 */ //プレーン自身はメモリの中で移動しないんだろうか? } }else{ GrafPtr newPort,cardPort; newPort = (GrafPtr)NewPtr(sizeof(GrafPort)); GetPort(&cardPort); (*newPort) = *cardPort; newPort->portBits.baseAddr = NewPtr((pRect->right+15)/16*2 * pRect->bottom); newPort->portBits.rowBytes = (pRect->right+15)/16*2; newPort->portBits.bounds = *pRect; newPort->portRect = *pRect; newPort->visRgn = NewRgn(); newPort->clipRgn = NewRgn(); RectRgn(newPort->visRgn,pRect); SetPort(newPort); ClipRect(pRect); EraseRect(pRect); SetPort(cardPort); ClipRect(&cardPort->portRect); if(thePlaneNo >= 0) { thePCXPtr->gp[thePlaneNo] = (GWorldPtr)newPort; } } return 0; } //バッファにPICTを描く void myLoadPict(XCmdPtr paramPtr,ResType aResType){ int rectMode; Rect theRect; Point thePoint; Str255 tmpStr; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //Rect抽出 if(paramPtr->paramCount <= 3){ rectMode = 1; //左上を0,0にする } else{ ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(EqualString(tmpStr,"\pOriginal",false,true)){ rectMode = 3; //PICTの矩形を使う } else if(IsRect(tmpStr) == true){ rectMode = 0; //指定矩形にする myStrToRect(paramPtr,tmpStr,&theRect); } else{ rectMode = 2; //左上を指定座標にする myStrToPoint(paramPtr,tmpStr,&thePoint); theRect.left = thePoint.h; theRect.top = thePoint.v; } } xLoadPict(paramPtr, &theRect, rectMode, *paramPtr->params[1], *paramPtr->params[2], aResType); } void xLoadPict(XCmdPtr paramPtr, Rect *pRect, int rectMode, char *planeName, char *resName, ResType aResType) { int pictNum; Point thePoint; PicHandle thePict; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; Str255 tmpStr; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,planeName,tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,resName,tmpStr); thePict = (PicHandle)GetNamedResource(aResType,tmpStr); if(thePict == NULL){ pictNum = myStrToNum(paramPtr,tmpStr); if(pictNum > 32767) thePict = NULL; else thePict = (PicHandle)GetResource(aResType,pictNum); if(thePict == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:not found PICT"); return; } } /* PICTのRectを抽出 */ if(rectMode == 1){ *pRect = (**thePict).picFrame; OffsetRect(pRect,-pRect->left,-pRect->top); } if(rectMode == 2){ thePoint.h = pRect->left; thePoint.v = pRect->top; *pRect = (**thePict).picFrame; OffsetRect(pRect,-pRect->left,-pRect->top); OffsetRect(pRect,thePoint.h,thePoint.v); } HLock((Handle)thePict); //GWorldにPICTを描画 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); DrawPicture(thePict, pRect); SetGWorld(saveGrafPort, saveGDHandle); ReleaseResource((Handle)thePict); } //バッファにcicnを描く void myLoadCicn(XCmdPtr paramPtr){ Rect theRect; Point thePoint; CIconHandle theCicn; Str255 tmpStr,resName; long cicnNum; int cicnNameNum,dstRectNum,i; short tmp; UInt32 resType; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; Handle nameStrH,dstStrH; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); LockPixels(GetGWorldPixMap(screenBuf)); SetGWorld(screenBuf, nil); nameStrH = paramPtr->params[2]; dstStrH = paramPtr->params[3]; cicnNameNum = numOfLinesOfHandle(nameStrH)+1; dstRectNum = numOfLinesOfHandle(dstStrH)+1; for(i=0;(i= -32768) theCicn = GetCIcon(cicnNum); if((cicnNum == 0)||(theCicn == NULL)){ SetResLoad(false); theCicn = (CIconHandle)GetNamedResource('cicn',tmpStr); SetResLoad(true); if(theCicn == NULL){ if((i+1==cicnNameNum)||(i+1==dstRectNum)){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:not found cicn"); } continue; } GetResInfo((Handle)theCicn,&tmp,&resType,resName); theCicn = GetCIcon(tmp); } HLock((Handle)theCicn); //Rect抽出 if(paramPtr->paramCount <= 3){ theRect = (*theCicn)->iconPMap.bounds; OffsetRect(&theRect,-theRect.left,-theRect.top); } else{ GetLineStrOfHandle(tmpStr,dstStrH,i%dstRectNum); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = (**theCicn).iconPMap.bounds; OffsetRect(&theRect,-theRect.left,-theRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&theRect,thePoint.h,thePoint.v); } } //GWorldにcicnを描画 PlotCIcon(&theRect,theCicn); DisposeCIcon(theCicn); } UnlockPixels(GetGWorldPixMap(screenBuf)); SetGWorld(saveGrafPort, saveGDHandle); } //バッファにICONを描く void myLoadIcon(XCmdPtr paramPtr){ Rect theRect; Point thePoint; Handle theIcon; Str255 tmpStr,resName; short iconNum; short iconNameNum,dstRectNum,i; UInt32 resType; RGBColor theColor,saveColor; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; Handle nameStrH, dstStrH; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; if(paramPtr->paramCount <= 4){ theColor.red = 0; theColor.green = 0; theColor.blue = 0; }else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); theColor = myGetColor(paramPtr,tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); LockPixels(GetGWorldPixMap(screenBuf)); SetGWorld(screenBuf, nil); GetForeColor(&saveColor); RGBForeColor(&theColor); nameStrH = paramPtr->params[2]; dstStrH = paramPtr->params[3]; iconNameNum = numOfLinesOfHandle(nameStrH)+1; dstRectNum = numOfLinesOfHandle(dstStrH)+1; for(i=0;(ireturnValue=PasToZero(paramPtr,"\pError:not found ICON"); } continue; } GetResInfo((Handle)theIcon,&iconNum,&resType,resName); theIcon = GetIcon(iconNum); } HLock((Handle)theIcon); //Rect抽出 if(paramPtr->paramCount <= 3){ SetRect(&theRect,0,0,32,32); } else{ GetLineStrOfHandle(tmpStr,dstStrH,i%dstRectNum); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ SetRect(&theRect,0,0,32,32); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&theRect,thePoint.h,thePoint.v); } } //GWorldにICONを描画 PlotIcon(&theRect,theIcon); ReleaseResource(theIcon); } RGBForeColor(&saveColor); UnlockPixels(GetGWorldPixMap(screenBuf)); SetGWorld(saveGrafPort, saveGDHandle); } void myPaintbuffer(XCmdPtr paramPtr){ Rect theRect; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; short mode; int pat; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; } //mode抽出 if(paramPtr->paramCount <= 4){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[4]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 5){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } PenSize(0,0); PenMode(mode); GetBackColor(&saveBkColor); GetForeColor(&saveColor); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PaintRect(&theRect); //Paint RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } void myOnDraw(XCmdPtr paramPtr){ Str255 tmpStr; GrafPtr cardPort; Rect srcRect,dstRect; Point thePoint; short mode; GWorldPtr screenBuf; BitMapPtr srcBitMap; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort(&cardPort); //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&screenBuf->portRect); } else{ srcRect = screenBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 3){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } //mode抽出 if(paramPtr->paramCount <= 4){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[4]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //BitMapPtrを取得 if((0xc000&(screenBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)screenBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)screenBuf)->portPixMap; //OpColor抽出 SetOpColor(mode); //CopyBitsによる転送 CopyBits2(srcBitMap, &(cardPort)->portBits, &srcRect,&dstRect,mode,nil ); } //CopyBits転送 void myCopyBits(XCmdPtr paramPtr, Boolean fastRoutine){ Str255 tmpStr; Handle srcStrH,dstStrH; Rect srcRect,dstRect; Point thePoint; RGBColor theOpColor = {65535, 65535, 65535}; RGBColor saveFColor,saveBColor; short mode; GWorldPtr srcBuf,dstBuf,cardPort; CGrafPtr saveGrafPort; GDHandle saveGDHandle; short srcRectNum,dstRectNum,i; PCXDataPtr PCXPtr; BitMapPtr srcBitMap,dstBitMap; int depth; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } PCXPtr = GetPCXPtr(paramPtr,false); GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //mode抽出 if(paramPtr->paramCount <= 5){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[5]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); GetForeColor(&saveFColor); GetBackColor(&saveBColor); //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent)RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } //バッファの色深度は8ビット以上専用 //転送元と転送先の色深度が同一であること if( fastRoutine ){ fastRoutine = false; if(0xc000&(srcBuf->portVersion) != 0){ depth = (*GetGWorldPixMap(srcBuf))->pixelSize; if(((0xc000&(dstBuf->portVersion)) != 0) && ((*GetGWorldPixMap(dstBuf))->pixelSize == depth) && (depth >= 8) && (mode == (srcCopy)) && (theOpColor.red == 65535) && (theOpColor.green == 65535) && (theOpColor.blue == 65535) ) { fastRoutine = true; } } } if(fastRoutine) { LockPixels(GetGWorldPixMap(srcBuf)); LockPixels(GetGWorldPixMap(dstBuf)); } srcStrH = paramPtr->params[3]; dstStrH = paramPtr->params[4]; srcRectNum = numOfLinesOfHandle(srcStrH)+1; dstRectNum = numOfLinesOfHandle(dstStrH)+1; for(i=0;(iportRect); } else{ srcRect = srcBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 4){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ GetLineStrOfHandle(tmpStr,dstStrH,i%dstRectNum); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } if(fastRoutine){ //拡大縮小のみ、高速転送 myZoomBlt(paramPtr, srcBuf, dstBuf, &srcRect, &dstRect, depth); } else { //CopyBitsによる転送 CopyBits2(srcBitMap,dstBitMap, &srcRect,&dstRect,mode,nil ); } } if(fastRoutine){ UnlockPixels(GetGWorldPixMap(srcBuf)); UnlockPixels(GetGWorldPixMap(dstBuf)); } RGBForeColor(&saveFColor); RGBBackColor(&saveBColor); SetGWorld(saveGrafPort, saveGDHandle); } //高速拡大縮小転送 void myZoomBlt(XCmdPtr paramPtr, GWorldPtr srcBuf, GWorldPtr dstBuf, Rect *srcRect, Rect *dstRect, int depth){ #pragma unused paramPtr int srcRow,dstRow; PixMapPtr srcPixMap,dstPixMap; unsigned char *srcStartAddr,*dstStartAddr; unsigned short *srcStartAddr16,*dstStartAddr16; unsigned long *srcStartAddr32,*dstStartAddr32; int srcWidthB,srcHeight; int dstWidthB,dstHeight; int srcLeft,srcTop; int dstRealWidth; int srcX,srcY,addX,addY; int Y; //PixMap抽出 srcPixMap = *((CGrafPtr)srcBuf)->portPixMap; dstPixMap = *((CGrafPtr)dstBuf)->portPixMap; //rowBytesを抽出 srcRow = (0x3fff & srcPixMap->rowBytes)/(depth/8); dstRow = (0x3fff & dstPixMap->rowBytes)/(depth/8); //PixMapのアドレスを求める srcStartAddr = (unsigned char *) srcPixMap->baseAddr; dstStartAddr = (unsigned char *) dstPixMap->baseAddr; srcStartAddr16 = (unsigned short *)srcStartAddr; dstStartAddr16 = (unsigned short *)dstStartAddr; srcStartAddr32 = (unsigned long *)srcStartAddr; dstStartAddr32 = (unsigned long *)dstStartAddr; dstStartAddr += dstRect->left + dstRow * dstRect->top; dstStartAddr16 += dstRect->left + dstRow * dstRect->top; dstStartAddr32 += dstRect->left + dstRow * dstRect->top; //クリッピング前に拡大率を求める //上下、左右反転時にはsrcHeight,srcWidthが負の値になることに注意 srcWidthB = (srcRect->right - srcRect->left); srcHeight = (srcRect->bottom - srcRect->top); dstWidthB = (dstRect->right - dstRect->left); dstHeight = (dstRect->bottom - dstRect->top); srcLeft = (srcRect->left<<16) + (1<<15); srcTop = (srcRect->top<<16) + (1<<15); //クリッピング if(dstRect->left < 0){ srcLeft -= (((double)dstRect->left*srcWidthB)/(double)dstWidthB)*65536.0; dstRect->left = 0; } if(dstRect->right > dstBuf->portRect.right){ dstRect->right = dstBuf->portRect.right; } if(dstRect->left >= dstRect->right) return; if(dstRect->top < 0){ srcTop -= (((double)dstRect->top*srcHeight)/(double)dstHeight)*65536.0; dstRect->top = 0; } if(dstRect->bottom > dstBuf->portRect.bottom){ dstRect->bottom = dstBuf->portRect.bottom; } if(dstRect->top >= dstRect->bottom) return; //0で割るのを防止 if((dstWidthB | dstHeight) == 0) return; dstRealWidth = dstRect->right - dstRect->left; addX = (srcWidthB<<16)/(dstWidthB); srcY = srcTop; addY = (srcHeight<<16)/(dstHeight); switch(depth){ case 8: { //拡大/縮小転送ルーチン unsigned char* dstEndAddr,*srcAddr; for(Y=abs(dstRect->bottom-dstRect->top); Y>0; Y--){ srcAddr = srcStartAddr+srcRow*(srcY>>16); srcX = srcLeft; dstEndAddr = dstStartAddr+dstRealWidth; while(dstStartAddr < dstEndAddr){ *dstStartAddr++ = srcAddr[srcX>>16]; srcX += addX; } srcY += addY; dstStartAddr += dstRow -dstRealWidth; } } break; case 16: { //拡大/縮小転送ルーチン unsigned short* dstEndAddr16,*srcAddr16; for(Y=abs(dstRect->bottom-dstRect->top); Y>0; Y--){ srcAddr16 = srcStartAddr16+srcRow*(srcY>>16); srcX = srcLeft; dstEndAddr16 = dstStartAddr16+dstRealWidth; while(dstStartAddr16 < dstEndAddr16){ *dstStartAddr16++ = srcAddr16[srcX>>16]; srcX += addX; } srcY += addY; dstStartAddr16 += dstRow -dstRealWidth; } } break; case 32: { //拡大/縮小転送ルーチン unsigned long* dstEndAddr32,*srcAddr32; for(Y=abs(dstRect->bottom-dstRect->top); Y>0; Y--){ srcAddr32 = srcStartAddr32+srcRow*(srcY>>16); srcX = srcLeft; dstEndAddr32 = dstStartAddr32+dstRealWidth; while(dstStartAddr32 < dstEndAddr32){ *dstStartAddr32++ = srcAddr32[srcX>>16]; srcX += addX; } srcY += addY; dstStartAddr32 += dstRow -dstRealWidth; } } break; } } //ずらしCopyBits転送 void myBrushCopyBits(XCmdPtr paramPtr){ Str255 tmpStr, rectStr; Rect srcRect,dstRect,tmpRect,DrawRect; Point thePoint; RGBColor theOpColor = {65535, 65535, 65535}; RGBColor saveFColor,saveBColor; short mode; GWorldPtr srcBuf,dstBuf,cardPort; CGrafPtr saveGrafPort; GDHandle saveGDHandle; PCXDataPtr PCXPtr; BitMapPtr srcBitMap,dstBitMap; int x, y, i; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } PCXPtr = GetPCXPtr(paramPtr,false); GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //mode抽出 if(paramPtr->paramCount <= 6){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); GetForeColor(&saveFColor); GetBackColor(&saveBColor); //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent)RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); } else{ srcRect = srcBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 4 || **(paramPtr->params[4]) == 0){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } //ずらし抽出 if(paramPtr->paramCount <= 5 || **(paramPtr->params[5]) == 0){ x = 0; y = 0; } else { ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); myStrToPoint(paramPtr,tmpStr,&thePoint); x = thePoint.h; y = thePoint.v; } //描画する範囲 DrawRect = dstRect; if(x<0) DrawRect.left += x; if(x>0) DrawRect.right += x; if(y<0) DrawRect.top += y; if(y>0) DrawRect.bottom += y; myClipRect(&DrawRect,&dstBuf->portRect); if(abs(x) > abs(y)){ for(i=0; i<=abs(x); i++){ tmpRect = dstRect; OffsetRect(&tmpRect, (x>0)?i:-i, y*i/abs(x)); //CopyBitsによる転送 CopyBits2(srcBitMap,dstBitMap, &srcRect,&tmpRect,mode,nil ); } } else{ for(i=0; i<=abs(y); i++){ tmpRect = dstRect; OffsetRect(&tmpRect, x*i/abs(y), (y>0)?i:-i); //CopyBitsによる転送 CopyBits2(srcBitMap,dstBitMap, &srcRect,&tmpRect,mode,nil ); } } RGBForeColor(&saveFColor); RGBBackColor(&saveBColor); SetGWorld(saveGrafPort, saveGDHandle); //矩形を返す NumToStr(paramPtr,DrawRect.left,rectStr); NumToStr(paramPtr,DrawRect.top,tmpStr); rectStr[rectStr[0]+1]=','; rectStr[0]++; for(i=1;i<=tmpStr[0];i++){ rectStr[rectStr[0]+i]=tmpStr[i]; } rectStr[0]+=tmpStr[0]; NumToStr(paramPtr,DrawRect.right,tmpStr); rectStr[rectStr[0]+1]=','; rectStr[0]++; for(i=1;i<=tmpStr[0];i++){ rectStr[rectStr[0]+i]=tmpStr[i]; } rectStr[0]+=tmpStr[0]; NumToStr(paramPtr,DrawRect.bottom,tmpStr); rectStr[rectStr[0]+1]=','; rectStr[0]++; for(i=1;i<=tmpStr[0];i++){ rectStr[rectStr[0]+i]=tmpStr[i]; } rectStr[0]+=tmpStr[0]; paramPtr->returnValue=PasToZero(paramPtr,rectStr); } void myCopyMask(XCmdPtr paramPtr){ Str255 tmpStr; Handle srcStrH,maskStrH,dstStrH; Rect srcRect,maskRect,dstRect; Point thePoint; RGBColor theOpColor,saveFColor,saveBColor; short mode; GWorldPtr srcBuf,maskBuf,dstBuf,cardPort; BitMapPtr srcBitMap,maskBitMap,dstBitMap; CGrafPtr saveGrafPort; GDHandle saveGDHandle; short srcRectNum,maskRectNum,dstRectNum,i; PCXDataPtr PCXPtr; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } PCXPtr = GetPCXPtr(paramPtr,false); GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //マスクPlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); maskBuf = myGetPlane(paramPtr,tmpStr); if(maskBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //mode抽出 if(paramPtr->paramCount <= 7){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[7]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); GetForeColor(&saveFColor); GetBackColor(&saveBColor); //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(maskBuf->portVersion)) == 0) maskBitMap = &((GrafPtr)maskBuf)->portBits; else maskBitMap = (BitMap*)*((CGrafPtr)maskBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 8){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[8],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } srcStrH = paramPtr->params[4]; maskStrH = paramPtr->params[5]; dstStrH = paramPtr->params[6]; srcRectNum = numOfLinesOfHandle(srcStrH)+1; maskRectNum = numOfLinesOfHandle(maskStrH)+1; dstRectNum = numOfLinesOfHandle(dstStrH)+1; for(i=0;(iportRect); } else{ srcRect = srcBuf->portRect; } //maskRect抽出 GetLineStrOfHandle(tmpStr,maskStrH,i%maskRectNum); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&maskRect); myClipRect(&maskRect,&maskBuf->portRect); } else{ maskRect = maskBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 6){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ GetLineStrOfHandle(tmpStr,dstStrH,i%dstRectNum); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } if(mode != srcCopy){ //CopyDeepMaskによる転送 CopyDeepMask(srcBitMap,maskBitMap,dstBitMap, &srcRect,&maskRect,&dstRect,mode,nil ); }else{ //CopyMaskによる転送 CopyMask(srcBitMap,maskBitMap,dstBitMap, &srcRect,&maskRect,&dstRect ); } } RGBForeColor(&saveFColor); RGBBackColor(&saveBColor); SetGWorld(saveGrafPort, saveGDHandle); } //左右反転 void myFlipHBuffer(XCmdPtr paramPtr){ Str255 tmpStr; Rect srcRect,dstRect; Point thePoint; RGBColor theOpColor; short mode,i,width; GWorldPtr srcBuf,dstBuf,cardPort; CGrafPtr saveGrafPort; GDHandle saveGDHandle; BitMapPtr srcBitMap,dstBitMap; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); } else{ srcRect = srcBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 4){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } if(dstRect.right-dstRect.left != srcRect.right-srcRect.left){ paramPtr->returnValue=PasToZero(paramPtr,"\pError: srcWidth <> dstWidth"); return; } //mode抽出 if(paramPtr->paramCount <= 5){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[5]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } //CopyBitsによる転送 //左右反転するために横幅1ドットを繰り返して転送する width = dstRect.right-dstRect.left; srcRect.right = srcRect.left+1; dstRect.left = dstRect.right-1; for(i=0; iparamCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); } else{ srcRect = srcBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 4){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } if(dstRect.bottom-dstRect.top != srcRect.bottom-srcRect.top){ paramPtr->returnValue=PasToZero(paramPtr,"\pError: srcHeight <> dstHeight"); return; } //mode抽出 if(paramPtr->paramCount <= 5){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[5]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } //CopyBitsによる転送 //上下反転するために縦幅1ドットずつ繰り返して転送する height = dstRect.bottom-dstRect.top; srcRect.bottom = srcRect.top+1; dstRect.top = dstRect.bottom-1; for(i=0; iparamCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); } else{ srcRect = srcBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 4){ dstRect = dstBuf->portRect; } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } //mode抽出 if(paramPtr->paramCount <= 5){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[5]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } //CopyBitsによる転送 tmpRect = srcRect; OffsetRect(&tmpRect,dstRect.left-tmpRect.left,dstRect.top-tmpRect.top); while(tmpRect.top < dstRect.bottom){ while(tmpRect.left < dstRect.right){ //CopyBitsによる転送 CopyBits2(srcBitMap,dstBitMap, &srcRect,&tmpRect,mode,nil ); OffsetRect(&tmpRect,tmpRect.right-tmpRect.left,0); } OffsetRect(&tmpRect,dstRect.left-tmpRect.left,tmpRect.bottom-tmpRect.top); } SetGWorld(saveGrafPort, saveGDHandle); } void myRotateBuffer(XCmdPtr paramPtr){ Str255 tmpStr; Rect srcRect,clipRect; Point srcPin,dstPin; RGBColor theOpColor; int mode,rx,ry,angle; GWorldPtr srcBuf,dstBuf,cardPort; CGrafPtr saveGrafPort; GDHandle saveGDHandle; BitMapPtr srcBitMap,dstBitMap; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); } else{ srcRect = srcBuf->portRect; } //srcPin抽出 //if(paramPtr->paramCount <= 4){ srcPin.h = (srcRect.left+srcRect.right+1)/2; srcPin.v = (srcRect.top+srcRect.bottom+1)/2; //} //else{ // ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); // myStrToPoint(paramPtr,tmpStr,&srcPin); //} //clipRect抽出 ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&clipRect); myClipRect(&clipRect,&dstBuf->portRect); } else{ clipRect = dstBuf->portRect; } //dstPin抽出 if(paramPtr->paramCount <= 5){ dstPin.h = (srcRect.left+srcRect.right+1)/2; dstPin.v = (srcRect.top+srcRect.bottom+1)/2; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); myStrToPoint(paramPtr,tmpStr,&dstPin); } //angle抽出 if(paramPtr->paramCount <= 7){ angle = 0; } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); angle = myStrToNum(paramPtr,tmpStr); } //rateX抽出 if(paramPtr->paramCount <= 8){ rx = 256; } else{ ZeroToPas(paramPtr,*paramPtr->params[8],tmpStr); if(tmpStr[0] == 0) rx = 256; else rx = myStrToNum(paramPtr,tmpStr); } //rateY抽出 if(paramPtr->paramCount <= 9){ ry = 256; } else{ ZeroToPas(paramPtr,*paramPtr->params[9],tmpStr); if(tmpStr[0] == 0) ry = 256; else ry = myStrToNum(paramPtr,tmpStr); } //mode抽出 if(paramPtr->paramCount <= 10){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[10],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[10]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } { int cosR,sinR; Rect dstRect; long srcLeft,srcTop,srcRight,srcBottom; long Xad,Yad,Xad2,Yad2; long srcX,srcY,srcBaseX,srcBaseY,dstY; long dstX; Rect spRect,dpRect; Boolean fastRoutine; int depth; //sin,cosは1回きりの呼び出し cosR = cos((double)angle/180*3.14159265358979)*65536; sinR = sin((double)angle/180*3.14159265358979)*65536; //転送先の大きさ(矩形)を求める dstRect.left = dstPin.h -((abs((((long)srcRect.right - srcRect.left+1)*cosR>>8)*(rx)) +abs((((long)srcRect.bottom - srcRect.top+1)*sinR>>8)*(ry)))>>17); dstRect.right = dstPin.h +((abs((((long)srcRect.right - srcRect.left+1)*cosR>>8)*(rx)) +abs((((long)srcRect.bottom - srcRect.top+1)*sinR>>8)*(ry)))>>17); dstRect.top = dstPin.v -((abs((((long)srcRect.right - srcRect.left+1)*sinR>>8)*(rx)) +abs((((long)srcRect.bottom - srcRect.top+1)*cosR>>8)*(ry)))>>17); dstRect.bottom = dstPin.v +((abs((((long)srcRect.right - srcRect.left+1)*sinR>>8)*(rx)) +abs((((long)srcRect.bottom - srcRect.top+1)*cosR>>8)*(ry)))>>17); //転送先サイズにクリップする if(dstRect.left < clipRect.left){ dstRect.left = clipRect.left; } if(dstRect.right > clipRect.right){ dstRect.right = clipRect.right; } if(dstRect.top < clipRect.top){ dstRect.top = clipRect.top; } if(dstRect.bottom > clipRect.bottom){ dstRect.bottom = clipRect.bottom; } if(dstRect.right-dstRect.left <= 0 || dstRect.bottom-dstRect.top <= 0){ //描く事あらへんがな return; } LockPixels(GetGWorldPixMap(srcBuf)); LockPixels(GetGWorldPixMap(dstBuf)); //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //バッファの色深度は8ビット以上専用 //転送元と転送先の色深度が同一であること fastRoutine = false; if((0xc000&(srcBuf->portVersion)) != 0){ depth = (*GetGWorldPixMap(srcBuf))->pixelSize; if((0xc000&(srcBuf->portVersion)) != 0 && (*GetGWorldPixMap(dstBuf))->pixelSize == depth && depth >= 8 && (mode == srcCopy || mode == transparent)) { fastRoutine = true; } } //高速化ルーチンを使用する if( fastRoutine == true){ int srcRow,dstRow; PixMapPtr srcPixMap,dstPixMap; //PixMap抽出 srcPixMap = *((CGrafPtr)srcBuf)->portPixMap; dstPixMap = *((CGrafPtr)dstBuf)->portPixMap; //高速転送ルーチン { unsigned char *srcStartAddr,*dstStartAddr; unsigned short *srcStartAddr16,*dstStartAddr16; unsigned long *srcStartAddr32,*dstStartAddr32; //rowBytesを抽出 srcRow = (0x3fff & srcPixMap->rowBytes)/(depth/8); dstRow = (0x3fff & dstPixMap->rowBytes)/(depth/8); //PixMapのアドレスを求める srcStartAddr = (unsigned char *) srcPixMap->baseAddr; dstStartAddr = (unsigned char *) dstPixMap->baseAddr; srcStartAddr16 = (unsigned short *)srcStartAddr; dstStartAddr16 = (unsigned short *)dstStartAddr; srcStartAddr32 = (unsigned long *)srcStartAddr; dstStartAddr32 = (unsigned long *)dstStartAddr; //高速化Lv.3 //描画ルーチン srcLeft = (srcRect.left<<16); srcTop = (srcRect.top<<16); srcRight = (srcRect.right<<16)-1; srcBottom = (srcRect.bottom<<16)-1; Xad = (cosR<<8)/(rx); Yad = (-sinR<<8)/(ry); Xad2 = (sinR<<8)/(rx); Yad2 = (cosR<<8)/(ry); dstY = dstRect.top-dstPin.v; srcBaseX = ((((dstY*sinR+(dstRect.left-dstPin.h)*cosR)<<4)/(rx))<<4)+(srcPin.h<<16); srcBaseY = ((((dstY*cosR-(dstRect.left-dstPin.h)*sinR)<<4)/(ry))<<4)+(srcPin.v<<16); //透過なし転送ルーチン if(mode == srcCopy){ switch(depth){ case 8: for ( ; dstY < dstRect.bottom-dstPin.v ; dstY++ ) { dstX = dstRect.left; srcX = srcBaseX; srcY = srcBaseY; srcBaseX += Xad2; srcBaseY += Yad2; while ( dstX <= dstRect.right ){ srcX += Xad; srcY += Yad; if( ~((srcX-srcLeft)|(srcY-srcTop)|(srcRight-srcX)|(srcBottom-srcY))>>31 ){ dstStartAddr[(dstX)+(dstPin.v+dstY)*dstRow] = srcStartAddr[(srcX>>(16))+(srcY>>16)*srcRow]; } dstX++; } } break; case 16: for ( ; dstY < dstRect.bottom-dstPin.v ; dstY++ ) { dstX = dstRect.left; srcX = srcBaseX; srcY = srcBaseY; srcBaseX += Xad2; srcBaseY += Yad2; while ( dstX <= dstRect.right ){ srcX += Xad; srcY += Yad; if( ~((srcX-srcLeft)|(srcY-srcTop)|(srcRight-srcX)|(srcBottom-srcY))>>31 ){ dstStartAddr16[(dstX)+(dstPin.v+dstY)*dstRow] = srcStartAddr16[(srcX>>(16))+(srcY>>16)*srcRow]; } dstX++; } } break; case 32: for ( ; dstY < dstRect.bottom-dstPin.v ; dstY++ ) { dstX = dstRect.left; srcX = srcBaseX; srcY = srcBaseY; srcBaseX += Xad2; srcBaseY += Yad2; while ( dstX <= dstRect.right ){ srcX += Xad; srcY += Yad; if( ~((srcX-srcLeft)|(srcY-srcTop)|(srcRight-srcX)|(srcBottom-srcY))>>31 ){ dstStartAddr32[(dstX)+(dstPin.v+dstY)*dstRow] = srcStartAddr32[(srcX>>(16))+(srcY>>16)*srcRow]; } dstX++; } } break; } } //透過あり転送ルーチン if(mode == transparent){ unsigned char CKey; unsigned short CKey16; unsigned long CKey32,savePix; RGBColor saveColor; //透過色データを取得 //OpColor抽出 if(paramPtr->paramCount <= 11){ theOpColor.red = 65535; theOpColor.green = 65535; theOpColor.blue = 65535; } else{ ZeroToPas(paramPtr,*paramPtr->params[11],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); } //カラーキーの色で描く! savePix = *dstStartAddr32; GetForeColor(&saveColor); RGBForeColor(&theOpColor); MoveTo(0,0); PenSize(1,1); Line(0,1); //4つのカラーキー情報を一つのlongに入れる switch(depth){ case 8: CKey = *dstStartAddr; break; case 16: CKey16 = *dstStartAddr16; break; case 32: CKey32 = *dstStartAddr32; break; } *dstStartAddr32 = savePix; RGBForeColor(&saveColor); switch(depth){ case 8: for ( ; dstY < dstRect.bottom-dstPin.v ; dstY++ ) { dstX = dstRect.left; srcX = srcBaseX; srcY = srcBaseY; srcBaseX += Xad2; srcBaseY += Yad2; while ( dstX <= dstRect.right ){ srcX += Xad; srcY += Yad; if( ~((srcX-srcLeft)|(srcY-srcTop)|(srcRight-srcX)|(srcBottom-srcY))>>31 ){ if(srcStartAddr[(srcX>>(16))+(srcY>>16)*srcRow] != CKey){ dstStartAddr[(dstX)+(dstPin.v+dstY)*dstRow] = srcStartAddr[(srcX>>(16))+(srcY>>16)*srcRow]; } } dstX++; } } break; case 16: for ( ; dstY < dstRect.bottom-dstPin.v ; dstY++ ) { dstX = dstRect.left; srcX = srcBaseX; srcY = srcBaseY; srcBaseX += Xad2; srcBaseY += Yad2; while ( dstX <= dstRect.right ){ srcX += Xad; srcY += Yad; if( ~((srcX-srcLeft)|(srcY-srcTop)|(srcRight-srcX)|(srcBottom-srcY))>>31 ){ if(srcStartAddr16[(srcX>>(16))+(srcY>>16)*srcRow] != CKey16){ dstStartAddr16[(dstX)+(dstPin.v+dstY)*dstRow] = srcStartAddr16[(srcX>>(16))+(srcY>>16)*srcRow]; } } dstX++; } } break; case 32: for ( ; dstY < dstRect.bottom-dstPin.v ; dstY++ ) { dstX = dstRect.left; srcX = srcBaseX; srcY = srcBaseY; srcBaseX += Xad2; srcBaseY += Yad2; while ( dstX <= dstRect.right ){ srcX += Xad; srcY += Yad; if( ~((srcX-srcLeft)|(srcY-srcTop)|(srcRight-srcX)|(srcBottom-srcY))>>31 ){ if(srcStartAddr32[(srcX>>(16))+(srcY>>16)*srcRow] != CKey32){ dstStartAddr32[(dstX)+(dstPin.v+dstY)*dstRow] = srcStartAddr32[(srcX>>(16))+(srcY>>16)*srcRow]; } } dstX++; } } break; } } } UnlockPixels(GetGWorldPixMap(srcBuf)); UnlockPixels(GetGWorldPixMap(dstBuf)); SetGWorld(saveGrafPort, saveGDHandle); return; } //CopyBitsルーチンを使用する //BitMap抽出 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 11){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[11],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } //高速化Lv.3 //描画ルーチン srcLeft = (srcRect.left<<16); srcTop = (srcRect.top<<16); srcRight = (srcRect.right<<16)-1; srcBottom = (srcRect.bottom<<16)-1; Xad = (cosR<<8)/(rx); Yad = (-sinR<<8)/(ry); Xad2 = (sinR<<8)/(rx); Yad2 = (cosR<<8)/(ry); dstY = dstRect.top-dstPin.v; srcBaseX = ((((dstY*sinR+(dstRect.left-dstPin.h)*cosR)<<4)/(rx))<<4)+(srcPin.h<<16); srcBaseY = ((((dstY*cosR-(dstRect.left-dstPin.h)*sinR)<<4)/(ry))<<4)+(srcPin.v<<16); for ( ; dstY < dstRect.bottom-dstPin.v ; dstY++ ) { dstX = dstRect.left; srcX = srcBaseX; srcY = srcBaseY; srcBaseX += Xad2; srcBaseY += Yad2; while ( dstX <= dstRect.right ){ srcX += Xad; srcY += Yad; if( ~((srcX-srcLeft)|(srcY-srcTop)|(srcRight-srcX)|(srcBottom-srcY))>>31 ){ //CopyBitsによる描画ルーチン SetRect(&spRect,srcX>>16,srcY>>16,(srcX>>16)+1,(srcY>>16)+1); SetRect(&dpRect,dstX,dstPin.v+dstY,dstX+1,dstPin.v+dstY+1); CopyBits2(srcBitMap,dstBitMap, &spRect,&dpRect,mode,nil ); } dstX++; } } } UnlockPixels(GetGWorldPixMap(srcBuf)); UnlockPixels(GetGWorldPixMap(dstBuf)); SetGWorld(saveGrafPort, saveGDHandle); } void myClipRect3(Rect *r, Rect *srcRect, Rect *maskRect, Rect *dstRect, Rect * clipRect){ int offset; if(r->left < 0){ offset = r->left; srcRect->left -= offset; maskRect->left -= offset; dstRect->left -= offset; } if(r->right > clipRect->right){ offset = r->right - clipRect->right; srcRect->right -= offset; maskRect->right -= offset; dstRect->right -= offset; } if(r->top < 0){ offset = r->top; srcRect->top -= offset; maskRect->top -= offset; dstRect->top -= offset; } if(r->bottom > clipRect->bottom){ offset = r->bottom - clipRect->bottom; srcRect->bottom -= offset; maskRect->bottom -= offset; dstRect->bottom -= offset; } } /* 16Bitカラー専用のアルファチャンネル付き転送 */ void myAlphaChannelBlt(XCmdPtr paramPtr){ Str255 tmpStr; Point thePoint; Rect srcRect,maskRect,dstRect; GWorldPtr srcBuf,maskBuf,dstBuf,cardPort; int depth; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //マスクPlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); maskBuf = myGetPlane(paramPtr,tmpStr); if(maskBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); } else{ srcRect = srcBuf->portRect; } //maskRect抽出 ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&maskRect); myClipRect(&maskRect,&maskBuf->portRect); } else{ maskRect = srcRect; } //srcRectとmaskRectのサイズが違うとエラー if( (srcRect.right-srcRect.left != maskRect.right - maskRect.left) || (srcRect.bottom-srcRect.top != maskRect.bottom - maskRect.top) ) { paramPtr->returnValue=PasToZero(paramPtr,"\pError:srcRect size not equal maskRect size"); return; } //dstRect抽出 if(paramPtr->paramCount <= 6){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } //srcRectとdstRectのサイズが違うとエラー if( (srcRect.right-srcRect.left != dstRect.right - dstRect.left) || (srcRect.bottom-srcRect.top != dstRect.bottom - dstRect.top) ) { paramPtr->returnValue=PasToZero(paramPtr,"\pError:srcRect size not equal dstRect size"); return; } //はみだし部分を縮める myClipRect3(&srcRect,&srcRect,&maskRect,&dstRect,&srcBuf->portRect); myClipRect3(&dstRect,&srcRect,&maskRect,&dstRect,&dstBuf->portRect); myClipRect3(&dstRect,&srcRect,&maskRect,&dstRect,&(*dstBuf->clipRgn)->rgnBBox); //バッファの色深度は16ビット以上専用 if((0xc000&(srcBuf->portVersion)) != 0){ depth = (*GetGWorldPixMap(srcBuf))->pixelSize; if ( depth < 16){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer depth illegal"); return; } } else { paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer depth illegal"); return; } if((0xc000&(dstBuf->portVersion)) != 0){ if ((*GetGWorldPixMap(dstBuf))->pixelSize != depth){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer depth illegal"); return; } } else { paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer depth illegal"); return; } if((0xc000&(maskBuf->portVersion)) != 0){ if (8 != (*GetGWorldPixMap(maskBuf))->pixelSize){ //マスクは8ビット paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer depth illegal"); return; } } else { paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer depth illegal"); return; } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //PixMapのLock LockPixels(GetGWorldPixMap(srcBuf)); LockPixels(GetGWorldPixMap(maskBuf)); LockPixels(GetGWorldPixMap(dstBuf)); //16ビットカラーのアルファ付き転送ルーチン if(depth == 16){ int srcRow,maskRow,dstRow; unsigned short *srcStartAddr,*dstStartAddr; unsigned char *maskStartAddr; PixMapPtr srcPixMap,maskPixMap,dstPixMap; int h,v; unsigned long bitmask = 0x001f; int alpha; //PixMap抽出 srcPixMap = *((CGrafPtr)srcBuf)->portPixMap; maskPixMap = *((CGrafPtr)maskBuf)->portPixMap; dstPixMap = *((CGrafPtr)dstBuf)->portPixMap; //PixMapのアドレスを求める srcRow = 0x3fff & srcPixMap->rowBytes; srcStartAddr = (unsigned short *) srcPixMap->baseAddr; maskRow = 0x3fff & maskPixMap->rowBytes; maskStartAddr = (unsigned char *) maskPixMap->baseAddr; dstRow = 0x3fff & dstPixMap->rowBytes; dstStartAddr = (unsigned short *) dstPixMap->baseAddr; srcStartAddr += srcRect.left + srcRow/2 * srcRect.top; maskStartAddr += maskRect.left + maskRow * maskRect.top; dstStartAddr += dstRect.left + dstRow/2 * dstRect.top; for(v=0; v>5) + (((bitmask&(*srcStartAddr)) * (bitmask&(*maskStartAddr)))>>5) | // ((((bitmask&(*dstStartAddr>>5)) * (bitmask&~(*maskStartAddr>>5)))>>5) + (((bitmask&(*srcStartAddr>>5)) * (bitmask&(*maskStartAddr>>5)))>>5)<<5) | // ((((bitmask&(*dstStartAddr>>10)) * (bitmask&~(*maskStartAddr>>10)))>>5) + (((bitmask&(*srcStartAddr>>10)) * (bitmask&(*maskStartAddr>>10)))>>5)<<10); // 255/256になる、多少遅いルーチン // alpha = 0xff-(*maskStartAddr); // inverseAlpha = *maskStartAddr; // *dstStartAddr = (((bitmask&(*dstStartAddr)) * inverseAlpha)>>8) + (((bitmask&(*srcStartAddr)) * alpha)>>8) | // ((((bitmask&(*dstStartAddr>>5)) * inverseAlpha)>>8) + (((bitmask&(*srcStartAddr>>5)) * alpha)>>8)<<5) | // ((((bitmask&(*dstStartAddr>>10)) * inverseAlpha)>>8) + (((bitmask&(*srcStartAddr>>10)) * alpha)>>8)<<10); alpha = *maskStartAddr; if (alpha == 255) alpha = 256; *dstStartAddr = (((((bitmask&(*dstStartAddr))-(int)(bitmask&(*srcStartAddr))) *alpha)>>8) +(bitmask&*srcStartAddr)) | (((((bitmask&(*dstStartAddr>>5))-(int)(bitmask&(*srcStartAddr>>5))) *alpha)>>8) + (bitmask&*srcStartAddr>>5))<<5 | (((((bitmask&(*dstStartAddr>>10))-(int)(bitmask&(*srcStartAddr>>10))) *alpha)>>8) + (*srcStartAddr>>10))<<10; dstStartAddr++;srcStartAddr++;maskStartAddr++; } dstStartAddr += dstRow/2 -(srcRect.right - srcRect.left); srcStartAddr += srcRow/2 -(srcRect.right - srcRect.left); maskStartAddr += maskRow -(srcRect.right - srcRect.left); } UnlockPixels(GetGWorldPixMap(srcBuf)); UnlockPixels(GetGWorldPixMap(maskBuf)); UnlockPixels(GetGWorldPixMap(dstBuf)); } //32ビットカラーのアルファ付き転送ルーチン if(depth == 32){ int srcRow,maskRow,dstRow; unsigned long *srcStartAddr,*dstStartAddr; unsigned char *maskStartAddr; PixMapPtr srcPixMap,maskPixMap,dstPixMap; int h,v; unsigned long bitmask = 0x00ff; unsigned int alpha,inverseAlpha; //PixMap抽出 srcPixMap = *((CGrafPtr)srcBuf)->portPixMap; maskPixMap = *((CGrafPtr)maskBuf)->portPixMap; dstPixMap = *((CGrafPtr)dstBuf)->portPixMap; //PixMapのアドレスを求める srcRow = 0x3fff & srcPixMap->rowBytes; srcStartAddr = (unsigned long *) srcPixMap->baseAddr; maskRow = 0x3fff & maskPixMap->rowBytes; maskStartAddr = (unsigned char *) maskPixMap->baseAddr; dstRow = 0x3fff & dstPixMap->rowBytes; dstStartAddr = (unsigned long *) dstPixMap->baseAddr; srcStartAddr += srcRect.left + srcRow/4 * srcRect.top; maskStartAddr += maskRect.left + maskRow * maskRect.top; dstStartAddr += dstRect.left + dstRow/4 * dstRect.top; for(v=0; v>8) + (((bitmask&(*srcStartAddr)) * alpha)>>8) | // ((((bitmask&(*dstStartAddr>>8)) * inverseAlpha)>>8) + (((bitmask&(*srcStartAddr>>8)) * alpha)>>8)<<8) | // ((((bitmask&(*dstStartAddr>>16)) * inverseAlpha)>>8) + (((bitmask&(*srcStartAddr>>16)) * alpha)>>8)<<16); alpha = *maskStartAddr; if (alpha == 255) alpha = 256; *dstStartAddr = (((((bitmask&(*dstStartAddr))-(int)(bitmask&(*srcStartAddr))) *alpha)>>8) +(bitmask&*srcStartAddr)) | (((((bitmask&(*dstStartAddr>>8))-(int)(bitmask&(*srcStartAddr>>8))) *alpha)>>8) + (bitmask&*srcStartAddr>>8))<<8 | (((((bitmask&(*dstStartAddr>>16))-(int)(bitmask&(*srcStartAddr>>16))) *alpha)>>8) + (*srcStartAddr>>16))<<16; dstStartAddr++;srcStartAddr++;maskStartAddr++; } dstStartAddr += dstRow/4 -(srcRect.right - srcRect.left); srcStartAddr += srcRow/4 -(srcRect.right - srcRect.left); maskStartAddr += maskRow -(srcRect.right - srcRect.left); } UnlockPixels(GetGWorldPixMap(srcBuf)); UnlockPixels(GetGWorldPixMap(maskBuf)); UnlockPixels(GetGWorldPixMap(dstBuf)); } SetGWorld(saveGrafPort, saveGDHandle); } typedef struct{ double h; double v; }PointFp; void myDistortBlt(XCmdPtr paramPtr){ int i,j,c1,c2; Str255 tmpStr; Str255 pointStr; Boolean isrect,srcClip; Rect srcRect,clipRect,srcClipRect; Point tmpPoint; PointFp srcPoint[4],dstPoint[4],tmpPoint32; short vMin,vMax; RGBColor theOpColor,saveColor; short mode; GWorldPtr srcBuf,dstBuf,cardPort; CGrafPtr saveGrafPort; GDHandle saveGDHandle; BitMapPtr srcBitMap,dstBitMap; if(paramPtr->paramCount <= 4){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //srcRect抽出 srcClip = false; ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); isrect = true; } else if(tmpStr[0] == 0){ srcRect = srcBuf->portRect; isrect = true; } else{ //srcPoint*4抽出 c2=1; for( i=0; i<4;){ for(c1=c2; c2<=tmpStr[0]; c2++){ if( tmpStr[c2] == '\0' || tmpStr[c2] == '\n' || tmpStr[c2] == ' ' ) { break; } pointStr[c2-c1+1] = tmpStr[c2]; } pointStr[0] = c2-c1; myStrToPoint(paramPtr,pointStr,&tmpPoint); srcPoint[i].h = tmpPoint.h; srcPoint[i].v = tmpPoint.v; c2++; i++; if(c2>tmpStr[0]) break; } if(i<3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:illegal srcRect"); return; } if(i==3) srcPoint[3] = srcPoint[2]; isrect = false; srcClip = true; srcClipRect = srcBuf->portRect; } if(isrect){ //srcPoint:4に分割 srcPoint[0].h = (double)srcRect.left; srcPoint[0].v = (double)srcRect.top; srcPoint[1].h = (double)srcRect.right; srcPoint[1].v = (double)srcRect.top; srcPoint[2].h = (double)srcRect.left; srcPoint[2].v = (double)srcRect.bottom; srcPoint[3].h = (double)srcRect.right; srcPoint[3].v = (double)srcRect.bottom; } //clipRect抽出 ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&clipRect); myClipRect(&clipRect,&dstBuf->portRect); } else{ clipRect = dstBuf->portRect; } //dstPoint*4抽出 ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); c2=1; for( i=0; i<4; ){ for(c1=c2; c2<=tmpStr[0]; c2++){ if( tmpStr[c2] == '\0' || tmpStr[c2] == '\n' || tmpStr[c2] == ' ' ) { break; } pointStr[c2-c1+1] = tmpStr[c2]; } pointStr[0] = c2-c1; myStrToPoint(paramPtr,pointStr,&tmpPoint); dstPoint[i].h = (double)tmpPoint.h; dstPoint[i].v = (double)tmpPoint.v; c2++; i++; if(c2>tmpStr[0]) break; } if(i<3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:illegal dstRect"); return; } if(i==3) dstPoint[3] = dstPoint[2]; //>>srcPointのソーティング開始 if(srcPoint[0].h > srcPoint[1].h){ tmpPoint32 = dstPoint[0]; dstPoint[0] = dstPoint[1]; dstPoint[1] = tmpPoint32; tmpPoint32 = srcPoint[0]; srcPoint[0] = srcPoint[1]; srcPoint[1] = tmpPoint32; } if(srcPoint[2].h > srcPoint[3].h){ tmpPoint32 = dstPoint[2]; dstPoint[2] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[2]; srcPoint[2] = srcPoint[3]; srcPoint[3] = tmpPoint32; } if(srcPoint[0].v > srcPoint[2].v){ tmpPoint32 = dstPoint[0]; dstPoint[0] = dstPoint[2]; dstPoint[2] = tmpPoint32; tmpPoint32 = srcPoint[0]; srcPoint[0] = srcPoint[2]; srcPoint[2] = tmpPoint32; } if(srcPoint[1].v > srcPoint[3].v){ tmpPoint32 = dstPoint[1]; dstPoint[1] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[1]; srcPoint[1] = srcPoint[3]; srcPoint[3] = tmpPoint32; } //<>dstPointのソーティング開始 //最も上(同率なら左上の点をきめる) for(i=0; i<3; i++){ for(j=i+1; j<4; j++){ if( (dstPoint[i].v > dstPoint[j].v) || (dstPoint[i].v == dstPoint[j].v) && (dstPoint[i].h <= dstPoint[j].h) ){ tmpPoint32 = dstPoint[i]; dstPoint[i] = dstPoint[j]; dstPoint[j] = tmpPoint32; tmpPoint32 = srcPoint[i]; srcPoint[i] = srcPoint[j]; srcPoint[j] = tmpPoint32; } } } vMin = dstPoint[0].v; vMax = dstPoint[3].v; //左上の線分をきめる //[0]-[1]が左側の線分 if( (dstPoint[1].h-dstPoint[0].h)/(dstPoint[1].v-dstPoint[0].v+0.01) > (dstPoint[2].h-dstPoint[0].h)/(dstPoint[2].v-dstPoint[0].v+0.01) ){ tmpPoint32 = dstPoint[1]; dstPoint[1] = dstPoint[2]; dstPoint[2] = tmpPoint32; tmpPoint32 = srcPoint[1]; srcPoint[1] = srcPoint[2]; srcPoint[2] = tmpPoint32; } if( (dstPoint[1].h-dstPoint[0].h)/(dstPoint[1].v-dstPoint[0].v+0.01) > (dstPoint[3].h-dstPoint[0].h)/(dstPoint[3].v-dstPoint[0].v+0.01) ){ tmpPoint32 = dstPoint[1]; dstPoint[1] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[1]; srcPoint[1] = srcPoint[3]; srcPoint[3] = tmpPoint32; } //右上の線分をきめる //[0]-[3]が右側の線分 if( (dstPoint[2].h-dstPoint[0].h)/(dstPoint[2].v-dstPoint[0].v+0.01) >= (dstPoint[3].h-dstPoint[0].h)/(dstPoint[3].v-dstPoint[0].v+0.01) ){ tmpPoint32 = dstPoint[2]; dstPoint[2] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[2]; srcPoint[2] = srcPoint[3]; srcPoint[3] = tmpPoint32; } //<paramCount <= 6){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } { long h,v,height; double srcH1,srcV1,srcH2,srcV2,sH,sV; double Xad,Yad,XadLeft,YadLeft,XadRight,YadRight; double dstLeft,dstRight,dstLeftAd,dstRightAd; Rect spRect,dpRect; int leftLine1,leftLine2,rightLine1,rightLine2; //高速ルーチン用変数定義 Boolean fastRoutine; int depth; int srcRow,dstRow; PixMapPtr srcPixMap,dstPixMap; unsigned char *srcStartAddr,*dstStartAddr,CKey; unsigned short *srcStartAddr16,*dstStartAddr16,CKey16; unsigned long *srcStartAddr32,*dstStartAddr32,CKey32,savePix; LockPixels(GetGWorldPixMap(srcBuf)); LockPixels(GetGWorldPixMap(dstBuf)); //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //バッファの色深度は8ビット以上専用 //転送元と転送先の色深度が同一であること if((0xc000&(srcBuf->portVersion)) != 0){ depth = (*GetGWorldPixMap(srcBuf))->pixelSize; } if((0xc000&(srcBuf->portVersion)) != 0 && (*GetGWorldPixMap(dstBuf))->pixelSize == depth && depth >= 8 && (mode == srcCopy || mode == transparent)) { fastRoutine = true; } else{ fastRoutine = false; } //高速化ルーチンを使用する if(fastRoutine == true){ //PixMap抽出 srcPixMap = *((CGrafPtr)srcBuf)->portPixMap; dstPixMap = *((CGrafPtr)dstBuf)->portPixMap; //高速転送ルーチンの準備 //rowBytesを抽出 srcRow = (0x3fff & srcPixMap->rowBytes)/(depth/8); dstRow = (0x3fff & dstPixMap->rowBytes)/(depth/8); //PixMapのアドレスを求める srcStartAddr = (unsigned char *) srcPixMap->baseAddr; dstStartAddr = (unsigned char *) dstPixMap->baseAddr; srcStartAddr16 = (unsigned short *)srcStartAddr; dstStartAddr16 = (unsigned short *)dstStartAddr; srcStartAddr32 = (unsigned long *)srcStartAddr; dstStartAddr32 = (unsigned long *)dstStartAddr; //透過あり転送ルーチンの準備 if(mode == transparent){ //透過色データを取得 //OpColor抽出 if(paramPtr->paramCount <= 7){ theOpColor.red = 65535; theOpColor.green = 65535; theOpColor.blue = 65535; } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); } //カラーキーの色で描く! savePix = *dstStartAddr32; GetForeColor(&saveColor); RGBForeColor(&theOpColor); PenNormal(); MoveTo(0,0); Line(0,1); //4つのカラーキー情報を一つのlongに入れる switch(depth){ case 8: CKey = *dstStartAddr; break; case 16: CKey16 = *dstStartAddr16; break; case 32: CKey32 = *dstStartAddr32; break; } *dstStartAddr32 = savePix; RGBForeColor(&saveColor); } } else{ //CopyBitsルーチンを使用する //BitMap抽出 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } } //高速化Lv.2 //描画ルーチン //左線分の転送元の増加率 leftLine1 = 0; leftLine2 = 1; dstLeft = (dstPoint[leftLine1].h); //*16 height = (dstPoint[leftLine2].v-dstPoint[leftLine1].v); if(height == 0) height = 1; dstLeftAd = ((dstPoint[leftLine2].h-dstPoint[leftLine1].h))/height; //*16 XadLeft = ((srcPoint[leftLine2].h-srcPoint[leftLine1].h))/height; //*16 YadLeft = ((srcPoint[leftLine2].v-srcPoint[leftLine1].v))/height; //*16 srcH1 = (srcPoint[leftLine1].h)+(XadLeft/10000.0); //*16 srcV1 = (srcPoint[leftLine1].v)+(YadLeft/10000.0); //*16 //右線分の転送元の増加率 rightLine1 = 0; rightLine2 = 3; dstRight = (dstPoint[rightLine1].h); //*16 height = (dstPoint[rightLine2].v-dstPoint[rightLine1].v); if(height == 0) height = 1; dstRightAd = ((dstPoint[rightLine2].h-dstPoint[rightLine1].h))/height; //*16 XadRight = ((srcPoint[rightLine2].h-srcPoint[rightLine1].h))/height; //*16 YadRight = ((srcPoint[rightLine2].v-srcPoint[rightLine1].v))/height; //*16 srcH2 = (srcPoint[rightLine1].h)+(XadRight/10000.0); //*16 srcV2 = (srcPoint[rightLine1].v)+(YadRight/10000.0); //*16 if(vMax > clipRect.bottom) vMax = clipRect.bottom; //vMin-vMaxまでくり返す for(v=vMin; v>次の線分に移っていれば //>>増加率再計算 //左線分の転送元の増加率 if(dstPoint[leftLine2].v <= v){ //次の線分に移る leftLine1 = leftLine2; leftLine2++; //左線分の増加率の再計算 height = (dstPoint[leftLine2].v-dstPoint[leftLine1].v); if(height == 0) height = 1; XadLeft = ((srcPoint[leftLine2].h-srcPoint[leftLine1].h))/height; //*16 YadLeft = ((srcPoint[leftLine2].v-srcPoint[leftLine1].v))/height; //*16 srcH1 = (srcPoint[leftLine1].h)+(XadLeft/10000.0); //*16 srcV1 = (srcPoint[leftLine1].v)+(YadLeft/10000.0); //*16 dstLeft = (dstPoint[leftLine1].h); //*16 dstLeftAd = ((dstPoint[leftLine2].h-dstPoint[leftLine1].h))/height; //*16 } //右線分の転送元の増加率 if(dstPoint[rightLine2].v <= v){ //次の線分に移る rightLine1 = rightLine2; rightLine2--; //右線分の増加率の再計算 height = (dstPoint[rightLine2].v-dstPoint[rightLine1].v); if(height == 0) height = 1; XadRight = ((srcPoint[rightLine2].h-srcPoint[rightLine1].h))/height; //*16 YadRight = ((srcPoint[rightLine2].v-srcPoint[rightLine1].v))/height; //*16 srcH2 = (srcPoint[rightLine1].h)+(XadRight/10000.0); //*16 srcV2 = (srcPoint[rightLine1].v)+(YadRight/10000.0); //*16 dstRight = (dstPoint[rightLine1].h); //*16 dstRightAd = ((dstPoint[rightLine2].h-dstPoint[rightLine1].h))/height; //*16 }//<<増加率の再計算終了 if(v >= clipRect.top){ //増加率の再計算 height = (dstRight)-(dstLeft); if(height == 0) height = 1; Xad = (srcH2-srcH1)/height; //*16 Yad = (srcV2-srcV1)/height; //*16 sH = srcH1 + Xad/2; //*16 sV = srcV1 + Yad/2; //*16 //clipRectの左端まで飛ばす h=dstLeft; if(h < clipRect.left){ sH += Xad*(clipRect.left - h); sV += Yad*(clipRect.left - h); h = clipRect.left; } if(fastRoutine == true && mode != transparent){ //高速ルーチン使用(透過なし) if(!srcClip){ switch(depth){ case 8: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ dstStartAddr[h+v*dstRow] = srcStartAddr[((int)(sH)+((int)sV)*srcRow)]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 16: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ dstStartAddr16[h+v*dstRow] = srcStartAddr16[((int)(sH)+((int)sV)*srcRow)]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 32: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ dstStartAddr32[h+v*dstRow] = srcStartAddr32[((int)(sH)+((int)sV)*srcRow)]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; } } } else if(fastRoutine == true && mode == transparent){ //高速ルーチン使用(透過あり) if(!srcClip){ switch(depth){ case 8: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ if(srcStartAddr[((int)(sH)+((int)sV)*srcRow)] != CKey) dstStartAddr[h+v*dstRow] = srcStartAddr[((int)(sH)+((int)sV)*srcRow)]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 16: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ if(srcStartAddr16[((int)(sH)+((int)sV)*srcRow)] != CKey16) dstStartAddr16[h+v*dstRow] = srcStartAddr16[((int)(sH)+((int)sV)*srcRow)]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 32: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ if(srcStartAddr32[((int)(sH)+((int)sV)*srcRow)] != CKey32) dstStartAddr32[h+v*dstRow] = srcStartAddr32[((int)(sH)+((int)sV)*srcRow)]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } } } } else{ //CopyBits使用 //左から右までくり返す for(; (hparamCount <= 4){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //srcRect抽出 srcClip = false; ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); isrect = true; } else if(tmpStr[0] == 0){ srcRect = srcBuf->portRect; isrect = true; } else{ //srcPoint*4抽出 c2=1; for( i=0; i<4;){ for(c1=c2; c2<=tmpStr[0]; c2++){ if( tmpStr[c2] == '\0' || tmpStr[c2] == '\n' || tmpStr[c2] == ' ' ) { break; } pointStr[c2-c1+1] = tmpStr[c2]; } pointStr[0] = c2-c1; myStrToPoint(paramPtr,pointStr,&tmpPoint); srcPoint[i].h = tmpPoint.h; srcPoint[i].v = tmpPoint.v; c2++; i++; if(c2>tmpStr[0]) break; } if(i<3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:illegal srcRect"); return; } if(i==3) srcPoint[3] = srcPoint[2]; isrect = false; srcClip = true; srcClipRect = srcBuf->portRect; } if(isrect){ //srcPoint:4に分割 srcPoint[0].h = srcRect.left; srcPoint[0].v = srcRect.top; srcPoint[1].h = srcRect.right; srcPoint[1].v = srcRect.top; srcPoint[2].h = srcRect.left; srcPoint[2].v = srcRect.bottom; srcPoint[3].h = srcRect.right; srcPoint[3].v = srcRect.bottom; } //clipRect抽出 ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&clipRect); myClipRect(&clipRect,&dstBuf->portRect); } else{ clipRect = dstBuf->portRect; } //dstPoint*4抽出 ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); c2=1; for( i=0; i<4; ){ for(c1=c2; c2<=tmpStr[0]; c2++){ if( tmpStr[c2] == '\0' || tmpStr[c2] == '\n' || tmpStr[c2] == ' ' ) { break; } pointStr[c2-c1+1] = tmpStr[c2]; } pointStr[0] = c2-c1; myStrToPoint(paramPtr,pointStr,&tmpPoint); dstPoint[i].h = tmpPoint.h; dstPoint[i].v = tmpPoint.v; c2++; i++; if(c2>tmpStr[0]) break; } if(i<3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:illegal dstRect"); return; } if(i==3) dstPoint[3] = dstPoint[2]; //>>srcPointのソーティング開始 if(srcPoint[0].h > srcPoint[1].h){ tmpPoint32 = dstPoint[0]; dstPoint[0] = dstPoint[1]; dstPoint[1] = tmpPoint32; tmpPoint32 = srcPoint[0]; srcPoint[0] = srcPoint[1]; srcPoint[1] = tmpPoint32; } if(srcPoint[2].h > srcPoint[3].h){ tmpPoint32 = dstPoint[2]; dstPoint[2] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[2]; srcPoint[2] = srcPoint[3]; srcPoint[3] = tmpPoint32; } if(srcPoint[0].v > srcPoint[2].v){ tmpPoint32 = dstPoint[0]; dstPoint[0] = dstPoint[2]; dstPoint[2] = tmpPoint32; tmpPoint32 = srcPoint[0]; srcPoint[0] = srcPoint[2]; srcPoint[2] = tmpPoint32; } if(srcPoint[1].v > srcPoint[3].v){ tmpPoint32 = dstPoint[1]; dstPoint[1] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[1]; srcPoint[1] = srcPoint[3]; srcPoint[3] = tmpPoint32; } if(srcClip){ srcClip = false; for(i=0; i<4; i++){ if(srcClipRect.left > srcPoint[i].h){ srcClip = true; break; } if(srcClipRect.top > srcPoint[i].v){ srcClip = true; break; } if(srcClipRect.right < srcPoint[i].h){ srcClip = true; break; } if(srcClipRect.bottom < srcPoint[i].v){ srcClip = true; break; } } } //<>dstPointのソーティング開始 //最も上(同率なら左上の点をきめる) for(i=0; i<3; i++){ for(j=i+1; j<4; j++){ if( (dstPoint[i].v > dstPoint[j].v) || (dstPoint[i].v == dstPoint[j].v) && (dstPoint[i].h <= dstPoint[j].h) ){ tmpPoint32 = dstPoint[i]; dstPoint[i] = dstPoint[j]; dstPoint[j] = tmpPoint32; tmpPoint32 = srcPoint[i]; srcPoint[i] = srcPoint[j]; srcPoint[j] = tmpPoint32; } } } vMin = dstPoint[0].v; vMax = dstPoint[3].v; //左上の線分をきめる //[0]-[1]が左側の線分 if( (dstPoint[1].h-dstPoint[0].h)/(dstPoint[1].v-dstPoint[0].v+0.01) > (dstPoint[2].h-dstPoint[0].h)/(dstPoint[2].v-dstPoint[0].v+0.01) ){ tmpPoint32 = dstPoint[1]; dstPoint[1] = dstPoint[2]; dstPoint[2] = tmpPoint32; tmpPoint32 = srcPoint[1]; srcPoint[1] = srcPoint[2]; srcPoint[2] = tmpPoint32; } if( (dstPoint[1].h-dstPoint[0].h)/(dstPoint[1].v-dstPoint[0].v+0.01) > (dstPoint[3].h-dstPoint[0].h)/(dstPoint[3].v-dstPoint[0].v+0.01) ){ tmpPoint32 = dstPoint[1]; dstPoint[1] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[1]; srcPoint[1] = srcPoint[3]; srcPoint[3] = tmpPoint32; } //右上の線分をきめる //[0]-[3]が右側の線分 if( (dstPoint[2].h-dstPoint[0].h)/(dstPoint[2].v-dstPoint[0].v+0.01) >= (dstPoint[3].h-dstPoint[0].h)/(dstPoint[3].v-dstPoint[0].v+0.01) ){ tmpPoint32 = dstPoint[2]; dstPoint[2] = dstPoint[3]; dstPoint[3] = tmpPoint32; tmpPoint32 = srcPoint[2]; srcPoint[2] = srcPoint[3]; srcPoint[3] = tmpPoint32; } //<paramCount <= 6){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } { long h,v,height; double srcH1,srcV1,srcH2,srcV2,sH,sV; double Xad,Yad,XadLeft,YadLeft,XadRight,YadRight; double dstLeft,dstRight,dstLeftAd,dstRightAd; Rect spRect,dpRect; int leftLine1,leftLine2,rightLine1,rightLine2; //高速ルーチン用変数定義 Boolean fastRoutine; int depth; int srcRow,dstRow; PixMapPtr srcPixMap,dstPixMap; unsigned char *srcStartAddr,*dstStartAddr,CKey; unsigned short *srcStartAddr16,*dstStartAddr16,CKey16; unsigned long *srcStartAddr32,*dstStartAddr32,CKey32,savePix; //パースペクティブ double leftRate1,leftRate2,rightRate1,rightRate2; double leftRate,rightRate; LockPixels(GetGWorldPixMap(srcBuf)); LockPixels(GetGWorldPixMap(dstBuf)); //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //バッファの色深度は8ビット以上専用 //転送元と転送先の色深度が同一であること if((0xc000&(srcBuf->portVersion)) != 0){ depth = (*GetGWorldPixMap(srcBuf))->pixelSize; } if((0xc000&(srcBuf->portVersion)) != 0 && (*GetGWorldPixMap(dstBuf))->pixelSize == depth && depth >= 8 && (mode == srcCopy || mode == transparent)) { fastRoutine = true; } else{ fastRoutine = false; } //高速化ルーチンを使用する if(fastRoutine == true){ //PixMap抽出 srcPixMap = *((CGrafPtr)srcBuf)->portPixMap; dstPixMap = *((CGrafPtr)dstBuf)->portPixMap; //高速転送ルーチンの準備 //rowBytesを抽出 srcRow = (0x3fff & srcPixMap->rowBytes)/(depth/8); dstRow = (0x3fff & dstPixMap->rowBytes)/(depth/8); //PixMapのアドレスを求める srcStartAddr = (unsigned char *) srcPixMap->baseAddr; dstStartAddr = (unsigned char *) dstPixMap->baseAddr; srcStartAddr16 = (unsigned short *)srcStartAddr; dstStartAddr16 = (unsigned short *)dstStartAddr; srcStartAddr32 = (unsigned long *)srcStartAddr; dstStartAddr32 = (unsigned long *)dstStartAddr; //透過あり転送ルーチンの準備 if(mode == transparent){ //透過色データを取得 //OpColor抽出 if(paramPtr->paramCount <= 7){ theOpColor.red = 65535; theOpColor.green = 65535; theOpColor.blue = 65535; } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); } //カラーキーの色で描く! savePix = *dstStartAddr32; GetForeColor(&saveColor); RGBForeColor(&theOpColor); PenNormal(); MoveTo(0,0); Line(0,1); //4つのカラーキー情報を一つのlongに入れる switch(depth){ case 8: CKey = *dstStartAddr; break; case 16: CKey16 = *dstStartAddr16; break; case 32: CKey32 = *dstStartAddr32; break; } *dstStartAddr32 = savePix; RGBForeColor(&saveColor); } } else{ //CopyBitsルーチンを使用する //BitMap抽出 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } } //高速化Lv.2 //描画ルーチン //左線分の転送元の増加率 leftLine1 = 0; leftLine2 = 1; dstLeft = (dstPoint[leftLine1].h); //*16 height = ((dstPoint[leftLine2].v-dstPoint[leftLine1].v)); if(height == 0) height = 1; dstLeftAd = ((dstPoint[leftLine2].h-dstPoint[leftLine1].h))/height; //*16 XadLeft = ((srcPoint[leftLine2].h-srcPoint[leftLine1].h))/height; //*16 YadLeft = ((srcPoint[leftLine2].v-srcPoint[leftLine1].v))/height; //*16 { double a1,b1,c1,d1,a2,b2,c2,d2; a1 = (dstPoint[(leftLine1+3)%4].h - dstPoint[leftLine1].h) ; b1 = (dstPoint[(leftLine1+3)%4].v - dstPoint[leftLine1].v) ; c1 = (dstPoint[(leftLine2+1)%4].h - dstPoint[leftLine2].h) ; d1 = (dstPoint[(leftLine2+1)%4].v - dstPoint[leftLine2].v) ; a2 = (srcPoint[(leftLine1+3)%4].h - srcPoint[leftLine1].h) ; b2 = (srcPoint[(leftLine1+3)%4].v - srcPoint[leftLine1].v) ; c2 = (srcPoint[(leftLine2+1)%4].h - srcPoint[leftLine2].h) ; d2 = (srcPoint[(leftLine2+1)%4].v - srcPoint[leftLine2].v) ; leftRate1 = sqrt(a1*a1 + b1*b1)/sqrt(a2*a2 + b2*b2); leftRate2 = sqrt(c1*c1 + d1*d1)/sqrt(c2*c2 + d2*d2); leftRate = (leftRate2)/(leftRate1); } //右線分の転送元の増加率 rightLine1 = 0; rightLine2 = 3; dstRight = (dstPoint[rightLine1].h); //*16 height = ((dstPoint[rightLine2].v-dstPoint[rightLine1].v)); if(height == 0) height = 1; dstRightAd = ((dstPoint[rightLine2].h-dstPoint[rightLine1].h))/height; //*16 XadRight = ((srcPoint[rightLine2].h-srcPoint[rightLine1].h))/height; //*16 YadRight = ((srcPoint[rightLine2].v-srcPoint[rightLine1].v))/height; //*16 { double a1,b1,c1,d1,a2,b2,c2,d2; a1 = (dstPoint[(rightLine1+1)%4].h - dstPoint[rightLine1].h) ; b1 = (dstPoint[(rightLine1+1)%4].v - dstPoint[rightLine1].v) ; c1 = (dstPoint[(rightLine2+3)%4].h - dstPoint[rightLine2].h) ; d1 = (dstPoint[(rightLine2+3)%4].v - dstPoint[rightLine2].v) ; a2 = (srcPoint[(rightLine1+1)%4].h - srcPoint[rightLine1].h) ; b2 = (srcPoint[(rightLine1+1)%4].v - srcPoint[rightLine1].v) ; c2 = (srcPoint[(rightLine2+3)%4].h - srcPoint[rightLine2].h) ; d2 = (srcPoint[(rightLine2+3)%4].v - srcPoint[rightLine2].v) ; rightRate1 = sqrt(a1*a1 + b1*b1)/sqrt(a2*a2 + b2*b2); rightRate2 = sqrt(c1*c1 + d1*d1)/sqrt(c2*c2 + d2*d2); rightRate = (rightRate2)/(rightRate1); } if(vMax > clipRect.bottom) vMax = clipRect.bottom; //vMin-vMaxまでくり返す for(v=vMin; v>次の線分に移っていれば //>>増加率再計算 //左線分の転送元の増加率 if(dstPoint[leftLine2].v <= v){ //次の線分に移る leftLine1 = leftLine2; leftLine2++; //左線分の増加率の再計算 height = ((dstPoint[leftLine2].v-dstPoint[leftLine1].v)); if(height == 0) height = 1; XadLeft = ((srcPoint[leftLine2].h-srcPoint[leftLine1].h))/height; //*16 YadLeft = ((srcPoint[leftLine2].v-srcPoint[leftLine1].v))/height; //*16 { double a1,b1,c1,d1,a2,b2,c2,d2; a1 = (dstPoint[(leftLine1+3)%4].h - dstPoint[leftLine1].h) ; b1 = (dstPoint[(leftLine1+3)%4].v - dstPoint[leftLine1].v) ; c1 = (dstPoint[(leftLine2+1)%4].h - dstPoint[leftLine2].h) ; d1 = (dstPoint[(leftLine2+1)%4].v - dstPoint[leftLine2].v) ; a2 = (srcPoint[(leftLine1+3)%4].h - srcPoint[leftLine1].h) ; b2 = (srcPoint[(leftLine1+3)%4].v - srcPoint[leftLine1].v) ; c2 = (srcPoint[(leftLine2+1)%4].h - srcPoint[leftLine2].h) ; d2 = (srcPoint[(leftLine2+1)%4].v - srcPoint[leftLine2].v) ; leftRate1 = sqrt(a1*a1 + b1*b1)/sqrt(a2*a2 + b2*b2); leftRate2 = sqrt(c1*c1 + d1*d1)/sqrt(c2*c2 + d2*d2); leftRate = (leftRate2)/(leftRate1); } dstLeft = (dstPoint[leftLine1].h); //*16 dstLeftAd = ((dstPoint[leftLine2].h-dstPoint[leftLine1].h))/height; //*16 } //右線分の転送元の増加率 if(dstPoint[rightLine2].v <= v){ //次の線分に移る rightLine1 = rightLine2; rightLine2--; //右線分の増加率の再計算 height = ((dstPoint[rightLine2].v-dstPoint[rightLine1].v)); if(height == 0) height = 1; XadRight = ((srcPoint[rightLine2].h-srcPoint[rightLine1].h))/height; //*16 YadRight = ((srcPoint[rightLine2].v-srcPoint[rightLine1].v))/height; //*16 { double a1,b1,c1,d1,a2,b2,c2,d2; a1 = (dstPoint[(rightLine1+1)%4].h - dstPoint[rightLine1].h) ; b1 = (dstPoint[(rightLine1+1)%4].v - dstPoint[rightLine1].v) ; c1 = (dstPoint[(rightLine2+3)%4].h - dstPoint[rightLine2].h) ; d1 = (dstPoint[(rightLine2+3)%4].v - dstPoint[rightLine2].v) ; a2 = (srcPoint[(rightLine1+1)%4].h - srcPoint[rightLine1].h) ; b2 = (srcPoint[(rightLine1+1)%4].v - srcPoint[rightLine1].v) ; c2 = (srcPoint[(rightLine2+3)%4].h - srcPoint[rightLine2].h) ; d2 = (srcPoint[(rightLine2+3)%4].v - srcPoint[rightLine2].v) ; rightRate1 = sqrt(a1*a1 + b1*b1)/sqrt(a2*a2 + b2*b2); rightRate2 = sqrt(c1*c1 + d1*d1)/sqrt(c2*c2 + d2*d2); rightRate = (rightRate2)/(rightRate1); } dstRight = (dstPoint[rightLine1].h); //*16 dstRightAd = ((dstPoint[rightLine2].h-dstPoint[rightLine1].h))/height; //*16 }//<<増加率の再計算終了 if(v >= clipRect.top){ double x1,z1,z2,rx; //増加率の再計算 height = (dstRight)-(dstLeft); if(height == 0) height = 1; x1 = v; z1 = dstPoint[leftLine1].v; z2 = dstPoint[leftLine2].v; //r1 = leftRate1; //r2 = leftRate2; //rx = r1 + ((r2 - r1)>>8) * (((x1-z1))/((z2-z1)>>8)); //rx = r1 + ((r2 - r1)>>8) * (((x1-z1)/((z2-z1)>>16)>>8)); rx = (1) + ((leftRate - (1))) * (((x1-z1)/((z2-z1)))); //srcH1 = srcPoint[leftLine1].h + ((srcPoint[leftLine2].h - srcPoint[leftLine1].h)>>16) * (((((1<<28)/rx)-((1<<28)/r1))<<12)/((1<<24)/r2-(1<<24)/r1)); //srcH1 = srcPoint[leftLine1].h + ((srcPoint[leftLine2].h - srcPoint[leftLine1].h)>>14) * (((((1<<30)/rx)-((1<<30)/r1))<<10)/((1<<26)/r2-(1<<26)/r1)); //srcH1 = srcPoint[leftLine1].h + ((srcPoint[leftLine2].h - srcPoint[leftLine1].h)>>16) * (((((1<<30)/rx)-((1<<30)/r1))<<12)/((1<<26)/r2-(1<<26)/r1)); srcH1 = srcPoint[leftLine1].h + ((srcPoint[leftLine2].h - srcPoint[leftLine1].h)) * (((((1)/rx)-((1)/(1))))/((1)/leftRate-(1)/(1))); srcV1 = srcPoint[leftLine1].v + ((srcPoint[leftLine2].v - srcPoint[leftLine1].v)) * (((((1)/rx)-((1)/(1))))/((1)/leftRate-(1)/(1))); x1 = v; z1 = dstPoint[rightLine1].v; z2 = dstPoint[rightLine2].v; //r1 = rightRate1; //r2 = rightRate2; rx = (1) + ((rightRate - (1))) * (((x1-z1)/((z2-z1)))); srcH2 = srcPoint[rightLine1].h + ((srcPoint[rightLine2].h - srcPoint[rightLine1].h)) * (((((1)/rx)-((1)/(1))))/((1)/rightRate-(1)/(1))); srcV2 = srcPoint[rightLine1].v + ((srcPoint[rightLine2].v - srcPoint[rightLine1].v)) * (((((1)/rx)-((1)/(1))))/((1)/rightRate-(1)/(1))); Xad = (srcH2-srcH1)/height; //*16 Yad = (srcV2-srcV1)/height; //*16 sH = srcH1 + Xad/2; //*16 sV = srcV1 + Yad/2; //*16 //clipRectの左端まで飛ばす h=dstLeft; if(h < clipRect.left){ sH += Xad*(clipRect.left - h); sV += Yad*(clipRect.left - h); h = clipRect.left; } if(fastRoutine == true && mode != transparent){ //高速ルーチン使用(透過なし) if(!srcClip){ switch(depth){ int right; case 8: right = (dstRight)= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ dstStartAddr[h+v*dstRow] = srcStartAddr[(int)(sH)+(int)(sV)*srcRow]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 16: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ dstStartAddr16[h+v*dstRow] = srcStartAddr16[(int)(sH)+(int)(sV)*srcRow]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 32: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ dstStartAddr32[h+v*dstRow] = srcStartAddr32[(int)(sH)+(int)(sV)*srcRow]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; } } } else if(fastRoutine == true && mode == transparent){ //高速ルーチン使用(透過あり) if(!srcClip){ switch(depth){ case 8: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ if(srcStartAddr[(int)(sH)+(int)(sV)*srcRow] != CKey) dstStartAddr[h+v*dstRow] = srcStartAddr[(int)(sH)+(int)(sV)*srcRow]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 16: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ if(srcStartAddr16[(int)(sH)+(int)(sV)*srcRow] != CKey16) dstStartAddr16[h+v*dstRow] = srcStartAddr16[(int)(sH)+(int)(sV)*srcRow]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } break; case 32: //左から右までくり返す for(; (h= srcClipRect.left) && (sH < srcClipRect.right) && (sV >= srcClipRect.top) && (sV < srcClipRect.bottom) ){ if(srcStartAddr32[(int)(sH)+(int)(sV)*srcRow] != CKey32) dstStartAddr32[h+v*dstRow] = srcStartAddr32[(int)(sH)+(int)(sV)*srcRow]; } //次の描画元ピクセル sH += Xad; //16 sV += Yad; //16 } } } } else{ //CopyBits使用 //左から右までくり返す for(; (hparamCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } PCXPtr = GetPCXPtr(paramPtr,false); GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //ぬりつぶす点を抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); StrToPoint(paramPtr,tmpStr,&startPoint); //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&srcBuf->portRect); } else{ srcRect = srcBuf->portRect; } //dstRect抽出 if(paramPtr->paramCount <= 5){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(srcBuf,nil); LockPixels(GetGWorldPixMap(srcBuf)); GetCPixel(startPoint.h,startPoint.v,&color); UnlockPixels(GetGWorldPixMap(srcBuf)); data = Color2Index(&color); //SetGWorld(dstBuf,nil); //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else{ paramPtr->returnValue=PasToZero(paramPtr,"\pError:dstBuffer is not made by NewMask"); dstBitMap = NULL; } if(dstBitMap != NULL){ //塗りつぶし領域のマスクを取得 SeedCFill(srcBitMap,dstBitMap, &srcRect,&dstRect, startPoint.h,startPoint.v, nil,0 ); } SetGWorld(saveGrafPort, saveGDHandle); } //GWorldを削除する void myKillBuffer(XCmdPtr paramPtr){ Str255 tmpStr; int thePlaneNo; PCXDataPtr thePCXPtr; thePCXPtr = GetPCXPtr(paramPtr,true); if(thePCXPtr == NULL){ return; } if(paramPtr->paramCount <= 1){ //uninstall UnsetStdBits(paramPtr); for(thePlaneNo=-3; thePlaneNocTable); //thePCXPtr->cTable = NULL; //DisposeHandle((Handle)GetWRefCon(getWinPtr(WINDOW_NAME))); //SetWRefCon((GrafPtr)getWinPtr(WINDOW_NAME),0); //ウィンドウを閉じる CloseXWindow(paramPtr,getWinPtr(WINDOW_NAME)); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); thePlaneNo = myStrToNum(paramPtr,tmpStr); if(thePlaneNo < 0 || thePlaneNo >= PLANE_MAX){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Buffer ID is out of (0-128)"); return; } //GWorldポインタを取得 xKillBuffer(paramPtr,thePCXPtr,thePlaneNo); } /* */ int xKillBuffer(XCmdPtr paramPtr,PCXDataPtr thePCXPtr,int thePlaneNo) { #pragma unused paramPtr GWorldPtr *screenBufPtr; if(0 <= thePlaneNo) screenBufPtr = &thePCXPtr->gp[thePlaneNo]; if(-1 == thePlaneNo) screenBufPtr = &thePCXPtr->primary; if(-2 == thePlaneNo) screenBufPtr = &thePCXPtr->secondary; if(-3 == thePlaneNo) screenBufPtr = &thePCXPtr->alpha; if(*screenBufPtr == NULL) return-1; if(0 <= thePlaneNo && (0xc000&(*screenBufPtr)->portVersion) == 0) { DisposeRgn((*screenBufPtr)->visRgn); DisposeRgn((*screenBufPtr)->clipRgn); DisposePtr(((GrafPtr)*screenBufPtr)->portBits.baseAddr); DisposePtr((Ptr)*screenBufPtr); //GrafPtr } else { DisposeGWorld(*screenBufPtr); //GWorldPtr } *screenBufPtr = NULL; return 0; } //バッファに文字列を書く void myStringBuffer(XCmdPtr paramPtr){ Point thePoint; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode; int pat; Handle tmpH; Str255 tmpStr,theString; int theSize,theFace; short theFont; FontInfo fInfo; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 4){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //文字列を取得 ZeroToPas(paramPtr,*paramPtr->params[2],theString); //色を取得 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); //描画位置を取得 ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); myStrToPoint(paramPtr,tmpStr,&thePoint); //mode抽出 if(paramPtr->paramCount <= 5){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); mode = GetPatMode(tmpStr); } //HyperCardのfont設定を取り出す tmpH = EvalExpr(paramPtr,"\pthe textFont"); ZeroToPas(paramPtr,*tmpH,tmpStr); GetFNum(tmpStr,&theFont); DisposeHandle(tmpH); tmpH = EvalExpr(paramPtr,"\pthe textSize"); ZeroToPas(paramPtr,*tmpH,tmpStr); theSize = myStrToNum(paramPtr,tmpStr); DisposeHandle(tmpH); tmpH = EvalExpr(paramPtr,"\pthe textStyle"); theFace = textToFace(paramPtr,*tmpH); DisposeHandle(tmpH); //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetForeColor(&saveColor); GetBackColor(&saveBkColor); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } TextFont(theFont); TextSize(theSize); TextMode(mode); TextFace(theFace); GetFontInfo (&fInfo); thePoint.v += fInfo.ascent; MoveTo(thePoint.h,thePoint.v); DrawString(theString); RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); SetGWorld(saveGrafPort, saveGDHandle); } void myInvalRect(XCmdPtr paramPtr){ Rect theRect; Str255 tmpStr; GrafPtr cardPort; CGrafPtr screenBuf; GetPort(&cardPort); theRect = cardPort->portRect; if(paramPtr->paramCount <= 1){ screenBuf = (CGrafPtr)cardPort; theRect = cardPort->portRect; } else{ ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(IsRect(tmpStr)){ myStrToRect(paramPtr,tmpStr,&theRect); }else{ theRect = screenBuf->portRect; } } SetPort((GrafPtr)screenBuf); InvalRect(&theRect); QDDone((GrafPtr)screenBuf); SetPort(cardPort); } //点を描く void mySetPixelBuffer(XCmdPtr paramPtr){ Point thePoint; Rect theRect; RGBColor theColor,theOpColor,saveColor; short mode; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; Handle dstStrH; short dstPointNum, i; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); theColor = myGetColor(paramPtr,tmpStr); /*座標のみ複数行対応(v1.73nt)*/ dstStrH = paramPtr->params[3]; dstPointNum = numOfLinesOfHandle(dstStrH)+1; //mode抽出 if(paramPtr->paramCount <= 4){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[4]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 5){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } PenSize(0,0); PenMode(mode); GetForeColor(&saveColor); RGBForeColor(&theColor); for(i=0;i< dstPointNum ;i++){ GetLineStrOfHandle(tmpStr,dstStrH,i); myStrToPoint(paramPtr,tmpStr,&thePoint); theRect.left = thePoint.h; theRect.top = thePoint.v; theRect.right = thePoint.h+1; theRect.bottom = thePoint.v+1; PaintRect(&theRect); } RGBForeColor(&saveColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //線分を描く void myLineBuffer(XCmdPtr paramPtr){ Point sPoint,ePoint; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode,theWidth; int pat; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 5){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); myStrToPoint(paramPtr,tmpStr,&sPoint); ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); myStrToPoint(paramPtr,tmpStr,&ePoint); //mode抽出 if(paramPtr->paramCount <= 6){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } PenSize(theWidth,theWidth); PenMode(mode); GetBackColor(&saveBkColor); GetForeColor(&saveColor); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } MoveTo(sPoint.h,sPoint.v); LineTo(ePoint.h,ePoint.v); //Line RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //枠付き矩形を描く void myRectBuffer(XCmdPtr paramPtr){ Rect theRect; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode,theWidth; int pat; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; } //mode抽出 if(paramPtr->paramCount <= 6){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetBackColor(&saveBkColor); GetForeColor(&saveColor); ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); PaintRect(&theRect); PenNormal(); } ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); FrameRect(&theRect); } RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //枠付き角丸矩形を描く void myRoundRectBuffer(XCmdPtr paramPtr){ Rect theRect; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode,theWidth; int pat; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; } //mode抽出 if(paramPtr->paramCount <= 6){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetBackColor(&saveBkColor); GetForeColor(&saveColor); ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); PaintRoundRect(&theRect,16,16); PenNormal(); } ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); FrameRoundRect(&theRect,16,16); } RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //枠付き楕円を描く void myOvalBuffer(XCmdPtr paramPtr){ Rect theRect; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode,theWidth; int pat; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; } //mode抽出 if(paramPtr->paramCount <= 6){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetBackColor(&saveBkColor); GetForeColor(&saveColor); ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); PaintOval(&theRect); PenNormal(); } ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); FrameOval(&theRect); } RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //枠付き弧を描く void myArcBuffer(XCmdPtr paramPtr){ Rect theRect; Point angle; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode,theWidth; int pat; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); myStrToPoint(paramPtr,tmpStr,&angle); ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; } //mode抽出 if(paramPtr->paramCount <= 7){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[7]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 8){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[8],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetBackColor(&saveBkColor); GetForeColor(&saveColor); ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); PaintArc(&theRect,angle.h,angle.v); PenNormal(); } ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); FrameArc(&theRect,angle.h,angle.v); } RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //多角形を描く void myPolyAngleBuffer(XCmdPtr paramPtr){ Rect theRect; int NumOfAngles,i; double angle,polyWidth,polyHeight,theH,theV; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode,theWidth; int pat; PolyHandle polyH; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); NumOfAngles = myStrToNum(paramPtr,tmpStr); ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); angle = (myStrToNum(paramPtr,tmpStr) -90.0)*3.14/180.0; ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; } polyWidth = (theRect.right-theRect.left)/2.0; polyHeight = (theRect.bottom-theRect.top)/2.0; theH = (theRect.left+theRect.right)/2.0; theV = (theRect.top+theRect.bottom)/2.0; //Polygonを作る polyH = OpenPoly(); if(polyH == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:More memory please"); return; } MoveTo(theH+polyWidth*cos(angle),theV+polyHeight*sin(angle)); for(i=0; iparamCount <= 8){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[8],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[8]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 9){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[9],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetBackColor(&saveBkColor); GetForeColor(&saveColor); ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); PaintPoly(polyH); PenNormal(); } ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); FramePoly(polyH); } KillPoly(polyH); RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //任意の図形を描く void myPolygonBuffer(XCmdPtr paramPtr){ Point thePoint; int i; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; int mode,theWidth; int pat; PolyHandle polyH; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); //Polygonを作る polyH = OpenPoly(); if(polyH == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:More memory please"); return; } GetLineStrOfHandle(tmpStr,paramPtr->params[5],0); myStrToPoint(paramPtr, tmpStr, &thePoint); MoveTo(thePoint.h, thePoint.v); for(i=1; i<32767; i++){ GetLineStrOfHandle(tmpStr,paramPtr->params[5],i); if(tmpStr[0] == 0) break; if(0 == myStrToPoint(paramPtr, tmpStr, &thePoint)) break; /* Pointではない */ LineTo(thePoint.h, thePoint.v); } ClosePoly(); //mode抽出 if(paramPtr->paramCount <= 6){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 7){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetBackColor(&saveBkColor); GetForeColor(&saveColor); ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); PaintPoly(polyH); PenNormal(); } ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); FramePoly(polyH); } KillPoly(polyH); RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } /* マスクの形状をした図形を描く */ void myPaintMask(XCmdPtr paramPtr){ Str255 tmpStr; Point thePoint; Rect theRect; RGBColor theColor,bkColor,theOpColor,saveColor,saveBkColor; short mode; int theWidth; int pat; GWorldPtr maskBuf,dstBuf; BitMapPtr maskBitMap; RgnHandle rgnH, rectRgnH, tmpRgnH; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //マスクPlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); maskBuf = myGetPlane(paramPtr,tmpStr); if(maskBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //BitMapPtrを取得 if((0xc000&(maskBuf->portVersion)) == 0) maskBitMap = &((GrafPtr)maskBuf)->portBits; else maskBitMap = (BitMap*)*((CGrafPtr)maskBuf)->portPixMap; //BitmapToRegion rgnH = NewRgn(); if(noErr != BitMapToRegion(rgnH, maskBitMap)) { DisposeRgn(rgnH); paramPtr->returnValue=PasToZero(paramPtr,"\pError:bitmap to region failure"); return; } //regionの移動、クリッピング ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); OffsetRgn(rgnH, theRect.left, theRect.top); //移動 rectRgnH = NewRgn(); RectRgn(rectRgnH, &theRect); tmpRgnH = NewRgn(); UnionRgn(rgnH, rectRgnH, tmpRgnH); //クリッピング DisposeRgn(rectRgnH); DisposeRgn(rgnH); rgnH = tmpRgnH; } else{ myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRgn(rgnH, thePoint.h, thePoint.v); //移動 } //ペンの太さ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); theWidth = myStrToNum(paramPtr,tmpStr); //mode抽出 if(paramPtr->paramCount <= 7){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[6]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetPatMode(tmpStr); } //OpColor抽出 if(paramPtr->paramCount <= 8){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[8],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetBackColor(&saveBkColor); GetForeColor(&saveColor); ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); PaintRgn(rgnH); PenNormal(); } ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(tmpStr[0] != 0){ myGetColor2(paramPtr,tmpStr,&theColor,&bkColor,&pat); RGBForeColor(&theColor); if(pat > 0) { Pattern patRsrc; GetIndPattern(&patRsrc, 128, pat); PenPat(&patRsrc); RGBBackColor(&bkColor); } PenSize(theWidth,theWidth); PenMode(mode); FrameRgn(rgnH); } DisposeRgn(rgnH); RGBForeColor(&saveColor); RGBBackColor(&saveBkColor); PenNormal(); SetGWorld(saveGrafPort, saveGDHandle); } //ピクチャフォントで文字列描画 void myPictureFontBuffer(XCmdPtr paramPtr){ Str255 tmpStr; Ptr theString; Rect srcRect,dstRect,tmpRect; Point dstPoint; RGBColor theOpColor; short mode; short width,height; GWorldPtr srcBuf,dstBuf,cardPort; CGrafPtr saveGrafPort; GDHandle saveGDHandle; BitMapPtr srcBitMap,dstBitMap; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } GetPort((GrafPtr*)&cardPort); //転送元PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); if(srcBuf == NULL) return; //転送先PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL) return; //文字列へのポインタ取得 theString = *paramPtr->params[3]; //転送元矩形を取得 srcRect = srcBuf->portRect; //描画位置を取得 if(paramPtr->paramCount <= 4){ dstPoint.h = 0; dstPoint.v = 0; } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); myStrToPoint(paramPtr,tmpStr,&dstPoint); } //mode抽出 if(paramPtr->paramCount <= 5){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[5]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } width = (srcRect.right-srcRect.left)/8; height = (srcRect.bottom-srcRect.top)/12; dstRect.left = dstPoint.h; dstRect.right = dstPoint.h +width; dstRect.top = dstPoint.v; dstRect.bottom = dstPoint.v +height; //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; //上過ぎなら改行まで飛ばす while(dstRect.bottom < dstBuf->portRect.top){ while(*theString != 13 && *theString != 0){ theString++; } dstRect.top += height; dstRect.bottom += height; if(*theString == 0) break; } while(*theString != 0){ if(*theString >= 32){ if(dstRect.right > dstBuf->portRect.left){ tmpRect.left = width*((*theString)%8); tmpRect.right = tmpRect.left +width; tmpRect.top = height*((*theString -32)/8); tmpRect.bottom = tmpRect.top +height; //CopyBitsによる転送 CopyBits2(srcBitMap,dstBitMap, &tmpRect,&dstRect,mode,nil ); } dstRect.left += width; dstRect.right += width; //右端越えていたら改行まで飛ばす if(dstRect.left > dstBuf->portRect.right){ do{ theString++; }while(*theString != 13 && *theString != 0); continue; } } else if(*theString == 13){ //return code dstRect.left = dstPoint.h; dstRect.right = dstPoint.h +width; dstRect.top += height; dstRect.bottom += height; //下越えていたら終了 if(dstRect.top > dstBuf->portRect.bottom) break; } if(*theString != 0)theString++; } SetGWorld(saveGrafPort, saveGDHandle); } /* スプライト */ void mySetSprite(XCmdPtr paramPtr){ PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,true); tSprite *spr; GWorldPtr plane; Point p; int i; Str255 tmpStr; unsigned char uc; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); //スプライトNo.抽出 i = myStrToNum(paramPtr,tmpStr); if(i<0 || i>SPRITE_MAX){ paramPtr->returnValue=PasToZero(paramPtr,"\pError: sprite number is out of scope"); return; } spr = &thePCXPtr->sprite[i]; uc = **paramPtr->params[3]; //スプライト文字抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); plane = myGetPlane(paramPtr,tmpStr); spr->sprite[uc].plane = myStrToNum(paramPtr,tmpStr); //spr->sprite[uc].mask = atoi(*paramPtr->params[1.5]); //マスクPlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&spr->sprite[uc].rect); } else{ spr->sprite[uc].rect = plane->portRect; } //offset if(paramPtr->params[5]==NULL){ p.h = 0; p.v = 0; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); myStrToPoint(paramPtr,tmpStr,&p); } spr->sprite[uc].oh = p.h; spr->sprite[uc].ov = p.v; //width if(paramPtr->paramCount <= 6){ spr->sprite[uc].width = spr->sprite[uc].rect.right - spr->sprite[uc].rect.left; } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); spr->sprite[uc].width = myStrToNum(paramPtr,tmpStr); } } /* スプライト取得 */ void myGetSprite(XCmdPtr paramPtr){ PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,true); tSprite *spr; int i; Str255 tmpStr; Str32 numStr; unsigned char uc; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); //スプライトNo.抽出 i = myStrToNum(paramPtr,tmpStr); if(i<0 || i>SPRITE_MAX){ paramPtr->returnValue=PasToZero(paramPtr,"\pError: sprite number is out of scope"); return; } spr = &thePCXPtr->sprite[i]; uc = **paramPtr->params[2]; //スプライト文字抽出 //68K XCMDでsprintfが使えない #if 0 printf((char *)tmpStr+1,"%d,\"%d,%d,%d,%d\",\"%d,%d\",%d", spr->sprite[uc].plane, spr->sprite[uc].rect.left, spr->sprite[uc].rect.top, spr->sprite[uc].rect.right, spr->sprite[uc].rect.bottom, spr->sprite[uc].oh, spr->sprite[uc].ov, spr->sprite[uc].width ); #else tmpStr[1] = '\0'; NumToStr(paramPtr, spr->sprite[uc].plane, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); strcat((char *)tmpStr+1, ",\""); NumToStr(paramPtr, spr->sprite[uc].rect.left, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); strcat((char *)tmpStr+1, ","); NumToStr(paramPtr, spr->sprite[uc].rect.top, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); strcat((char *)tmpStr+1, ","); NumToStr(paramPtr, spr->sprite[uc].rect.right, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); strcat((char *)tmpStr+1, ","); NumToStr(paramPtr, spr->sprite[uc].rect.bottom, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); strcat((char *)tmpStr+1, "\",\""); NumToStr(paramPtr, spr->sprite[uc].oh, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); strcat((char *)tmpStr+1, ","); NumToStr(paramPtr, spr->sprite[uc].ov, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); strcat((char *)tmpStr+1, "\","); NumToStr(paramPtr, spr->sprite[uc].width, numStr); strcat((char *)tmpStr+1, (char *)numStr+1); #endif tmpStr[0] = strlen((char *)tmpStr+1); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } void myDrawSprite(XCmdPtr paramPtr) { PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,true); GWorldPtr src, plane; RGBColor theOpColor; tSprite *spr; Rect *srcr, dstr; Point p; CGrafPtr saveGrafPort; GDHandle saveGDHandle; unsigned char uc; int i; Str255 tmpStr; short mode; BitMapPtr srcBitMap,dstBitMap; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //dstPlane抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); plane = myGetPlane(paramPtr,tmpStr); if(plane == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer is not exist"); return; } ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); //スプライトNo.抽出 i = myStrToNum(paramPtr,tmpStr); if(i<0 || i>SPRITE_MAX){ paramPtr->returnValue=PasToZero(paramPtr,"\pError: sprite number is out of scope"); return; } spr = &thePCXPtr->sprite[i]; uc = **paramPtr->params[3]; //スプライト文字抽出 //dstRect if(paramPtr->params[4] == NULL){ dstr = plane->portRect; OffsetRect(&dstr, -dstr.left, -dstr.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstr); } else{ dstr = spr->sprite[uc].rect; OffsetRect(&dstr, -dstr.left, -dstr.top); OffsetRect(&dstr, -dstr.right/2, -dstr.bottom/2); myStrToPoint(paramPtr,tmpStr,&p); OffsetRect(&dstr,p.h,p.v); } } OffsetRect(&dstr, spr->sprite[uc].oh, spr->sprite[uc].ov); //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(plane, nil); //mode抽出 if(paramPtr->params[5] == NULL){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[5]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } src = thePCXPtr->gp[spr->sprite[(int)uc].plane]; if(!src){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Sprite hasn\'t set"); return; } srcr = &spr->sprite[(int)uc].rect; //BitMapPtrを取得 if((0xc000&(src->portVersion)) == 0) srcBitMap = &((GrafPtr)src)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)src)->portPixMap; if((0xc000&(plane->portVersion)) == 0) dstBitMap = &((GrafPtr)plane)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)plane)->portPixMap; CopyBits2(srcBitMap, dstBitMap, srcr, &dstr, mode, NULL ); SetGWorld(saveGrafPort, saveGDHandle); } void myStringSprite(XCmdPtr paramPtr) { PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,true); GWorldPtr src, plane; RGBColor theOpColor; tSprite *spr; Rect *srcr, dr, dstr, dstr2; Point p; CGrafPtr saveGrafPort; GDHandle saveGDHandle; int i; Str255 tmpStr; short mode; unsigned char *string; BitMapPtr srcBitMap,dstBitMap; if(paramPtr->paramCount <= 3){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //dstPlane抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); plane = myGetPlane(paramPtr,tmpStr); if(plane == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer is not exist"); return; } ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); //スプライトNo.抽出 i = myStrToNum(paramPtr,tmpStr); if(i<0 || i>SPRITE_MAX){ paramPtr->returnValue=PasToZero(paramPtr,"\pError: sprite number is out of scope"); return; } spr = &thePCXPtr->sprite[i]; string = (unsigned char *)*paramPtr->params[3]; //スプライト文字抽出 //dstRect if(paramPtr->params[4]==NULL){ dr = plane->portRect; OffsetRect(&dr, -dr.left, -dr.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dr); ClipRect(&dr); } else{ dr = plane->portRect; OffsetRect(&dr, -dr.left, -dr.top); myStrToPoint(paramPtr,tmpStr,&p); OffsetRect(&dr,p.h,p.v); } } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(plane, nil); //mode抽出 if(paramPtr->params[5]==NULL){ mode = srcCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); if(StringMatch(paramPtr,"\p with dithering",*paramPtr->params[5]) != nil){ mode = ditherCopy; tmpStr[0] -= 15; } else mode = 0; mode |= GetMode(tmpStr); } //OpColor抽出 if(paramPtr->paramCount <= 6){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); if(mode == blend || mode == addPin || mode == subPin) OpColor(&theOpColor); else if(mode == transparent) RGBBackColor(&theOpColor); else RGBForeColor(&theOpColor); } if(*string == '\0') return; dstr.left = dr.left; dstr.top = dr.top; //BitMapPtrを取得 if((0xc000&(plane->portVersion)) == 0) dstBitMap = &((GrafPtr)plane)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)plane)->portPixMap; while(*string != '\0'){ src = thePCXPtr->gp[spr->sprite[(int)*string].plane]; srcr = &spr->sprite[(int)*string].rect; dstr.right = dstr.left + (srcr->right - srcr->left); dstr.bottom = dstr.top + (srcr->bottom - srcr->top); dstr2 = dstr; SetRect(&dstr2, (dstr2.left+dstr2.right)/2-(spr->sprite[(int)*string].width)/2, dstr2.top, (dstr2.left+dstr2.right)/2+(spr->sprite[(int)*string].width+1)/2, dstr2.bottom); OffsetRect(&dstr2, spr->sprite[(int)*string].oh, spr->sprite[(int)*string].ov); if(src){ //BitMapPtrを取得 if((0xc000&(src->portVersion)) == 0) srcBitMap = &((GrafPtr)src)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)src)->portPixMap; CopyBits2(srcBitMap, dstBitMap, srcr, &dstr2, mode, NULL ); } if(*string == '\n'){ dstr.left = dr.left; dstr.top = dstr.bottom; } else{ dstr.left += spr->sprite[(int)*string].width; } string++; } ClipRect(&plane->portRect); SetGWorld(saveGrafPort, saveGDHandle); } //GWorldポインタを返す void getGWorldPort(XCmdPtr paramPtr){ Str255 tmpStr; GWorldPtr screenBuf; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //GWorldポインタを返す NumToStr(paramPtr,(unsigned long)screenBuf,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } //読み込んだGWorldポインタをバッファに void setGWorldPort(XCmdPtr paramPtr){ int thePlaneNo; Str255 tmpStr; GWorldPtr screenBuf; PCXDataPtr thePCXPtr; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); thePlaneNo = myStrToNum(paramPtr,tmpStr); if(thePlaneNo < 0 || thePlaneNo >= PLANE_MAX){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Buffer ID is out of (0-128)"); return; } //すでにバッファがあるならエラー if(GetPCXPtr(paramPtr,false)->gp[thePlaneNo] != NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:This Buffer is exist"); return; } //GWorldポインタを取得 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); screenBuf = (GWorldPtr)myStrToNum(paramPtr,tmpStr); //GWorldPtrを設定 thePCXPtr = GetPCXPtr(paramPtr,false); if(thePCXPtr == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Cannot create new window"); return; } thePCXPtr->gp[thePlaneNo] = screenBuf; } /* ウィンドウPICTの設定。パレットとかに使えるぞ */ void setWindowPict(XCmdPtr paramPtr){ Str255 tmpStr; GWorldPtr srcBuf; CGrafPtr dstBuf; PicHandle thePict; Rect srcRect,dstRect; Point thePoint; OpenCPicParams picParam; BitMapPtr srcBitMap, dstBitMap; //srcPlane抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); srcBuf = myGetPlane(paramPtr,tmpStr); //dstPlane抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer is not exist"); return; } //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(*paramPtr->params[3] && IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); } else{ srcRect = srcBuf->portRect; } myClipRect(&srcRect,&srcRect); //dstRect抽出 if(paramPtr->paramCount <= 4){ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&dstRect); } else{ dstRect = srcRect; OffsetRect(&dstRect,-dstRect.left,-dstRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&dstRect,thePoint.h,thePoint.v); } } thePict = GetWindowPic((GrafPtr)dstBuf); if(thePict != NULL) KillPicture(thePict); if(srcBuf == NULL){ SetWindowPic((GrafPtr)dstBuf, NULL); return; //消したら帰る } picParam.srcRect = dstRect; OffsetRect(&picParam.srcRect, -picParam.srcRect.left, -picParam.srcRect.top); picParam.hRes = 72<<16; picParam.vRes = 72<<16; picParam.version = -2; picParam.reserved1 = 0; picParam.reserved2 = 0; thePict = OpenCPicture(&picParam); //ClipRect(&srcRect); //念のため入れたほうがいいらしい。新居さんの本より。 //BitMapPtrを取得 if((0xc000&(srcBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)srcBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)srcBuf)->portPixMap; if((0xc000&(dstBuf->portVersion)) == 0) dstBitMap = &((GrafPtr)dstBuf)->portBits; else dstBitMap = (BitMap*)*((CGrafPtr)dstBuf)->portPixMap; CopyBits2(srcBitMap,dstBitMap,&srcRect,&dstRect,srcCopy,0); (**thePict).picFrame = dstRect; // 念のため入れたほうがいいらしい。新居さんの本より。 ClosePicture(); //ウィンドウにPICTを設定 SetWindowPic((GrafPtr)dstBuf,thePict); } /* ForeColor */ void mySetForeColor(XCmdPtr paramPtr){ Str255 tmpStr; RGBColor color; CGrafPtr dstBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; //dstPlane抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer is not exist"); return; } //Color抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); color = myGetColor(paramPtr,tmpStr); GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); RGBForeColor(&color); //ForeColor変更 SetGWorld(saveGrafPort, saveGDHandle); } /* BackColor */ void mySetBackColor(XCmdPtr paramPtr){ Str255 tmpStr; RGBColor color; CGrafPtr dstBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; //dstPlane抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer is not exist"); return; } //Color抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); color = myGetColor(paramPtr,tmpStr); GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); RGBBackColor(&color); //BackColor変更 SetGWorld(saveGrafPort, saveGDHandle); } /* 画像で同じ色のドットを探して、位置を返す */ #define _abs(a) ((a)>=0 ? (a):-(a)) void mySeekColor(XCmdPtr paramPtr){ int x,y; int xx, yy; int diff,it; int thePlaneNo; int i; Str255 tmpStr, resultStr; RGBColor SeekColor, theColor; CGrafPtr dstBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; //dstPlane抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); thePlaneNo = myStrToNum(paramPtr,tmpStr); dstBuf = myGetPlane(paramPtr,tmpStr); if(dstBuf == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:buffer is not exist"); return; } //Color抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); SeekColor = myGetColor(paramPtr,tmpStr); GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(dstBuf, nil); if(thePlaneNo >= 0 && thePlaneNo < PLANE_MAX){ LockPixels(GetGWorldPixMap(dstBuf)); } /* 検索 */ xx = 0; yy = 0; diff = 0x7fffffff; for(y=dstBuf->portRect.top; yportRect.bottom; y++) { for(x=dstBuf->portRect.left; xportRect.right; x++) { GetCPixel(x, y, &theColor); it = _abs((int)theColor.red - (int)SeekColor.red); it += _abs((int)theColor.green - (int)SeekColor.green); it += _abs((int)theColor.blue - (int)SeekColor.blue); if(it < diff) { xx = x; yy = y; diff = it; if(diff == 0) break; } } if(diff == 0) break; } if(thePlaneNo >= 0 && thePlaneNo < PLANE_MAX){ UnlockPixels(GetGWorldPixMap(dstBuf)); } SetGWorld(saveGrafPort, saveGDHandle); /* 出力文字列作成 */ resultStr[0] = 0; NumToStr(paramPtr, diff, tmpStr); /* diff */ for(i=1;i<=tmpStr[0];i++){ resultStr[resultStr[0]+1]=tmpStr[i]; resultStr[0]++; } resultStr[resultStr[0]+1]=' '; resultStr[0]++; NumToStr(paramPtr, xx, tmpStr); /* xx */ for(i=1;i<=tmpStr[0];i++){ resultStr[resultStr[0]+1]=tmpStr[i]; resultStr[0]++; } resultStr[resultStr[0]+1]=','; resultStr[0]++; NumToStr(paramPtr, yy, tmpStr); /* yy */ for(i=1;i<=tmpStr[0];i++){ resultStr[resultStr[0]+1]=tmpStr[i]; resultStr[0]++; } paramPtr->returnValue=PasToZero(paramPtr,resultStr); } //点の色を取得 void myGetPixelBuffer(XCmdPtr paramPtr){ Point thePoint; RGBColor theColor; int thePlaneNo,i; Str255 tmpStr,colStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); StrToPoint(paramPtr,tmpStr,&thePoint); //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); thePlaneNo = myStrToNum(paramPtr,tmpStr); //PlaneNo.抽出 screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; if(thePoint.h<0 || thePoint.v<0 || thePoint.h >= screenBuf->portRect.right || thePoint.v >= screenBuf->portRect.bottom){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:out of size"); return; } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); if(thePlaneNo >= 0 && thePlaneNo < PLANE_MAX){ LockPixels(GetGWorldPixMap(screenBuf)); GetCPixel(thePoint.h,thePoint.v,&theColor); UnlockPixels(GetGWorldPixMap(screenBuf)); }else{ GetCPixel(thePoint.h,thePoint.v,&theColor); } SetGWorld(saveGrafPort, saveGDHandle); //色を返す NumToStr(paramPtr,theColor.red,colStr); NumToStr(paramPtr,theColor.green,tmpStr); colStr[colStr[0]+1]=','; colStr[0]++; for(i=1;i<=tmpStr[0];i++){ colStr[colStr[0]+i]=tmpStr[i]; } colStr[0]+=tmpStr[0]; NumToStr(paramPtr,theColor.blue,tmpStr); colStr[colStr[0]+1]=','; colStr[0]++; for(i=1;i<=tmpStr[0];i++){ colStr[colStr[0]+i]=tmpStr[i]; } colStr[0]+=tmpStr[0]; paramPtr->returnValue=PasToZero(paramPtr,colStr); } //マスクからそのマスクを囲む最小の矩形を返す void myGetRgnBounds(XCmdPtr paramPtr){ OSErr status; RgnHandle rgnH; GWorldPtr screenBuf; BitMapPtr srcBitMap; Str255 rectStr, tmpStr; Rect r; int i; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); //BitMapPtrを取得 if((0xc000&(screenBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)screenBuf)->portBits; else{ paramPtr->returnValue=PasToZero(paramPtr,"\pError: port is not mask"); return; } rgnH = NewRgn(); status = BitMapToRegion(rgnH, srcBitMap); //リージョンが使えるなら、リージョンを使おう if(noErr != status){ paramPtr->returnValue=PasToZero(paramPtr,"\pError: convert to region failure"); return; } r = (*rgnH)->rgnBBox; DisposeRgn(rgnH); //矩形を返す NumToStr(paramPtr,r.left,rectStr); NumToStr(paramPtr,r.top,tmpStr); rectStr[rectStr[0]+1]=','; rectStr[0]++; for(i=1;i<=tmpStr[0];i++){ rectStr[rectStr[0]+i]=tmpStr[i]; } rectStr[0]+=tmpStr[0]; NumToStr(paramPtr,r.right,tmpStr); rectStr[rectStr[0]+1]=','; rectStr[0]++; for(i=1;i<=tmpStr[0];i++){ rectStr[rectStr[0]+i]=tmpStr[i]; } rectStr[0]+=tmpStr[0]; NumToStr(paramPtr,r.bottom,tmpStr); rectStr[rectStr[0]+1]=','; rectStr[0]++; for(i=1;i<=tmpStr[0];i++){ rectStr[rectStr[0]+i]=tmpStr[i]; } rectStr[0]+=tmpStr[0]; paramPtr->returnValue=PasToZero(paramPtr,rectStr); } //PICTリソースとして保存する void saveAsPictRsrc(XCmdPtr paramPtr,ResType aResType){ int picId; Str255 tmpStr; GWorldPtr screenBuf; GrafPtr cardPort; PicHandle thePict; Rect srcRect; OpenCPicParams picParam; BitMapPtr srcBitMap; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&screenBuf->portRect); } else{ srcRect = screenBuf->portRect; } //ID抽出 if(**(paramPtr->params[3]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); picId = myStrToNum(paramPtr,tmpStr); thePict = (PicHandle)GetResource(aResType,picId); if(thePict != NULL){ // paramPtr->returnValue=PasToZero(paramPtr,"\pError:This PICT ID is used"); // return; RemoveResource((Handle)thePict); } }else{ picId = UniqueID(aResType); } if(picId <= 0 || picId >= 32768){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:bad id"); return; } //BitMapPtrを取得 if((0xc000&(screenBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)screenBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)screenBuf)->portPixMap; GetPort(&cardPort); picParam.srcRect = srcRect; OffsetRect(&picParam.srcRect, -picParam.srcRect.left, -picParam.srcRect.top); picParam.hRes = 72<<16; picParam.vRes = 72<<16; picParam.version = -2; picParam.reserved1 = 0; picParam.reserved2 = 0; thePict = OpenCPicture(&picParam); ClipRect(&srcRect); //念のため入れたほうがいいらしい。新居さんの本より。 CopyBits2(srcBitMap, &cardPort->portBits, &srcRect,&srcRect,srcCopy,nil ); (**thePict).picFrame = srcRect; // 念のため入れたほうがいいらしい。新居さんの本より。 ClosePicture(); ClipRect(&cardPort->portRect); HLock((Handle)thePict); //ロックして if(paramPtr->paramCount > 4 && **paramPtr->params[4] != 0) ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); else tmpStr[0] = 0; AddResource( (Handle)thePict, aResType, picId, tmpStr); if(ResError() == noErr){ WriteResource( (Handle)thePict); DetachResource((Handle)thePict); HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する if(**(paramPtr->params[3]) == 0){ NumToStr(paramPtr,picId,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } }else{ HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する paramPtr->returnValue=PasToZero(paramPtr,"\pError:Some problem at saving PICT resource"); return; } } //マスク付きPICTリソースとして保存する void saveAsMaskPictRsrc(XCmdPtr paramPtr,ResType aResType){ int picId; Str255 tmpStr; GWorldPtr dataBuf, maskBuf; GrafPtr cardPort; PicHandle thePict; Rect srcRect; OpenCPicParams picParam; BitMapPtr dataBitMap, maskBitMap; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); dataBuf = myGetPlane(paramPtr,tmpStr); if(dataBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); maskBuf = myGetPlane(paramPtr,tmpStr); if(maskBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&dataBuf->portRect); myClipRect(&srcRect,&maskBuf->portRect); } else{ srcRect = dataBuf->portRect; myClipRect(&srcRect,&maskBuf->portRect); } //ID抽出 if(**(paramPtr->params[4]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); picId = myStrToNum(paramPtr,tmpStr); thePict = (PicHandle)GetResource(aResType,picId); if(thePict != NULL){ // paramPtr->returnValue=PasToZero(paramPtr,"\pError:This PICT ID is used"); // return; RemoveResource((Handle)thePict); } }else{ picId = UniqueID(aResType); } if(picId <= 0 || picId >= 32768){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:bad id"); return; } //BitMapPtrを取得 if((0xc000&(dataBuf->portVersion)) == 0) dataBitMap = &((GrafPtr)dataBuf)->portBits; else dataBitMap = (BitMap*)*((CGrafPtr)dataBuf)->portPixMap; if((0xc000&(maskBuf->portVersion)) == 0) maskBitMap = &((GrafPtr)maskBuf)->portBits; else maskBitMap = (BitMap*)*((CGrafPtr)maskBuf)->portPixMap; GetPort(&cardPort); picParam.srcRect = srcRect; OffsetRect(&picParam.srcRect, -picParam.srcRect.left, -picParam.srcRect.top); picParam.hRes = 72<<16; picParam.vRes = 72<<16; picParam.version = -2; picParam.reserved1 = 0; picParam.reserved2 = 0; thePict = OpenCPicture(&picParam); ClipRect(&srcRect); //念のため入れたほうがいいらしい。新居さんの本より。 CopyBits2(maskBitMap, &cardPort->portBits, &srcRect,&srcRect,srcBic,nil ); CopyBits2(dataBitMap, &cardPort->portBits, &srcRect,&srcRect,srcOr,nil ); (**thePict).picFrame = srcRect; // 念のため入れたほうがいいらしい。新居さんの本より。 ClosePicture(); ClipRect(&cardPort->portRect); HLock((Handle)thePict); //ロックして if(paramPtr->paramCount > 5 && **paramPtr->params[5] != 0) ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); else tmpStr[0] = 0; AddResource( (Handle)thePict, aResType, picId, tmpStr); if(ResError() == noErr){ WriteResource( (Handle)thePict); DetachResource((Handle)thePict); HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する if(**(paramPtr->params[4]) == 0){ NumToStr(paramPtr,picId,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } }else{ HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する paramPtr->returnValue=PasToZero(paramPtr,"\pError:Some problem at saving PICT resource"); return; } } #if 0 //どうもうまくいかない //マスク付でカードピクチャを保存 void saveCardPict(XCmdPtr paramPtr){ int picId; Str255 tmpStr; GrafPtr cardPort; PicHandle thePict; Rect srcRect; OpenCPicParams picParam; BitMap maskBitMap,dataBitMap; GetPort(&cardPort); //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&cardPort->portRect); } else{ srcRect = cardPort->portRect; } //ID抽出 if(**(paramPtr->params[2]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); picId = myStrToNum(paramPtr,tmpStr); thePict = (PicHandle)GetResource('PICT',picId); if(thePict != NULL){ // paramPtr->returnValue=PasToZero(paramPtr,"\pError:This PICT ID is used"); // return; RemoveResource((Handle)thePict); } }else{ for(picId = 1000;picId < 32768;picId++){ thePict = (PicHandle)GetResource('PICT',picId); if(thePict == NULL) break; ReleaseResource((Handle)thePict); } } if(picId <= 0 || picId >= 32768){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:bad id"); return; } //BitMapPtrを取得 GetMaskAndData(paramPtr,&maskBitMap,&dataBitMap); picParam.srcRect = srcRect; OffsetRect(&picParam.srcRect, -picParam.srcRect.left, -picParam.srcRect.top); picParam.hRes = 72<<16; picParam.vRes = 72<<16; picParam.version = -2; picParam.reserved1 = 0; picParam.reserved2 = 0; thePict = OpenCPicture(&picParam); ClipRect(&srcRect); //念のため入れたほうがいいらしい。新居さんの本より。 CopyBits2(&maskBitMap, &cardPort->portBits, &srcRect,&srcRect,srcBic,nil ); CopyBits2(&dataBitMap, &cardPort->portBits, &srcRect,&srcRect,srcOr,nil ); (**thePict).picFrame = srcRect; // 念のため入れたほうがいいらしい。新居さんの本より。 ClosePicture(); ClipRect(&cardPort->portRect); HLock((Handle)thePict); //ロックして if(paramPtr->paramCount > 3 && **paramPtr->params[3] != 0) ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); else tmpStr[0] = 0; AddResource( (Handle)thePict, 'PICT', picId, tmpStr); if(ResError() == noErr){ WriteResource( (Handle)thePict); DetachResource((Handle)thePict); HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する if(**(paramPtr->params[2]) == 0){ NumToStr(paramPtr,picId,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } }else{ HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する paramPtr->returnValue=PasToZero(paramPtr,"\pError:Some problem at saving PICT resource"); return; } } #endif //マスク付きcicnリソースとして保存する void saveAsCicnRsrc(XCmdPtr paramPtr){ int picId; Str255 tmpStr; GWorldPtr dataBuf, maskBuf; CIconHandle theCicn; Rect srcRect, dstRect; int width, height; int depth, outDepth; int pixRowBytes, bitRowBytes; int ctIndex; unsigned short useTable[256]; int i, j; Ptr p; unsigned short *s; unsigned long pixValue; Ptr baseAddr; PixMapHandle dataPixMap; BitMapPtr maskBitMap; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); dataBuf = myGetPlane(paramPtr,tmpStr); if(dataBuf == NULL) return; ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); maskBuf = myGetPlane(paramPtr,tmpStr); //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&dataBuf->portRect); myClipRect(&srcRect,&maskBuf->portRect); } else{ srcRect = dataBuf->portRect; myClipRect(&srcRect,&maskBuf->portRect); } dstRect = srcRect; OffsetRect(&dstRect, -dstRect.left, -dstRect.top); //ID抽出 if(**(paramPtr->params[4]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); picId = myStrToNum(paramPtr,tmpStr); theCicn = (CIconHandle)GetResource('cicn',picId); if(theCicn != NULL){ // paramPtr->returnValue=PasToZero(paramPtr,"\pError:This PICT ID is used"); // return; RemoveResource((Handle)theCicn); } }else{ picId = UniqueID('cicn'); } if(picId <= 0 || picId >= 32768){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:bad id"); return; } //BitMapPtrを取得 dataPixMap = GetGWorldPixMap(dataBuf); if(maskBuf) { if((0xc000&(maskBuf->portVersion)) == 0) maskBitMap = &((GrafPtr)maskBuf)->portBits; else maskBuf = NULL; } //Cicnの準備 width = srcRect.right - srcRect.left; height = srcRect.bottom - srcRect.top; depth = (*dataPixMap)->pixelSize; bitRowBytes = (width+7)/8; switch(depth) { case 1: ctIndex = 0; break; case 2: ctIndex = 4; break; case 4: ctIndex = 16; break; case 8: ctIndex = 256; break; default: ctIndex = 1; break; } //ここでPixMapをLockする LockPixels(dataPixMap); //4-256色の場合、CTableを最小にする if(depth >= 2 && depth <= 8) { for(i=0; i<256; i++) { useTable[i] = 0; } for(i=0; ibaseAddr + (0x7fff&(*dataPixMap)->rowBytes)*(i+srcRect.top); for(j=0; j0)? 8:0)+ // CTable Header ctIndex*8+ // CTable Data pixRowBytes*height // PixMap Data ); //cicnデータをセット HLock((Handle)theCicn); //ロックして (*theCicn)->iconPMap.rowBytes = 0x8000 | pixRowBytes; (*theCicn)->iconPMap.bounds = dstRect; (*theCicn)->iconPMap.hRes = 72<<16; (*theCicn)->iconPMap.vRes = 72<<16; (*theCicn)->iconPMap.pixelType = (*dataPixMap)->pixelType; (*theCicn)->iconPMap.pixelSize = outDepth; (*theCicn)->iconPMap.cmpCount = (*dataPixMap)->cmpCount; if(outDepth <= 8) (*theCicn)->iconPMap.cmpSize = outDepth; else (*theCicn)->iconPMap.cmpSize = (*dataPixMap)->cmpSize; (*theCicn)->iconMask.rowBytes = bitRowBytes; (*theCicn)->iconMask.bounds = dstRect; (*theCicn)->iconBMap.rowBytes = bitRowBytes; (*theCicn)->iconBMap.bounds = dstRect; //Maskデータ p = (char *)(*theCicn)->iconMaskData; if(maskBuf) { baseAddr = maskBitMap->baseAddr + srcRect.left/8; for(i=0; irowBytes*(i+srcRect.top), p, bitRowBytes); p += bitRowBytes; } //Iconデータはマスクと同じ baseAddr = maskBitMap->baseAddr + srcRect.left/8; for(i=0; irowBytes*(i+srcRect.top), p, bitRowBytes); p += bitRowBytes; } } else { //マスクデータは真っ黒 for(i=0; ipmTable)->ctTable[j].rgb.red; s[2] = (*(*dataPixMap)->pmTable)->ctTable[j].rgb.green; s[3] = (*(*dataPixMap)->pmTable)->ctTable[j].rgb.blue; } p += 8; } //PixMapデータ if(depth > 8) { //16bitカラー以上 baseAddr = (*dataPixMap)->baseAddr + srcRect.left*depth/8; for(i=0; irowBytes)*(i+srcRect.top), p, pixRowBytes); p += pixRowBytes; } } else { //256色以下 for(i=0; ibaseAddr + (0x7fff&(*dataPixMap)->rowBytes)*(i+srcRect.top); for(j=0; jparamCount > 5 && **paramPtr->params[5] != 0) ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); else tmpStr[0] = 0; AddResource( (Handle)theCicn, 'cicn', picId, tmpStr); SetResAttrs( (Handle)theCicn, resPurgeable); //purgeableに設定 if(ResError() == noErr){ WriteResource( (Handle)theCicn); DetachResource((Handle)theCicn); HUnlock((Handle)theCicn); //ロックを解除 DisposeHandle((Handle)theCicn); //メモリを解放する if(**(paramPtr->params[4]) == 0){ NumToStr(paramPtr,picId,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } }else{ HUnlock((Handle)theCicn); //ロックを解除 DisposeHandle((Handle)theCicn); //メモリを解放する paramPtr->returnValue=PasToZero(paramPtr,"\pError:Some problem at saving cicn resource"); return; } } //クリップボードにコピー void copyAsPict(XCmdPtr paramPtr){ Str255 tmpStr; GWorldPtr screenBuf; GrafPtr cardPort; PicHandle thePict; Rect srcRect; OpenCPicParams picParam; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&screenBuf->portRect); } else{ srcRect = screenBuf->portRect; } GetPort(&cardPort); picParam.srcRect = srcRect; OffsetRect(&picParam.srcRect, -picParam.srcRect.left, -picParam.srcRect.top); picParam.hRes = 72<<16; picParam.vRes = 72<<16; picParam.version = -2; picParam.reserved1 = 0; picParam.reserved2 = 0; thePict = OpenCPicture(&picParam); ClipRect(&picParam.srcRect); //念のため入れたほうがいいらしい。新居さんの本より。 if(screenBuf == (CGrafPtr)cardPort) CopyBits2(&((GrafPtr)screenBuf)->portBits, &cardPort->portBits, &srcRect,&picParam.srcRect,srcCopy,nil ); else CopyBits2((BitMap*)*((CGrafPtr)screenBuf)->portPixMap, &cardPort->portBits, &srcRect,&picParam.srcRect,srcCopy,nil ); (**thePict).picFrame = picParam.srcRect; // 念のため入れたほうがいいらしい。新居さんの本より。 ClosePicture(); ClipRect(&cardPort->portRect); HLock((Handle)thePict); //ロックして ZeroScrap(); PutScrap( GetHandleSize((Handle)thePict), 'PICT', (Ptr)*thePict); HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する } //Mask付きでクリップボードにコピー void copyAsMaskPict(XCmdPtr paramPtr, int useRgn){ OSErr status; RgnHandle rgnH; Str255 tmpStr; int mode; GWorldPtr screenBuf,maskBuf; BitMapPtr srcBitMap,maskBitMap; GrafPtr cardPort; PicHandle thePict; Rect srcRect; OpenCPicParams picParam; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); maskBuf = myGetPlane(paramPtr,tmpStr); //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&srcRect); myClipRect(&srcRect,&screenBuf->portRect); } else{ srcRect = screenBuf->portRect; } //BitMapPtrを取得 if((0xc000&(screenBuf->portVersion)) == 0) srcBitMap = &((GrafPtr)screenBuf)->portBits; else srcBitMap = (BitMap*)*((CGrafPtr)screenBuf)->portPixMap; if((0xc000&(maskBuf->portVersion)) == 0) maskBitMap = &((GrafPtr)maskBuf)->portBits; else maskBitMap = (BitMap*)*((CGrafPtr)maskBuf)->portPixMap; GetPort(&cardPort); picParam.srcRect = srcRect; //OffsetRect(&picParam.srcRect, -picParam.srcRect.left, -picParam.srcRect.top); picParam.hRes = 72<<16; picParam.vRes = 72<<16; picParam.version = -2; picParam.reserved1 = 0; picParam.reserved2 = 0; thePict = OpenCPicture(&picParam); ClipRect(&picParam.srcRect); //念のため入れたほうがいいらしい。新居さんの本より。 rgnH = NewRgn(); //マスク画像 if(maskBuf){ if(useRgn == 2 && (0xc000&(maskBuf->portVersion)) == 0) { status = BitMapToRegion(rgnH, maskBitMap); //リージョンが使えるなら、リージョンを使おう if(noErr == status) { SetClip(rgnH); } } if(useRgn == 1 && (0xc000&(maskBuf->portVersion)) == 0) { status = BitMapToRegion(rgnH, maskBitMap); //リージョンが使えるなら、リージョンを使おう if(noErr == status) { EraseRgn(rgnH); } } if( useRgn == 0 || (0xc000&(maskBuf->portVersion)) != 0 || status != noErr) { CopyBits2(maskBitMap, &cardPort->portBits, &srcRect,&picParam.srcRect,srcBic,nil); } } //カラー画像(白黒かもしれんけど) if(screenBuf){ if(useRgn && (0xc000&(screenBuf->portVersion)) == 0) { DisposeRgn(rgnH); rgnH = NewRgn(); status = BitMapToRegion(rgnH, srcBitMap); //リージョンが使えるなら、リージョンを使おう if(noErr == status) { //mode抽出 if(paramPtr->params[4] == NULL){ if(useRgn == 2) mode = patCopy; else mode = patOr; } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); mode = GetPatMode(tmpStr); } PenMode(mode); PaintRgn(rgnH); PenNormal(); } } if( !useRgn || (0xc000&(screenBuf->portVersion)) != 0 || status != noErr) { //mode抽出 if(paramPtr->paramCount < 4 || **paramPtr->params[4] == 0){ if(useRgn == 2) mode = srcCopy; else mode = srcOr; } else{ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); mode = GetMode(tmpStr); } CopyBits2(srcBitMap, &cardPort->portBits, &srcRect,&picParam.srcRect,mode,rgnH); } } DisposeRgn(rgnH); (**thePict).picFrame = picParam.srcRect; // 念のため入れたほうがいいらしい。新居さんの本より。 ClosePicture(); ClipRect(&cardPort->portRect); HLock((Handle)thePict); //ロックして ZeroScrap(); PutScrap( GetHandleSize((Handle)thePict), 'PICT', (Ptr)*thePict); HUnlock((Handle)thePict); //ロックを解除 KillPicture(thePict); //メモリを解放する } //クリップボードからPICTをペースト void pastePict(XCmdPtr paramPtr){ PicHandle thePict; long offset, dataSize; int thePlaneNo; Rect pictRect; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; OSErr err; Str255 tmpStr; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); thePlaneNo = myStrToNum(paramPtr,tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL && (thePlaneNo < 0 || thePlaneNo > 128)) return; //PICTの存在をチェック if((dataSize = GetScrap(0, 'PICT', &offset)) <= 0){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:no pict in clip"); return; } thePict = (PicHandle)NewHandle(dataSize); //PICTを取り出すメモリを用意 if(thePict == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Can't load pict"); return; } dataSize = GetScrap((Handle)thePict, 'PICT', &offset); //実際に取り出す //srcRect抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&pictRect); } else{ pictRect = (**thePict).picFrame; //PICTの位置と大きさを取り出す if(!EqualString(tmpStr,"\pOriginal",false,true)) OffsetRect(&pictRect,-pictRect.left,-pictRect.top); } //バッファが無ければ作る if(screenBuf == NULL){ //GWorld作成 err = NewGWorld(&screenBuf, 0, &pictRect, NULL, NULL, 0); if(err != noErr){ DisposeHandle((Handle)thePict); paramPtr->returnValue=PasToZero(paramPtr,"\pError:Can't create new buffer. More memory please"); return; } //GWorldをクリア GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); EraseRect(&screenBuf->portRect); SetGWorld(saveGrafPort, saveGDHandle); GetPCXPtr(paramPtr,false)->gp[thePlaneNo] = screenBuf; } myClipRect(&pictRect,&screenBuf->portRect); GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); DrawPicture(thePict,&pictRect); SetGWorld(saveGrafPort, saveGDHandle); DisposeHandle((Handle)thePict); } //バッファの矩型サイズを取得 void myGetBufferSize(XCmdPtr paramPtr){ short i; Str255 tmpStr,tmp2Str; GWorldPtr screenBuf; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //サイズを返す NumToStr(paramPtr,screenBuf->portRect.right,tmpStr); NumToStr(paramPtr,screenBuf->portRect.bottom,tmp2Str); tmpStr[tmpStr[0]+1]=','; tmpStr[0]++; for(i=1;i<=tmp2Str[0];i++){ tmpStr[tmpStr[0]+i]=tmp2Str[i]; } tmpStr[0]+=tmp2Str[0]; paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } //バッファの色深度を取得 void myGetBufferDepth(XCmdPtr paramPtr){ Str255 tmpStr; short depth; GWorldPtr screenBuf,cardPort; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; GetPort(&(GrafPtr)cardPort); //色深度を返す if((0xc000&(screenBuf->portVersion)) != 0){ depth = (*GetGWorldPixMap(screenBuf))->pixelSize; }else if(screenBuf != cardPort){ depth = 1; }else{ CGrafPtr gomiGP; GDHandle hGD; PixMapHandle hPM; GetGWorld(&gomiGP, &hGD); hPM = (*hGD)->gdPMap; depth = (*hPM)->pixelSize; } NumToStr(paramPtr,depth,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); } //バッファのクリップ矩型を設定 void myClipRectBuffer(XCmdPtr paramPtr){ Rect theRect; Str255 tmpStr; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //Rect抽出 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; } GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); ClipRect(&theRect); SetGWorld(saveGrafPort, saveGDHandle); } //バッファに文字列を書く void myTextBuffer(XCmdPtr paramPtr){ Rect theRect,clipRect; Point thePoint,theScroll; RGBColor theColor,saveColor,theOpColor; short mode; Handle tmpH; Str255 tmpStr; Ptr theString,lastString; short width; short theSize,theFont,theFace,theAlign,theHeight; Boolean dontWrap; FontInfo fInfo; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //文字列へのポインタ取得 theString = *paramPtr->params[2]; //色を取得 if(**(paramPtr->params[3]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); theColor = myGetColor(paramPtr,tmpStr); }else{ theColor.red = 0; theColor.green = 0; theColor.blue = 0; } //フォント if(paramPtr->paramCount >= 4){ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); }else{ tmpH = EvalExpr(paramPtr,"\pthe textFont"); ZeroToPas(paramPtr,*tmpH,tmpStr); DisposeHandle(tmpH); } GetFNum(tmpStr,&theFont); //フォントサイズ if(**(paramPtr->params[5]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); theSize = myStrToNum(paramPtr,tmpStr); }else{ theSize = 12; } //フォントスタイル if(**(paramPtr->params[6]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theFace = textToFace(paramPtr,(Ptr)tmpStr); }else{ theFace = 0; } //アライン //-2=left,1=center,-1=right if(**(paramPtr->params[7]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theAlign = textToAlign(paramPtr,(Ptr)tmpStr); }else{ theAlign = 0; } if(theAlign == 0) theAlign = -2; //スクロール if(**(paramPtr->params[8]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[8],tmpStr); myStrToPoint(paramPtr,tmpStr,&theScroll); }else{ theScroll.h = 0; theScroll.v = 0; } //textHeight if(**(paramPtr->params[9]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[9],tmpStr); theHeight = myStrToNum(paramPtr,tmpStr); }else{ theHeight = 16; } //dontWrap if(**(paramPtr->params[10]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[10],tmpStr); dontWrap = (EqualString(tmpStr,"\ptrue",false,true)); }else{ dontWrap = false; } //描画位置を取得 if(paramPtr->paramCount <= 11){ theRect = screenBuf->portRect; } else{ ZeroToPas(paramPtr,*paramPtr->params[11],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; OffsetRect(&theRect,-theRect.left,-theRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&theRect,thePoint.h,thePoint.v); } } //mode抽出 if(paramPtr->paramCount <= 12){ mode = patCopy; } else{ ZeroToPas(paramPtr,*paramPtr->params[12],tmpStr); mode = GetPatMode(tmpStr); } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); //OpColor抽出 if(paramPtr->paramCount <= 13){ SetOpColor(mode); } else{ ZeroToPas(paramPtr,*paramPtr->params[13],tmpStr); theOpColor = myGetColor(paramPtr,tmpStr); OpColor(&theOpColor); } GetForeColor(&saveColor); RGBForeColor(&theColor); TextFont(theFont); TextSize(theSize); TextMode(mode); TextFace(theFace); clipRect = theRect; myClipRect(&clipRect,&screenBuf->portRect); ClipRect(&clipRect); theRect.left -= theScroll.h; theRect.right -= theScroll.h; theRect.top -= theScroll.v; theRect.bottom -= theScroll.v; GetFontInfo (&fInfo); theRect.top += fInfo.ascent; //上過ぎなら改行まで飛ばす while(dontWrap&&(theRect.top+theHeight) < clipRect.top){ while(*theString != 13 && *theString != 0){ theString++; } theRect.top += theHeight; if(*theString == 0) break; theString++; } lastString = theString; while(*theString != 0){ while(*theString != 13 && *theString != 0){ theString++; } if(!dontWrap){ width = TextWidth(lastString,0,theString-lastString); while(width > theRect.right - theRect.left -4){ if(width >= 2*(theRect.right - theRect.left)){ theString -= (theString-lastString)/4; }else if(width >= 1.5*(theRect.right - theRect.left)){ theString -= (theString-lastString)/8; }else theString--; width = TextWidth(lastString,0,theString-lastString); } if(theString == lastString) theString++; //0はまずいでしょ? } if(theAlign == -2){ //Align:left MoveTo(theRect.left,theRect.top); }else if(theAlign == -1){ //Align:right width = TextWidth(lastString,0,theString-lastString); MoveTo(theRect.right-width,theRect.top); }else if(theAlign == 1){ //Align:center width = TextWidth(lastString,0,theString-lastString); MoveTo((theRect.left+theRect.right-width +1)/2,theRect.top); } DrawText(lastString,0,theString-lastString); lastString = theString; theRect.top += theHeight; //下越えていたら終了 if(theRect.top-fInfo.ascent > clipRect.bottom) break; if(*theString != 0)theString++; } ClipRect(&screenBuf->portRect); RGBForeColor(&saveColor); SetGWorld(saveGrafPort, saveGDHandle); } //バッファに文字列を書く高さと幅を返す void myTextBufferSize(XCmdPtr paramPtr){ Rect theRect; Point thePoint; Handle tmpH; Str255 tmpStr,tmpStr2; Ptr theString,lastString; short width,maxWidth,i; long maxHeight; short theSize,theFont,theFace,theAlign,theHeight; Boolean dontWrap; FontInfo fInfo; GWorldPtr screenBuf; CGrafPtr saveGrafPort; GDHandle saveGDHandle; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); screenBuf = myGetPlane(paramPtr,tmpStr); if(screenBuf == NULL) return; //文字列へのポインタ取得 theString = *paramPtr->params[2]; //フォント if(paramPtr->paramCount >= 4){ ZeroToPas(paramPtr,*paramPtr->params[4],tmpStr); }else{ tmpH = EvalExpr(paramPtr,"\pthe textFont"); ZeroToPas(paramPtr,*tmpH,tmpStr); DisposeHandle(tmpH); } GetFNum(tmpStr,&theFont); //フォントサイズ if(**(paramPtr->params[5]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[5],tmpStr); theSize = myStrToNum(paramPtr,tmpStr); }else{ theSize = 12; } //フォントスタイル if(**(paramPtr->params[6]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[6],tmpStr); theFace = textToFace(paramPtr,(Ptr)tmpStr); }else{ theFace = 0; } //アライン //-2=left,1=center,-1=right if(**(paramPtr->params[7]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[7],tmpStr); theAlign = textToAlign(paramPtr,(Ptr)tmpStr); }else{ theAlign = 0; } if(theAlign == 0) theAlign = -2; //textHeight if(**(paramPtr->params[9]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[9],tmpStr); theHeight = myStrToNum(paramPtr,tmpStr); }else{ theHeight = 16; } //dontWrap if(**(paramPtr->params[10]) > 0){ ZeroToPas(paramPtr,*paramPtr->params[10],tmpStr); dontWrap = (EqualString(tmpStr,"\ptrue",false,true)); }else{ dontWrap = false; } //描画位置を取得 if(paramPtr->paramCount <= 11){ theRect = screenBuf->portRect; } else{ ZeroToPas(paramPtr,*paramPtr->params[11],tmpStr); if(IsRect(tmpStr) == true){ myStrToRect(paramPtr,tmpStr,&theRect); } else{ theRect = screenBuf->portRect; OffsetRect(&theRect,-theRect.left,-theRect.top); myStrToPoint(paramPtr,tmpStr,&thePoint); OffsetRect(&theRect,thePoint.h,thePoint.v); } } //ポートを設定 GetGWorld(&saveGrafPort, &saveGDHandle); SetGWorld(screenBuf, nil); TextFont(theFont); TextSize(theSize); TextFace(theFace); GetFontInfo (&fInfo); theRect.top += fInfo.ascent; maxWidth = 0; maxHeight = 0; lastString = theString; while(*theString != 0){ while(*theString != 13 && *theString != 0){ theString++; } if(!dontWrap){ width = TextWidth(lastString,0,theString-lastString); while(width > theRect.right - theRect.left -4){ if(width >= 2*(theRect.right - theRect.left)){ theString -= (theString-lastString)/4; }else if(width >= 1.5*(theRect.right - theRect.left)){ theString -= (theString-lastString)/8; }else theString--; width = TextWidth(lastString,0,theString-lastString); } if(theString == lastString) theString++; //0はまずいでしょ? } if(theAlign == -2){ //Align:left }else if(theAlign == -1){ //Align:right width = TextWidth(lastString,0,theString-lastString); }else if(theAlign == 1){ //Align:center width = TextWidth(lastString,0,theString-lastString); } lastString = theString; if(width > maxWidth)maxWidth = width; maxHeight += theHeight; if(*theString != 0)theString++; } SetGWorld(saveGrafPort, saveGDHandle); //最大幅と高さを返す NumToStr(paramPtr,maxWidth,tmpStr2); NumToStr(paramPtr,maxHeight,tmpStr); tmpStr2[tmpStr2[0]+1]=','; tmpStr2[0]++; for(i=1;i<=tmpStr[0];i++){ tmpStr2[tmpStr2[0]+i]=tmpStr[i]; } tmpStr2[0]+=tmpStr[0]; paramPtr->returnValue=PasToZero(paramPtr,tmpStr2); } //バッファ、あるいはカードウィンドウのポートを取得 CGrafPtr myGetPlane(XCmdPtr paramPtr,Str255 tmpStr){ int thePlaneNo; GWorldPtr screenBuf; thePlaneNo = myStrToNum(paramPtr,tmpStr); if(thePlaneNo < 0 || thePlaneNo >= PLANE_MAX){ if(EqualString(tmpStr,"\pdir",false,true) || EqualString(tmpStr,"\pdirect",false,true) ){ GetPort(&(GrafPtr)screenBuf); }else if(EqualString(tmpStr,"\pcd",false,true) || EqualString(tmpStr,"\pcard",false,true) ){ PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,false); if(thePCXPtr == NULL || thePCXPtr->primary == NULL || thePCXPtr->bltMode == BLT_OFF) GetPort(&(GrafPtr)screenBuf); else screenBuf = GetPCXPtr(paramPtr,false)->primary; }else if(EqualString(tmpStr,"\ppri",false,true) || EqualString(tmpStr,"\pprimary",false,true) ){ screenBuf = GetPCXPtr(paramPtr,false)->primary; }else if(EqualString(tmpStr,"\pcd buf",false,true) || EqualString(tmpStr,"\pcard buf",false,true) ){ screenBuf = GetPCXPtr(paramPtr,false)->secondary; }else if(EqualString(tmpStr,"\pcd alpha",false,true) || EqualString(tmpStr,"\pcard alpha",false,true) ){ screenBuf = GetPCXPtr(paramPtr,false)->alpha; }else if((screenBuf = (CGrafPtr)getWinPtr(tmpStr)) == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:Buffer ID is out of (0-128)"); return NULL; } }else{ //GWorldポインタを取得 screenBuf = GetPCXPtr(paramPtr,false)->gp[thePlaneNo]; if(screenBuf == NULL){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:This Buffer is not exist"); } } return screenBuf; } /* 文字列からRGBColorに変換して返す */ struct colorName{ unsigned char name[16]; RGBColor color; }; RGBColor myGetColor(XCmdPtr paramPtr,Str255 str){ RGBColor colPtr; myGetColor2(paramPtr, str, &colPtr, NULL, NULL); return colPtr; } void myGetColor2(XCmdPtr paramPtr,Str255 str, RGBColor *colPtr, RGBColor *bkColPtr, int *pat){ #if powerc static struct colorName colName[] = { #else struct colorName colName[] = { #endif /* W3C仕様 */ {"\pBlack", {0x0000,0x0000,0x0000}}, {"\pGray", {0x8000,0x8000,0x8000}}, {"\pSilver", {0xC000,0xC000,0xC000}}, {"\pWhite", {0xffff,0xffff,0xffff}}, {"\pRed", {0xffff,0x0000,0x0000}}, {"\pYellow", {0xffff,0xffff,0x0000}}, {"\pLime", {0x0000,0xffff,0x0000}}, {"\pAqua", {0x0000,0xffff,0xffff}}, {"\pBlue", {0x0000,0x0000,0xffff}}, {"\pFuchsia", {0xffff,0x0000,0xffff}}, {"\pMaroon", {0x8000,0x0000,0x0000}}, {"\pOlive", {0x8000,0x8000,0x0000}}, {"\pGreen", {0x0000,0x8000,0x0000}}, {"\pTeal", {0x0000,0x8000,0x8000}}, {"\pNavy", {0x0000,0x0000,0x8000}}, {"\pPurple", {0x8000,0x0000,0x8000}}, /* CSS2.1追加 */ {"\pOrange", {0xffff,0xA500,0x0000}}, /* HTMLカラーからピックアップ */ {"\pBrown", {0x9600,0x3900,0x3900}}, {"\pPink", {0xffff,0xc000,0xcb00}}, {"\pYellowGreen",{0xc000,0xc200,0x3200}}, {"\pViolet", {0xee00,0x8200,0xee00}}, {"\pSkyBlue", {0x8700,0xce00,0xeb00}}, {"\pTan", {0xd200,0xb400,0x8c00}}, {"\pIvory", {0xffff,0xffff,0xf000}}, {"\pGold", {0xffff,0xd700,0x0000}}, {"\pIndigo", {0x4b00,0x0000,0x8200}}, {"\pAzure", {0xf000,0xffff,0xffff}}, /* 同色異名 */ {"\pMagenta", {0xffff,0x0000,0xffff}}, {"\pCyan", {0x0000,0xffff,0xffff}}, {"\pGrey", {0x8000,0x8000,0x8000}}, }; Str255 itemStr; RGBColor theColor; int i, j, k=0; *pat = 0; for(j=0; j<3; j++){ //item j+1 of str CopyWordStr(str, itemStr, j+k, ','); if(itemStr[1] == '#' && itemStr[0] == 4){ theColor.red = (16*myHexToNum(itemStr[2])+myHexToNum(itemStr[2]))<<8; theColor.green = (16*myHexToNum(itemStr[3])+myHexToNum(itemStr[3]))<<8; theColor.blue = (16*myHexToNum(itemStr[4])+myHexToNum(itemStr[4]))<<8; } else if(itemStr[1] == '#' && itemStr[0] == 7){ theColor.red = (16*myHexToNum(itemStr[2])+myHexToNum(itemStr[3]))<<8; theColor.green = (16*myHexToNum(itemStr[4])+myHexToNum(itemStr[5]))<<8; theColor.blue = (16*myHexToNum(itemStr[6])+myHexToNum(itemStr[7]))<<8; } else if(itemStr[1]>='0' && itemStr[1]<='9'){ theColor.red = myStrToNum(paramPtr, itemStr); k++; CopyWordStr(str, itemStr, j+k, ','); theColor.green = myStrToNum(paramPtr, itemStr); k++; CopyWordStr(str, itemStr, j+k, ','); theColor.blue = myStrToNum(paramPtr, itemStr); } else if((itemStr[1]=='P' || itemStr[1]=='p') && (itemStr[2]=='A' || itemStr[2]=='a') && (itemStr[3]=='T' || itemStr[3]=='t') ){ if(itemStr[0] == 4) *pat = itemStr[4]-'0'; else if(itemStr[0] == 5) *pat = 10*(itemStr[4]-'0') + itemStr[5]-'0'; return; } else { for(i=0; i= '0' && c <= '9') return c-'0'; else if(c >= 'A' && c <= 'F') return c-'A'+10; else if(c >= 'a' && c <= 'f') return c-'a'+10; else return 0; } Boolean IsPoint(Str255 str){ short i,commaCnt; commaCnt = 0; for(i=1; i<=str[0]; i++){ if(str[i] == ',' || str[i] ==' ') commaCnt++; } if(commaCnt == 1) return true; else return false; } Boolean IsRect(Str255 str){ short i,commaCnt; commaCnt = 0; for(i=1; i<=str[0]; i++){ if(str[i] == ',') commaCnt++; } if(commaCnt == 3) return true; else return false; } int myStrToRect(XCmdPtr paramPtr,Str255 str,Rect* r){ #pragma unused paramPtr int i, j, k; int num; Str32 tmpStr; //初期化 r->left = 0; r->top = 0; r->right = 0; r->bottom = 0; k = 0; //commaの数 j = 1; while(k <= 4) { tmpStr[0] = 0; i = 1; //commaまでtmpstrに取り出す for(; j <= str[0] && str[j] != ','; i++,j++) { tmpStr[i] = str[j]; tmpStr[0]++; } j++; //数値を評価 num = myStrToNum(paramPtr,tmpStr); if(num == 0x80000000) { break; } //left,top,right,bottomの順に入れる k++; switch(k) { case 1: r->left = num; break; case 2: r->top = num; break; case 3: r->right = num; break; case 4: r->bottom = num; break; } } if(k == 4) return 1; //OK,数値が4つあった else if(k <= 3) { paramPtr->returnValue=PasToZero(paramPtr,"\pError:Illegal rect"); return 0; //NG } else return 0; } int myStrToPoint(XCmdPtr paramPtr,Str255 str,Point* p){ #pragma unused paramPtr int i, j, k; int num; Str32 tmpStr; //初期化 p->h = 0; p->v = 0; k = 0; //commaの数 j = 1; while(k <= 2) { tmpStr[0] = 0; i = 1; if(j > str[0]) break; //commaまでtmpstrに取り出す for(; j <= str[0] && str[j] != ','; i++,j++) { tmpStr[i] = str[j]; tmpStr[0]++; } j++; //数値を評価 num = myStrToNum(paramPtr,tmpStr); if(num == 0x80000000) { break; } //h,vの順に入れる k++; switch(k) { case 1: p->h = num; break; case 2: p->v = num; break; } } if(k == 2) return 1; //OK,数値が2つあった else return 0; //NG } static int internalStrToNum(Str255 str){ int i,x; x = 0; for(i=1; i '9') return 0x80000000; } if (str[1] == '-') return -x; else return x; case '0': x *= 10; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': x = x*10 + str[i] - '0'; break; default: return 0x80000000; } } if (str[1] == '-') return -x; else return x; } int myStrToNum(XCmdPtr paramPtr,Str255 str){ #pragma unused paramPtr int i, x; Handle tmpH; Str255 tmpStr; x = internalStrToNum(str); if(x == 0x80000000) { //エラーだった場合はHyperTalkで式を評価する tmpH = EvalExpr(paramPtr, str); tmpStr[0] = 0; for(i=0; (*tmpH)[i]; i++) { tmpStr[i+1] = (*tmpH)[i]; tmpStr[0]++; } DisposeHandle(tmpH); x = internalStrToNum(tmpStr); } return x; } short GetMode(Str255 modeStr){ if(EqualString(modeStr,"\ptransparent",false,true)){ return transparent; } if(EqualString(modeStr,"\pblend",false,true)){ return blend; } if(EqualString(modeStr,"\pnotcopy",false,true)){ return notSrcCopy; } if(EqualString(modeStr,"\pcopy",false,true)){ return srcCopy; } if(EqualString(modeStr,"\pnotor",false,true)){ return notSrcOr; } if(EqualString(modeStr,"\por",false,true)){ return srcOr; } if(EqualString(modeStr,"\pnotxor",false,true)){ return notSrcXor; } if(EqualString(modeStr,"\pxor",false,true)){ return srcXor; } if(EqualString(modeStr,"\pnotbic",false,true)){ return notSrcBic; } if(EqualString(modeStr,"\pbic",false,true)){ return srcBic; } if(EqualString(modeStr,"\paddover",false,true)){ return addOver; } if(EqualString(modeStr,"\paddpin",false,true)){ return addPin; } if(EqualString(modeStr,"\psubover",false,true)){ return subOver; } if(EqualString(modeStr,"\psubpin",false,true)){ return subPin; } if(EqualString(modeStr,"\padmax",false,true)){ return adMax; } if(EqualString(modeStr,"\padmin",false,true)){ return adMin; } if(EqualString(modeStr,"\philite",false,true)){ return hilite; } return srcCopy; } short GetPatMode(Str255 modeStr){ if(EqualString(modeStr,"\ptransparent",false,true)){ return transparent; } if(EqualString(modeStr,"\pblend",false,true)){ return blend; } if(EqualString(modeStr,"\pnotcopy",false,true)){ return notPatCopy; } if(EqualString(modeStr,"\pcopy",false,true)){ return patCopy; } if(EqualString(modeStr,"\pnotor",false,true)){ return notPatOr; } if(EqualString(modeStr,"\por",false,true)){ return patOr; } if(EqualString(modeStr,"\pnotxor",false,true)){ return notPatXor; } if(EqualString(modeStr,"\pxor",false,true)){ return patXor; } if(EqualString(modeStr,"\pnotbic",false,true)){ return notPatBic; } if(EqualString(modeStr,"\pbic",false,true)){ return patBic; } if(EqualString(modeStr,"\paddover",false,true)){ return addOver; } if(EqualString(modeStr,"\paddpin",false,true)){ return addPin; } if(EqualString(modeStr,"\psubover",false,true)){ return subOver; } if(EqualString(modeStr,"\psubpin",false,true)){ return subPin; } if(EqualString(modeStr,"\padmax",false,true)){ return adMax; } if(EqualString(modeStr,"\padmin",false,true)){ return adMin; } if(EqualString(modeStr,"\philite",false,true)){ return hilite; } return patCopy; } short textToFace(XCmdPtr paramPtr,Ptr styleList){ short theFace; theFace = 0; if(StringMatch(paramPtr, "\pbold",styleList) != nil) theFace += 1; if(StringMatch(paramPtr, "\pitalic",styleList) != nil) theFace += 2; if(StringMatch(paramPtr,"\punderline",styleList) != nil) theFace += 4; if(StringMatch(paramPtr, "\poutline",styleList) != nil) theFace += 8; if(StringMatch(paramPtr, "\pshadow",styleList) != nil) theFace += 16; if(StringMatch(paramPtr, "\pcondense",styleList) != nil) theFace += 32; if(StringMatch(paramPtr, "\pextend",styleList) != nil) theFace += 64; return theFace; } short textToAlign(XCmdPtr paramPtr,Ptr Align){ if(StringMatch(paramPtr,"\pcenter",Align) != nil) return 1; else if(StringMatch(paramPtr, "\pright",Align) != nil) return -1; else if(StringMatch(paramPtr, "\pleft",Align) != nil) return -2; else return 0; } void myClipRect(Rect *r,const Rect *clipRect){ if(r->left < clipRect->left ) r->left = clipRect->left; if(r->top < clipRect->top ) r->top = clipRect->top; if(r->right > clipRect->right ) r->right = clipRect->right; if(r->bottom> clipRect->bottom) r->bottom= clipRect->bottom; } void SetOpColor(short mode){ RGBColor theColor; if(mode == blend){ theColor.red = 32767; theColor.green = 32767; theColor.blue = 32767; OpColor(&theColor); } else if(mode == addPin){ theColor.red = 65535; theColor.green = 65535; theColor.blue = 65535; OpColor(&theColor); } else if(mode == subPin){ theColor.red = 0; theColor.green = 0; theColor.blue = 0; OpColor(&theColor); } theColor.red = 0; theColor.green = 0; theColor.blue = 0; RGBForeColor(&theColor); theColor.red = 65535; theColor.green = 65535; theColor.blue = 65535; RGBBackColor(&theColor); } //改行の数を数える(HCのnumber of linesとは違う) short numOfLinesOfHandle(Handle strH){ short returnCnt; char *c; HLock(strH); c = *strH; returnCnt = 0; while(*c){ if(*c++ == 13) returnCnt++; } HUnlock(strH); return returnCnt; } //word単位で文字列を切り出す //return 0 .. そんなwordないよ //return 1 .. 切り出したよ int CopyWordStr(Str255 srcStr, Str255 dstStr, short word, char sep){ int i; int wordCnt = 0; dstStr[0] = 0; for(i=1; i<=srcStr[0]; i++) { //セパレータを探す if(srcStr[i] == sep && (i > 1 && srcStr[i-1] != sep)) { wordCnt++; if(wordCnt > word) return 1; continue; } if(word != wordCnt) continue; //文字をコピー dstStr[0]++; dstStr[dstStr[0]] = srcStr[i]; } if(dstStr[0] == 0) return 0; else return 1; } //line行目の文字列を取り出す(0行目から始まる!) void GetLineStrOfHandle(Str255 lineStr,Handle str,short line){ short j,returnCnt; char *c; HLock(str); c = *str; returnCnt = 0; while(returnCnt < line && *c){ if(*c == 13) returnCnt++; c++; } for(j=1; j <= 254; j++, c++){ if(*c == 13 || *c == 0){ break; } lineStr[j] = *c; } HUnlock(str); lineStr[0] = j-1; lineStr[j] = 0; } //全色数対応の色値取得サブルーチン unsigned long myGetPix(Ptr baseRowAddr, int x, int depth) { unsigned char *b1 = (unsigned char *)baseRowAddr; unsigned short *b2; unsigned long *b4; switch(depth) { case 1: return (*(b1+x/8)) & (0x0001<<(7-(x%8))); case 2: return (*(b1+x/4)) & (0x0003<<(6-2*(x%4))); case 4: return (*(b1+x/2)) & (0x000F<<(4-4*(x%2))); case 8: return *(b1+x); case 16: b2 = (unsigned short *)(b1+x*2); return *b2; case 32: b4 = (unsigned long *)(b1+x*4); return *b4; default: return 0; } return 0; } //全色数対応の色値設定サブルーチン void mySetPix(Ptr baseRowAddr, int x, int depth, unsigned long pixValue) { unsigned short *b2; unsigned long *b4; switch(depth) { case 1: *(baseRowAddr+x/8) &= ~(0x0001<<(7-(x%8))); *(baseRowAddr+x/8) |= (pixValue<<(7-(x%8))); break; case 2: *(baseRowAddr+x/4) &= ~(0x0003<<(6-2*(x%4))); *(baseRowAddr+x/4) |= (pixValue<<(6-2*(x%4))); break; case 4: *(baseRowAddr+x/2) &= ~(0x000F<<(4-4*(x%2))); *(baseRowAddr+x/2) |= (pixValue<<(4-4*(x%2))); break; case 8: *(baseRowAddr+x) = pixValue; break; case 16: b2 = (unsigned short *)(baseRowAddr+x*2); *b2 = pixValue; break; case 32: b4 = (unsigned long *)(baseRowAddr+x*4); *b4 = pixValue; break; default: break; } } pascal void GetMaskAndData(XCmdPtr paramPtr, BitMap* maskBitsPtr, BitMap* dataBitsPtr){ paramPtr->inArgs[0] = (long)maskBitsPtr; paramPtr->inArgs[1] = (long)dataBitsPtr; paramPtr->request = 29; (*((PascalVoidFunctionPtr)(paramPtr->entryPoint)))(); } static pascal void myStdBits( BitMap *srcBits, Rect *srcRect, Rect *dstRect, short mode, RgnHandle maskRgn) { GrafPtr cardport; BitMapPtr pri, sec, alpha; PCXDataPtr thePCXPtr = GetPCXPtr(NULL,true); int bltMode; if(NULL == thePCXPtr) { bltMode = BLT_OFF; } else { bltMode = thePCXPtr->bltMode; } switch(bltMode) { case BLT_DOUBLE: /* BitmapPtrがすり替えられる */ if(NULL != thePCXPtr->primary) { Rect sr; sr.left = srcRect->left/2; sr.top = srcRect->top/2; sr.right = srcRect->right/2; sr.bottom = srcRect->bottom/2; pri = (BitMap *)*(thePCXPtr->primary)->portPixMap; StdBits(pri,&sr,dstRect,mode,maskRgn); } else StdBits(srcBits,srcRect,dstRect,mode,maskRgn); break; case BLT_SPEED: /* BitmapPtrがすり替えられる */ if(NULL != thePCXPtr->primary) { pri = (BitMap *)*(thePCXPtr->primary)->portPixMap; StdBits(pri,srcRect,dstRect,mode,maskRgn); } else StdBits(srcBits,srcRect,dstRect,mode,maskRgn); break; case BLT_MIX: case BLT_ALPHA: case BLT_HALF: if(NULL != thePCXPtr->primary && NULL != thePCXPtr->secondary) { pri = (BitMap *)*(thePCXPtr->primary)->portPixMap; sec = (BitMap *)*(thePCXPtr->secondary)->portPixMap; GetPort(&cardport); if(bltMode == BLT_ALPHA) { /* まず白黒描画 */ SetPort((GrafPtr)thePCXPtr->secondary); StdBits(srcBits,srcRect,srcRect,srcCopy,maskRgn); /* それからカラー描画 */ alpha = (BitMap *)*(thePCXPtr->alpha)->portPixMap; CopyDeepMask(pri,alpha,sec,srcRect,srcRect,srcRect,mode,maskRgn); } else { /* まずカラー描画 */ SetPort((GrafPtr)thePCXPtr->secondary); if(bltMode == BLT_HALF) { RGBColor col={32767,32767,32767}; RGBForeColor(&col); } StdBits(pri,srcRect,srcRect,srcCopy,maskRgn); /* それから白黒描画 */ if(bltMode == BLT_HALF) { RGBColor col={0,0,0}; RGBForeColor(&col); } StdBits(srcBits,srcRect,srcRect,srcOr,maskRgn); } SetPort(cardport); StdBits(sec,srcRect,dstRect,mode,maskRgn); } else StdBits(srcBits,srcRect,dstRect,mode,maskRgn); break; case BLT_HIDE: if(NULL != thePCXPtr->secondary) { GetPort(&cardport); SetPort((GrafPtr)thePCXPtr->secondary); StdBits(srcBits,srcRect,dstRect,srcCopy,maskRgn); SetPort(cardport); } break; case BLT_OFF: default: StdBits(srcBits,srcRect,dstRect,mode,maskRgn); break; } } /* 標準描画関数の置き換え */ void SetStdBits( XCmdPtr paramPtr ) { PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,false); GrafPtr cardport; Str255 tmpStr; int depth; int err; Rect theRect; Handle tmpH; WindowPtr theWinPtr; theWinPtr = getWinPtr(WINDOW_NAME); //XWMoveHi(paramPtr, theWinPtr, true); XWAlwaysMoveHigh(paramPtr, theWinPtr, true); GetPort(&cardport); thePCXPtr->saveCardPort = cardport; tmpH = EvalExpr(paramPtr,"\prect of this cd"); ZeroToPas(paramPtr,*tmpH,tmpStr); DisposeHandle(tmpH); if(IsRect(tmpStr) == true) myStrToRect(paramPtr,tmpStr,&theRect); OffsetRect(&theRect,-theRect.left,-theRect.top); thePCXPtr->bltMode = BLT_OFF; /* set mode and create buffer */ if(*paramPtr->params[2]) { ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); depth = myStrToNum(paramPtr,tmpStr); } else depth = 0; ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); if(StringMatch(paramPtr,"\poff",tmpStr) != nil) { thePCXPtr->bltMode = BLT_OFF; } if(StringMatch(paramPtr,"\pspeed",tmpStr) != nil) { thePCXPtr->bltMode = BLT_SPEED; } if(StringMatch(paramPtr,"\pmix",tmpStr) != nil) { thePCXPtr->bltMode = BLT_MIX; } if(StringMatch(paramPtr,"\pblend",tmpStr) != nil) { thePCXPtr->bltMode = BLT_ALPHA; } if(StringMatch(paramPtr,"\phide",tmpStr) != nil) { thePCXPtr->bltMode = BLT_HIDE; } if(StringMatch(paramPtr,"\phalf",tmpStr) != nil) { thePCXPtr->bltMode = BLT_HALF; } if(StringMatch(paramPtr,"\pdouble",tmpStr) != nil) { thePCXPtr->bltMode = BLT_DOUBLE; } if(StringMatch(paramPtr,"\paddColor",tmpStr) != nil) { thePCXPtr->bltMode = BLT_ADDCOLOR; } if(thePCXPtr->theProcs.bitsProc == NULL || thePCXPtr->primary == NULL || theRect.right != thePCXPtr->primary->portRect.right || theRect.bottom != thePCXPtr->primary->portRect.bottom ) { err = xNewBuffer(paramPtr,true,false,thePCXPtr,&theRect,-1,depth);/* primary */ err |= xNewBuffer(paramPtr,true,false,thePCXPtr,&theRect,-2,depth);/* secondary */ err |= xNewBuffer(paramPtr,true,true,thePCXPtr,&theRect,-3,8);/* alpha */ if(err != 0) { thePCXPtr->bltMode = BLT_OFF; paramPtr->returnValue=PasToZero(paramPtr,"\pError:Install failure"); return; } SetStdCProcs(&thePCXPtr->theProcs); //thePCXPtr->theProcs.bitsProc = (QDBitsProcPtr)NewRoutineDescriptor(myStdBits, uppQDBitsProcInfo, GetCurrentArchitecture()); thePCXPtr->theProcs.bitsProc = NewQDBitsProc(myStdBits); } //thePCXPtr->theProcs = *cardport->grafProcs; cardport->grafProcs = (QDProcs *)&thePCXPtr->theProcs; theWinPtr = getWinPtr(WINDOW_NAME); XWHasInterruptCode(paramPtr,theWinPtr,true); } /* 標準描画関数を元に戻す */ void UnsetStdBits( XCmdPtr paramPtr ) { GrafPtr cardport; PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,true); WindowPtr theWinPtr; if(thePCXPtr == NULL) return; theWinPtr = getWinPtr(WINDOW_NAME); //XWMoveHi(paramPtr, theWinPtr, true); //XWAlwaysMoveHigh(paramPtr, theWinPtr, false); if(NULL == thePCXPtr->theProcs.bitsProc) return; GetPort(&cardport); thePCXPtr->bltMode = BLT_OFF; SetStdCProcs(&thePCXPtr->saveProcs); cardport->grafProcs = (QDProcs *)&thePCXPtr->saveProcs; /* kill buffer */ /*xKillBuffer(paramPtr,thePCXPtr,-1); xKillBuffer(paramPtr,thePCXPtr,-2); xKillBuffer(paramPtr,thePCXPtr,-3);*/ theWinPtr = getWinPtr(WINDOW_NAME); //XWHasInterruptCode(paramPtr,theWinPtr,false); } /* デバッグモードの入/切 */ void DebugMode(XCmdPtr paramPtr){ Str255 tmpStr; PCXDataPtr PCXPtr = GetPCXPtr(paramPtr,false); if(paramPtr->paramCount <= 1){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //PlaneNo.抽出 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); if(EqualString(tmpStr,"\ptrue",false,true)){ PCXPtr->debugMode = 1; } else if(EqualString(tmpStr,"\pfalse",false,true)){ PCXPtr->debugMode = 0; } } enum suiteCmd { SUITE_NONE = 0, SUITE_COPYBITS, SUITE_COPYMASK, SUITE_COPYALPHA, SUITE_TILING, SUITE_PICFONT, SUITE_CICN, SUITE_PICT, SUITE_XPIC, SUITE_ICON, SUITE_PAINT, SUITE_SETPIXEL, SUITE_LINE, SUITE_RECT, SUITE_ROUNDRECT, SUITE_OVAL, SUITE_ARC, SUITE_POLYANGLE, SUITE_POLYGON, SUITE_PAINTMASK, SUITE_MAKEFILLMASK, SUITE_DRAWSPRITE, SUITE_STRINGSPRITE, SUITE_STRING, SUITE_FLASH, SUITE_TEXT, SUITE_DO, SUITE_END, }; struct cmdname{ unsigned char name[16]; }; /* スイートの設定 */ void mySetSuite(XCmdPtr paramPtr){ #if powerc static struct cmdname cmdName[] = { #else struct cmdname cmdName[] = { #endif {"\pNone" }, {"\pCopyBits" }, {"\pCopyMask" }, {"\pCopyAlpha" }, {"\pTiling" }, {"\pPicFont" }, {"\pCicn" }, {"\pPict" }, {"\pxPic" }, {"\pIcon" }, {"\pPaint" }, {"\pSetPixel" }, {"\pLine" }, {"\pRect" }, {"\pRoundRect" }, {"\pOval" }, {"\pArc" }, {"\pPolyAngle" }, {"\pPolygon" }, {"\pPaintMask" }, {"\pMakeFillMask"}, {"\pDrawSprite" }, {"\pStringSprite"}, {"\pString" }, {"\pFlash" }, {"\pText" }, {"\pDo" }, }; int i, j; int suiteNo; int cmd; int li; int lineStartNo, lineEndNo; int autoNo; Point tmpPoint; Str255 tmpStr; char c; char *pcLine = NULL; PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,false); suitePtr theSuitePtr; if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } //スイート番号取得 ZeroToPas(paramPtr,*paramPtr->params[1],tmpStr); suiteNo = myStrToNum(paramPtr,tmpStr); if(suiteNo < 1 || suiteNo > SUITE_MAX) { paramPtr->returnValue=PasToZero(paramPtr,"\pError:illegal suiteNo."); return; } if(thePCXPtr->suite[suiteNo-1] == NULL) { thePCXPtr->suite[suiteNo-1] = (suiteHandle)NewHandleClear(sizeof(suiteData)); } theSuitePtr = *(thePCXPtr->suite[suiteNo-1]); //行番号取得 if(**(paramPtr->params[2]) != '\0') { ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); myStrToPoint(paramPtr,tmpStr,&tmpPoint); lineStartNo = tmpPoint.h; lineEndNo = tmpPoint.v; if(lineStartNo < 1) lineStartNo = 1; autoNo = 0; if(lineEndNo == 0 ) { lineEndNo = SUITE_LINES; autoNo = 1; } if(lineStartNo > lineEndNo) lineEndNo = lineStartNo; if(lineEndNo > SUITE_LINES) lineEndNo = SUITE_LINES; } else { lineStartNo = 1; lineEndNo = SUITE_LINES; //autoNo = 1; //登録した行数以降のは残す } //メタ文字列の始まりから始める if(paramPtr->paramCount >= 3) { pcLine = *paramPtr->params[3]; } for(li = lineStartNo; li <= lineEndNo; li++) { //設定データをクリア theSuitePtr->line[li-1].cmd = 0; for(i=0; iline[li-1].arg[i] != NULL) { DisposeHandle(theSuitePtr->line[li-1].arg[i]); theSuitePtr->line[li-1].arg[i] = NULL; } } if(pcLine == NULL) continue; //現在の行を複数のHandleに分ける for(i=0; i= 0x81 && (c <= 0x9f || (c >= 0xe0 && c <= 0xfc))) j++; break; } if(flag == false) break; } //文字列を評価した結果を、保存 if(j > 0) { Handle hand; char cSave; cSave = *(pcLine+j); *(pcLine+j) = '\0'; ZeroToPas(paramPtr,pcLine,tmpStr); *(pcLine+j) = cSave; hand = EvalExpr(paramPtr,tmpStr); MoveHHi(hand); HLock(hand); theSuitePtr->line[li-1].arg[i] = hand; theSuitePtr->line[li-1].argEval[i] = 0; } //一行終わりか? pcLine += j+1; if(c == '\0' || c == '\r' || c == '\n') break; } //コマンド抽出 ZeroToPas(paramPtr,*theSuitePtr->line[li-1].arg[0],tmpStr); cmd = 0; for(i=0; iline[li-1].cmd = cmd; //文字列終わりか? if(pcLine != NULL) { if(c == '\0') { if(autoNo == 1) break; //メタ文字列セット終了 pcLine = NULL; } } } } /* スイートの描画 */ void myDrawSuite(XCmdPtr paramPtr){ int i; int suiteNo; int li; int lineStartNo, lineEndNo; Handle dstBufH; Point tmpPoint; Str255 tmpStr; PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,true); suitePtr theSuitePtr; int saveParamCount; Handle saveParam[16]; char dummyChar = '\0'; Ptr dummyPtr = &dummyChar; Handle dummyHandle = &dummyPtr; Handle saveReturnValue = NULL; //paramPtrを自前で作って渡してやる事でこれまでの関数をそのまま使う。 //楽だ。ひゃっほう。 if(paramPtr->paramCount <= 2){ paramPtr->returnValue=PasToZero(paramPtr,"\pError:please set more params"); return; } if(thePCXPtr == NULL) return; //出力先バッファ文字列を保持 dstBufH = paramPtr->params[1]; //スイート番号取得 ZeroToPas(paramPtr,*paramPtr->params[2],tmpStr); suiteNo = myStrToNum(paramPtr,tmpStr); if(suiteNo < 1 || suiteNo > SUITE_MAX) { paramPtr->returnValue=PasToZero(paramPtr,"\pError:illegal suiteNo."); return; } theSuitePtr = *(thePCXPtr->suite[suiteNo-1]); if(theSuitePtr == NULL) { return; } //paramを保存 saveParamCount = paramPtr->paramCount; for(i=0; iparamCount; i++) { saveParam[i] = paramPtr->params[i]; } //行番号取得 if(paramPtr->paramCount > 3 && **(paramPtr->params[3]) != '\0') { ZeroToPas(paramPtr,*paramPtr->params[3],tmpStr); myStrToPoint(paramPtr,tmpStr,&tmpPoint); lineStartNo = tmpPoint.h; lineEndNo = tmpPoint.v; if(lineStartNo > lineEndNo) lineEndNo = lineStartNo; } else { lineStartNo = 1; lineEndNo = SUITE_LINES; } for(li = lineStartNo; li <= lineEndNo; li++) { if(theSuitePtr->line[li-1].cmd == 0) continue; //引数を無理矢理設定! for(i=1; iline[li-1].arg[i] == NULL) { paramPtr->params[i] = dummyHandle; } else { if(theSuitePtr->line[li-1].argEval[i] == 1) { char *c1, *c2; ZeroToPas(paramPtr,*(theSuitePtr->line[li-1].arg[i]),tmpStr); paramPtr->params[i] = EvalExpr(paramPtr,tmpStr); //2つの文字列が同じかどうかを比較 c1 = *paramPtr->params[i]; c2 = *(theSuitePtr->line[li-1].arg[i]); while(*c1 || *c2) { if(*c1 != *c2) { theSuitePtr->line[li-1].argEval[i] = 1; //同じ文字列だ DisposeHandle(paramPtr->params[i]); paramPtr->params[i] = theSuitePtr->line[li-1].arg[i]; break; } } } else { paramPtr->params[i] = theSuitePtr->line[li-1].arg[i]; } paramPtr->paramCount = i+1; } } //出力バッファの引数番号 switch(theSuitePtr->line[li-1].cmd) { case SUITE_COPYBITS: case SUITE_TILING: case SUITE_PICFONT: case SUITE_PAINTMASK: case SUITE_MAKEFILLMASK: i=2; break; case SUITE_COPYMASK: case SUITE_COPYALPHA: i=3; break; case SUITE_DO: i=0;//dstBuf無し break; default: i=1; break; } //バッファ指定が無ければ,デフォルト出力にする if(paramPtr->params[i] == dummyHandle) { paramPtr->params[i] = dstBufH; if(i+1 > paramPtr->paramCount) paramPtr->paramCount = i+1; } //関数をコール switch(theSuitePtr->line[li-1].cmd) { case SUITE_COPYBITS: myCopyBits(paramPtr, false); break; case SUITE_COPYMASK: myCopyMask(paramPtr); break; case SUITE_COPYALPHA: myAlphaChannelBlt(paramPtr); break; case SUITE_TILING: myTilingBuffer(paramPtr); break; case SUITE_PICFONT: myPictureFontBuffer(paramPtr); break; case SUITE_CICN: myLoadCicn(paramPtr); break; case SUITE_PICT: myLoadPict(paramPtr,'PICT'); break; case SUITE_XPIC: myLoadPict(paramPtr,'xPic'); break; case SUITE_ICON: myLoadIcon(paramPtr); break; case SUITE_PAINT: myPaintbuffer(paramPtr); break; case SUITE_SETPIXEL: mySetPixelBuffer(paramPtr); break; case SUITE_LINE: myLineBuffer(paramPtr); break; case SUITE_RECT: myRectBuffer(paramPtr); break; case SUITE_ROUNDRECT: myRoundRectBuffer(paramPtr); break; case SUITE_OVAL: myOvalBuffer(paramPtr); break; case SUITE_ARC: myArcBuffer(paramPtr); break; case SUITE_POLYANGLE: myPolyAngleBuffer(paramPtr); break; case SUITE_POLYGON: myPolygonBuffer(paramPtr); break; case SUITE_PAINTMASK: myPaintMask(paramPtr); break; case SUITE_MAKEFILLMASK: mySeedFill(paramPtr); break; case SUITE_DRAWSPRITE: myDrawSprite(paramPtr); break; case SUITE_STRINGSPRITE: myStringSprite(paramPtr); break; case SUITE_STRING: myStringBuffer(paramPtr); break; case SUITE_FLASH: myInvalRect(paramPtr); break; case SUITE_TEXT: myTextBuffer(paramPtr); break; case SUITE_DO: RunHandler(paramPtr, paramPtr->params[2]); break; case SUITE_NONE: case SUITE_END: default: break; } //必要無くなったハンドルだけを破棄する for(i=1; i<=paramPtr->paramCount; i++) { if(theSuitePtr->line[li-1].argEval[i] == 1) { if(paramPtr->params[i] != NULL && paramPtr->params[i] != dummyHandle && paramPtr->params[i] != dstBufH) { DisposeHandle(paramPtr->params[i]); } } } //エラー値は保存して、最後のひとつだけを返す if(paramPtr->returnValue != NULL) { DisposeHandle(saveReturnValue); saveReturnValue = paramPtr->returnValue; paramPtr->returnValue = NULL; } } //paramを復帰 paramPtr->returnValue = saveReturnValue; paramPtr->paramCount = saveParamCount; for(i=0; iparamCount; i++) { paramPtr->params[i] = saveParam[i]; } } //タブレット開始 void myOpenTablet(XCmdPtr paramPtr) { myCntrlParam wacomDriverControl; short driverRefNum; PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,false); if (OpenDriver("\p.Wacom", &driverRefNum) != noErr) { // don't run if no driver installed return; } wacomDriverControl.ioCRefNum = driverRefNum; wacomDriverControl.csCode = GET_RECORD; if (PBStatusSync((ParmBlkPtr)(&wacomDriverControl)) != noErr) { paramPtr->returnValue=PasToZero(paramPtr,"\pError: No Tablet"); return; } thePCXPtr->theTabletData = (tabletRecord *)(wacomDriverControl.csParam[0]); } //筆圧感知 void myGetTablet(XCmdPtr paramPtr) { Str255 tmpStr; PCXDataPtr thePCXPtr = GetPCXPtr(paramPtr,false); if (!thePCXPtr->theTabletData) { paramPtr->returnValue=PasToZero(paramPtr,"\pError: No Tablet"); return; } NumToStr(paramPtr, (thePCXPtr->theTabletData->pressure*1024UL)/thePCXPtr->theTabletData->pressLevels,tmpStr); paramPtr->returnValue=PasToZero(paramPtr,tmpStr); }