//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd. // = FileName : TImageDrawDC 类 // = Version : ver2.0 // = Author : wlw // = CreateDate : 2002-09-09 // = Description: TImageDrawDC 定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "globalFunc.h" #include "TImageDrawDC.h" #include "TGGiJpegStorage.h" #include "TGGiBitmapStorage.h" #include "io.h" #include "PushMemVar.h" #include "AString.h" namespace { struct STColorRGB { ads_real red, blue, green; }; void acadrgb(int hsv, struct STColorRGB *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. */ } void ColorToRGB(int nAcadColor, int *nR, int *nG, int *nB) { STColorRGB rgb; acadrgb(nAcadColor, &rgb); *nR = AS_INT(255 * rgb.red); *nG = AS_INT(255 * rgb.green); *nB = AS_INT(255 * rgb.blue); } BOOL SplitLibraryPath(const TCHAR *totalName, TCHAR *slbFile, TCHAR *sldFile) { if (!totalName || !slbFile || !sldFile) { return FALSE; } TCString fullName = totalName; TCHAR *p1 = fullName._StrChr(_T('(')); TCHAR dwgFile[80] = _T(""); if (p1) { *p1 = 0; p1++; _tcscpy(dwgFile, p1); TCHAR *p2 = _tcschr(dwgFile, _T(')')); if (p2) { *p2 = 0; } else { return FALSE; } } else { return FALSE; } _tcscpy(slbFile, fullName); _tcscpy(sldFile, dwgFile); return TRUE; } } TImageDrawDC::TImageDrawDC() : m_bAutoScale(TRUE), m_bUniformScale(TRUE), m_bHighlight(FALSE) { m_pDC = NULL; m_palDIB = NULL; m_hDIB = NULL; m_nIT = IT_NONE; m_bkColor = RGB(0,0,0); m_nRotation = 0.0; m_nMirror = 0; } TImageDrawDC::TImageDrawDC(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 = IT_NONE; m_bkColor = bkcolor; m_nRotation = 0.0; m_nMirror = 0; } TImageDrawDC::~TImageDrawDC() { if(m_palDIB) { delete m_palDIB; } if(m_hDIB) { ::GlobalUnlock((HGLOBAL) m_hDIB); ::GlobalFree((HGLOBAL)m_hDIB); } } void TImageDrawDC::SetSlideMirror(int nXY) { m_nMirror = nXY; } void TImageDrawDC::SetAutoScale(BOOL bAuto) { m_bAutoScale = bAuto; } void TImageDrawDC::SetUniformScale(BOOL bTrue) { m_bUniformScale = bTrue; } void TImageDrawDC::GetRectDC(CRect &rectDC) const { rectDC = m_rectDC; } void TImageDrawDC::SetRectDC(const CRect &rect) { m_rectDC = rect; } void TImageDrawDC::SetDC(CDC *pDc) { m_pDC = pDc; } void TImageDrawDC::SetRotation(double nRot) { m_nRotation = nRot; } void TImageDrawDC::SetBackColor(COLORREF co) { m_bkColor = co; } BOOL TImageDrawDC::IsImageLoaded() { return (m_hDIB ? TRUE : FALSE); } BOOL TImageDrawDC::IsHighlight() const { return m_bHighlight; } void TImageDrawDC::SetHighlight(BOOL bTrue) { m_bHighlight = bTrue; } void TImageDrawDC::InitDC(CDC *pDC, const CRect &rect, COLORREF bkcolor/*=RGB(0,0,0)*/) { m_pDC = pDC; m_rectDC = rect; m_bkColor = bkcolor; } COLORREF TImageDrawDC::GetBkColor() { return m_bkColor; } BOOL TImageDrawDC::PaintJpeg(const TCHAR *pJpgFile) { m_nIT = IT_BITMAP; if(m_palDIB) { delete m_palDIB; } if(m_hDIB) { ::GlobalUnlock((HGLOBAL) m_hDIB); ::GlobalFree((HGLOBAL)m_hDIB); } m_palDIB = NULL; m_hDIB = NULL; if(!pJpgFile || !pJpgFile[0]) { Fill(RGB(192,192,192)); return TRUE; } TCString sLib, sJpg; if(!SplitLibraryPath(pJpgFile, sLib, sJpg)) { return PaintImageOnly(pJpgFile); } TCString strFilePath(256); strFilePath << sLib << _T(".JPB"); TGGiJpegStorage lib(strFilePath, std::ios_base::in|std::ios_base::binary); TCString sTempPath(256); GetTempPath(255, sTempPath); int nStrLen=_tcslen(sTempPath); if(nStrLen && sTempPath[nStrLen-1] != _T('\\')) { sTempPath << _T("\\"); } sTempPath << sJpg; int nRet = lib.QuickCopy(sTempPath); if(nRet) { sTempPath << _T(".JPG"); } else { Fill(m_bkColor); return FALSE; } BOOL bRet = PaintImageOnly(sTempPath); _tremove(sTempPath); return bRet; } // pszImageFile FullPath of Image file, like: // A.BMP, A.JPG, A(a1) // Support BMP, JPG format (both stand along or from LIB) // if pszImageFile == NULL, then clear it BOOL TImageDrawDC::PaintImage(const TCHAR *pszImageFile) { m_nIT = IT_BITMAP; if(m_palDIB) { delete m_palDIB; } if(m_hDIB) { ::GlobalUnlock((HGLOBAL) m_hDIB); ::GlobalFree((HGLOBAL)m_hDIB); } m_palDIB = NULL; m_hDIB = NULL; if(!pszImageFile || !pszImageFile[0]) { Fill(RGB(192,192,192)); return TRUE; } TCString sLib, sJpg; if(!SplitLibraryPath(pszImageFile, sLib, sJpg)) { return PaintImageOnly(pszImageFile); } TCString strFilePath(256); strFilePath << sLib << _T(".BMB"); TGGiBitmapStorage lib(strFilePath, std::ios_base::in|std::ios_base::binary); TCString sTempPath(256); GetTempPath(255, sTempPath); int nStrLen = _tcslen(sTempPath); if(nStrLen && sTempPath[nStrLen-1] != _T('\\')) { sTempPath << _T("\\"); } sTempPath << sJpg; int nRet = lib.QuickCopy(sTempPath); if(nRet == 1) { sTempPath << _T(".BMP"); } else if(nRet == 2) { sTempPath << _T(".JPG"); } else { Fill(m_bkColor); return FALSE; } BOOL bRet = PaintImageOnly(sTempPath); _tremove(sTempPath); return bRet; } BOOL TImageDrawDC::PaintDIB(HDIB hDib) // DIB is keep here { if(m_palDIB) { delete m_palDIB; } if(m_hDIB) { ::GlobalUnlock((HGLOBAL) m_hDIB); ::GlobalFree((HGLOBAL)m_hDIB); } m_hDIB=hDib; m_palDIB = new CPalette; ::CreateDIBPalette(m_hDIB, m_palDIB); m_nIT = IT_BITMAP; return PaintImage(); } // Paint Image, not include from LIB BOOL TImageDrawDC::PaintImageOnly(const TCHAR *pszFile) { /*m_nIT = IT_BITMAP; if(m_palDIB) { delete m_palDIB; } if(m_hDIB) { ::GlobalUnlock((HGLOBAL) m_hDIB); ::GlobalFree((HGLOBAL)m_hDIB); } m_palDIB = NULL; m_hDIB = NULL; SplitpathOperator parser(pszFile); const TCHAR *pszExt = parser.m_sExt; if(!pszExt[0]) { return FALSE; } if(_tcsicmp(pszExt, _T(".BMP")) == 0) { CFile file; if (!file.Open(pszFile, CFile::modeRead | CFile::shareDenyWrite)) { return FALSE; } m_hDIB = ::ReadDIBFile(file); } else if(_tcsicmp(pszExt, _T(".JPG")) == 0) { m_hDIB = (HDIB)CTangentImage::ReadJpeg(pszFile); } else { m_hDIB = (HDIB)CTangentImage::GetCopyToHandle(pszFile, CXIMAGE_FORMAT_BMP); if (m_hDIB) return FALSE; if(_tcsicmp(pszExt, _T(".gif")) == 0 || _tcsicmp(pszExt, _T(".tga")) == 0) { int nImgType=(_tcsicmp(pszExt, _T(".gif")) == 0 ? 1 : 2); TCString sTempFile=GetTempFileName(_T(".jpg")); int nType = (1 == nImgType) ? CXIMAGE_FORMAT_GIF : CXIMAGE_FORMAT_TGA; BOOL bRet = CTangentImage::WriteJpeg(pszFile, sTempFile, nType); if(bRet) { bRet=PaintImageOnly(sTempFile); } _tremove(sTempFile); return bRet; } } m_palDIB = new CPalette; ::CreateDIBPalette(m_hDIB, m_palDIB);*/ return PaintImage(); } BOOL TImageDrawDC::GetImageSize(CSize &sizeImage) const { if(!m_hDIB || !m_palDIB) return FALSE; LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB); sizeImage.cx = (int) ::DIBWidth(lpDIB); // Size of DIB - x sizeImage.cy = (int) ::DIBHeight(lpDIB); // Size of DIB - y ::GlobalUnlock((HGLOBAL) m_hDIB); return TRUE; } BOOL TImageDrawDC::PaintImage() { if(!m_pDC) { return FALSE; } m_nIT = IT_BITMAP; if(!m_hDIB || !m_palDIB) { Fill(RGB(192,192,192)); return FALSE; } Fill(m_bkColor); LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB); int cxDIB = (int) ::DIBWidth(lpDIB); // Size of DIB - x int cyDIB = (int) ::DIBHeight(lpDIB); // Size of DIB - y ::GlobalUnlock((HGLOBAL) m_hDIB); CRect rcDIB; rcDIB.top = rcDIB.left = 0; rcDIB.right = cxDIB; rcDIB.bottom = cyDIB; if(!m_bAutoScale) { CRect rectDest = m_rectDC; rectDest.right = rectDest.left + cxDIB; rectDest.bottom = rectDest.top + cyDIB; ::PaintDIB(m_pDC->m_hDC, &rectDest, m_hDIB, &rcDIB, m_palDIB); } else if(m_bUniformScale) { // Do uniform scale, so adjust rectDC CRect rectDC = m_rectDC; double nWidthDIB = rcDIB.Width(), nWidthDC=m_rectDC.Width(), nHeightDIB = rcDIB.Height(), nHeightDC = m_rectDC.Height(); double nScale = min(nWidthDC / nWidthDIB, nHeightDC / nHeightDIB); // 平移到中心的距离 double nMoveX=0, nMoveY=0; nMoveX = (m_rectDC.Width() - nScale * rcDIB.Width()) / 2.0; nMoveY = (m_rectDC.Height() - nScale * rcDIB.Height()) / 2.0; rectDC.DeflateRect(int(nMoveX), int(nMoveY)); ::PaintDIB(m_pDC->m_hDC, &rectDC, m_hDIB, &rcDIB, m_palDIB); } else { // not uniform scale CRect rectDest=m_rectDC; ::PaintDIB(m_pDC->m_hDC, &rectDest, m_hDIB, &rcDIB, m_palDIB); } if(m_bHighlight) { CRect rect = m_rectDC; m_pDC->Draw3dRect(rect,RGB(128,128,128),RGB(240,240,240)); //3D rect.DeflateRect(1, 1); m_pDC->Draw3dRect(rect,RGB(128,128,128),RGB(240,240,240)); //3D rect.DeflateRect(1,1); CBrush brush(RGB(255,0,0)); m_pDC->FrameRect(&rect, &brush); rect.DeflateRect(1,1); m_pDC->FrameRect(&rect, &brush); } else { CBrush brush(GetBkColor()); CRect rect = m_rectDC; m_pDC->FrameRect(&rect, &brush); rect.DeflateRect(1,1); m_pDC->FrameRect(&rect, &brush); rect.DeflateRect(1,1); m_pDC->FrameRect(&rect, &brush); rect.DeflateRect(1,1); m_pDC->FrameRect(&rect, &brush); } return TRUE; } BOOL TImageDrawDC::PaintSlide(const TCHAR *pszSlideFile) { if(!m_pDC) { return FALSE; } m_nIT = IT_SLIDE; m_slide.Reset(); if(!pszSlideFile || !pszSlideFile[0]) { Fill(RGB(192,192,192)); return TRUE; } if(m_slide.FromSlide(pszSlideFile) != RTNORM) { Fill(RGB(192,192,192)); return FALSE; } return PaintSlide(); } BOOL TImageDrawDC::PaintSlide() { if(!m_pDC) { return FALSE; } if(!m_slide) { Fill(RGB(192,192,192)); return FALSE; } if(m_bHighlight) { Fill(RGB(0,128,192)); } else { Fill(m_bkColor); } TGGeColorLineList lstVectors; lstVectors = m_slide; ads_matrix mat; if(fabs(m_nRotation) > 1.0E-6) { ADSGePoint3d().GetRotationMatrix(m_nRotation, mat); for(int n = 0; n < lstVectors.Length(); n++) { TGGeColorLine &buf = *lstVectors[n]; ADSGePoint3d ptStart = buf.GetStartPoint(), ptEnd = buf.GetEndPoint(); ptStart.TransformBy(mat); ptEnd.TransformBy(mat); buf.SetStartPoint(ptStart); buf.SetEndPoint(ptEnd); } for(n = 0; n < lstVectors.m_lstSolid.Length(); n++) { TGGeColorSolid &buf = *lstVectors.m_lstSolid[n]; buf.TransUCS(mat); } } if (m_nMirror > 0) {//镜像 1时为y轴镜像,2时为x轴镜像,3时xy一起镜像 AcGePoint3d pt(0,0,0),ptx(1,0,0),pty(0,1,0); AcGeLine3d lnmiry,lnmirx; lnmiry.set(pt, pty); lnmirx.set(pt, ptx); AcGeMatrix3d mat3d,mat3dy,mat3dx; mat3dy.setToMirroring(lnmiry); mat3dx.setToMirroring(lnmirx); if (m_nMirror == 1) { mat3d = mat3dy; GlobalFunc::AsAdsMatrix(mat3d, mat); } if (m_nMirror == 2) { mat3d = mat3dx; GlobalFunc::AsAdsMatrix(mat3d, mat); } if (m_nMirror == 3) { mat3d = mat3dy * mat3dx; GlobalFunc::AsAdsMatrix(mat3d, mat); } GlobalFunc::AsAdsMatrix(mat3d, mat); for(int n = 0; n < lstVectors.Length(); n++) { TGGeColorLine &buf = *lstVectors[n]; buf.TransformBy(mat); } for(n = 0; n < lstVectors.m_lstSolid.Length(); n++) { TGGeColorSolid &bufs = *lstVectors.m_lstSolid[n]; bufs.TransUCS(mat); } } lstVectors.WcsToDcs(m_rectDC.Width(), m_rectDC.Height(), 5); for(int i = lstVectors.Length() - 1; i >= 0; i--) { TGGeColorLine &buf=*lstVectors[i]; CPoint ptStart(m_rectDC.left + AS_INT(buf.GetStartPoint().x), m_rectDC.top + AS_INT(buf.GetStartPoint().y)); CPoint ptEnd(m_rectDC.left + AS_INT(buf.GetEndPoint().x), m_rectDC.top + AS_INT(buf.GetEndPoint().y)); int nR, nG, nB; ColorToRGB(buf.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 < lstVectors.m_lstSolid.Length(); i++) { TGGeColorSolid &ln = *lstVectors.m_lstSolid[i]; int nR, nG, nB; ColorToRGB(ln.m_nColor, &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[ln.Length()]; for(int j = 0; j < ln.Length(); j++) { ADSGePoint3d pt = *ln[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,ln.Length(),ALTERNATE); m_pDC->FillRgn(&rgn,&brush); m_pDC->SelectObject(pOld); brush.DeleteObject(); } m_nIT = IT_SLIDE; return TRUE; } BOOL TImageDrawDC::PaintBitmap(CBitmap &bmp) { if(!m_pDC || !bmp.GetSafeHandle()) { return FALSE; } BITMAP bmpInfo; bmp.GetBitmap(&bmpInfo); CDC dcTmp; dcTmp.CreateCompatibleDC(m_pDC); dcTmp.SelectObject(&bmp); m_pDC->StretchBlt(m_rectDC.left, m_rectDC.top, m_rectDC.Width(), m_rectDC.Height(), &dcTmp, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, SRCCOPY); return TRUE; } // Refresh the image BOOL TImageDrawDC::Redraw() { //Fill(m_bkColor); if(m_nIT == IT_SLIDE) { return PaintSlide(); } else if(m_nIT == IT_BITMAP) { return PaintImage(); } else { Fill(RGB(192,192,192)); } return FALSE; } void TImageDrawDC::Fill(COLORREF cref) { if(!m_pDC) { return; } if(!cref) { m_pDC->FillSolidRect(&m_rectDC, m_bkColor); } else { m_pDC->FillSolidRect(&m_rectDC, cref); } } BOOL TImageDrawDC::PaintImageNormal(const TCHAR * pszImageFile) { return TRUE; } BOOL TImageDrawDC::PaintImageOnlyNormal(const TCHAR * pszImageFile) { return TRUE; }