@@ -179,33 +179,31 @@ public string GetGraphic(Size viewBox, string darkColorHex, string lightColorHex
179
179
// Output SVG rectangles
180
180
double x = xi * pixelsPerModule;
181
181
if (logo == null || !logo.FillLogoBackground() || !IsBlockedByLogo(x, y, logoAttr, pixelsPerModule))
182
- svgFile.AppendLine($@"<rect x=""{CleanSvgVal(x)}"" y=""{CleanSvgVal(y)}"" width=""{CleanSvgVal(xL * pixelsPerModule)}"" height=""{CleanSvgVal(yL * pixelsPerModule)}"" fill=""{darkColorHex}"" />");
183
-
182
+ svgFile.AppendLine($@"<rect x=""{CleanSvgVal(x)}"" y=""{CleanSvgVal(y)}"" width=""{CleanSvgVal(xL * pixelsPerModule)}"" height=""{CleanSvgVal(yL * pixelsPerModule)}"" fill=""{darkColorHex}"" />");
184
183
}
185
184
}
186
185
}
187
186
188
187
//Render logo, if set
189
188
if (logo != null)
190
- {
191
-
192
- if (logo.GetMediaType() == SvgLogo.MediaType.PNG)
189
+ {
190
+ if (logo.GetMediaType() == SvgLogo.MediaType.PNG || logo.IsEmbedded())
193
191
{
194
192
svgFile.AppendLine($@"<svg width=""100%"" height=""100%"" version=""1.1"" xmlns = ""http://www.w3.org/2000/svg"">");
195
193
svgFile.AppendLine($@"<image x=""{CleanSvgVal(logoAttr.Value.X)}"" y=""{CleanSvgVal(logoAttr.Value.Y)}"" width=""{CleanSvgVal(logoAttr.Value.Width)}"" height=""{CleanSvgVal(logoAttr.Value.Height)}"" xlink:href=""{logo.GetDataUri()}"" />");
194
+ svgFile.AppendLine(@"</svg>");
196
195
}
197
196
else if (logo.GetMediaType() == SvgLogo.MediaType.SVG)
198
197
{
199
- svgFile.AppendLine($@"<svg x=""{CleanSvgVal(logoAttr.Value.X)}"" y=""{CleanSvgVal(logoAttr.Value.Y)}"" width=""{CleanSvgVal(logoAttr.Value.Width)}"" height=""{CleanSvgVal(logoAttr.Value.Height)}"" version=""1.1"" xmlns = ""http://www.w3.org/2000/svg"">");
200
- var rawLogo = (string)logo.GetRawLogo( );
201
- //Remove some attributes from logo, because it would lead to wrong sizing inside our svg wrapper
202
- new List<string>() { "width ", "height", "x", "y" }.ForEach(attr =>
203
- {
204
- rawLogo = Regex.Replace(rawLogo, $@"(?!=<svg[^>]*?) +{attr}=(""[^""]+""|'[^']+')(?=[^>]*>)", "" );
205
- });
206
- svgFile.Append(rawLogo);
198
+ var rawLogo = (string)logo.GetRawLogo();
199
+ var svg = System.Xml.Linq.XDocument.Parse(rawLogo );
200
+ svg.Root.SetAttributeValue("x", CleanSvgVal(logoAttr.Value.X));
201
+ svg.Root.SetAttributeValue("y ", CleanSvgVal(logoAttr.Value.Y));
202
+ svg.Root.SetAttributeValue("width", CleanSvgVal(logoAttr.Value.Width));
203
+ svg.Root.SetAttributeValue("height", CleanSvgVal(logoAttr.Value.Height) );
204
+ svg.Root.SetAttributeValue("shape-rendering", "geometricPrecision");
205
+ svgFile.AppendLine(svg.ToString(System.Xml.Linq.SaveOptions.DisableFormatting).Replace("svg:", ""));
207
206
}
208
- svgFile.AppendLine(@"</svg>");
209
207
}
210
208
211
209
svgFile.Append(@"</svg>");
@@ -267,8 +265,9 @@ public class SvgLogo
267
265
private int _iconSizePercent;
268
266
private bool _fillLogoBackground;
269
267
private object _logoRaw;
268
+ private bool _isEmbedded;
269
+
270
270
271
-
272
271
/// <summary>
273
272
/// Create a logo object to be used in SvgQRCode renderer
274
273
/// </summary>
@@ -289,6 +288,7 @@ public SvgLogo(Bitmap iconRasterized, int iconSizePercent = 15, bool fillLogoBac
289
288
_mediaType = MediaType.PNG;
290
289
_fillLogoBackground = fillLogoBackground;
291
290
_logoRaw = iconRasterized;
291
+ _isEmbedded = false;
292
292
}
293
293
294
294
/// <summary>
@@ -297,13 +297,15 @@ public SvgLogo(Bitmap iconRasterized, int iconSizePercent = 15, bool fillLogoBac
297
297
/// <param name="iconVectorized">Logo to be rendered as SVG/vectorized graphic/string</param>
298
298
/// <param name="iconSizePercent">Degree of percentage coverage of the QR code by the logo</param>
299
299
/// <param name="fillLogoBackground">If true, the background behind the logo will be cleaned</param>
300
- public SvgLogo(string iconVectorized, int iconSizePercent = 15, bool fillLogoBackground = true)
300
+ /// <param name="iconEmbedded">If true, the logo will be expressed as <image>-tag instead of embedding the svg</param>
301
+ public SvgLogo(string iconVectorized, int iconSizePercent = 15, bool fillLogoBackground = true, bool iconEmbedded = false)
301
302
{
302
303
_iconSizePercent = iconSizePercent;
303
304
_logoData = Convert.ToBase64String(Encoding.UTF8.GetBytes(iconVectorized), Base64FormattingOptions.None);
304
305
_mediaType = MediaType.SVG;
305
306
_fillLogoBackground = fillLogoBackground;
306
307
_logoRaw = iconVectorized;
308
+ _isEmbedded = iconEmbedded;
307
309
}
308
310
309
311
/// <summary>
@@ -315,6 +317,16 @@ public object GetRawLogo()
315
317
return _logoRaw;
316
318
}
317
319
320
+ /// <summary>
321
+ /// Defines, if the logo shall be natively embedded.
322
+ /// true=native svg embedding, false=embedding via image-tag
323
+ /// </summary>
324
+ /// <returns></returns>
325
+ public bool IsEmbedded()
326
+ {
327
+ return _isEmbedded;
328
+ }
329
+
318
330
/// <summary>
319
331
/// Returns the media type of the logo
320
332
/// </summary>
0 commit comments