Commit 4dd84f2c authored by Elen.Subbotina's avatar Elen.Subbotina Committed by Alexander Trofimov

протащены градиенты в мета файлах

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62851 954022d7-b5bf-4e40-9824-e11837661b57
parent c16c34a8
...@@ -33,6 +33,7 @@ namespace MetaFile ...@@ -33,6 +33,7 @@ namespace MetaFile
virtual unsigned int GetStyleEx() = 0; virtual unsigned int GetStyleEx() = 0;
virtual unsigned int GetHatch() = 0; virtual unsigned int GetHatch() = 0;
virtual unsigned int GetAlpha() = 0; virtual unsigned int GetAlpha() = 0;
virtual unsigned int GetAlpha2() = 0;
virtual std::wstring GetDibPatterPath() = 0; virtual std::wstring GetDibPatterPath() = 0;
virtual void GetBounds(double& left, double& top, double& width, double& height) = 0; virtual void GetBounds(double& left, double& top, double& width, double& height) = 0;
}; };
......
...@@ -565,24 +565,46 @@ namespace MetaFile ...@@ -565,24 +565,46 @@ namespace MetaFile
m_pRenderer->put_BrushColor1(oFgColor.ToInt()); m_pRenderer->put_BrushColor1(oFgColor.ToInt());
} }
else if ( BS_LINEARGRADIENT == unBrushStyle || else if ( BS_LINEARGRADIENT == unBrushStyle ||
BS_RADIALGRADIENT == unBrushStyle ||
BS_AXIALGRADIENT == unBrushStyle ||
BS_RECTGRADIENT == unBrushStyle || BS_RECTGRADIENT == unBrushStyle ||
BS_PATHGRADIENT == unBrushStyle BS_PATHGRADIENT == unBrushStyle
) )
{ {
m_pRenderer->put_BrushType(c_BrushTypeCenter); m_pRenderer->put_BrushType(c_BrushTypePathGradient1);
m_pRenderer->put_BrushColor1(pBrush->GetColor()); m_pRenderer->put_BrushColor1(pBrush->GetColor());
m_pRenderer->put_BrushColor2(pBrush->GetColor2()); m_pRenderer->put_BrushColor2(pBrush->GetColor2());
m_pRenderer->put_BrushAlpha1(pBrush->GetAlpha()); m_pRenderer->put_BrushAlpha1(pBrush->GetAlpha());
m_pRenderer->put_BrushAlpha2(pBrush->GetAlpha2());
m_pRenderer->put_BrushLinearAngle(pBrush->GetStyleEx()); m_pRenderer->put_BrushLinearAngle(pBrush->GetStyleEx());
double l=0, t=0, w=0, h=0;
pBrush->GetBounds(l,t,w,h);
m_pRenderer->BrushBounds(l,t,w,h);
long Colors[2];
Colors[0] = (pBrush->GetColor()<<8) + pBrush->GetAlpha();
Colors[1] = (pBrush->GetColor2()<<8) + pBrush->GetAlpha2();
double Position[2] = {0, 1};
m_pRenderer->put_BrushGradientColors(Colors,Position,2);
}
else if ( BS_RADIALGRADIENT == unBrushStyle ||
BS_AXIALGRADIENT == unBrushStyle
)
{
m_pRenderer->put_BrushType(c_BrushTypePathGradient2);
m_pRenderer->put_BrushColor1(pBrush->GetColor());
m_pRenderer->put_BrushColor2(pBrush->GetColor2());
m_pRenderer->put_BrushAlpha1(pBrush->GetAlpha());
m_pRenderer->put_BrushAlpha2(pBrush->GetAlpha2());
long Colors[2];
Colors[0] = (pBrush->GetColor()<<8) + pBrush->GetAlpha();
Colors[1] = (pBrush->GetColor2()<<8) + pBrush->GetAlpha2();
double Position[2] = {0, 1};
m_pRenderer->put_BrushGradientColors(Colors,Position,2);
} }
else //if (BS_SOLID == unBrushStyle) else //if (BS_SOLID == unBrushStyle)
{ {
m_pRenderer->put_BrushType(c_BrushTypeSolid); m_pRenderer->put_BrushType(c_BrushTypeSolid);
......
...@@ -62,6 +62,10 @@ namespace MetaFile ...@@ -62,6 +62,10 @@ namespace MetaFile
{ {
return BrushAlpha; return BrushAlpha;
} }
unsigned int GetAlpha2()
{
return 0Xff;
}
std::wstring GetDibPatterPath() std::wstring GetDibPatterPath()
{ {
return DibPatternPath; return DibPatternPath;
......
...@@ -170,7 +170,7 @@ namespace MetaFile ...@@ -170,7 +170,7 @@ namespace MetaFile
pFontCache->SetStreams(m_pAppFonts->GetStreams()); pFontCache->SetStreams(m_pAppFonts->GetStreams());
pFontManager->SetOwnerCache(pFontCache); pFontManager->SetOwnerCache(pFontCache);
CGraphicsRenderer oRenderer; CGraphicsRenderer oRenderer;
oRenderer.SetFontManager(pFontManager); oRenderer.SetFontManager(pFontManager);
if (-1 == nHeight) if (-1 == nHeight)
...@@ -193,7 +193,13 @@ namespace MetaFile ...@@ -193,7 +193,13 @@ namespace MetaFile
if (!pBgraData) if (!pBgraData)
return; return;
memset(pBgraData, 0xff, nWidth * nHeight * 4); DWORD alfa = 0xffffff;
// ,
//memset(pBgraData, 0xff, nWidth * nHeight * 4);
for (int i = 0; i < nWidth * nHeight; i++)
{
((DWORD*)pBgraData)[i] = alfa;
}
CBgraFrame oFrame; CBgraFrame oFrame;
oFrame.put_Data(pBgraData); oFrame.put_Data(pBgraData);
oFrame.put_Width(nWidth); oFrame.put_Width(nWidth);
......
...@@ -459,7 +459,7 @@ class CSvmFile : virtual public IMetaFileBase ...@@ -459,7 +459,7 @@ class CSvmFile : virtual public IMetaFileBase
delete[] pdDx; delete[] pdDx;
} }
} }
void DrawText(std::wstring& wsString, unsigned int unCharsCount, int _nX, int _nY, int* pnDx = NULL) void DrawText(std::wstring& wsString, unsigned int unCharsCount, int _nX, int _nY, int* pnDx = NULL)
{ {
int nX = _nX; int nX = _nX;
......
...@@ -156,7 +156,7 @@ CDataStream& operator>>(CDataStream &stream, TSvmPoint &p) ...@@ -156,7 +156,7 @@ CDataStream& operator>>(CDataStream &stream, TSvmPoint &p)
return stream; return stream;
} }
CSvmBrush::CSvmBrush() : Color(255, 255, 255) CSvmBrush::CSvmBrush() : Color(255, 255, 255), Color2(255, 255, 255)
{ {
BrushStyle = BS_SOLID; BrushStyle = BS_SOLID;
BrushHatch = HS_HORIZONTAL; BrushHatch = HS_HORIZONTAL;
...@@ -165,7 +165,10 @@ CSvmBrush::CSvmBrush(CSvmBrush& oBrush) ...@@ -165,7 +165,10 @@ CSvmBrush::CSvmBrush(CSvmBrush& oBrush)
{ {
BrushStyle = oBrush.BrushStyle; BrushStyle = oBrush.BrushStyle;
Color = oBrush.Color; Color = oBrush.Color;
Color2 = oBrush.Color2;
BrushHatch = oBrush.BrushHatch; BrushHatch = oBrush.BrushHatch;
BrushStyleEx = oBrush.BrushStyleEx;
BrushBounds = oBrush.BrushBounds;
} }
int CSvmBrush::GetColor() int CSvmBrush::GetColor()
...@@ -192,6 +195,10 @@ unsigned int CSvmBrush::GetAlpha() ...@@ -192,6 +195,10 @@ unsigned int CSvmBrush::GetAlpha()
{ {
return 0xff-Color.a; return 0xff-Color.a;
} }
unsigned int CSvmBrush::GetAlpha2()
{
return 0xff-Color2.a;
}
void CSvmBrush::GetBounds(double& left, double& top, double& width, double& height) void CSvmBrush::GetBounds(double& left, double& top, double& width, double& height)
{ {
left = BrushBounds.l; left = BrushBounds.l;
...@@ -238,9 +245,6 @@ CDataStream& operator>>(CDataStream &stream, TSvmPolygon &p) ...@@ -238,9 +245,6 @@ CDataStream& operator>>(CDataStream &stream, TSvmPolygon &p)
CDataStream& operator>>(CDataStream &stream, TSvmColor &c) CDataStream& operator>>(CDataStream &stream, TSvmColor &c)
{ {
char s;
unsigned short a, r, g, b, p;
stream >> c.b; stream >> c.b;
stream >> c.g; stream >> c.g;
stream >> c.r; stream >> c.r;
...@@ -250,6 +254,23 @@ CDataStream& operator>>(CDataStream &stream, TSvmColor &c) ...@@ -250,6 +254,23 @@ CDataStream& operator>>(CDataStream &stream, TSvmColor &c)
return stream; return stream;
} }
CDataStream& operator>>(CDataStream &stream, TSvmColorEx &c)
{
stream >> c.name;
if ( c.name & 0x8000 )
{
//if(compression_mode)
stream >> c.r;
stream >> c.g;
stream >> c.b;
}
else
{
//из таблички
}
return stream;
}
CDataStream& operator>>(CDataStream &stream, TSvmLineInfo &i) CDataStream& operator>>(CDataStream &stream, TSvmLineInfo &i)
{ {
VersionCompat version; VersionCompat version;
...@@ -419,5 +440,24 @@ CDataStream& operator>>(CDataStream &stream, TSvmBitmap &b) ...@@ -419,5 +440,24 @@ CDataStream& operator>>(CDataStream &stream, TSvmBitmap &b)
return stream; return stream;
} }
CDataStream& operator>>(CDataStream &stream, TSvmGradient &g)
{
stream >> g.version;
stream >> g.style;
stream >> g.color1;
stream >> g.color2;
stream >> g.angle;
stream >> g.border;
stream >> g.offX;
stream >> g.offY;
stream >> g.intensityStart;
stream >> g.intensityEnd;
stream >> g.stepCount;
return stream;
}
} }
...@@ -149,6 +149,33 @@ struct TSvmPolygon ...@@ -149,6 +149,33 @@ struct TSvmPolygon
std::vector<TSvmPoint> points; std::vector<TSvmPoint> points;
}; };
struct TSvmColorEx
{
unsigned short name;
unsigned short r;
unsigned short g;
unsigned short b;
};
struct TSvmGradient
{
VersionCompat version;
unsigned short style;
TSvmColorEx color1;
TSvmColorEx color2;
unsigned short angle;
unsigned short border;
unsigned short offX;
unsigned short offY;
unsigned short intensityStart;
unsigned short intensityEnd;
unsigned short stepCount;
};
struct TSvmColor struct TSvmColor
{ {
unsigned char r; unsigned char r;
...@@ -160,15 +187,15 @@ struct TSvmColor ...@@ -160,15 +187,15 @@ struct TSvmColor
TSvmColor() TSvmColor()
{ {
r = 0; g = 0; b = 0; r = 0; g = 0; b = 0; a = 0;
} }
TSvmColor(unsigned char _r, unsigned char _g, unsigned char _b) TSvmColor(unsigned char _r, unsigned char _g, unsigned char _b)
{ {
r = _r; g = _g; b = _b; r = _r; g = _g; b = _b;
} }
void Set(unsigned char _r, unsigned char _g, unsigned char _b) void Set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a = 0)
{ {
r = _r; g = _g; b = _b; r = _r; g = _g; b = _b; a = _a;
} }
void Init() void Init()
{ {
...@@ -232,6 +259,7 @@ public: ...@@ -232,6 +259,7 @@ public:
unsigned int GetStyle(); unsigned int GetStyle();
unsigned int GetHatch(); unsigned int GetHatch();
unsigned int GetAlpha(); unsigned int GetAlpha();
unsigned int GetAlpha2();
std::wstring GetDibPatterPath(){ return L""; } std::wstring GetDibPatterPath(){ return L""; }
void GetBounds(double& left, double& top, double& width, double& height); void GetBounds(double& left, double& top, double& width, double& height);
...@@ -380,9 +408,12 @@ CDataStream& operator>>(CDataStream &stream, TSvmPoint &p); ...@@ -380,9 +408,12 @@ CDataStream& operator>>(CDataStream &stream, TSvmPoint &p);
CDataStream& operator>>(CDataStream &stream, TSvmRect &p); CDataStream& operator>>(CDataStream &stream, TSvmRect &p);
CDataStream& operator>>(CDataStream &stream, TSvmPolygon &p); CDataStream& operator>>(CDataStream &stream, TSvmPolygon &p);
CDataStream& operator>>(CDataStream &stream, TSvmColor &c); CDataStream& operator>>(CDataStream &stream, TSvmColor &c);
CDataStream& operator>>(CDataStream &stream, TSvmColorEx &c);
CDataStream& operator>>(CDataStream &stream, TSvmBitmap &b); CDataStream& operator>>(CDataStream &stream, TSvmBitmap &b);
CDataStream& operator>>(CDataStream &stream, CSvmFont *f); CDataStream& operator>>(CDataStream &stream, CSvmFont *f);
CDataStream& operator>>(CDataStream &stream, TSvmLineInfo &l); CDataStream& operator>>(CDataStream &stream, TSvmLineInfo &l);
CDataStream& operator>>(CDataStream &stream, TSvmGradient &g);
} }
......
...@@ -209,7 +209,7 @@ void CSvmPlayer::SetRasterOp(int op) ...@@ -209,7 +209,7 @@ void CSvmPlayer::SetRasterOp(int op)
} }
void CSvmPlayer::InitStockObjects() void CSvmPlayer::InitStockObjects()
{ {
InitStockBrush(false, 79, 129, 189); //default OnlyOffice InitStockBrush(false, 0x00, 0x00, 0x00, 0xff); //
InitStockPen(false, 0x00, 0x00, 0x00); InitStockPen(false, 0x00, 0x00, 0x00);
} }
void CSvmPlayer::Pop() void CSvmPlayer::Pop()
...@@ -354,7 +354,7 @@ void CSvmPlayer::Push(int nFlags) // ...@@ -354,7 +354,7 @@ void CSvmPlayer::Push(int nFlags) //
// pData->mpRefPoint = NULL; // pData->mpRefPoint = NULL;
//} //}
} }
void CSvmPlayer::InitStockBrush(bool bNull, unsigned char r, unsigned char g, unsigned char b) void CSvmPlayer::InitStockBrush(bool bNull, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{ {
CSvmBrush* pBrush = new CSvmBrush(); CSvmBrush* pBrush = new CSvmBrush();
if (!pBrush) if (!pBrush)
...@@ -365,7 +365,7 @@ void CSvmPlayer::InitStockBrush(bool bNull, unsigned char r, unsigned char g, u ...@@ -365,7 +365,7 @@ void CSvmPlayer::InitStockBrush(bool bNull, unsigned char r, unsigned char g, u
else else
{ {
pBrush->BrushStyle = BS_SOLID; pBrush->BrushStyle = BS_SOLID;
pBrush->Color.Set(r, g, b); pBrush->Color.Set(r, g, b, a);
} }
RegisterObject((CSvmObjectBase*)pBrush); RegisterObject((CSvmObjectBase*)pBrush);
...@@ -403,8 +403,8 @@ CSvmDC::CSvmDC() ...@@ -403,8 +403,8 @@ CSvmDC::CSvmDC()
m_ulMiterLimit = 0; m_ulMiterLimit = 0;
m_ulFillMode = WINDING; m_ulFillMode = WINDING;
m_ulStretchMode = 0; m_ulStretchMode = 0;
m_oWindow.Init(); //m_oWindow.Init();
m_oViewport.Init(); //m_oViewport.Init();
m_dPixelHeight = m_dPixelHeightPrefered = 1; m_dPixelHeight = m_dPixelHeightPrefered = 1;
m_dPixelWidth = m_dPixelWidthPrefered = 1; m_dPixelWidth = m_dPixelWidthPrefered = 1;
...@@ -443,8 +443,8 @@ CSvmDC* CSvmDC::Copy() ...@@ -443,8 +443,8 @@ CSvmDC* CSvmDC::Copy()
pNewDC->m_dPixelHeightPrefered = m_dPixelHeightPrefered; pNewDC->m_dPixelHeightPrefered = m_dPixelHeightPrefered;
pNewDC->m_dPixelWidthPrefered = m_dPixelWidthPrefered; pNewDC->m_dPixelWidthPrefered = m_dPixelWidthPrefered;
pNewDC->m_oWindow.Copy(&m_oWindow); //pNewDC->m_oWindow.Copy(&m_oWindow);
pNewDC->m_oViewport.Copy(&m_oViewport); //pNewDC->m_oViewport.Copy(&m_oViewport);
pNewDC->m_oCurPos = m_oCurPos; pNewDC->m_oCurPos = m_oCurPos;
//pNewDC->m_oClip = m_oClip; //pNewDC->m_oClip = m_oClip;
pNewDC->m_unArcDirection = m_unArcDirection; pNewDC->m_unArcDirection = m_unArcDirection;
...@@ -531,7 +531,8 @@ void CSvmDC::SetMapMode(TSvmMapMode & mapMode, bool prefered ) ...@@ -531,7 +531,8 @@ void CSvmDC::SetMapMode(TSvmMapMode & mapMode, bool prefered )
// //
break; break;
case MAP_RELATIVE: case MAP_RELATIVE:
UpdatePixelMetrics(); SetPixelWidth(dPixel);
SetPixelHeight(dPixel);
break; break;
case MAP_LASTENUMDUMMY: case MAP_LASTENUMDUMMY:
break; break;
...@@ -544,7 +545,6 @@ void CSvmDC::SetMapMode(TSvmMapMode & mapMode, bool prefered ) ...@@ -544,7 +545,6 @@ void CSvmDC::SetMapMode(TSvmMapMode & mapMode, bool prefered )
} }
UpdatePixelMetrics();
} }
TXForm* CSvmDC::GetTransform() TXForm* CSvmDC::GetTransform()
...@@ -672,41 +672,6 @@ void CSvmDC::SetPixelHeight(double dPixelH) ...@@ -672,41 +672,6 @@ void CSvmDC::SetPixelHeight(double dPixelH)
m_dPixelHeight = dPixelH; m_dPixelHeight = dPixelH;
} }
TSvmWindow* CSvmDC::GetWindow()
{
return &m_oWindow;
}
void CSvmDC::SetViewportOff(int lX, int lY)
{
m_oViewport.lX = lX;
m_oViewport.lY = lY;
UpdatePixelMetrics();
}
void CSvmDC::SetViewportExt(int lX, int lY)
{
m_oViewport.ulW = lX;
m_oViewport.ulH = lY;
UpdatePixelMetrics();
}
TSvmWindow* CSvmDC::GetViewport()
{
return &m_oViewport;
}
bool CSvmDC::UpdatePixelMetrics()
{
if (GetMapModeUnit() == MAP_RELATIVE)
{
double dPixelX = 1;//(double)m_oViewport.ulW / (double)m_oWindow.ulW;
double dPixelY = 1;//(double)m_oViewport.ulH / (double)m_oWindow.ulH;
SetPixelWidth(dPixelX);
SetPixelHeight(dPixelY);
}
return true;
}
void CSvmDC::SetRop2Mode(unsigned int& nMode) void CSvmDC::SetRop2Mode(unsigned int& nMode)
{ {
m_ulRop2Mode = nMode; m_ulRop2Mode = nMode;
......
...@@ -36,7 +36,7 @@ public: ...@@ -36,7 +36,7 @@ public:
private: private:
void InitStockObjects(); void InitStockObjects();
void InitStockBrush (bool bNull, unsigned char r, unsigned char g, unsigned char b); void InitStockBrush (bool bNull, unsigned char r, unsigned char g, unsigned char b , unsigned char a);
void InitStockPen (bool bNull, unsigned char r, unsigned char g, unsigned char b); void InitStockPen (bool bNull, unsigned char r, unsigned char g, unsigned char b);
typedef std::map < unsigned int, CSvmObjectBase* > CSvmObjectMap; typedef std::map < unsigned int, CSvmObjectBase* > CSvmObjectMap;
...@@ -94,8 +94,6 @@ public: ...@@ -94,8 +94,6 @@ public:
CSvmPen* GetPen(); CSvmPen* GetPen();
void SetStretchMode(unsigned int& oMode); void SetStretchMode(unsigned int& oMode);
unsigned int GetStretchMode(); unsigned int GetStretchMode();
TSvmWindow* GetWindow();
TSvmWindow* GetViewport();
void SetRop2Mode(unsigned int& nMode); void SetRop2Mode(unsigned int& nMode);
unsigned int GetRop2Mode(); unsigned int GetRop2Mode();
//void SetPalette(CSvmLogPalette* pPalette); //void SetPalette(CSvmLogPalette* pPalette);
...@@ -109,28 +107,6 @@ public: ...@@ -109,28 +107,6 @@ public:
void SetArcDirection(unsigned int unDirection); void SetArcDirection(unsigned int unDirection);
unsigned int GetArcDirection(); unsigned int GetArcDirection();
void SetViewportOff(int lX, int lY);
void SetViewportExt(int lX, int lY);
void SetWindowOff(short shX, short shY)
{
m_oWindow.lX += shX;
m_oWindow.lY += shY;
UpdatePixelMetrics();
}
void SetWindowScale(double dX, double dY)
{
m_oWindow.ulW = (int)(m_oWindow.ulW * dX);
m_oWindow.ulH = (int)(m_oWindow.ulH * dY);
UpdatePixelMetrics();
}
void SetWindowExt(short shW, short shH)
{
m_oWindow.ulW = shW;
m_oWindow.ulH = shH;
UpdatePixelMetrics();
}
double m_dPixelWidth; double m_dPixelWidth;
double m_dPixelHeight; double m_dPixelHeight;
...@@ -143,7 +119,6 @@ private: ...@@ -143,7 +119,6 @@ private:
void SetPixelWidth(double dPixelW); void SetPixelWidth(double dPixelW);
void SetPixelHeight(double dPixelH); void SetPixelHeight(double dPixelH);
bool UpdatePixelMetrics();
CSvmBrush* m_pBrush; CSvmBrush* m_pBrush;
CSvmPen* m_pPen; CSvmPen* m_pPen;
...@@ -162,9 +137,6 @@ private: ...@@ -162,9 +137,6 @@ private:
unsigned int m_ulStretchMode; unsigned int m_ulStretchMode;
unsigned int m_ulRop2Mode; unsigned int m_ulRop2Mode;
TSvmWindow m_oWindow;
TSvmWindow m_oViewport;
TSvmPoint m_oCurPos; TSvmPoint m_oCurPos;
//CSvmClip m_oClip; //CSvmClip m_oClip;
unsigned int m_unArcDirection; unsigned int m_unArcDirection;
......
...@@ -61,11 +61,11 @@ void ConvertFolder(CMetaFile &oMetaFile, std::wstring wsFolderPath, const int nT ...@@ -61,11 +61,11 @@ void ConvertFolder(CMetaFile &oMetaFile, std::wstring wsFolderPath, const int nT
wsFilePath.append(vFiles.at(nIndex)); wsFilePath.append(vFiles.at(nIndex));
if (oMetaFile.LoadFromFile(wsFilePath.c_str())) if (oMetaFile.LoadFromFile(wsFilePath.c_str()))
{ {
std::wstring wsDstFilePath = (wsFilePath.substr(0, wsFilePath.size() - 3)).append(L"bmp"); std::wstring wsDstFilePath = (wsFilePath.substr(0, wsFilePath.size() - 3)).append(L"png");
double w, h, x, y; double w, h, x, y;
oMetaFile.GetBounds(&x, &y, &w, &h); oMetaFile.GetBounds(&x, &y, &w, &h);
oMetaFile.ConvertToRaster(wsDstFilePath.c_str(), 1, w); oMetaFile.ConvertToRaster(wsDstFilePath.c_str(), 4, w);
oMetaFile.Close(); oMetaFile.Close();
} }
......
...@@ -55,6 +55,10 @@ namespace MetaFile ...@@ -55,6 +55,10 @@ namespace MetaFile
} }
unsigned int GetHatch(); unsigned int GetHatch();
unsigned int GetAlpha(); unsigned int GetAlpha();
unsigned int GetAlpha2()
{
return 0xff;
}
std::wstring GetDibPatterPath(); std::wstring GetDibPatterPath();
void GetBounds(double& left, double& top, double& width, double& height) {} void GetBounds(double& left, double& top, double& width, double& height) {}
......
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