www.pudn.com > C++_Flash.rar > SWFMatrix.cpp


// SWFMatrix.cpp: implementation of the CSWFMatrix class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "SWFMatrix.h" 
 
 
CSWFMatrix::CSWFMatrix() 
{ 
	// Init members 
	m_SWFStream = NULL; 
	m_SWFStreamLength = 0; 
	m_SWFMatrix.MatrixFlags = 0; 
	m_SWFMatrix.NScaleBits = m_SWFMatrix.NRotateBits = m_SWFMatrix.NTranslateBits = 0; 
	m_SWFMatrix.ScaleX = m_SWFMatrix.ScaleY = 0; 
	m_SWFMatrix.RotateSkew0 = m_SWFMatrix.RotateSkew1 = 0; 
	m_SWFMatrix.TranslateX = m_SWFMatrix.TranslateY = 0; 
	memset(&m_Matrix, 0, sizeof(MATRIX_F)); 
} 
 
CSWFMatrix::~CSWFMatrix() 
{ 
	if (m_SWFStream != NULL) 
	{ 
		delete m_SWFStream; 
		m_SWFStream = NULL; 
	} 
} 
 
void CSWFMatrix::SetMatrix(MATRIX_F matrix) 
{ 
	// Copy transformation matrix 
	memcpy(&m_Matrix, &matrix, sizeof(MATRIX_F)); 
 
	// If matrix has scaling 
	if ((matrix.scaleX != 0) || (matrix.scaleY != 0)) 
	{ 
		ULONG scaleX = (ULONG)(matrix.scaleX * 65536); 
		ULONG scaleY = (ULONG)(matrix.scaleY * 65536); 
 
		int maxValue = __max((int)matrix.scaleX, (int)matrix.scaleY); 
		UCHAR scaleBitsNeaded = 0; 
		// Calculate scale-bits neaded 
		while (pow(2, scaleBitsNeaded) < maxValue) 
			scaleBitsNeaded++; 
		scaleBitsNeaded += 17; 
 
		m_SWFMatrix.MatrixFlags |= 0x04; 
		m_SWFMatrix.NScaleBits = scaleBitsNeaded; 
		m_SWFMatrix.ScaleX = MAKELONG(LOWORD(scaleX), HIWORD(scaleX)); 
		m_SWFMatrix.ScaleY = MAKELONG(LOWORD(scaleY), HIWORD(scaleY)); 
	} 
 
	// If matrix has rotation 
	if ((matrix.rotateSkew0 != 0) || (matrix.rotateSkew1 != 0)) 
	{ 
		ULONG rotateSkew0 = (ULONG)(matrix.rotateSkew0 * 65536); 
		ULONG rotateSkew1 = (ULONG)(matrix.rotateSkew1 * 65536); 
 
		int maxValue = __max((int)matrix.rotateSkew0, (int)matrix.rotateSkew1); 
		UCHAR rotateSkewBitsNeaded = 0; 
		// Calculate rotate-skew-bits neaded 
		while (pow(2, rotateSkewBitsNeaded) < maxValue) 
			rotateSkewBitsNeaded++; 
		rotateSkewBitsNeaded += 17; 
 
		m_SWFMatrix.MatrixFlags |= 0x02; 
		m_SWFMatrix.NRotateBits = rotateSkewBitsNeaded; 
		m_SWFMatrix.RotateSkew0 = MAKELONG(LOWORD(rotateSkew0), HIWORD(rotateSkew0)); 
		m_SWFMatrix.RotateSkew1 = MAKELONG(LOWORD(rotateSkew1), HIWORD(rotateSkew1)); 
	} 
 
	// If matrix has translation 
	if ((matrix.translateX != 0) || (matrix.translateY != 0)) 
	{ 
		m_SWFMatrix.MatrixFlags |= 0x01; 
		m_SWFMatrix.TranslateX = (int)(matrix.translateX * 20); 
		m_SWFMatrix.TranslateY = (int)(matrix.translateY * 20); 
 
		int maxValue = __max(abs(m_SWFMatrix.TranslateX), abs(m_SWFMatrix.TranslateY)); 
		UCHAR translateBitsNeaded = 0; 
		// Calculate translate-bits neaded 
		while (pow(2, translateBitsNeaded) < maxValue) 
			translateBitsNeaded++; 
		translateBitsNeaded++; 
 
		m_SWFMatrix.NTranslateBits = translateBitsNeaded; 
	} 
} 
 
void CSWFMatrix::GetMatrix(MATRIX_F& matrix) 
{ 
	// Copy transformation matrix 
	memcpy(&matrix, &m_Matrix, sizeof(MATRIX_F)); 
} 
 
UCHAR* CSWFMatrix::BuildSWFStream() 
{ 
	UCHAR bitsNeaded = 2; 
	int byteIndex=0, bitOffset=0, i; 
 
	// Calculate total bits neaded 
	if (m_SWFMatrix.MatrixFlags & 0x04) 
		bitsNeaded += (5 + 2*m_SWFMatrix.NScaleBits); 
	if (m_SWFMatrix.MatrixFlags & 0x02) 
		bitsNeaded += (5 + 2*m_SWFMatrix.NRotateBits); 
	bitsNeaded += (5 + 2*m_SWFMatrix.NTranslateBits); 
 
	// Create byte field 
	m_SWFStreamLength = bitsNeaded / 8; 
	if ((bitsNeaded%8) != 0) 
		m_SWFStreamLength++; 
	if (m_SWFStream != NULL) 
		delete m_SWFStream; 
	m_SWFStream = new UCHAR[m_SWFStreamLength]; 
	memset(m_SWFStream, 0, m_SWFStreamLength); 
 
	// Write scale bit-field to .SWF stream 
	if (m_SWFMatrix.MatrixFlags & 0x04) 
	{ 
		m_SWFStream[byteIndex] |= 0x80; 
		bitOffset++; 
 
		// Write nScaleBits bit-field to .SWF stream 
		UCHAR nScaleBits = m_SWFMatrix.NScaleBits << 3; 
		UCHAR maskNScaleBits = 0x80; 
		for (i=0; i<5; i++) 
		{ 
			m_SWFStream[byteIndex] |= (((nScaleBits & maskNScaleBits) >> (7-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
			bitOffset++; 
			if ((bitOffset != 0) && (bitOffset % 8) == 0) 
				byteIndex++; 
 
			maskNScaleBits = maskNScaleBits >> 1; 
		} 
 
		// Write scaleX bit-field to .SWF stream 
		ULONG scaleX = m_SWFMatrix.ScaleX << (32-m_SWFMatrix.NScaleBits); 
		ULONG maskScaleX = 0x80000000; 
		for (i=0; i> (31-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
			bitOffset++; 
			if ((bitOffset != 0) && (bitOffset % 8) == 0) 
				byteIndex++; 
 
			maskScaleX = maskScaleX >> 1; 
		} 
 
		// Write scaleY bit-field to .SWF stream 
		ULONG scaleY = m_SWFMatrix.ScaleY << (32-m_SWFMatrix.NScaleBits); 
		ULONG maskScaleY = 0x80000000; 
		for (i=0; i> (31-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
			bitOffset++; 
			if ((bitOffset != 0) && (bitOffset % 8) == 0) 
				byteIndex++; 
 
			maskScaleY = maskScaleY >> 1; 
		} 
	} 
	else 
		bitOffset++; 
 
	// Write rotate bit-field to .SWF stream 
	if (m_SWFMatrix.MatrixFlags & 0x02) 
	{ 
		// Write rotateFlag to .SWF stream 
		m_SWFStream[byteIndex] |= (0x01 << ((byteIndex+1)*8-bitOffset-1)); 
		bitOffset++; 
		if ((bitOffset != 0) && (bitOffset % 8) == 0) 
			byteIndex++; 
 
		// Write nRotateBits bit-field to .SWF stream 
		UCHAR nRotateBits = m_SWFMatrix.NRotateBits << 3; 
		UCHAR maskNRotateBits = 0x80; 
		for (i=0; i<5; i++) 
		{ 
			m_SWFStream[byteIndex] |= (((nRotateBits & maskNRotateBits) >> (7-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
			bitOffset++; 
			if ((bitOffset != 0) && (bitOffset % 8) == 0) 
				byteIndex++; 
 
			maskNRotateBits = maskNRotateBits >> 1; 
		} 
 
		// Write rotateSkew0 bit-field to .SWF stream 
		ULONG rotateSkew0 = m_SWFMatrix.RotateSkew0 << (32-m_SWFMatrix.NRotateBits); 
		ULONG maskRotateSkew0 = 0x80000000; 
		for (i=0; i> (31-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
			bitOffset++; 
			if ((bitOffset != 0) && (bitOffset % 8) == 0) 
				byteIndex++; 
 
			maskRotateSkew0 = maskRotateSkew0 >> 1; 
		} 
 
		// Write rotateSkew1 bit-field to .SWF stream 
		ULONG rotateSkew1 = m_SWFMatrix.RotateSkew1 << (32-m_SWFMatrix.NRotateBits); 
		ULONG maskRotateSkew1 = 0x80000000; 
		for (i=0; i> (31-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
			bitOffset++; 
			if ((bitOffset != 0) && (bitOffset % 8) == 0) 
				byteIndex++; 
 
			maskRotateSkew1 = maskRotateSkew1 >> 1; 
		} 
	} 
	else 
	{ 
		bitOffset++; 
		if ((bitOffset != 0) && (bitOffset % 8) == 0) 
			byteIndex++; 
	} 
 
	// Write nTranslateBits bit-field to .SWF stream 
	UCHAR nTranslateBits = m_SWFMatrix.NTranslateBits << 3; 
	UCHAR maskNTranslateBits = 0x80; 
	for (i=0; i<5; i++) 
	{ 
		m_SWFStream[byteIndex] |= (((nTranslateBits & maskNTranslateBits) >> (7-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
		bitOffset++; 
		if ((bitOffset != 0) && (bitOffset % 8) == 0) 
			byteIndex++; 
 
		maskNTranslateBits = maskNTranslateBits >> 1; 
	} 
 
	// Write translateX bit-field to .SWF stream 
	ULONG translateX = m_SWFMatrix.TranslateX << (32-m_SWFMatrix.NTranslateBits); 
	ULONG maskTranslateX = 0x80000000; 
	for (i=0; i> (31-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
		bitOffset++; 
		if ((bitOffset != 0) && (bitOffset % 8) == 0) 
			byteIndex++; 
 
		maskTranslateX = maskTranslateX >> 1; 
	} 
 
	// Write translateY bit-field to .SWF stream 
	ULONG translateY = m_SWFMatrix.TranslateY << (32-m_SWFMatrix.NTranslateBits); 
	ULONG maskTranslateY = 0x80000000; 
	for (i=0; i> (31-i)) << ((byteIndex+1)*8-bitOffset-1)); 
 
		bitOffset++; 
		if ((bitOffset != 0) && (bitOffset % 8) == 0) 
			byteIndex++; 
 
		maskTranslateY = maskTranslateY >> 1; 
	} 
 
	return m_SWFStream; 
} 
 
int CSWFMatrix::GetSWFStreamLength() 
{ 
	return m_SWFStreamLength; 
}