|
// 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<m_SWFMatrix.NScaleBits; i++)
{
m_SWFStream[byteIndex] |= (((scaleX & maskScaleX) >> (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<m_SWFMatrix.NScaleBits; i++)
{
m_SWFStream[byteIndex] |= (((scaleY & maskScaleY) >> (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<m_SWFMatrix.NRotateBits; i++)
{
m_SWFStream[byteIndex] |= (((rotateSkew0 & maskRotateSkew0) >> (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<m_SWFMatrix.NRotateBits; i++)
{
m_SWFStream[byteIndex] |= (((rotateSkew1 & maskRotateSkew1) >> (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<m_SWFMatrix.NTranslateBits; i++)
{
m_SWFStream[byteIndex] |= (((translateX & maskTranslateX) >> (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<m_SWFMatrix.NTranslateBits; i++)
{
m_SWFStream[byteIndex] |= (((translateY & maskTranslateY) >> (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;
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
He has a master degree in Computer Science at Faculty of Electronics in Nis (Serbia), and works as a C++/C# application developer for Windows platforms since 2001. He likes traveling, reading and meeting new people and cultures.