Commit ae84bdc8 authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander Trofimov

Исправлены баги с пересчетом координат. Настойки карандаша переделаны на нормальные константы.

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62181 954022d7-b5bf-4e40-9824-e11837661b57
parent c0b0338b
......@@ -5,7 +5,25 @@
namespace MetaFile
{
unsigned char GetLowestBit(unsigned long ulValue)
{
if (0 == ulValue)
return 0;
unsigned char unOffset = 0;
unsigned long ulBit = 1;
while (!(ulValue & ulBit))
{
ulBit = ulBit << 1;
unOffset++;
// 32-
if (ulBit & 0x80000000)
return 0;
}
return unOffset;
}
bool ReadImageCoreHeader(BYTE* pHeaderBuffer, unsigned long ulHeaderBufferLen, BYTE* pImageBuffer, unsigned long ulImageBufferLen, BYTE** ppDstBuffer, unsigned long* pulWidth, unsigned long* pulHeight)
{
CDataStream oHeaderStream;
......@@ -159,8 +177,119 @@ namespace MetaFile
}
else if (BI_BITCOUNT_2 == ushBitCount)
{
// TODO: ,
return false;
unsigned char unColorTableLen = 16;
if (0 != unColorUsed)
unColorTableLen = (std::min)((unsigned char)16, (unsigned char)unColorUsed);
TRgbQuad oColorTable[16];
if (oHeaderStream.CanRead() < unColorTableLen * 4)
return false;
//
for (unsigned short ushIndex = 0; ushIndex < unColorTableLen; ushIndex++)
{
oHeaderStream >> oColorTable[ushIndex];
}
// 4 - 1
//
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
if (lCalcLen != lBufLen)
return false;
// 4, 8
int nAdd = 0;
while (0 != div_t(div(nWidth + nAdd, 8)).rem)
{
nAdd++;
}
int nScanLineBytes = (nWidth + nAdd) / 2;
if (lBufLen < (nScanLineBytes * nHeight))
return false;
pBgraBuffer = new BYTE[nWidth * nHeight * 4 * sizeof(BYTE)];
if (NULL == pBgraBuffer)
return false;
ulHeight = (unsigned short)abs(nHeight);
ulWidth = (unsigned short)nWidth;
if (nHeight < 0)
{
for (int nY = 0; nY < abs(nHeight); nY++)
{
for (int nLineIndex = 0; nLineIndex < nScanLineBytes; nLineIndex++)
{
BYTE nByte = *pBuffer; pBuffer++;
int nX = nLineIndex * 2;
int nIndex = 4 * (nWidth * nY + nX);
BYTE nColorIndex = (nByte & 0xf0) >> 4;
if (nX < nWidth)
{
pBgraBuffer[nIndex + 0] = oColorTable[nColorIndex].b;
pBgraBuffer[nIndex + 1] = oColorTable[nColorIndex].g;
pBgraBuffer[nIndex + 2] = oColorTable[nColorIndex].r;
pBgraBuffer[nIndex + 3] = 255;
}
nX = nLineIndex * 2 + 1;
nIndex = 4 * (nWidth * nY + nX);
nColorIndex = nByte & 0x0f;
if (nX < nWidth)
{
pBgraBuffer[nIndex + 0] = oColorTable[nColorIndex].b;
pBgraBuffer[nIndex + 1] = oColorTable[nColorIndex].g;
pBgraBuffer[nIndex + 2] = oColorTable[nColorIndex].r;
pBgraBuffer[nIndex + 3] = 255;
}
}
}
}
else
{
for (int nY = abs(nHeight) - 1; nY >= 0; nY--)
{
for (int nLineIndex = 0; nLineIndex < nScanLineBytes; nLineIndex++)
{
BYTE nByte = *pBuffer; pBuffer++;
int nX = nLineIndex * 2;
int nIndex = 4 * (nWidth * nY + nX);
BYTE nColorIndex = (nByte & 0xf0) >> 4;
if (nX < nWidth)
{
pBgraBuffer[nIndex + 0] = oColorTable[nColorIndex].b;
pBgraBuffer[nIndex + 1] = oColorTable[nColorIndex].g;
pBgraBuffer[nIndex + 2] = oColorTable[nColorIndex].r;
pBgraBuffer[nIndex + 3] = 255;
}
nX = nLineIndex * 2 + 1;
nIndex = 4 * (nWidth * nY + nX);
nColorIndex = nByte & 0x0f;
if (nX < nWidth)
{
pBgraBuffer[nIndex + 0] = oColorTable[nColorIndex].b;
pBgraBuffer[nIndex + 1] = oColorTable[nColorIndex].g;
pBgraBuffer[nIndex + 2] = oColorTable[nColorIndex].r;
pBgraBuffer[nIndex + 3] = 255;
}
}
}
}
*ppDstBuffer = pBgraBuffer;
*pulWidth = ulWidth;
*pulHeight = ulHeight;
return true;
}
else if (BI_BITCOUNT_3 == ushBitCount)
{
......@@ -170,7 +299,7 @@ namespace MetaFile
ushColorTableLen = (std::min)((unsigned short)256, (unsigned short)unColorUsed);
TRgbQuad oColorTable[256];
if (lBufLen < ushColorTableLen * 4)
if (oHeaderStream.CanRead() < ushColorTableLen * 4)
return false;
//
......@@ -242,11 +371,33 @@ namespace MetaFile
}
else if (BI_BITCOUNT_4 == ushBitCount)
{
// ( )
pBuffer += unColorUsed * 4; lBufLen -= unColorUsed * 4;
unsigned long ulMaskR = 0x1f, ulMaskB = 0x7C00, ulMaskG = 0x3E0;
unsigned long ulShiftR = 0, ulShiftB = 10, ulShiftG = 5;
double dKoefR = 255 / 31.0, dKoefB = 255 / 31.0, dKoefG = 255 / 31.0;
if (BI_RGB != unCompression)
return false; // TODO: ,
if (BI_RGB == unCompression)
{
// ,
// 000000000011111 - Red
// 000001111100000 - Green
// 111110000000000 - Blue
}
else if (BI_BITFIELDS == unCompression)
{
oHeaderStream >> ulMaskR;
oHeaderStream >> ulMaskG;
oHeaderStream >> ulMaskB;
ulShiftR = GetLowestBit(ulMaskR);
ulShiftB = GetLowestBit(ulMaskB);
ulShiftG = GetLowestBit(ulMaskG);
dKoefR = 255.0 / (ulMaskR >> ulShiftR);
dKoefG = 255.0 / (ulMaskG >> ulShiftG);
dKoefB = 255.0 / (ulMaskB >> ulShiftB);
}
else
return false;
//
long lCalcLen = (((nWidth * ushPlanes * ushBitCount + 31) & ~31) / 8) * abs(nHeight);
......@@ -276,14 +427,15 @@ namespace MetaFile
{
int nIndex = 4 * (nWidth * nY + nX);
unsigned short ushValue = ((pBuffer[1] << 8) | pBuffer[0]) & 32767; pBuffer += 2; lBufLen -= 2;
unsigned char unR = ushValue & 31; // 000000000011111
unsigned char unG = (ushValue & 992) >> 5; // 000001111100000
unsigned char unB = (ushValue & 31744) >> 10; // 111110000000000
unsigned short ushValue = ((pBuffer[1] << 8) | pBuffer[0]) & 0xFFFF; pBuffer += 2; lBufLen -= 2;
pBgraBuffer[nIndex + 0] = (unsigned char)(unR / 31.0 * 255);
pBgraBuffer[nIndex + 1] = (unsigned char)(unG / 31.0 * 255);
pBgraBuffer[nIndex + 2] = (unsigned char)(unB / 31.0 * 255);
unsigned char unR = (ushValue & ulMaskR) >> ulShiftR;
unsigned char unG = (ushValue & ulMaskG) >> ulShiftG;
unsigned char unB = (ushValue & ulMaskB) >> ulShiftB;
pBgraBuffer[nIndex + 0] = (unsigned char)(unB * dKoefB);
pBgraBuffer[nIndex + 1] = (unsigned char)(unG * dKoefG);
pBgraBuffer[nIndex + 2] = (unsigned char)(unR * dKoefR);
pBgraBuffer[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
......@@ -297,14 +449,14 @@ namespace MetaFile
{
int nIndex = 4 * (nWidth * nY + nX);
unsigned short ushValue = ((pBuffer[1] << 8) | pBuffer[0]) & 32767; pBuffer += 2; lBufLen -= 2;
unsigned char unR = ushValue & 31; // 000000000011111
unsigned char unG = (ushValue & 992) >> 5; // 000001111100000
unsigned char unB = (ushValue & 31744) >> 10; // 111110000000000
unsigned short ushValue = ((pBuffer[1] << 8) | pBuffer[0]) & 0xFFFF; pBuffer += 2; lBufLen -= 2;
unsigned char unR = (ushValue & ulMaskR) >> ulShiftR;
unsigned char unG = (ushValue & ulMaskG) >> ulShiftG;
unsigned char unB = (ushValue & ulMaskB) >> ulShiftB;
pBgraBuffer[nIndex + 0] = (unsigned char)(unR / 31.0 * 255);
pBgraBuffer[nIndex + 1] = (unsigned char)(unG / 31.0 * 255);
pBgraBuffer[nIndex + 2] = (unsigned char)(unB / 31.0 * 255);
pBgraBuffer[nIndex + 0] = (unsigned char)(unB * dKoefB);
pBgraBuffer[nIndex + 1] = (unsigned char)(unG * dKoefG);
pBgraBuffer[nIndex + 2] = (unsigned char)(unR * dKoefR);
pBgraBuffer[nIndex + 3] = 255;
}
pBuffer += nAdd; lBufLen -= nAdd;
......@@ -473,7 +625,7 @@ namespace MetaFile
}
return false;
}
}
void ReadImage(BYTE* pHeaderBuffer, unsigned long ulHeaderBufferLen, BYTE* pImageBuffer, unsigned long ulImageBufferLen, BYTE** ppDstBuffer, unsigned long* pulWidth, unsigned long* pulHeight)
{
if (ulHeaderBufferLen <= 0 || NULL == pHeaderBuffer || NULL == pImageBuffer || ulImageBufferLen < 0)
......
......@@ -475,6 +475,11 @@ namespace MetaFile
pCur = pBuffer;
}
unsigned long CanRead()
{
return (unsigned long)(pEnd - pCur);
}
private:
BYTE *pBuffer;
......
This diff is collapsed.
......@@ -386,13 +386,13 @@ namespace MetaFile
Copy(&oOther);
}
}
void Apply(double* pX, double* pY)
void Apply(double& dX, double& dY)
{
double dX = *pX;
double dY = *pY;
double _dX = dX;
double _dY = dY;
*pX = dX * M11 + dY * M21 + Dx;
*pY = dX * M12 + dY * M22 + Dy;
dX = _dX * M11 + _dY * M21 + Dx;
dY = _dX * M12 + _dY * M22 + Dy;
}
};
......
......@@ -7,6 +7,7 @@
#include "../../../graphics/Image.h"
#include "../../../raster/ImageFileFormatChecker.h"
#include "../../../raster/BgraFrame.h"
#include "../../../graphics/AggPlusEnums.h"
#include "EmfOutputDevice.h"
#include "EmfFile.h"
......@@ -101,10 +102,8 @@ namespace MetaFile
if (lLogicalFontHeight < 0.01)
lLogicalFontHeight = 18;
TEmfRectL* pBounds = m_pEmfFile->GetDCBounds();
TEmfPointD oHeightPoint = TranslatePoint(0, lLogicalFontHeight + pBounds->lTop);
double dFontHeight = lLogicalFontHeight * m_dScaleY * pDC->GetPixelHeight() / 25.4 * 72;
double dFontHeight = oHeightPoint.y / 25.4 * 72;
std::wstring wsFaceName((const wchar_t*)pLogFont->FaceName);
m_pRenderer->put_FontName(wsFaceName);
m_pRenderer->put_FontSize(dFontHeight);
......@@ -260,6 +259,8 @@ namespace MetaFile
void StartPath()
{
CheckEndPath();
UpdateTransform();
m_lDrawPathType = -1;
......@@ -395,16 +396,22 @@ namespace MetaFile
double dX = m_pEmfFile->TranslateX(lX);
double dY = m_pEmfFile->TranslateY(lY);
//
// . ,
// .
TEmfRectL* pBounds = m_pEmfFile->GetDCBounds();
double dT = pBounds->lTop;
double dL = pBounds->lLeft;
TEmfXForm* pInverse = m_pEmfFile->GetDC()->GetInverseTransform();
pInverse->Apply(&dL, &dT);
TEmfXForm* pTransform = m_pEmfFile->GetDC()->GetTransform();
pTransform->Apply(dX, dY);
dX -= dL;
dY -= dT;
pInverse->Apply(dX, dY);
TEmfPointD oPoint;
oPoint.x = m_dScaleX * (double)(dX - dL) + m_dX;
oPoint.y = m_dScaleY * (double)(dY - dT) + m_dY;
oPoint.x = m_dScaleX * dX + m_dX;
oPoint.y = m_dScaleY * dY + m_dY;
return oPoint;
}
......@@ -473,20 +480,20 @@ namespace MetaFile
unsigned long ulPenStyle = pPen->PenStyle & PS_STYLE_MASK;
BYTE nCapStyle = 0;
if (0 == ulPenEndCap)
nCapStyle = 2;
else if (1 == ulPenEndCap)
nCapStyle = 1;
else if (2 == ulPenEndCap)
nCapStyle = 0;
if (PS_ENDCAP_ROUND == ulPenEndCap)
nCapStyle = Aggplus::LineCapRound;
else if (PS_ENDCAP_SQUARE == ulPenEndCap)
nCapStyle = Aggplus::LineCapSquare;
else if (PS_ENDCAP_FLAT == ulPenEndCap)
nCapStyle = Aggplus::LineCapFlat;
BYTE nJoinStyle = 0;
if (0 == ulPenJoin)
nJoinStyle = 2;
else if (1 == ulPenJoin)
nJoinStyle = 1;
else if (2 == ulPenJoin)
nJoinStyle = 2;
if (PS_JOIN_ROUND == ulPenJoin)
nJoinStyle = Aggplus::LineJoinRound;
else if (PS_JOIN_BEVEL == ulPenJoin)
nJoinStyle = Aggplus::LineJoinBevel;
else if (PS_JOIN_MITER == ulPenJoin)
nJoinStyle = Aggplus::LineJoinMiter;
double dMiterLimit = pDC->GetMiterLimit() * m_dScaleX * pDC->GetPixelWidth();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment