From 3faa6deed4978daff22d6cb5542faa0c55208e39 Mon Sep 17 00:00:00 2001 From: anna-dingler <98650930+anna-dingler@users.noreply.github.com> Date: Tue, 21 Mar 2023 16:12:02 -0700 Subject: [PATCH] [UWP] Sync release branch with main (#8330) * Switch to gotFocus (#8148) (#8150) * Update custom.props * [UWP] Update custom.props for object model release (#8225) * Update custom.props for object model release * Updated Xcode version (#8222) * removed build step as they are redundant (#8201) * removed build step as they are redundant * added pod installation step Co-authored-by: Joseph Woo * [UWP Renderer] Add a null check to inline action rendering (#8228) * Update custom.props for object model release * Updated Xcode version (#8222) * removed build step as they are redundant (#8201) * removed build step as they are redundant * added pod installation step * Add a null check for inline Actions Co-authored-by: Joseph Woo * [UWP][Infra] Update nuget files for release (#6576) (#8240) * [UWP][Infra] Update nuget files for release (#6576) * Add new nuspec files * Fix nuspec * Update build copy script * Add dependency to renderer * 1.5 website schema explorer updates (#6550) * Updating schema explorer properties * adding tableCell to toc and attempting whitespace fix * indentation fix indentation fix * Removing filtered prop Removing filtered prop - it's auto generated in our build Co-authored-by: RahulAmlekar * Custom.props to 1.0.0 for Object model build * Update dependency version Co-authored-by: Rahul Amlekar Co-authored-by: RahulAmlekar Co-authored-by: Rebecca Muraira * Remove blank lines Co-authored-by: almedina-ms <35784165+almedina-ms@users.noreply.github.com> Co-authored-by: Rahul Amlekar Co-authored-by: RahulAmlekar Co-authored-by: Rebecca Muraira * [UWP Renderer] Parse for SVG width and height (#8256) * WIP: set raster height and width * WIP: add template method * WIP: parse svg for size * Update resources and spacing * update visualizer csproj * Only set height * Resolve PR comments * Remove try catch blocks * [UWP] Remove weak_ref from method headers and pass by value (#8295) * Temp branch * svg updates * Pass by value * Remove temp var * Use make_weak * Fix spacing * Resolve PR comments * Use image properties struct * Resolve PR comments and handle errors * Add test json * Update custom props (#8329) * Update the object model dependency (#8331) --------- Co-authored-by: Joseph Woo Co-authored-by: almedina-ms <35784165+almedina-ms@users.noreply.github.com> Co-authored-by: Rahul Amlekar Co-authored-by: RahulAmlekar Co-authored-by: Rebecca Muraira --- custom.props | 4 +- samples/v1.5/Tests/Image.Svg.json | 65 +++ .../NuGet/AdaptiveCards.Rendering.Uwp.nuspec | 2 +- .../lib/AdaptiveImageRenderer.cpp | 451 +++++++++++++----- source/uwp/SharedRenderer/lib/Util.cpp | 13 + source/uwp/SharedRenderer/lib/Util.h | 2 + source/uwp/SharedRenderer/lib/XamlBuilder.h | 64 ++- .../Symbols/adaptive-card-fixed-height.svg | 24 + .../SharedVisualizer.projitems | 1 + 9 files changed, 478 insertions(+), 148 deletions(-) create mode 100644 samples/v1.5/Tests/Image.Svg.json create mode 100644 source/uwp/SharedVisualizer/Assets/Symbols/adaptive-card-fixed-height.svg diff --git a/custom.props b/custom.props index a24ca7b33c..547e19d673 100644 --- a/custom.props +++ b/custom.props @@ -1,10 +1,10 @@ - 1 + 3 1 - 1.1.0 + 3.1.1 AdaptiveCards diff --git a/samples/v1.5/Tests/Image.Svg.json b/samples/v1.5/Tests/Image.Svg.json new file mode 100644 index 0000000000..2b79c89ff4 --- /dev/null +++ b/samples/v1.5/Tests/Image.Svg.json @@ -0,0 +1,65 @@ +{ + "type": "AdaptiveCard", + "version": "1.5", + "body": [ + { + "type": "Image", + "url": "https://adaptivecards.io/content/adaptive-card.svg", + "size": "small" + }, + { + "type": "Image", + "url": "https://adaptivecards.io/content/adaptive-card.svg", + "height": "70px", + "width": "40px" + }, + { + "type": "Image", + "url": "symbol:adaptive-card-fixed-height.svg", + "backgroundColor": "#000000", + "horizontalAlignment": "right", + "width": "50px", + "style": "person" + }, + { + "type": "Image", + "url": "symbol:adaptive-card-fixed-height.svg", + "backgroundColor": "#000000", + "horizontalAlignment": "right", + "size": "medium" + }, + { + "type": "Image", + "url": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiICBoZWlnaHQ9IjI5NC40IiB2aWV3Qm94PSIwIDAgNzAwLjAwMDAxIDI5NC40MjI1OCI+IAo8c3R5bGU+CiAgCiAgLnRlc3QgewogICAgYW5pbWF0aW9uOiBmYWRlIDNzIGluZmluaXRlIGFsdGVybmF0ZTsgCiAgICAKICB9CiAgCiAgQGtleWZyYW1lcyBmYWRlIHsKICAgIAogICAgZnJvbSB7CiAgICAgIG9wYWNpdHk6IDAKICAgIH0KICAgIAogICAgdG8gewogICAgICAKICAgICAgb3BhY2l0eToxCiAgICB9CiAgICAKICB9CiAgCiAgPC9zdHlsZT4KICAKICA8cGF0aCBjbGFzcz0idGVzdCIgZD0iTTYwMi4yIDEyOC42Yy0xMS43IDIuNy00Mi42IDQuMi00Mi42IDQuMmwtMy44IDEyLjJzMTUuMy0xLjMgMjYuNS0uMmMwIDAgMy42LS4zIDQgNCAuMiA0LjQtLjMgOS0uMyA5cy0uMyAyLjctNCAzLjRjLTQuMy43LTMzLjMgMi0zMy4zIDJMNTQ0IDE3OXMtMS43IDMuNiAyLjIgMi42YzMuNi0xIDM0LTYuOCAzOC02IDQuMiAxIDkgNi44IDcuNiAxMi0xLjYgNi4zLTMyIDI1LjctNTAuNCAyNC40IDAgMC05LjcuNi0xNy44LTEyLjUtNy44LTEyLjUgMi43LTM2IDIuNy0zNnMtNC43LTExLTEuMi0xNWMwIDAgMi0xLjcgOC0yLjJsNy41LTE1LjRzLTguNS41LTEzLjUtNS43Yy00LjYtNi01LTguNi0xLjQtMTAuMiAzLjgtMiAzOS04LjMgNjMuMi03LjUgMCAwIDguNS0xIDE2IDEzLjcgMCAwIDMuNCA2LTIuNiA3LjRNNTExIDE4Ny44Yy0zIDcuMy0xMS4zIDE1LTIxLjMgMTAuMy0xMC4yLTQuOC0yNi4zLTM3LjYtMjYuMy0zNy42cy02LTEyLjItNy4yLTExLjhjMCAwLTEuMy0yLjQtMiAxMS0xIDEzLjMuMiAzOS4yLTUuMyA0My4zLTUgNC0xMSAyLjMtMTQuNC0yLjQtMi44LTQuNy00LTE2LTIuNC0zNS43IDEuOC0xOS43IDYuMy00MC43IDEyLTQ3LjIgNi02LjYgMTAuOC0xLjggMTIuNiAwIDAgMCA3LjcgNyAyMC43IDI3LjdsMi4yIDMuOHMxMS44IDE5LjcgMTMgMTkuNmMwIDAgMSAxIDEuOC4yIDEuMi0uMy44LTYuNy44LTYuN1M0OTMgMTQxIDQ4MiAxMDVjMCAwLTEuNi00LjYtLjUtOSAxLTQgNS4zLTIgNS4zLTJzMTYuNiA4IDI0LjcgMzVjOCAyNyAyLjYgNTEuNS0uNCA1OC44TTQyOS42IDExOC41Yy0xLjYgMi44LTIuMyA2LjctOS4yIDcuOCAwIDAtNjcgNC43LTcwLjMgOS40IDAgMC0yLjIgMi44IDEuNCAzLjUgMy44LjggMTkgMi44IDI2LjIgMy4yIDcuOCAwIDM0IC4yIDQzLjYgMTIgMCAwIDUuNSA1LjYgNS4zIDE4LjMtLjIgMTMtMi41IDE3LjYtNy42IDIyLjMtNS4zIDQuNC01MC43IDI0LjgtODAtNi40IDAgMC0xMy40LTE1IDQuNy0yNi40IDAgMCAxMy04IDQ2LjMgMS4zIDAgMCAxMCAzLjYgOS42IDcuMy0uNiA0LTguMyA4LTE5LjUgNy44LTEwLjgtLjMtMTguOC01LjUtMTcuMi00LjYgMS41LjUtMTEuNy02LjQtMTUuOC0xLjctNCA0LjQtMyA3IDEgOS43IDEwIDUuOCA0OS4zIDMuNyA2MS05LjQgMCAwIDQuNy01LjMtMi40LTkuNi03LTQtMjcuNC02LjUtMzUuMy02LjgtNy41LS40LTM1LjYgMC0zOS44LTcuMyAwIDAtNC01LjIuNC0xOS40IDQuNi0xNSAzNy4zLTIwLjggNTEuNS0yMiAwIDAgMzktMS42IDQ2LjMgNi40IDAgMCAxIDEuOC0uMiA0LjVNMzE5IDIwNi40Yy00LjcgMy41LTE0LjcgMi0xNy42LTItMi44LTMuNS0zLjgtMTcuMy0zLjMtMzkgLjctMjIuMiAxLTQ5LjQgNi01My44IDUtNC4zIDgtLjUgMTAgMi40IDIgMyA0LjYgNi4zIDUgMTMuMi42IDcgMi4zIDQzIDIuMyA0M3MyLjIgMzIuOC0yLjMgMzYuMk0zMjkgODkuNGMtMTMuOCA0LjctMjMuMiAzLjItMzEuMi0uMy0zLjUgNi4zLTUuNiA4LjItOC4yIDguNi00IC40LTcuNS02LTgtOC0uOC0xLjUtMi43LTQuMi0uNC0xMC4zLTcuOC03LTguNC0xNi40LTctMjIuNyAxLjgtNy40IDE1LTM1LjIgNTUtMzguNSAwIDAgMTkuNi0xLjQgMjMgOWguNnMxOSAwIDE4LjYgMTdjMCAxNy0yMSAzOC4yLTQyLjQgNDUuNW0xNy44LTQ4LjdjLTEyLjYgMi0zMiAxOC44LTQxLjMgMzIuNyAxNC4zIDIuNiAzOS4zIDEuNiA1MC41LTIxIDAgMCA1LjMtMTQuMi05LjItMTEuN20tNTUuMyAxMWMtNCA2LjUtNC4yIDEwLjQtMi4zIDEzIDQuNy03IDEzLTE4IDI1LjUtMjYuNi05LjYgMS0xNy43IDUtMjMuMiAxMy42TTYzMi4yIDIwNS43Yy05LjIgMjIuNi0xNyA0NS41LTIxLjUgNzkuOCAwIDAtMSA2LjctNi41IDQuNS01LjUtMi0xNC41LTExLTE2LjUtMjMuNy0yLTE2LjYgNS40LTQ0LjYgMjAuNS03Ni44LTQuNC03LTcuNS0xNy40LTUtMzIgMCAwIDQtMjcgMzEtNTEuNCAwIDAgMy4yLTIuNyA1LTEuOCAyLjIgMSAxLjMgOS42LS41IDE0LTEuNiA0LjItMTMuNiAyNS0xMy42IDI1cy03LjUgMTQuMi01LjQgMjUuM2MxNC4yLTIxLjggNDYuNS02NiA2Ni41LTUyIDEyLjcgOSAxMi43IDM4IDMuMiA1NC44LTcuNSAxMy4zLTI4LjcgNDAuOC01NyAzNC40bTQxLjYtNjhjLTcuNCA4LTIwLjYgMjMuMi0zMSA0My44IDExLTEuMiAyMS43LTcuMyAyNS0xMC40IDUuMy00LjcgMTcuNS0xNy40IDE1LjYtMzQuMiAwIDAtMS4yLTguOC05LjYuOE0yMjYgMjE3LjVjLTM1LjQgMTAuOC02OC44IDUuOC04NyAxLS41IDcuNC0xLjMgMTAuNS0yLjUgMTEuNy0xLjQgMS42LTEzIDguMi0xOS40LTEuMi0yLjgtNC41LTQuMi0xMi42LTUtMjAtNDEtMTguNi02MC00Ni02MC42LTQ3LTEtMS0xMC4zLTEwLjctMS0yMi43IDguNy0xMC44IDM3LjUtMjEuNyA2My4zLTI2IDEtMjIgMy40LTM5IDYuNS00Ni41IDMuNy05IDguNC0xIDEyLjYgNSAzLjQgNC41IDUuNSAyMy44IDUuNyAzOS4yIDE2LjgtLjggMjcgLjQgNDUuNyA0IDI0LjYgNC4yIDQxIDE2LjggMzkuNyAzMS0xLjIgMTQtMTQgMTkuOC0xOSAyMC4yLTUgLjQtMTMtMy4zLTEzLTMuMy01LjYtMi42LS41LTUgNi03LjggNy4yLTMuNSA1LjYtNyA1LjYtNy0yLjYtOC0zNC41LTEzLjMtNjYuMi0xMy4zIDAgMTcuNS43IDQ2LjUgMS4yIDYzLjQgMjIuMiA0LjIgMzguOCAzLjMgMzguOCAzLjNzODEtMi4zIDgzLjMtNTRjMi41LTUxLjgtODEtMTAxLjQtMTQyLjUtMTE3QzU2LjggMTQuNCAyMiAyNS44IDE5IDI3LjNjLTMuMyAxLjYtLjMgMi4yLS4zIDIuMlMyMiAzMCAyOCAzMmM2IDIgMS4yIDUgMS4yIDVDMTguNyA0MC42IDcgMzguNSA0LjcgMzMuN2MtMi4zLTQuNyAxLjUtOSA2LTE1LjMgNC4yLTYuNSA5LTYuMyA5LTYuMyA3Ni0yNi41IDE2OC44IDIxIDE2OC44IDIxIDg2LjggNDMuOCAxMDEuNiA5NS4zIDEwMCAxMTUuMy0xLjQgMTkuNy05IDUzLTYyLjUgNjkuMk01OSAxNDZjLTguNiA0LTIuNiAxMC40LTIuNiAxMC40IDE2LjIgMTcuMyAzNiAyOC4yIDU1IDM1IDIuMi0zMCAyLTQwLjcgMi01NS44Qzg0IDEzNy42IDY3IDE0Mi40IDU5IDE0NiIvPiA8L3N2Zz4=", + "size": "medium" + }, + { + "type": "Image", + "url": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MDAiICBoZWlnaHQ9IjI5NC40IiB2aWV3Qm94PSIwIDAgNzAwLjAwMDAxIDI5NC40MjI1OCI+IAo8c3R5bGU+CiAgCiAgLnRlc3QgewogICAgYW5pbWF0aW9uOiBmYWRlIDNzIGluZmluaXRlIGFsdGVybmF0ZTsgCiAgICAKICB9CiAgCiAgQGtleWZyYW1lcyBmYWRlIHsKICAgIAogICAgZnJvbSB7CiAgICAgIG9wYWNpdHk6IDAKICAgIH0KICAgIAogICAgdG8gewogICAgICAKICAgICAgb3BhY2l0eToxCiAgICB9CiAgICAKICB9CiAgCiAgPC9zdHlsZT4KICAKICA8cGF0aCBjbGFzcz0idGVzdCIgZD0iTTYwMi4yIDEyOC42Yy0xMS43IDIuNy00Mi42IDQuMi00Mi42IDQuMmwtMy44IDEyLjJzMTUuMy0xLjMgMjYuNS0uMmMwIDAgMy42LS4zIDQgNCAuMiA0LjQtLjMgOS0uMyA5cy0uMyAyLjctNCAzLjRjLTQuMy43LTMzLjMgMi0zMy4zIDJMNTQ0IDE3OXMtMS43IDMuNiAyLjIgMi42YzMuNi0xIDM0LTYuOCAzOC02IDQuMiAxIDkgNi44IDcuNiAxMi0xLjYgNi4zLTMyIDI1LjctNTAuNCAyNC40IDAgMC05LjcuNi0xNy44LTEyLjUtNy44LTEyLjUgMi43LTM2IDIuNy0zNnMtNC43LTExLTEuMi0xNWMwIDAgMi0xLjcgOC0yLjJsNy41LTE1LjRzLTguNS41LTEzLjUtNS43Yy00LjYtNi01LTguNi0xLjQtMTAuMiAzLjgtMiAzOS04LjMgNjMuMi03LjUgMCAwIDguNS0xIDE2IDEzLjcgMCAwIDMuNCA2LTIuNiA3LjRNNTExIDE4Ny44Yy0zIDcuMy0xMS4zIDE1LTIxLjMgMTAuMy0xMC4yLTQuOC0yNi4zLTM3LjYtMjYuMy0zNy42cy02LTEyLjItNy4yLTExLjhjMCAwLTEuMy0yLjQtMiAxMS0xIDEzLjMuMiAzOS4yLTUuMyA0My4zLTUgNC0xMSAyLjMtMTQuNC0yLjQtMi44LTQuNy00LTE2LTIuNC0zNS43IDEuOC0xOS43IDYuMy00MC43IDEyLTQ3LjIgNi02LjYgMTAuOC0xLjggMTIuNiAwIDAgMCA3LjcgNyAyMC43IDI3LjdsMi4yIDMuOHMxMS44IDE5LjcgMTMgMTkuNmMwIDAgMSAxIDEuOC4yIDEuMi0uMy44LTYuNy44LTYuN1M0OTMgMTQxIDQ4MiAxMDVjMCAwLTEuNi00LjYtLjUtOSAxLTQgNS4zLTIgNS4zLTJzMTYuNiA4IDI0LjcgMzVjOCAyNyAyLjYgNTEuNS0uNCA1OC44TTQyOS42IDExOC41Yy0xLjYgMi44LTIuMyA2LjctOS4yIDcuOCAwIDAtNjcgNC43LTcwLjMgOS40IDAgMC0yLjIgMi44IDEuNCAzLjUgMy44LjggMTkgMi44IDI2LjIgMy4yIDcuOCAwIDM0IC4yIDQzLjYgMTIgMCAwIDUuNSA1LjYgNS4zIDE4LjMtLjIgMTMtMi41IDE3LjYtNy42IDIyLjMtNS4zIDQuNC01MC43IDI0LjgtODAtNi40IDAgMC0xMy40LTE1IDQuNy0yNi40IDAgMCAxMy04IDQ2LjMgMS4zIDAgMCAxMCAzLjYgOS42IDcuMy0uNiA0LTguMyA4LTE5LjUgNy44LTEwLjgtLjMtMTguOC01LjUtMTcuMi00LjYgMS41LjUtMTEuNy02LjQtMTUuOC0xLjctNCA0LjQtMyA3IDEgOS43IDEwIDUuOCA0OS4zIDMuNyA2MS05LjQgMCAwIDQuNy01LjMtMi40LTkuNi03LTQtMjcuNC02LjUtMzUuMy02LjgtNy41LS40LTM1LjYgMC0zOS44LTcuMyAwIDAtNC01LjIuNC0xOS40IDQuNi0xNSAzNy4zLTIwLjggNTEuNS0yMiAwIDAgMzktMS42IDQ2LjMgNi40IDAgMCAxIDEuOC0uMiA0LjVNMzE5IDIwNi40Yy00LjcgMy41LTE0LjcgMi0xNy42LTItMi44LTMuNS0zLjgtMTcuMy0zLjMtMzkgLjctMjIuMiAxLTQ5LjQgNi01My44IDUtNC4zIDgtLjUgMTAgMi40IDIgMyA0LjYgNi4zIDUgMTMuMi42IDcgMi4zIDQzIDIuMyA0M3MyLjIgMzIuOC0yLjMgMzYuMk0zMjkgODkuNGMtMTMuOCA0LjctMjMuMiAzLjItMzEuMi0uMy0zLjUgNi4zLTUuNiA4LjItOC4yIDguNi00IC40LTcuNS02LTgtOC0uOC0xLjUtMi43LTQuMi0uNC0xMC4zLTcuOC03LTguNC0xNi40LTctMjIuNyAxLjgtNy40IDE1LTM1LjIgNTUtMzguNSAwIDAgMTkuNi0xLjQgMjMgOWguNnMxOSAwIDE4LjYgMTdjMCAxNy0yMSAzOC4yLTQyLjQgNDUuNW0xNy44LTQ4LjdjLTEyLjYgMi0zMiAxOC44LTQxLjMgMzIuNyAxNC4zIDIuNiAzOS4zIDEuNiA1MC41LTIxIDAgMCA1LjMtMTQuMi05LjItMTEuN20tNTUuMyAxMWMtNCA2LjUtNC4yIDEwLjQtMi4zIDEzIDQuNy03IDEzLTE4IDI1LjUtMjYuNi05LjYgMS0xNy43IDUtMjMuMiAxMy42TTYzMi4yIDIwNS43Yy05LjIgMjIuNi0xNyA0NS41LTIxLjUgNzkuOCAwIDAtMSA2LjctNi41IDQuNS01LjUtMi0xNC41LTExLTE2LjUtMjMuNy0yLTE2LjYgNS40LTQ0LjYgMjAuNS03Ni44LTQuNC03LTcuNS0xNy40LTUtMzIgMCAwIDQtMjcgMzEtNTEuNCAwIDAgMy4yLTIuNyA1LTEuOCAyLjIgMSAxLjMgOS42LS41IDE0LTEuNiA0LjItMTMuNiAyNS0xMy42IDI1cy03LjUgMTQuMi01LjQgMjUuM2MxNC4yLTIxLjggNDYuNS02NiA2Ni41LTUyIDEyLjcgOSAxMi43IDM4IDMuMiA1NC44LTcuNSAxMy4zLTI4LjcgNDAuOC01NyAzNC40bTQxLjYtNjhjLTcuNCA4LTIwLjYgMjMuMi0zMSA0My44IDExLTEuMiAyMS43LTcuMyAyNS0xMC40IDUuMy00LjcgMTcuNS0xNy40IDE1LjYtMzQuMiAwIDAtMS4yLTguOC05LjYuOE0yMjYgMjE3LjVjLTM1LjQgMTAuOC02OC44IDUuOC04NyAxLS41IDcuNC0xLjMgMTAuNS0yLjUgMTEuNy0xLjQgMS42LTEzIDguMi0xOS40LTEuMi0yLjgtNC41LTQuMi0xMi42LTUtMjAtNDEtMTguNi02MC00Ni02MC42LTQ3LTEtMS0xMC4zLTEwLjctMS0yMi43IDguNy0xMC44IDM3LjUtMjEuNyA2My4zLTI2IDEtMjIgMy40LTM5IDYuNS00Ni41IDMuNy05IDguNC0xIDEyLjYgNSAzLjQgNC41IDUuNSAyMy44IDUuNyAzOS4yIDE2LjgtLjggMjcgLjQgNDUuNyA0IDI0LjYgNC4yIDQxIDE2LjggMzkuNyAzMS0xLjIgMTQtMTQgMTkuOC0xOSAyMC4yLTUgLjQtMTMtMy4zLTEzLTMuMy01LjYtMi42LS41LTUgNi03LjggNy4yLTMuNSA1LjYtNyA1LjYtNy0yLjYtOC0zNC41LTEzLjMtNjYuMi0xMy4zIDAgMTcuNS43IDQ2LjUgMS4yIDYzLjQgMjIuMiA0LjIgMzguOCAzLjMgMzguOCAzLjNzODEtMi4zIDgzLjMtNTRjMi41LTUxLjgtODEtMTAxLjQtMTQyLjUtMTE3QzU2LjggMTQuNCAyMiAyNS44IDE5IDI3LjNjLTMuMyAxLjYtLjMgMi4yLS4zIDIuMlMyMiAzMCAyOCAzMmM2IDIgMS4yIDUgMS4yIDVDMTguNyA0MC42IDcgMzguNSA0LjcgMzMuN2MtMi4zLTQuNyAxLjUtOSA2LTE1LjMgNC4yLTYuNSA5LTYuMyA5LTYuMyA3Ni0yNi41IDE2OC44IDIxIDE2OC44IDIxIDg2LjggNDMuOCAxMDEuNiA5NS4zIDEwMCAxMTUuMy0xLjQgMTkuNy05IDUzLTYyLjUgNjkuMk01OSAxNDZjLTguNiA0LTIuNiAxMC40LTIuNiAxMC40IDE2LjIgMTcuMyAzNiAyOC4yIDU1IDM1IDIuMi0zMCAyLTQwLjcgMi01NS44Qzg0IDEzNy42IDY3IDE0Mi40IDU5IDE0NiIvPiA8L3N2Zz4=", + "height": "300px", + "width": "300px" + }, + { + "type": "Image", + "url": "symbol:adaptive-card.svg", + "backgroundColor": "#000000", + "horizontalAlignment": "right", + "width": "100px" + }, + { + "type": "Image", + "size": "medium", + "url": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSJhdXRvIiAgaGVpZ2h0PSJhdXRvIiB2aWV3Qm94PSIwIDAgNzAwLjAwMDAxIDI5NC40MjI1OCI+IAo8c3R5bGU+CiAgCiAgLnRlc3QgewogICAgYW5pbWF0aW9uOiBmYWRlIDNzIGluZmluaXRlIGFsdGVybmF0ZTsgCiAgICAKICB9CiAgCiAgQGtleWZyYW1lcyBmYWRlIHsKICAgIAogICAgZnJvbSB7CiAgICAgIG9wYWNpdHk6IDAKICAgIH0KICAgIAogICAgdG8gewogICAgICAKICAgICAgb3BhY2l0eToxCiAgICB9CiAgICAKICB9CiAgCiAgPC9zdHlsZT4KICAKICA8cGF0aCBjbGFzcz0idGVzdCIgZD0iTTYwMi4yIDEyOC42Yy0xMS43IDIuNy00Mi42IDQuMi00Mi42IDQuMmwtMy44IDEyLjJzMTUuMy0xLjMgMjYuNS0uMmMwIDAgMy42LS4zIDQgNCAuMiA0LjQtLjMgOS0uMyA5cy0uMyAyLjctNCAzLjRjLTQuMy43LTMzLjMgMi0zMy4zIDJMNTQ0IDE3OXMtMS43IDMuNiAyLjIgMi42YzMuNi0xIDM0LTYuOCAzOC02IDQuMiAxIDkgNi44IDcuNiAxMi0xLjYgNi4zLTMyIDI1LjctNTAuNCAyNC40IDAgMC05LjcuNi0xNy44LTEyLjUtNy44LTEyLjUgMi43LTM2IDIuNy0zNnMtNC43LTExLTEuMi0xNWMwIDAgMi0xLjcgOC0yLjJsNy41LTE1LjRzLTguNS41LTEzLjUtNS43Yy00LjYtNi01LTguNi0xLjQtMTAuMiAzLjgtMiAzOS04LjMgNjMuMi03LjUgMCAwIDguNS0xIDE2IDEzLjcgMCAwIDMuNCA2LTIuNiA3LjRNNTExIDE4Ny44Yy0zIDcuMy0xMS4zIDE1LTIxLjMgMTAuMy0xMC4yLTQuOC0yNi4zLTM3LjYtMjYuMy0zNy42cy02LTEyLjItNy4yLTExLjhjMCAwLTEuMy0yLjQtMiAxMS0xIDEzLjMuMiAzOS4yLTUuMyA0My4zLTUgNC0xMSAyLjMtMTQuNC0yLjQtMi44LTQuNy00LTE2LTIuNC0zNS43IDEuOC0xOS43IDYuMy00MC43IDEyLTQ3LjIgNi02LjYgMTAuOC0xLjggMTIuNiAwIDAgMCA3LjcgNyAyMC43IDI3LjdsMi4yIDMuOHMxMS44IDE5LjcgMTMgMTkuNmMwIDAgMSAxIDEuOC4yIDEuMi0uMy44LTYuNy44LTYuN1M0OTMgMTQxIDQ4MiAxMDVjMCAwLTEuNi00LjYtLjUtOSAxLTQgNS4zLTIgNS4zLTJzMTYuNiA4IDI0LjcgMzVjOCAyNyAyLjYgNTEuNS0uNCA1OC44TTQyOS42IDExOC41Yy0xLjYgMi44LTIuMyA2LjctOS4yIDcuOCAwIDAtNjcgNC43LTcwLjMgOS40IDAgMC0yLjIgMi44IDEuNCAzLjUgMy44LjggMTkgMi44IDI2LjIgMy4yIDcuOCAwIDM0IC4yIDQzLjYgMTIgMCAwIDUuNSA1LjYgNS4zIDE4LjMtLjIgMTMtMi41IDE3LjYtNy42IDIyLjMtNS4zIDQuNC01MC43IDI0LjgtODAtNi40IDAgMC0xMy40LTE1IDQuNy0yNi40IDAgMCAxMy04IDQ2LjMgMS4zIDAgMCAxMCAzLjYgOS42IDcuMy0uNiA0LTguMyA4LTE5LjUgNy44LTEwLjgtLjMtMTguOC01LjUtMTcuMi00LjYgMS41LjUtMTEuNy02LjQtMTUuOC0xLjctNCA0LjQtMyA3IDEgOS43IDEwIDUuOCA0OS4zIDMuNyA2MS05LjQgMCAwIDQuNy01LjMtMi40LTkuNi03LTQtMjcuNC02LjUtMzUuMy02LjgtNy41LS40LTM1LjYgMC0zOS44LTcuMyAwIDAtNC01LjIuNC0xOS40IDQuNi0xNSAzNy4zLTIwLjggNTEuNS0yMiAwIDAgMzktMS42IDQ2LjMgNi40IDAgMCAxIDEuOC0uMiA0LjVNMzE5IDIwNi40Yy00LjcgMy41LTE0LjcgMi0xNy42LTItMi44LTMuNS0zLjgtMTcuMy0zLjMtMzkgLjctMjIuMiAxLTQ5LjQgNi01My44IDUtNC4zIDgtLjUgMTAgMi40IDIgMyA0LjYgNi4zIDUgMTMuMi42IDcgMi4zIDQzIDIuMyA0M3MyLjIgMzIuOC0yLjMgMzYuMk0zMjkgODkuNGMtMTMuOCA0LjctMjMuMiAzLjItMzEuMi0uMy0zLjUgNi4zLTUuNiA4LjItOC4yIDguNi00IC40LTcuNS02LTgtOC0uOC0xLjUtMi43LTQuMi0uNC0xMC4zLTcuOC03LTguNC0xNi40LTctMjIuNyAxLjgtNy40IDE1LTM1LjIgNTUtMzguNSAwIDAgMTkuNi0xLjQgMjMgOWguNnMxOSAwIDE4LjYgMTdjMCAxNy0yMSAzOC4yLTQyLjQgNDUuNW0xNy44LTQ4LjdjLTEyLjYgMi0zMiAxOC44LTQxLjMgMzIuNyAxNC4zIDIuNiAzOS4zIDEuNiA1MC41LTIxIDAgMCA1LjMtMTQuMi05LjItMTEuN20tNTUuMyAxMWMtNCA2LjUtNC4yIDEwLjQtMi4zIDEzIDQuNy03IDEzLTE4IDI1LjUtMjYuNi05LjYgMS0xNy43IDUtMjMuMiAxMy42TTYzMi4yIDIwNS43Yy05LjIgMjIuNi0xNyA0NS41LTIxLjUgNzkuOCAwIDAtMSA2LjctNi41IDQuNS01LjUtMi0xNC41LTExLTE2LjUtMjMuNy0yLTE2LjYgNS40LTQ0LjYgMjAuNS03Ni44LTQuNC03LTcuNS0xNy40LTUtMzIgMCAwIDQtMjcgMzEtNTEuNCAwIDAgMy4yLTIuNyA1LTEuOCAyLjIgMSAxLjMgOS42LS41IDE0LTEuNiA0LjItMTMuNiAyNS0xMy42IDI1cy03LjUgMTQuMi01LjQgMjUuM2MxNC4yLTIxLjggNDYuNS02NiA2Ni41LTUyIDEyLjcgOSAxMi43IDM4IDMuMiA1NC44LTcuNSAxMy4zLTI4LjcgNDAuOC01NyAzNC40bTQxLjYtNjhjLTcuNCA4LTIwLjYgMjMuMi0zMSA0My44IDExLTEuMiAyMS43LTcuMyAyNS0xMC40IDUuMy00LjcgMTcuNS0xNy40IDE1LjYtMzQuMiAwIDAtMS4yLTguOC05LjYuOE0yMjYgMjE3LjVjLTM1LjQgMTAuOC02OC44IDUuOC04NyAxLS41IDcuNC0xLjMgMTAuNS0yLjUgMTEuNy0xLjQgMS42LTEzIDguMi0xOS40LTEuMi0yLjgtNC41LTQuMi0xMi42LTUtMjAtNDEtMTguNi02MC00Ni02MC42LTQ3LTEtMS0xMC4zLTEwLjctMS0yMi43IDguNy0xMC44IDM3LjUtMjEuNyA2My4zLTI2IDEtMjIgMy40LTM5IDYuNS00Ni41IDMuNy05IDguNC0xIDEyLjYgNSAzLjQgNC41IDUuNSAyMy44IDUuNyAzOS4yIDE2LjgtLjggMjcgLjQgNDUuNyA0IDI0LjYgNC4yIDQxIDE2LjggMzkuNyAzMS0xLjIgMTQtMTQgMTkuOC0xOSAyMC4yLTUgLjQtMTMtMy4zLTEzLTMuMy01LjYtMi42LS41LTUgNi03LjggNy4yLTMuNSA1LjYtNyA1LjYtNy0yLjYtOC0zNC41LTEzLjMtNjYuMi0xMy4zIDAgMTcuNS43IDQ2LjUgMS4yIDYzLjQgMjIuMiA0LjIgMzguOCAzLjMgMzguOCAzLjNzODEtMi4zIDgzLjMtNTRjMi41LTUxLjgtODEtMTAxLjQtMTQyLjUtMTE3QzU2LjggMTQuNCAyMiAyNS44IDE5IDI3LjNjLTMuMyAxLjYtLjMgMi4yLS4zIDIuMlMyMiAzMCAyOCAzMmM2IDIgMS4yIDUgMS4yIDVDMTguNyA0MC42IDcgMzguNSA0LjcgMzMuN2MtMi4zLTQuNyAxLjUtOSA2LTE1LjMgNC4yLTYuNSA5LTYuMyA5LTYuMyA3Ni0yNi41IDE2OC44IDIxIDE2OC44IDIxIDg2LjggNDMuOCAxMDEuNiA5NS4zIDEwMCAxMTUuMy0xLjQgMTkuNy05IDUzLTYyLjUgNjkuMk01OSAxNDZjLTguNiA0LTIuNiAxMC40LTIuNiAxMC40IDE2LjIgMTcuMyAzNiAyOC4yIDU1IDM1IDIuMi0zMCAyLTQwLjcgMi01NS44Qzg0IDEzNy42IDY3IDE0Mi40IDU5IDE0NiIvPiA8L3N2Zz4=" + }, + { + "type": "Image", + "url": "https://adaptivecards.io/content/adaptive-card.svg" + }, + { + "type": "Image", + "backgroundColor": "#eeeeee", + "style": "person", + "url": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSJhdXRvIiAgaGVpZ2h0PSJhdXRvIiB2aWV3Qm94PSIwIDAgNzAwLjAwMDAxIDI5NC40MjI1OCI+IAo8c3R5bGU+CiAgCiAgLnRlc3QgewogICAgYW5pbWF0aW9uOiBmYWRlIDNzIGluZmluaXRlIGFsdGVybmF0ZTsgCiAgICAKICB9CiAgCiAgQGtleWZyYW1lcyBmYWRlIHsKICAgIAogICAgZnJvbSB7CiAgICAgIG9wYWNpdHk6IDAKICAgIH0KICAgIAogICAgdG8gewogICAgICAKICAgICAgb3BhY2l0eToxCiAgICB9CiAgICAKICB9CiAgCiAgPC9zdHlsZT4KICAKICA8cGF0aCBjbGFzcz0idGVzdCIgZD0iTTYwMi4yIDEyOC42Yy0xMS43IDIuNy00Mi42IDQuMi00Mi42IDQuMmwtMy44IDEyLjJzMTUuMy0xLjMgMjYuNS0uMmMwIDAgMy42LS4zIDQgNCAuMiA0LjQtLjMgOS0uMyA5cy0uMyAyLjctNCAzLjRjLTQuMy43LTMzLjMgMi0zMy4zIDJMNTQ0IDE3OXMtMS43IDMuNiAyLjIgMi42YzMuNi0xIDM0LTYuOCAzOC02IDQuMiAxIDkgNi44IDcuNiAxMi0xLjYgNi4zLTMyIDI1LjctNTAuNCAyNC40IDAgMC05LjcuNi0xNy44LTEyLjUtNy44LTEyLjUgMi43LTM2IDIuNy0zNnMtNC43LTExLTEuMi0xNWMwIDAgMi0xLjcgOC0yLjJsNy41LTE1LjRzLTguNS41LTEzLjUtNS43Yy00LjYtNi01LTguNi0xLjQtMTAuMiAzLjgtMiAzOS04LjMgNjMuMi03LjUgMCAwIDguNS0xIDE2IDEzLjcgMCAwIDMuNCA2LTIuNiA3LjRNNTExIDE4Ny44Yy0zIDcuMy0xMS4zIDE1LTIxLjMgMTAuMy0xMC4yLTQuOC0yNi4zLTM3LjYtMjYuMy0zNy42cy02LTEyLjItNy4yLTExLjhjMCAwLTEuMy0yLjQtMiAxMS0xIDEzLjMuMiAzOS4yLTUuMyA0My4zLTUgNC0xMSAyLjMtMTQuNC0yLjQtMi44LTQuNy00LTE2LTIuNC0zNS43IDEuOC0xOS43IDYuMy00MC43IDEyLTQ3LjIgNi02LjYgMTAuOC0xLjggMTIuNiAwIDAgMCA3LjcgNyAyMC43IDI3LjdsMi4yIDMuOHMxMS44IDE5LjcgMTMgMTkuNmMwIDAgMSAxIDEuOC4yIDEuMi0uMy44LTYuNy44LTYuN1M0OTMgMTQxIDQ4MiAxMDVjMCAwLTEuNi00LjYtLjUtOSAxLTQgNS4zLTIgNS4zLTJzMTYuNiA4IDI0LjcgMzVjOCAyNyAyLjYgNTEuNS0uNCA1OC44TTQyOS42IDExOC41Yy0xLjYgMi44LTIuMyA2LjctOS4yIDcuOCAwIDAtNjcgNC43LTcwLjMgOS40IDAgMC0yLjIgMi44IDEuNCAzLjUgMy44LjggMTkgMi44IDI2LjIgMy4yIDcuOCAwIDM0IC4yIDQzLjYgMTIgMCAwIDUuNSA1LjYgNS4zIDE4LjMtLjIgMTMtMi41IDE3LjYtNy42IDIyLjMtNS4zIDQuNC01MC43IDI0LjgtODAtNi40IDAgMC0xMy40LTE1IDQuNy0yNi40IDAgMCAxMy04IDQ2LjMgMS4zIDAgMCAxMCAzLjYgOS42IDcuMy0uNiA0LTguMyA4LTE5LjUgNy44LTEwLjgtLjMtMTguOC01LjUtMTcuMi00LjYgMS41LjUtMTEuNy02LjQtMTUuOC0xLjctNCA0LjQtMyA3IDEgOS43IDEwIDUuOCA0OS4zIDMuNyA2MS05LjQgMCAwIDQuNy01LjMtMi40LTkuNi03LTQtMjcuNC02LjUtMzUuMy02LjgtNy41LS40LTM1LjYgMC0zOS44LTcuMyAwIDAtNC01LjIuNC0xOS40IDQuNi0xNSAzNy4zLTIwLjggNTEuNS0yMiAwIDAgMzktMS42IDQ2LjMgNi40IDAgMCAxIDEuOC0uMiA0LjVNMzE5IDIwNi40Yy00LjcgMy41LTE0LjcgMi0xNy42LTItMi44LTMuNS0zLjgtMTcuMy0zLjMtMzkgLjctMjIuMiAxLTQ5LjQgNi01My44IDUtNC4zIDgtLjUgMTAgMi40IDIgMyA0LjYgNi4zIDUgMTMuMi42IDcgMi4zIDQzIDIuMyA0M3MyLjIgMzIuOC0yLjMgMzYuMk0zMjkgODkuNGMtMTMuOCA0LjctMjMuMiAzLjItMzEuMi0uMy0zLjUgNi4zLTUuNiA4LjItOC4yIDguNi00IC40LTcuNS02LTgtOC0uOC0xLjUtMi43LTQuMi0uNC0xMC4zLTcuOC03LTguNC0xNi40LTctMjIuNyAxLjgtNy40IDE1LTM1LjIgNTUtMzguNSAwIDAgMTkuNi0xLjQgMjMgOWguNnMxOSAwIDE4LjYgMTdjMCAxNy0yMSAzOC4yLTQyLjQgNDUuNW0xNy44LTQ4LjdjLTEyLjYgMi0zMiAxOC44LTQxLjMgMzIuNyAxNC4zIDIuNiAzOS4zIDEuNiA1MC41LTIxIDAgMCA1LjMtMTQuMi05LjItMTEuN20tNTUuMyAxMWMtNCA2LjUtNC4yIDEwLjQtMi4zIDEzIDQuNy03IDEzLTE4IDI1LjUtMjYuNi05LjYgMS0xNy43IDUtMjMuMiAxMy42TTYzMi4yIDIwNS43Yy05LjIgMjIuNi0xNyA0NS41LTIxLjUgNzkuOCAwIDAtMSA2LjctNi41IDQuNS01LjUtMi0xNC41LTExLTE2LjUtMjMuNy0yLTE2LjYgNS40LTQ0LjYgMjAuNS03Ni44LTQuNC03LTcuNS0xNy40LTUtMzIgMCAwIDQtMjcgMzEtNTEuNCAwIDAgMy4yLTIuNyA1LTEuOCAyLjIgMSAxLjMgOS42LS41IDE0LTEuNiA0LjItMTMuNiAyNS0xMy42IDI1cy03LjUgMTQuMi01LjQgMjUuM2MxNC4yLTIxLjggNDYuNS02NiA2Ni41LTUyIDEyLjcgOSAxMi43IDM4IDMuMiA1NC44LTcuNSAxMy4zLTI4LjcgNDAuOC01NyAzNC40bTQxLjYtNjhjLTcuNCA4LTIwLjYgMjMuMi0zMSA0My44IDExLTEuMiAyMS43LTcuMyAyNS0xMC40IDUuMy00LjcgMTcuNS0xNy40IDE1LjYtMzQuMiAwIDAtMS4yLTguOC05LjYuOE0yMjYgMjE3LjVjLTM1LjQgMTAuOC02OC44IDUuOC04NyAxLS41IDcuNC0xLjMgMTAuNS0yLjUgMTEuNy0xLjQgMS42LTEzIDguMi0xOS40LTEuMi0yLjgtNC41LTQuMi0xMi42LTUtMjAtNDEtMTguNi02MC00Ni02MC42LTQ3LTEtMS0xMC4zLTEwLjctMS0yMi43IDguNy0xMC44IDM3LjUtMjEuNyA2My4zLTI2IDEtMjIgMy40LTM5IDYuNS00Ni41IDMuNy05IDguNC0xIDEyLjYgNSAzLjQgNC41IDUuNSAyMy44IDUuNyAzOS4yIDE2LjgtLjggMjcgLjQgNDUuNyA0IDI0LjYgNC4yIDQxIDE2LjggMzkuNyAzMS0xLjIgMTQtMTQgMTkuOC0xOSAyMC4yLTUgLjQtMTMtMy4zLTEzLTMuMy01LjYtMi42LS41LTUgNi03LjggNy4yLTMuNSA1LjYtNyA1LjYtNy0yLjYtOC0zNC41LTEzLjMtNjYuMi0xMy4zIDAgMTcuNS43IDQ2LjUgMS4yIDYzLjQgMjIuMiA0LjIgMzguOCAzLjMgMzguOCAzLjNzODEtMi4zIDgzLjMtNTRjMi41LTUxLjgtODEtMTAxLjQtMTQyLjUtMTE3QzU2LjggMTQuNCAyMiAyNS44IDE5IDI3LjNjLTMuMyAxLjYtLjMgMi4yLS4zIDIuMlMyMiAzMCAyOCAzMmM2IDIgMS4yIDUgMS4yIDVDMTguNyA0MC42IDcgMzguNSA0LjcgMzMuN2MtMi4zLTQuNyAxLjUtOSA2LTE1LjMgNC4yLTYuNSA5LTYuMyA5LTYuMyA3Ni0yNi41IDE2OC44IDIxIDE2OC44IDIxIDg2LjggNDMuOCAxMDEuNiA5NS4zIDEwMCAxMTUuMy0xLjQgMTkuNy05IDUzLTYyLjUgNjkuMk01OSAxNDZjLTguNiA0LTIuNiAxMC40LTIuNiAxMC40IDE2LjIgMTcuMyAzNiAyOC4yIDU1IDM1IDIuMi0zMCAyLTQwLjcgMi01NS44Qzg0IDEzNy42IDY3IDE0Mi40IDU5IDE0NiIvPiA8L3N2Zz4=" + } + ] +} diff --git a/source/uwp/NuGet/AdaptiveCards.Rendering.Uwp.nuspec b/source/uwp/NuGet/AdaptiveCards.Rendering.Uwp.nuspec index 2941a3db17..e32921a888 100644 --- a/source/uwp/NuGet/AdaptiveCards.Rendering.Uwp.nuspec +++ b/source/uwp/NuGet/AdaptiveCards.Rendering.Uwp.nuspec @@ -13,7 +13,7 @@ EULA-Windows.txt © Microsoft Corporation. All rights reserved. - + diff --git a/source/uwp/SharedRenderer/lib/AdaptiveImageRenderer.cpp b/source/uwp/SharedRenderer/lib/AdaptiveImageRenderer.cpp index 6e4e097f9b..37eb08912c 100644 --- a/source/uwp/SharedRenderer/lib/AdaptiveImageRenderer.cpp +++ b/source/uwp/SharedRenderer/lib/AdaptiveImageRenderer.cpp @@ -87,6 +87,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto isVisible = adaptiveCardElement.IsVisible(); winrt::FrameworkElement frameworkElement{nullptr}; + winrt::ImageSource imageSource{nullptr}; // Issue #8125 if (imageStyle == winrt::ImageStyle::Person) @@ -101,8 +102,10 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto ellipseAsShape = ellipse.as(); auto backgrondEllipseAsShape = backgroundEllipse.as(); - SetImageOnUIElement( - imageUrl, ellipse, resourceResolvers, (size == winrt::ImageSize::Auto), parentElement, ellipseAsShape, isVisible, isImageSvg, imageStretch); + auto imgProperties = + ImageProperties{ellipse, (size == winrt::ImageSize::Auto), parentElement, ellipseAsShape, isVisible, isImageSvg, imageStretch}; + + imageSource = SetImageOnUIElement(imageUrl, resourceResolvers, imgProperties); if (size == winrt::ImageSize::None || size == winrt::ImageSize::Stretch || size == winrt::ImageSize::Auto || hasExplicitMeasurements) { @@ -162,8 +165,10 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto parentElement = renderArgs.ParentElement(); - SetImageOnUIElement( - imageUrl, xamlImage, resourceResolvers, (size == winrt::ImageSize::Auto), parentElement, frameworkElement, isVisible, isImageSvg); + auto imgProperties = + ImageProperties{xamlImage, (size == winrt::ImageSize::Auto), parentElement, frameworkElement, isVisible, isImageSvg}; + + imageSource = SetImageOnUIElement(imageUrl, resourceResolvers, imgProperties); } auto sizeOptions = hostConfig.ImageSizes(); @@ -172,6 +177,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering { if (pixelWidth) { + SetRasterizedPixelWidth(imageSource, pixelWidth); if (imageStyle == winrt::ImageStyle::Person) { frameworkElement.Width(pixelWidth); @@ -184,6 +190,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering if (pixelHeight) { + SetRasterizedPixelHeight(imageSource, pixelHeight); if (imageStyle == winrt::ImageStyle::Person) { frameworkElement.Height(pixelHeight); @@ -225,6 +232,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering } frameworkElement.MaxWidth(imageSize); + SetRasterizedPixelWidth(imageSource, imageSize); // We don't want to set a max height on the person ellipse as ellipses do not understand preserving // aspect ratio when constrained on both axes. @@ -271,17 +279,10 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering adaptiveCardElement, selectAction, renderContext, frameworkElement, XamlHelpers::SupportsInteractivity(hostConfig), true); } - template - void XamlBuilder::SetImageOnUIElement( - winrt::Uri const& imageUrl, - T const& uiElement, - winrt::AdaptiveCardResourceResolvers const& resolvers, - bool isAutoSize, - winrt::IInspectable const& parentElement, - winrt::IInspectable const& imageContainer, - bool isVisible, - bool isImageSvg, - winrt::Stretch stretch) + template + winrt::ImageSource XamlBuilder::SetImageOnUIElement(winrt::Uri const& imageUrl, + winrt::AdaptiveCardResourceResolvers const& resolvers, + ImageProperties const& imgProperties) { bool mustHideElement = true; @@ -297,11 +298,11 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering { // Create a Image to hold the image data. We use BitmapImage & SvgImageSource in order to allow // the tracker to subscribe to the ImageLoaded/Failed events - auto image = CreateImageSource(isImageSvg); + auto image = CreateImageSource(imgProperties.isImageSvg); if (!m_enableXamlImageHandling && (m_listeners.size() != 0)) { - if (!isImageSvg) + if (!imgProperties.isImageSvg) { image.as().CreateOptions(winrt::BitmapCreateOptions::None); } @@ -315,8 +316,8 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto getResourceStreamOperation = resolver.GetResourceStreamAsync(args); getResourceStreamOperation.Completed( - [this, weakThis = this->get_weak(), uiElement, image, stretch, isAutoSize, parentElement, imageContainer, isVisible, isImageSvg]( - winrt::IAsyncOperation const& operation, winrt::AsyncStatus status) -> void + [this, weakThis = this->get_weak(), image, imgProperties]( + auto const& operation, auto status) -> void { if (status == winrt::AsyncStatus::Completed) { @@ -328,44 +329,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering this->m_imageLoadTracker->MarkFailedLoadImage(image); return; } - SetImageSource(uiElement, image, stretch); - - if (isImageSvg) - { - auto setSourceOperation = image.as().SetSourceAsync(randomAccessStream); - - setSourceOperation.Completed( - [weakThis, uiElement, isAutoSize, parentElement, imageContainer, isVisible]( - winrt::IAsyncOperation const& operation, winrt::AsyncStatus status) - { - auto loadStatus = operation.GetResults(); - if (status == winrt::AsyncStatus::Completed && isAutoSize && - loadStatus == winrt::SvgImageSourceLoadStatus::Success) - { - if (auto strongThis = weakThis.get()) - { - strongThis->SetAutoSize(uiElement, parentElement, imageContainer, isVisible, false /* imageFiresOpenEvent */); - } - } - }); - } - else - { - auto setSourceAction = image.as().SetSourceAsync(randomAccessStream); - - setSourceAction.Completed( - [weakThis, uiElement, isAutoSize, parentElement, imageContainer, isVisible]( - winrt::IAsyncAction const&, winrt::AsyncStatus status) - { - if (status == winrt::AsyncStatus::Completed && isAutoSize) - { - if (auto strongThis = weakThis.get()) - { - strongThis->SetAutoSize(uiElement, parentElement, imageContainer, isVisible, false /* imageFiresOpenEvent */); - } - } - }); - } + strongThis->HandleAccessStreamForImageSource(imgProperties, randomAccessStream, image); } } else @@ -377,6 +341,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering } } }); + return image; } } @@ -391,9 +356,9 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering dataWriter.WriteBytes(std::vector{decodedData.begin(), decodedData.end()}); - auto image = CreateImageSource(isImageSvg); + auto image = CreateImageSource(imgProperties.isImageSvg); - if (!isImageSvg) + if (!imgProperties.isImageSvg) { image.as().CreateOptions(winrt::BitmapCreateOptions::IgnoreImageCache); } @@ -402,58 +367,24 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto streamWriteOperation = dataWriter.StoreAsync(); streamWriteOperation.Completed( - [weakThis = this->get_weak(), dataWriter, image, uiElement, isAutoSize, parentElement, imageContainer, isVisible, isImageSvg]( - winrt::IAsyncOperation const& /*operation*/, winrt::AsyncStatus /*status*/) -> void + [weakThis = this->get_weak(), dataWriter, image, imgProperties]( + auto const& /*operation*/, auto status) -> void { - if (auto strongThis = weakThis.get()) + if (status == winrt::AsyncStatus::Completed) { - if (const auto stream = dataWriter.DetachStream().try_as()) + if (auto strongThis = weakThis.get()) { - stream.Seek(0); - strongThis->SetImageSource(uiElement, image); - - if (isImageSvg) + if (const auto stream = dataWriter.DetachStream().try_as()) { - auto setSourceOperation = image.as().SetSourceAsync(stream); - - setSourceOperation.Completed( - [weakThis, uiElement, isAutoSize, parentElement, imageContainer, isVisible]( - winrt::IAsyncOperation const& operation, winrt::AsyncStatus status) - { - auto loadStatus = operation.GetResults(); - if (status == winrt::AsyncStatus::Completed && isAutoSize && - loadStatus == winrt::SvgImageSourceLoadStatus::Success) - { - if (auto strongThis = weakThis.get()) - { - strongThis->SetAutoSize(uiElement, parentElement, imageContainer, isVisible, false /* imageFiresOpenEvent */); - } - } - }); - } - else - { - auto setSourceAction = image.as().SetSourceAsync(stream); - - setSourceAction.Completed( - [weakThis, uiElement, isAutoSize, parentElement, imageContainer, isVisible]( - winrt::IAsyncAction const& /*operation*/, winrt::AsyncStatus status) - { - if (status == winrt::AsyncStatus::Completed && isAutoSize) - { - if (auto strongThis = weakThis.get()) - { - strongThis->SetAutoSize(uiElement, parentElement, imageContainer, isVisible, false /* imageFiresOpenEvent */); - } - } - }); + stream.Seek(0); + strongThis->HandleAccessStreamForImageSource(imgProperties, stream, image); } } } }); m_writeAsyncOperations.push_back(streamWriteOperation); mustHideElement = false; - return; + return image; } // Otherwise, no resolver... @@ -461,28 +392,58 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering { // If we've been explicitly told to let Xaml handle the image loading, or there are // no listeners waiting on the image load callbacks, use Xaml to load the images - auto image = CreateImageSource(isImageSvg); + auto image = CreateImageSource(imgProperties.isImageSvg); - if (isImageSvg) + if (imgProperties.isImageSvg) { - image.as().UriSource(imageUrl); + // If we have an SVG, we need to try to parse for the image size before setting the image source + auto svgDocumentLoadOperation = winrt::XmlDocument::LoadFromUriAsync(imageUrl); + + svgDocumentLoadOperation.Completed( + [weakThis = this->get_weak(), + weakImageSource = winrt::make_weak(image.as()), + imageUrl](auto const& operation, auto status) -> void + { + auto strongThis = weakThis.get(); + auto strongImageSource = weakImageSource.get(); + + if (strongThis && strongImageSource) + { + if (status == winrt::AsyncStatus::Completed) + { + auto success = strongThis->ParseXmlForHeightAndWidth(operation.GetResults(), strongImageSource); + + if (success) + { + // Now that we've parsed the height and width successfully, we can set the image source + strongThis->SetSvgUriSource(strongImageSource, imageUrl); + } + } + } + }); } else { image.as().UriSource(imageUrl); } - SetImageSource(uiElement, image, stretch); + SetImageSource(imgProperties.uiElement, image, imgProperties.stretch); // Issue #8126 - if (isAutoSize) + if (imgProperties.isAutoSize) { - SetAutoSize(uiElement, parentElement, imageContainer, isVisible, true /* imageFiresOpenEvent */); + SetAutoSize(imgProperties.uiElement, + imgProperties.parentElement, + imgProperties.imageContainer, + imgProperties.isVisible, + true /* imageFiresOpenEvent */); } + + return image; } else { - PopulateImageFromUrlAsync(imageUrl, uiElement, isImageSvg); + return PopulateImageFromUrlAsync(imageUrl, imgProperties); } } @@ -501,8 +462,9 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering } // Issue #8127 - template - void XamlBuilder::PopulateImageFromUrlAsync(winrt::Uri const& imageUrl, T const& imageControl, bool const& isImageSvg) + template + winrt::ImageSource XamlBuilder::PopulateImageFromUrlAsync(winrt::Uri const& imageUrl, + ImageProperties const& imgProperties) { winrt::HttpBaseProtocolFilter httpBaseProtocolFilter{}; httpBaseProtocolFilter.AllowUI(false); @@ -511,19 +473,18 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering // Create an ImageSource to hold the image data. We use BitmapImage & SvgImageSource in order to allow // the tracker to subscribe to the ImageLoaded/Failed events - auto image = CreateImageSource(isImageSvg); + auto image = CreateImageSource(imgProperties.isImageSvg); this->m_imageLoadTracker->TrackImage(image); - if (!isImageSvg) + if (!imgProperties.isImageSvg) { image.as().CreateOptions(winrt::BitmapCreateOptions::None); } auto getStreamOperation = httpClient.GetInputStreamAsync(imageUrl); getStreamOperation.Completed( - [this, weakThis = this->get_weak(), imageControl]( - winrt::IAsyncOperationWithProgress const& operation, - winrt::AsyncStatus status) -> void + [this, weakThis = this->get_weak(), imgProperties, image]( + auto const& operation, auto status) -> void { if (status == winrt::AsyncStatus::Completed) { @@ -536,16 +497,146 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering m_copyStreamOperations.push_back(copyStreamOperation); copyStreamOperation.Completed( - [randomAccessStream](winrt::IAsyncOperationWithProgress const& /*operation*/, - winrt::AsyncStatus /*status*/) { randomAccessStream.Seek(0); }); + [randomAccessStream, weakThis, imgProperties, image]( + auto const& /*operation*/, auto status) + { + if (status == winrt::AsyncStatus::Completed) + { + randomAccessStream.Seek(0); + if (auto strongThis = weakThis.get()) + { + strongThis->HandleAccessStreamForImageSource( + imgProperties, randomAccessStream, image); + } + } + }); } } }); m_getStreamOperations.push_back(getStreamOperation); + + return image; + } + + template + void XamlBuilder::HandleAccessStreamForImageSource(ImageProperties const& imgProperties, + TStream const& stream, + winrt::ImageSource const& imageSource) + { + SetImageSource(imgProperties.uiElement, imageSource, imgProperties.stretch); + + if (imgProperties.isImageSvg) + { + // If we have an SVG, we need to try to parse for the image size before setting the image source + auto streamSize = stream.Size(); + auto inputStream = stream.GetInputStreamAt(0); + auto streamDataReader = winrt::DataReader(inputStream); + auto loadDataReaderOperation = streamDataReader.LoadAsync((uint32_t)streamSize); + + loadDataReaderOperation.Completed( + [weakThis = this->get_weak(), streamDataReader, streamRef = winrt::make_weak(stream), + imageSourceRef = winrt::make_weak(imageSource.as()), imgProperties]( + auto const& result, auto status) -> void + { + auto strongThis = weakThis.get(); + auto strongImageSource = imageSourceRef.get(); + auto strongStream = streamRef.get(); + + if (strongThis && strongImageSource && strongStream) + { + if (status == winrt::AsyncStatus::Completed) + { + auto bytes = result.GetResults(); + + try + { + auto svgText = streamDataReader.ReadString(bytes); + + if (!svgText.empty()) + { + auto svgDocument = winrt::XmlDocument(); + svgDocument.LoadXml(svgText); + + auto success = strongThis->ParseXmlForHeightAndWidth(svgDocument, strongImageSource); + + if (success) + { + // Now that we've parsed the size, we can set the image source + strongThis->SetSvgImageSourceAsync(strongImageSource, strongStream, imgProperties); + } + } + } + catch (winrt::hresult_error) + { + // There was an error reading the streamDataReader or loading the xml + } + } + } + }); + } + else + { + auto setSourceAction = imageSource.as().SetSourceAsync(stream); + + setSourceAction.Completed([weakThis = this->get_weak(), imgProperties]( + auto const& /*operation*/, auto status) + { + if (status == winrt::AsyncStatus::Completed && imgProperties.isAutoSize) + { + if (auto strongThis = weakThis.get()) + { + strongThis->SetAutoSize(imgProperties.uiElement, + imgProperties.parentElement, + imgProperties.imageContainer, + imgProperties.isVisible, + false /* imageFiresOpenEvent */); + } + } + }); + } + } + + winrt::fire_and_forget XamlBuilder::SetSvgUriSource(winrt::SvgImageSource const imageSource, + winrt::Uri const uri) + { + co_await winrt::resume_foreground(imageSource.Dispatcher()); + imageSource.UriSource(uri); + } + + template + winrt::IAsyncAction XamlBuilder::SetSvgImageSourceAsync(winrt::SvgImageSource const imageSource, + TStream const stream, + ImageProperties const imgProperties) + { + auto weakThis = this->get_weak(); + + co_await winrt::resume_foreground(imageSource.Dispatcher()); + auto setSourceOperation = imageSource.SetSourceAsync(stream); + + setSourceOperation.Completed( + [weakThis, imgProperties]( + auto const& operation, auto status) + { + auto loadStatus = operation.GetResults(); + if (status == winrt::AsyncStatus::Completed && loadStatus == winrt::SvgImageSourceLoadStatus::Success) + { + if (auto strongThis = weakThis.get()) + { + if (imgProperties.isAutoSize) + { + strongThis->SetAutoSize(imgProperties.uiElement, + imgProperties.parentElement, + imgProperties.imageContainer, + imgProperties.isVisible, + false /* imageFiresOpenEvent */); + } + } + } + }); } - template - void XamlBuilder::SetImageSource(T const& destination, winrt::ImageSource const& imageSource, winrt::Stretch /*stretch*/) + template + void XamlBuilder::SetImageSource(TDest const& destination, winrt::ImageSource const& imageSource, winrt::Stretch /*stretch*/) { destination.Source(imageSource); }; @@ -590,7 +681,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto weakParent = winrt::make_weak(parentElement); brushAsImageBrush.ImageOpened( - [ellipse, weakParent, isVisible](winrt::IInspectable const& sender, winrt::RoutedEventArgs /*args*/) -> void + [ellipse, weakParent, isVisible](auto const& sender, auto /*args*/) -> void { if (isVisible) { @@ -616,13 +707,12 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering } } - template - void XamlBuilder::SetAutoSize( - T const& destination, - winrt::IInspectable const& parentElement, - winrt::IInspectable const&, /* imageContainer */ - bool isVisible, - bool imageFiresOpenEvent) + template + void XamlBuilder::SetAutoSize(TDest const& destination, + winrt::IInspectable const& parentElement, + winrt::IInspectable const&, /* imageContainer */ + bool isVisible, + bool imageFiresOpenEvent) { if (parentElement && m_enableXamlImageHandling) { @@ -643,9 +733,7 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto weakImage = winrt::make_weak(xamlImage); xamlImage.ImageOpened( - [weakImage, weakParent, imageSource, isVisible]( - winrt::IInspectable const& /*sender*/, winrt::RoutedEventArgs const& - /*args*/) -> void + [weakImage, weakParent, imageSource, isVisible](auto const& /*sender*/, auto const& /*args*/) -> void { if (const auto lambdaImageAsFrameworkElement = weakImage.get()) { @@ -669,4 +757,107 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering auto foundSvg = url.find("svg"); return !(foundSvg == std::string::npos); } + + bool XamlBuilder::ParseXmlForHeightAndWidth(winrt::XmlDocument const& xmlDoc, + winrt::SvgImageSource const& imageSource) + { + if (xmlDoc) + { + auto rootElement = xmlDoc.DocumentElement(); + + // Root element must be an SVG + if (winrt::operator==(rootElement.NodeName(), L"svg")) + { + auto height = rootElement.GetAttribute(L"height"); + auto width = rootElement.GetAttribute(L"width"); + + // We only need to set height or width, not both (fixes aspect ratio for person style) + bool isHeightSet = false; + + if (!height.empty()) + { + if (auto heightAsDouble = TryHStringToDouble(height)) + { + SetRasterizedPixelHeightAsync(imageSource, heightAsDouble.value()); + isHeightSet = true; + } + } + + if (!width.empty()) + { + if (auto widthAsDouble = TryHStringToDouble(width)) + { + SetRasterizedPixelWidthAsync(imageSource, widthAsDouble.value(), isHeightSet); + } + } + + return true; + } + } + return false; + } + + winrt::fire_and_forget XamlBuilder::SetRasterizedPixelHeightAsync(winrt::SvgImageSource const imageSource, + double const imageSize, + bool const dropIfUnset) + { + co_await winrt::resume_foreground(imageSource.Dispatcher()); + auto currentSize = imageSource.RasterizePixelHeight(); + bool sizeIsUnset = isinf(currentSize); + + // If the size has already been set explicitly, we need to update it with the correct value + // Ex: If `size: small`, the rasterize pixel size will be 40x40 at this point. + // If the actual image is 100x100, we cannot leave it as 100x40 and must set both height and width + bool dropHeight = sizeIsUnset && dropIfUnset; + + if (!dropHeight) + { + imageSource.RasterizePixelHeight(imageSize); + } + } + + winrt::fire_and_forget XamlBuilder::SetRasterizedPixelWidthAsync(winrt::SvgImageSource const imageSource, + double const imageSize, + bool const dropIfUnset) + { + co_await winrt::resume_foreground(imageSource.Dispatcher()); + auto currentSize = imageSource.RasterizePixelWidth(); + bool sizeIsUnset = isinf(currentSize); + + // If the size has already been set explicitly, we need to update it with the correct value + // Ex: If `size: small`, the rasterize pixel size will be 40x40 at this point. + // If the actual image is 100x100, we cannot leave it as 100x40 and must set both height and width + bool dropWidth = sizeIsUnset && dropIfUnset; + + if (!dropWidth) + { + imageSource.RasterizePixelWidth(imageSize); + } + } + + void XamlBuilder::SetRasterizedPixelHeight(winrt::ImageSource const& imageSource, double const& imageSize) { + if (auto image = imageSource.try_as()) + { + auto currentSize = image.RasterizePixelHeight(); + bool sizeIsUnset = isinf(currentSize); + + if (sizeIsUnset) + { + image.RasterizePixelHeight(imageSize); + } + } + } + + void XamlBuilder::SetRasterizedPixelWidth(winrt::ImageSource const& imageSource, double const& imageSize) { + if (auto image = imageSource.try_as()) + { + auto currentSize = image.RasterizePixelWidth(); + bool sizeIsUnset = isinf(currentSize); + + if (sizeIsUnset) + { + image.RasterizePixelWidth(imageSize); + } + } + } } diff --git a/source/uwp/SharedRenderer/lib/Util.cpp b/source/uwp/SharedRenderer/lib/Util.cpp index 9c4aa66773..f185b0e2f9 100644 --- a/source/uwp/SharedRenderer/lib/Util.cpp +++ b/source/uwp/SharedRenderer/lib/Util.cpp @@ -92,6 +92,19 @@ std::string HStringToUTF8(winrt::hstring const& in) return WStringToString(in); } +std::optional TryHStringToDouble(winrt::hstring const& in) +{ + try + { + return std::stod(winrt::to_string(in)); + } + catch (std::invalid_argument) + { + // in was not a valid double + return {}; + } +} + // Get a Color object from color string // Expected formats are "#AARRGGBB" (with alpha channel) and "#RRGGBB" (without alpha channel) winrt::Windows::UI::Color GetColorFromString(const std::string& colorString) diff --git a/source/uwp/SharedRenderer/lib/Util.h b/source/uwp/SharedRenderer/lib/Util.h index eef868c74a..9f17f891f6 100644 --- a/source/uwp/SharedRenderer/lib/Util.h +++ b/source/uwp/SharedRenderer/lib/Util.h @@ -95,6 +95,8 @@ template struct property_opt std::string WStringToString(std::wstring_view in); std::wstring StringToWString(std::string_view in); +std::optional TryHStringToDouble(winrt::hstring const& in); + // This function is needed to deal with the fact that non-windows platforms handle Unicode without the need for wchar_t. // (which has a platform specific implementation) It converts a std::string to an HSTRING. winrt::hstring UTF8ToHString(std::string_view in); diff --git a/source/uwp/SharedRenderer/lib/XamlBuilder.h b/source/uwp/SharedRenderer/lib/XamlBuilder.h index 753f1e6d0e..e4cffc56a7 100644 --- a/source/uwp/SharedRenderer/lib/XamlBuilder.h +++ b/source/uwp/SharedRenderer/lib/XamlBuilder.h @@ -13,6 +13,18 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering public: XamlBuilder(); + template + struct ImageProperties + { + TElement uiElement; + bool isAutoSize; + winrt::IInspectable parentElement; + winrt::IInspectable imageContainer; + bool isVisible; + boolean isImageSvg; + winrt::Stretch stretch = winrt::Stretch::UniformToFill; + }; + // IImageLoadTrackerListener void AllImagesLoaded() override; void ImagesLoadingHadError() override; @@ -54,34 +66,56 @@ namespace AdaptiveCards::Rendering::Xaml_Rendering winrt::AdaptiveRenderArgs const& renderArgs, XamlBuilder* xamlBuilder); - template - void SetAutoSize(T const& destination, + template + void SetAutoSize(TDest const& destination, winrt::IInspectable const& parentElement, winrt::IInspectable const& imageContainer, bool isVisible, bool imageFiresOpenEvent); - template - void SetImageSource(T const& destination, winrt::ImageSource const& imageSource, winrt::Stretch stretch = winrt::Stretch::UniformToFill); + template + void SetImageSource(TDest const& destination, winrt::ImageSource const& imageSource, winrt::Stretch stretch = winrt::Stretch::UniformToFill); - template - void SetImageOnUIElement(winrt::Uri const& imageUrl, - T const& uiElement, - winrt::AdaptiveCardResourceResolvers const& resolvers, - bool isAutoSize, - winrt::IInspectable const& parentElement, - winrt::IInspectable const& imageContainer, - bool isVisible, - bool isImageSvg = false, - winrt::Stretch stretch = winrt::Stretch::UniformToFill); + template + winrt::ImageSource SetImageOnUIElement(winrt::Uri const& imageUrl, + winrt::AdaptiveCardResourceResolvers const& resolvers, + ImageProperties const& imgProperties); winrt::ImageSource CreateImageSource(bool isImageSvg); - template void PopulateImageFromUrlAsync(winrt::Uri const& imageUrl, T const& imageControl, bool const& isImageSvg); + template + winrt::ImageSource PopulateImageFromUrlAsync(winrt::Uri const& imageUrl, + ImageProperties const& imgProperties); + + template + void HandleAccessStreamForImageSource(ImageProperties const& imgProperties, + TStream const& stream, + winrt::ImageSource const& imageSource); + + winrt::fire_and_forget SetSvgUriSource(winrt::SvgImageSource const imageSourceRef, + winrt::Uri const uriRef); + + template + winrt::IAsyncAction SetSvgImageSourceAsync(winrt::SvgImageSource const imageSourceRef, + TStream const streamRef, + ImageProperties const imgProperties); boolean IsSvgImage(std::string url); void FireAllImagesLoaded(); void FireImagesLoadingHadError(); + + bool ParseXmlForHeightAndWidth(winrt::XmlDocument const& xmlDoc, + winrt::SvgImageSource const& imageSourceRef); + + winrt::fire_and_forget SetRasterizedPixelHeightAsync(winrt::SvgImageSource const imageSourceRef, + double const imageSize, + bool const dropIfUnset = false); + winrt::fire_and_forget SetRasterizedPixelWidthAsync(winrt::SvgImageSource const imageSourceRef, + double const imageSize, + bool const dropIfUnset = false); + + void SetRasterizedPixelHeight(winrt::ImageSource const& imageSource, double const& imageSize); + void SetRasterizedPixelWidth(winrt::ImageSource const& imageSource, double const& imageSize); }; } diff --git a/source/uwp/SharedVisualizer/Assets/Symbols/adaptive-card-fixed-height.svg b/source/uwp/SharedVisualizer/Assets/Symbols/adaptive-card-fixed-height.svg new file mode 100644 index 0000000000..cd416bf2e1 --- /dev/null +++ b/source/uwp/SharedVisualizer/Assets/Symbols/adaptive-card-fixed-height.svg @@ -0,0 +1,24 @@ + + + + adaptive_cards + Created with Sketch. + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/uwp/SharedVisualizer/SharedVisualizer.projitems b/source/uwp/SharedVisualizer/SharedVisualizer.projitems index eb14cf30c4..cdadf068c2 100644 --- a/source/uwp/SharedVisualizer/SharedVisualizer.projitems +++ b/source/uwp/SharedVisualizer/SharedVisualizer.projitems @@ -10,6 +10,7 @@ +