void SImageWnd::OnPaint(IRenderTarget *pRT) { CRect rcWnd = GetWindowRect(); if(m_pImg) { CRect rcImg(CPoint(0,0),m_pImg->Size()); pRT->DrawBitmapEx(rcWnd,m_pImg,&rcImg,MAKELONG(EM_STRETCH,m_fl)); } else if (m_pSkin) m_pSkin->Draw(pRT, rcWnd, m_iFrame); }
/**< display image full fit wnd */ bool ImagePanel::ImgZoomFit() { if (!m_img.IsOk()) return false; wxRect2DDouble rcWnd(0.0, 0.0, 0.0, 0.0); // wnd rect wxRect2DDouble rcImg(0.0, 0.0, 0.0, 0.0); // img rect do { wxSize szWnd = GetClientSize(); wxSize szImg = m_img.GetSize(); rcWnd.m_width = szWnd.GetWidth(); rcWnd.m_height = szWnd.GetHeight(); rcImg.m_width = szImg.GetWidth(); rcImg.m_height = szImg.GetHeight(); } while(false); // image is full displayed m_rcSrc.m_x = 0.0; m_rcSrc.m_y = 0.0; m_rcSrc.m_width = rcImg.m_width; m_rcSrc.m_height = rcImg.m_height; // calculation scale and dest rect if (rcWnd.m_width/rcWnd.m_height > rcImg.m_width/rcImg.m_height) // wnd is wide then image, or image is heigher then wnd { wxDouble dTmp = 0.0; m_dScale = rcWnd.m_height/rcImg.m_height; dTmp = rcImg.m_width*m_dScale; // image scale width m_rcDest.m_x = (rcWnd.m_width - dTmp)/2.0; m_rcDest.m_y = 0.0; m_rcDest.m_width = dTmp; m_rcDest.m_height = rcWnd.m_height; } else // wnd is heigher than image, or image is wide than wnd { wxDouble dTmp = 0.0; m_dScale = rcWnd.m_width/rcImg.m_width; dTmp = rcImg.m_height*m_dScale; // image scale height m_rcDest.m_x = 0.0; m_rcDest.m_y = (rcWnd.m_height - dTmp)/2.0; m_rcDest.m_width = rcWnd.m_width; m_rcDest.m_height = dTmp; } // update panel Refresh(false); return true; }
/* OnDraw() */ void CWallBrowserStretchView::OnDraw(CDC* pDC) { // documento CWallBrowserDoc* pDoc = (CWallBrowserDoc*)GetDocument(); if(!pDoc) return; // nome file memset(m_szFileName,'\0',sizeof(m_szFileName)); strcpyn(m_szFileName,pDoc->GetFileName(),sizeof(m_szFileName)); if(m_szFileName[0]=='\0') return; // immagine CImage *pImage = pDoc->GetImage(); if(pImage && pImage->GetWidth() > 0 && pImage->GetHeight() > 0) m_ImageDraw.SetImage(pImage); else return; // immagine valida if(!pDoc->GetPictureFlag()) return; // dimensione corrente della vista GetClientRect(&m_rcClient); // adatta l'immagine alla dimensione corrente della vista double nRemains = 0.0; double nWidth = (double)pImage->GetWidth(); double nHeight = (double)pImage->GetHeight(); if(nHeight > (double)m_rcClient.bottom) { nRemains = FDIV(nHeight,(double)m_rcClient.bottom); if(nRemains > 0.0) { nHeight = FDIV(nHeight,nRemains); nWidth = FDIV(nWidth,nRemains); } } if(nWidth > (double)m_rcClient.right) { nRemains = FDIV(nWidth,(double)m_rcClient.right); if(nRemains > 0.0) { nHeight = FDIV(nHeight,nRemains); nWidth = FDIV(nWidth,nRemains); } } m_rcInvalid.SetRect(0,0,(int)nWidth,(int)nHeight); // nome del file if(m_pMainFrameStatusBar) { strcpyn(m_szStatus,pDoc->GetFileName(),sizeof(m_szStatus)); m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_FILENAME_ID,m_szStatus); } double nFactor = 0.0; char szFactor[8] = {0}; if(m_nViewType==VIEWTYPE_SCROLL) { nFactor = GetZoomRatio(); if(nFactor >= 1.0) sprintf(szFactor,"%.2f:1",nFactor); else sprintf(szFactor,"1:%.2f",1/nFactor); } // fattore di zoom e % di visualizzazione dell'immagine nella vista int nRatio = (int)((nWidth * 100.0)/pImage->GetWidth()); if(m_pMainFrameStatusBar) { m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_ZOOM_ID,szFactor); if(m_nViewType==VIEWTYPE_STRETCH) _snprintf(m_szStatus,sizeof(m_szStatus)-1,"%d%% (stretch)",nRatio); else _snprintf(m_szStatus,sizeof(m_szStatus)-1,"%.1f%% (scroll)",nFactor * 100.0); m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_RATIO_ID,m_szStatus); } // area della vista (client rect) m_rcClient.right = (int)nWidth; m_rcClient.bottom = (int)nHeight; // ricava le informazioni per il titolo char szTitle[_MAX_PATH+1] = {0}; int nColors = pImage->GetNumColors(); if(m_nViewType==VIEWTYPE_STRETCH) _snprintf(szFactor,sizeof(szFactor)-1,"%d%%",nRatio); _snprintf(szTitle, sizeof(szTitle)-1, "%s (%s) - %d x %d x %d%s", pDoc->GetFileName(), szFactor, pImage->GetWidth(), pImage->GetHeight(), (nColors > 256 || nColors==0) ? 16 : nColors, (nColors > 256 || nColors==0) ? "M" : "" ); pDoc->SetTitle(szTitle); // ricava le informazioni per la status bar if(m_pMainFrameStatusBar) { int nColors = pImage->GetNumColors(); _snprintf(m_szStatus, sizeof(m_szStatus)-1, "%d x %d x %d%s colors, %d bpp", pImage->GetWidth(), pImage->GetHeight(), (nColors > 256 || nColors==0) ? 16 : nColors, (nColors > 256 || nColors==0) ? "M" : "", pImage->GetBPP() ); m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_INFO_ID,m_szStatus); UINT nMemUsed = pImage->GetMemUsed(); if(nMemUsed < 1024L) _snprintf(m_szStatus,sizeof(m_szStatus)-1,"%ld bytes",nMemUsed); else if(nMemUsed < 1048576L) _snprintf(m_szStatus,sizeof(m_szStatus)-1,"%0.1f KB",FDIV(((float)nMemUsed),1024.0f)); else _snprintf(m_szStatus,sizeof(m_szStatus)-1,"%0.2f MB",FDIV(((float)nMemUsed),1048576.0f)); m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_MEM_ID,m_szStatus); strcpyn(m_szStatus,pImage->GetLibraryName(),sizeof(m_szStatus)); m_pMainFrameStatusBar->SetPaneText(ID_INDICATOR_LIBRARY_ID,m_szStatus); } // area dell'immagine CRect rcImg(0,0,pImage->GetWidth(),pImage->GetHeight()); // se per la vista deve usare lo scroll, imposta le aree in modo tale che vengano visualizzate le barre di scorrimento if(m_nViewType==VIEWTYPE_SCROLL) m_rcClient = rcImg; // visualizza l'immagine scalata rispetto alla dimensione corrente della vista m_ImageDraw.DrawEx(pDC->GetSafeHdc(), &m_rcClient, &rcImg, NULL, FALSE, COLORONCOLOR, m_nDrawMode, SRCCOPY, m_bRebuildPalette ); m_bRebuildPalette = FALSE; }
/**< move image */ bool ImagePanel::ImgMove(wxSize szMove) { if (!m_img.IsOk()) return false; // the move size must be valid if (szMove.x == 0 || szMove.y == 0) return false; wxPoint2DDouble ptMove(szMove.x, szMove.y); wxRect2DDouble rcWnd(0.0, 0.0, 0.0, 0.0); // wnd rect wxRect2DDouble rcImg(0.0, 0.0, 0.0, 0.0); // img rect do { wxSize szWnd = GetClientSize(); wxSize szImg = m_img.GetSize(); rcWnd.m_width = szWnd.GetWidth(); rcWnd.m_height = szWnd.GetHeight(); rcImg.m_width = szImg.GetWidth(); rcImg.m_height = szImg.GetHeight(); } while(false); // current image rect in wnd coordinate wxRect2DDouble rcNew; rcNew.m_x = m_rcDest.m_x - m_rcSrc.m_x*m_dScale; rcNew.m_y = m_rcDest.m_y - m_rcSrc.m_y*m_dScale; rcNew.m_width = rcImg.m_width*m_dScale; rcNew.m_height = rcImg.m_height*m_dScale; // then horizontal move the rect if ((rcNew.m_x + ptMove.m_x) > rcWnd.m_width/2.0) ptMove.m_x = (int)(rcWnd.m_width/2.0 - rcNew.m_x); else if ((rcNew.GetRight() + ptMove.m_x) <= rcWnd.m_width/2.0) ptMove.m_x = (int)(rcWnd.m_width/2.0 - rcNew.GetRight()); // and then vertical move the rect if ((rcNew.m_y + ptMove.m_y) > rcWnd.m_height/2.0) ptMove.m_y = (int)(rcWnd.m_height/2.0 - rcNew.m_y); else if ((rcNew.GetBottom() + ptMove.m_y) <= rcWnd.m_height/2.0) ptMove.m_y = (int)(rcWnd.m_height/2.0 - rcNew.GetBottom()); rcNew.Offset(ptMove); // the dest rect is the intersection of new rect and wnd rect wxRect2DDouble::Intersect(rcNew, rcWnd, &m_rcDest); // calculate the src rect m_rcSrc.m_x = (m_rcDest.m_x - rcNew.m_x)/m_dScale; m_rcSrc.m_y = (m_rcDest.m_y - rcNew.m_y)/m_dScale; m_rcSrc.m_width = m_rcDest.m_width/m_dScale; m_rcSrc.m_height = m_rcDest.m_height/m_dScale; // ensure the src rect is valid if (m_rcSrc.m_x < 0.0) m_rcSrc.m_x = 0.0; if (m_rcSrc.m_y < 0.0) m_rcSrc.m_y = 0.0; if (m_rcSrc.GetRight() > rcImg.m_width) m_rcSrc.m_width = rcImg.m_width - m_rcSrc.m_x; if (m_rcSrc.GetBottom() > rcImg.m_height) m_rcSrc.m_height = rcImg.m_height - m_rcSrc.m_y; // update panel Refresh(false); return true; }
/**< dispaly image in real size */ bool ImagePanel::ImgZoomActual() { if (!m_img.IsOk()) return false; wxRect2DDouble rcWnd(0.0, 0.0, 0.0, 0.0); // wnd rect wxRect2DDouble rcImg(0.0, 0.0, 0.0, 0.0); // img rect do { wxSize szWnd = GetClientSize(); wxSize szImg = m_img.GetSize(); rcWnd.m_width = szWnd.GetWidth(); rcWnd.m_height = szWnd.GetHeight(); rcImg.m_width = szImg.GetWidth(); rcImg.m_height = szImg.GetHeight(); } while(false); // image is actual size displayed m_dScale = 1.0; // Horizontal positioning if (rcWnd.m_width > rcImg.m_width) { m_rcSrc.m_x = 0.0; m_rcSrc.m_width = rcImg.m_width; // wnd left and right have space m_rcDest.m_x = (rcWnd.m_width - rcImg.m_width)/2.0; m_rcDest.m_width = rcImg.m_width; } else { // only part of image be displayed m_rcSrc.m_x = (rcImg.m_width - rcWnd.m_width)/2.0; m_rcSrc.m_width = rcWnd.m_width; // wnd is filled width m_rcDest.m_x = 0.0; m_rcDest.m_width = rcWnd.m_width; } // Vertical positioning if (rcWnd.m_height > rcImg.m_height) { m_rcSrc.m_y = 0.0; m_rcSrc.m_height = rcImg.m_height; // wnd's top and bottom have space m_rcDest.m_y = (rcWnd.m_height - rcImg.m_height)/2.0; m_rcDest.m_height = rcImg.m_height; } else { // only part image be displayed m_rcSrc.m_y = (rcImg.m_height - rcWnd.m_height)/2.0; m_rcSrc.m_height = rcWnd.m_height; // wnd is fill height m_rcDest.m_y = 0.0; m_rcDest.m_height = rcWnd.m_height; } // update panel Refresh(false); return true; }
/**< display image of sel rect full fit wnd */ bool ImagePanel::ImgZoomRect(wxRect rcSel) { if (!m_img.IsOk()) return false; // the rect must be regular if (rcSel.width <= 2 || rcSel.height < 2) return false; wxRect2DDouble rcWnd(0.0, 0.0, 0.0, 0.0); // wnd rect wxRect2DDouble rcImg(0.0, 0.0, 0.0, 0.0); // image rect do { wxSize szWnd = GetClientSize(); wxSize szImg = m_img.GetSize(); rcWnd.m_width = szWnd.GetWidth(); rcWnd.m_height = szWnd.GetHeight(); rcImg.m_width = szImg.GetWidth(); rcImg.m_height = szImg.GetHeight(); } while(false); // calculate the new scale wxDouble dScale = 1.0; if (rcWnd.m_width/rcWnd.m_height > rcSel.width/(wxDouble)rcSel.height) dScale = rcWnd.m_height/rcSel.height; else dScale = rcWnd.m_width/rcSel.width; dScale *= m_dScale; if (dScale > 20.0) dScale = 20.0; // sel rect center point wxPoint2DDouble ptV0, ptI0; ptV0.m_x = rcSel.x + rcSel.width/2.0; ptV0.m_y = rcSel.y + rcSel.height/2.0; ptI0.m_x = m_rcSrc.m_x + (ptV0.m_x - m_rcDest.m_x)/m_dScale; ptI0.m_y = m_rcSrc.m_y + (ptV0.m_y - m_rcDest.m_y)/m_dScale; // calculate the new image rect in wnd coordinate wxRect2DDouble rcNew; rcNew.m_x = ptV0.m_x - ptI0.m_x*dScale; rcNew.m_y = ptV0.m_y - ptI0.m_y*dScale; rcNew.m_width = rcImg.m_width*dScale; rcNew.m_height = rcImg.m_height*dScale; // move the sel rect center to the wnd center rcNew.m_x -= ptV0.m_x - rcWnd.m_width/2.0; rcNew.m_y -= ptV0.m_y - rcWnd.m_height/2.0; ptV0.m_x = rcWnd.m_width/2.0; ptV0.m_y = rcWnd.m_height/2.0; // the dest rect is the intersection of the new image view rect & wnd rect wxRect2DDouble::Intersect(rcWnd, rcNew, &m_rcDest); // calculate the src rect m_rcSrc.m_x = ptI0.m_x + (m_rcDest.m_x - ptV0.m_x)/dScale; m_rcSrc.m_y = ptI0.m_y + (m_rcDest.m_y - ptV0.m_y)/dScale; m_rcSrc.m_width = m_rcDest.m_width/dScale; m_rcSrc.m_height = m_rcDest.m_height/dScale; // ensure the src rect is valid if (m_rcSrc.m_x < 0.0) m_rcSrc.m_x = 0.0; if (m_rcSrc.m_y < 0.0) m_rcSrc.m_y = 0.0; if (m_rcSrc.GetRight() > rcImg.m_width) m_rcSrc.m_width = rcImg.m_width - m_rcSrc.m_x; if (m_rcSrc.GetBottom() > rcImg.m_height) m_rcSrc.m_height = rcImg.m_height - m_rcSrc.m_y; // the new scale m_dScale = dScale; // update ui Refresh(false); return true; }
/**< on wnd resized */ void ImagePanel::OnSize(wxSizeEvent& event) { if (!m_img.IsOk()) return; // ensure the new size is valid if (event.m_size.x < 2 || event.m_size.y < 2) return; // the center move of the wnd wxPoint2DDouble szMove; szMove.m_x = (event.m_size.x - m_szClient.x)/2.0; szMove.m_y = (event.m_size.y - m_szClient.y)/2.0; wxRect2DDouble rcImg(0.0, 0.0, 0.0, 0.0); // img rect wxRect2DDouble rcWnd(0.0, 0.0, event.m_size.x, event.m_size.y); // new wnd rect do { wxSize szImg = m_img.GetSize(); rcImg.m_width = szImg.GetWidth(); rcImg.m_height = szImg.GetHeight(); } while(false); // current image rect in wnd coordinate wxRect2DDouble rcNew; rcNew.m_x = m_rcDest.m_x - m_rcSrc.m_x*m_dScale; rcNew.m_y = m_rcDest.m_y - m_rcSrc.m_y*m_dScale; rcNew.m_width = rcImg.m_width*m_dScale; rcNew.m_height = rcImg.m_height*m_dScale; // then horizontal move the rect if ((rcNew.m_x + szMove.m_x) > rcWnd.m_width/2.0) szMove.m_x = (int)(rcWnd.m_width/2.0 - rcNew.m_x); else if ((rcNew.GetRight() + szMove.m_x) <= rcWnd.m_width/2.0) szMove.m_x = (int)(rcWnd.m_width/2.0 - rcNew.GetRight()); // and then vertical move the rect if ((rcNew.m_y + szMove.m_y) > rcWnd.m_height/2.0) szMove.m_y = (int)(rcWnd.m_height/2.0 - rcNew.m_y); else if ((rcNew.GetBottom() + szMove.m_y) <= rcWnd.m_height/2.0) szMove.m_y = (int)(rcWnd.m_height/2.0 - rcNew.GetBottom()); rcNew.Offset(szMove); // the dest rect is the intersection of new rect and wnd rect wxRect2DDouble::Intersect(rcNew, rcWnd, &m_rcDest); // calculate the src rect m_rcSrc.m_x = (m_rcDest.m_x - rcNew.m_x)/m_dScale; m_rcSrc.m_y = (m_rcDest.m_y - rcNew.m_y)/m_dScale; m_rcSrc.m_width = m_rcDest.m_width/m_dScale; m_rcSrc.m_height = m_rcDest.m_height/m_dScale; // ensure the src rect is valid if (m_rcSrc.m_x < 0.0) m_rcSrc.m_x = 0.0; if (m_rcSrc.m_y < 0.0) m_rcSrc.m_y = 0.0; if (m_rcSrc.GetRight() > rcImg.m_width) m_rcSrc.m_width = rcImg.m_width - m_rcSrc.m_x; if (m_rcSrc.GetBottom() > rcImg.m_height) m_rcSrc.m_height = rcImg.m_height - m_rcSrc.m_y; // log the size m_szClient = event.m_size; // update panel //Refresh(false); }
/**< according to the specified zoom percentage */ bool ImagePanel::ImgZoomScale(wxDouble dScale, wxPoint* pPt /*= nullptr*/) { if (!m_img.IsOk()) return false; if (dScale <= 0.0) return false; if (dScale > 20.0) dScale = 20.0; wxRect2DDouble rcWnd(0.0, 0.0, 0.0, 0.0); // wnd rect wxRect2DDouble rcImg(0.0, 0.0, 0.0, 0.0); // img rect do { wxSize szWnd = GetClientSize(); wxSize szImg = m_img.GetSize(); rcWnd.m_width = szWnd.GetWidth(); rcWnd.m_height = szWnd.GetHeight(); rcImg.m_width = szImg.GetWidth(); rcImg.m_height = szImg.GetHeight(); } while(false); // default image pix in wnd center as the fixed point wxPoint2DDouble ptV0, ptI0; wxDouble dTmp = 0.0; if (pPt == nullptr) { ptV0.m_x = rcWnd.m_width/2.0; ptV0.m_y = rcWnd.m_height/2.0; } else { ptV0.m_x = pPt->x; ptV0.m_y = pPt->y; } dTmp = (ptV0.m_x - m_rcDest.m_x)/m_dScale; // V2I ptI0.m_x = m_rcSrc.m_x + dTmp; dTmp = (ptV0.m_y - m_rcDest.m_y)/m_dScale; ptI0.m_y = m_rcSrc.m_y + dTmp; // the image view rect in new scale wxRect2DDouble rcNew; rcNew.m_x = ptV0.m_x - ptI0.m_x*dScale; rcNew.m_y = ptV0.m_y - ptI0.m_y*dScale; rcNew.m_width = rcImg.m_width*dScale; rcNew.m_height = rcImg.m_height*dScale; // Dest rect is the intersection of new image view rect & wnd rect wxRect2DDouble::Intersect(rcWnd, rcNew, &m_rcDest); // the src rect in new scale m_rcSrc.m_x = ptI0.m_x + (m_rcDest.m_x - ptV0.m_x)/dScale; m_rcSrc.m_y = ptI0.m_y + (m_rcDest.m_y - ptV0.m_y)/dScale; m_rcSrc.m_width = m_rcDest.m_width/dScale; m_rcSrc.m_height = m_rcDest.m_height/dScale; // ensure the src rect is valid if (m_rcSrc.m_x < 0.0) m_rcSrc.m_x = 0.0; if (m_rcSrc.m_y < 0.0) m_rcSrc.m_y = 0.0; if (m_rcSrc.GetRight() > rcImg.m_width) m_rcSrc.m_width = rcImg.m_width - m_rcSrc.m_x; if (m_rcSrc.GetBottom() > rcImg.m_height) m_rcSrc.m_height = rcImg.m_height - m_rcSrc.m_y; // new zoom scale m_dScale = dScale; // update panel Refresh(false); return true; }