void _cairo_win32_display_surface_unset_clip (cairo_win32_display_surface_t *surface) { XFORM saved_xform; int gm = GetGraphicsMode (surface->win32.dc); if (gm == GM_ADVANCED) { GetWorldTransform (surface->win32.dc, &saved_xform); ModifyWorldTransform (surface->win32.dc, NULL, MWT_IDENTITY); } /* initial_clip_rgn will either be a real region or NULL (which means reset to no clip region) */ SelectClipRgn (surface->win32.dc, surface->initial_clip_rgn); if (surface->had_simple_clip) { /* then if we had a simple clip, intersect */ IntersectClipRect (surface->win32.dc, surface->win32.extents.x, surface->win32.extents.y, surface->win32.extents.x + surface->win32.extents.width, surface->win32.extents.y + surface->win32.extents.height); } if (gm == GM_ADVANCED) SetWorldTransform (surface->win32.dc, &saved_xform); }
BOOL WINAPI SetWorldTransform( HDC hDC, CONST XFORM *Xform ) { /* FIXME shall we add undoc #define MWT_SETXFORM 4 ?? */ return ModifyWorldTransform( hDC, Xform, MWT_MAX+1); }
void GraphicsContextPlatformPrivate::concatCTM(const AffineTransform& transform) { if (!m_hdc) return; XFORM xform = transform.toTransformationMatrix(); ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
void GraphicsContextPlatformPrivate::translate(float x , float y) { if (!m_hdc) return; XFORM xform = TransformationMatrix().translate(x, y); ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
void GraphicsContextPlatformPrivate::scale(const FloatSize& size) { if (!m_hdc) return; XFORM xform = TransformationMatrix().scaleNonUniform(size.width(), size.height()); ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
static cairo_int_status_t _cairo_win32_save_initial_clip (HDC hdc, cairo_win32_display_surface_t *surface) { RECT rect; int clipBoxType; int gm; XFORM saved_xform; /* GetClipBox/GetClipRgn and friends interact badly with a world transform * set. GetClipBox returns values in logical (transformed) coordinates; * it's unclear what GetClipRgn returns, because the region is empty in the * case of a SIMPLEREGION clip, but I assume device (untransformed) coordinates. * Similarly, IntersectClipRect works in logical units, whereas SelectClipRgn * works in device units. * * So, avoid the whole mess and get rid of the world transform * while we store our initial data and when we restore initial coordinates. * * XXX we may need to modify x/y by the ViewportOrg or WindowOrg * here in GM_COMPATIBLE; unclear. */ gm = GetGraphicsMode (hdc); if (gm == GM_ADVANCED) { GetWorldTransform (hdc, &saved_xform); ModifyWorldTransform (hdc, NULL, MWT_IDENTITY); } clipBoxType = GetClipBox (hdc, &rect); if (clipBoxType == ERROR) { _cairo_win32_print_gdi_error (__FUNCTION__); SetGraphicsMode (hdc, gm); /* XXX: Can we make a more reasonable guess at the error cause here? */ return _cairo_error (CAIRO_STATUS_DEVICE_ERROR); } surface->win32.extents.x = rect.left; surface->win32.extents.y = rect.top; surface->win32.extents.width = rect.right - rect.left; surface->win32.extents.height = rect.bottom - rect.top; surface->initial_clip_rgn = NULL; surface->had_simple_clip = FALSE; if (clipBoxType == COMPLEXREGION) { surface->initial_clip_rgn = CreateRectRgn (0, 0, 0, 0); if (GetClipRgn (hdc, surface->initial_clip_rgn) <= 0) { DeleteObject(surface->initial_clip_rgn); surface->initial_clip_rgn = NULL; } } else if (clipBoxType == SIMPLEREGION) { surface->had_simple_clip = TRUE; } if (gm == GM_ADVANCED) SetWorldTransform (hdc, &saved_xform); return CAIRO_STATUS_SUCCESS; }
static void test_modify_world_transform(void) { HDC hdc = GetDC(0); int ret; ret = SetGraphicsMode(hdc, GM_ADVANCED); ok(ret, "ret = %d\n", ret); ret = ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); ok(ret, "ret = %d\n", ret); ret = ModifyWorldTransform(hdc, NULL, MWT_LEFTMULTIPLY); ok(!ret, "ret = %d\n", ret); ret = ModifyWorldTransform(hdc, NULL, MWT_RIGHTMULTIPLY); ok(!ret, "ret = %d\n", ret); ReleaseDC(0, hdc); }
HFONT CRetrySplashScreen::CreateDialogFont (HDC hdc, TCHAR *szFaceName, int ptSize, DWORD dwWeight, BOOL bUnderline) { POINT pt; FLOAT cxDPI, cyDPI; HFONT hFont; LOGFONT lf; int iDeciPtWidth = 0; int iDeciPtHeight = 10 * ptSize; int iSavedDC = SaveDC(hdc); SetGraphicsMode (hdc, GM_ADVANCED); ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); SetViewportOrgEx (hdc, 0,0, NULL); SetWindowOrgEx (hdc, 0,0, NULL); cxDPI = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSX); cyDPI = (FLOAT) GetDeviceCaps(hdc, LOGPIXELSY); pt.x = (int) (iDeciPtWidth * cxDPI / 72); pt.y = (int) (iDeciPtHeight * cyDPI / 72); DPtoLP(hdc, &pt, 1); lf.lfHeight = - (int) (fabs ((double) pt.y) / 10.0 + 0.5); lf.lfWidth = 0; lf.lfEscapement = 0; lf.lfOrientation = 0; lf.lfWeight = dwWeight; lf.lfItalic = 0; lf.lfUnderline = (bUnderline ? 1 : 0); lf.lfStrikeOut = 0; lf.lfCharSet = 0; lf.lfOutPrecision = 0; lf.lfClipPrecision = 0; lf.lfQuality = 0; lf.lfPitchAndFamily = 0; TCHAR szLocaleData[BUFFER_SIZE]; int iRet = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SENGCOUNTRY, szLocaleData, BUFFER_SIZE); if (strncmp(szLocaleData, "Japan", 5) != 0){ strcpy (lf.lfFaceName, szFaceName); } else { strcpy (lf.lfFaceName, TEXT("MS UI Gothic")); } hFont = CreateFontIndirect(&lf); RestoreDC (hdc, iSavedDC); return hFont; }
void StretchDrawTo(HDC handle,LPRECT rect,float Angle) { if(Angle==0) { StretchBlt(handle,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top, Canvas->Handle,0,0,Width,Height,SRCCOPY); }else { Angle=Angle*0.017453292; Angle=-Angle; XFORM Matrix; SetGraphicsMode(handle, GM_ADVANCED); Matrix.eM11 = 1; Matrix.eM12 = 0; Matrix.eM21 = 0; Matrix.eM22 = 1; Matrix.eDx = -rect->left; Matrix.eDy = -rect->top; SetWorldTransform(handle, &Matrix); Matrix.eM11 = cos(Angle); Matrix.eM12 = sin(Angle); Matrix.eM21 = -sin(Angle); Matrix.eM22 = cos(Angle); Matrix.eDx = 0; Matrix.eDy = 0; ModifyWorldTransform(handle, &Matrix, MWT_RIGHTMULTIPLY); Matrix.eM11 = 1; Matrix.eM12 = 0; Matrix.eM21 = 0; Matrix.eM22 = 1; Matrix.eDx = rect->left; Matrix.eDy = rect->top; ModifyWorldTransform(handle, &Matrix, MWT_RIGHTMULTIPLY); StretchBlt(handle,rect->left,rect->top,rect->right-rect->left,rect->bottom-rect->top, Canvas->Handle,0,0,Width,Height,SRCCOPY); ModifyWorldTransform(handle, &Matrix, MWT_IDENTITY); } }
void GraphicsContextPlatformPrivate::scale(const FloatSize& size) { if (!m_hdc) return; XFORM xform; xform.eM11 = size.width(); xform.eM12 = 0.0f; xform.eM21 = 0.0f; xform.eM22 = size.height(); xform.eDx = 0.0f; xform.eDy = 0.0f; ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
void GraphicsContextPlatformPrivate::translate(float x , float y) { if (!m_hdc) return; XFORM xform; xform.eM11 = 1.0f; xform.eM12 = 0.0f; xform.eM21 = 0.0f; xform.eM22 = 1.0f; xform.eDx = x; xform.eDy = y; ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
void GraphicsContextPlatformPrivate::rotate(float degreesAngle) { float radiansAngle = degreesAngle * deg2rad; float cosAngle = cosf(radiansAngle); float sinAngle = sinf(radiansAngle); XFORM xform; xform.eM11 = cosAngle; xform.eM12 = -sinAngle; xform.eM21 = sinAngle; xform.eM22 = cosAngle; xform.eDx = 0.0f; xform.eDy = 0.0f; ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
static void test_modify_world_transform(void) { HDC hdc = GetDC(0); int ret; ret = SetGraphicsMode(hdc, GM_ADVANCED); if(!ret) /* running in win9x so quit */ { ReleaseDC(0, hdc); skip("GM_ADVANCED is not supported on this platform\n"); return; } ret = ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); ok(ret, "ret = %d\n", ret); ret = ModifyWorldTransform(hdc, NULL, MWT_LEFTMULTIPLY); ok(!ret, "ret = %d\n", ret); ret = ModifyWorldTransform(hdc, NULL, MWT_RIGHTMULTIPLY); ok(!ret, "ret = %d\n", ret); ReleaseDC(0, hdc); }
void GraphicsContextPlatformPrivate::concatCTM(const TransformationMatrix& transform) { if (!m_hdc) return; CGAffineTransform mat = transform; XFORM xform; xform.eM11 = mat.a; xform.eM12 = mat.b; xform.eM21 = mat.c; xform.eM22 = mat.d; xform.eDx = mat.tx; xform.eDy = mat.ty; ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
void GraphicsContextPlatformPrivate::concatCTM(const TransformationMatrix& transform) { cairo_surface_t* surface = cairo_get_target(cr); HDC hdc = cairo_win32_surface_get_dc(surface); SaveDC(hdc); const cairo_matrix_t* matrix = reinterpret_cast<const cairo_matrix_t*>(&transform); XFORM xform; xform.eM11 = matrix->xx; xform.eM12 = matrix->xy; xform.eM21 = matrix->yx; xform.eM22 = matrix->yy; xform.eDx = matrix->x0; xform.eDy = matrix->y0; ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); }
/////////////////////////////////////////////////////////////////////////////// // Descripcion: // - Crea la fuente true type, pero NO la selecciona. // Parametros: // - hdc. DC a la superficie sobre la que se va a crear la fuente. // - swDeciPt. Tamaño de la fuentes en puntos por 10. Si nuestra fuente va a // tener un tamaño de 16, debera de valer 16x10 = 160. // Devuelve: // Notas: /////////////////////////////////////////////////////////////////////////////// void CFont::CreateTTFont(const HDC& hdc, const sword& swDeciPt) { // SOLO si los parametros son validos ASSERT(hdc); ASSERT(swDeciPt); // Configura el DC recibido SetGraphicsMode(hdc, GM_ADVANCED); ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); SetViewportOrgEx(hdc, 0, 0, NULL); SetWindowOrgEx(hdc, 0, 0, NULL); // Se establece la res. logica float cxDpi = (float) GetDeviceCaps(hdc, LOGPIXELSX); float cyDpi = (float) GetDeviceCaps(hdc, LOGPIXELSY); // Define ptos. por pulgada POINT pt; pt.x = 0; pt.y = (sword) (swDeciPt * cyDpi / 72); DPtoLP(hdc, &pt, 1); // Configura y crea la fuente LOGFONT lf; memset(&lf, 0, sizeof(lf)); lf.lfHeight = -(sword) (fabs(pt.y) / 10.0 + 0.5); strcpy(lf.lfFaceName, m_FontInfo.szName.c_str()); m_FontInfo.hFont = CreateFontIndirect(&lf); lf.lfQuality = ANTIALIASED_QUALITY; // Se obtiene datos sobre metrica y anchura m_FontInfo.hPrevFont = (HFONT) SelectObject(hdc, m_FontInfo.hFont); GetTextMetrics(hdc, &m_FontInfo.tm); GetCharABCWidths(hdc, 32, 255, m_FontInfo.abc); // Restaura el estado del hdc anterior }
static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) { Color fillColor = graphicsContext->fillColor(); bool drawIntoBitmap = false; TextDrawingModeFlags drawingMode = graphicsContext->textDrawingMode(); if (drawingMode == TextModeFill) { if (!fillColor.alpha()) return; drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->inTransparencyLayer(); if (!drawIntoBitmap) { FloatSize offset; float blur; Color color; ColorSpace shadowColorSpace; graphicsContext->getShadow(offset, blur, color, shadowColorSpace); drawIntoBitmap = offset.width() || offset.height() || blur; } } // We have to convert CG's two-dimensional floating point advances to just horizontal integer advances. Vector<int, 2048> gdiAdvances; int totalWidth = 0; for (int i = 0; i < numGlyphs; i++) { gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i))); totalWidth += gdiAdvances[i]; } HDC hdc = 0; OwnPtr<GraphicsContext::WindowsBitmap> bitmap; IntRect textRect; if (!drawIntoBitmap) hdc = graphicsContext->getWindowsContext(textRect, true, false); if (!hdc) { drawIntoBitmap = true; // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges. // FIXME: Can get glyphs' optical bounds (even from CG) to get this right. const FontMetrics& fontMetrics = font->fontMetrics(); int lineGap = fontMetrics.lineGap(); textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2, point.y() - fontMetrics.ascent() - lineGap, totalWidth + fontMetrics.ascent() + fontMetrics.descent(), fontMetrics.lineSpacing()); bitmap = graphicsContext->createWindowsBitmap(textRect.size()); memset(bitmap->buffer(), 255, bitmap->bufferLength()); hdc = bitmap->hdc(); XFORM xform; xform.eM11 = 1.0f; xform.eM12 = 0.0f; xform.eM21 = 0.0f; xform.eM22 = 1.0f; xform.eDx = -textRect.x(); xform.eDy = -textRect.y(); SetWorldTransform(hdc, &xform); } SelectObject(hdc, font->platformData().hfont()); // Set the correct color. if (drawIntoBitmap) SetTextColor(hdc, RGB(0, 0, 0)); else SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue())); SetBkMode(hdc, TRANSPARENT); SetTextAlign(hdc, TA_LEFT | TA_BASELINE); // Uniscribe gives us offsets to help refine the positioning of combining glyphs. FloatSize translation = glyphBuffer.offsetAt(from); if (translation.width() || translation.height()) { XFORM xform; xform.eM11 = 1.0; xform.eM12 = 0; xform.eM21 = 0; xform.eM22 = 1.0; xform.eDx = translation.width(); xform.eDy = translation.height(); ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); } if (drawingMode == TextModeFill) { XFORM xform; xform.eM11 = 1.0; xform.eM12 = 0; xform.eM21 = font->platformData().syntheticOblique() ? -tanf(syntheticObliqueAngle * piFloat / 180.0f) : 0; xform.eM22 = 1.0; xform.eDx = point.x(); xform.eDy = point.y(); ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data()); if (font->syntheticBoldOffset()) { xform.eM21 = 0; xform.eDx = font->syntheticBoldOffset(); xform.eDy = 0; ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY); ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data()); } } else { XFORM xform; GetWorldTransform(hdc, &xform); AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy); CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity; if (font->platformData().syntheticOblique()) initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0)); initialGlyphTransform.tx = 0; initialGlyphTransform.ty = 0; CGContextRef cgContext = graphicsContext->platformContext(); CGContextSaveGState(cgContext); BOOL fontSmoothingEnabled = false; SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0); CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled); CGContextScaleCTM(cgContext, 1.0, -1.0); CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height())); for (unsigned i = 0; i < numGlyphs; ++i) { RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i))); CGContextSaveGState(cgContext); CGContextConcatCTM(cgContext, initialGlyphTransform); if (drawingMode & TextModeFill) { CGContextAddPath(cgContext, glyphPath.get()); CGContextFillPath(cgContext); if (font->syntheticBoldOffset()) { CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0); CGContextAddPath(cgContext, glyphPath.get()); CGContextFillPath(cgContext); CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0); } } if (drawingMode & TextModeStroke) { CGContextAddPath(cgContext, glyphPath.get()); CGContextStrokePath(cgContext); if (font->syntheticBoldOffset()) { CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0); CGContextAddPath(cgContext, glyphPath.get()); CGContextStrokePath(cgContext); CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0); } } CGContextRestoreGState(cgContext); CGContextTranslateCTM(cgContext, gdiAdvances[i], 0); } CGContextRestoreGState(cgContext); } if (drawIntoBitmap) { UInt8* buffer = bitmap->buffer(); unsigned bufferLength = bitmap->bufferLength(); for (unsigned i = 0; i < bufferLength; i += 4) { // Use green, which is always in the middle. UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255; buffer[i] = fillColor.blue(); buffer[i + 1] = fillColor.green(); buffer[i + 2] = fillColor.red(); buffer[i + 3] = alpha; } graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location()); } else graphicsContext->releaseWindowsContext(hdc, textRect, true, false); }
HFONT EzCreateFont (HDC hdc, TCHAR * szFaceName, int iDeciPtHeight, int iDeciPtWidth, int iAttributes, BOOL fLogRes) { FLOAT cxDpi, cyDpi ; HFONT hFont ; LOGFONT lf ; POINT pt ; TEXTMETRIC tm ; SaveDC (hdc) ; #ifndef HAVE_API_WIN32_CE SetGraphicsMode (hdc, GM_ADVANCED) ; ModifyWorldTransform (hdc, NULL, MWT_IDENTITY) ; #endif SetViewportOrgEx (hdc, 0, 0, NULL) ; #ifndef HAVE_API_WIN32_CE SetWindowOrgEx (hdc, 0, 0, NULL) ; #endif if (fLogRes) { cxDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSX) ; cyDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSY) ; } else { cxDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, HORZRES) / GetDeviceCaps (hdc, HORZSIZE)) ; cyDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, VERTRES) / GetDeviceCaps (hdc, VERTSIZE)) ; } pt.x = (int) (iDeciPtWidth * cxDpi / 72) ; pt.y = (int) (iDeciPtHeight * cyDpi / 72) ; #ifndef HAVE_API_WIN32_CE DPtoLP (hdc, &pt, 1) ; #endif lf.lfHeight = - (int) (fabs (pt.y) / 10.0 + 0.5) ; lf.lfWidth = 0 ; lf.lfEscapement = 0 ; lf.lfOrientation = 0 ; lf.lfWeight = iAttributes & EZ_ATTR_BOLD ? 700 : 0 ; lf.lfItalic = iAttributes & EZ_ATTR_ITALIC ? 1 : 0 ; lf.lfUnderline = iAttributes & EZ_ATTR_UNDERLINE ? 1 : 0 ; lf.lfStrikeOut = iAttributes & EZ_ATTR_STRIKEOUT ? 1 : 0 ; lf.lfCharSet = DEFAULT_CHARSET ; lf.lfOutPrecision = 0 ; lf.lfClipPrecision = 0 ; lf.lfQuality = 0 ; lf.lfPitchAndFamily = 0 ; lstrcpy (lf.lfFaceName, szFaceName) ; hFont = CreateFontIndirect (&lf) ; if (iDeciPtWidth != 0) { hFont = (HFONT) SelectObject (hdc, hFont) ; GetTextMetrics (hdc, &tm) ; DeleteObject (SelectObject (hdc, hFont)) ; lf.lfWidth = (int) (tm.tmAveCharWidth * fabs (pt.x) / fabs (pt.y) + 0.5) ; hFont = CreateFontIndirect (&lf) ; } RestoreDC (hdc, -1) ; return hFont ; }
void GraphicsContextPlatformPrivate::rotate(float degreesAngle) { XFORM xform = TransformationMatrix().rotate(degreesAngle); ModifyWorldTransform(m_hdc, &xform, MWT_LEFTMULTIPLY); }
BOOL CImagePng::DrawImagePng(HDC hDC,int nXDst,int nYDst,int nWidthDst,int nHeightDst,int nXSrc,int nYSrc,int nWidthSrc,int nHeightSrc,double dbRotateAngle,DWORD dwRop) { try { if (m_nWidth <= 0||m_nHeight <= 0||m_hBmp == NULL) return FALSE; BOOL bResult = FALSE; BLENDFUNCTION bf; bf.BlendOp = AC_SRC_OVER; bf.BlendFlags = 0; bf.SourceConstantAlpha = 255; bf.AlphaFormat = AC_SRC_ALPHA; HDC hMemDC = CreateCompatibleDC(hDC); HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, m_hBmp); HDC hRotateMemDC = CreateCompatibleDC(hDC); HBITMAP hRotateBmp = CreateCompatibleBitmap(hDC,nWidthDst,nHeightDst); HBITMAP hOldBmp2 = (HBITMAP)SelectObject(hRotateMemDC, hRotateBmp); BITMAP bm; ::GetObject(m_hBmp,sizeof(bm),&bm); POINT CenterPoint; CenterPoint.x = bm.bmWidth/2; CenterPoint.y = bm.bmHeight/2; float sin_angle = (float)sin(dbRotateAngle); float cos_angle = (float)cos(dbRotateAngle); //旋转世界坐标系统 XFORM xform; memset(&xform,0,sizeof(xform)); xform.eM11 = cos_angle; xform.eM12 = -sin_angle; xform.eM21 = sin_angle; xform.eM22 = cos_angle; xform.eDx = (float)(CenterPoint.x - (CenterPoint.x*cos_angle+CenterPoint.y*sin_angle)); xform.eDy = (float)(CenterPoint.y - (-CenterPoint.x*sin_angle+CenterPoint.y*cos_angle)); int nOldMode = SetGraphicsMode(hRotateMemDC,GM_ADVANCED); bResult = SetWorldTransform(hRotateMemDC,&xform); float fRateX = (float)nWidthDst/m_nWidth; float fRateY = (float)nHeightDst/m_nHeight; memset(&xform,0,sizeof(xform)); xform.eM11 = fRateX; xform.eM12 = 0; xform.eM21 = 0; xform.eM22 = fRateY; xform.eDx = 0; xform.eDy = 0; //缩放世界坐标系统 bResult = ModifyWorldTransform(hRotateMemDC,&xform,MWT_RIGHTMULTIPLY); //旋转图像 bResult = AlphaBlend(hRotateMemDC,0,0,m_nWidth,m_nHeight,hMemDC,0,0,m_nWidth,m_nHeight,bf); //还原世界坐标系统 xform.eM11 = (float)1.0f; xform.eM12 = (float)0.0f; xform.eM21 = (float)0.0f; xform.eM22 = (float)1.0f; xform.eDx = (float)0.0f; xform.eDy = (float)0.0f; bResult = SetWorldTransform(hRotateMemDC,&xform); //还原图形模式 SetGraphicsMode(hDC,nOldMode); //复制图像 AlphaBlend(hDC,nXDst,nYDst,nWidthDst,nHeightDst,hRotateMemDC,0,0,nWidthDst,nHeightDst,bf); SelectObject(hRotateMemDC,hOldBmp2); DeleteObject(hRotateBmp); DeleteDC(hRotateMemDC); SelectObject(hMemDC,hOldBmp); DeleteDC(hMemDC); return TRUE; } catch(...) { } return FALSE; }
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static HMENU hMenu ; static PAINTSTRUCT ps; static int cxClient, cyClient; static int first; static RECT rect; switch (iMsg) { case WM_CREATE: // Initialize program vars sys_error.hwnd = (int) hwnd; graphics.logicalunit = (int) hwnd; strcpy (sys_error.sys_szClientClass, szAppName); strcpy (graphics.device, "sys-scn"); strcpy (sys_error.program_type, "sys"); sys_error.next_graph = 0; // draw first picture first = TRUE; return 0; case WM_SIZE: // Resize screen cxClient = LOWORD (lParam); cyClient = HIWORD (lParam); if (!first) { sys_error.next_graph = 1; // On resize - we want to redraw current picture } return 0; case WM_COMMAND : hMenu = GetMenu (hwnd) ; switch (LOWORD (wParam)) { case IDM_NEW : // Draw next picture sys_error.next_graph = 1; SendMessage (hwnd, WM_PAINT, 0, 0L); return 0 ; case IDM_REDRAW : // Re-Draw current sys_error.next_graph = 2; SendMessage (hwnd, WM_PAINT, 0, 0L); return 0 ; case IDM_GO : // GO sys_error.next_graph = 3; SendMessage (hwnd, WM_PAINT, 0, 0L); return 0 ; case IDM_PRINT: // Print request sys_error.next_graph = 4; SendMessage (hwnd, WM_PAINT, 0, 0L); return 0; case IDM_OPT1: // Option 1 sys_error.next_graph = 5; SendMessage (hwnd, WM_PAINT, 0, 0L); return 0; case IDM_OPT2: // Option 2 sys_error.next_graph = 6; SendMessage (hwnd, WM_PAINT, 0, 0L); return 0; case IDM_EXIT : SendMessage (hwnd, WM_CLOSE, 0, 0L) ; return 0 ; case IDM_HELP : MessageBox (hwnd, "Help not yet implemented!", szAppName, MB_ICONEXCLAMATION | MB_OK) ; return 0 ; case IDM_ABOUT : MessageBox (hwnd, "Windows Graphic Driver Version 1.00.", szAppName, MB_ICONINFORMATION | MB_OK) ; return 0 ; } break ; case WM_PAINT: if (sys_error.next_graph != 4) InvalidateRect (hwnd, NULL, TRUE); hdc = BeginPaint (hwnd, &ps); graphics.hdc = hdc; SetGraphicsMode (graphics.hdc, GM_ADVANCED); ModifyWorldTransform (graphics.hdc, NULL, MWT_IDENTITY); SetRect (&rect, 0, 0, cxClient, cyClient); fordrive (); if (first) { first = FALSE; } EndPaint (hwnd, &ps); return 0; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }