void CObjectImageArray::PaintImageGrayed (CG16bitImage &Dest, int x, int y, int iTick, int iRotation) const // PaintImageGrayed // // Paints the image on the destination { if (m_pImage) { CG16bitImage *pSource = m_pImage->GetImage(); if (pSource == NULL) return; int xSrc = ComputeSourceX(iTick); if (m_pRotationOffset) { x += m_pRotationOffset[iRotation % m_iRotationCount].x; y -= m_pRotationOffset[iRotation % m_iRotationCount].y; } Dest.BltGray(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), 128, *pSource, x - (RectWidth(m_rcImage) / 2), y - (RectHeight(m_rcImage) / 2)); } }
void CObjectImageArray::PaintSilhoutte (CG16bitImage &Dest, int x, int y, int iTick, int iRotation, COLORREF wColor) const // PaintSilhouette // // Paints a silhouette of the object { if (m_pImage) { CG16bitImage &Source(*m_pImage->GetImage()); int xSrc = ComputeSourceX(iTick); if (m_pRotationOffset) { x += m_pRotationOffset[iRotation % m_iRotationCount].x; y -= m_pRotationOffset[iRotation % m_iRotationCount].y; } Dest.FillMask(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), Source, wColor, x - (RectWidth(m_rcImage) / 2), y - (RectHeight(m_rcImage) / 2)); } }
void CObjectImageArray::PaintImageUL (CG16bitImage &Dest, int x, int y, int iTick, int iRotation, bool srcAlpha) const // PaintImageUL // // Paints the image. x,y is the upper-left corner of the destination // // Note: This should not use the rotation offsets { if (m_pImage) { CG16bitImage &Source(*m_pImage->GetImage()); int xSrc = ComputeSourceX(iTick); int ySrc; if (m_iBlending == blendLighten) { Dest.BltLighten(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), 255, Source, x, y); } else { ySrc = m_rcImage.top + (iRotation * RectHeight(m_rcImage)); Dest.Blt(x, y, Source, xSrc, ySrc, xSrc + RectWidth(m_rcImage), ySrc + RectHeight(m_rcImage), srcAlpha); } } }
void CObjectImageArray::GenerateGlowImage (int iRotation) const // GenerateGlowImage // // Generates a mask that looks like a glow. The mask is 0 for all image pixels // and for all pixels where there is no glow (thus we can optimize painting // of the glow by ignoring 0 values) { ASSERT(iRotation >= 0 && iRotation < m_iRotationCount); // Source if (m_pImage == NULL) return; CG16bitImage &Source(*m_pImage->GetImage()); // Allocate the array of images (if not already allocated) if (m_pGlowImages == NULL) m_pGlowImages = new CG16bitImage[m_iRotationCount]; // If the image for this rotation has already been initialized, then // we're done if (!m_pGlowImages[iRotation].IsEmpty()) return; // Otherwise we need to create the glow mask. The glow image is larger // than the object image (by GLOW_SIZE) int cxSrcWidth = RectWidth(m_rcImage); int cySrcHeight = RectHeight(m_rcImage); int cxGlowWidth = cxSrcWidth + 2 * GLOW_SIZE; int cyGlowHeight = cySrcHeight + 2 * GLOW_SIZE; if (m_pGlowImages[iRotation].Create(cxGlowWidth, cyGlowHeight, 8) != NOERROR) { m_pGlowImages[iRotation].DiscardSurface(); kernelDebugLogMessage("Unable to create image"); return; } RECT rcSrc; rcSrc.left = ComputeSourceX(0); rcSrc.top = m_rcImage.top + (iRotation * cySrcHeight); rcSrc.right = rcSrc.left + cxSrcWidth; rcSrc.bottom = rcSrc.top + cySrcHeight; m_pGlowImages[iRotation].DrawGlowImage(0, 0, Source, rcSrc.left, rcSrc.top, rcSrc.right, rcSrc.bottom, 4); }
void CObjectImageArray::GenerateScaledImages (int iRotation, int cxWidth, int cyHeight) const // GenerateScaledImages // // Generate scaled images { ASSERT(iRotation >= 0 && iRotation < m_iRotationCount); // Allocate the array of images (if not already allocated) if (m_pScaledImages == NULL) m_pScaledImages = new CG16bitImage [m_iRotationCount]; // If the image for this rotation has already been initialized, then // we're done if (m_pScaledImages[iRotation].HasRGB()) return; // Otherwise we need to create the scaled image m_pScaledImages[iRotation].CreateBlank(cxWidth, cyHeight, false); // Get the extent of the source image RECT rcSrc; rcSrc.left = ComputeSourceX(0); rcSrc.top = m_rcImage.top + (iRotation * RectHeight(m_rcImage)); rcSrc.right = rcSrc.left + RectWidth(m_rcImage); rcSrc.bottom = rcSrc.top + RectHeight(m_rcImage); CG16bitImage *pSource = m_pImage->GetImage(); if (pSource == NULL) return; // Scale the image m_pScaledImages[iRotation].GaussianScaledBlt( rcSrc.left, rcSrc.top, RectWidth(rcSrc), RectHeight(rcSrc), *pSource, 0, 0, cxWidth, cyHeight); m_pScaledImages[iRotation].SetTransparentColor(0); }
void CObjectImageArray::PaintRotatedImage (CG16bitImage &Dest, int x, int y, int iTick, int iRotation) const // PaintRotatedImage // // Paint rotated image { if (m_pImage == NULL) return; CG16bitImage *pSource = m_pImage->GetImage(); if (pSource == NULL) return; int xSrc = ComputeSourceX(iTick); int cxSrc = RectWidth(m_rcImage); int cySrc = RectHeight(m_rcImage); // Calculate the position of the upper-left corner of // the rotated image. #if 0 CVector vUL(-cxSrc / 2, cySrc / 2); vUL = vUL.Rotate(iRotation); #endif // LATER: Since we have an actual rotation angle, we can calculate // any rotation offset directly (instead of of using m_pRotationOffset) // (But we are too lazy to do that now) ASSERT(m_pRotationOffset == NULL); // Blt DrawBltRotated(Dest, x, y, iRotation, *pSource, xSrc, m_rcImage.top, cxSrc, cySrc); }
bool CObjectImageArray::PointInImage (int x, int y, int iTick, int iRotation) const // PointInImage // // Returns TRUE if the given point is inside the masked part of the image // x, y is relative to the center of the image (GDI directions) { if (m_pImage) { CG16bitImage *pSource = m_pImage->GetImage(); if (pSource == NULL) return false; // Compute the position of the frame int cxWidth = RectWidth(m_rcImage); int cyHeight = RectHeight(m_rcImage); int xSrc = ComputeSourceX(iTick); int ySrc = m_rcImage.top + (iRotation * cyHeight); // Adjust the point so that it is relative to the // frame origin (upper left) x = xSrc + x + (cxWidth / 2); y = ySrc + y + (cyHeight / 2); // Adjust for rotation if (m_pRotationOffset) { x -= m_pRotationOffset[iRotation % m_iRotationCount].x; y += m_pRotationOffset[iRotation % m_iRotationCount].y; } // Check bounds if (x < xSrc || y < ySrc || x >= (xSrc + cxWidth) || y >= (ySrc + cyHeight)) return false; // Check to see if the point is inside or outside the mask return (pSource->GetPixelAlpha(x, y) != 0); } else return false; }
void CObjectImageArray::PaintImage (CG16bitImage &Dest, int x, int y, int iTick, int iRotation) const // PaintImage // // Paints the image on the destination { if (m_pImage) { CG16bitImage *pSource = m_pImage->GetImage(); if (pSource == NULL) return; int xSrc = ComputeSourceX(iTick); if (m_pRotationOffset) { x += m_pRotationOffset[iRotation % m_iRotationCount].x; y -= m_pRotationOffset[iRotation % m_iRotationCount].y; } if (m_iBlending == blendLighten) { Dest.BltLighten(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), 255, *pSource, x - (RectWidth(m_rcImage) / 2), y - (RectHeight(m_rcImage) / 2)); } else { Dest.ColorTransBlt(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), 255, *pSource, x - (RectWidth(m_rcImage) / 2), y - (RectHeight(m_rcImage) / 2)); } } }
void CObjectImageArray::PaintImageUL (CG16bitImage &Dest, int x, int y, int iTick, int iRotation) const // PaintImageUL // // Paints the image. x,y is the upper-left corner of the destination // // Note: This should not use the rotation offsets { if (m_pImage) { CG16bitImage *pSource = m_pImage->GetImage(); if (pSource == NULL) return; int xSrc = ComputeSourceX(iTick); if (m_iBlending == blendLighten) { Dest.BltLighten(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), 255, *pSource, x, y); } else { Dest.ColorTransBlt(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), 255, *pSource, x, y); } } }
RECT CObjectImageArray::GetImageRect (int iTick, int iRotation, int *retxCenter, int *retyCenter) const // GetImageRect // // Returns the rect of the image { RECT rcRect; rcRect.left = ComputeSourceX(iTick); rcRect.right = rcRect.left + RectWidth(m_rcImage); rcRect.top = m_rcImage.top + (iRotation * RectHeight(m_rcImage)); rcRect.bottom = rcRect.top + RectHeight(m_rcImage); if (retxCenter) *retxCenter = rcRect.left + ((RectWidth(m_rcImage) / 2) - (m_pRotationOffset ? m_pRotationOffset[iRotation % m_iRotationCount].x : 0)); if (retyCenter) *retyCenter = rcRect.top + ((RectHeight(m_rcImage) / 2) + (m_pRotationOffset ? m_pRotationOffset[iRotation % m_iRotationCount].y : 0)); return rcRect; }
void CObjectImageArray::PaintImage (CG16bitImage &Dest, int x, int y, int iTick, int iRotation, bool srcAlpha) const // PaintImage // // Paints the image on the destination { if (m_pImage) { CG16bitImage &Source(*m_pImage->GetImage()); int xSrc = ComputeSourceX(iTick); int ySrc; if (m_pRotationOffset) { x += m_pRotationOffset[iRotation % m_iRotationCount].x; y -= m_pRotationOffset[iRotation % m_iRotationCount].y; } if (m_iBlending == blendLighten) { Dest.BltLighten(xSrc, m_rcImage.top + (iRotation * RectHeight(m_rcImage)), RectWidth(m_rcImage), RectHeight(m_rcImage), 255, Source, x - (RectWidth(m_rcImage) / 2), y - (RectHeight(m_rcImage) / 2)); } else { ySrc = m_rcImage.top + (iRotation * RectHeight(m_rcImage)); Dest.Blt(x - (RectWidth(m_rcImage) / 2), y - (RectHeight(m_rcImage) / 2), Source, xSrc, ySrc, xSrc + RectWidth(m_rcImage), ySrc + RectHeight(m_rcImage), srcAlpha); } } }
void CObjectImageArray::GenerateScaledImages (int iRotation, int cxWidth, int cyHeight) const // GenerateScaledImages // // Generate scaled images { ASSERT(iRotation >= 0 && iRotation < m_iRotationCount); // Allocate the array of images (if not already allocated) if (m_pScaledImages == NULL) m_pScaledImages = new CG16bitImage [m_iRotationCount]; // If the image for this rotation has already been initialized, then // we're done if (!m_pScaledImages[iRotation].IsEmpty()) return; // Otherwise we need to create the scaled image m_pScaledImages[iRotation].Create(cxWidth, cyHeight); // Get the extent of the source image RECT rcSrc; rcSrc.left = ComputeSourceX(0); rcSrc.top = m_rcImage.top + (iRotation * RectHeight(m_rcImage)); rcSrc.right = rcSrc.left + RectWidth(m_rcImage); rcSrc.bottom = rcSrc.top + RectHeight(m_rcImage); // Scale the image m_pScaledImages[iRotation].BltRotoZ(0, 0, cxWidth, cyHeight, *m_pImage->GetImage(), rcSrc.left, rcSrc.top, rcSrc.right, rcSrc.bottom, 0, 0, false); }
void CObjectImageArray::PointInImageInit (SPointInObjectCtx &Ctx, int iTick, int iRotation) const // PointInImageInit // // Initializes the context to optimize the PointInImage call { if (m_pImage) { Ctx.pImage = m_pImage->GetImage(); if (Ctx.pImage == NULL) return; // Compute the position of the frame int cxWidth = RectWidth(m_rcImage); int cyHeight = RectHeight(m_rcImage); Ctx.rcImage.left = ComputeSourceX(iTick); Ctx.rcImage.top = m_rcImage.top + (iRotation * cyHeight); Ctx.rcImage.right = Ctx.rcImage.left + cxWidth; Ctx.rcImage.bottom = Ctx.rcImage.top + cyHeight; // Compute the offset required to convert to image coordinates Ctx.xImageOffset = Ctx.rcImage.left + (cxWidth / 2); Ctx.yImageOffset = Ctx.rcImage.top + (cyHeight / 2); // Adjust for rotation if (m_pRotationOffset) { Ctx.xImageOffset -= m_pRotationOffset[iRotation % m_iRotationCount].x; Ctx.yImageOffset += m_pRotationOffset[iRotation % m_iRotationCount].y; } } }
bool CObjectImageArray::ImagesIntersect (int iTick, int iRotation, int x, int y, const CObjectImageArray &Image2, int iTick2, int iRotation2) const // ImagesIntersect // // Returns TRUE if the given image intersects with this image { if (m_pImage == NULL || Image2.m_pImage == NULL) return false; // Compute the rectangle of image1 RECT rcRect; int cxWidth = RectWidth(m_rcImage); int cyHeight = RectHeight(m_rcImage); rcRect.left = ComputeSourceX(iTick); rcRect.top = m_rcImage.top + (iRotation * cyHeight); rcRect.right = rcRect.left + cxWidth; rcRect.bottom = rcRect.top + cyHeight; // Compute the rectangle of image2 RECT rcRect2; int cxWidth2 = RectWidth(Image2.m_rcImage); int cyHeight2 = RectHeight(Image2.m_rcImage); rcRect2.left = Image2.ComputeSourceX(iTick); rcRect2.top = Image2.m_rcImage.top + (iRotation2 * cyHeight2); rcRect2.right = rcRect2.left + cxWidth2; rcRect2.bottom = rcRect2.top + cyHeight2; // Now figure out the position of image2 on the image1 coordinate space int xCenter = rcRect.left + (cxWidth / 2); int yCenter = rcRect.top + (cyHeight / 2); RECT rcImage2On1; rcImage2On1.left = xCenter + x - (cxWidth2 / 2); rcImage2On1.top = yCenter + y - (cyHeight2 / 2); if (m_pRotationOffset) { rcImage2On1.left -= m_pRotationOffset[iRotation % m_iRotationCount].x; rcImage2On1.top += m_pRotationOffset[iRotation % m_iRotationCount].y; } if (Image2.m_pRotationOffset) { rcImage2On1.left += Image2.m_pRotationOffset[iRotation2 % Image2.m_iRotationCount].x; rcImage2On1.top -= Image2.m_pRotationOffset[iRotation2 % Image2.m_iRotationCount].y; } rcImage2On1.right = rcImage2On1.left + cxWidth2; rcImage2On1.bottom = rcImage2On1.top + cyHeight2; // Intersect the rectangles RECT rcRectInt; if (!::IntersectRect(&rcRectInt, &rcRect, &rcImage2On1)) return false; // Figure out the position of image1 on the image2 coordinate space int xOffset = rcRect.left - rcImage2On1.left; int yOffset = rcRect.top - rcImage2On1.top; RECT rcImage1On2; rcImage1On2.left = rcRect2.left + xOffset; rcImage1On2.top = rcRect2.top + yOffset; rcImage1On2.right = rcImage1On2.left + cxWidth; rcImage1On2.bottom = rcImage1On2.top + cyHeight; // Intersect the rectangles RECT rcRectInt2; ::IntersectRect(&rcRectInt2, &rcRect2, &rcImage1On2); ASSERT(RectWidth(rcRectInt) == RectWidth(rcRectInt2)); ASSERT(RectHeight(rcRectInt) == RectHeight(rcRectInt2)); // Images CG16bitImage *pSrc1 = m_pImage->GetImage(); CG16bitImage *pSrc2 = Image2.m_pImage->GetImage(); if (pSrc1 == NULL || pSrc2 == NULL) return false; // If both rectangles have a mask if (pSrc1->HasAlpha() && pSrc2->HasAlpha()) { // Now iterate over the intersection area and see if there // are any pixels in common. BYTE *pRow = pSrc1->GetAlphaRow(rcRectInt.top) + rcRectInt.left; BYTE *pRowEnd = pSrc1->GetAlphaRow(rcRectInt.bottom) + rcRectInt.left; BYTE *pRow2 = pSrc2->GetAlphaRow(rcRectInt2.top) + rcRectInt2.left; int cxWidthInt = RectWidth(rcRectInt); while (pRow < pRowEnd) { BYTE *pPos = pRow; BYTE *pEnd = pPos + cxWidthInt; BYTE *pPos2 = pRow2; while (pPos < pEnd) { if (*pPos && *pPos2) return true; pPos++; pPos2++; } pRow = pSrc1->NextAlphaRow(pRow); pRow2 = pSrc2->NextAlphaRow(pRow2); } } // If neither has a mask else if (!pSrc1->HasAlpha() && !pSrc2->HasAlpha()) { // Now iterate over the intersection area and see if there // are any pixels in common. WORD *pRow = pSrc1->GetRowStart(rcRectInt.top) + rcRectInt.left; WORD *pRowEnd = pSrc1->GetRowStart(rcRectInt.bottom) + rcRectInt.left; WORD *pRow2 = pSrc2->GetRowStart(rcRectInt2.top) + rcRectInt2.left; WORD wBackColor = pSrc1->GetBackColor(); int cxWidthInt = RectWidth(rcRectInt); while (pRow < pRowEnd) { WORD *pPos = pRow; WORD *pEnd = pPos + cxWidthInt; WORD *pPos2 = pRow2; while (pPos < pEnd) { if (*pPos != wBackColor && *pPos2 != wBackColor) return true; pPos++; pPos2++; } pRow = pSrc1->NextRow(pRow); pRow2 = pSrc2->NextRow(pRow2); } } // Don't know how to handle this case else return true; // If we get this far then we did not intersect return false; }
void CObjectImageArray::GenerateGlowImage (int iRotation) const // GenerateGlowImage // // Generates a mask that looks like a glow. The mask is 0 for all image pixels // and for all pixels where there is no glow (thus we can optimize painting // of the glow by ignoring 0 values) { ASSERT(iRotation >= 0 && iRotation < m_iRotationCount); // Source if (m_pImage == NULL) return; CG16bitImage *pSource = m_pImage->GetImage(); if (pSource == NULL) return; // Allocate the array of images (if not already allocated) if (m_pGlowImages == NULL) m_pGlowImages = new CG16bitImage [m_iRotationCount]; // If the image for this rotation has already been initialized, then // we're done if (m_pGlowImages[iRotation].HasAlpha()) return; // Otherwise we need to create the glow mask. The glow image is larger // than the object image (by GLOW_SIZE) int cxSrcWidth = RectWidth(m_rcImage); int cySrcHeight = RectHeight(m_rcImage); int cxGlowWidth = cxSrcWidth + 2 * GLOW_SIZE; int cyGlowHeight = cySrcHeight + 2 * GLOW_SIZE; m_pGlowImages[iRotation].CreateBlankAlpha(cxGlowWidth, cyGlowHeight); // Get the extent of the source image RECT rcSrc; rcSrc.left = ComputeSourceX(0); rcSrc.top = m_rcImage.top + (iRotation * cySrcHeight); rcSrc.right = rcSrc.left + cxSrcWidth; rcSrc.bottom = rcSrc.top + cySrcHeight; // Loop over every pixel of the destination BYTE *pDestRow = m_pGlowImages[iRotation].GetAlphaRow(0); BYTE *pDestRowEnd = m_pGlowImages[iRotation].GetAlphaRow(cyGlowHeight); int ySrc = rcSrc.top - GLOW_SIZE; while (pDestRow < pDestRowEnd) { BYTE *pDest = pDestRow; BYTE *pDestEnd = pDest + cxGlowWidth; int xSrc = rcSrc.left - GLOW_SIZE; while (pDest < pDestEnd) { // If the source image is using this pixel then we don't // do anything. WORD wValue; if ((xSrc >= rcSrc.left && xSrc < rcSrc.right && ySrc >= rcSrc.top && ySrc < rcSrc.bottom) && ((wValue = *(pSource->GetRowStart(ySrc) + xSrc)) != 0x0000)) { DWORD dwGray = (CG16bitImage::RedValue(wValue) + CG16bitImage::GreenValue(wValue) + CG16bitImage::BlueValue(wValue)) / 3; if (dwGray < 0x40) *pDest = 0x60; else *pDest = 0x00; } // Otherwise we process the pixel else { int xStart = (rcSrc.left > (xSrc - GLOW_SIZE) ? ((rcSrc.left - (xSrc - GLOW_SIZE) + (GLOW_SIZE / 2 - 1)) / (GLOW_SIZE / 2)) : 0); int xEnd = ((xSrc + GLOW_SIZE) >= rcSrc.right ? (FILTER_SIZE - (((GLOW_SIZE / 2 + 1) + xSrc + GLOW_SIZE - rcSrc.right) / (GLOW_SIZE / 2))) : FILTER_SIZE); int yStart = (rcSrc.top > (ySrc - GLOW_SIZE) ? ((rcSrc.top - (ySrc - GLOW_SIZE) + (GLOW_SIZE / 2 - 1)) / (GLOW_SIZE / 2)) : 0); int yEnd = ((ySrc + GLOW_SIZE) >= rcSrc.bottom ? (FILTER_SIZE - (((GLOW_SIZE / 2 + 1) + ySrc + GLOW_SIZE - rcSrc.bottom) / (GLOW_SIZE / 2))) : FILTER_SIZE); int iTotal = 0; for (int i = yStart; i < yEnd; i++) for (int j = xStart; j < xEnd; j++) if (*(pSource->GetRowStart(ySrc + g_FilterOffset[i]) + xSrc + g_FilterOffset[j]) != 0x0000) iTotal += g_Filter[i][j]; int iValue = (512 * iTotal / FIXED_POINT); *pDest = (iValue > 0xf8 ? 0xf8 : (BYTE)iValue); } // Next pDest++; xSrc++; } pDestRow = m_pGlowImages[iRotation].NextAlphaRow(pDestRow); ySrc++; } }
bool CObjectImageArray::ImagesIntersect (int iTick, int iRotation, int x, int y, const CObjectImageArray &Image2, int iTick2, int iRotation2) const // ImagesIntersect // // Returns TRUE if the given image intersects with this image { if (m_pImage == NULL || Image2.m_pImage == NULL) return false; // Compute the rectangle of image1 RECT rcRect; int cxWidth = RectWidth(m_rcImage); int cyHeight = RectHeight(m_rcImage); rcRect.left = ComputeSourceX(iTick); rcRect.top = m_rcImage.top + (iRotation * cyHeight); rcRect.right = rcRect.left + cxWidth; rcRect.bottom = rcRect.top + cyHeight; // Compute the rectangle of image2 RECT rcRect2; int cxWidth2 = RectWidth(Image2.m_rcImage); int cyHeight2 = RectHeight(Image2.m_rcImage); rcRect2.left = Image2.ComputeSourceX(iTick); rcRect2.top = Image2.m_rcImage.top + (iRotation2 * cyHeight2); rcRect2.right = rcRect2.left + cxWidth2; rcRect2.bottom = rcRect2.top + cyHeight2; // Now figure out the position of image2 on the image1 coordinate space int xCenter = rcRect.left + (cxWidth / 2); int yCenter = rcRect.top + (cyHeight / 2); RECT rcImage2On1; rcImage2On1.left = xCenter + x - (cxWidth2 / 2); rcImage2On1.top = yCenter + y - (cyHeight2 / 2); if (m_pRotationOffset) { rcImage2On1.left -= m_pRotationOffset[iRotation % m_iRotationCount].x; rcImage2On1.top += m_pRotationOffset[iRotation % m_iRotationCount].y; } if (Image2.m_pRotationOffset) { rcImage2On1.left += Image2.m_pRotationOffset[iRotation2 % Image2.m_iRotationCount].x; rcImage2On1.top -= Image2.m_pRotationOffset[iRotation2 % Image2.m_iRotationCount].y; } rcImage2On1.right = rcImage2On1.left + cxWidth2; rcImage2On1.bottom = rcImage2On1.top + cyHeight2; // Intersect the rectangles RECT rcRectInt; if (!::IntersectRect(&rcRectInt, &rcRect, &rcImage2On1)) return false; // Figure out the position of image1 on the image2 coordinate space int xOffset = rcRect.left - rcImage2On1.left; int yOffset = rcRect.top - rcImage2On1.top; RECT rcImage1On2; rcImage1On2.left = rcRect2.left + xOffset; rcImage1On2.top = rcRect2.top + yOffset; rcImage1On2.right = rcImage1On2.left + cxWidth; rcImage1On2.bottom = rcImage1On2.top + cyHeight; // Intersect the rectangles RECT rcRectInt2; ::IntersectRect(&rcRectInt2, &rcRect2, &rcImage1On2); ASSERT(RectWidth(rcRectInt) == RectWidth(rcRectInt2)); ASSERT(RectHeight(rcRectInt) == RectHeight(rcRectInt2)); // Images CG16bitImage &Src1(*m_pImage->GetImage()); CG16bitImage &Src2(*Image2.m_pImage->GetImage()); return Src1.Intersect(rcRectInt.left, rcRectInt.top, rcRectInt.right, rcRectInt.bottom, Src2, rcRectInt2.left, rcRectInt2.top); }