Files
envi-code/SourceCode/Code2026/CoreCommand/SlideDc.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

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;
}