/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: mrtwin.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 ***** */

/////////////////////////////////////////////////////////////////////////////
//
// mrtwin.cpp	
//
//	(Macintosh version of RTWIN.cpp)
//
// Function:
//  BOOL OnPaint(TextWindow* pTextWindow, void* pDC, void* pPaintstruct,
//		BOOL bSomeonesBeginOrEndTimeWasCrossedOverSinceLastDraw,
//		INT16 xScrollWindowAmt, INT16 yScrollWindowAmt);
//
// Purpose:
//  This function does the actual rendering of text by doing a TextOut() of
//  all text in all TextContainers in the TextContainerList of pTextWindow
//  whose text is visible in the rectangle to be updated
//  This Function is called from WM_PAINT and hdc and ps are from
//  BeginPaint(); ps holds the invalid rectangle to be updated: 
//
// Returns:
//  Returns FALSE on error, TRUE otherwise. 
//
//
//
// Function:
//  BOOL PaintBackground(TextWindow* pTextWindow, void* pPaintstruct)
//
// Purpose:
//  This function paints the background of the window at the given rectangle
//  of pPaintstruct.
//  This Function is called from WM_PAINT, and pPaintstruct is (in Windows)
//  from  BeginPaint(); pPaintstruct holds the invalid rectangle to be
//  painted.
//
// Returns:
//  Returns FALSE on error, TRUE otherwise. 
//


#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"
#if defined(_GETCHARSET_)
#error
#endif
#include "atotime.h" //for live time comparison: IsTimeAMoreRecentThanTimeB()
#include "rtwin.h"
#include "atocolor.h"
#include "fontdefs.h"
#include "fontinfo.h"
#include "textprsr.h" /* for REAL_TEXT_TRANSPARENT_BGCOLOR_MAJOR_VERSION + ... */
#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

#include "textprsr.h" /*for ..._CONTENT_VERSION_... defines */

#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 definition

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

//Characters of the same font and height in Mac tend to be wider
// than on Windows (from which the char-width tables were derived),
// so we need to draw with a slightly smaller character so they don't
// crowd each other out.   0.875 = 14/16, i.e., 16pt font will be
// drawn with 14-pt characters: 
#define MACINTOSH_RT_FONT_TEXTSIZE_FUDGE_FACTOR	     0.875

#define	FONTFACE_BUF_SIZE   32


UINT16	Convert8BitTo16Bit(UINT8 x)
{
    float factor=((float)x)/255;
    long returnValue=(factor*65535);
    
    return returnValue;
}


//
//	Converts a Windows COLORTYPE into an RGBColor type.
//
void ConvertCOLORTYPEtoRGBColor(RGBColor& rgbColor, COLORTYPE colorVal)
{
    char*	x=(char*)&colorVal;

    rgbColor.red   =(short)Convert8BitTo16Bit(x[1]);
    rgbColor.green =(short)Convert8BitTo16Bit(x[2]);
    rgbColor.blue  =(short)Convert8BitTo16Bit(x[3]);
}

/////////////////////////////////////////////////////////////////////////////
// Function:
//	BOOL
//	OnPaint
//	(
//		TextWindow* pTextWindow,
//		void* pDC,
//		void* pPaintstruct
//	)
//
// Purpose:
//  This function does the actual rendering of text by doing a TextOut() of
//  all text in all TextContainers in the TextContainerList of pTextWindow
//  whose text is visible in the rectangle to be updated
//  This Function is called from WM_PAINT and hdc and ps are from
//  BeginPaint(); ps holds the invalid rectangle to be updated: 
//
// Returns:
//	Returns FALSE on error, TRUE otherwise. 
//
BOOL OnPaint(TextWindow* pTextWindow, void* pvoidEvent,
	void* pPaintstruct, ULONG32 ulTimeOfCurrentDraw,
	BOOL bSomeonesBeginOrEndTimeWasCrossedOverSinceLastDraw,
	INT16 iXScrollWindowAmt, INT16 iYScrollWindowAmt)
{
    HX_ASSERT_VALID_PTR(pTextWindow);
    if(!pTextWindow)
    {
	return FALSE;
    }
    
    BOOL	b_FunctionSucceeded = TRUE;
    LONG32 lWindowWidth = pTextWindow->getWindowWidth();
    LONG32 lWindowHeight = pTextWindow->getWindowHeight();
    
    BOOL bChromaKeyWasAppliedToBg = FALSE;
    BOOL bChromaKeyWasAppliedToSomeText = FALSE;

    HXxEvent* pEvent = (HXxEvent*)pvoidEvent;
    HX_ASSERT(pEvent);

    ULONG32 listSize = pTextWindow->textCntnrListSize();

    //get real rect to draw into - don't draw into entire window
    Rect updateRect;
    ::SetRect(&updateRect, 0, 0, pTextWindow->getWindowWidth(), pTextWindow->getWindowHeight()); 
#if defined(DO_CPU_FRIENDLY_SCROLLING)
    // /Fixes background-not-being-completely-drawn part of PR 85479; make
    // sure we draw in entire offscreen area which is 1.5 * (w or h) depending
    // on direction of motion:
    if (pTextWindow->getCrawlRate()  &&  !pTextWindow->getScrollRate())
    {
	updateRect.right += pTextWindow->getWindowWidth()/2;
    }
    else if (!pTextWindow->getCrawlRate()  &&  pTextWindow->getScrollRate())
    {
	updateRect.bottom += pTextWindow->getWindowHeight()/2;
    }
#endif /* defined(DO_CPU_FRIENDLY_SCROLLING) */
    // /XXXEH- use the following if and when the core starts doing
    // subrects on the Mac:
    CHXxRect* pDestRect = pEvent?
            (CHXxRect*)((HXxEvent*)pvoidEvent)->param2 :
            NULL;

    UINT32 ulEffectiveFgOpacity = pTextWindow->getMediaOpacity();
    UINT32 ulEffectiveBgOpacity = pTextWindow->getBackgroundOpacity();
    UINT32 ulChromaKey = pTextWindow->getChromaKey();
    UINT32 ulChromaKeyTolerance = pTextWindow->getChromaKeyTolerance();
    UINT32 ulChromaKeyOpacity = pTextWindow->getChromaKeyOpacity();    
#if defined(DO_CPU_FRIENDLY_SCROLLING)
    BOOL bDoingScrollOfRect = FALSE;
    if(!bSomeonesBeginOrEndTimeWasCrossedOverSinceLastDraw  &&
	    (iXScrollWindowAmt>0  ||  iYScrollWindowAmt>0)
	    // /XXXEH- no CPU-friendly *diagonal* motion, yet, since
	    // we don't support that in Windows player and it doesn't
	    // work perfectly yet on the Mac:
	    &&  !(iXScrollWindowAmt>0  &&  iYScrollWindowAmt>0))
    {
	bDoingScrollOfRect = TRUE;
    }
#endif /* defined(DO_CPU_FRIENDLY_SCROLLING) */

    {
	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;

#if defined(DO_CPU_FRIENDLY_SCROLLING)
	    theMacGWorld = pTextWindow->m_pOffScreenWorld;
#else
  	    QDErr err = ::NewGWorld(&theMacGWorld, 32, &gwRect, NULL, NULL, useTempMem);
#endif /* defined(DO_CPU_FRIENDLY_SCROLLING) */
	    if (theMacGWorld)
	    {
		::SetGWorld(theMacGWorld, NULL);
		::SetOrigin(theBounds.left, theBounds.top);
		::SetClip(theClipRgn);
		::LockPixels((::GetGWorldPixMap(theMacGWorld)));
		::RGBForeColor(&theForeColor);
		::RGBBackColor(&theBackColor);
	    }
	    ::DisposeRgn(theClipRgn);
	}

	COLORTYPE backColorType = pTextWindow->getBackgroundColor();

#if defined (HANDLE_TRANSPARENT_WINDOW_BACKGROUND)
	BOOL bDrawBackgroundAsTransparent = FALSE;
	// /XXXEH- We need to revisit this and deal with transparent alpha
	// channel here properly rather than just skipping drawing:

	// /Putting parens around the two parts of this if() that are on either
	// side of the '||' helps fix PR 85479 (horizontal-motion version):
	if ((TRANSPARENT_COLOR == backColorType)  &&
	    ( (pTextWindow->getMajorContentVersion() >
	    REAL_TEXT_TRANSPARENT_BGCOLOR_MAJOR_VERSION)  ||
	    (pTextWindow->getMajorContentVersion() ==
	    REAL_TEXT_TRANSPARENT_BGCOLOR_MAJOR_VERSION  &&
	    pTextWindow->getMinorContentVersion() >=
	    REAL_TEXT_TRANSPARENT_BGCOLOR_MINOR_VERSION) ) )
	{
	    // /It's "transparent" and has high enough content version #:
	    bDrawBackgroundAsTransparent = TRUE;
	}
#endif /* defined (HANDLE_TRANSPARENT_WINDOW_BACKGROUND). */

//
//	Erase the background with the specified color.
//
	RGBColor	backColor, prevBackColor;

	ConvertCOLORTYPEtoRGBColor(backColor, backColorType);

	if (1
#if defined(DO_CPU_FRIENDLY_SCROLLING)
		&&  !bDoingScrollOfRect  // /Don't re-draw bg if moving
#endif /* defined(DO_CPU_FRIENDLY_SCROLLING). */
#if defined (HANDLE_TRANSPARENT_WINDOW_BACKGROUND)
		&&  !bDrawBackgroundAsTransparent // /Don't draw transparent bg
#endif /* defined (HANDLE_TRANSPARENT_WINDOW_BACKGROUND). */
		)
	{
	    //
	    //	Set the Background color of the offscreen port.
	    //
	    ::GetBackColor(&prevBackColor);
	    ::RGBBackColor(&backColor);

	    ::EraseRect(&updateRect);
	}

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


	    //We must adjust for where the virtual window location is due to
	    // looping:
	    LONG32 currentXOffsetDueToLooping = 0L;
	    LONG32 currentYOffsetDueToLooping = 0L;
	    if(pTextWindow->isLooping())
	    {
		currentXOffsetDueToLooping =
			pTextWindow->getCurrentXOffsetDueToLooping();
		currentYOffsetDueToLooping =
			pTextWindow->getCurrentYOffsetDueToLooping();
	    }

	    BOOL bWindowHeightIsNotTheOriginalValue = 
		    lWindowHeight != pTextWindow->getHeight();
	    BOOL bWindowWidthIsNotTheOriginalValue =
		    lWindowWidth != pTextWindow->getWidth();

	    //We must adjust for where the virtual window location is due to
	    // "teleprompter" adjustment so that the last line of text is visible
	    // at the bottom edge of the window:
	    LONG32 currentYOffsetForTeleprompter = 0L;
	    if(TYPE_TELEPROMPTER == pTextWindow->getType())
	    {
		currentYOffsetForTeleprompter =
			pTextWindow->getCurrentYOffsetForTeleprompter();
	    }

	    ///
	    /// Draw each text item in the offscreen port.
	    ///
	    
	    float fXScaleFactor = (float)lWindowWidth / (float)pTextWindow->getWidth();
	    float fYScaleFactor = (float)lWindowHeight / (float)pTextWindow->getHeight();
	    
	    // /Helps fix PR 83385:
	    // Initialize chromaKey flag. If 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:
	    if (pTextWindow->isChromaKeySet())
	    {
	        if (DoesChromaKeyMatch(backColorType, ulChromaKey,
			 ulChromaKeyTolerance) )
	        {
	            if (ulChromaKeyOpacity < 255)
	            {
	                bChromaKeyWasAppliedToBg = TRUE;
	                ulEffectiveBgOpacity = ulChromaKeyOpacity;
	            }
	        }
	    }
    

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

		if(curTextContainerPtr->textHasChangedSinceLastDraw()  ||
			curTextContainerPtr->textShouldBeDrawn())
		{
		    LONG32 lUpperLeftXWithOffsets =
			    currentXOffsetDueToLooping +
			    curTextContainerPtr->getXUpperLeftCorner();
		    LONG32 lLowerRightXWithOffsets =
			    currentXOffsetDueToLooping +
			    curTextContainerPtr->getXLowerRightCorner();
		    LONG32 lUpperLeftYWithOffsets =
			    currentYOffsetDueToLooping +
			    currentYOffsetForTeleprompter +
			    curTextContainerPtr->getYUpperLeftCorner();
		    LONG32 lLowerRightYWithOffsets =
			    currentYOffsetDueToLooping +
			    currentYOffsetForTeleprompter +
			    curTextContainerPtr->getYLowerRightCorner();

		    LONG32 xScaled = lUpperLeftXWithOffsets;

		    LONG32 yScaled = lUpperLeftYWithOffsets;

		    LONG32 lScaledUpperLeftXWithOffsets =
			    lUpperLeftXWithOffsets;
		    LONG32 lScaledLowerRightXWithOffsets =
			    lLowerRightXWithOffsets;
		    LONG32 lScaledUpperLeftYWithOffsets =
			    lUpperLeftYWithOffsets;
		    LONG32 lScaledLowerRightYWithOffsets =
			    lLowerRightYWithOffsets;

		    if (bWindowWidthIsNotTheOriginalValue)
		    {
			xScaled  = 
				LONG32((float)xScaled * fXScaleFactor);
			lScaledUpperLeftXWithOffsets =
				LONG32((float)lScaledUpperLeftXWithOffsets *
				fXScaleFactor);
			lScaledLowerRightXWithOffsets =
				LONG32((float)lScaledLowerRightXWithOffsets *
				fXScaleFactor);
		    }
		    if (bWindowHeightIsNotTheOriginalValue)
		    {
			yScaled  = 
				LONG32((float)yScaled * fYScaleFactor);
			lScaledUpperLeftYWithOffsets =
				LONG32((float)lScaledUpperLeftYWithOffsets *
				fYScaleFactor);
			lScaledLowerRightYWithOffsets =
				LONG32((float)lScaledLowerRightYWithOffsets *
				fYScaleFactor);
		    }

		    ///Make sure curTextContainerPtr's text is located in the
		    ///window before we go to the trouble of doing a TextOut:
		    if(	    (lScaledUpperLeftXWithOffsets
				> updateRect.right) 
			    ||  (lScaledLowerRightXWithOffsets
				< updateRect.left)
			    ||  (lScaledUpperLeftYWithOffsets
				> updateRect.bottom) 
			    ||  (lScaledLowerRightYWithOffsets
				< updateRect.top) )
		    {
			continue; //text doesn't overlap the window.
		    }
		    //If updateRect is in stretched coordinates, then the above
		    // check won't find everyone who is outside the window, so
		    // let's make sure we do here:
		    if (bWindowHeightIsNotTheOriginalValue)
		    {
			if(yScaled > updateRect.bottom)
			    continue; //It's outside the window
		    }
		    if (bWindowWidthIsNotTheOriginalValue)
		    {
			if(xScaled > updateRect.right)
			    continue; //It's outside the window
		    }

		    //Since OnTimeSync()/OnTimeSynch() may not yet have been
		    //called, we need to time-bounds check:
		    //XXXEH- revisit this; don't do this every time for every T.C.,
		    // but instead just keep track of whether or not OnTimeSynch()
		    // has been called yet or not (...???):
		    //First, if we're live, we need to compare times keeping
		    // ULONG32-wrap-around in mind:
		    BOOL bBeginTimeIsMoreRecentThanCurTime =
			    IsTimeAMoreRecentThanTimeB(
			    curTextContainerPtr->getBeginTime(),
			    ulTimeOfCurrentDraw,
			    pTextWindow->isLiveSource());
		    BOOL bCurTimeIsMoreRecentThanEndTime =
			    IsTimeAMoreRecentThanTimeB(
			    ulTimeOfCurrentDraw,
			    curTextContainerPtr->getEndTime(),
			    pTextWindow->isLiveSource());
		    //Sanity check:
		    if(TIME_INVALID == curTextContainerPtr->getEndTime())
		    {
			HX_ASSERT(!bCurTimeIsMoreRecentThanEndTime);
		    }
		    if(bBeginTimeIsMoreRecentThanCurTime  ||
			    bCurTimeIsMoreRecentThanEndTime)
		    {
			continue;
		    }

		    //
		    //	For the current text container, setup the style.
		    //
		    Style	tcStyle=NULL;
		    
		    if (curTextContainerPtr->isBold()) tcStyle +=bold;
		    if (curTextContainerPtr->isItalicized()) tcStyle +=italic;

		    TextFace(tcStyle);

		    UINT32 ulAuthoredFaceIndx = curTextContainerPtr->getFontFace();
		    // /Use a short int in Mac APIs that take a short* .
		    // This is needed to fix PR 92364:
		    short iFaceIndx = (short)ulAuthoredFaceIndx;

		    //Get the face name and see if it's installed on this
		    // system, but first we need to translate the faceIndx
		    // back to a string and then use the string to query
		    // the system for installation status; the reason for
		    // this is that a face index may differ from Mac to
		    // Mac; Apple gave up on hard-coded indices a while ago:
		    _CHAR pFontFaceBuf[FONTFACE_BUF_SIZE];
		    getFontFaceStringFromFaceIndex(ulAuthoredFaceIndx,
			    pFontFaceBuf, FONTFACE_BUF_SIZE,
			    pTextWindow->getMajorContentVersion(),
			    pTextWindow->getMinorContentVersion());
			    
		    BOOL bFontFaceFoundOnSystem = FALSE;

		    BOOL bActiveContentVersionIncludesKorean = FALSE;
		    //XXXEH: docs need updating: version="1.3" or higher must
		    // be set in the <window> tag of the rt file in order for
		    // Korean to be rendered:
		    if(pTextWindow->getMajorContentVersion() >
			REAL_TEXT_KOREAN_FONT_HANDLING_CONTENT_MAJOR_VERSION
			||
			(pTextWindow->getMajorContentVersion() ==
			REAL_TEXT_KOREAN_FONT_HANDLING_CONTENT_MAJOR_VERSION
			&&
			pTextWindow->getMinorContentVersion() >=
			REAL_TEXT_KOREAN_FONT_HANDLING_CONTENT_MINOR_VERSION)
			)
		    {
			bActiveContentVersionIncludesKorean = TRUE;
		    }
		    if(strlen(pFontFaceBuf))
		    {
			c2pstrcpy((StringPtr)pFontFaceBuf, pFontFaceBuf);//change C str to Pascal str
			// /Calling GetFNum() with a short* (&iFaceIndx)
			// instead of a (short*)&UINT32 fixes PR 92364; the
			// value being returned was flipped due to the way a
			// UINT32 is stored on a Big-Endian machine, e.g., Mac
			GetFNum((StringPtr)pFontFaceBuf, &iFaceIndx);
			bFontFaceFoundOnSystem = (iFaceIndx != 0);
		    }
		    //else it's an empty string so do mapping, below...

		    //If this font was not found installed on the system,
		    // then we need to use a reasonable substitute:
		    if(!bFontFaceFoundOnSystem)
		    {
		    	iFaceIndx = (short)ulAuthoredFaceIndx;
			if (ulAuthoredFaceIndx & ARIAL_DERIVATIVE_FONT  ||
				ulAuthoredFaceIndx & USES_ARIAL_SPACING)
			{
			    //Just go ahead and use Arial if it exists:
			    GetFNum("\pArial", &iFaceIndx);
			    if(0==iFaceIndx)
			    {			
				//Just go ahead and use Helvetica, but use
				// its string name first since the hardcoded
				// index is not necessarily the same on all
				// Macs now :-(
				GetFNum("\pHelvetica", &iFaceIndx);
				if(0==iFaceIndx)
				{			
				    iFaceIndx = HELVETICA_FONT_FACE_INDX;
				}
			    }
			}
			else if (ulAuthoredFaceIndx & USES_TIMES_SPACING)
			{
			    iFaceIndx = TIMES_FONT_FACE_INDX;
			}
			else if (ulAuthoredFaceIndx & USES_COURIER_SPACING)
			{
			    iFaceIndx = COURIERTT_FONT_FACE_INDX;
			}
			else if (ulAuthoredFaceIndx & USES_SYSTEM_SPACING)
			{
			    iFaceIndx = GENEVA_FONT_FACE_INDX;
			}
#if defined(CJK_FONT_INDEX) 
			if (OSAKA_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\pOsaka", &iFaceIndx);
			}
			else if (SIMPLECHINESE_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\p'ËÎÌå", &iFaceIndx);
			}
			else if (TRADITIONALCHINESE_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\p²Ó©úÅé", &iFaceIndx);
			}
			//KOREAN!
			else if (SEOUL_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\pSeoul", &iFaceIndx);
			    if (!bActiveContentVersionIncludesKorean)
			    {
				iFaceIndx = DEFAULT_FONT_FACE_INDX;
			    }
			}
			//KOREAN!
			else if (BATANG_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\pBatang", &iFaceIndx);
			    if(0==iFaceIndx)
			    {
				GetFNum("\pSeoul", &iFaceIndx);
			    }
			    if (!bActiveContentVersionIncludesKorean)
			    {
				iFaceIndx = DEFAULT_FONT_FACE_INDX;
			    }
			}
			//KOREAN!
			else if (BATANGCHE_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\pBatangche", &iFaceIndx);
			    if(0==iFaceIndx)
			    {
				GetFNum("\pSeoul", &iFaceIndx);
			    }
			    if (!bActiveContentVersionIncludesKorean)
			    {
				iFaceIndx = DEFAULT_FONT_FACE_INDX;
			    }
			}
			//KOREAN!
			else if (GULIM_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\pGulim", &iFaceIndx);
			    if(0==iFaceIndx)
			    {
				GetFNum("\pSeoul", &iFaceIndx);
			    }
			    if (!bActiveContentVersionIncludesKorean)
			    {
				iFaceIndx = DEFAULT_FONT_FACE_INDX;
			    }
			}
			//KOREAN!
			else if (GULIMCHE_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\pGulimche", &iFaceIndx);
			    if(0==iFaceIndx)
			    {
				GetFNum("\pSeoul", &iFaceIndx);
			    }
			    if (!bActiveContentVersionIncludesKorean)
			    {
				iFaceIndx = DEFAULT_FONT_FACE_INDX;
			    }
			}
			//KOREAN!
			else if (APPLEGOTHIC_FONT_FACE_INDX == ulAuthoredFaceIndx  ||
				GOTHIC_FONT_FACE_INDX == ulAuthoredFaceIndx)
			{
			    GetFNum("\pAppleGothic", &iFaceIndx);
			    if(0==iFaceIndx)
			    {
				GetFNum("\pGothic", &iFaceIndx);
			    }
			    if (!bActiveContentVersionIncludesKorean)
			    {
				iFaceIndx = DEFAULT_FONT_FACE_INDX;
			    }
			}
			else
			{
			    iFaceIndx = DEFAULT_FONT_FACE_INDX;
			}
#endif //CJK_FONT_INDEX is defined.
		    }
		    TextFont(iFaceIndx); 
		    
		    //Support for font scaling in 2x and FS mode
		    ULONG32 ulFontPointSize =
			    curTextContainerPtr->getFontPointSize();
		    INT32 lScaledHeight = (INT32)((float)ulFontPointSize * fYScaleFactor);

		    FontInfo fi;
		    
		    TextSize(INT32(lScaledHeight *
			    MACINTOSH_RT_FONT_TEXTSIZE_FUDGE_FACTOR));
		    TextMode(srcOr);
		    
		    GetFontInfo (&fi);

		    RGBColor	textColor, bgTextColor;
		    
		    COLORTYPE bgTextColorCOLORTYPE =
		    	    curTextContainerPtr->getTextBackgroundColor();
		    COLORTYPE foreColorType = curTextContainerPtr->getTextColor();
		    COLORTYPE fontBgColorType =
		    	    curTextContainerPtr->getTextBackgroundColor();

		    if (TYPE_TICKERTAPE == pTextWindow->getType())
		    {
		    	foreColorType =
		    		curTextContainerPtr->getTickertapeTextColor();
		    }

		    UINT32 ulEffectiveFontBgOpacity = ulEffectiveFgOpacity;
		    // /This helps fix chromaKey part of PR 83385 which was no
		    // support for backgroundOpacity, mediaOpacity, chromaKey:
 		    if (pTextWindow->isChromaKeySet()  &&
 		    	    ulChromaKeyOpacity < 255)
		    {
			if (DoesChromaKeyMatch((UINT32)foreColorType,
				ulChromaKey, ulChromaKeyTolerance) )
			{
			    ulEffectiveFgOpacity = ulChromaKeyOpacity;
			    bChromaKeyWasAppliedToSomeText = TRUE;
			    // /Set the text color to be exactly the chromaKey
			    // to help fix PR 83385: we'll go through pixels
			    // just before blt and adjust alpha channel val for
			    // each one that exactly matches chromaKey (or
			    // chromaKey+1 if text and background colors are
			    // identical but opacities differ (see below):
			    foreColorType = ulChromaKey;
			}
			// /Fixes so font bgColor (rect behind each char) now
			// works if within chromaKeyTolerance but !=chromaKey:
			if (DoesChromaKeyMatch((UINT32)fontBgColorType,
				ulChromaKey, ulChromaKeyTolerance))
			{
			    ulEffectiveFontBgOpacity = ulChromaKeyOpacity;
			    bChromaKeyWasAppliedToSomeText = TRUE;
			    fontBgColorType = ulChromaKey;
			}
		    }
		    // /Part of "fix" for PR 83385: 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++;
			}
		    }
		    // /Do same for font bgColor:
		    if (fontBgColorType == backColorType  &&
			    ulEffectiveFontBgOpacity != ulEffectiveBgOpacity)
		    {
			if (0xFFFFFF == fontBgColorType)
			{
			    fontBgColorType--;
			}
			else
			{
			    fontBgColorType++;
			}
		    }

		    ConvertCOLORTYPEtoRGBColor(textColor, foreColorType);
		    
		    ConvertCOLORTYPEtoRGBColor(bgTextColor, fontBgColorType);

		    //
		    //	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 color 
		    //		
		    ::RGBForeColor(&textColor);
		    
		    //
		    //	Convert the text buffer to a Str255 pascal string.
		    //
		    _CHAR* pTextbuffer = curTextContainerPtr->getBuffer();
		    ULONG32 ulTextLengthPlusOneOfCurTC =
			    curTextContainerPtr->getTextLengthPlus1();

		    char tmpString[4]; /* Flawfinder: ignore */  //[0] holds string len (Pascal string),
					// [1] holds char to be drawn (or [1] and
					// [2] do if DBCS), and [2] (or [3] if 
					// 2-byte char) holds '\0';
		    INT16 tmpStringLen = 0;
		    tmpString[1] = (char)0;
		    tmpString[1] = tmpString[2] = tmpString[3] = '\0';

		    if(pTextbuffer  &&  ulTextLengthPlusOneOfCurTC > 1)
		    {
			//XXXEH- I think we want to use this
			// (in GetCharacterWidth(), below, and not faceIndex,
			// calculated above, but I need to test this.  File
			// format uses the following and does no special code
			// to handle font faces on the Mac:
			ULONG32 ulFontFace =
				curTextContainerPtr->getFontFace();
			BOOL bIsBold =
				curTextContainerPtr->isBold();
			BOOL bIsItalicized =
				curTextContainerPtr->isItalicized();
			ULONG32 ulCharset =
				curTextContainerPtr->getFontCharset();

			//if bgcolor is not transparent, and/or if
			// isUnderlined is TRUE, draw a rect (or line for
			// underline) manually behind the entire text rather
			// than letting textout do it for each letter (which
			// is slower and sometimes leaves gaps if the letter
			// spacing is slightly different than the os would
			// natively space it:
			if((BAD_RGB_COLOR != bgTextColorCOLORTYPE  &&
				TRANSPARENT_COLOR != bgTextColorCOLORTYPE)  ||
				curTextContainerPtr->isUnderlined()  ||
				curTextContainerPtr->isStruckOut())
			{
			    int yLowerRightScaled = lScaledLowerRightYWithOffsets;

			    Rect drawRect;
			    //NOTE: right, top, and bottom get set
			    // individually, below:
			    drawRect.left = xScaled;

			    //Fix for bug 6527; when double sized, we want to
			    // double the padding on the right edge.  This
			    // "padding" (which used to be +1 always) is
			    // necessary when drawing a rect
			    //    (-- XXXEH- is this true in the Mac? --)
			    // because PaintRect draws up to, but not
			    // including, the right edge:
			    int additionalWidth = 1;
			    if(lLowerRightYWithOffsets != 0) //avoid div by 0.
			    {
				additionalWidth =
				    yLowerRightScaled /
				    lLowerRightYWithOffsets;
			    }
			    if(additionalWidth < 1)
			    {
				additionalWidth=1;
			    }
			    drawRect.right =
				    lScaledLowerRightXWithOffsets + additionalWidth;
			    if(BAD_RGB_COLOR != bgTextColorCOLORTYPE  &&
				    TRANSPARENT_COLOR != bgTextColorCOLORTYPE)
			    {
				drawRect.top = yScaled;
				drawRect.bottom = yLowerRightScaled+1;
				RGBColor rgb;
				::GetForeColor(&rgb);
				::RGBForeColor(&bgTextColor);
				::PaintRect(&drawRect);
				::RGBForeColor(&rgb);
			    }
			    //Do underlining manually now (due to
			    // possible gaps if alternate font has to be
			    // used and forced spacing is not quite as os
			    // calculates it):
			    if(curTextContainerPtr->isUnderlined())
			    {
				INT32 thickness =
					(yLowerRightScaled - yScaled) / 12;
				if(thickness < 1)
				{
				    thickness = 1;
				}
				if(bIsBold)
				{
				    thickness += (thickness/2);
				}
				drawRect.top =
					yLowerRightScaled-thickness+1;
				drawRect.bottom = yLowerRightScaled+1;
				//Draw the underline:
				::PaintRect(&drawRect);
			    }
			    //Do strike-through manually because there's no
			    // native Mac support for it:
			    if(curTextContainerPtr->isStruckOut())
			    {
				INT32 thickness =
					(yLowerRightScaled - yScaled) / 18;
				if(thickness < 1)
				{
				    thickness = 1;
				}
				drawRect.top =
					yScaled +
					((yLowerRightScaled - yScaled)/2) +1;
				drawRect.bottom = drawRect.top +
					thickness;
				//Draw the underline:
				::PaintRect(&drawRect);
			    }
			}


			LONG32 ulXTotalCharsOffset = 0L;
			do //draw each character @ offset in x from the first:
			{
			    _CHAR ch = *pTextbuffer;
			    UINT16 usCh = ch;
			    tmpString[0] = 1; //=length of a 1-char Str255,
			    tmpString[1] = ch;
			    if (HX_DBCS_CHARSET & ulCharset  ||
				    HX_UNICODE_CHARSET & ulCharset)
			    {
				if (HX_UNICODE_CHARSET & ulCharset  ||
					(UCHAR)ch >= DBCS_MIN_LEAD_BYTE_VAL)
				{   //then ch is lead byte of a 2-byte char.
				    pTextbuffer++;
				    ch = *pTextbuffer;
				    tmpString[0] = 2; //this is a 2-byte char.
				    tmpString[2] = ch; //==trail byte.
				    usCh <<= 8;
				    usCh |= ch;
				}
			    }
			    //XXXEH- test this DBCS stuff^^!!!

			    //Now move in x by the amount that the
			    // cross-platform (uniform) table says is the
			    // width of this char:
			    ULONG32 ulLookupCharWidth =
				    GetCharacterWidth(usCh, ulFontFace,
				    ulFontPointSize, bIsBold, bIsItalicized,
				    ulCharset);
			    if(bWindowWidthIsNotTheOriginalValue)
			    {
				ulLookupCharWidth =
					LONG32(((float)ulLookupCharWidth *
					(float)lWindowWidth) /
					(float)pTextWindow->getWidth());
			    }

			    //(XXXXXEH-Does the following handle UNICODE ok?)
			    //However, we want to horizontally center the
			    // character inside its bounding box in case its
			    // native width is noticably different from its
			    // cross-platform-table-assigned width:
			    LONG32 lXPlatWidth = (LONG32)ulLookupCharWidth;
			    LONG32 lNativeWidth =
				    (LONG32)StringWidth((UCHAR*)tmpString);

			    LONG32 lCrossPlatVsNativeWidthOffset = 0L;
			    if(lNativeWidth  &&  //Should never be 0, but...
				    lXPlatWidth!=lNativeWidth) 
			    {
				//Note: we should not adjust lNativeWidth if
				// bWindowWidthIsNotTheOriginalValue because
				// that's already been accounted for in
				// font point size.

				//Note: this can be negative!:
				lCrossPlatVsNativeWidthOffset =
					(lXPlatWidth-lNativeWidth)/2;
					
				//Move by the adjusted difference so we end
				// up drawing the next char centered
				// horizontally in its bounding box:
				Move(lCrossPlatVsNativeWidthOffset, 0);
			    }

			    DrawString((StringPtr)tmpString);

			    ulXTotalCharsOffset += ulLookupCharWidth;
			    //Move to draw the next char:
			    MoveTo(moveX + ulXTotalCharsOffset, moveY);

			} while(*(++pTextbuffer));
		    }
		}
	    
	    } //end "while(pos)".
	} //end "if(listSize...)".

	::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;
#if defined(DO_CPU_FRIENDLY_SCROLLING)
#if 1 /* PR 85479 vertical-scrolling version's stretch-snap problems is
       * fixed by working around core bug where core appears to be ignoring
       * the srcRect's bottom attribute:
       */
		    if (bDoingScrollOfRect)
		    {
			srcRect.left = iXScrollWindowAmt;
			srcRect.right += srcRect.left;
			// /For vertically-scrolling version of PR 85479,
			// we'll have to handle scrolling (below) by moving the
			// dataBlob pointer instead of telling the core to use
			// a srcRect offset.
		    }
#else
		    if (bDoingScrollOfRect)
		    {
			srcRect.left = iXScrollWindowAmt;
			srcRect.top = iYScrollWindowAmt;
			srcRect.right += srcRect.left;
			srcRect.bottom += srcRect.top;
		    }
#endif /* PR 85479. */
#endif /* defined(DO_CPU_FRIENDLY_SCROLLING) */

		    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;

#if defined(DO_CPU_FRIENDLY_SCROLLING)
#if 1 /* PR 85479 vertical-scrolling version's stretch-snap problems is
       * fixed by working around core bug where core appears to be ignoring
       * the srcRect's bottom attribute:
       */
		    // /For vertically-scrolling version of PR 85479,
		    // we have to handle scrolling here by moving the
		    // dataBlob pointer instead of telling the core to use
		    // a srcRect offset:
		    if (iYScrollWindowAmt  &&  bDoingScrollOfRect)
		    {
			pDataBlob += iYScrollWindowAmt * bitmapInfo.biWidth * 4; 
		    }
#endif /* PR 85479. */
#endif /* defined(DO_CPU_FRIENDLY_SCROLLING) */
		    
		    // /Handle alpha channel if not everything is fully opaque:
		    DWORD oldComp = bitmapInfo.biCompression;
		    if (pTextWindow->getBackgroundOpacity() < 255 ||
			    pTextWindow->getMediaOpacity() < 255 ||
			    bChromaKeyWasAppliedToSomeText  ||
			    bChromaKeyWasAppliedToBg)
		    {
			bitmapInfo.biCompression = HX_ARGB; // /AlphaRGB

			// /So, here's the fix (w/work-around) for PR 83385:
			// 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;
			    }
			    // /If chromaKey was applied to *any* text, then
			    // it overrides any mediaOpacity value and we just
			    // need to see if non-bg pixel matches chromaKey: 
			    else if (bChromaKeyWasAppliedToSomeText)
			    {
				// /Better solution is to have map of all
				// colors used to draw text that are within
				// chromaKeyTolerance, but that would be slower:
				// /We've adjusted all within-chroma-key-
				// tolerance text colors to be chroma key (or
				// chroma key+1 in case text is same as bg):
				if (*pBlob == ulChromaKey  ||
					*pBlob == ulChromaKey+1)
				{
				    *pBlob |= ulFgAlpha;
				}
			    }
			    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;
		    
		    HX_RELEASE(pVideoSurface);
		}
	    }
	    
	    ::UnlockPixels(::GetGWorldPixMap(theMacGWorld));
#if !defined(DO_CPU_FRIENDLY_SCROLLING)
  	    ::DisposeGWorld(theMacGWorld);
#endif /* defined(DO_CPU_FRIENDLY_SCROLLING) */
            
            ::RGBForeColor(&holdFore);
            ::RGBBackColor(&holdBack);
	}
    }
    
    b_FunctionSucceeded=TRUE;

    return b_FunctionSucceeded;
}


// /---------------------- Transparency helper functions: -------------------

BOOL DoesChromaKeyChannelMatch(UINT32 ulColor,
                               UINT32 ulChromaKey,
                               UINT32 ulChromaKeyTol)
{
    BOOL bRet = FALSE;

    INT32 lDiff = ((INT32) ulColor) - ((INT32) ulChromaKey);
    if (lDiff < 0)
    {
        lDiff = -lDiff;
    }
    if (lDiff <= (INT32) ulChromaKeyTol)
    {
        bRet = TRUE;
    }

    return bRet;
}

#define ARGB32_RED(a)   (((a) & 0x00FF0000) >> 16)
#define ARGB32_GREEN(a) (((a) & 0x0000FF00) >>  8)
#define ARGB32_BLUE(a)   ((a) & 0x000000FF)

BOOL DoesChromaKeyMatch(UINT32 ulColor,
                        UINT32 ulChromaKey,
                        UINT32 ulChromaKeyTol)
{
    BOOL bRet = FALSE;

    if (DoesChromaKeyChannelMatch(ARGB32_RED(ulColor),
                                  ARGB32_RED(ulChromaKey),
                                  ARGB32_RED(ulChromaKeyTol)) &&
        DoesChromaKeyChannelMatch(ARGB32_GREEN(ulColor),
                                  ARGB32_GREEN(ulChromaKey),
                                  ARGB32_GREEN(ulChromaKeyTol)) &&
        DoesChromaKeyChannelMatch(ARGB32_BLUE(ulColor),
                                  ARGB32_BLUE(ulChromaKey),
                                  ARGB32_BLUE(ulChromaKeyTol)))
    {
        bRet = TRUE;
    }

    return bRet;
}

#if 0 /* We will need this when we start using our own text rendering engine,
         but for now we handle varied opacity levels differently due to Mac's
         backwards-from-our-Core version of what fully opaque is: */
BOOL applyBGOpacity(UINT32 ulOpacity, UINT32 ulBGColorNoAlpha,
	UINT32* pulBits, UINT32 ulBufferSizeIn4byteUnits,
	// /On Mac, we may want to set bits even if fully opaque
	// because sometimes bits have ff in upper byte when it
	// should be 0 and this was being drawn as transparent.
	// For *all* platforms, this can be a handy shortcut for
	// setting the background color and applying the alpha
	// value in one pass:
	BOOL bSetEvenIfFullyOpaque)
{
    BOOL bSucceeded = FALSE;

    // Compute the color to copy
    if ((bSetEvenIfFullyOpaque  ||  ulOpacity < 255)  &&  pulBits)
    {
	bSucceeded = TRUE;
	UINT32  ulAlpha   = 255 - ulOpacity;
	UINT32  ulColorA  = (ulBGColorNoAlpha & 0x00FFFFFF) |
                        (ulAlpha << 24);
    
	UINT32* pulTmpBf = pulBits;
	for (UINT32 ul = ulBufferSizeIn4byteUnits; ul--; ul)
	{
	   *pulTmpBf = ulColorA;
	   pulTmpBf++;
	}
    }

    return bSucceeded;
}
#endif /* 0. */

#if 0 /* We will need this when we start using our own text rendering engine,
         but for now we handle varied opacity levels differently due to Mac's
         backwards-from-our-Core version of what fully opaque is: */
BOOL ApplyTextOpacity(GWorldPtr pTheMacGWorld,
                      INT32       lTotalOffscrnHeight,
                      INT32       lX,
                      INT32       lY,
                      INT32       lW,
                      INT32       lH,
                      BOOL        bRowsInverted,
                      UINT32      ulColor,
                      UINT32      ulOpacity)
{
    BOOL bRet = TRUE;
    
    PixMapHandle thePM = ::GetGWorldPixMap(pTheMacGWorld);	    
    if (!thePM  &&  !(*thePM))
    {
	return FALSE;
    }

    INT32 lTotalOffscrnWidth = ((**thePM).rowBytes & 0x3fff) / 4;

    UCHAR* pBits = (UCHAR*)::GetPixBaseAddr(thePM);
	
    // Make sure the color to match doesn't already
    // have an alpha value
    UINT32 ulColorNoAlpha = ulColor & 0x00FFFFFF;
    // Compute the alpha to set
    if (ulOpacity > 255)
    {
	ulOpacity = 255;
    }
    UINT32  ulAlphaShifted = (255 - ulOpacity) << 24;
    // Run through the rectangle
    UINT32* pulBits  = (UINT32*) pBits;

    // /Use of lMaxRows in the for loop, below, fixes PR 66089: crash when
    // resizing semi-opaque plain text.  Don't exceed the bitmap boundaries:
    LONG32 lMaxRows = lTotalOffscrnHeight;
    LONG32 lWBoundsChecked = lW < lTotalOffscrnWidth? lW : lTotalOffscrnWidth-1;

    for (INT32 lRow = lY; lRow < lY + lH  &&  lRow < lMaxRows; lRow++)
    {
        UINT32* pPix  = pulBits +
                        (bRowsInverted ? lTotalOffscrnHeight - 1 - lRow : lRow) *
                         lTotalOffscrnWidth + lX;
        UINT32  ulNum = (UINT32) lWBoundsChecked; // /For PR 66089.
        while (ulNum--)
        {
            // Is this one of the colors that we are looking for?
            UINT32 ulPixNoAlpha = *pPix & 0x00FFFFFF;
            if (ulPixNoAlpha == ulColorNoAlpha)
            {
                *pPix = ulPixNoAlpha | ulAlphaShifted;
            }
            pPix++;
        }
    }

    return bRet;
}
#endif /* 0. */



