Files
core/DesktopEditor/raster/Metafile/StarView/SvmFile.cpp
Oleg.Korshul c596239a11 перешел на новые OfficeUtils
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@64213 954022d7-b5bf-4e40-9824-e11837661b57
2016-05-21 00:25:20 +03:00

981 lines
26 KiB
C++

#include "SvmFile.h"
#include <string>
#include "../Common/MetaFileTypes.h"
#include "../Common/MetaFileRenderer.h"
#include "../../../../OfficeUtils/src/OfficeUtils.h"
#ifdef _DEBUG
#include <iostream>
#endif
#include "SvmEnums.h"
#include "SvmObjects.h"
#define DEBUG_CSvmParser 0
namespace MetaFile
{
static const struct ActionNames
{
int actionNumber;
std::wstring actionName;
} actionNames[] =
{
{ META_NULL_ACTION, L"META_NULL_ACTION" },
{ META_PIXEL_ACTION, L"META_PIXEL_ACTION" },
{ META_POINT_ACTION, L"META_POINT_ACTION" },
{ META_LINE_ACTION, L"META_LINE_ACTION" },
{ META_RECT_ACTION, L"META_RECT_ACTION" },
{ META_ROUNDRECT_ACTION, L"META_ROUNDRECT_ACTION" },
{ META_ELLIPSE_ACTION, L"META_ELLIPSE_ACTION" },
{ META_ARC_ACTION, L"META_ARC_ACTION" },
{ META_PIE_ACTION, L"META_PIE_ACTION" },
{ META_CHORD_ACTION, L"META_CHORD_ACTION" },
{ META_POLYLINE_ACTION, L"META_POLYLINE_ACTION" },
{ META_POLYGON_ACTION, L"META_POLYGON_ACTION" },
{ META_POLYPOLYGON_ACTION, L"META_POLYPOLYGON_ACTION" },
{ META_TEXT_ACTION, L"META_TEXT_ACTION" },
{ META_TEXTARRAY_ACTION, L"META_TEXTARRAY_ACTION" },
{ META_STRETCHTEXT_ACTION, L"META_STRETCHTEXT_ACTION" },
{ META_TEXTRECT_ACTION, L"META_TEXTRECT_ACTION" },
{ META_BMP_ACTION, L"META_BMP_ACTION" },
{ META_BMPSCALE_ACTION, L"META_BMPSCALE_ACTION" },
{ META_BMPSCALEPART_ACTION, L"META_BMPSCALEPART_ACTION" },
{ META_BMPEX_ACTION, L"META_BMPEX_ACTION" },
{ META_BMPEXSCALE_ACTION, L"META_BMPEXSCALE_ACTION" },
{ META_BMPEXSCALEPART_ACTION, L"META_BMPEXSCALEPART_ACTION" },
{ META_MASK_ACTION, L"META_MASK_ACTION" },
{ META_MASKSCALE_ACTION, L"META_MASKSCALE_ACTION" },
{ META_MASKSCALEPART_ACTION, L"META_MASKSCALEPART_ACTION" },
{ META_GRADIENT_ACTION, L"META_GRADIENT_ACTION" },
{ META_HATCH_ACTION, L"META_HATCH_ACTION" },
{ META_WALLPAPER_ACTION, L"META_WALLPAPER_ACTION" },
{ META_CLIPREGION_ACTION, L"META_CLIPREGION_ACTION" },
{ META_ISECTRECTCLIPREGION_ACTION, L"META_ISECTRECTCLIPREGION_ACTION" },
{ META_ISECTREGIONCLIPREGION_ACTION, L"META_ISECTREGIONCLIPREGION_ACTION" },
{ META_MOVECLIPREGION_ACTION, L"META_MOVECLIPREGION_ACTION" },
{ META_LINECOLOR_ACTION, L"META_LINECOLOR_ACTION" },
{ META_FILLCOLOR_ACTION, L"META_FILLCOLOR_ACTION" },
{ META_TEXTCOLOR_ACTION, L"META_TEXTCOLOR_ACTION" },
{ META_TEXTFILLCOLOR_ACTION, L"META_TEXTFILLCOLOR_ACTION" },
{ META_TEXTALIGN_ACTION, L"META_TEXTALIGN_ACTION" },
{ META_MAPMODE_ACTION, L"META_MAPMODE_ACTION" },
{ META_FONT_ACTION, L"META_FONT_ACTION" },
{ META_PUSH_ACTION, L"META_PUSH_ACTION" },
{ META_POP_ACTION, L"META_POP_ACTION" },
{ META_RASTEROP_ACTION, L"META_RASTEROP_ACTION" },
{ META_TRANSPARENT_ACTION, L"META_TRANSPARENT_ACTION" },
{ META_EPS_ACTION, L"META_EPS_ACTION" },
{ META_REFPOINT_ACTION, L"META_REFPOINT_ACTION" },
{ META_TEXTLINECOLOR_ACTION, L"META_TEXTLINECOLOR_ACTION" },
{ META_TEXTLINE_ACTION, L"META_TEXTLINE_ACTION" },
{ META_FLOATTRANSPARENT_ACTION, L"META_FLOATTRANSPARENT_ACTION" },
{ META_GRADIENTEX_ACTION, L"META_GRADIENTEX_ACTION" },
{ META_LAYOUTMODE_ACTION, L"META_LAYOUTMODE_ACTION" },
{ META_TEXTLANGUAGE_ACTION, L"META_TEXTLANGUAGE_ACTION" },
{ META_OVERLINECOLOR_ACTION, L"META_OVERLINECOLOR_ACTION" },
{ META_RENDERGRAPHIC_ACTION, L"META_RENDERGRAPHIC_ACTION" },
{ META_COMMENT_ACTION, L"META_COMMENT_ACTION" }
};
void CSvmFile::PlayMetaFile()
{
m_oStream.SeekToStart();
// Check the signature "VCLMTF"
std::string start = std::string((char*)m_oStream.GetCurPtr(), 6);
if (start != "VCLMTF")
{
SetError();
return;
}
m_oStream.Skip(6);
Read_SVM_HEADER();
if (m_pOutput)
{
m_pOutput->Begin();
}
for (unsigned int action = 0; action < m_oHeader.actionCount; ++action)
{
unsigned short actionType;
m_oStream >> actionType;
m_oStream >> m_currentActionVersion;
m_oStream >> m_unRecordSize;
m_unRecordPos = m_oStream.Tell();
switch (actionType)
{
case META_RECT_ACTION: Read_META_RECTANGLE(); break;
case META_POLYLINE_ACTION: Read_META_POLYLINE(); break;
case META_POLYGON_ACTION: Read_META_POLYGON(); break;
case META_POLYPOLYGON_ACTION: Read_META_POLYPOLYGON(); break;
case META_LINE_ACTION: Read_META_LINE(); break;
case META_TEXT_ACTION: Read_META_TEXT(); break;
case META_TEXTARRAY_ACTION: Read_META_ARRAYTEXT(); break;
case META_TEXTALIGN_ACTION: Read_META_TEXTALIGN(); break;
case META_TEXTRECT_ACTION: Read_META_TEXTRECT(); break;
case META_TEXTFILLCOLOR_ACTION: Read_META_SETTEXTFILLCOLOR(); break;
case META_TEXTCOLOR_ACTION: Read_META_SETTEXTCOLOR(); break;
case META_STRETCHTEXT_ACTION: Read_META_STRETCHTEXT(); break;
case META_TEXTLANGUAGE_ACTION:
case META_TEXTLINECOLOR_ACTION:
case META_TEXTLINE_ACTION:
break;
case META_MAPMODE_ACTION: Read_META_SETMAPMODE(); break;
case META_FONT_ACTION: Read_META_FONT(); break;
case META_BMPSCALE_ACTION: Read_META_BMPSCALE(); break;
case META_BMP_ACTION: Read_META_BMP(); break;
case META_LINECOLOR_ACTION: Read_META_SETLINECOLOR(); break;
case META_FILLCOLOR_ACTION: Read_META_SETFILLCOLOR(); break;
case META_GRADIENT_ACTION: Read_META_GRADIENT(); break;
case META_GRADIENTEX_ACTION: Read_META_GRADIENTEX(); break;
case META_HATCH_ACTION:
case META_RASTEROP_ACTION: Read_META_RASTEROP(); break;
case META_PUSH_ACTION: Read_META_PUSH(); break;
case META_POP_ACTION: Read_META_POP(); break;
case META_TRANSPARENT_ACTION: Read_META_TRANSPARENT(); break;
case META_FLOATTRANSPARENT_ACTION: Read_META_FLOATTRANSPARENT(); break;
case META_ISECTRECTCLIPREGION_ACTION: Read_META_SECTRECTCLIPREGION(); break;
case META_ISECTREGIONCLIPREGION_ACTION: Read_META_SECTREGIONCLIPREGION(); break;
case META_ROUNDRECT_ACTION:
case META_ELLIPSE_ACTION:
case META_ARC_ACTION:
case META_PIE_ACTION:
case META_CHORD_ACTION:
case META_PIXEL_ACTION:
case META_POINT_ACTION:
case META_BMPSCALEPART_ACTION:
case META_BMPEX_ACTION:
case META_BMPEXSCALE_ACTION:
case META_BMPEXSCALEPART_ACTION:
case META_MASK_ACTION:
case META_MASKSCALE_ACTION:
case META_MASKSCALEPART_ACTION:
case META_WALLPAPER_ACTION:
case META_CLIPREGION_ACTION:
case META_MOVECLIPREGION_ACTION:
case META_EPS_ACTION:
case META_REFPOINT_ACTION:
case META_LAYOUTMODE_ACTION:
case META_OVERLINECOLOR_ACTION:
case META_RENDERGRAPHIC_ACTION:
case META_COMMENT_ACTION:
case META_NULL_ACTION:
default:
break;
}
m_currentActionType = actionType;
int need_skip = m_unRecordSize - (m_oStream.Tell() - m_unRecordPos);
m_oStream.Skip(need_skip);
#ifdef _DEBUG
if (100 <= actionType && actionType <= META_LAST_ACTION && need_skip > 0 && !m_pOutput)
{
std::wstring name = actionNames[actionType - 99].actionName;
std::wcout << name << L"\t\t" << actionType << L"\t(version = " << m_currentActionVersion << L")\t; skiped = " << need_skip << L"\n";
}
#endif
}
if (m_pOutput)
m_pOutput->End();
}
void CSvmFile::Read_META_LINE()
{
TSvmPoint start, end;
m_oStream >> start;
m_oStream >> end;
if (m_currentActionVersion >= 2)
{
TSvmLineInfo line_info;
m_oStream >> line_info;
CSvmPen *last_pen = dynamic_cast<CSvmPen *>(m_oPlayer.GetLastObject(SVM_OBJECT_PEN));
if (last_pen)
{
last_pen->Width = line_info.width;
switch(line_info.style)
{
case LINE_SOLID: last_pen->PenStyle = PS_SOLID ; break;
case LINE_DASH: last_pen->PenStyle = PS_DASH ; break;
}
}
}
MoveTo(start.x, start.y);
LineTo(end.x, end.y);
}
void CSvmFile::Read_META_RECTANGLE()
{
TSvmRect oBox;
m_oStream >> oBox;
{
MoveTo(oBox.l, oBox.t);
LineTo(oBox.r, oBox.t);
LineTo(oBox.r, oBox.b);
LineTo(oBox.l, oBox.b);
}
ClosePath();
DrawPath(true, true);
}
void CSvmFile::Read_SVM_HEADER()
{
m_oStream >> m_oHeader;
m_pDC->SetMapMode(m_oHeader.mapMode, true);
m_oBoundingBox = m_oHeader.boundRect;
m_oBoundingBox.nRight *= m_pDC->m_dPixelWidthPrefered * 2;
m_oBoundingBox.nBottom *= m_pDC->m_dPixelHeightPrefered * 2;
m_oBoundingBox.nLeft *= m_pDC->m_dPixelWidthPrefered * 2;
m_oBoundingBox.nTop *= m_pDC->m_dPixelHeightPrefered * 2;
// *2 ради повышения качества картинки (если в векторе насамом деле растр - сментся на растровые размеры ниже
m_bFirstPoint = true;
}
void CSvmFile::Read_META_POLYLINE()
{
TSvmPolygon polygon;
m_oStream >> polygon;
if (m_currentActionVersion >= 2)
{
TSvmLineInfo line_info;
m_oStream >> line_info;
CSvmPen *last_pen = dynamic_cast<CSvmPen *>(m_oPlayer.GetLastObject(SVM_OBJECT_PEN));
if (last_pen)
{
last_pen->Width = line_info.width;
switch(line_info.style)
{
case LINE_SOLID: last_pen->PenStyle = PS_SOLID ; break;
case LINE_DASH: last_pen->PenStyle = PS_DASH ; break;
}
}
}
if (m_currentActionVersion >= 3)
{
unsigned char bHasPolyFlags = 0;
m_oStream >> bHasPolyFlags;
if ( bHasPolyFlags )
{
}
//read flags
//enum PolyFlags
//{
// POLY_NORMAL,
// POLY_SMOOTH,
// POLY_CONTROL,
// POLY_SYMMTR
//};
}
if (polygon.points.size() < 1) return;
MoveTo(polygon.points[0].x, polygon.points[0].y);
for (int i = 1; i < polygon.points.size(); i++)
{
LineTo(polygon.points[i].x, polygon.points[i].y);
}
ClosePath();
DrawPath(true, false);
}
void CSvmFile::Read_META_POLYGON()
{
TSvmPolygon polygon;
m_oStream >> polygon;
if (polygon.points.size() < 1) return;
MoveTo(polygon.points[0].x, polygon.points[0].y);
for (int i = 1; i < polygon.points.size(); i++)
{
LineTo(polygon.points[i].x, polygon.points[i].y);
}
ClosePath();
DrawPath(true, true);
}
void CSvmFile::Read_META_POLYPOLYGON(std::vector<TSvmPolygon> & polygons, std::vector<TSvmPolygon> & complexPolygons)
{
unsigned short ushNumberOfPolygons;
m_oStream >> ushNumberOfPolygons;
if (ushNumberOfPolygons <= 0)
return;
for (unsigned short ushIndex = 0; ushIndex < ushNumberOfPolygons; ushIndex++)
{
TSvmPolygon poligon;
m_oStream >> poligon;
polygons.push_back(poligon);
}
if (m_currentActionVersion > 1)
{
unsigned short complexPolygonCount;
m_oStream >> complexPolygonCount;
complexPolygons.resize(complexPolygonCount);
for (unsigned short i = 0; i < complexPolygonCount; i++)
{
unsigned short complexPolygonIndex;
m_oStream >> complexPolygonIndex;
if (complexPolygonIndex >= complexPolygons.size())
{
complexPolygons.resize(complexPolygonIndex+1);
}
m_oStream >> complexPolygons[complexPolygonIndex];
}
}
}
void CSvmFile::Read_META_POLYPOLYGON()
{
std::vector<TSvmPolygon> polygons;
std::vector<TSvmPolygon> complexPolygons;
Read_META_POLYPOLYGON(polygons, complexPolygons);
if (polygons.size() < 1) return;
////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (m_pOutput)
{
m_pOutput->StartPath();
for (unsigned short ushPolygonIndex = 0; ushPolygonIndex < polygons.size(); ushPolygonIndex++)
{
unsigned short ushPointsCount = polygons[ushPolygonIndex].points.size();
if (ushPointsCount <= 0)
continue;
MoveTo(polygons[ushPolygonIndex].points[0].x, polygons[ushPolygonIndex].points[0].y);
for (int i = 1; i < ushPointsCount; i++)
{
LineTo(polygons[ushPolygonIndex].points[i].x, polygons[ushPolygonIndex].points[i].y);
}
ClosePath();
}
//for (unsigned short ushPolygonIndex = 0; ushPolygonIndex < complexPolygons.size(); ushPolygonIndex++)
//{
// unsigned short ushPointsCount = complexPolygons[ushPolygonIndex].points.size();
// if (ushPointsCount <= 0)
// continue;
// MoveTo(complexPolygons[ushPolygonIndex].points[0].x, complexPolygons[ushPolygonIndex].points[0].y);
// for (int i = 1; i < ushPointsCount; i++)
// {
// LineTo(complexPolygons[ushPolygonIndex].points[i].x, complexPolygons[ushPolygonIndex].points[i].y);
// }
// ClosePath();
//}
DrawPath(true, true);
}
}
void CSvmFile::Read_META_SETMAPMODE()
{
TSvmMapMode mapMode;
m_oStream >> mapMode;
m_pDC->SetMapMode(mapMode);
UpdateOutputDC();
}
void CSvmFile::Read_META_STRETCHTEXT()
{
std::wstring sText;
TSvmPoint startPoint;
m_oStream >> startPoint;
parseString(m_oStream, sText, m_currentActionVersion, m_currentCharset);
unsigned short Index;
unsigned short Len;
unsigned int Width;
m_oStream >> Width;
m_oStream >> Index;
m_oStream >> Len;
if (m_currentActionVersion > 1)
{
unsigned short nLen;
m_oStream >> nLen;
std::wstring buf;
unsigned short nTemp;
while ( nLen-- )
{
m_oStream >> nTemp;
buf += (wchar_t)nTemp;
}
sText = buf;
}
DrawText(sText, sText.length(), startPoint.x, startPoint.y);
}
void CSvmFile::Read_META_TEXT()
{
std::wstring sText;
TSvmPoint startPoint;
m_oStream >> startPoint;
parseString(m_oStream, sText, m_currentActionVersion, m_currentCharset);
//unsigned short index, len;
//
//m_oStream >> index;
//m_oStream >> len;
//if (m_currentActionVersion > 1)
//{
// unsigned short nLen;
// m_oStream >> nLen;
//
// std::wstring buf;
// unsigned short nTemp;
// while ( nLen-- )
// {
// m_oStream >> nTemp;
// buf += (wchar_t)nTemp;
// }
// sText = buf;
//}
DrawText(sText, sText.length(), startPoint.x, startPoint.y);
}
void CSvmFile::Read_META_ARRAYTEXT()
{
std::wstring sText;
TSvmPoint startPoint;
m_oStream >> startPoint;
parseString(m_oStream, sText, m_currentActionVersion, m_currentCharset);
unsigned short nIndex, nLen;
unsigned int nArrayLen;
m_oStream >> nIndex;
m_oStream >> nLen;
m_oStream >> nArrayLen;
int *mpDXAry = NULL;
if( nArrayLen > 0 )
{
// #i9762#, #106172# Ensure that DX array is at least mnLen entries long
const unsigned int nIntAryLen = (std::max)(nArrayLen, (unsigned int)nLen) ;
mpDXAry = new int[ nIntAryLen ];
int i=0;
for( i = 0; i < nArrayLen; i++ )
m_oStream >> mpDXAry[ i ];
// #106172# setup remainder
for( ; i < nIntAryLen; i++ )
mpDXAry[ i ] = 0;
}
if ( m_currentActionVersion >= 2 ) // Version 2
{
unsigned short nLen;
m_oStream >> nLen;
std::wstring tempBuffer;
unsigned short nTemp;
while ( nLen-- )
{
m_oStream >> nTemp;
tempBuffer += (wchar_t)nTemp;
}
}
DrawText(sText, sText.length(), startPoint.x, startPoint.y, mpDXAry);
if (mpDXAry)
delete []mpDXAry;
}
void CSvmFile::Read_META_TEXTRECT()
{
TSvmRect rect;
unsigned short style;
std::wstring sText;
m_oStream >> rect;
parseString(m_oStream, sText, m_currentActionVersion, m_currentCharset);
m_oStream >> style;
if ( m_currentActionVersion >= 2 )
{
}
DrawText(sText, sText.length(), rect);
}
void CSvmFile::Read_META_TEXTALIGN()
{
unsigned short nTmp16;
m_oStream >> nTmp16;
unsigned int align = 0;
switch(nTmp16)
{
case 0: align = TA_TOP; break;
case 1: align = TA_BASELINE;break;
case 2: align = TA_BOTTOM; break;
}
m_pDC->SetTextAlign(align);
}
void CSvmFile::Read_META_SETTEXTCOLOR()
{
TSvmColor oColor;
m_oStream >> oColor;
m_pDC->SetTextColor(oColor);
UpdateOutputDC();
}
void CSvmFile::Read_META_SETTEXTFILLCOLOR()
{
TSvmColor oColor;
m_oStream >> oColor;
m_pDC->SetTextBgColor(oColor);
UpdateOutputDC();
}
void CSvmFile::Read_META_SETFILLCOLOR()
{
if (m_currentActionType == META_GRADIENT_ACTION ||
m_currentActionType == META_GRADIENTEX_ACTION)
{
//поменять основной цвет??
m_oStream.Skip(m_unRecordSize);
return;
}
CSvmBrush* pBrush = new CSvmBrush();
pBrush->BrushStyle = BS_NULL;
if (!pBrush)
return SetError();
bool doSet;
m_oStream >> pBrush->Color;
m_oStream >> doSet;
if (doSet)
{
pBrush->BrushStyle = BS_SOLID;
}
m_oPlayer.RegisterObject((CSvmObjectBase*)pBrush);
}
void CSvmFile::Read_META_SETLINECOLOR()
{
CSvmPen* pPen = new CSvmPen();
if (!pPen)
return SetError();
pPen->PenStyle = PS_NULL;
bool doSet;
m_oStream >> pPen->Color;
m_oStream >> doSet;
if (doSet)
{
pPen->PenStyle = PS_COSMETIC | PS_SOLID;
}
m_oPlayer.RegisterObject((CSvmObjectBase*)pPen);
}
void CSvmFile::Read_META_GRADIENTEX()
{
std::vector<TSvmPolygon> polygons;
std::vector<TSvmPolygon> complexPolygons;
Read_META_POLYPOLYGON(polygons, complexPolygons);
CSvmBrush* pBrush = new CSvmBrush();
if (!pBrush)
return SetError();
TSvmGradient gradient;
m_oStream >> gradient;
switch((ESvmGradientStyle)gradient.style)
{
case GRADIENT_LINEAR: pBrush->BrushStyle = BS_LINEARGRADIENT; break;
case GRADIENT_AXIAL: pBrush->BrushStyle = BS_AXIALGRADIENT; break;
case GRADIENT_RADIAL: pBrush->BrushStyle = BS_RADIALGRADIENT; break;
case GRADIENT_ELLIPTICAL: pBrush->BrushStyle = BS_RADIALGRADIENT; break;
case GRADIENT_SQUARE: pBrush->BrushStyle = BS_LINEARGRADIENT; break;
case GRADIENT_RECT: pBrush->BrushStyle = BS_RECTGRADIENT; break;
}
pBrush->Color.Set(gradient.color1.r>>8, gradient.color1.g>>8, gradient.color1.b>>8);
pBrush->Color2.Set(gradient.color2.r>>8, gradient.color2.g>>8, gradient.color2.b>>8);
pBrush->BrushStyleEx = 90 + gradient.angle % 3600; //проверить на разных
m_oPlayer.RegisterObject((CSvmObjectBase*)pBrush);
}
void CSvmFile::Read_META_TRANSPARENT()
{
std::vector<TSvmPolygon> polygons;
std::vector<TSvmPolygon> complexPolygons;
Read_META_POLYPOLYGON(polygons, complexPolygons);
unsigned short nPercent;
m_oStream >> nPercent;
if (m_pOutput)
{
CSvmBrush *last_brush = dynamic_cast<CSvmBrush *>(m_oPlayer.GetLastObject(SVM_OBJECT_BRUSH));
CSvmBrush* pBrush = new CSvmBrush();
pBrush->BrushStyle = BS_NULL;
if (!pBrush)
return SetError();
if ((last_brush) /*&& (last_brush->BrushStyle > 0)*/) //skip Nofill
{
pBrush->BrushStyle = last_brush->BrushStyle;
pBrush->BrushHatch = last_brush->BrushHatch;
pBrush->BrushStyleEx = last_brush->BrushStyleEx;
pBrush->BrushBounds = last_brush->BrushBounds;
pBrush->Color = last_brush->Color;
pBrush->Color2 = last_brush->Color2;
pBrush->Color.a = 0xff * nPercent /100;
pBrush->Color2.a = 0xff * nPercent /100;
}
m_oPlayer.RegisterObject((CSvmObjectBase*)pBrush);
m_pOutput->StartPath();
for (unsigned short ushPolygonIndex = 0; ushPolygonIndex < polygons.size(); ushPolygonIndex++)
{
unsigned short ushPointsCount = polygons[ushPolygonIndex].points.size();
if (ushPointsCount <= 0)
continue;
MoveTo(polygons[ushPolygonIndex].points[0].x, polygons[ushPolygonIndex].points[0].y);
for (int i = 1; i < ushPointsCount; i++)
{
LineTo(polygons[ushPolygonIndex].points[i].x, polygons[ushPolygonIndex].points[i].y);
}
m_pOutput->ClosePath();
}
}
DrawPath(false, true);
}
void CSvmFile::Read_META_FLOATTRANSPARENT()
{
// тут возможен также вариант svg
CSvmFile metaFile(m_oStream.GetCurPtr() , m_unRecordSize);
metaFile.SetOutputDevice(m_pOutput);
metaFile.PlayMetaFile();
int skip_size = metaFile.m_oStream.Tell();
m_oStream.Skip( skip_size);
TSvmPoint point;
TSvmSize size;
m_oStream >> point;
m_oStream >> size;
///////////////////////////////////////////////////
CSvmBrush* pBrush = new CSvmBrush();
if (!pBrush)
return SetError();
m_oStream >> pBrush->BrushBounds;
TSvmGradient gradient;
m_oStream >> gradient;
switch((ESvmGradientStyle)gradient.style)
{
case GRADIENT_LINEAR: pBrush->BrushStyle = BS_LINEARGRADIENT; break;
case GRADIENT_AXIAL: pBrush->BrushStyle = BS_AXIALGRADIENT; break;
case GRADIENT_RADIAL: pBrush->BrushStyle = BS_RADIALGRADIENT; break;
case GRADIENT_ELLIPTICAL: pBrush->BrushStyle = BS_RADIALGRADIENT; break;
case GRADIENT_SQUARE: pBrush->BrushStyle = BS_LINEARGRADIENT; break;
case GRADIENT_RECT: pBrush->BrushStyle = BS_RECTGRADIENT; break;
}
pBrush->Color.Set(gradient.color1.r>>8, gradient.color1.g>>8, gradient.color1.b>>8);
pBrush->Color2.Set(gradient.color2.r>>8, gradient.color2.g>>8, gradient.color2.b>>8);
pBrush->BrushStyleEx = 90 + gradient.angle % 3600; //проверить на разных
m_oPlayer.RegisterObject((CSvmObjectBase*)pBrush);
}
void CSvmFile::Read_META_GRADIENT()
{
CSvmBrush* pBrush = new CSvmBrush();
if (!pBrush)
return SetError();
m_oStream >> pBrush->BrushBounds;
TSvmGradient gradient;
m_oStream >> gradient;
switch((ESvmGradientStyle)gradient.style)
{
case GRADIENT_LINEAR: pBrush->BrushStyle = BS_LINEARGRADIENT; break;
case GRADIENT_AXIAL: pBrush->BrushStyle = BS_AXIALGRADIENT; break;
case GRADIENT_RADIAL: pBrush->BrushStyle = BS_RADIALGRADIENT; break;
case GRADIENT_ELLIPTICAL: pBrush->BrushStyle = BS_RADIALGRADIENT; break;
case GRADIENT_SQUARE: pBrush->BrushStyle = BS_LINEARGRADIENT; break;
case GRADIENT_RECT: pBrush->BrushStyle = BS_RECTGRADIENT; break;
}
pBrush->Color.Set(gradient.color1.r>>8, gradient.color1.g>>8, gradient.color1.b>>8);
pBrush->Color2.Set(gradient.color2.r>>8, gradient.color2.g>>8, gradient.color2.b>>8);
pBrush->BrushStyleEx = 90 + gradient.angle % 3600; //проверить на разных
m_oPlayer.RegisterObject((CSvmObjectBase*)pBrush);
}
void CSvmFile::Read_META_FONT()
{
CSvmFont* pFont = new CSvmFont();
if (!pFont)
return SetError();
m_oStream >> pFont;
m_currentCharset = pFont->CharSet;
m_oPlayer.RegisterObject((CSvmObjectBase*)pFont);
}
#define COMPRESS_OWN ('S'|('D'<<8))
#define COMPRESS_NONE ( 0 )
#define RLE_8 ( 1 )
#define RLE_4 ( 2 )
#define BITFIELDS ( 3 )
#define ZCOMPRESS ( COMPRESS_OWN | 0x01000000 )
inline USHORT discretizeBitcount( int nInputCount )
{
return ( nInputCount <= 1 ) ? 1 :
( nInputCount <= 4 ) ? 4 :
( nInputCount <= 8 ) ? 8 : 24;
}
bool CSvmFile::ReadImage(unsigned short ushColorUsage, BYTE** ppBgraBuffer, unsigned int* pulWidth, unsigned int* pulHeight)
{
unsigned int unRemainBytes = m_unRecordSize - ( m_oStream.Tell() - m_unRecordPos);
if (unRemainBytes <= 0)
return false;
BYTE* pBuffer = m_oStream.GetCurPtr();
MetaFile::ReadImage(pBuffer, unRemainBytes, ushColorUsage, ppBgraBuffer, pulWidth, pulHeight);
return true;
}
void CSvmFile::Read_META_POP()
{
m_oPlayer.Pop();
}
void CSvmFile::Read_META_PUSH()
{
unsigned short nFlags;
m_oStream >> nFlags;
m_oPlayer.Push(nFlags);
}
void CSvmFile::Read_META_RASTEROP()
{
unsigned short tmp;
m_oStream >> tmp;
m_oPlayer.SetRasterOp(tmp);
}
void CSvmFile::Read_META_BMP()
{
}
void CSvmFile::Read_META_SECTRECTCLIPREGION()
{
TSvmRect rect;
m_oStream >> rect;
}
void CSvmFile::Read_META_SECTREGIONCLIPREGION()
{
}
void CSvmFile::Read_META_BMPSCALE()
{
unsigned int nHeaderSize = 0;
unsigned int nTmp32;
unsigned short nTmp16 = 0;
bool bRet = false;
m_oStream >> nTmp16;
m_oStream >> nHeaderSize;
if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) )
{
if ( 0x4142 == nTmp16 )
{
m_oStream.Skip( 12 );//не то !!!
m_oStream >> nTmp16;
m_oStream.Skip( 8 );
m_oStream >> nTmp32;
nHeaderSize = nTmp32 - 28UL;;
bRet = ( 0x4D42 == nTmp16 );
}
else
{
m_oStream.Skip( 4 );
m_oStream >> nTmp32;
nHeaderSize = nTmp32 - 14;
}
}
TSvmBitmap bitmap_info;
m_oStream >> bitmap_info; //size = 40
unsigned short nColors;
BYTE* pData = NULL;
int nBitCount = discretizeBitcount(bitmap_info.nBitCount);
if( nBitCount <= 8 )
{
if( bitmap_info.nColsUsed )
nColors = (USHORT) bitmap_info.nColsUsed;
else
nColors = ( 1 << bitmap_info.nBitCount );
}
else
nColors = 0;
BYTE *pBgraBuffer = NULL;
unsigned int ulWidth = 0, ulHeight = 0;
if( ZCOMPRESS == bitmap_info.nCompression )
{
COfficeUtils OfficeUtils(NULL);
ULONG destSize, srcSize;
m_oStream >> srcSize >> destSize >> bitmap_info.nCompression;
BYTE* srcBuf = m_oStream.GetCurPtr();
BYTE* destBuf = new BYTE[destSize];
if (destSize > 0 && m_pOutput && destBuf )
{
if (OfficeUtils.Uncompress(destBuf, &destSize, srcBuf, srcSize) != S_OK)
{
delete []destBuf;
return;
}
}
m_oStream.Skip(srcSize);
MetaFile::ReadImage((BYTE*)&bitmap_info, bitmap_info.nSize, destBuf, destSize, &pBgraBuffer, &ulWidth, &ulHeight);
delete []destBuf;
}
else
{
BYTE *Header = new BYTE [ nHeaderSize];
memcpy(Header, &bitmap_info, bitmap_info.nSize);
m_oStream.ReadBytes(Header + bitmap_info.nSize, nHeaderSize - bitmap_info.nSize);
MetaFile::ReadImage(Header , nHeaderSize, m_oStream.GetCurPtr(), bitmap_info.nSizeImage, &pBgraBuffer, &ulWidth, &ulHeight);
m_oStream.Skip(bitmap_info.nSizeImage);
delete Header;
}
//иногда наверху неверно вычисляется оригинальный размер - если внутри одиночная картинка
if (bitmap_info.nHeight > m_oBoundingBox.nBottom &&
bitmap_info.nWidth > m_oBoundingBox.nRight && !m_pOutput)
{
m_oBoundingBox.nRight = bitmap_info.nWidth;
m_oBoundingBox.nBottom = bitmap_info.nHeight;
}
TSvmSize size;
TSvmPoint point;
m_oStream >> point;
m_oStream >> size.cx;
m_oStream >> size.cy;
if (pBgraBuffer)
{
if ( m_pOutput)
{
m_pOutput->DrawBitmap( point.x, point.y, size.cx, size.cy, pBgraBuffer, bitmap_info.nWidth, bitmap_info.nHeight);
}
delete []pBgraBuffer;
UpdateOutputDC();
}
}
} // namespace MetaFile