Sync TortoiseIDiff and TortoiseUDiff from TortoiseSVN
[TortoiseGit.git] / src / Utils / MiscUI / SVG.cpp
blobbb27cc8bcff0408d1d8d85064979ffc7fb80350b
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2010-2011 - TortoiseSVN
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 #include "stdafx.h"
20 #include "SVG.h"
21 #include "SmartHandle.h"
23 SVG::SVG()
24 : viewportWidth(1000)
25 , viewportHeight(1000)
29 SVG::~SVG()
33 bool SVG::Save( const CString& path )
35 DWORD dwWritten = 0;
36 CAutoFile hFile = CreateFile(path, GENERIC_WRITE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
37 if (!hFile)
38 return false;
40 CStringA header;
41 header.Format("<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"%d\" height=\"%d\" viewBox=\"0 0 %d %d\">\r\n", viewportWidth, viewportHeight, viewportWidth, viewportHeight);
42 CStringA footer = "\r\n</svg>";
44 if (!WriteFile(hFile, header, (DWORD)header.GetLength(), &dwWritten, NULL))
45 return false;
47 for (std::vector<CStringA>::const_iterator it = objects.begin(); it != objects.end(); ++it)
49 if (!WriteFile(hFile, *it, (DWORD)it->GetLength(), &dwWritten, NULL))
50 return false;
51 if (!WriteFile(hFile, "\r\n", (DWORD)2, &dwWritten, NULL))
52 return false;
54 if (!WriteFile(hFile, footer, (DWORD)footer.GetLength(), &dwWritten, NULL))
55 return false;
57 return true;
61 void SVG::RoundedRectangle( int x, int y, int width, int height, Gdiplus::Color stroke, int penWidth, Gdiplus::Color fill, int radius /*= 0*/, int mode )
63 CStringA sObj,tmp;
64 if(mode == 3)
66 sObj.Format("<rect x=\"%d\" y=\"%d\" height=\"%d\" width=\"%d\" rx=\"%d\" ry=\"%d\" style=\"stroke:#%06lx; stroke-width:%d; fill: #%06lx\"/>",
67 x, y, height, width, radius, radius, GetColor(stroke), penWidth, GetColor(fill));
68 }else
70 sObj += "<path d=\"";
71 if(mode & 0x1)
73 tmp.Format("M %d %d a %d %d 0 0 1 %d %d ", x, y+radius, radius, radius, radius, -radius);
74 sObj += tmp;
75 tmp.Format("h %d ", width - 2*radius);
76 sObj += tmp;
77 tmp.Format("a %d %d 0 0 1 %d %d ", radius, radius, radius, radius);
78 sObj += tmp;
79 }else
81 tmp.Format("M %d %d h %d ",x, y, width);
82 sObj += tmp;
85 if(mode & 0x2)
87 tmp.Format("V %d a %d %d 0 0 1 %d %d ", y+height-radius, radius,radius, -radius, radius);
88 sObj += tmp;
89 tmp.Format("h %d a %d %d 0 0 1 %d %d z ", - width + 2* radius, radius,radius, -radius, -radius);
90 sObj += tmp;
92 }else
94 tmp.Format("V %d h %d z ", y+height, -width);
95 sObj += tmp;
97 sObj +=_T("\" ");
98 tmp.Format("style=\"stroke:#%06lx; stroke-width:%d; fill: #%06lx\"/>", GetColor(stroke), penWidth, GetColor(fill));
99 sObj += tmp;
101 objects.push_back(sObj);
104 void SVG::Polygon( const Gdiplus::PointF * points, int numPoints, Gdiplus::Color stroke, int penWidth, Gdiplus::Color fill )
106 CStringA pointstring;
107 CStringA sTemp;
108 for (int i = 0; i < numPoints; ++i)
110 sTemp.Format("%d,%d ", (int)points[i].X, (int)points[i].Y);
111 pointstring += sTemp;
113 pointstring.TrimRight();
115 CStringA sObj;
116 sObj.Format("<polygon points=\"%s\" style=\"stroke:#%06lx; stroke-width:%d; fill:#%06lx;\"/>",
117 (LPCSTR)pointstring, GetColor(stroke), penWidth, GetColor(fill));
119 objects.push_back(sObj);
122 void SVG::DrawPath( const Gdiplus::PointF * points, int numPoints, Gdiplus::Color stroke, int penWidth, Gdiplus::Color fill )
124 CStringA pointstring;
125 CStringA sTemp;
126 for (int i = 0; i < numPoints; ++i)
128 sTemp.Format("%c %d %d ", i==0? 'M':'L', (int)points[i].X, (int)points[i].Y);
129 pointstring += sTemp;
131 pointstring.TrimRight();
133 CStringA sObj;
134 sObj.Format("<path d=\"%s\" style=\"stroke:#%06lx; stroke-width:%d; fill:#%06lx;\"/>",
135 (LPCSTR)pointstring, GetColor(stroke), penWidth, GetColor(fill));
137 objects.push_back(sObj);
140 void SVG::Polyline( const Gdiplus::PointF * points, int numPoints, Gdiplus::Color stroke, int penWidth)
142 CStringA pointstring;
143 CStringA sTemp;
144 for (int i = 0; i < numPoints; ++i)
146 sTemp.Format("%d,%d ", (int)points[i].X, (int)points[i].Y);
147 pointstring += sTemp;
149 pointstring.TrimRight();
151 CStringA sObj;
152 sObj.Format("<polyline points=\"%s\" style=\"stroke:#%06lx; stroke-width:%d; fill:none;\"/>",
153 (LPCSTR)pointstring, GetColor(stroke), penWidth);
155 objects.push_back(sObj);
157 void SVG::GradientRectangle( int x, int y, int width, int height, Gdiplus::Color topColor, Gdiplus::Color bottomColor, Gdiplus::Color stroke )
159 CStringA sObj;
160 sObj.Format(
161 "<g>\
162 <defs>\
163 <linearGradient id=\"linearGradient%d\" \
164 x1=\"0%%\" y1=\"0%%\" \
165 x2=\"0%%\" y2=\"100%%\" \
166 spreadMethod=\"pad\">\
167 <stop offset=\"0%%\" stop-color=\"#%06lx\" stop-opacity=\"1\"/>\
168 <stop offset=\"100%%\" stop-color=\"#%06lx\" stop-opacity=\"1\"/>\
169 </linearGradient>\
170 </defs>\
171 <rect x=\"%d\" y=\"%d\" height=\"%d\" width=\"%d\" style=\"stroke:#%06lx; fill::url(#linearGradient%d)\"/>\
172 </g>",
173 (int)objects.size(), GetColor(topColor), GetColor(bottomColor), x, y, height, width, GetColor(stroke), (int)objects.size());
175 objects.push_back(sObj);
178 void SVG::PolyBezier( const POINT * points, int numPoints, Gdiplus::Color stroke )
180 if (numPoints == 0)
181 return;
183 CStringA pointstring;
184 CStringA sTemp;
185 sTemp.Format("M%d,%d ", points[0].x, points[0].y);
186 pointstring += sTemp;
188 for (int i = 1; i < numPoints; i += 3)
190 sTemp.Format("C%d,%d %d,%d %d,%d", points[i].x, points[i].y, points[i+1].x, points[i+1].y, points[i+2].x, points[i+2].y);
191 pointstring += sTemp;
193 pointstring.TrimRight();
195 CStringA sObj;
196 sObj.Format("<path d=\"%s\" style=\"stroke:#%06lx; fill:none;\"/>",
197 (LPCSTR)pointstring, GetColor(stroke));
199 objects.push_back(sObj);
202 void SVG::Ellipse( int x, int y, int width, int height, Gdiplus::Color stroke, int penWidth, Gdiplus::Color fill )
204 int cx = x + width/2;
205 int cy = y + height/2;
206 int rx = width/2;
207 int ry = height/2;
208 CStringA sObj;
209 sObj.Format("<ellipse cx=\"%d\" cy=\"%d\" rx=\"%d\" ry=\"%d\" style=\"stroke:#%06lx; stroke-width:%d; fill: #%06lx\"/>",
210 cx, cy, rx, ry, GetColor(stroke), penWidth, GetColor(fill));
212 objects.push_back(sObj);
215 void SVG::Text( int x, int y, LPCSTR font, int fontsize, bool italic, bool bold, Gdiplus::Color color, LPCSTR text , int al)
217 CStringA sObj;
218 sObj.Format("<text x=\"%d\" y=\"%d\" \
219 style=\"font-family:%s;\
220 font-size:%dpt;\
221 font-style:%s;\
222 font-weight:%s;\
223 stroke:none;\
224 text-anchor: %s;\
225 fill:#%06lx;\">%s</text>",
226 x, y, font, fontsize, italic ? "italic" : "none", bold ? "bold" : "none",
227 al==SVG::left? "left": al==SVG::middle? "middle": "right",
228 GetColor(color),text);
230 objects.push_back(sObj);
233 DWORD SVG::GetColor( Gdiplus::Color c )
235 return ((DWORD)c.GetRed() << 16) | ((DWORD)c.GetGreen() << 8) | ((DWORD)c.GetBlue());