Example #1
0
CGlowingRingPainter::CGlowingRingPainter (CG32bitImage &Dest, int iRadius, int iWidth, CG32bitPixel rgbColor) :
		m_Dest(Dest),
		m_rcClip(Dest.GetClipRect()),
		m_iRadius(iRadius),
		m_iWidth(iWidth)

//	CGlowingRingPainter constructor

	{
	int i;

	if (m_iWidth <= 0)
		{
		m_pColorRamp = NULL;
		return;
		}

	//	Generate a color ramp

	int iCenter = m_iWidth / 2;
	int iExtra = m_iWidth % 2;
	int iOuter = iCenter - 1;
	int iInner = iCenter + iExtra;

	m_ColorRamp.InsertEmpty(m_iWidth);

	//	We expect the color ramp to be pre-multiplied

	CG32bitPixel rgbPreMult = CG32bitPixel::PreMult(rgbColor);

	//	Init the center

	if (iExtra)
		m_ColorRamp[iCenter] = rgbPreMult;

	//	Edges

	for (i = 0; i < iCenter; i++)
		{
		ASSERT(iOuter >= 0 && iOuter < m_iWidth);
		ASSERT(iInner >=0 && iInner < m_iWidth);

		BYTE byAlpha = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetAlpha() * (iCenter - i) / (iCenter + 1)));
		BYTE byRed = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetRed() * (iCenter - i) / (iCenter + 1)));
		BYTE byGreen = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetGreen() * (iCenter - i) / (iCenter + 1)));
		BYTE byBlue = (BYTE)Min((WORD)0xff, (WORD)(rgbPreMult.GetBlue() * (iCenter - i) / (iCenter + 1)));

		m_ColorRamp[iOuter] = CG32bitPixel(byRed, byGreen, byBlue, byAlpha);
		m_ColorRamp[iInner] = CG32bitPixel(byRed, byGreen, byBlue, byAlpha);

		iOuter--;
		iInner++;
		}

	m_pColorRamp = &m_ColorRamp;
	}
Example #2
0
CGRealRGB::CGRealRGB (CG32bitPixel rgbColor) :
		m_rR(rgbColor.GetRed() / 255.0),
		m_rG(rgbColor.GetGreen() / 255.0),
		m_rB(rgbColor.GetBlue() / 255.0),
		m_rA(rgbColor.GetAlpha() / 255.0)

//	CGRealRGB constructor

	{
	}
Example #3
0
CG32bitPixel CG32bitPixel::Darken (CG32bitPixel rgbSource, BYTE byOpacity)

//	Darken
//
//	Equivalent to Blend(0, rgbSource, byOpacity)
	
	{
	BYTE *pAlpha = g_Alpha8[byOpacity];
	return CG32bitPixel(pAlpha[rgbSource.GetRed()], pAlpha[rgbSource.GetGreen()], pAlpha[rgbSource.GetBlue()]);
	}
Example #4
0
CG32bitPixel CG32bitPixel::Desaturate (CG32bitPixel rgbColor)

//	Desaturate
//
//	Desaturate the given color

	{
	BYTE byMax = Max(Max(rgbColor.GetRed(), rgbColor.GetGreen()), rgbColor.GetBlue());
	BYTE byMin = Min(Min(rgbColor.GetRed(), rgbColor.GetGreen()), rgbColor.GetBlue());
	return CG32bitPixel::FromGrayscale((BYTE)(((DWORD)byMax + (DWORD)byMin) / 2), rgbColor.GetAlpha());
	}
Example #5
0
CGlowingRingPainter::CGlowingRingPainter (CG32bitImage &Dest, int iRadius, int iWidth, const TArray<CG32bitPixel> &ColorRamp, BYTE byOpacity) :
		m_Dest(Dest),
		m_rcClip(Dest.GetClipRect()),
		m_iRadius(iRadius),
		m_iWidth(iWidth)

//	CGlowingRingPainter constructor

	{
	int i;

	//	Pre-multiply the color ramp

	m_ColorRamp.InsertEmpty(ColorRamp.GetCount());
	m_pColorRamp = &m_ColorRamp;

	if (byOpacity == 0xff)
		{
		for (i = 0; i < m_ColorRamp.GetCount(); i++)
			m_ColorRamp[i] = CG32bitPixel::PreMult(ColorRamp[i]);
		}
	else
		{
		for (i = 0; i < m_ColorRamp.GetCount(); i++)
			{
			CG32bitPixel rgbPreMult = CG32bitPixel::PreMult(ColorRamp[i]);
			m_ColorRamp[i] = CG32bitPixel(CG32bitPixel::Blend(0, rgbPreMult, byOpacity), CG32bitPixel::BlendAlpha(rgbPreMult.GetAlpha(), byOpacity));
			}
		}
	}
Example #6
0
CG32bitPixel CG32bitPixel::PreMult (CG32bitPixel rgbColor, BYTE byAlpha)

//	PreMult
//
//	Returns a new color premultiplied by the alpha value.

	{
	if (byAlpha == 0x00)
		return CG32bitPixel::Null();
	else if (byAlpha == 0xff)
		return CG32bitPixel(rgbColor, 0xff);
	else
		{
		BYTE *pAlpha = CG32bitPixel::AlphaTable(byAlpha);

		BYTE byRed = rgbColor.GetRed();
		BYTE byGreen = rgbColor.GetGreen();
		BYTE byBlue = rgbColor.GetBlue();

		return CG32bitPixel(pAlpha[byRed], pAlpha[byGreen], pAlpha[byBlue], byAlpha);
		}
	}
Example #7
0
CG32bitPixel CG32bitPixel::Blend (CG32bitPixel rgbDest, CG32bitPixel rgbSrc)

//	Blend
//
//	Combines rgbSrc with rgbDest, using rgbSrc as the source opacity.
//	We assume dest has no alpha component and we assume that rgbSrc does.

	{
	BYTE *pAlpha = g_Alpha8[rgbSrc.GetAlpha()];
	BYTE *pAlphaInv = g_Alpha8[rgbSrc.GetAlpha() ^ 0xff];	//	Equivalent to 255 - rgbSrc.GetAlpha()

	BYTE byRedResult = pAlphaInv[rgbDest.GetRed()] + pAlpha[rgbSrc.GetRed()];
	BYTE byGreenResult = pAlphaInv[rgbDest.GetGreen()] + pAlpha[rgbSrc.GetGreen()];
	BYTE byBlueResult = pAlphaInv[rgbDest.GetBlue()] + pAlpha[rgbSrc.GetBlue()];

	return CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
	}
Example #8
0
CG32bitPixel CG32bitPixel::Blend (CG32bitPixel rgbFrom, CG32bitPixel rgbTo, double rFade)

//	Fade
//
//	Fade from one value to the other. rFade goes from 0 to 1.

	{
	if (rFade <= 0.0)
		return rgbFrom;
	else if (rFade >= 1.0)
		return rgbTo;
	else
		{
		int iRDiff = (int)(DWORD)rgbTo.GetRed() - (int)(DWORD)rgbFrom.GetRed();
		int iGDiff = (int)(DWORD)rgbTo.GetGreen() - (int)(DWORD)rgbFrom.GetGreen();
		int iBDiff = (int)(DWORD)rgbTo.GetBlue() - (int)(DWORD)rgbFrom.GetBlue();

		BYTE byRed = (BYTE)((int)(DWORD)rgbFrom.GetRed() + (iRDiff * rFade));
		BYTE byGreen = (BYTE)((int)(DWORD)rgbFrom.GetGreen() + (iGDiff * rFade));
		BYTE byBlue = (BYTE)((int)(DWORD)rgbFrom.GetBlue() + (iBDiff * rFade));

		return CG32bitPixel(byRed, byGreen, byBlue);
		}
	}
Example #9
0
CG32bitPixel CG32bitPixel::Fade (CG32bitPixel rgbFrom, CG32bitPixel rgbTo, int iPercent)

//	Fade
//
//	Fade from one value to the other by percent.

	{
	if (iPercent <= 0)
		return rgbFrom;
	else if (iPercent >= 100)
		return rgbTo;
	else
		{
		int iRDiff = (int)(DWORD)rgbTo.GetRed() - (int)(DWORD)rgbFrom.GetRed();
		int iGDiff = (int)(DWORD)rgbTo.GetGreen() - (int)(DWORD)rgbFrom.GetGreen();
		int iBDiff = (int)(DWORD)rgbTo.GetBlue() - (int)(DWORD)rgbFrom.GetBlue();

		BYTE byRed = (BYTE)((int)(DWORD)rgbFrom.GetRed() + (iRDiff * iPercent / 100));
		BYTE byGreen = (BYTE)((int)(DWORD)rgbFrom.GetGreen() + (iGDiff * iPercent / 100));
		BYTE byBlue = (BYTE)((int)(DWORD)rgbFrom.GetBlue() + (iBDiff * iPercent / 100));

		return CG32bitPixel(byRed, byGreen, byBlue);
		}
	}
Example #10
0
CG32bitPixel CG32bitPixel::Blend (CG32bitPixel rgbDest, CG32bitPixel rgbSrc, BYTE bySrcAlpha)

//	Blend
//
//	Combines rgbSrc with rgbDest, using bySrcAlpha as the source opacity.
//	We assume source and dest have no alpha component.

	{
	BYTE *pAlpha = g_Alpha8[bySrcAlpha];
	BYTE *pAlphaInv = g_Alpha8[255 - bySrcAlpha];

	BYTE byRedResult = pAlphaInv[rgbDest.GetRed()] + pAlpha[rgbSrc.GetRed()];
	BYTE byGreenResult = pAlphaInv[rgbDest.GetGreen()] + pAlpha[rgbSrc.GetGreen()];
	BYTE byBlueResult = pAlphaInv[rgbDest.GetBlue()] + pAlpha[rgbSrc.GetBlue()];

	return CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
	}
Example #11
0
void CGSelectorArea::PaintModifier (CG32bitImage &Dest, int x, int y, const CString &sText, CG32bitPixel rgbColor, CG32bitPixel rgbBackColor, int *rety)

//	PaintModifier
//
//	Paints a modifier block.

	{
	int cx = m_VI.GetFont(fontSmall).MeasureText(sText);
	if (!rgbBackColor.IsNull())
		Dest.Fill(x - cx - 8,
				y,
				cx + 8,
				m_VI.GetFont(fontSmall).GetHeight(),
				rgbBackColor);

	m_VI.GetFont(fontSmall).DrawText(Dest,
			x - cx - 4,
			y,
			rgbColor,
			sText);

	if (rety)
		*rety = y + m_VI.GetFont(fontSmall).GetHeight() + 1;
	}
void CCommandLineDisplay::Output (const CString &sOutput, CG32bitPixel rgbColor)

//	Output
//
//	Output the given string

	{
	int i;

	if (m_pFonts == NULL || m_pFonts->Console.GetAverageWidth() == 0)
		return;

	if (rgbColor.IsNull())
		rgbColor = TEXT_COLOR;

	if (sOutput.IsBlank())
		{
		AppendOutput(NULL_STR, rgbColor);
		return;
		}

	int cxCol = m_pFonts->Console.GetAverageWidth();
	int iCols = Max(1, (RectWidth(m_rcRect) - (LEFT_SPACING + RIGHT_SPACING)) / cxCol);

	//	Split into lines

	TArray<CString> Lines;
	m_pFonts->Console.BreakText(sOutput, 
			(RectWidth(m_rcRect) - (LEFT_SPACING + RIGHT_SPACING)),
			&Lines);

	//	Split the string into parts

	for (i = 0; i < Lines.GetCount(); i++)
		AppendOutput(Lines[i], rgbColor);
	}
Example #13
0
void CGlowingRingPainter::DrawLine (int x, int y)

//	DrawLine
//
//	Draws a line

	{
	int xStart = m_xDest - x;
	int xEnd = m_xDest + x + 1;

	if (xEnd <= m_rcClip.left || xStart >= m_rcClip.right)
		return;

	//	See which lines we need to paint

	int yLine = m_yDest - y;
	bool bPaintTop = (yLine >= m_rcClip.top && yLine < m_rcClip.bottom);
	CG32bitPixel *pCenterTop = m_Dest.GetPixelPos(m_xDest, yLine);

	yLine = m_yDest + y;
	bool bPaintBottom = ((y > 0) && (yLine >= m_rcClip.top && yLine < m_rcClip.bottom));
	CG32bitPixel *pCenterBottom = m_Dest.GetPixelPos(m_xDest, yLine);

	//	Compute radius increment

	int iRadius = y;
	int d = -y;
	int deltaE = 3;
	int deltaSE = -2 * y + 1;

	//	Loop

	int xPos = 0;

	//	This will skip the center pixel in the circle (avoids a divide by
	//	zero in the inner loop).

	if (y == 0)
		{
		xPos = 1;
		d += deltaSE;
		deltaE += 2;
		iRadius++;
		}

	//	Blt the line 

	while (xPos <= x)
		{
		//	Figure out the radius of the pixel at this location

		if (d < 0)
			{
			d += deltaE;
			deltaE += 2;
			deltaSE += 2;
			}
		else
			{
			d += deltaSE;
			deltaE += 2;
			//  deltaSE += 0;
			iRadius++;
			}

		//	Compute the index into the ramp based on radius and ring thickness
		//	(If we're outside the ramp, then continue)

		int iIndex = m_iRadius - iRadius;
		if (iIndex >= m_iWidth || iIndex < 0)
			{
			xPos++;
			continue;
			}

		//	Compute the transparency

		CG32bitPixel rgbColor = m_pColorRamp->GetAt(iIndex);
		BYTE byOpacity = rgbColor.GetAlpha();

		//	Optimize opaque painting

		if (byOpacity == 0x00)
			;
		else if (byOpacity == 0xff)
			{
			if (m_xDest - xPos < m_rcClip.right && m_xDest - xPos >= m_rcClip.left)
				{
				if (bPaintTop)
					*(pCenterTop - xPos) = rgbColor;

				if (bPaintBottom)
					*(pCenterBottom - xPos) = rgbColor;
				}

			if (xPos > 0 && m_xDest + xPos < m_rcClip.right && m_xDest + xPos >= m_rcClip.left)
				{
				if (bPaintTop)
					*(pCenterTop + xPos) = rgbColor;

				if (bPaintBottom)
					*(pCenterBottom + xPos) = rgbColor;
				}
			}
		else
			{
			BYTE *pAlphaInv = CG32bitPixel::AlphaTable(byOpacity ^ 0xff);

			WORD wRed = rgbColor.GetRed();
			WORD wGreen = rgbColor.GetGreen();
			WORD wBlue = rgbColor.GetBlue();

			//	Draw transparent

#define DRAW_PIXEL(pos)	\
			{ \
			BYTE byRedResult = (BYTE)Min((WORD)0xff, (WORD)(pAlphaInv[(pos)->GetRed()] + wRed)); \
			BYTE byGreenResult = (BYTE)Min((WORD)0xff, (WORD)(pAlphaInv[(pos)->GetGreen()] + wGreen)); \
			BYTE byBlueResult = (BYTE)Min((WORD)0xff, (WORD)(pAlphaInv[(pos)->GetBlue()] + wBlue)); \
			\
			*(pos) = CG32bitPixel(byRedResult, byGreenResult, byBlueResult); \
			}

			//	Paint

			if (m_xDest - xPos < m_rcClip.right && m_xDest - xPos >= m_rcClip.left)
				{
				if (bPaintTop)
					DRAW_PIXEL(pCenterTop - xPos);

				if (bPaintBottom)
					DRAW_PIXEL(pCenterBottom - xPos);
				}

			if (xPos > 0 && m_xDest + xPos < m_rcClip.right && m_xDest + xPos >= m_rcClip.left)
				{
				if (bPaintTop)
					DRAW_PIXEL(pCenterTop + xPos);

				if (bPaintBottom)
					DRAW_PIXEL(pCenterBottom + xPos);
				}
#undef DRAW_PIXEL
			}

		xPos++;
		}
	}
Example #14
0
void CGButtonArea::Paint (CG32bitImage &Dest, const RECT &rcRect)

//	Paint
//
//	Handle paint

	{
	int i;

	//	Paint the background

	CG32bitPixel rgbBackColor = ((m_bMouseOver && !m_bDisabled) ? m_rgbBackColorHover : (m_bDisabled ? CG32bitPixel(m_rgbBackColor, 0xC0) : m_rgbBackColor));
	if (!rgbBackColor.IsNull())
		{
		if (m_iBorderRadius > 0)
			{
			CGDraw::RoundedRect(Dest, rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), m_iBorderRadius, rgbBackColor);
			CGDraw::RoundedRectOutline(Dest, rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), m_iBorderRadius, 1, m_rgbBorderColor);
			}
		else
			Dest.Fill(rcRect.left, rcRect.top, RectWidth(rcRect), RectHeight(rcRect), rgbBackColor);
		}

	//	Paint the label

	int xPaint = rcRect.left + m_rcPadding.left;
	int yPaint = rcRect.top + m_rcPadding.top;
	if (m_pLabelFont)
		{
		//	If we're disabled, paint gray

		if (m_bDisabled)
			Dest.DrawText(xPaint,
					yPaint,
					*m_pLabelFont,
					RGB_DISABLED_TEXT,
					m_sLabel);

		//	If we have a prefix accelerator, draw that

		else if (!m_sAccelerator.IsBlank())
			{
			//	Measure the size of the accelerator

			int cyAccel;
			int cxAccel = m_pLabelFont->MeasureText(m_sAccelerator, &cyAccel);

			//	We draw a rounded-rect box

			int cxBox = cxAccel + (2 * ACCEL_INNER_PADDING);
			int cyBox = cyAccel + 1;
			CGDraw::RoundedRect(Dest, xPaint, yPaint, cxBox, cyBox, ACCEL_BORDER_RADIUS, m_rgbAccelColor);

			//	Draw the text

			Dest.DrawText(xPaint + ACCEL_INNER_PADDING, yPaint, *m_pLabelFont, CG32bitPixel(0, 0, 0), m_sAccelerator);

			//	Now draw the rest of the label

			Dest.DrawText(xPaint + cxBox + (2 * ACCEL_INNER_PADDING), yPaint, *m_pLabelFont, m_rgbLabelColor, m_sLabel);
			}

		//	If we have an accelerator, paint in pieces

		else if (m_iAccelerator != -1)
			{
			char *pPos = m_sLabel.GetASCIIZPointer();
			int x = xPaint;

			if (m_iAccelerator > 0)
				Dest.DrawText(x, yPaint, *m_pLabelFont, m_rgbLabelColor, CString(pPos, m_iAccelerator, true), 0, &x);

			Dest.DrawText(x, yPaint, *m_pLabelFont, m_rgbAccelColor, CString(pPos + m_iAccelerator, 1, true), 0, &x);
			Dest.DrawText(x, yPaint, *m_pLabelFont, m_rgbLabelColor, CString(pPos + m_iAccelerator + 1, m_sLabel.GetLength() - m_iAccelerator - 1, true));
			}
		else
			Dest.DrawText(xPaint,
					yPaint,
					*m_pLabelFont,
					m_rgbLabelColor,
					m_sLabel);

		yPaint += m_pLabelFont->GetHeight();
		}

	//	Paint the description

	if (m_pDescFont)
		{
		for (i = 0; i < m_Lines.GetCount(); i++)
			{
			Dest.DrawText(xPaint,
					yPaint,
					*m_pDescFont,
					m_rgbDescColor,
					m_Lines[i]);

			yPaint += m_pDescFont->GetHeight();
			}
		}
	}
Example #15
0
void CG8bitSparseImage::MaskFill (CG32bitImage &Dest, int xDest, int yDest, int cxDest, int cyDest, int xSrc, int ySrc, CG32bitPixel rgbColor) const

//	MaskFill
//
//	Fills the destination image with the given color through our mask.

	{
	//	Make sure we're in bounds

	if (!Dest.AdjustCoords(&xSrc, &ySrc, GetWidth(), GetHeight(), 
			&xDest, &yDest,
			&cxDest, &cyDest))
		return;

	//	Short-circuit

	if (rgbColor.GetAlpha() == 0x00)
		return;

	//	Compute a pre-multiplied color

	BYTE *pAlpha = CG32bitPixel::AlphaTable(rgbColor.GetAlpha());
	CG32bitPixel rgbPreMultColor = CG32bitPixel(pAlpha[rgbColor.GetRed()], pAlpha[rgbColor.GetGreen()], pAlpha[rgbColor.GetBlue()], rgbColor.GetAlpha());

	//	Loop

	int yPos = ySrc;
	int yPosEnd = ySrc + cyDest;
	int yTile = yPos / m_cyTile;
	int yOffset = ClockMod(yPos, m_cyTile);
	int xTileStart = xSrc / m_cxTile;
	int xOffsetStart = ClockMod(xSrc, m_cxTile);

	int yDestPos = yDest;
	while (yPos < yPosEnd)
		{
		int cyTileLeft = Min(m_cyTile - yOffset, yPosEnd - yPos);

		//	Is this a valid tile row, then continue

		if (yTile >= 0 && yTile < m_yTileCount)
			{
			int xPos = xSrc;
			int xPosEnd = xSrc + cxDest;
			int xTile = xTileStart;
			int xOffset = xOffsetStart;

			int xDestPos = xDest;
			while (xPos < xPosEnd)
				{
				int cxTileLeft = Min(m_cxTile - xOffset, xPosEnd - xPos);

				//	If this is a valid tile, then we can continue

				if (xTile >= 0 && xTile < m_xTileCount)
					{
					const CNode &Tile = GetTile(xTile, yTile);

					switch (Tile.GetType())
						{
						case typeByte:
							{
							BYTE byAlpha = Tile.GetByte();
							if (byAlpha == 0x00)
								{}
							else if (byAlpha == 0xff)
								Dest.Fill(xDestPos, yDestPos, cxTileLeft, cyTileLeft, rgbColor);
							else
								//	We just modify the alpha on the original color (Fill will take care of the rest)
								Dest.Fill(xDestPos, yDestPos, cxTileLeft, cyTileLeft, CG32bitPixel(rgbColor, CG32bitPixel::BlendAlpha(rgbColor.GetAlpha(), byAlpha)));
							break;
							}

						case typeNodeArray:
							{
							CNode *Rows = Tile.GetNodeArray();
							CNode *pSrcRow = Rows + yOffset;
							CNode *pSrcRowEnd = pSrcRow + cyTileLeft;

							CG32bitPixel *pDestRow = Dest.GetPixelPos(xDestPos, yDestPos);

							while (pSrcRow < pSrcRowEnd)
								{
								CG32bitPixel *pDest = pDestRow;
								CG32bitPixel *pDestEnd = pDestRow + cxTileLeft;

								switch (pSrcRow->GetType())
									{
									case typeByte:
										{
										BYTE byAlpha = pSrcRow->GetByte();
										if (byAlpha == 0x00)
											{}
										else if (byAlpha == 0xff)
											{
											BYTE byFillAlpha = rgbColor.GetAlpha();
											if (byFillAlpha == 0xff)
												{
												while (pDest < pDestEnd)
													*pDest++ = rgbColor;
												}
											else
												{
												BYTE *pAlphaInv = CG32bitPixel::AlphaTable(byFillAlpha ^ 0xff);

												BYTE byRed = rgbPreMultColor.GetRed();
												BYTE byGreen = rgbPreMultColor.GetGreen();
												BYTE byBlue = rgbPreMultColor.GetBlue();

												while (pDest < pDestEnd)
													{
													BYTE byRedResult = pAlphaInv[pDest->GetRed()] + byRed;
													BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + byGreen;
													BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + byBlue;

													*pDest++ = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}
												}
											}
										else
											{
											//	Blend the alphas together
											BYTE byFillAlpha = CG32bitPixel::BlendAlpha(byAlpha, rgbColor.GetAlpha());

											BYTE *pAlpha = CG32bitPixel::AlphaTable(byFillAlpha);
											BYTE *pAlphaInv = CG32bitPixel::AlphaTable(byFillAlpha ^ 0xff);

											BYTE byRed = pAlpha[rgbColor.GetRed()];
											BYTE byGreen = pAlpha[rgbColor.GetBlue()];
											BYTE byBlue = pAlpha[rgbColor.GetGreen()];

											while (pDest < pDestEnd)
												{
												BYTE byRedResult = pAlphaInv[pDest->GetRed()] + byRed;
												BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + byGreen;
												BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + byBlue;

												*pDest++ = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
												}
											}
										break;
										}

									case typeByteArray:
										{
										BYTE *pSrcAlpha = pSrcRow->GetByteArray() + xOffset;
										BYTE *pSrcAlphaEnd = pSrcAlpha + cxTileLeft;

										BYTE byColorAlpha = rgbColor.GetAlpha();
										if (byColorAlpha == 0xff)
											{
											while (pSrcAlpha < pSrcAlphaEnd)
												{
												if (*pSrcAlpha == 0x00)
													{}
												else if (*pSrcAlpha == 0xff)
													*pDest = rgbColor;
												else
													{
													BYTE *pAlpha = CG32bitPixel::AlphaTable(*pSrcAlpha);
													BYTE *pAlphaInv = CG32bitPixel::AlphaTable(*pSrcAlpha ^ 0xff);

													BYTE byRedResult = pAlphaInv[pDest->GetRed()] + pAlpha[rgbColor.GetRed()];
													BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + pAlpha[rgbColor.GetGreen()];
													BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + pAlpha[rgbColor.GetBlue()];

													*pDest = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}

												pSrcAlpha++;
												pDest++;
												}
											}
										else
											{
											BYTE *pAlphaFFInv = CG32bitPixel::AlphaTable(byColorAlpha ^ 0xff);

											while (pSrcAlpha < pSrcAlphaEnd)
												{
												if (*pSrcAlpha == 0x00)
													{}
												else if (*pSrcAlpha == 0xff)
													{
													BYTE byRedResult = pAlphaFFInv[pDest->GetRed()] + rgbPreMultColor.GetRed();
													BYTE byGreenResult = pAlphaFFInv[pDest->GetGreen()] + rgbPreMultColor.GetGreen();
													BYTE byBlueResult = pAlphaFFInv[pDest->GetBlue()] + rgbPreMultColor.GetBlue();

													*pDest = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}
												else
													{
													BYTE byFillAlpha = CG32bitPixel::BlendAlpha(*pSrcAlpha, byColorAlpha);

													BYTE *pAlpha = CG32bitPixel::AlphaTable(byFillAlpha);
													BYTE *pAlphaInv = CG32bitPixel::AlphaTable(byFillAlpha ^ 0xff);

													BYTE byRedResult = pAlphaInv[pDest->GetRed()] + pAlpha[rgbColor.GetRed()];
													BYTE byGreenResult = pAlphaInv[pDest->GetGreen()] + pAlpha[rgbColor.GetGreen()];
													BYTE byBlueResult = pAlphaInv[pDest->GetBlue()] + pAlpha[rgbColor.GetBlue()];

													*pDest = CG32bitPixel(byRedResult, byGreenResult, byBlueResult);
													}

												pSrcAlpha++;
												pDest++;
												}
											}
										break;
										}
									}

								pSrcRow++;
								pDestRow = Dest.NextRow(pDestRow);
								}

							break;
							}
						}
					}

				//	Move to the next tile

				xTile++;
				xOffset = 0;
				xPos += cxTileLeft;
				xDestPos += cxTileLeft;
				}
			}

		//	Next tile row

		yTile++;
		yOffset = 0;
		yPos += cyTileLeft;
		yDestPos += cyTileLeft;
		}
	}