1388 lines
25 KiB
C++
1388 lines
25 KiB
C++
#include "stdafx.h"
|
|
#include "SlideDc.h"
|
|
|
|
#include <stdio.h>
|
|
#include <io.h>
|
|
#include <time.h>
|
|
#include <atlconv.h>
|
|
|
|
#if (ARX>15)
|
|
#define _ios std::ios_base
|
|
#else
|
|
#define _ios ios
|
|
#endif
|
|
|
|
#define Cpoint(to, from) {to[0] = from[0]; to[1] = from[1]; to[2] = from[2];}
|
|
#define SLIDE_MAXSLDRLEN 31
|
|
#define SLIDE_TEST_NUMBER 0x1234
|
|
#define SLIDE_ACADSLIDE "AutoCAD Slide"
|
|
#define SLIDE_OFFSETVECTOR '\xFB'
|
|
#define SLIDE_ENDOFFILE '\xFC'
|
|
#define SLIDE_SOLIDFILL '\xFD'
|
|
#define SLIDE_COMMONENDVECTOR '\xFE'
|
|
#define SLIDE_NEWCOLOR '\xFF'
|
|
#define AS_INT(f) (f < 0.0 ? int((f) - 0.5) : int((f) + 0.5))
|
|
|
|
const TCHAR *SLD_EXT = _T(".SLD");
|
|
const TCHAR *SLB_TITLE = _T("AutoCAD Slide Library 1.0");
|
|
|
|
static const TCHAR *sMsgPrompt[] =
|
|
{
|
|
/*MSG0*/ _T("\n选择无效,重新选择!"),
|
|
/*MSG1*/ _T("\n请重新选择!"),
|
|
/*MSG2*/ _T("\n发现不可变形的对象: "),
|
|
/*MSG3*/ _T("\n图块内有延伸方向不同于Z轴的对象,不能打散!"),
|
|
/*MSG4*/ _T("\n是否为该对象"),
|
|
};
|
|
|
|
|
|
typedef struct Catalogue
|
|
{
|
|
char itemName[32];
|
|
long addr;
|
|
public:
|
|
|
|
Catalogue()
|
|
{
|
|
for (int i = 0; i< 32; i++)
|
|
{
|
|
itemName[i] = 0;
|
|
}
|
|
addr = 0;
|
|
}
|
|
}CATALOGUE;
|
|
|
|
class CCharBuf
|
|
{
|
|
public:
|
|
CCharBuf(char *pBuf, int nSize);
|
|
virtual ~CCharBuf();
|
|
|
|
int operator !();
|
|
|
|
int IsEOF();
|
|
|
|
int Read(void *pDest, int nCount);
|
|
|
|
protected:
|
|
|
|
char* m_pBuf;
|
|
int m_nSize;
|
|
int m_nPos;
|
|
};
|
|
|
|
class CSlideLib
|
|
{
|
|
public:
|
|
CSlideLib(const TCHAR *fname,int opMode = (_ios::in | _ios::out | _ios::binary));
|
|
virtual ~CSlideLib();
|
|
|
|
int Open(const TCHAR *file, int mode);
|
|
void Close();
|
|
|
|
char * ReadItem(const TCHAR *szItemName, unsigned *nLen);
|
|
|
|
int operator !()
|
|
{
|
|
return !_libfile;
|
|
}
|
|
|
|
protected:
|
|
|
|
#if (ARX>15)
|
|
std::fstream _libfile;
|
|
#else
|
|
fstream _libfile;
|
|
#endif
|
|
int openMode;
|
|
const TCHAR* slbfile;
|
|
const TCHAR* libExt, *itemExt;
|
|
const char* title;
|
|
};
|
|
|
|
static wchar_t * wstrchr_new(const wchar_t *string, int c,bool bToFile=true)
|
|
{
|
|
wchar_t *pstr = (wchar_t*)wcschr(string,c);
|
|
if (pstr == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
wchar_t *pstr1 = NULL,*pstr2 = NULL;
|
|
pstr1 = ++pstr;
|
|
while(1)
|
|
{
|
|
pstr2 = wcschr(pstr1,c);
|
|
if (pstr2 == NULL)
|
|
{
|
|
if (bToFile && c != '\\' && c != '/' && c != ':' && c != '*' && c != '?' && c != '"' && c != '<' && c != '>' && c != '|')
|
|
{
|
|
if ((pstr2 = wcschr(pstr1,'\\')) != NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
return --pstr;
|
|
}
|
|
else
|
|
{
|
|
pstr = pstr2;
|
|
pstr1 = ++pstr;
|
|
}
|
|
}
|
|
}
|
|
|
|
#define tstrchr_new wstrchr_new
|
|
|
|
CSlideLib::CSlideLib(const TCHAR *fname,int opMode)
|
|
: slbfile(fname), openMode(opMode)
|
|
{
|
|
itemExt = SLD_EXT;
|
|
title = "AutoCAD Slide Library 1.0";
|
|
|
|
libExt = wstrchr_new(fname, '.');
|
|
if (opMode)
|
|
{
|
|
Open(NULL, opMode);
|
|
}
|
|
}
|
|
|
|
CSlideLib::~CSlideLib()
|
|
{
|
|
|
|
}
|
|
|
|
static void CT_clear_strbuf(char *strbeg, int strsize)
|
|
{
|
|
int i;
|
|
for (i = 0; i<strsize; i++)
|
|
{
|
|
strbeg[i] = 0;
|
|
}
|
|
}
|
|
|
|
int CSlideLib::Open(const TCHAR *file, int mode)
|
|
{
|
|
openMode = mode;
|
|
if (file)
|
|
{
|
|
slbfile = file;
|
|
}
|
|
|
|
if (!slbfile || !openMode)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
TCHAR szFile[MAX_PATH];
|
|
int isExist = (ads_findfile(slbfile, szFile ) == RTNORM);
|
|
|
|
if (!isExist && !(mode & _ios::out))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#if (ARX>15)
|
|
if(!isExist)
|
|
{
|
|
int nTempMode = _ios::binary|_ios::out;
|
|
std::ofstream out(slbfile, nTempMode);
|
|
|
|
Catalogue entry;
|
|
CT_clear_strbuf(entry.itemName, 32 );
|
|
strcpy(entry.itemName,title);
|
|
|
|
entry.itemName[25] = 0x0d;
|
|
entry.itemName[26] = 0x0a;
|
|
entry.itemName[27] = 0x1a;
|
|
out.write(entry.itemName,32);
|
|
|
|
CT_clear_strbuf(entry.itemName, 32 );
|
|
entry.addr = 0L;
|
|
out.write((char*)&entry,36);
|
|
out.flush();
|
|
|
|
ads_printf(sMsgPrompt[0], (TCHAR *)slbfile);
|
|
|
|
isExist = TRUE;
|
|
}
|
|
#endif
|
|
|
|
_libfile.open(slbfile,mode);
|
|
if (!_libfile)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if(!isExist && (mode&_ios::out))
|
|
{
|
|
Catalogue entry;
|
|
CT_clear_strbuf(entry.itemName, 32 );
|
|
strcpy(entry.itemName,title);
|
|
|
|
entry.itemName[25] = 0x0d;
|
|
entry.itemName[26] = 0x0a;
|
|
entry.itemName[27] = 0x1a;
|
|
_libfile.write(entry.itemName,32);
|
|
|
|
CT_clear_strbuf(entry.itemName, 32 );
|
|
entry.addr = 0L;
|
|
_libfile.write((char*)&entry,36);
|
|
_libfile.flush();
|
|
|
|
ads_printf(sMsgPrompt[0], (TCHAR *)slbfile);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void CSlideLib::Close()
|
|
{
|
|
_libfile.close();
|
|
}
|
|
|
|
char* CSlideLib::ReadItem(const TCHAR *sldfile, unsigned *pnFileSize)
|
|
{
|
|
char szExt[16] = "";
|
|
|
|
//取得所有的目录
|
|
Catalogue entry[2];
|
|
entry[0].itemName[0] = entry[1].itemName[0] = 0;
|
|
|
|
_libfile.clear();
|
|
_libfile.seekg(32, _ios::beg);
|
|
Catalogue rec;
|
|
|
|
while(1)
|
|
{
|
|
_libfile.read((char *)&rec, 36);
|
|
if (!_libfile || !rec.itemName[0])
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
USES_CONVERSION;
|
|
const char* pszsldfile = W2A(sldfile);
|
|
|
|
if (_stricmp(rec.itemName, pszsldfile ) == 0)
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
szExt[i] = rec.itemName[16 + i];
|
|
}
|
|
|
|
szExt[3] = 0;
|
|
entry[0] = rec;
|
|
_libfile.read((char *)&entry[1], 36);
|
|
|
|
if (!entry[1].itemName[0])//最后一个记录
|
|
{
|
|
_libfile.seekg(0, _ios::end);
|
|
entry[1].addr = _libfile.tellg();
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
long sld_fsize = entry[1].addr - entry[0].addr;
|
|
_libfile.seekg(entry[0].addr, _ios::beg);
|
|
|
|
char * pItemBuf = new char [(int)sld_fsize];
|
|
_libfile.read(pItemBuf, (int)sld_fsize);
|
|
|
|
if (pnFileSize)
|
|
{
|
|
*pnFileSize = (unsigned)sld_fsize;
|
|
}
|
|
return pItemBuf;
|
|
}
|
|
|
|
CSlideDc::CSlideDc()
|
|
: m_bAutoScale(TRUE), m_bUniformScale(TRUE), m_bHighlight(FALSE)
|
|
{
|
|
m_pDC = NULL;
|
|
m_palDIB = NULL;
|
|
m_hDIB = NULL;
|
|
m_nIT = 2;
|
|
m_bkColor = RGB(0,0,0);
|
|
m_nRotation = 0.0;
|
|
}
|
|
|
|
CSlideDc::CSlideDc(CDC *pDC, const CRect &rect, COLORREF bkcolor)
|
|
: m_pDC(pDC), m_rectDC(rect), m_bAutoScale(TRUE), m_bUniformScale(TRUE), m_bHighlight(FALSE)
|
|
{
|
|
m_palDIB = NULL;
|
|
m_hDIB = NULL;
|
|
m_nIT = 2;//SLIDE
|
|
m_bkColor = bkcolor;
|
|
m_nRotation = 0.0;
|
|
}
|
|
|
|
CSlideDc::~CSlideDc()
|
|
{
|
|
if(m_palDIB)
|
|
{
|
|
delete m_palDIB;
|
|
}
|
|
if(m_hDIB)
|
|
{
|
|
::GlobalUnlock((HGLOBAL) m_hDIB);
|
|
::GlobalFree((HGLOBAL)m_hDIB);
|
|
}
|
|
Reset();
|
|
}
|
|
|
|
void CSlideDc::InitDC(CDC *pDC, const CRect &rect, COLORREF bkcolor/* = RGB(0,0,0)*/)
|
|
{
|
|
m_pDC = pDC;
|
|
m_rectDC = rect;
|
|
m_bkColor = bkcolor;
|
|
}
|
|
|
|
void CSlideDc::SetDC(CDC *pDc)
|
|
{
|
|
m_pDC = pDc;
|
|
}
|
|
|
|
void CSlideDc::Reset()
|
|
{
|
|
for (int i = 0;i < m_arLines.length();i++)
|
|
{
|
|
SLine* pLn = m_arLines.at(i);
|
|
if (pLn != NULL)
|
|
delete pLn;
|
|
}
|
|
m_arLines.removeAll();
|
|
|
|
for (int i = 0;i < m_arSolid.length();i++)
|
|
{
|
|
SSolid* pSld = m_arSolid.at(i);
|
|
if (pSld != NULL)
|
|
{
|
|
if (pSld->poly.nPts > 0)
|
|
delete [] pSld->poly.pts;
|
|
|
|
delete pSld;
|
|
}
|
|
}
|
|
m_arSolid.removeAll();
|
|
}
|
|
|
|
BOOL CSlideDc::PaintSlide(const TCHAR *pszSlideFile)
|
|
{
|
|
if(!m_pDC)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
m_nIT = 2;
|
|
Reset();
|
|
|
|
if(!pszSlideFile || !pszSlideFile[0])
|
|
{
|
|
Fill(RGB(192,192,192));
|
|
return TRUE;
|
|
}
|
|
|
|
if( ReadFromSlide(pszSlideFile) != RTNORM)
|
|
{
|
|
Fill(RGB(192,192,192));
|
|
return FALSE;
|
|
}
|
|
return PaintSlide();
|
|
}
|
|
|
|
static int SplitSlbName(const TCHAR *totalName, TCHAR *slbFile, TCHAR *sldFile)
|
|
{
|
|
if (!totalName || !slbFile || !sldFile)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
int nStrlen = wcslen(totalName) + 1;
|
|
TCHAR *fullName = new TCHAR[nStrlen];
|
|
memcpy(fullName, totalName, nStrlen * sizeof(TCHAR));
|
|
|
|
TCHAR *p1 = _tcschr(fullName,_T('('));
|
|
//acutPrintf(_T("\nfullname= %s"),totalName);
|
|
|
|
TCHAR dwgFile[256] = _T("");
|
|
if (p1)
|
|
{
|
|
*p1 = 0;
|
|
p1++;
|
|
_tcscpy(dwgFile, p1);
|
|
TCHAR *p2 = _tcschr(dwgFile, _T(')'));
|
|
if (p2)
|
|
{
|
|
*p2 = 0;
|
|
}
|
|
else
|
|
{
|
|
return RTERROR;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
_tcscpy(slbFile, fullName);
|
|
_tcscpy(sldFile, dwgFile);
|
|
|
|
delete [] fullName;
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
static int GetApplicationPath(TCHAR *vPath,HINSTANCE hInstance)
|
|
{
|
|
TCHAR fileName[MAX_PATH] = _T("");
|
|
|
|
GetModuleFileName(hInstance, fileName, MAX_PATH);
|
|
|
|
TCHAR drive[_MAX_DRIVE] = _T(""), dir[_MAX_DIR] = _T(""), fname[_MAX_FNAME] = _T(""),
|
|
ext[_MAX_EXT] = _T("");
|
|
_tsplitpath(fileName, drive, dir, fname, ext);
|
|
_tcscpy(vPath, drive);
|
|
_tcscat(vPath, dir);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int FindFile(const TCHAR *szFile, TCHAR * szPath)
|
|
{
|
|
//..//dwb/arch.slb
|
|
TCHAR szArxPath[MAX_PATH];
|
|
GetApplicationPath(szArxPath,_hdllInstance);
|
|
|
|
CString arx = szArxPath;
|
|
arx.TrimRight(_T('\\'));
|
|
CString sdwb = arx.Left(arx.ReverseFind(_T('\\')));
|
|
sdwb += _T("\\dwb");
|
|
|
|
CString sFile;
|
|
sFile.Format(_T("%s\\%s"),sdwb,szFile);
|
|
|
|
CFileFind find;
|
|
if (find.FindFile(sFile))
|
|
{
|
|
_tcscpy(szPath, sFile);
|
|
return 1;
|
|
}
|
|
else//sys下找
|
|
{
|
|
//然后sys下找
|
|
//...//sys/**.slb
|
|
sdwb = arx.Left(arx.ReverseFind(_T('\\')));
|
|
sdwb += _T("\\sys");
|
|
sFile.Format(_T("%s\\%s"),sdwb,szFile);
|
|
|
|
if (find.FindFile(sFile))
|
|
{
|
|
_tcscpy(szPath, sFile);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
CCharBuf::CCharBuf(char *pBuf, int nSize)
|
|
: m_pBuf(pBuf), m_nSize(nSize)
|
|
{
|
|
m_nPos = 0;
|
|
}
|
|
|
|
CCharBuf::~CCharBuf()
|
|
{
|
|
if (m_pBuf)
|
|
{
|
|
delete m_pBuf;
|
|
}
|
|
}
|
|
|
|
int CCharBuf::IsEOF()
|
|
{
|
|
return (m_nPos >= m_nSize);
|
|
}
|
|
|
|
int CCharBuf::operator !()
|
|
{
|
|
return (!m_pBuf || IsEOF());
|
|
}
|
|
|
|
int CCharBuf::Read(void *pDest, int nCount)
|
|
{
|
|
if (m_nPos + nCount > m_nSize)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
memcpy(pDest, &m_pBuf[m_nPos], nCount);
|
|
m_nPos += nCount;
|
|
|
|
return 1;
|
|
}
|
|
|
|
BOOL CSlideDc::ReadFromSlide(const TCHAR *pszSlide)
|
|
{
|
|
TCHAR szSlb[MAX_PATH] = _T(""), szSld[MAX_PATH] = _T("");
|
|
char *pBuf = NULL;
|
|
unsigned nLen = 0;
|
|
|
|
if (SplitSlbName(pszSlide, szSlb, szSld) != RTNORM)
|
|
{
|
|
if (!FindFile(pszSlide, szSld))
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
//acutPrintf(_T("\nsld = %s"),szSld);
|
|
|
|
FILE *fp = _tfopen(szSld, _T("rb"));
|
|
if (!fp)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
nLen = (unsigned) _filelength(_fileno(fp));
|
|
pBuf = new char [nLen];
|
|
|
|
fread(pBuf,sizeof(char),nLen,fp);
|
|
fclose(fp);
|
|
}
|
|
else
|
|
{
|
|
TCHAR *pExt = tstrchr_new(szSlb, '.');
|
|
|
|
if (!pExt)
|
|
{
|
|
_tcscat(szSlb, _T(".SLB"));
|
|
}
|
|
|
|
TCHAR szSlbPath[MAX_PATH] = _T("");
|
|
if (!FindFile(szSlb, szSlbPath))
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
CSlideLib slb(szSlbPath, _ios::binary|_ios::in);
|
|
if (!slb)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
pBuf = slb.ReadItem(szSld, &nLen);
|
|
if (!pBuf)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
}
|
|
|
|
CCharBuf iBuffer(pBuf, nLen);
|
|
|
|
char cvalue[1];
|
|
double pt[20],
|
|
lst[2];
|
|
short tvalue[1],
|
|
nverts[1];
|
|
char String[SLIDE_MAXSLDRLEN * 2 + 1],
|
|
*cp1;
|
|
short fi1,
|
|
color;
|
|
|
|
double ar1,
|
|
ar2;
|
|
long aspect;
|
|
POINT *points = NULL;
|
|
BOOL testflag;
|
|
|
|
iBuffer.Read(String,SLIDE_MAXSLDRLEN);
|
|
if (_strnicmp(String,SLIDE_ACADSLIDE,strlen(SLIDE_ACADSLIDE) != 0)
|
|
|| String[18] < 1
|
|
|| String[18] > 2)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
cp1 = (char *)(&fi1);
|
|
*(cp1) = *((char *)(String + 29));
|
|
*(cp1 + 1) = *((char *)(String + 30));
|
|
|
|
testflag = (SLIDE_TEST_NUMBER == fi1) ? FALSE : TRUE;
|
|
|
|
if (testflag)
|
|
{
|
|
cp1 = (char *)(&fi1);
|
|
*(cp1 + 1) = *((char *)(String + 19));
|
|
*(cp1) = *((char *)(String + 20));
|
|
}
|
|
else
|
|
{
|
|
fi1 = *((short *)(String + 19));
|
|
}
|
|
|
|
ar1 = fi1;
|
|
|
|
if (testflag)
|
|
{
|
|
cp1 = (char *)(&fi1);
|
|
*(cp1 + 1) = *((char *)(String + 21));
|
|
*(cp1) = *((char *)(String + 22));
|
|
}
|
|
else
|
|
{
|
|
fi1 = *((short *)(String + 21));
|
|
}
|
|
|
|
ar2 = fi1;
|
|
|
|
aspect = *((long *)(String + 23));
|
|
|
|
for (;;)
|
|
{
|
|
iBuffer.Read(String,2);
|
|
switch(String[(testflag) ? 0 : 1])
|
|
{
|
|
case SLIDE_OFFSETVECTOR:
|
|
{
|
|
iBuffer.Read(String + 2, 3);
|
|
|
|
memcpy(cvalue,String + ((testflag) ? 1 : 0),sizeof(char));
|
|
pt[0] = lst[0] + (double)cvalue[0];
|
|
|
|
memcpy(cvalue,String + 2,sizeof(char));
|
|
pt[1] = lst[1] + (double)cvalue[0];
|
|
|
|
memcpy(cvalue,String + 3,sizeof(char));
|
|
pt[2] = lst[0] + (double)cvalue[0];
|
|
|
|
memcpy(cvalue,String + 4,sizeof(char));
|
|
pt[3] = lst[1] + (double)cvalue[0];
|
|
|
|
// 保存最后一点
|
|
lst[0] = pt[0];
|
|
lst[1] = pt[1];
|
|
|
|
SLine* pLn = new SLine;
|
|
pLn->pt1.x = pt[0];
|
|
pLn->pt1.y = pt[1];
|
|
pLn->pt1.z = 0.0;
|
|
|
|
pLn->pt2.x = pt[2];
|
|
pLn->pt2.y = pt[3];
|
|
pLn->pt2.z = 0.0;
|
|
|
|
pLn->nColorIndex = color;
|
|
m_arLines.append(pLn);
|
|
|
|
break;
|
|
}
|
|
case SLIDE_ENDOFFILE:
|
|
goto err;
|
|
case SLIDE_SOLIDFILL:
|
|
iBuffer.Read(String,4);
|
|
if (testflag)
|
|
{
|
|
cp1 = (char *)(&fi1);
|
|
*(cp1 + 1) = *((char *)(String + 1));
|
|
*(cp1) = *((char *)(String));
|
|
|
|
nverts[0] = (short)cp1;
|
|
}
|
|
else
|
|
{
|
|
memcpy(nverts,String,sizeof(short));
|
|
}
|
|
|
|
if (testflag)
|
|
{
|
|
cp1 = (char *)(&fi1);
|
|
*(cp1 + 1) = *((char *)(String + 3));
|
|
*(cp1) = *((char *)(String + 2));
|
|
|
|
tvalue[0] = (short)cp1;
|
|
}
|
|
else
|
|
{
|
|
memcpy(tvalue,String + 2,sizeof(short));
|
|
}
|
|
|
|
if (nverts[0] > 1 && (2 * nverts[0]) <= sizeof(pt) / sizeof(pt[0]) && tvalue[0] < 0)
|
|
{
|
|
if ((points = (POINT *)calloc(nverts[0],sizeof(POINT))) == NULL)
|
|
{
|
|
ASSERT(false);
|
|
goto err;
|
|
}
|
|
|
|
for (fi1 = 0; fi1 < nverts[0]; ++fi1)
|
|
{
|
|
iBuffer.Read(String,2);
|
|
if (String[(testflag) ? 0 : 1] != SLIDE_SOLIDFILL)
|
|
{
|
|
goto err;
|
|
}
|
|
|
|
iBuffer.Read(String,4);
|
|
|
|
if (testflag)
|
|
{
|
|
cp1 = (char *)(&fi1);
|
|
*(cp1 + 1) = *((char *)(String + 1));
|
|
*(cp1) = *((char *)(String));
|
|
|
|
tvalue[0] = (short)cp1;
|
|
}
|
|
else
|
|
{
|
|
memcpy(tvalue,String,sizeof(short));
|
|
}
|
|
|
|
pt[fi1 * 2] = tvalue[0];
|
|
|
|
if (testflag)
|
|
{
|
|
cp1 = (char *)(&fi1);
|
|
*(cp1 + 1) = *((char *)(String + 1));
|
|
*(cp1) = *((char *)(String));
|
|
|
|
tvalue[0] = (short)cp1;
|
|
}
|
|
else
|
|
{
|
|
memcpy(tvalue,String + 2,sizeof(short));
|
|
}
|
|
|
|
pt[fi1 * 2 + 1] = tvalue[0];
|
|
|
|
if (pt[fi1 * 2 + 1] < 0)
|
|
{
|
|
if (fi1 != nverts[0] - 1)
|
|
{
|
|
ASSERT(false);
|
|
goto err;
|
|
}
|
|
|
|
nverts[0]--;
|
|
}
|
|
|
|
points[fi1].x = (long)pt[fi1 * 2];
|
|
points[fi1].y = (long)pt[fi1 * 2 + 1];
|
|
}
|
|
|
|
SPoly poly;
|
|
poly.nPts = *nverts;
|
|
poly.pts = new SPoint[*nverts];
|
|
for (int kk = 0; kk < *nverts; kk++)
|
|
{
|
|
poly.pts[kk].x = points[kk].x;
|
|
poly.pts[kk].y = points[kk].y;
|
|
}
|
|
|
|
SSolid* pSolid = new SSolid;
|
|
pSolid->poly.nPts = poly.nPts;
|
|
pSolid->poly.pts = poly.pts;
|
|
pSolid->nColorIndex = color;
|
|
m_arSolid.append(pSolid);
|
|
|
|
free(points);
|
|
points = NULL;
|
|
}
|
|
break;
|
|
case SLIDE_COMMONENDVECTOR:
|
|
{
|
|
iBuffer.Read(String + 2, 1);
|
|
pt[0] = lst[0];
|
|
pt[1] = lst[1];
|
|
|
|
memcpy(cvalue, String + ((testflag) ? 1 : 0), sizeof(char));
|
|
lst[0] = pt[2] = pt[0] + (double)cvalue[0];
|
|
memcpy(cvalue,String + 2,sizeof(char));
|
|
lst[1] = pt[3] = pt[1] + (double)cvalue[0];
|
|
|
|
SLine* pLn = new SLine;
|
|
pLn->pt1.x = pt[0];
|
|
pLn->pt1.y = pt[1];
|
|
pLn->pt1.z = 0.0;
|
|
|
|
pLn->pt2.x = pt[2];
|
|
pLn->pt2.y = pt[3];
|
|
pLn->pt2.z = 0.0;
|
|
|
|
pLn->nColorIndex = color;
|
|
m_arLines.append(pLn);
|
|
|
|
break;
|
|
}
|
|
case SLIDE_NEWCOLOR:
|
|
color = String[(testflag) ? 1 : 0];
|
|
if (color < 0)
|
|
{
|
|
color = 256 + color;
|
|
}
|
|
|
|
if (color > 255 || color < 0)
|
|
{
|
|
color = 7;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
if (String[(testflag) ? 0 : 1] < 0)
|
|
{
|
|
goto err;
|
|
}
|
|
|
|
if (testflag)
|
|
{
|
|
memcpy((char *)tvalue, String + 1, sizeof(char));
|
|
memcpy((char *)tvalue + 1, String, sizeof(char));
|
|
}
|
|
else
|
|
{
|
|
memcpy(tvalue, String, sizeof(short));
|
|
}
|
|
|
|
pt[0] = (double)tvalue[0];
|
|
for (fi1 = 1; fi1 < 4; ++fi1)
|
|
{
|
|
iBuffer.Read(String,2);
|
|
|
|
if (testflag)
|
|
{
|
|
memcpy((char *)tvalue, String + 1, sizeof(char));
|
|
memcpy((char *)tvalue + 1, String, sizeof(char));
|
|
}
|
|
else
|
|
{
|
|
memcpy(tvalue, String, sizeof(short));
|
|
}
|
|
|
|
pt[fi1] = (double)tvalue[0];
|
|
}
|
|
|
|
lst[0] = pt[0];
|
|
lst[1] = pt[1];
|
|
|
|
SLine* pLn = new SLine;
|
|
pLn->pt1.x = pt[0];
|
|
pLn->pt1.y = pt[1];
|
|
pLn->pt1.z = 0.0;
|
|
|
|
pLn->pt2.x = pt[2];
|
|
pLn->pt2.y = pt[3];
|
|
pLn->pt2.z = 0.0;
|
|
|
|
pLn->nColorIndex = color;
|
|
m_arLines.append(pLn);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
err:
|
|
ASSERT(!points);
|
|
return RTNORM;
|
|
}
|
|
|
|
void CSlideDc::Fill(COLORREF cref)
|
|
{
|
|
if(!m_pDC)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(!cref)
|
|
{
|
|
m_pDC->FillSolidRect(&m_rectDC, m_bkColor);
|
|
}
|
|
else
|
|
{
|
|
m_pDC->FillSolidRect(&m_rectDC, cref);
|
|
}
|
|
}
|
|
|
|
|
|
static void InitRotationMatrix(ads_real dRot, ads_matrix mat)
|
|
{
|
|
ads_matrix matRot =
|
|
{
|
|
{cos(dRot), -sin(dRot), 0, 0},
|
|
{sin(dRot), cos(dRot), 0, 0},
|
|
{0, 0, 1, 0},
|
|
{0, 0, 0, 1}
|
|
};
|
|
memcpy(mat, matRot, sizeof(matRot));
|
|
}
|
|
|
|
static void AT_xformpt(ads_matrix xform,ads_point pt,ads_point newpt)
|
|
{
|
|
int i,j;
|
|
ads_point pt0;
|
|
|
|
newpt[X] = newpt[Y] = newpt[Z] = 0.0;
|
|
Cpoint(pt0, pt);
|
|
|
|
for (i = X; i <= Z; i++)
|
|
{
|
|
for (j = X; j <= Z; j++)
|
|
{
|
|
newpt[i] += xform[i][j] * pt0[j];
|
|
}
|
|
newpt[i] += xform[i][T];
|
|
}
|
|
}
|
|
|
|
static void TransformBy(SPoint& spt,ads_matrix mat)
|
|
{
|
|
ads_point pt,ptnew;
|
|
pt[X] = spt.x;pt[Y] = spt.y;pt[Z]=spt.z;
|
|
AT_xformpt(mat,pt,ptnew);
|
|
spt.x = ptnew[X];spt.y = ptnew[Y];spt.z = ptnew[Z];
|
|
}
|
|
|
|
static void TransUCS(SSolid* pSolid,ads_matrix mat)
|
|
{
|
|
int nLen = pSolid->poly.nPts;
|
|
for (int i = 0; i < nLen; i++)
|
|
{
|
|
SPoint& spt = pSolid->poly.pts[i];
|
|
TransformBy(spt,mat);
|
|
}
|
|
}
|
|
|
|
static SPoint Max(const SPoint &pt1, const SPoint &pt2)
|
|
{
|
|
SPoint upPt;
|
|
upPt.x = max(pt1.x, pt2.x);
|
|
upPt.y = max(pt1.y, pt2.y);
|
|
upPt.z = max(pt1.z, pt2.z);
|
|
return upPt;
|
|
}
|
|
|
|
static SPoint Min(const SPoint &pt1, const SPoint &pt2)
|
|
{
|
|
SPoint lowPt;
|
|
lowPt.x = min(pt1.x, pt2.x);
|
|
lowPt.y = min(pt1.y, pt2.y);
|
|
lowPt.z = min(pt1.z, pt2.z);
|
|
return lowPt;
|
|
}
|
|
|
|
static int GetExtend(SLine* pLn,SPoint &ptlow, SPoint &ptup)
|
|
{
|
|
SPoint ptStart = pLn->pt1;
|
|
SPoint ptEnd = pLn->pt2;
|
|
|
|
ptlow = Min(ptStart, ptEnd);
|
|
ptup = Max(ptStart, ptEnd);
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
static int GetExtend(SSolid* pSolid,SPoint &ptlow1, SPoint &ptup1)
|
|
{
|
|
if (pSolid->poly.nPts == 0)
|
|
return RTNONE;
|
|
|
|
SPoint ptLow,ptUp;
|
|
ptLow = ptUp = pSolid->poly.pts[0];
|
|
|
|
for(int i = 1;i < pSolid->poly.nPts;i++)
|
|
{
|
|
SPoint& ptCur = pSolid->poly.pts[i];
|
|
ptLow = Min(ptLow, ptCur);
|
|
ptUp = Max(ptUp, ptCur);
|
|
}
|
|
ptlow1 = ptLow;
|
|
ptup1 = ptUp;
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
static int GetExtend(AcArray<SSolid*>& arSolids,AcArray<SLine*>& arLines,SPoint &ptLow, SPoint &ptUp)
|
|
{
|
|
if (arSolids.isEmpty() && arLines.isEmpty())
|
|
return RTERROR;
|
|
|
|
BOOL bInit = FALSE;
|
|
for (int i = 0; i < arLines.length(); i++)
|
|
{
|
|
SLine* pLn = arLines.at(i);
|
|
SPoint pt1,pt2;
|
|
GetExtend(pLn,pt1,pt2);
|
|
|
|
if (!bInit)
|
|
{
|
|
ptLow = pt1;
|
|
ptUp = pt2;
|
|
bInit = TRUE;
|
|
}
|
|
else
|
|
{
|
|
ptLow = Min(pt1, ptLow);
|
|
ptUp = Max(pt2, ptUp);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < arSolids.length(); i++)
|
|
{
|
|
SSolid* pSolid = arSolids.at(i);
|
|
SPoint pt1, pt2;
|
|
GetExtend(pSolid,pt1,pt2);
|
|
|
|
if (!bInit)
|
|
{
|
|
ptLow = pt1;
|
|
ptUp = pt2;
|
|
bInit = TRUE;
|
|
}
|
|
else
|
|
{
|
|
ptLow = Min(pt1, ptLow);
|
|
ptUp = Max(pt2, ptUp);
|
|
}
|
|
}
|
|
return RTNORM;
|
|
}
|
|
|
|
static void WcsToDcs(AcArray<SSolid*>& arSolids,AcArray<SLine*>& arLines,int m_nSizeX, int m_nSizeY, int m_nOffset)
|
|
{
|
|
m_nSizeX -= m_nOffset * 2;
|
|
m_nSizeY -= m_nOffset * 2;
|
|
|
|
SPoint ptLow, ptUp;
|
|
if (GetExtend(arSolids,arLines,ptLow, ptUp) != RTNORM)
|
|
{
|
|
return;
|
|
}
|
|
|
|
SPoint m_ptOrg = ptLow;
|
|
ads_real m_nModelX = ptUp.x - ptLow.x;
|
|
ads_real m_nModelY = ptUp.y - ptLow.y;
|
|
|
|
ads_real nScaleX = m_nModelX > 1.0E-6 ? m_nSizeX / m_nModelX : 1.0,
|
|
nScaleY = m_nModelY > 1.0E-6 ? m_nSizeY / m_nModelY : 1.0;
|
|
ads_real nMoveX = 0, nMoveY = 0; // 平移到中心的距离
|
|
|
|
nScaleX = nScaleY = min(nScaleX, nScaleY);
|
|
nMoveX = (m_nSizeX - nScaleX * m_nModelX) / 2.0;
|
|
nMoveY = (m_nSizeY - nScaleY * m_nModelY) / 2.0;
|
|
|
|
AcArray<SLine*> &lstMe = arLines;
|
|
for (int i = 0; i < lstMe.length(); i++)
|
|
{
|
|
SLine* pLn = lstMe.at(i);
|
|
for (int j = 0; j < 2; j++)
|
|
{
|
|
SPoint &ptModel = j ? pLn->pt2 : pLn->pt1;
|
|
SPoint ptImage;
|
|
ptImage.x = (ptModel.x - m_ptOrg.x) * nScaleX;
|
|
ptImage.y = (ptModel.y - m_ptOrg.y) * nScaleY;
|
|
ptImage.x += m_nOffset + nMoveX;
|
|
ptImage.y += m_nOffset + nMoveY;
|
|
|
|
// Y翻转
|
|
ptImage.y = (m_nSizeY + 2 * m_nOffset) - ptImage.y;
|
|
ptModel = ptImage;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < arSolids.length(); i++)
|
|
{
|
|
SSolid* pSolid = arSolids.at(i);
|
|
|
|
for (int j = 0; j < pSolid->poly.nPts; j++)
|
|
{
|
|
SPoint &ptModel = pSolid->poly.pts[j];
|
|
SPoint ptImage;
|
|
ptImage.x = (ptModel.x - m_ptOrg.x) * nScaleX;
|
|
ptImage.y = (ptModel.y - m_ptOrg.y) * nScaleY;
|
|
ptImage.x += m_nOffset + nMoveX;
|
|
ptImage.y += m_nOffset + nMoveY;
|
|
|
|
// Y翻转
|
|
ptImage.y = (m_nSizeY + 2 * m_nOffset) - ptImage.y;
|
|
ptModel = ptImage;
|
|
}
|
|
}
|
|
}
|
|
|
|
struct r_g_b
|
|
{
|
|
ads_real red, blue, green;
|
|
};
|
|
|
|
static void acadrgb(int hsv, struct r_g_b *rgp)
|
|
{
|
|
static double brightfac[5] = { 1.0, 0.65, 0.5, 0.3, 0.15 }; /* Brightness levels */
|
|
static double halfsat = .5; /* Halfway saturation */
|
|
int ih, vs;
|
|
double h, s, f, value;
|
|
|
|
// assert(hsv > 0 || hsv < 256);
|
|
|
|
switch (hsv)
|
|
{
|
|
case 0:
|
|
rgp->red = 0.0;
|
|
rgp->blue = 0.0;
|
|
rgp->green = 0.0;
|
|
value = 0.0;
|
|
break;
|
|
|
|
case 1:
|
|
rgp->red = 1.0;
|
|
rgp->green = 0.0;
|
|
rgp->blue = 0.0;
|
|
value = 1.0;
|
|
break;
|
|
|
|
case 2:
|
|
rgp->red = 1.0;
|
|
rgp->green = 1.0;
|
|
rgp->blue = 0.0;
|
|
value = 1.0;
|
|
break;
|
|
|
|
case 3:
|
|
rgp->red = 0.0;
|
|
rgp->green = 1.0;
|
|
rgp->blue = 0.0;
|
|
value = 1.0;
|
|
break;
|
|
|
|
case 4:
|
|
rgp->red = 0.0;
|
|
rgp->green = 1.0;
|
|
rgp->blue = 1.0;
|
|
value = 1.0;
|
|
break;
|
|
|
|
case 5:
|
|
rgp->red = 0.0;
|
|
rgp->green = 0.0;
|
|
rgp->blue = 1.0;
|
|
value = 1.0;
|
|
break;
|
|
|
|
case 6:
|
|
rgp->red = 1.0;
|
|
rgp->green = 0.0;
|
|
rgp->blue = 1.0;
|
|
value = 1.0;
|
|
break;
|
|
|
|
case 7:
|
|
case 8:
|
|
case 9:
|
|
rgp->red = 1.0;
|
|
rgp->green = 1.0;
|
|
rgp->blue = 1.0;
|
|
value = 1.0;
|
|
break;
|
|
|
|
default:
|
|
if (hsv > 9 && hsv < 250)
|
|
{
|
|
/* Apply the algorithm from Foley & van Dam to turn HSV into RGB values */
|
|
ih = (hsv - 10) / 10; /* Integer hue value. */
|
|
if (ih >= 24) /* Range is 0-23. */
|
|
{
|
|
ih -= 24;
|
|
}
|
|
vs = hsv % 10; /* Encoded value and saturation */
|
|
h = ih / 4.; /* Map into range [0.0,6.0) */
|
|
ih = (int)h; /* The integer part. */
|
|
f = h - ih; /* Fractional part. */
|
|
value = brightfac[vs >> 1]; /* Value in [0,1] */
|
|
s = vs & 1 ? halfsat : 1.0; /* Saturation */
|
|
|
|
switch (ih)
|
|
{
|
|
case 0:
|
|
rgp->red = 1.0;
|
|
rgp->green = (double) (1.0 - s * (1.0 - f));
|
|
rgp->blue = (double) (1.0 - s);
|
|
break;
|
|
|
|
case 1:
|
|
rgp->red = (double) (1.0 - s * f);
|
|
rgp->green = 1.0;
|
|
rgp->blue = (double) (1 - s);
|
|
break;
|
|
|
|
case 2:
|
|
rgp->red = (double) (1.0 - s);
|
|
rgp->green = 1.0;
|
|
rgp->blue = (double) (1.0 - s *(1.0 - f));
|
|
break;
|
|
|
|
case 3:
|
|
rgp->red = (double) (1.0 - s);
|
|
rgp->green = (double) (1.0 - s * f);
|
|
rgp->blue = 1.0;
|
|
break;
|
|
|
|
case 4:
|
|
rgp->red = (double) (1.0 - s * (1.0 - f));
|
|
rgp->green = (double) (1.0 - s);
|
|
rgp->blue = 1.0;
|
|
break;
|
|
|
|
case 5:
|
|
rgp->red = 1.0;
|
|
rgp->green = (double) (1.0 - s);
|
|
rgp->blue = (double) (1.0 - s * f);
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Define some extra colours from dark grey to white in the 250 to 255 slots */
|
|
value = 0.33 + (hsv - 250) * 0.134;
|
|
rgp->red = 1.0;
|
|
rgp->green = 1.0;
|
|
rgp->blue = 1.0;
|
|
}
|
|
break; /* Default */
|
|
}
|
|
rgp->red *= value; /* Apply lightness scale factor */
|
|
rgp->green *= value; /* to components resulting from */
|
|
rgp->blue *= value; /* hue and saturation. */
|
|
}
|
|
|
|
static void ColorToRGB(int nAcadColor, int *nR, int *nG, int *nB)
|
|
{
|
|
r_g_b rgb;
|
|
acadrgb(nAcadColor, &rgb);
|
|
*nR = AS_INT(255*rgb.red);
|
|
*nG = AS_INT(255*rgb.green);
|
|
*nB = AS_INT(255*rgb.blue);
|
|
}
|
|
|
|
BOOL CSlideDc::PaintSlide()
|
|
{
|
|
if(!m_pDC)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(m_arLines.isEmpty() && m_arSolid.isEmpty())
|
|
{
|
|
Fill(RGB(192,192,192));
|
|
return FALSE;
|
|
}
|
|
|
|
if(m_bHighlight)
|
|
{
|
|
Fill(RGB(0,128,192));
|
|
}
|
|
else
|
|
{
|
|
Fill(m_bkColor);
|
|
}
|
|
|
|
if(fabs(m_nRotation) > 1.0E-6)
|
|
{
|
|
ads_matrix mat;
|
|
InitRotationMatrix(m_nRotation, mat);
|
|
|
|
for(int n = 0; n < m_arLines.length(); n++)
|
|
{
|
|
SLine* pLn = m_arLines.at(n);
|
|
SPoint ptSta = pLn->pt1;
|
|
SPoint ptEnd = pLn->pt2;
|
|
TransformBy(ptSta,mat);
|
|
TransformBy(ptEnd,mat);
|
|
pLn->pt1 = ptSta;
|
|
pLn->pt2 = ptEnd;
|
|
}
|
|
|
|
for(n = 0; n < m_arSolid.length(); n++)
|
|
{
|
|
SSolid* pSolid = m_arSolid.at(n);
|
|
TransUCS(pSolid,mat);
|
|
}
|
|
}
|
|
|
|
WcsToDcs(m_arSolid,m_arLines,m_rectDC.Width(), m_rectDC.Height(), 5);
|
|
|
|
for(int i = m_arLines.length() - 1; i >= 0; i--)
|
|
{
|
|
SLine* pLn = m_arLines.at(i);
|
|
CPoint ptStart(m_rectDC.left + AS_INT(pLn->pt1.x), m_rectDC.top + AS_INT(pLn->pt1.y));
|
|
CPoint ptEnd(m_rectDC.left + AS_INT(pLn->pt2.x), m_rectDC.top + AS_INT(pLn->pt2.y));
|
|
int nR, nG, nB;
|
|
ColorToRGB(pLn->nColorIndex, &nR, &nG, &nB);
|
|
|
|
if(m_bkColor == RGB(255,255,255))
|
|
{
|
|
nR = 255 - nR;
|
|
nG = 255 - nG;
|
|
nB = 255 - nB;
|
|
}
|
|
|
|
CPen pen(PS_SOLID, 1, RGB(nR, nG, nB));
|
|
CPen *pOld = m_pDC->SelectObject(&pen);
|
|
|
|
m_pDC->MoveTo(ptStart);
|
|
if(ptStart == ptEnd)
|
|
{
|
|
ptEnd.x += 1;
|
|
ptEnd.y += 1;
|
|
}
|
|
m_pDC->LineTo(ptEnd);
|
|
m_pDC->SelectObject(pOld);
|
|
}
|
|
|
|
for(i = 0; i < m_arSolid.length(); i++)
|
|
{
|
|
SSolid* pSolid = m_arSolid.at(i);
|
|
|
|
int nR, nG, nB;
|
|
ColorToRGB(pSolid->nColorIndex, &nR, &nG, &nB);
|
|
|
|
if(m_bkColor == RGB(255,255,255))
|
|
{//白底
|
|
nR = 255 - nR;
|
|
nG = 255 - nG;
|
|
nB = 255 - nB;
|
|
}
|
|
|
|
CBrush brush;
|
|
brush.CreateSolidBrush(RGB(nR,nG,nB));
|
|
|
|
CBrush *pOld = m_pDC->SelectObject(&brush);
|
|
|
|
CPoint *verts = new CPoint[pSolid->poly.nPts];
|
|
for(int j = 0; j < pSolid->poly.nPts; j++)
|
|
{
|
|
SPoint pt = pSolid->poly.pts[j];
|
|
verts[j].x = m_rectDC.left + AS_INT(pt.x);
|
|
verts[j].y = m_rectDC.top + AS_INT(pt.y);
|
|
}
|
|
|
|
CRgn rgn;
|
|
rgn.CreatePolygonRgn(verts,pSolid->poly.nPts,ALTERNATE);
|
|
|
|
m_pDC->FillRgn(&rgn,&brush);
|
|
m_pDC->SelectObject(pOld);
|
|
brush.DeleteObject();
|
|
}
|
|
m_nIT = 2;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CSlideDc::Redraw()
|
|
{
|
|
if(m_nIT == 2)
|
|
{
|
|
return PaintSlide();
|
|
}
|
|
else
|
|
{
|
|
Fill(RGB(192,192,192));
|
|
}
|
|
return FALSE;
|
|
} |