#include "stdafx.h" #include "SlideDc.h" #include #include #include #include #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; i15) 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& arSolids,AcArray& 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& arSolids,AcArray& 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 &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; }