/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: drawptxt.cpp,v 1.1.2.1 2004/07/09 01:50:38 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

/////////////////////////////////////////////////////////////////////////////
//
// drawptxt.cpp	
//
//	(Macintosh version of ../WIN/drawptxt.cpp)
//
//


#include "hxtypes.h"
#include "hxassert.h"
#include "hxslist.h"
#include "hxstack.h"
#include "chxxtype.h"
#include "rt_types.h"
#include "txtattrb.h"
#include "txtcntnr.h"
#include "textline.h"
#include "txtwindw.h"
#include "textprsr.h"
#include "rtwin.h"
#include "atocolor.h"
#include "fontdefs.h"
#include "fontinfo.h"
#ifndef _MAC_MACHO
#include "ugworld.h"
#include "udstate.h"
#endif
#include "hxcom.h"
#include "hxvsurf.h" // for IHXVideoSurface
#include "hxevent.h" // for HX_SURFACE_UPDATE

#ifndef _MAC_MACHO
#include <Quickdraw.h>
#endif

#ifndef _MAC_MACHO
#include "udutils.h" // to get topLeft and botRight macros
#endif

#include "platform/mac/maclibrary.h" // for DWORD

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static char HX_THIS_FILE[] = __FILE__;
#endif


// /These are in mrtwin.cpp:
UINT16	Convert8BitTo16Bit(UINT8 x);
void ConvertCOLORTYPEtoRGBColor(RGBColor& rgbColor, COLORTYPE colorVal);



BOOL
DrawPlainText(TextWindow* pTextWindow, void* pvoidEvent,
	void* pPaintstruct, ULONG32 ulTimeOfCurrentDraw)
{
    HX_ASSERT_VALID_PTR(pTextWindow);
    if(!pTextWindow)
    {
	return FALSE;
    }
    
    BOOL b_FunctionSucceeded = TRUE;
    LONG32 lWindowWidth = pTextWindow->getWindowWidth();
    LONG32 lWindowHeight = pTextWindow->getWindowHeight();

    HXxEvent* pEvent = (HXxEvent*)pvoidEvent;
    HX_ASSERT(pEvent);
	    
    ULONG32 listSize = pTextWindow->textCntnrListSize();

    Rect updateRect;
    ::SetRect(&updateRect, 0, 0, pTextWindow->getWindowWidth(), pTextWindow->getWindowHeight()); 
    // /XXXEH- use the following if and when the core starts doing
    // subrects on the Mac:
    CHXxRect* pDestRect = pEvent?
            (CHXxRect*)((HXxEvent*)pvoidEvent)->param2 :
            NULL;

    COLORTYPE backColorType = pTextWindow->getBackgroundColor();

    UINT32 ulEffectiveFgOpacity = pTextWindow->getMediaOpacity();
    UINT32 ulEffectiveBgOpacity = pTextWindow->getBackgroundOpacity();
    UINT32 ulChromaKey = pTextWindow->getChromaKey();
    UINT32 ulChromaKeyTolerance = pTextWindow->getChromaKeyTolerance();
    UINT32 ulChromaKeyOpacity = pTextWindow->getChromaKeyOpacity();        
    // /Helps fix PR 67215:
    // Initialize chromaKey flag. If the background color is the same as the
    // chroma key, then we know we are applying the chroma key. Also, when we
    // draw text of a certain color later down in this method, we may be
    // setting this flag, depending on the text color:
    BOOL bChromaKeyWasApplied = FALSE;
    if (pTextWindow->isChromaKeySet())
    {
        if (DoesChromaKeyMatch(backColorType, ulChromaKey,
		ulChromaKeyTolerance))
        {
            if (ulChromaKeyOpacity < 255)
            {
                bChromaKeyWasApplied = TRUE;
                ulEffectiveBgOpacity = ulChromaKeyOpacity;
            }
        }
    }
    
    // /Draw all the text:
    {
	GWorldPtr theMacGWorld;
	CGrafPtr theSavePort;
	GDHandle theSaveDevice;
	Rect theBounds = updateRect;
	{
	    ::GetGWorld(&theSavePort, &theSaveDevice);
	    RGBColor theForeColor, theBackColor;
	    ::GetForeColor(&theForeColor);
	    ::GetBackColor(&theBackColor);
	    RgnHandle theClipRgn = ::NewRgn();
	    ::GetClip(theClipRgn);
	    theMacGWorld = NULL;
	    
	    Rect gwRect = theBounds;
	    
            Point topLeft;
            Point botRight;
            
            topLeft.h = gwRect.left;
            topLeft.v = gwRect.top;
            
            botRight.h = gwRect.right;
            botRight.v = gwRect.bottom;
            
	    LocalToGlobal(&topLeft);
	    LocalToGlobal(&botRight);
            
            gwRect.left = topLeft.h;
            gwRect.top = topLeft.v;
            gwRect.right = botRight.h;
            gwRect.bottom = botRight.v;
	    	    
	    theMacGWorld = pTextWindow->m_pOffScreenWorld;
	    if (theMacGWorld)
	    {
		::SetGWorld(theMacGWorld, NULL);
		::SetOrigin(theBounds.left, theBounds.top);
		::SetClip(theClipRgn);
		::LockPixels((::GetGWorldPixMap(theMacGWorld)));
		::RGBForeColor(&theForeColor);
		::RGBBackColor(&theBackColor);
	    }
	    else
	    {
		b_FunctionSucceeded = FALSE;
		goto cleanup;
	    }
	    ::DisposeRgn(theClipRgn);
	}

	RGBColor backColor, prevBackColor;
	ConvertCOLORTYPEtoRGBColor(backColor, backColorType);
	::GetBackColor(&prevBackColor);

	// /Paint the background with the specified color:
	// /Just paint using OS API with non-alpha color:
	::RGBBackColor(&backColor);
	::EraseRect(&updateRect);

	//Only draw the text again if we really need to:
	if (listSize  &&
		(TIME_INVALID != ulTimeOfCurrentDraw) )
	{
	    LISTPOSITION pos = pTextWindow->GetStartPosition();

	    while(pos)
	    {
		TextContainer* curTextContainerPtr =
				/*  Note: effectively does GetAt(pos++):  */
				(TextContainer*)pTextWindow->GetNext(pos);

		if (curTextContainerPtr->textHasChangedSinceLastDraw()  ||
			curTextContainerPtr->textShouldBeDrawn())
		{
		    _CHAR* pTextbuffer = curTextContainerPtr->getBuffer();
		    ULONG32 ulTextLengthPlusOneOfCurTC =
			    curTextContainerPtr->getTextLengthPlus1();

		    if (!pTextbuffer  ||  ulTextLengthPlusOneOfCurTC <= 1)
		    {
		        curTextContainerPtr->textHasChangedSinceLastDraw(FALSE);
		        continue;
		    }

		    LONG32 lUpperLeftXWithOffsets =
			    curTextContainerPtr->getXUpperLeftCorner();
		    LONG32 lLowerRightXWithOffsets =
			    curTextContainerPtr->getXLowerRightCorner();
		    LONG32 lUpperLeftYWithOffsets =
			    curTextContainerPtr->getYUpperLeftCorner();
		    LONG32 lLowerRightYWithOffsets =
			    curTextContainerPtr->getYLowerRightCorner();

		    LONG32 xScaled = lUpperLeftXWithOffsets;

		    LONG32 yScaled = lUpperLeftYWithOffsets;
		    
		    const char* pCurFontFaceString = // /NOTE: NULL is a valid value:
			    pTextWindow->getDefaultFontFaceString();
			    
		    const char* pCharset = pTextWindow->getDefaultCharsetString();
		    
		    ULONG32 ulCharset = CHARSET__default;
		    if (pCharset) // /If NULL, just use user's default
		    {
			pTextWindow->getCharsetULONG32(pCharset,
				PLAINTEXT_MAX_CHARSET_LEVEL_SUPPORTED, ulCharset);
			
			BOOL bMightNeedCharsetTranslationForMac = FALSE;
			
			if (CHARSET__iso_8859_1 == ulCharset)
			{
			    bMightNeedCharsetTranslationForMac = TRUE;
			}
			
			// /XXXEH- handle other charset conversions here.
			
			if (bMightNeedCharsetTranslationForMac)
			{
			    if (!pTextWindow->isCharsetTranslatedForOS())
			    {
				// /This may change some of the buffer contents;
				// if so, it's on a 1-byte-for-1-byte basis:
				if (ConvertAcrossCharacterSets(pTextbuffer,
					ulCharset, TRUE,
					PLAINTEXT_MAX_CHARSET_LEVEL_SUPPORTED))
				{
				    pTextWindow->setCharsetTranslatedForOS(TRUE);
				}
			    }
			}
		    }
		    
		    Style tcStyle = NULL;
#if XXXEH_HANDLE_UNDERLINE
		    BOOL bIsUnderlined =
			    pTextWindow->isUnderlinedPlainText();
#else
		    BOOL bIsUnderlined = FALSE;
#endif
		    ULONG32 ulFontWeight = pTextWindow->getDefaultFontWeight();
		    // /XXXEH- add bold-threshold defined value:
		    if (ulFontWeight > DEFAULT_FONT_WEIGHT + 100)
		    {
			tcStyle += bold;
		    }
		    if (pTextWindow->isDefaultFontStyleItalic())
		    {
			tcStyle += italic;
		    }

		    ULONG32 ulBasePointSize = pTextWindow->getDefaultPtSize();
		    
		    TextFace(tcStyle);

		    BOOL bFontFaceFoundOnSystem = FALSE;
		    INT16 iFaceIndx = 0;
		    
		    if (pCurFontFaceString)
		    {
			INT16 iLenOfCurFontFace = strlen(pCurFontFaceString)+1;
			char* pFontFaceBuf = new char[iLenOfCurFontFace];
			if (!pFontFaceBuf)
			{
			     b_FunctionSucceeded = FALSE;
			     goto cleanup;
			}
			*pFontFaceBuf = '\0';
			//change C str to Pascal str
			c2pstrcpy((StringPtr)pFontFaceBuf, pCurFontFaceString);
			GetFNum((StringPtr)pFontFaceBuf, (short*)&iFaceIndx);
			bFontFaceFoundOnSystem = (iFaceIndx!=0);
			delete [] pFontFaceBuf;
		    }
		    //else it's an empty string so do mapping, below...

		    // /If the author specified an explicit font and it was
		    // not found installed on the system, use a reasonable
		    // substitute font based on the charset:
		    if (!bFontFaceFoundOnSystem  &&  pCurFontFaceString  &&
			    pCharset != NULL)
		    {
			if (CHARSET__x_sjis == ulCharset)
			{
			    GetFNum("\pOsaka", (short*)&iFaceIndx);
			    // /XXXEH- if that failed, look for other
			    // well-known Japanese shift-jis fonts:
			}
			else if (CHARSET__gb2312 == ulCharset)
			{
			    // /Simplified Chinese:
			    GetFNum("\p'ËÎÌå", (short*)&iFaceIndx);
			}
			else if (CHARSET__big5 == ulCharset  ||
				CHARSET__x_euc_tw == ulCharset)
			{
			    // /Traditional Chinese:
			    GetFNum("\p²Ó©úÅé", (short*)&iFaceIndx);
			}
			else if (CHARSET__hangeul == ulCharset  ||
				CHARSET__ksc5601 == ulCharset)
			{
			    GetFNum("\pSeoul", (short*)&iFaceIndx);
			    if(0==iFaceIndx)
			    {
				GetFNum("\pAppleGothic", (short*)&iFaceIndx);
			    }
			    if(0==iFaceIndx)
			    {
				GetFNum("\pGothic", (short*)&iFaceIndx);
			    }
			    if(0==iFaceIndx)
			    {
				GetFNum("\pBatang", (short*)&iFaceIndx);
			    }
			    if(0==iFaceIndx)
			    {
				GetFNum("\pBatangche", (short*)&iFaceIndx);
			    }
			    if(0==iFaceIndx)
			    {
				GetFNum("\pGulim", (short*)&iFaceIndx);
			    }
			    if(0==iFaceIndx)
			    {
				GetFNum("\pGulimche", (short*)&iFaceIndx);
			    }
			}
		    }
		    if (iFaceIndx)
		    {
			TextFont(iFaceIndx);
		    }
		    else // /0 is sys font, 1 is application font; use app font:
		    {
			TextFont(1);
		    }
		    
		    INT32 lScaledHeight = (INT32)(ulBasePointSize);

		    FontInfo fi;
		    
		    TextSize(INT32(ulBasePointSize));
		    TextMode(srcOr);
		    
		    GetFontInfo(&fi);

		    RGBColor textColor, bgTextColor;
		    
		    COLORTYPE foreColorType = pTextWindow->getDefaultTextColor();
		    // /Part of "fix" for PR 67215: if text color == bgcolor,
		    // adjust text color to be off by 1 so that the work-around
		    // for PR 67215, below, doesn't think fg pixels are bg ones.
		    // This allows mediaOpacity<255 and/or backgroundOpacity<255
		    // to work even if text color equals bgcolor.  (If no media
		    // transparency AND no bg transparency, or if both are
		    // equal, we don't need to do anything.)  Note that chroma-
		    // key is already factored into both Fg and BgOpacity vals:
		    if (foreColorType == backColorType  &&
			    ulEffectiveFgOpacity != ulEffectiveBgOpacity)
		    {
			if (0xFFFFFF == foreColorType)
			{
			    foreColorType--;
			}
			else
			{
			    foreColorType++;
			}
		    }

		    ConvertCOLORTYPEtoRGBColor(textColor, foreColorType);

		    // /Move to the appropriate spot for drawing.
		    INT16 moveX = xScaled + updateRect.left;
		    INT16 moveY = yScaled + lScaledHeight - fi.descent + updateRect.top;
		    MoveTo(moveX, moveY);

		    // /Set the text color 
		    ::RGBForeColor(&textColor);

		    INT16 iAlign = teFlushDefault;
		    INT16 iYOffsetForVertAlign = 0;
		    BOOL bDoSingleLineWithExplicitLineBreaksAsSpaces = FALSE;
		    BOOL bAvoidWordWrapsInTextBox = FALSE;
		    textHorizAlign curHorizAlign = pTextWindow->getHorizAlign();
		    if (!pTextWindow->usingWordwrap())
		    {
			textVertAlign curVertAlign = pTextWindow->getVertAlign();
			if (pTextWindow->wasVertAlignExplicitlySet())
			{
			    // /DrawText() forces newline chars to act as space chars,
			    // so only do this if author explicitly set the vert alignment
			    // attribute which only works if all text is on a single-line:
			    bDoSingleLineWithExplicitLineBreaksAsSpaces = TRUE;
			}
			else
			{
			    // /Fixes Mac version of PR 73512: if wordWrap is "false" and
			    // there are explicit newline characters, we need to make sure
			    // that TETextBox's box is large enough that wordwraps can't occur:
			    bAvoidWordWrapsInTextBox = TRUE;
			}
			
			if (kVAlignCenter == curVertAlign)
			{
			    iYOffsetForVertAlign = (lWindowHeight - lScaledHeight)/2;
			}
			else if (kVAlignBottom == curVertAlign)
			{
			    iYOffsetForVertAlign = lWindowHeight - lScaledHeight;
			}
			else
			{
			    HX_ASSERT(kVAlignTop == curVertAlign);
			    iYOffsetForVertAlign = fi.descent;
			}
		    }
		    if (pTextWindow->usingWordwrap()  ||  // /multi-line
			    bAvoidWordWrapsInTextBox)
		    {
			if (kHAlignCenter == curHorizAlign)
			{
			    iAlign = teCenter;
			}
			else if (kHAlignRight == curHorizAlign)
			{
			    iAlign = teFlushRight;
			}
			else if (kHAlignLeft == curHorizAlign)
			{
			    iAlign = teFlushLeft;
			}
			// /else use default horiz alignment (teFlushDefault)
		    }

		    BOOL bDrawBackgroundOfCharacters = FALSE;
		    COLORTYPE bgTextColorCOLORTYPE = pTextWindow->getDefaultTextBgColor();
		    if (BAD_RGB_COLOR != bgTextColorCOLORTYPE  &&
				TRANSPARENT_COLOR != bgTextColorCOLORTYPE)
		    {
			ConvertCOLORTYPEtoRGBColor(bgTextColor, bgTextColorCOLORTYPE);
			bDrawBackgroundOfCharacters = TRUE;
		    }

		    if (bDoSingleLineWithExplicitLineBreaksAsSpaces)
		    {
			Rect bgRect;
			if (bDrawBackgroundOfCharacters)
			{
			    bgRect.right = TextWidth((void*)pTextbuffer, 0,
				(SInt16)ulTextLengthPlusOneOfCurTC-1) + 1;
			    bgRect.left = moveX;
			    bgRect.top = moveY + iYOffsetForVertAlign -
				lScaledHeight + (fi.descent/2);
			    bgRect.bottom = bgRect.top + lScaledHeight + 1;
			    RGBColor rgb;
			    ::GetForeColor(&rgb);
			    ::RGBForeColor(&bgTextColor);
			    ::PaintRect(&bgRect);
			    ::RGBForeColor(&rgb);
			}
			MoveTo(moveX, moveY + iYOffsetForVertAlign);
			DrawText((void*)pTextbuffer, 0,
				(SInt16)ulTextLengthPlusOneOfCurTC-1);
		    }
		    else // /Allow for multiple lines:
		    {
			if (bDrawBackgroundOfCharacters)
			{
			    RGBColor rgb;
			    ::GetForeColor(&rgb);
			    ::RGBForeColor(&bgTextColor);
			    TextMode(notSrcOr);			    
			    TETextBox((void*)pTextbuffer, (INT32)ulTextLengthPlusOneOfCurTC-1,
				    &updateRect, iAlign);
			    ::RGBForeColor(&rgb);
#if defined(XXXEH_TESTING_BGCOLORING)
#else
// /XXXEH- This doesn't work yet; need to draw to another GWorld and
// then merge the two offscreens to get the final result:	    
			    TextMode(srcOr);
#endif
			}
#if defined(XXXEH_TESTING_BGCOLORING)
updateRect.bottom = 100;
updateRect.right = 100;
TETextBox((void*)pTextbuffer, 10,
	&updateRect, iAlign);
#else
			if (bAvoidWordWrapsInTextBox)
			{
			    // /Fixes Mac version of PR 73512; allow explicit newline
			    // chars to be interpreted literally but don't allow
			    // (implicit) word wrap:
			    INT32 iTextWidthInPixels = TextWidth((void*)pTextbuffer, 0,
				(SInt16)ulTextLengthPlusOneOfCurTC-1) + 1;
			    if (teFlushLeft == iAlign)
			    {
				updateRect.right = iTextWidthInPixels;
			    }
			    else if (teFlushRight == iAlign)
			    {
				updateRect.left = updateRect.right -
					iTextWidthInPixels;
			    }
			    else if (teCenter == iAlign)
			    {
				updateRect.left =
					(-iTextWidthInPixels + lWindowWidth) / 2;
				updateRect.right =
					(iTextWidthInPixels + lWindowWidth) / 2;
			    }
			}

			// /XXXEH- TODO: use DrawThemeTextBox() per grobbins:
			TETextBox((void*)pTextbuffer, (INT32)ulTextLengthPlusOneOfCurTC-1,
				&updateRect, iAlign);

#endif
		    }

		    curTextContainerPtr->textHasChangedSinceLastDraw(FALSE);
		    
		} //end if (...textShouldBeDrawn... || ...textHasChanged...).	    
	    } //end "while(pos)".
	} //end "if (listSize...)".

        // /Adding this helps fix chromaKey part of PR 67215 (which
        // was a lack of support for media opacity & chroma key):
        UINT32 ulFGColor = (UINT32)pTextWindow->getDefaultTextColor();
        if (pTextWindow->isChromaKeySet()  &&
		ulChromaKeyOpacity < 255)
        {
            if (DoesChromaKeyMatch(ulFGColor,
                            ulChromaKey, ulChromaKeyTolerance) )
	    {
		ulEffectiveFgOpacity = ulChromaKeyOpacity;
		bChromaKeyWasApplied = TRUE;
	    }
	}

	::RGBBackColor(&prevBackColor);

	::SetGWorld(theSavePort, theSaveDevice);
	if (theMacGWorld)
	{
	    RGBColor holdFore;
            RGBColor holdBack;
            RGBColor blackRGB = {0x0000,0x0000,0x0000};
            RGBColor whiteRGB = {0xffff,0xffff,0xffff};
            ::GetForeColor(&holdFore);
            ::GetBackColor(&holdBack);
            ::RGBForeColor(&blackRGB);
            ::RGBBackColor(&whiteRGB);
            
	    if (pEvent && pEvent->event == HX_SURFACE_UPDATE)
	    {
		IHXVideoSurface* pVideoSurface = (IHXVideoSurface*)pEvent->param1;
		HX_ASSERT(pVideoSurface);
		if (pVideoSurface)
		{
		    pVideoSurface->AddRef();
		    
		    HXxRect destRect, srcRect;
		    destRect.left = 0;
		    destRect.top = 0;
		    destRect.right = theBounds.right-theBounds.left;
		    destRect.bottom = theBounds.bottom-theBounds.top;
		    srcRect = destRect;
		    
		    PixMapHandle thePM = ::GetGWorldPixMap(theMacGWorld); // it's already been locked, woo hoo
		    
		    UCHAR* pDataBlob = (UCHAR*)::GetPixBaseAddr(thePM);

		    HXBitmapInfoHeader bitmapInfo;
		    
		    bitmapInfo.biSize = sizeof(bitmapInfo);
		    bitmapInfo.biWidth = ((**thePM).rowBytes & 0x3fff) / 4;
		    bitmapInfo.biHeight = (theBounds.bottom - theBounds.top);
		    bitmapInfo.biPlanes = 1; // definitely for RGB data
		    bitmapInfo.biBitCount = 32; // number of bits per pixel
		    bitmapInfo.biCompression = HXCOLOR_RGB3_ID;
		    bitmapInfo.biSizeImage = ((**thePM).rowBytes & 0x3fff) * bitmapInfo.biHeight;
		    bitmapInfo.biXPelsPerMeter = 0; // sez to always use 0
		    bitmapInfo.biYPelsPerMeter = 0; // sez to always use 0
		    bitmapInfo.biClrUsed = 0; // it's not 8-bit RGB
		    bitmapInfo.biClrImportant = 0; // it's not 8-bit RGB
		    bitmapInfo.rcolor = 0;
		    bitmapInfo.gcolor = 0;
		    bitmapInfo.bcolor = 0;

		    // /Handle alpha channel if not everything is fully opaque:
		    DWORD oldComp = bitmapInfo.biCompression;
		    if (pTextWindow->getBackgroundOpacity() < 255 ||
			    pTextWindow->getMediaOpacity() < 255 ||
			    bChromaKeyWasApplied)
		    {
			bitmapInfo.biCompression = HX_ARGB; // /AlphaRGB
			
			// /So, here's the fix (w/work-around) for PR 67215:
			// Go through buffer and set alpha values for
			// background pixels to background transparency val,
			// and set alpha values for all foreground pixels to
			// foreground transparency val:
			UINT32 uiSzMinusBytesProcessed = bitmapInfo.biSizeImage;
			UINT32 ulFgAlpha = (0xFF - 
				(ulEffectiveFgOpacity & 0xFF)) << 24;
			UINT32 ulBgAlpha = (0xFF - 
				(ulEffectiveBgOpacity & 0xFF)) << 24;
			UINT32* pBlob = (UINT32*)pDataBlob;
			while (uiSzMinusBytesProcessed  &&  pBlob)
			{
			    // /First, remove Mac-imposed 0xFF alpha val:
			    *pBlob &= 0x00FFFFFF;
			    if (backColorType == *pBlob)
			    {
				// /A background pixel; set bg alpha (if any):
				*pBlob |= ulBgAlpha;
			    }
			    else
			    {
				// /A foreground pixel; set fg alpha (if any):
				*pBlob |= ulFgAlpha;
			    }
			    uiSzMinusBytesProcessed -= 4;
			    pBlob++;
			}
		    }

		    pEvent->result = pVideoSurface->Blt(
				pDataBlob,
				&bitmapInfo,
				destRect,
				srcRect);
		    
		    bitmapInfo.biCompression = oldComp; // /restore it.

		    HX_RELEASE(pVideoSurface);
		}
	    }
	    
	    ::UnlockPixels(::GetGWorldPixMap(theMacGWorld));
            
            ::RGBForeColor(&holdFore);
            ::RGBBackColor(&holdBack);
	}
    }
    
    b_FunctionSucceeded=TRUE;

cleanup:

    return b_FunctionSucceeded;
}

