2

In a Delphi 10.4.2 Win32 VCL Application on Windows 10 x64, I use a TWebBrowser component to display local SVG files. The TWebBrowser component has these properties:

object wb1: TWebBrowser
  Left = 0
  Top = 0
  Width = 936
  Height = 578
  Align = alClient
  TabOrder = 0
  SelectedEngine = EdgeIfAvailable
  ExplicitLeft = -214
  ExplicitTop = -61
  ExplicitWidth = 856
  ExplicitHeight = 483
  ControlData = {
    4C00000078580000EB3100000000000000000000000000000000000000000000
    000000004C000000000000000000000001000000E0D057007335CF11AE690800
    2B2E12620A000000000000004C0000000114020000000000C000000000000046
    8000000000000000000000000000000000000000000000000000000000000000
    00000000000000000100000000000000000000000000000000000000}
end

Here I load a local SVG file:

procedure TForm1.FormCreate(Sender: TObject);
begin
  wb1.Navigate('file:///\\Mac\Home\Downloads\test\Vector SVG 2.svg');
end;

The display of the SVG file is very nice, but it is left-aligned in the TWebBrowser client area and it is not shrinked/stretched in the TWebBrowser client area:

enter image description here

So how can I make the SVG file image be centered in the TWebBrowser client area and shrinked/stretched in the TWebBrowser client area?

EDIT: I have followed the advice of @AndreasRejbrand and created this HTML page:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
<img src="Vector SVG 2.svg"
  style="position: absolute; top: 0; left: 0; width: 100%; height: 100%" />
</body>
</html>

This is the source of the "Vector SVG 2" SVG file: Too large to insert here

And this is where I load the HTML file:

procedure TForm1.FormCreate(Sender: TObject);
begin
  wb1.Navigate('file:///\\Mac\Home\Downloads\test\vector.html');
end;

However, the image is still left-aligned and not shrinked (and has no scrollbars anymore):

enter image description here

user1580348
  • 5,721
  • 4
  • 43
  • 105
  • This is an HTML/CSS question. You should make an HTML page that does the rendering the way you want. – Olivier Mar 08 '21 at 14:56

1 Answers1

3

To some extent this depends on the properties of the SVG image. Specifically, it depends on the values of its width, height, preserveAspectRatio, and viewBox parameters.

Consider the following example:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
  width="650" height="650" viewBox="0 0 650 650">
<title>A flower</title>
<!-- Content -->
</svg>

This looks like this in the TWebBrowser:

Screenshot of a VCL application form with a single TWebBrowser on it, displaying a SVG image. The SVG image doesn't fit vertically into the current view and is left-aligned.

We have several options. One thing we can do is change the SVG so it doesn't have a fixed size:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
  width="100%" height="100%" viewBox="0 0 650 650">
<title>A flower</title>
<!-- Content -->
</svg>

Result:

Screenshot of same window. Now the image is proportionally scaled to fix into the view. It is centred horizontally.

Another approach is to create a minimal HTML5 page containing the SVG image.

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
<img src="test.svg"
  style="position: absolute; top: 0; left: 0; width: 100%; height: 100%" />
</body>
</html>

Animation of the window being resized

Here's the SVG: https://privat.rejbrand.se/flower.svg.

If the SVG file doesn't have a viewBox attribute, the approach above doesn't work. One solution -- obviously -- is then to add a viewBox attribute. For example, the OP's file has width="600" height="1050". By adding viewBox="0 0 600 1050" it becomes scalable:

<svg ... width="600" height="1050" viewBox="0 0 600 1050" ... >

Screen recording

Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • Nice example. Just to nitpick: HTML tags should not be self-closed. I know it's common practice, but only XHTML should use them. – Olivier Mar 08 '21 at 15:32
  • @Olivier: True. I'm a huge XML fan, so I tend to do that. But I think all conforming HTML5 UAs need to handle documents with self-closed tags? – Andreas Rejbrand Mar 08 '21 at 15:33
  • According to [this](https://stackoverflow.com/a/3558200/12763954): *"The slash at the end of the start tag is allowed, but has no meaning."* So it looks like it's valid HTML5 indeed. – Olivier Mar 08 '21 at 15:45
  • See my edit of the question: Unfortunately, the image is still left-aligned and not shrinked. – user1580348 Mar 08 '21 at 16:09
  • You should test with IE or Edge first (depending on which one is used by your `TWebBrowser` object). – Olivier Mar 08 '21 at 16:23
  • This is very strange: When I set `WebBrowser1.SelectedEngine = EdgeOnly` then the display remains EMPTY at run-time, ALTHOUGH Ege is installed on my Windows 10 x64 system! – user1580348 Mar 08 '21 at 16:58
  • @user1580348: It is not enough to have the Edge browser installed. You also need a few other things, see http://docwiki.embarcadero.com/RADStudio/Sydney/en/Using_TEdgeBrowser_Component_and_Changes_to_the_TWebBrowser_Component. And even if you follow all of these steps, it might not work. Getting Edge to work in Delphi apps seems very difficult. – Andreas Rejbrand Mar 08 '21 at 17:54
  • An alternative solution is to embed Chromium with [CEF4Delphi](https://github.com/salvadordf/CEF4Delphi). – Olivier Mar 08 '21 at 17:58
  • Yes, that is what I did last time I needed a modern browser control. – Andreas Rejbrand Mar 08 '21 at 17:59
  • @user1580348: What does the SVG file look like (`width`, `height`, `preserveAspectRatio`, `viewBox` attributes)? – Andreas Rejbrand Mar 08 '21 at 18:01
  • @AndreasRejbrand The "Vector SVG 2" SVG contains the attributes `width="600"`, `height="1050`, but NO `ViewBox` attribute neither a `preserveAspectRatio`. – user1580348 Mar 08 '21 at 18:28
  • @user1580348: The lack of a view box complicates things. I'll see what we can do about that. – Andreas Rejbrand Mar 08 '21 at 18:31
  • @AndreasRejbrand I uploaded the SVG here: https://svgshare.com/i/Upj.svg or: https://svgur.com/s/Upj – user1580348 Mar 08 '21 at 18:34
  • @user1580348: Is updating the SVG file an option? – Andreas Rejbrand Mar 08 '21 at 18:37
  • @AndreasRejbrand Updating the SVG file would be an option if it would work with all SVG files. – user1580348 Mar 08 '21 at 18:40
  • @user1580348 Try this: `... ` – Olivier Mar 08 '21 at 19:47
  • @Olivier: That will not preserve the aspect ratio of the SVG (at least not in IE). – Andreas Rejbrand Mar 08 '21 at 19:52
  • @Olivier: Using the OP's SVG file *without* a `viewBox`? – Andreas Rejbrand Mar 08 '21 at 19:53
  • Yes, I took the OP's file. – Olivier Mar 08 '21 at 19:54
  • https://privat.rejbrand.se/svgar.png and https://privat.rejbrand.se/svgar2.png – Andreas Rejbrand Mar 08 '21 at 19:54
  • And even if the AR would be preserved, that approach surely would only *shrink* the image, not *enlarge* it? (Now, the OP's image is very tall so you might not notice that defect if you have a small screen...) – Andreas Rejbrand Mar 08 '21 at 20:03
  • @AndreasRejbrand ATTENTION (!): I have found an SVG which when loaded DIRECTLY in `TWebBrowser.SelectedEngine = IEOnly` (without container HML page) is displayed PERFECTLY like I want: Proportional, Full size, etc.: https://svgur.com/s/Usv What is it that makes this SVG displayed perfectly in the Browser? If I could transfer these properties to any other SVG then I would have a perfect solution! - The only difference with the display in a real browser is that the clock hands don't move. – user1580348 Mar 09 '21 at 18:50
  • @user1580348: You already know this! In my answer, I made an example SVG of a flower. You can see the SVG's source code in the first snippet. Then I write "One thing we can do is change the SVG so it doesn't have a fixed size:". And what do I change? What is the difference between the first snippet and the second snippet of my answer? Well, the second snippet has `width="100%" height="100%" viewBox="0 0 650 650"`, i.e. the full size of the parent view and a defined `viewBox` (constructed from the original width and height). That's what I've been saying all the time! :) – Andreas Rejbrand Mar 09 '21 at 19:12
  • @user1580348: Then my answer continues "*Another* approach is to create an HTML page ... ". However, please notice that *both* approaches require that the SVG has a `viewBox`. – Andreas Rejbrand Mar 09 '21 at 19:14
  • In fact, the second screenshot in my answer is from an Internet Explorer control that has directly loaded the second version of the SVG. – Andreas Rejbrand Mar 09 '21 at 19:21
  • @AndreasRejbrand You are completely right! Now I have to write code to apply this patch to any existing SVG file. In detail, the task is: 1. Extract the SVG tag 2. Parse the attributes of the SVG tag and change them accordingly. Which XML library would you recommend to use for this purpose? The reason I ask is because a specific Microsoft XML library seems to be allergic to certain SVG files. – user1580348 Mar 09 '21 at 20:10
  • @user1580348: Yes, I remember the DOCTYPE (DTD) issue. Unfortunately, I have never worked with any other XML library, so I cannot give you any advice there. One option might be to simply remove the DOCTYPE manually and then pass the result to the XML parser. – Andreas Rejbrand Mar 09 '21 at 21:23