mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
1272 lines
36 KiB
C++
1272 lines
36 KiB
C++
/*
|
||
* (c) Copyright Ascensio System SIA 2010-2023
|
||
*
|
||
* This program is a free software product. You can redistribute it and/or
|
||
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
||
* version 3 as published by the Free Software Foundation. In accordance with
|
||
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
||
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
||
* of any third-party rights.
|
||
*
|
||
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
||
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
||
*
|
||
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
||
* street, Riga, Latvia, EU, LV-1050.
|
||
*
|
||
* The interactive user interfaces in modified source and object code versions
|
||
* of the Program must display Appropriate Legal Notices, as required under
|
||
* Section 5 of the GNU AGPL version 3.
|
||
*
|
||
* Pursuant to Section 7(b) of the License you must retain the original Product
|
||
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
||
* grant you any rights under trademark law for use of our trademarks.
|
||
*
|
||
* All the Product's GUI elements, including illustrations and icon sets, as
|
||
* well as technical writing content are licensed under the terms of the
|
||
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
||
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||
*
|
||
*/
|
||
#include <string>
|
||
|
||
#include "../../../graphics/pro/Graphics.h"
|
||
#include "../Common/MetaFileTypes.h"
|
||
#include "../Common/MetaFileRenderer.h"
|
||
|
||
#include "../../../../OfficeUtils/src/OfficeUtils.h"
|
||
#ifdef _DEBUG
|
||
#include <iostream>
|
||
#endif
|
||
|
||
#include "SvmFile.h"
|
||
#include "SvmEnums.h"
|
||
#include "SvmObjects.h"
|
||
|
||
#define DEBUG_CSvmParser 0
|
||
|
||
namespace MetaFile
|
||
{
|
||
|
||
static const struct ActionNamesSmv
|
||
{
|
||
int actionNumber;
|
||
std::wstring actionName;
|
||
} actionNamesSmv[] =
|
||
{
|
||
{ 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: Read_META_TEXTLANGUAGE(); break;
|
||
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_BMPEX_ACTION: Read_META_BMPEX(); break;
|
||
case META_BMPEXSCALE_ACTION: Read_META_BMPEXSCALE(); 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_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 = actionNamesSmv[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();
|
||
|
||
ClearFile();
|
||
}
|
||
|
||
void CSvmFile::Read_META_LAYOUTMODE()
|
||
{
|
||
unsigned int textLayputMode;
|
||
|
||
m_oStream >> textLayputMode;
|
||
|
||
UpdateOutputDC();
|
||
}
|
||
|
||
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 = static_cast<int>(line_info.width / (m_oPlayer.GetDC()->m_dPixelWidth * 2));
|
||
|
||
switch(line_info.style)
|
||
{
|
||
case LINE_SOLID: last_pen->PenStyle = PS_SOLID ; break;
|
||
case LINE_DASH: last_pen->PenStyle = PS_DASH ; break;
|
||
default: break;
|
||
}
|
||
}
|
||
}
|
||
MoveTo(start.x + m_oCurrnetOffset.x, start.y + m_oCurrnetOffset.y);
|
||
LineTo(end.x + m_oCurrnetOffset.x, end.y + m_oCurrnetOffset.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);
|
||
|
||
if (m_bMainStream) //из-за 2 идет увеличение самой картинки в 2 раза (содержимое имеет исходный размер, т.е. в 2 раза меньше нужного)
|
||
{
|
||
unsigned int unCoef = 1;
|
||
m_oBoundingBox = m_oHeader.boundRect;
|
||
m_oBoundingBox.Right = static_cast<int>(m_pDC->m_dPixelWidthPrefered * unCoef * m_oBoundingBox.Right);
|
||
m_oBoundingBox.Bottom = static_cast<int>(m_pDC->m_dPixelHeightPrefered * unCoef * m_oBoundingBox.Bottom);
|
||
|
||
m_oBoundingBox.Left = static_cast<int>(m_pDC->m_dPixelWidthPrefered * unCoef * m_oBoundingBox.Left);
|
||
m_oBoundingBox.Top = static_cast<int>(m_pDC->m_dPixelHeightPrefered * unCoef * m_oBoundingBox.Top);
|
||
}// *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 / (m_oPlayer.GetDC()->m_dPixelWidth * 2);
|
||
|
||
switch(line_info.style)
|
||
{
|
||
case LINE_SOLID: last_pen->PenStyle = PS_SOLID ; break;
|
||
case LINE_DASH: last_pen->PenStyle = PS_DASH ; break;
|
||
default: break;
|
||
}
|
||
|
||
if (last_pen->Width < 1)
|
||
last_pen->Width = 20;
|
||
}
|
||
}
|
||
|
||
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 + m_oCurrnetOffset.x, polygon.points[0].y + m_oCurrnetOffset.y);
|
||
|
||
for (size_t i = 1; i < polygon.points.size(); i++)
|
||
{
|
||
LineTo(polygon.points[i].x + m_oCurrnetOffset.x, polygon.points[i].y + m_oCurrnetOffset.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 + m_oCurrnetOffset.x, polygon.points[0].y + m_oCurrnetOffset.y);
|
||
|
||
for (size_t i = 1; i < polygon.points.size(); i++)
|
||
{
|
||
LineTo(polygon.points[i].x + m_oCurrnetOffset.x, polygon.points[i].y + m_oCurrnetOffset.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 + m_oCurrnetOffset.x, polygons[ushPolygonIndex].points[0].y + m_oCurrnetOffset.y);
|
||
for (int i = 1; i < ushPointsCount; i++)
|
||
{
|
||
LineTo(polygons[ushPolygonIndex].points[i].x + m_oCurrnetOffset.x, polygons[ushPolygonIndex].points[i].y + m_oCurrnetOffset.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 + m_oCurrnetOffset.x, complexPolygons[ushPolygonIndex].points[0].y);
|
||
// for (int i = 1; i < ushPointsCount; i++)
|
||
// {
|
||
// LineTo(complexPolygons[ushPolygonIndex].points[i].x + m_oCurrnetOffset.x, complexPolygons[ushPolygonIndex].points[i].y);
|
||
// }
|
||
// ClosePath();
|
||
//}
|
||
DrawPath(true, true);
|
||
}
|
||
}
|
||
|
||
void CSvmFile::Read_META_SETMAPMODE()
|
||
{
|
||
TSvmMapMode mapMode;
|
||
m_oStream >> mapMode;
|
||
|
||
m_pDC->SetMapMode(mapMode);
|
||
|
||
m_oCurrnetOffset = mapMode.origin;
|
||
|
||
UpdateOutputDC();
|
||
}
|
||
|
||
void CSvmFile::Read_META_TEXTLANGUAGE()
|
||
{
|
||
m_oStream >> m_currentLanguage;
|
||
}
|
||
|
||
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 + m_oCurrnetOffset.x, startPoint.y + m_oCurrnetOffset.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 + m_oCurrnetOffset.x, startPoint.y + m_oCurrnetOffset.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 ];
|
||
|
||
unsigned 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 + m_oCurrnetOffset.x, startPoint.y + m_oCurrnetOffset.y, mpDXAry, nArrayLen);
|
||
|
||
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 + m_oCurrnetOffset.x, polygons[ushPolygonIndex].points[0].y + m_oCurrnetOffset.y);
|
||
for (int i = 1; i < ushPointsCount; i++)
|
||
{
|
||
LineTo(polygons[ushPolygonIndex].points[i].x + m_oCurrnetOffset.x, polygons[ushPolygonIndex].points[i].y + m_oCurrnetOffset.y);
|
||
}
|
||
|
||
m_pOutput->ClosePath();
|
||
}
|
||
}
|
||
|
||
DrawPath(false, true);
|
||
}
|
||
|
||
void CSvmFile::Read_META_FLOATTRANSPARENT()
|
||
{
|
||
return;
|
||
// тут возможен также вариант svg
|
||
CSvmFile subMetaFile(m_oStream.GetCurPtr() , m_unRecordSize);
|
||
|
||
subMetaFile.m_bMainStream = false;
|
||
subMetaFile.SetFontManager(GetFontManager());
|
||
|
||
subMetaFile.PlayMetaFile();
|
||
int skip_size = subMetaFile.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();
|
||
|
||
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);
|
||
|
||
//---------------------------------------------------------
|
||
CSvmBrush* pBrushCopy = new CSvmBrush(*pBrush);
|
||
subMetaFile.m_oPlayer.RegisterObject((CSvmObjectBase*)pBrushCopy);
|
||
|
||
//---------------------------------------------------------
|
||
subMetaFile.m_oStream.SeekToStart();
|
||
|
||
//CGraphicsRenderer oRenderer;
|
||
|
||
//TRect *rect = subMetaFile.GetBounds();
|
||
//
|
||
//int nW = rect->nRight - rect->nLeft;
|
||
//int nH = rect->nBottom - rect->nTop;
|
||
//
|
||
//double dWidth = nW;
|
||
//double dHeight = nH;
|
||
|
||
//BYTE* pBgraData = new BYTE[nW * nH * 4];
|
||
//if (!pBgraData)
|
||
// return;
|
||
|
||
// _UINT32 alfa = 0xffffff;
|
||
////дефолтный тон должен быть прозрачным, а не белым
|
||
////memset(pBgraData, 0xff, nWidth * nHeight * 4);
|
||
//for (int i = 0; i < nW * nH; i++)
|
||
//{
|
||
// ((_UINT32*)pBgraData)[i] = alfa;
|
||
//}
|
||
//CBgraFrame oFrame;
|
||
//oFrame.put_Data(pBgraData);
|
||
//oFrame.put_Width(nW);
|
||
//oFrame.put_Height(nH);
|
||
//oFrame.put_Stride(-4 * nW);
|
||
|
||
//oRenderer.CreateFromBgraFrame(&oFrame);
|
||
//oRenderer.SetSwapRGB(false);
|
||
//oRenderer.put_Width(dWidth);
|
||
//oRenderer.put_Height(dHeight);
|
||
//
|
||
//CMetaFileRenderer oSvmOut(&subMetaFile, &oRenderer, 0, 0, dWidth, dHeight);
|
||
subMetaFile.SetOutputDevice(m_pOutput);//&oSvmOut);
|
||
|
||
subMetaFile.PlayMetaFile();
|
||
|
||
double dX = point.x, dY = point.y, dR = point.x + size.cx, dB = point.y + size.cy;
|
||
|
||
TranslatePoint(point.x, point.y, dX, dY);
|
||
TranslatePoint(point.x + size.cx, point.y + size.cy, dR, dB);
|
||
|
||
//if (m_pOutput)
|
||
//{
|
||
// LONG width, height;
|
||
// BYTE* bytes = oRenderer.GetPixels(width, height);
|
||
// m_pOutput->DrawBitmap(dX, dY, dR - dX, dB - dY, bytes, width, height);
|
||
// oFrame.SaveFile(NSFile::CFileBinary::CreateTempFileWithUniqueName(L"d:\\test\\_svm", L"svm"), 1);
|
||
|
||
//}
|
||
|
||
}
|
||
|
||
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);
|
||
|
||
//ROP_OVERPAINT, ROP_XOR, ROP_0, ROP_1, ROP_INVERT
|
||
|
||
//switch(tmp)
|
||
//{
|
||
//case 0: if ( m_pOutput) m_pOutput->EndClipPath(0); break;
|
||
//case 1: if ( m_pOutput) m_pOutput->StartClipPath(RGN_AND); break;
|
||
//case 2: if ( m_pOutput) m_pOutput->StartClipPath(RGN_OR); break;
|
||
//case 3: if ( m_pOutput) m_pOutput->StartClipPath(RGN_DIFF); break;
|
||
//}
|
||
|
||
|
||
}
|
||
void CSvmFile::Read_META_BMP()
|
||
{
|
||
TSvmBitmap bitmap_info;
|
||
|
||
BYTE *pBgraBuffer = NULL;
|
||
unsigned int ulWidth = 0, ulHeight = 0;
|
||
|
||
Read_META_BMP(bitmap_info, &pBgraBuffer, &ulWidth, &ulHeight );
|
||
|
||
if (bitmap_info.nHeight > (unsigned int)m_oBoundingBox.Bottom &&
|
||
bitmap_info.nWidth > (unsigned int)m_oBoundingBox.Right && !m_pOutput)
|
||
{
|
||
m_oBoundingBox.Right = bitmap_info.nWidth;
|
||
m_oBoundingBox.Bottom = bitmap_info.nHeight;
|
||
}
|
||
|
||
if (pBgraBuffer)
|
||
{
|
||
if ( m_pOutput)
|
||
{
|
||
m_pOutput->DrawBitmap( m_oCurrnetOffset.x, m_oCurrnetOffset.y, bitmap_info.nWidth, bitmap_info.nHeight, pBgraBuffer, bitmap_info.nWidth, bitmap_info.nHeight);
|
||
}
|
||
|
||
delete []pBgraBuffer;
|
||
|
||
UpdateOutputDC();
|
||
}
|
||
}
|
||
void CSvmFile::Read_META_BMP(TSvmBitmap & bitmap_info, BYTE** ppDstBuffer, unsigned int* pulWidth, unsigned int* pulHeight)
|
||
{
|
||
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;
|
||
}
|
||
}
|
||
|
||
unsigned short nColors;
|
||
BYTE* pData = NULL;
|
||
|
||
m_oStream >> bitmap_info; //size = 40
|
||
|
||
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;
|
||
|
||
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, ppDstBuffer, pulWidth, pulHeight);
|
||
delete []destBuf;
|
||
}
|
||
else if (nHeaderSize >= bitmap_info.nSize)
|
||
{
|
||
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, ppDstBuffer, pulWidth, pulHeight);
|
||
m_oStream.Skip(bitmap_info.nSizeImage);
|
||
delete[] Header;
|
||
}
|
||
}
|
||
|
||
void CSvmFile::Read_META_BMPEX()
|
||
{
|
||
TSvmBitmap bitmap_info;
|
||
|
||
BYTE *pBgraBuffer = NULL;
|
||
unsigned int ulWidth = 0, ulHeight = 0;
|
||
|
||
Read_META_BMP(bitmap_info, &pBgraBuffer, &ulWidth, &ulHeight);
|
||
|
||
// if (ulWidth != bitmap_info.nWidth && bitmap_info.nWidth % 2 != 0)
|
||
{
|
||
bitmap_info.nWidth = ulWidth;
|
||
}
|
||
//иногда наверху неверно вычисляется оригинальный размер - если внутри одиночная картинка
|
||
|
||
if (bitmap_info.nHeight > (unsigned int)m_oBoundingBox.Bottom &&
|
||
bitmap_info.nWidth > (unsigned int)m_oBoundingBox.Right && !m_pOutput)
|
||
{
|
||
m_oBoundingBox.Right = bitmap_info.nWidth;
|
||
m_oBoundingBox.Bottom = bitmap_info.nHeight;
|
||
}
|
||
unsigned int nMagic1;
|
||
unsigned int nMagic2;
|
||
|
||
m_oStream >> nMagic1 >> nMagic2;
|
||
|
||
TSvmBitmap bitmap_info_mask;
|
||
BYTE *pBgraBufferMask = NULL;
|
||
unsigned int ulWidthMask = 0, ulHeightMask = 0;
|
||
|
||
if ( (0x25091962 == nMagic1) && (0xACB20201 == nMagic2))
|
||
{
|
||
BYTE transparentType;
|
||
m_oStream >> transparentType;
|
||
|
||
switch(transparentType)
|
||
{
|
||
case 2:// bitmap mask
|
||
Read_META_BMP(bitmap_info_mask, &pBgraBufferMask, &ulWidthMask, &ulHeightMask);
|
||
break;
|
||
case 1:// transparent color
|
||
TSvmColor oColor;
|
||
m_oStream >> oColor;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (pBgraBufferMask)
|
||
{
|
||
delete []pBgraBufferMask;
|
||
}
|
||
|
||
if (pBgraBuffer)
|
||
{
|
||
DrawImage(m_oCurrnetOffset.x, m_oCurrnetOffset.y, bitmap_info.nWidth, bitmap_info.nHeight, pBgraBuffer, bitmap_info.nWidth, bitmap_info.nHeight);
|
||
|
||
delete []pBgraBuffer;
|
||
|
||
UpdateOutputDC();
|
||
}
|
||
}
|
||
|
||
void CSvmFile::Read_META_SECTRECTCLIPREGION()
|
||
{
|
||
TSvmRect rect;
|
||
|
||
m_oStream >> rect;
|
||
}
|
||
void CSvmFile::Read_META_SECTREGIONCLIPREGION()
|
||
{
|
||
}
|
||
void CSvmFile::Read_META_BMPEXSCALE()
|
||
{
|
||
TSvmBitmap bitmap_info;
|
||
|
||
BYTE *pBgraBuffer = NULL;
|
||
unsigned int ulWidth = 0, ulHeight = 0;
|
||
|
||
Read_META_BMP(bitmap_info, &pBgraBuffer, &ulWidth, &ulHeight);
|
||
|
||
//иногда наверху неверно вычисляется оригинальный размер - если внутри одиночная картинка
|
||
|
||
// if (ulWidth != bitmap_info.nWidth && bitmap_info.nWidth % 2 != 0)
|
||
{
|
||
bitmap_info.nWidth = ulWidth;
|
||
}
|
||
|
||
if (bitmap_info.nHeight > (unsigned int)m_oBoundingBox.Bottom &&
|
||
bitmap_info.nWidth > (unsigned int)m_oBoundingBox.Right && !m_pOutput)
|
||
{
|
||
m_oBoundingBox.Right = bitmap_info.nWidth;
|
||
m_oBoundingBox.Bottom = bitmap_info.nHeight;
|
||
}
|
||
unsigned int nMagic1;
|
||
unsigned int nMagic2;
|
||
|
||
m_oStream >> nMagic1 >> nMagic2;
|
||
|
||
TSvmBitmap bitmap_info_mask;
|
||
|
||
BYTE *pBgraBufferMask = NULL;
|
||
unsigned int ulWidthMask = 0, ulHeightMask = 0;
|
||
|
||
if ( (0x25091962 == nMagic1) && (0xACB20201 == nMagic2))
|
||
{
|
||
BYTE transparentType;
|
||
m_oStream >> transparentType;
|
||
|
||
switch(transparentType)
|
||
{
|
||
case 2:// bitmap mask
|
||
Read_META_BMP(bitmap_info_mask, &pBgraBufferMask, &ulWidthMask, &ulHeightMask);
|
||
break;
|
||
case 1:// transparent color
|
||
TSvmColor oColor;
|
||
m_oStream >> oColor;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (pBgraBufferMask)
|
||
{
|
||
delete []pBgraBufferMask;
|
||
}
|
||
|
||
TSvmSize size;
|
||
TSvmPoint point;
|
||
|
||
m_oStream >> point;
|
||
m_oStream >> size.cx;
|
||
m_oStream >> size.cy;
|
||
|
||
if (pBgraBuffer)
|
||
{
|
||
DrawImage(point.x + m_oCurrnetOffset.x, point.y + m_oCurrnetOffset.y, size.cx, size.cy, pBgraBuffer, ulWidth, ulHeight);
|
||
|
||
delete []pBgraBuffer;
|
||
|
||
UpdateOutputDC();
|
||
}
|
||
|
||
}
|
||
void CSvmFile::Read_META_BMPSCALE()
|
||
{
|
||
TSvmBitmap bitmap_info;
|
||
|
||
BYTE *pBgraBuffer = NULL;
|
||
|
||
unsigned int ulWidth = 0, ulHeight = 0;
|
||
|
||
Read_META_BMP(bitmap_info, &pBgraBuffer, &ulWidth, &ulHeight );
|
||
|
||
//иногда наверху неверно вычисляется оригинальный размер - если внутри одиночная картинка
|
||
//if (ulWidth != bitmap_info.nWidth && bitmap_info.nWidth % 2 != 0)
|
||
{
|
||
bitmap_info.nWidth = ulWidth;
|
||
}
|
||
|
||
if (bitmap_info.nHeight > (unsigned int)m_oBoundingBox.Bottom &&
|
||
bitmap_info.nWidth > (unsigned int)m_oBoundingBox.Right && !m_pOutput)
|
||
{
|
||
m_oBoundingBox.Right = bitmap_info.nWidth;
|
||
m_oBoundingBox.Bottom = bitmap_info.nHeight;
|
||
}
|
||
|
||
TSvmSize size;
|
||
TSvmPoint point;
|
||
|
||
m_oStream >> point;
|
||
m_oStream >> size.cx;
|
||
m_oStream >> size.cy;
|
||
|
||
if (pBgraBuffer)
|
||
{
|
||
DrawImage(point.x + m_oCurrnetOffset.x, point.y + m_oCurrnetOffset.y, size.cx, size.cy, pBgraBuffer, ulWidth, ulHeight);
|
||
|
||
delete []pBgraBuffer;
|
||
|
||
UpdateOutputDC();
|
||
}
|
||
|
||
}
|
||
} // namespace MetaFile
|
||
|