diff --git a/.github/fabricbot.json b/.github/fabricbot.json deleted file mode 100644 index a42cda55ad..0000000000 --- a/.github/fabricbot.json +++ /dev/null @@ -1,2834 +0,0 @@ -{ - "version": "1.0", - "tasks": [ - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssueCommentResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "operator": "not", - "operands": [ - { - "name": "isOpen", - "parameters": {} - } - ] - }, - { - "name": "isAction", - "parameters": { - "action": "created" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/no-recent-activity" - } - }, - { - "operator": "or", - "operands": [ - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-info" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-repro" - } - } - ] - }, - { - "operator": "not", - "operands": [ - { - "name": "noActivitySince", - "parameters": { - "days": 7 - } - } - ] - }, - { - "operator": "not", - "operands": [ - { - "name": "isCloseAndComment", - "parameters": {} - } - ] - }, - { - "name": "isActivitySender", - "parameters": { - "user": { - "type": "author" - } - } - }, - { - "name": "activitySenderHasPermissions", - "parameters": { - "permissions": "none" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issue_comment" - ], - "taskName": "[Idle Issue Management] For issues closed due to inactivity, re-open an issue if issue author posts a reply within 7 days.", - "actions": [ - { - "name": "reopenIssue", - "parameters": {} - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/no-recent-activity" - } - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/needs-info" - } - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/needs-repro" - } - }, - { - "name": "addLabel", - "parameters": { - "label": "status/needs-attention" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssueCommentResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "isAction", - "parameters": { - "action": "created" - } - }, - { - "operator": "not", - "operands": [ - { - "name": "isOpen", - "parameters": {} - } - ] - }, - { - "name": "activitySenderHasPermissions", - "parameters": { - "permissions": "read" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 7 - } - }, - { - "operator": "not", - "operands": [ - { - "name": "isCloseAndComment", - "parameters": {} - } - ] - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issue_comment" - ], - "taskName": "[Closed Issue Management] For issues closed with no activity over 7 days, ask non-contributor to consider opening a new issue instead.", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hello lovely human, thank you for your comment on this issue. Because this issue has been closed for a period of time, please strongly consider opening a new issue linking to this issue instead to ensure better visibility of your comment. Thank you!" - } - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "frequency": [ - { - "weekDay": 0, - "hours": [ - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22 - ], - "timezoneOffset": -8 - }, - { - "weekDay": 1, - "hours": [ - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22 - ], - "timezoneOffset": -8 - }, - { - "weekDay": 2, - "hours": [ - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22 - ], - "timezoneOffset": -8 - }, - { - "weekDay": 3, - "hours": [ - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22 - ], - "timezoneOffset": -8 - }, - { - "weekDay": 4, - "hours": [ - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22 - ], - "timezoneOffset": -8 - }, - { - "weekDay": 5, - "hours": [ - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22 - ], - "timezoneOffset": -8 - }, - { - "weekDay": 6, - "hours": [ - 1, - 4, - 7, - 10, - 13, - 16, - 19, - 22 - ], - "timezoneOffset": -8 - } - ], - "searchTerms": [ - { - "name": "isClosed", - "parameters": {} - }, - { - "name": "noActivitySince", - "parameters": { - "days": 30 - } - }, - { - "name": "isUnlocked", - "parameters": {} - }, - { - "name": "isIssue", - "parameters": {} - } - ], - "taskName": "[Closed Issue Management] Lock issues closed without activity for over 30 days", - "actions": [ - { - "name": "lockIssue", - "parameters": { - "reason": "resolved" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssueCommentResponder", - "version": "1.0", - "config": { - "taskName": "[Idle Issue Management] Replace needs author feedback label with needs attention label when the author comments on an issue", - "conditions": { - "operator": "and", - "operands": [ - { - "name": "isAction", - "parameters": { - "action": "created" - } - }, - { - "operator": "or", - "operands": [ - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-info" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-repro" - } - } - ] - }, - { - "name": "isOpen", - "parameters": {} - }, - { - "operator": "or", - "operands": [ - { - "operator": "and", - "operands": [ - { - "operator": "not", - "operands": [ - { - "name": "activitySenderHasPermissions", - "parameters": { - "permissions": "write" - } - } - ] - }, - { - "operator": "not", - "operands": [ - { - "name": "activitySenderHasPermissions", - "parameters": { - "permissions": "admin" - } - } - ] - } - ] - }, - { - "name": "isActivitySender", - "parameters": { - "user": { - "type": "author" - } - } - } - ] - } - ] - }, - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "status/needs-attention" - } - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/needs-info" - } - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/needs-repro" - } - } - ], - "eventType": "issue", - "eventNames": [ - "issue_comment" - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "taskName": "[Closed Issue Management] Remove no recent activity label from issues", - "conditions": { - "operator": "and", - "operands": [ - { - "operator": "not", - "operands": [ - { - "name": "isAction", - "parameters": { - "action": "closed" - } - } - ] - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/no-recent-activity" - } - } - ] - }, - "actions": [ - { - "name": "removeLabel", - "parameters": { - "label": "status/no-recent-activity" - } - } - ], - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssueCommentResponder", - "version": "1.0", - "config": { - "taskName": "[Idle Issue Management] Remove no recent activity label when an issue is commented on", - "conditions": { - "operator": "and", - "operands": [ - { - "name": "hasLabel", - "parameters": { - "label": "status/no-recent-activity" - } - } - ] - }, - "actions": [ - { - "name": "removeLabel", - "parameters": { - "label": "status/no-recent-activity" - } - } - ], - "eventType": "issue", - "eventNames": [ - "issue_comment" - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "taskName": "[Idle Issue Management] Close stale `status/needs-info` issues", - "frequency": [ - { - "weekDay": 1, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 2, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 3, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 4, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 5, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - } - ], - "searchTerms": [ - { - "name": "isIssue", - "parameters": {} - }, - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-info" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/no-recent-activity" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 3 - } - } - ], - "actions": [ - { - "name": "closeIssue", - "parameters": {} - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "taskName": "[Idle Issue Management] Close stale `status/needs-repro` issues", - "frequency": [ - { - "weekDay": 1, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 2, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 3, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 4, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 5, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - } - ], - "searchTerms": [ - { - "name": "isIssue", - "parameters": {} - }, - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-repro" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/no-recent-activity" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 3 - } - } - ], - "actions": [ - { - "name": "closeIssue", - "parameters": {} - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "taskName": "[Idle Issue Management] Add no recent activity label to `status/needs-info` issues", - "frequency": [ - { - "weekDay": 1, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 2, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 3, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 4, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 5, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - } - ], - "searchTerms": [ - { - "name": "isIssue", - "parameters": {} - }, - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-info" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 4 - } - }, - { - "name": "noLabel", - "parameters": { - "label": "status/no-recent-activity" - } - } - ], - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "status/no-recent-activity" - } - }, - { - "name": "addReply", - "parameters": { - "comment": "This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**. If it *is* closed, feel free to comment when you are able to provide the additional information and we will re-investigate." - } - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "taskName": "[Idle Issue Management] Add no recent activity label to `status/needs-repro` issues", - "frequency": [ - { - "weekDay": 1, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 2, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 3, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 4, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - }, - { - "weekDay": 5, - "hours": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23 - ] - } - ], - "searchTerms": [ - { - "name": "isIssue", - "parameters": {} - }, - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/needs-repro" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 4 - } - }, - { - "name": "noLabel", - "parameters": { - "label": "status/no-recent-activity" - } - } - ], - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "status/no-recent-activity" - } - }, - { - "name": "addReply", - "parameters": { - "comment": "This issue has been automatically marked as stale because it has been marked as requiring author feedback to reproduce the issue but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**. If it *is* closed, feel free to comment when you are able to provide the additional information and we will re-investigate." - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "PullRequestResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "isAction", - "parameters": { - "action": "opened" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "dotnet-maestro[bot]", - "association": "CONTRIBUTOR" - } - }, - { - "name": "titleContains", - "parameters": { - "titlePattern": "Update dependencies" - } - } - ] - }, - "eventType": "pull_request", - "eventNames": [ - "pull_request", - "issues", - "project_card" - ], - "taskName": "[Infrastructure PRs] Add area-infrastructure label to dependency update Pull Requests", - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "area/infrastructure 🏗️" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "addedToMilestone", - "parameters": { - "milestoneName": "Backlog" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Comment: Issue moved to Backlog", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time." - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "PullRequestResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "status/needs-info" - } - } - ] - }, - "eventType": "pull_request", - "eventNames": [ - "pull_request", - "issues", - "project_card" - ], - "taskName": "Replace `status/needs-info` with `status/pr-needs-author-input` for PRs", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hello. I see that you've just added `status/needs-info` label to this PR.\nThat label is for Issues and not for PRs. Don't worry, I'm going to replace it with the correct one." - } - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/needs-info" - } - }, - { - "name": "addLabel", - "parameters": { - "label": "status/pr-needs-author-input" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "PullRequestResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "status/needs-repro" - } - } - ] - }, - "eventType": "pull_request", - "eventNames": [ - "pull_request", - "issues", - "project_card" - ], - "taskName": "Remove `status/needs-repro` from PRs", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hello. I see that you've just added `status/needs-repro` label to this PR.\nThat label is for Issues and not for PRs, so I removed it." - } - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/needs-repro" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "status/needs-info" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Add comment when `status/needs-info` is applied to issue", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hi @${issueAuthor}. We have added the `status/needs-info` label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time." - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "status/needs-repro" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Add comment when `status/needs-repro` is applied to issue", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hi @${issueAuthor}. We have added the `status/needs-repro` label to this issue, which indicates that we require steps and sample code to reproduce the issue before we can take further action. Please try to create a minimal sample project/solution or code samples which reproduce the issue, ideally as a GitHub repo that we can clone.\n\nThis issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time." - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "or", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "control-newcontrol" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-general" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-webview" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-datetimepicker" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-picker" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-switch" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-dualscreen" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-checkbox" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-border" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-label" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-button" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-dialogalert" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-entry" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-frame" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-stepper" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-refreshview" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-image" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-activityindicator" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-radiobutton" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-slider" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-progressbar" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-pages" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-map" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Add area/controls label when any 'control-X' label is applied to the issue", - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "area/controls 🎮" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "PullRequestResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "or", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "control-newcontrol" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-general" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-webview" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-datetimepicker" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-picker" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-switch" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-dualscreen" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-checkbox" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-border" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-label" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-button" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-dialogalert" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-entry" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-frame" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-stepper" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-refreshview" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-image" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-activityindicator" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-radiobutton" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-slider" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-progressbar" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-pages" - } - }, - { - "name": "labelAdded", - "parameters": { - "label": "control-map" - } - } - ] - }, - "eventType": "pull_request", - "eventNames": [ - "pull_request", - "issues", - "project_card" - ], - "taskName": "Add area/controls label when any 'control-X' label is applied to the PR", - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "area/controls 🎮" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "isAction", - "parameters": { - "action": "opened" - } - }, - { - "operator": "or", - "operands": [ - { - "name": "isActivitySender", - "parameters": { - "user": "alexeystrakh" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "alexkblount" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "BenBtg" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "DeanFaizal" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "jgold6" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "jmongaras" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "jonlipsky" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "JoonghyunCho" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "juanlao" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "migueBarrera" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "mikeparker104" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "myroot" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "rookiejava" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "shyunMin" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "sung-su" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "Sweekriti91" - } - } - ] - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Add 'partner' label when issue is opened by a partner", - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "partner" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "labelAdded", - "parameters": { - "label": "status/move-to-vs-feedback" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Ask user to use VS Feedback for VS issues", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Thanks for the issue report @${issueAuthor}! This issue appears to be a problem with Visual Studio, so we ask that you use the VS feedback tool to report the issue. That way it will get to the routed to the team that owns this experience in VS.\n\nIf you encounter a problem with Visual Studio, we want to know about it so that we can diagnose and fix it. By using the Report a Problem tool, you can collect detailed information about the problem, and send it to Microsoft with just a few button clicks.\n\n1. Go to the [VS feedback tool](https://docs.microsoft.com/visualstudio/ide/how-to-report-a-problem-with-visual-studio?view=vs-2022) to report the issue\n2. Close this bug, and consider adding a link to the VS Feedback issue so that others can follow its activity there.\n\nThis issue will be automatically closed in 3 days if there are no further comments." - } - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "frequency": [ - { - "weekDay": 0, - "hours": [ - 0, - 6, - 12, - 18 - ] - }, - { - "weekDay": 1, - "hours": [ - 0, - 6, - 12, - 18 - ] - }, - { - "weekDay": 2, - "hours": [ - 0, - 6, - 12, - 18 - ] - }, - { - "weekDay": 3, - "hours": [ - 0, - 6, - 12, - 18 - ] - }, - { - "weekDay": 4, - "hours": [ - 0, - 6, - 12, - 18 - ] - }, - { - "weekDay": 5, - "hours": [ - 0, - 6, - 12, - 18 - ] - }, - { - "weekDay": 6, - "hours": [ - 0, - 6, - 12, - 18 - ] - } - ], - "searchTerms": [ - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/move-to-vs-feedback" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 3 - } - } - ], - "taskName": "Close `status/move-to-vs-feedback` after 3 days of no activity", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "This issue is being closed due to inactivity. If this issue is still affecting you, please follow the steps above to use the VS Feedback Tool to report the issue." - } - }, - { - "name": "closeIssue", - "parameters": {} - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssueCommentResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "isAction", - "parameters": { - "action": "created" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/move-to-vs-feedback" - } - }, - { - "operator": "not", - "operands": [ - { - "name": "noActivitySince", - "parameters": { - "days": 3 - } - } - ] - }, - { - "operator": "not", - "operands": [ - { - "name": "isCloseAndComment", - "parameters": {} - } - ] - }, - { - "name": "isActivitySender", - "parameters": { - "user": { - "type": "author" - } - } - }, - { - "name": "activitySenderHasPermissions", - "parameters": { - "permissions": "none" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issue_comment" - ], - "taskName": "For issues labeled with `status/move-to-vs-feedback` mark as `status/needs-attention` if there is activity", - "actions": [ - { - "name": "removeLabel", - "parameters": { - "label": "status/move-to-vs-feedback" - } - }, - { - "name": "addLabel", - "parameters": { - "label": "status/needs-attention" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "isAction", - "parameters": { - "user": "roubachof", - "action": "opened" - } - }, - { - "operator": "or", - "operands": [ - { - "name": "isActivitySender", - "parameters": { - "user": "roubachof" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": "davidbritch" - } - } - ] - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Add 'i/great-reporter' when issue is opened by an author we know opens high quality issues", - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "i/great-reporter" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "IssuesOnlyResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "status/try-latest-version" - } - } - ] - }, - "eventType": "issue", - "eventNames": [ - "issues", - "project_card" - ], - "taskName": "Add comment when `status/try-latest-version` is applied to the issue", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hi @${issueAuthor}. We have added the `status/try-latest-version` label to this issue, which indicates that we'd like you to try and reproduce this issue on the latest available public version. This can happen because we think that this issue was fixed in a version that has just been released, or the information provided by you indicates that you might be working with an older version.\n\nIf the issue still persists, please let us know with any additional details and ideally a reproduction project provided through a GitHub repository.\n\nThis issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time." - } - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "frequency": [ - { - "weekDay": 0, - "hours": [ - 3, - 15 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 1, - "hours": [ - 3, - 15 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 2, - "hours": [ - 3, - 15 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 3, - "hours": [ - 3, - 15 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 4, - "hours": [ - 3, - 15 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 5, - "hours": [ - 3, - 15 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 6, - "hours": [ - 3, - 15 - ], - "timezoneOffset": 2 - } - ], - "searchTerms": [ - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/try-latest-version" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 7 - } - } - ], - "taskName": "[Idle Issue Management] Close stale `status/try-latest-version` issues", - "actions": [ - { - "name": "closeIssue", - "parameters": {} - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "PullRequestResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "activitySenderHasPermissions", - "parameters": { - "permissions": "read" - } - }, - { - "operator": "not", - "operands": [ - { - "name": "isActivitySender", - "parameters": { - "user": "dotnet-maestro" - } - } - ] - }, - { - "operator": "not", - "operands": [ - { - "name": "isActivitySender", - "parameters": { - "user": "dotnet-maestro-bot" - } - } - ] - }, - { - "name": "isAction", - "parameters": { - "action": "opened" - } - } - ] - }, - "eventType": "pull_request", - "eventNames": [ - "pull_request", - "issues", - "project_card" - ], - "taskName": "Add 'community ✨' label to community contributions", - "actions": [ - { - "name": "addLabel", - "parameters": { - "label": "community ✨" - } - }, - { - "name": "addReactionToIssue", - "parameters": { - "reaction": "heart" - } - }, - { - "name": "addReply", - "parameters": { - "comment": "Hey there @${issueAuthor}! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed." - } - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "frequency": [ - { - "weekDay": 0, - "hours": [ - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 1, - "hours": [ - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 2, - "hours": [ - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 3, - "hours": [ - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 4, - "hours": [ - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 5, - "hours": [ - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 6, - "hours": [ - 2, - 5, - 8, - 11, - 14, - 17, - 20, - 23 - ], - "timezoneOffset": 2 - } - ], - "searchTerms": [ - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "isPr", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/pr-needs-author-input" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 10 - } - }, - { - "name": "noLabel", - "parameters": { - "label": "stale" - } - } - ], - "taskName": "Stale PR reminder", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hi @${issueAuthor}.\nIt seems you haven't touched this PR for the last two weeks. To avoid accumulating old PRs, we're marking it as `stale`. As a result, it will be closed if no further activity occurs **within 4 days of this comment**." - } - }, - { - "name": "addLabel", - "parameters": { - "label": "stale" - } - } - ] - } - }, - { - "taskType": "scheduled", - "capabilityId": "ScheduledSearch", - "subCapability": "ScheduledSearch", - "version": "1.1", - "config": { - "frequency": [ - { - "weekDay": 0, - "hours": [ - 3, - 7, - 11, - 15, - 19, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 1, - "hours": [ - 3, - 7, - 11, - 15, - 19, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 2, - "hours": [ - 3, - 7, - 11, - 15, - 19, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 3, - "hours": [ - 3, - 7, - 11, - 15, - 19, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 4, - "hours": [ - 3, - 7, - 11, - 15, - 19, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 5, - "hours": [ - 3, - 7, - 11, - 15, - 19, - 23 - ], - "timezoneOffset": 2 - }, - { - "weekDay": 6, - "hours": [ - 3, - 7, - 11, - 15, - 19, - 23 - ], - "timezoneOffset": 2 - } - ], - "searchTerms": [ - { - "name": "isOpen", - "parameters": {} - }, - { - "name": "isPr", - "parameters": {} - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/pr-needs-author-input" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "stale" - } - }, - { - "name": "noActivitySince", - "parameters": { - "days": 4 - } - } - ], - "taskName": "Close stale PRs", - "actions": [ - { - "name": "closeIssue", - "parameters": {} - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "PullRequestResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "hasLabel", - "parameters": { - "label": "stale" - } - }, - { - "name": "hasLabel", - "parameters": { - "label": "status/pr-needs-author-input" - } - }, - { - "name": "isActivitySender", - "parameters": { - "user": { - "type": "author" - } - } - }, - { - "operator": "not", - "operands": [ - { - "name": "activitySenderHasPermissions", - "parameters": { - "permissions": "write" - } - } - ] - } - ] - }, - "eventType": "pull_request", - "eventNames": [ - "pull_request", - "issues", - "project_card" - ], - "taskName": "Revitalize stale PR and reopen", - "actions": [ - { - "name": "reopenIssue", - "parameters": {} - }, - { - "name": "removeLabel", - "parameters": { - "label": "stale" - } - }, - { - "name": "removeLabel", - "parameters": { - "label": "status/pr-needs-author-input" - } - } - ] - } - }, - { - "taskType": "trigger", - "capabilityId": "IssueResponder", - "subCapability": "PullRequestResponder", - "version": "1.0", - "config": { - "conditions": { - "operator": "and", - "operands": [ - { - "name": "labelAdded", - "parameters": { - "label": "status/pr-needs-author-input" - } - } - ] - }, - "eventType": "pull_request", - "eventNames": [ - "pull_request", - "issues", - "project_card" - ], - "taskName": "Add comment when `status/pr-needs-author-input` is applied to PR", - "actions": [ - { - "name": "addReply", - "parameters": { - "comment": "Hi @${issueAuthor}. We have added the `status/pr-needs-author-input` label to this issue, which indicates that we have an open question/action for you before we can take further action. This PRwill be closed automatically in 14 days if we do not hear back from you by then - please feel free to re-open it if you come back to this PR after that time." - } - } - ] - } - } - ], - "userGroups": [] -} \ No newline at end of file diff --git a/.github/policies/resourceManagement.yml b/.github/policies/resourceManagement.yml new file mode 100644 index 0000000000..5dc7e5b351 --- /dev/null +++ b/.github/policies/resourceManagement.yml @@ -0,0 +1,562 @@ +id: +name: GitOps.PullRequestIssueManagement +description: GitOps.PullRequestIssueManagement primitive +owner: +resource: repository +disabled: false +where: +configuration: + resourceManagementConfiguration: + scheduledSearches: + - description: '[Idle Issue Management] Close stale `status/needs-info` issues' + frequencies: + - weekday: + day: Monday + time: 0:0 + - weekday: + day: Tuesday + time: 0:0 + - weekday: + day: Wednesday + time: 0:0 + - weekday: + day: Thursday + time: 0:0 + - weekday: + day: Friday + time: 0:0 + filters: + - isIssue + - isOpen + - hasLabel: + label: status/needs-info + - hasLabel: + label: status/no-recent-activity + - noActivitySince: + days: 3 + actions: + - closeIssue + - description: '[Idle Issue Management] Close stale `status/needs-repro` issues' + frequencies: + - weekday: + day: Monday + time: 0:0 + - weekday: + day: Tuesday + time: 0:0 + - weekday: + day: Wednesday + time: 0:0 + - weekday: + day: Thursday + time: 0:0 + - weekday: + day: Friday + time: 0:0 + filters: + - isIssue + - isOpen + - hasLabel: + label: status/needs-repro + - hasLabel: + label: status/no-recent-activity + - noActivitySince: + days: 3 + actions: + - closeIssue + - description: '[Idle Issue Management] Add no recent activity label to `status/needs-info` issues' + frequencies: + - weekday: + day: Monday + time: 0:0 + - weekday: + day: Tuesday + time: 0:0 + - weekday: + day: Wednesday + time: 0:0 + - weekday: + day: Thursday + time: 0:0 + - weekday: + day: Friday + time: 0:0 + filters: + - isIssue + - isOpen + - hasLabel: + label: status/needs-info + - noActivitySince: + days: 4 + - isNotLabeledWith: + label: status/no-recent-activity + actions: + - addLabel: + label: status/no-recent-activity + - addReply: + reply: This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**. If it *is* closed, feel free to comment when you are able to provide the additional information and we will re-investigate. + - description: '[Idle Issue Management] Add no recent activity label to `status/needs-repro` issues' + frequencies: + - weekday: + day: Monday + time: 0:0 + - weekday: + day: Tuesday + time: 0:0 + - weekday: + day: Wednesday + time: 0:0 + - weekday: + day: Thursday + time: 0:0 + - weekday: + day: Friday + time: 0:0 + filters: + - isIssue + - isOpen + - hasLabel: + label: status/needs-repro + - noActivitySince: + days: 4 + - isNotLabeledWith: + label: status/no-recent-activity + actions: + - addLabel: + label: status/no-recent-activity + - addReply: + reply: This issue has been automatically marked as stale because it has been marked as requiring author feedback to reproduce the issue but has not had any activity for **4 days**. It will be closed if no further activity occurs **within 3 days of this comment**. If it *is* closed, feel free to comment when you are able to provide the additional information and we will re-investigate. + - description: Close `status/move-to-vs-feedback` after 3 days of no activity + frequencies: + - hourly: + hour: 6 + filters: + - isOpen + - hasLabel: + label: status/move-to-vs-feedback + - noActivitySince: + days: 3 + actions: + - addReply: + reply: This issue is being closed due to inactivity. If this issue is still affecting you, please follow the steps above to use the VS Feedback Tool to report the issue. + - closeIssue + - description: '[Idle Issue Management] Close stale `status/try-latest-version` issues' + frequencies: + - hourly: + hour: 12 + filters: + - isOpen + - hasLabel: + label: status/try-latest-version + - noActivitySince: + days: 7 + actions: + - closeIssue + - description: Stale PR reminder + frequencies: + - hourly: + hour: 3 + filters: + - isOpen + - isPullRequest + - hasLabel: + label: status/pr-needs-author-input + - noActivitySince: + days: 10 + - isNotLabeledWith: + label: stale + actions: + - addReply: + reply: >- + Hi @${issueAuthor}. + + It seems you haven't touched this PR for the last two weeks. To avoid accumulating old PRs, we're marking it as `stale`. As a result, it will be closed if no further activity occurs **within 4 days of this comment**. + - addLabel: + label: stale + - description: Close stale PRs + frequencies: + - hourly: + hour: 4 + filters: + - isOpen + - isPullRequest + - hasLabel: + label: status/pr-needs-author-input + - hasLabel: + label: stale + - noActivitySince: + days: 4 + actions: + - closeIssue + eventResponderTasks: + - if: + - payloadType: Issue_Comment + - isAction: + action: Created + - or: + - hasLabel: + label: status/needs-info + - hasLabel: + label: status/needs-repro + - isOpen + - or: + - and: + - not: + activitySenderHasPermission: + permission: Write + - not: + activitySenderHasPermission: + permission: Admin + - isActivitySender: + issueAuthor: True + then: + - addLabel: + label: status/needs-attention + - removeLabel: + label: status/needs-info + - removeLabel: + label: status/needs-repro + description: '[Idle Issue Management] Replace needs author feedback label with needs attention label when the author comments on an issue' + - if: + - payloadType: Issues + - not: + isAction: + action: Closed + - hasLabel: + label: status/no-recent-activity + then: + - removeLabel: + label: status/no-recent-activity + description: '[Closed Issue Management] Remove no recent activity label from issues' + - if: + - payloadType: Issue_Comment + - hasLabel: + label: status/no-recent-activity + then: + - removeLabel: + label: status/no-recent-activity + description: '[Idle Issue Management] Remove no recent activity label when an issue is commented on' + - if: + - payloadType: Pull_Request + - isAction: + action: Opened + - isActivitySender: + user: dotnet-maestro[bot] + issueAuthor: False + - titleContains: + pattern: Update dependencies + isRegex: False + then: + - addLabel: + label: "area/infrastructure \U0001F3D7️" + description: '[Infrastructure PRs] Add area-infrastructure label to dependency update Pull Requests' + - if: + - payloadType: Pull_Request + - labelAdded: + label: status/needs-info + then: + - addReply: + reply: >- + Hello. I see that you've just added `status/needs-info` label to this PR. + + That label is for Issues and not for PRs. Don't worry, I'm going to replace it with the correct one. + - removeLabel: + label: status/needs-info + - addLabel: + label: status/pr-needs-author-input + description: Replace `status/needs-info` with `status/pr-needs-author-input` for PRs + - if: + - payloadType: Pull_Request + - labelAdded: + label: status/needs-repro + then: + - addReply: + reply: >- + Hello. I see that you've just added `status/needs-repro` label to this PR. + + That label is for Issues and not for PRs, so I removed it. + - removeLabel: + label: status/needs-repro + description: Remove `status/needs-repro` from PRs + - if: + - payloadType: Issues + - labelAdded: + label: status/needs-info + then: + - addReply: + reply: Hi @${issueAuthor}. We have added the `status/needs-info` label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time. + description: Add comment when `status/needs-info` is applied to issue + - if: + - payloadType: Issues + - labelAdded: + label: status/needs-repro + then: + - addReply: + reply: >- + Hi @${issueAuthor}. We have added the `status/needs-repro` label to this issue, which indicates that we require steps and sample code to reproduce the issue before we can take further action. Please try to create a minimal sample project/solution or code samples which reproduce the issue, ideally as a GitHub repo that we can clone. + + + This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time. + description: Add comment when `status/needs-repro` is applied to issue + - if: + - payloadType: Issues + - or: + - labelAdded: + label: control-newcontrol + - labelAdded: + label: control-general + - labelAdded: + label: control-webview + - labelAdded: + label: control-datetimepicker + - labelAdded: + label: control-picker + - labelAdded: + label: control-switch + - labelAdded: + label: control-dualscreen + - labelAdded: + label: control-checkbox + - labelAdded: + label: control-border + - labelAdded: + label: control-label + - labelAdded: + label: control-button + - labelAdded: + label: control-dialogalert + - labelAdded: + label: control-entry + - labelAdded: + label: control-frame + - labelAdded: + label: control-stepper + - labelAdded: + label: control-refreshview + - labelAdded: + label: control-image + - labelAdded: + label: control-activityindicator + - labelAdded: + label: control-radiobutton + - labelAdded: + label: control-slider + - labelAdded: + label: control-progressbar + - labelAdded: + label: control-pages + - labelAdded: + label: control-map + then: + - addLabel: + label: "area/controls \U0001F3AE" + description: Add area/controls label when any 'control-X' label is applied to the issue + - if: + - payloadType: Pull_Request + - or: + - labelAdded: + label: control-newcontrol + - labelAdded: + label: control-general + - labelAdded: + label: control-webview + - labelAdded: + label: control-datetimepicker + - labelAdded: + label: control-picker + - labelAdded: + label: control-switch + - labelAdded: + label: control-dualscreen + - labelAdded: + label: control-checkbox + - labelAdded: + label: control-border + - labelAdded: + label: control-label + - labelAdded: + label: control-button + - labelAdded: + label: control-dialogalert + - labelAdded: + label: control-entry + - labelAdded: + label: control-frame + - labelAdded: + label: control-stepper + - labelAdded: + label: control-refreshview + - labelAdded: + label: control-image + - labelAdded: + label: control-activityindicator + - labelAdded: + label: control-radiobutton + - labelAdded: + label: control-slider + - labelAdded: + label: control-progressbar + - labelAdded: + label: control-pages + - labelAdded: + label: control-map + then: + - addLabel: + label: "area/controls \U0001F3AE" + description: Add area/controls label when any 'control-X' label is applied to the PR + - if: + - payloadType: Issues + - isAction: + action: Opened + - or: + - isActivitySender: + user: alexeystrakh + issueAuthor: False + - isActivitySender: + user: alexkblount + issueAuthor: False + - isActivitySender: + user: BenBtg + issueAuthor: False + - isActivitySender: + user: DeanFaizal + issueAuthor: False + - isActivitySender: + user: jgold6 + issueAuthor: False + - isActivitySender: + user: jmongaras + issueAuthor: False + - isActivitySender: + user: jonlipsky + issueAuthor: False + - isActivitySender: + user: JoonghyunCho + issueAuthor: False + - isActivitySender: + user: juanlao + issueAuthor: False + - isActivitySender: + user: migueBarrera + issueAuthor: False + - isActivitySender: + user: mikeparker104 + issueAuthor: False + - isActivitySender: + user: myroot + issueAuthor: False + - isActivitySender: + user: rookiejava + issueAuthor: False + - isActivitySender: + user: shyunMin + issueAuthor: False + - isActivitySender: + user: sung-su + issueAuthor: False + - isActivitySender: + user: Sweekriti91 + issueAuthor: False + then: + - addLabel: + label: partner + description: Add 'partner' label when issue is opened by a partner + - if: + - payloadType: Issues + - isOpen + - labelAdded: + label: status/move-to-vs-feedback + then: + - addReply: + reply: >- + Thanks for the issue report @${issueAuthor}! This issue appears to be a problem with Visual Studio, so we ask that you use the VS feedback tool to report the issue. That way it will get to the routed to the team that owns this experience in VS. + + + If you encounter a problem with Visual Studio, we want to know about it so that we can diagnose and fix it. By using the Report a Problem tool, you can collect detailed information about the problem, and send it to Microsoft with just a few button clicks. + + + 1. Go to the [VS feedback tool](https://docs.microsoft.com/visualstudio/ide/how-to-report-a-problem-with-visual-studio?view=vs-2022) to report the issue + + 2. Close this bug, and consider adding a link to the VS Feedback issue so that others can follow its activity there. + + + This issue will be automatically closed in 3 days if there are no further comments. + description: Ask user to use VS Feedback for VS issues + - if: + - payloadType: Issues + - isAction: + action: Opened + - or: + - isActivitySender: + user: roubachof + issueAuthor: False + - isActivitySender: + user: davidbritch + issueAuthor: False + then: + - addLabel: + label: i/great-reporter + description: Add 'i/great-reporter' when issue is opened by an author we know opens high quality issues + - if: + - payloadType: Issues + - labelAdded: + label: status/try-latest-version + then: + - addReply: + reply: >- + Hi @${issueAuthor}. We have added the `status/try-latest-version` label to this issue, which indicates that we'd like you to try and reproduce this issue on the latest available public version. This can happen because we think that this issue was fixed in a version that has just been released, or the information provided by you indicates that you might be working with an older version. + + + If the issue still persists, please let us know with any additional details and ideally a reproduction project provided through a GitHub repository. + + + This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time. + description: Add comment when `status/try-latest-version` is applied to the issue + - if: + - payloadType: Pull_Request + - activitySenderHasPermission: + permission: Read + - not: + isActivitySender: + user: dotnet-maestro + issueAuthor: False + - not: + isActivitySender: + user: dotnet-maestro-bot + issueAuthor: False + - isAction: + action: Opened + then: + - addLabel: + label: community ✨ + - addReply: + reply: Hey there @${issueAuthor}! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. + description: Add 'community ✨' label to community contributions + - if: + - payloadType: Pull_Request + - hasLabel: + label: stale + - hasLabel: + label: status/pr-needs-author-input + - isActivitySender: + issueAuthor: True + - not: + activitySenderHasPermission: + permission: Write + then: + - reopenIssue + - removeLabel: + label: stale + - removeLabel: + label: status/pr-needs-author-input + description: Revitalize stale PR and reopen + - if: + - payloadType: Pull_Request + - labelAdded: + label: status/pr-needs-author-input + then: + - addReply: + reply: Hi @${issueAuthor}. We have added the `status/pr-needs-author-input` label to this issue, which indicates that we have an open question/action for you before we can take further action. This PRwill be closed automatically in 14 days if we do not hear back from you by then - please feel free to re-open it if you come back to this PR after that time. + description: Add comment when `status/pr-needs-author-input` is applied to PR +onFailure: +onSuccess: diff --git a/.github/workflows/similarissues.yml b/.github/workflows/similarissues.yml new file mode 100644 index 0000000000..73a49f265b --- /dev/null +++ b/.github/workflows/similarissues.yml @@ -0,0 +1,38 @@ +name: Find Similar Issues + +on: + issues: + types: [opened] + issue_comment: + types: [created] + +jobs: + getSimilarIssues: + runs-on: ubuntu-latest + if: >- + (github.event_name == 'issues' && github.event.action == 'opened') || + (github.event_name == 'issue_comment' && github.event.action == 'created' && startsWith(github.event.comment.body, '/similarissues')) + outputs: + message: ${{ steps.getBody.outputs.message }} + steps: + - id: getBody + uses: craigloewen-msft/GitGudSimilarIssues@main + with: + issueTitle: ${{ github.event.issue.title }} + issueBody: ${{ github.event.issue.body }} + repo: ${{ github.repository }} + similaritytolerance: "0.70" + add-comment: + needs: getSimilarIssues + runs-on: ubuntu-latest + permissions: + issues: write + if: needs.getSimilarIssues.outputs.message != '' + steps: + - name: Add comment + run: gh issue comment "$NUMBER" --repo "$REPO" --body "$BODY" + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NUMBER: ${{ github.event.issue.number }} + REPO: ${{ github.repository }} + BODY: ${{ needs.getSimilarIssues.outputs.message }} diff --git a/README.md b/README.md index 81a4dc0f4f..e20162e2ec 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,6 @@ However, these are easy to install as they are found on the various websites. If Here are some links to show the differences in our code as compared to Google's code. -What version are we on? [**m115**](https://github.com/google/skia/tree/chrome/m115) -Are we up-to-date with Google? [Compare](https://github.com/mono/skia/compare/skiasharp...google:chrome/m115) -What have we added? [Compare](https://github.com/google/skia/compare/chrome/m115...mono:skiasharp) +What version are we on? [**m116**](https://github.com/google/skia/tree/chrome/m116) +Are we up-to-date with Google? [Compare](https://github.com/mono/skia/compare/skiasharp...google:chrome/m116) +What have we added? [Compare](https://github.com/google/skia/compare/chrome/m116...mono:skiasharp) diff --git a/benchmarks/SkiaSharp.Benchmarks.sln b/benchmarks/SkiaSharp.Benchmarks.sln index aea131389d..2cbfe66ee3 100644 --- a/benchmarks/SkiaSharp.Benchmarks.sln +++ b/benchmarks/SkiaSharp.Benchmarks.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Benchmarks", "Ski EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.SceneGraph", "..\binding\SkiaSharp.SceneGraph\SkiaSharp.SceneGraph.csproj", "{42B5D998-A676-4B50-B558-1D3ACA7D3FC4}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Resources", "..\binding\SkiaSharp.Resources\SkiaSharp.Resources.csproj", "{AD2C6978-4F5E-E592-B565-26C357877B2C}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Skottie", "..\binding\SkiaSharp.Skottie\SkiaSharp.Skottie.csproj", "{DD03EAA1-A85D-4588-8B84-8285EC1979C8}" EndProject Global @@ -41,6 +43,10 @@ Global {42B5D998-A676-4B50-B558-1D3ACA7D3FC4}.Debug|Any CPU.Build.0 = Debug|Any CPU {42B5D998-A676-4B50-B558-1D3ACA7D3FC4}.Release|Any CPU.ActiveCfg = Release|Any CPU {42B5D998-A676-4B50-B558-1D3ACA7D3FC4}.Release|Any CPU.Build.0 = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.Build.0 = Release|Any CPU {DD03EAA1-A85D-4588-8B84-8285EC1979C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {DD03EAA1-A85D-4588-8B84-8285EC1979C8}.Debug|Any CPU.Build.0 = Debug|Any CPU {DD03EAA1-A85D-4588-8B84-8285EC1979C8}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/binding/Binding.Shared/PlatformConfiguration.cs b/binding/Binding.Shared/PlatformConfiguration.cs index e3c3b8b481..7a1fbdf18f 100644 --- a/binding/Binding.Shared/PlatformConfiguration.cs +++ b/binding/Binding.Shared/PlatformConfiguration.cs @@ -18,42 +18,52 @@ public static class PlatformConfiguration { private const string LibCLibrary = "libc"; - public static bool IsUnix { get; } + public static bool IsUnix => IsMac || IsLinux; - public static bool IsWindows { get; } - - public static bool IsMac { get; } - - public static bool IsLinux { get; } - - public static bool IsArm { get; } - - public static bool Is64Bit { get; } + public static bool IsWindows { +#if WINDOWS_UWP + get => true; +#elif NET6_0_OR_GREATER + get => OperatingSystem.IsWindows (); +#else + get => RuntimeInformation.IsOSPlatform (OSPlatform.Windows); +#endif + } - static PlatformConfiguration () - { + public static bool IsMac { #if WINDOWS_UWP - IsMac = false; - IsLinux = false; - IsUnix = false; - IsWindows = true; - - var arch = Package.Current.Id.Architecture; - const ProcessorArchitecture arm64 = (ProcessorArchitecture)12; - IsArm = arch == ProcessorArchitecture.Arm || arch == arm64; + get => false; +#elif NET6_0_OR_GREATER + get => OperatingSystem.IsMacOS (); #else - IsMac = RuntimeInformation.IsOSPlatform (OSPlatform.OSX); - IsLinux = RuntimeInformation.IsOSPlatform (OSPlatform.Linux); - IsUnix = IsMac || IsLinux; - IsWindows = RuntimeInformation.IsOSPlatform (OSPlatform.Windows); + get => RuntimeInformation.IsOSPlatform (OSPlatform.OSX); +#endif + } - var arch = RuntimeInformation.ProcessArchitecture; - IsArm = arch == Architecture.Arm || arch == Architecture.Arm64; + public static bool IsLinux { +#if WINDOWS_UWP + get => false; +#elif NET6_0_OR_GREATER + get => OperatingSystem.IsLinux (); +#else + get => RuntimeInformation.IsOSPlatform (OSPlatform.Linux); #endif + } - Is64Bit = IntPtr.Size == 8; + public static bool IsArm { +#if WINDOWS_UWP + get { + var arch = Package.Current.Id.Architecture; + const ProcessorArchitecture arm64 = (ProcessorArchitecture)12; + return arch == ProcessorArchitecture.Arm || arch == arm64; + } +#else + get => RuntimeInformation.ProcessArchitecture is Architecture.Arm or Architecture.Arm64; +#endif } + public static bool Is64Bit => IntPtr.Size == 8; + private static string linuxFlavor; public static string LinuxFlavor diff --git a/binding/Directory.Build.targets b/binding/Directory.Build.targets index f6e780a0ff..813aac0552 100644 --- a/binding/Directory.Build.targets +++ b/binding/Directory.Build.targets @@ -4,6 +4,10 @@ + + + + SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images. diff --git a/binding/IncludeNativeAssets.SkiaSharp.WinUI.targets b/binding/IncludeNativeAssets.SkiaSharp.WinUI.targets new file mode 100644 index 0000000000..89e4c652b7 --- /dev/null +++ b/binding/IncludeNativeAssets.SkiaSharp.WinUI.targets @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/binding/NativeAssets.Build.targets b/binding/NativeAssets.Build.targets index cd68c556fa..d34c35f239 100644 --- a/binding/NativeAssets.Build.targets +++ b/binding/NativeAssets.Build.targets @@ -33,16 +33,20 @@ - + <_NativeWindowsPackageFileToUse Include="@(NativeWindowsPackageFile->HasMetadata('Folder'))" /> + <_NativeWindowsPackageFileWithNoFolder Include="@(NativeWindowsPackageFile)" /> + <_NativeWindowsPackageFileWithNoFolder Remove="@(_NativeWindowsPackageFileToUse)" /> + <_NativeWindowsPackageFileToUse Include="@(_NativeWindowsPackageFileWithNoFolder)" Folder="native" /> + <_CompletedNativeWindowsPackageFile - Include="@(NativeWindowsPackageFile)" + Include="@(_NativeWindowsPackageFileToUse)" TargetFramework="%(RuntimeIdentifier)" - TargetPath="native\%(Filename)%(Extension)" - PackagePath="runtimes\%(RuntimeIdentifier)\native\%(Filename)%(Extension)" /> + TargetPath="%(Folder)\%(Filename)%(Extension)" + PackagePath="runtimes\%(RuntimeIdentifier)\%(Folder)\%(Filename)%(Extension)" /> <_BuildOutputInPackage Remove="@(_BuildOutputInPackage)" /> <_BuildOutputInPackage Include="@(_CompletedNativeWindowsPackageFile)" Condition="'%(Extension)' != '.pdb'" /> <_TargetPathsToSymbols Remove="@(_TargetPathsToSymbols)" /> diff --git a/binding/SkiaSharp.NativeAssets.WinUI/SkiaSharp.NativeAssets.WinUI.csproj b/binding/SkiaSharp.NativeAssets.WinUI/SkiaSharp.NativeAssets.WinUI.csproj new file mode 100644 index 0000000000..fab3a0d1e0 --- /dev/null +++ b/binding/SkiaSharp.NativeAssets.WinUI/SkiaSharp.NativeAssets.WinUI.csproj @@ -0,0 +1,16 @@ + + + $(WindowsTargetFrameworks) + SkiaSharp + $(PackagingGroup) - Native Assets for Windows UI (WinUI 3) + true + + + + + + + + + + \ No newline at end of file diff --git a/binding/SkiaSharp.Resources/Properties/SkiaSharpResourcesAssemblyInfo.cs b/binding/SkiaSharp.Resources/Properties/SkiaSharpResourcesAssemblyInfo.cs new file mode 100644 index 0000000000..32dd31681e --- /dev/null +++ b/binding/SkiaSharp.Resources/Properties/SkiaSharpResourcesAssemblyInfo.cs @@ -0,0 +1,36 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; + +[assembly: AssemblyTitle("SkiaSharp.Resources")] +[assembly: AssemblyDescription("This package adds lottie support to SkiaSharp via skottie.")] +[assembly: AssemblyCompany("Microsoft Corporation")] +[assembly: AssemblyProduct("SkiaSharp")] +[assembly: AssemblyCopyright("© Microsoft Corporation. All rights reserved.")] +[assembly: NeutralResourcesLanguage("en")] + +[assembly: InternalsVisibleTo("SkiaSharp.Tests, PublicKey=" + + "002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" + + "8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" + + "3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fd" + + "dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" + + "65d016df")] + +[assembly: InternalsVisibleTo("SkiaSharp.Benchmarks, PublicKey=" + + "002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" + + "8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" + + "3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fd" + + "dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" + + "65d016df")] + +[assembly: AssemblyMetadata("IsTrimmable", "True")] + +#if __IOS__ || __TVOS__ || __MACOS__ +// This attribute allows you to mark your assemblies as “safe to link”. +// When the attribute is present, the linker—if enabled—will process the assembly +// even if you’re using the “Link SDK assemblies only” option, which is the default for device builds. +#pragma warning disable CS0618 // Type or member is obsolete +[assembly: Foundation.LinkerSafe] +#pragma warning restore CS0618 // Type or member is obsolete +#endif diff --git a/binding/SkiaSharp.Resources/ResourceProvider.cs b/binding/SkiaSharp.Resources/ResourceProvider.cs new file mode 100644 index 0000000000..5b22bc5c7d --- /dev/null +++ b/binding/SkiaSharp.Resources/ResourceProvider.cs @@ -0,0 +1,64 @@ +using System; + +namespace SkiaSharp.Resources +{ + public abstract unsafe class ResourceProvider : SKObject, ISKReferenceCounted, ISKSkipObjectRegistration + { + internal ResourceProvider (IntPtr handle, bool owns) + : base (handle, owns) + { + } + + public SKData? Load (string resourceName) => + Load ("", resourceName); + + public SKData? Load (string resourcePath, string resourceName) => + SKData.GetObject (ResourcesApi.skresources_resource_provider_load (Handle, resourcePath, resourceName)); + } + + public sealed class CachingResourceProvider : ResourceProvider + { + public CachingResourceProvider (ResourceProvider resourceProvider) + : base (Create (resourceProvider), true) + { + Referenced(this, resourceProvider); + } + + private static IntPtr Create (ResourceProvider resourceProvider) + { + _ = resourceProvider ?? throw new ArgumentNullException (nameof (resourceProvider)); + return ResourcesApi.skresources_caching_resource_provider_proxy_make (resourceProvider.Handle); + } + } + + public sealed class DataUriResourceProvider : ResourceProvider + { + public DataUriResourceProvider (bool preDecode = false) + : this (null, preDecode) + { + } + + public DataUriResourceProvider (ResourceProvider? fallbackProvider, bool preDecode = false) + : base (Create (fallbackProvider, preDecode), true) + { + Referenced (this, fallbackProvider); + } + + private static IntPtr Create (ResourceProvider? fallbackProvider, bool preDecode = false) => + ResourcesApi.skresources_data_uri_resource_provider_proxy_make (fallbackProvider?.Handle ?? IntPtr.Zero, preDecode); + } + + public sealed class FileResourceProvider : ResourceProvider + { + public FileResourceProvider (string baseDirectory, bool preDecode = false) + : base (Create (baseDirectory, preDecode), true) + { + } + + private static IntPtr Create (string baseDirectory, bool preDecode) + { + using var baseDir = new SKString(baseDirectory ?? throw new ArgumentNullException (nameof (baseDirectory))); + return ResourcesApi.skresources_file_resource_provider_make (baseDir.Handle, preDecode); + } + } +} diff --git a/binding/SkiaSharp.Resources/ResourcesApi.cs b/binding/SkiaSharp.Resources/ResourcesApi.cs new file mode 100644 index 0000000000..06438cd026 --- /dev/null +++ b/binding/SkiaSharp.Resources/ResourcesApi.cs @@ -0,0 +1,23 @@ +#nullable disable + +using System; + +namespace SkiaSharp +{ + internal partial class ResourcesApi + { +#if __IOS__ || __TVOS__ + private const string SKIA = "@rpath/libSkiaSharp.framework/libSkiaSharp"; +#else + private const string SKIA = "libSkiaSharp"; +#endif + +#if USE_DELEGATES + private static readonly Lazy libSkiaSharpHandle = + new Lazy (() => LibraryLoader.LoadLocalLibrary (SKIA)); + + private static T GetSymbol (string name) where T : Delegate => + LibraryLoader.GetSymbolDelegate (libSkiaSharpHandle.Value, name); +#endif + } +} diff --git a/binding/SkiaSharp.Resources/ResourcesApi.generated.cs b/binding/SkiaSharp.Resources/ResourcesApi.generated.cs new file mode 100644 index 0000000000..71eb442fcc --- /dev/null +++ b/binding/SkiaSharp.Resources/ResourcesApi.generated.cs @@ -0,0 +1,268 @@ +using System; +using System.Runtime.InteropServices; + +#region Namespaces + +using SkiaSharp.Resources; + +#endregion + +#region Class declarations + +using gr_backendrendertarget_t = System.IntPtr; +using gr_backendtexture_t = System.IntPtr; +using gr_direct_context_t = System.IntPtr; +using gr_glinterface_t = System.IntPtr; +using gr_recording_context_t = System.IntPtr; +using gr_vk_extensions_t = System.IntPtr; +using gr_vk_memory_allocator_t = System.IntPtr; +using gr_vkinterface_t = System.IntPtr; +using sk_bitmap_t = System.IntPtr; +using sk_blender_t = System.IntPtr; +using sk_canvas_t = System.IntPtr; +using sk_codec_t = System.IntPtr; +using sk_colorfilter_t = System.IntPtr; +using sk_colorspace_icc_profile_t = System.IntPtr; +using sk_colorspace_t = System.IntPtr; +using sk_compatpaint_t = System.IntPtr; +using sk_data_t = System.IntPtr; +using sk_document_t = System.IntPtr; +using sk_drawable_t = System.IntPtr; +using sk_flattenable_t = System.IntPtr; +using sk_font_t = System.IntPtr; +using sk_fontmgr_t = System.IntPtr; +using sk_fontstyle_t = System.IntPtr; +using sk_fontstyleset_t = System.IntPtr; +using sk_image_t = System.IntPtr; +using sk_imagefilter_t = System.IntPtr; +using sk_manageddrawable_t = System.IntPtr; +using sk_managedtracememorydump_t = System.IntPtr; +using sk_maskfilter_t = System.IntPtr; +using sk_nodraw_canvas_t = System.IntPtr; +using sk_nvrefcnt_t = System.IntPtr; +using sk_nway_canvas_t = System.IntPtr; +using sk_opbuilder_t = System.IntPtr; +using sk_overdraw_canvas_t = System.IntPtr; +using sk_paint_t = System.IntPtr; +using sk_path_effect_t = System.IntPtr; +using sk_path_iterator_t = System.IntPtr; +using sk_path_rawiterator_t = System.IntPtr; +using sk_path_t = System.IntPtr; +using sk_pathmeasure_t = System.IntPtr; +using sk_picture_recorder_t = System.IntPtr; +using sk_picture_t = System.IntPtr; +using sk_pixelref_factory_t = System.IntPtr; +using sk_pixmap_t = System.IntPtr; +using sk_refcnt_t = System.IntPtr; +using sk_region_cliperator_t = System.IntPtr; +using sk_region_iterator_t = System.IntPtr; +using sk_region_spanerator_t = System.IntPtr; +using sk_region_t = System.IntPtr; +using sk_rrect_t = System.IntPtr; +using sk_runtimeeffect_t = System.IntPtr; +using sk_shader_t = System.IntPtr; +using sk_stream_asset_t = System.IntPtr; +using sk_stream_filestream_t = System.IntPtr; +using sk_stream_managedstream_t = System.IntPtr; +using sk_stream_memorystream_t = System.IntPtr; +using sk_stream_streamrewindable_t = System.IntPtr; +using sk_stream_t = System.IntPtr; +using sk_string_t = System.IntPtr; +using sk_surface_t = System.IntPtr; +using sk_surfaceprops_t = System.IntPtr; +using sk_svgcanvas_t = System.IntPtr; +using sk_textblob_builder_t = System.IntPtr; +using sk_textblob_t = System.IntPtr; +using sk_tracememorydump_t = System.IntPtr; +using sk_typeface_t = System.IntPtr; +using sk_vertices_t = System.IntPtr; +using sk_wstream_dynamicmemorystream_t = System.IntPtr; +using sk_wstream_filestream_t = System.IntPtr; +using sk_wstream_managedstream_t = System.IntPtr; +using sk_wstream_t = System.IntPtr; +using skottie_animation_builder_t = System.IntPtr; +using skottie_animation_t = System.IntPtr; +using skottie_logger_t = System.IntPtr; +using skottie_marker_observer_t = System.IntPtr; +using skottie_property_observer_t = System.IntPtr; +using skottie_resource_provider_t = System.IntPtr; +using skresources_external_track_asset_t = System.IntPtr; +using skresources_image_asset_t = System.IntPtr; +using skresources_multi_frame_image_asset_t = System.IntPtr; +using skresources_resource_provider_t = System.IntPtr; +using sksg_invalidation_controller_t = System.IntPtr; +using vk_device_t = System.IntPtr; +using vk_instance_t = System.IntPtr; +using vk_physical_device_features_2_t = System.IntPtr; +using vk_physical_device_features_t = System.IntPtr; +using vk_physical_device_t = System.IntPtr; +using vk_queue_t = System.IntPtr; + +#endregion + +#region Functions + +namespace SkiaSharp +{ + internal unsafe partial class ResourcesApi + { + #region skresources_resource_provider.h + + // skresources_resource_provider_t* skresources_caching_resource_provider_proxy_make(skresources_resource_provider_t* rp) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skresources_resource_provider_t skresources_caching_resource_provider_proxy_make (skresources_resource_provider_t rp); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skresources_resource_provider_t skresources_caching_resource_provider_proxy_make (skresources_resource_provider_t rp); + } + private static Delegates.skresources_caching_resource_provider_proxy_make skresources_caching_resource_provider_proxy_make_delegate; + internal static skresources_resource_provider_t skresources_caching_resource_provider_proxy_make (skresources_resource_provider_t rp) => + (skresources_caching_resource_provider_proxy_make_delegate ??= GetSymbol ("skresources_caching_resource_provider_proxy_make")).Invoke (rp); + #endif + + // skresources_resource_provider_t* skresources_data_uri_resource_provider_proxy_make(skresources_resource_provider_t* rp, bool predecode) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skresources_resource_provider_t skresources_data_uri_resource_provider_proxy_make (skresources_resource_provider_t rp, [MarshalAs (UnmanagedType.I1)] bool predecode); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skresources_resource_provider_t skresources_data_uri_resource_provider_proxy_make (skresources_resource_provider_t rp, [MarshalAs (UnmanagedType.I1)] bool predecode); + } + private static Delegates.skresources_data_uri_resource_provider_proxy_make skresources_data_uri_resource_provider_proxy_make_delegate; + internal static skresources_resource_provider_t skresources_data_uri_resource_provider_proxy_make (skresources_resource_provider_t rp, [MarshalAs (UnmanagedType.I1)] bool predecode) => + (skresources_data_uri_resource_provider_proxy_make_delegate ??= GetSymbol ("skresources_data_uri_resource_provider_proxy_make")).Invoke (rp, predecode); + #endif + + // skresources_resource_provider_t* skresources_file_resource_provider_make(sk_string_t* base_dir, bool predecode) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skresources_resource_provider_t skresources_file_resource_provider_make (sk_string_t base_dir, [MarshalAs (UnmanagedType.I1)] bool predecode); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skresources_resource_provider_t skresources_file_resource_provider_make (sk_string_t base_dir, [MarshalAs (UnmanagedType.I1)] bool predecode); + } + private static Delegates.skresources_file_resource_provider_make skresources_file_resource_provider_make_delegate; + internal static skresources_resource_provider_t skresources_file_resource_provider_make (sk_string_t base_dir, [MarshalAs (UnmanagedType.I1)] bool predecode) => + (skresources_file_resource_provider_make_delegate ??= GetSymbol ("skresources_file_resource_provider_make")).Invoke (base_dir, predecode); + #endif + + // void skresources_resource_provider_delete(skresources_resource_provider_t* instance) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void skresources_resource_provider_delete (skresources_resource_provider_t instance); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void skresources_resource_provider_delete (skresources_resource_provider_t instance); + } + private static Delegates.skresources_resource_provider_delete skresources_resource_provider_delete_delegate; + internal static void skresources_resource_provider_delete (skresources_resource_provider_t instance) => + (skresources_resource_provider_delete_delegate ??= GetSymbol ("skresources_resource_provider_delete")).Invoke (instance); + #endif + + // sk_data_t* skresources_resource_provider_load(skresources_resource_provider_t* instance, const char* path, const char* name) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_data_t skresources_resource_provider_load (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_data_t skresources_resource_provider_load (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name); + } + private static Delegates.skresources_resource_provider_load skresources_resource_provider_load_delegate; + internal static sk_data_t skresources_resource_provider_load (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name) => + (skresources_resource_provider_load_delegate ??= GetSymbol ("skresources_resource_provider_load")).Invoke (instance, path, name); + #endif + + // skresources_external_track_asset_t* skresources_resource_provider_load_audio_asset(skresources_resource_provider_t* instance, const char* path, const char* name, const char* id) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skresources_external_track_asset_t skresources_resource_provider_load_audio_asset (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String id); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skresources_external_track_asset_t skresources_resource_provider_load_audio_asset (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String id); + } + private static Delegates.skresources_resource_provider_load_audio_asset skresources_resource_provider_load_audio_asset_delegate; + internal static skresources_external_track_asset_t skresources_resource_provider_load_audio_asset (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String id) => + (skresources_resource_provider_load_audio_asset_delegate ??= GetSymbol ("skresources_resource_provider_load_audio_asset")).Invoke (instance, path, name, id); + #endif + + // skresources_image_asset_t* skresources_resource_provider_load_image_asset(skresources_resource_provider_t* instance, const char* path, const char* name, const char* id) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skresources_image_asset_t skresources_resource_provider_load_image_asset (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String id); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skresources_image_asset_t skresources_resource_provider_load_image_asset (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String id); + } + private static Delegates.skresources_resource_provider_load_image_asset skresources_resource_provider_load_image_asset_delegate; + internal static skresources_image_asset_t skresources_resource_provider_load_image_asset (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String path, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String id) => + (skresources_resource_provider_load_image_asset_delegate ??= GetSymbol ("skresources_resource_provider_load_image_asset")).Invoke (instance, path, name, id); + #endif + + // sk_typeface_t* skresources_resource_provider_load_typeface(skresources_resource_provider_t* instance, const char* name, const char* url) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_typeface_t skresources_resource_provider_load_typeface (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String url); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_typeface_t skresources_resource_provider_load_typeface (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String url); + } + private static Delegates.skresources_resource_provider_load_typeface skresources_resource_provider_load_typeface_delegate; + internal static sk_typeface_t skresources_resource_provider_load_typeface (skresources_resource_provider_t instance, [MarshalAs (UnmanagedType.LPStr)] String name, [MarshalAs (UnmanagedType.LPStr)] String url) => + (skresources_resource_provider_load_typeface_delegate ??= GetSymbol ("skresources_resource_provider_load_typeface")).Invoke (instance, name, url); + #endif + + // void skresources_resource_provider_ref(skresources_resource_provider_t* instance) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void skresources_resource_provider_ref (skresources_resource_provider_t instance); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void skresources_resource_provider_ref (skresources_resource_provider_t instance); + } + private static Delegates.skresources_resource_provider_ref skresources_resource_provider_ref_delegate; + internal static void skresources_resource_provider_ref (skresources_resource_provider_t instance) => + (skresources_resource_provider_ref_delegate ??= GetSymbol ("skresources_resource_provider_ref")).Invoke (instance); + #endif + + // void skresources_resource_provider_unref(skresources_resource_provider_t* instance) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void skresources_resource_provider_unref (skresources_resource_provider_t instance); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void skresources_resource_provider_unref (skresources_resource_provider_t instance); + } + private static Delegates.skresources_resource_provider_unref skresources_resource_provider_unref_delegate; + internal static void skresources_resource_provider_unref (skresources_resource_provider_t instance) => + (skresources_resource_provider_unref_delegate ??= GetSymbol ("skresources_resource_provider_unref")).Invoke (instance); + #endif + + #endregion + + } +} + +#endregion Functions + +#region Delegates + +#endregion + +#region Structs + +#endregion + +#region Enums + +#endregion diff --git a/binding/SkiaSharp.Resources/SkiaSharp.Resources.csproj b/binding/SkiaSharp.Resources/SkiaSharp.Resources.csproj new file mode 100644 index 0000000000..87ee248726 --- /dev/null +++ b/binding/SkiaSharp.Resources/SkiaSharp.Resources.csproj @@ -0,0 +1,18 @@ + + + $(AllTargetFrameworks) + SkiaSharp.Resources + SkiaSharp.Resources + SkiaSharp.Resources + SkiaSharp Resource Providers + SkiaSharp Skottie provides a Lottie implementation using the SkiaSharp library. + skottie;lottie + enable + + + $(DefineConstants);USE_DELEGATES + + + + + \ No newline at end of file diff --git a/binding/SkiaSharp.SceneGraph/SceneGraphApi.generated.cs b/binding/SkiaSharp.SceneGraph/SceneGraphApi.generated.cs index a3b6ab1f96..36d57c6fbc 100644 --- a/binding/SkiaSharp.SceneGraph/SceneGraphApi.generated.cs +++ b/binding/SkiaSharp.SceneGraph/SceneGraphApi.generated.cs @@ -18,6 +18,7 @@ using gr_vk_memory_allocator_t = System.IntPtr; using gr_vkinterface_t = System.IntPtr; using sk_bitmap_t = System.IntPtr; +using sk_blender_t = System.IntPtr; using sk_canvas_t = System.IntPtr; using sk_codec_t = System.IntPtr; using sk_colorfilter_t = System.IntPtr; @@ -85,6 +86,10 @@ using skottie_marker_observer_t = System.IntPtr; using skottie_property_observer_t = System.IntPtr; using skottie_resource_provider_t = System.IntPtr; +using skresources_external_track_asset_t = System.IntPtr; +using skresources_image_asset_t = System.IntPtr; +using skresources_multi_frame_image_asset_t = System.IntPtr; +using skresources_resource_provider_t = System.IntPtr; using sksg_invalidation_controller_t = System.IntPtr; using vk_device_t = System.IntPtr; using vk_instance_t = System.IntPtr; diff --git a/binding/SkiaSharp.Skottie/Animation.cs b/binding/SkiaSharp.Skottie/Animation.cs index a6ad5ae5b9..a7360d7328 100644 --- a/binding/SkiaSharp.Skottie/Animation.cs +++ b/binding/SkiaSharp.Skottie/Animation.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using SkiaSharp.Resources; using SkiaSharp.SceneGraph; namespace SkiaSharp.Skottie @@ -20,6 +21,11 @@ void ISKNonVirtualReferenceCounted.UnreferenceNative () protected override void DisposeNative () => SkottieApi.skottie_animation_delete (Handle); + // AnimationBuilder + + public static AnimationBuilder CreateBuilder (AnimationBuilderFlags flags = AnimationBuilderFlags.None) => + new AnimationBuilder (flags); + // Parse public static Animation? Parse (string json) => @@ -77,6 +83,7 @@ public static bool TryCreate (SKData data, [System.Diagnostics.CodeAnalysis.NotN fixed (byte* ptr = span) { animation = GetObject (SkottieApi.skottie_animation_make_from_data (ptr, (IntPtr)span.Length)); + GC.KeepAlive(data); return animation != null; } } diff --git a/binding/SkiaSharp.Skottie/AnimationBuilder.cs b/binding/SkiaSharp.Skottie/AnimationBuilder.cs new file mode 100644 index 0000000000..b84f563a36 --- /dev/null +++ b/binding/SkiaSharp.Skottie/AnimationBuilder.cs @@ -0,0 +1,88 @@ +using System; +using System.IO; +using SkiaSharp.Resources; + +namespace SkiaSharp.Skottie +{ + public sealed unsafe class AnimationBuilder : SKObject, ISKSkipObjectRegistration + { + internal AnimationBuilder (AnimationBuilderFlags flags) + : this (SkottieApi.skottie_animation_builder_new (flags), true) + { + } + + internal AnimationBuilder (IntPtr handle, bool owns) + : base (handle, owns) + { + } + + public AnimationBuilder SetFontManager (SKFontManager fontManager) + { + _ = fontManager ?? throw new ArgumentNullException (nameof (fontManager)); + SkottieApi.skottie_animation_builder_set_font_manager (Handle, fontManager.Handle); + Referenced (this, fontManager); + return this; + } + + public AnimationBuilder SetResourceProvider (ResourceProvider resourceProvider) + { + _ = resourceProvider ?? throw new ArgumentNullException (nameof (resourceProvider)); + SkottieApi.skottie_animation_builder_set_resource_provider (Handle, resourceProvider.Handle); + Referenced (this, resourceProvider); + return this; + } + + public AnimationBuilderStats Stats + { + get + { + AnimationBuilderStats stats; + SkottieApi.skottie_animation_builder_get_stats (Handle, &stats); + return stats; + } + } + + public Animation? Build (Stream stream) + { + _ = stream ?? throw new ArgumentNullException (nameof (stream)); + + using var data = SKData.Create (stream); + return Build (data); + } + + public Animation? Build (SKStream stream) + { + _ = stream ?? throw new ArgumentNullException (nameof (stream)); + + using var data = SKData.Create (stream); + return Build (data); + } + + public Animation? Build (SKData data) + { + _ = data ?? throw new ArgumentNullException (nameof (data)); + + var preamble = Utils.GetPreambleSize (data); + var span = data.AsSpan ().Slice (preamble); + + fixed (byte* ptr = span) { + try { + return Animation.GetObject (SkottieApi.skottie_animation_builder_make_from_data (Handle, ptr, (IntPtr)span.Length)); + } finally { + GC.KeepAlive(data); + } + } + } + + public Animation? Build (string path) + { + _ = path ?? throw new ArgumentNullException (nameof (path)); + + using var data = SKData.Create (path); + return Build (data); + } + + protected override void DisposeNative () + => SkottieApi.skottie_animation_builder_delete (Handle); + } +} diff --git a/binding/SkiaSharp.Skottie/AnimationBuilderStats.cs b/binding/SkiaSharp.Skottie/AnimationBuilderStats.cs new file mode 100644 index 0000000000..42d9e48efd --- /dev/null +++ b/binding/SkiaSharp.Skottie/AnimationBuilderStats.cs @@ -0,0 +1,21 @@ + +using System; + +namespace SkiaSharp.Skottie +{ + public partial struct AnimationBuilderStats + { + public readonly TimeSpan TotalLoadTime => + TimeSpan.FromMilliseconds (fTotalLoadTimeMS); + + public readonly TimeSpan JsonParseTime => + TimeSpan.FromMilliseconds (fJsonParseTimeMS); + + public readonly TimeSpan SceneParseTime => + TimeSpan.FromMilliseconds (fSceneParseTimeMS); + + public readonly int JsonSize => (int)fJsonSize; + + public readonly int AnimatorCount => (int)fAnimatorCount; + } +} diff --git a/binding/SkiaSharp.Skottie/SkiaSharp.Skottie.csproj b/binding/SkiaSharp.Skottie/SkiaSharp.Skottie.csproj index 8947f56b39..4fd4ef3112 100644 --- a/binding/SkiaSharp.Skottie/SkiaSharp.Skottie.csproj +++ b/binding/SkiaSharp.Skottie/SkiaSharp.Skottie.csproj @@ -15,5 +15,6 @@ + \ No newline at end of file diff --git a/binding/SkiaSharp.Skottie/SkottieApi.generated.cs b/binding/SkiaSharp.Skottie/SkottieApi.generated.cs index 8bcc631ec4..38f281ace3 100644 --- a/binding/SkiaSharp.Skottie/SkottieApi.generated.cs +++ b/binding/SkiaSharp.Skottie/SkottieApi.generated.cs @@ -18,6 +18,7 @@ using gr_vk_memory_allocator_t = System.IntPtr; using gr_vkinterface_t = System.IntPtr; using sk_bitmap_t = System.IntPtr; +using sk_blender_t = System.IntPtr; using sk_canvas_t = System.IntPtr; using sk_codec_t = System.IntPtr; using sk_colorfilter_t = System.IntPtr; @@ -85,6 +86,10 @@ using skottie_marker_observer_t = System.IntPtr; using skottie_property_observer_t = System.IntPtr; using skottie_resource_provider_t = System.IntPtr; +using skresources_external_track_asset_t = System.IntPtr; +using skresources_image_asset_t = System.IntPtr; +using skresources_multi_frame_image_asset_t = System.IntPtr; +using skresources_resource_provider_t = System.IntPtr; using sksg_invalidation_controller_t = System.IntPtr; using vk_device_t = System.IntPtr; using vk_instance_t = System.IntPtr; @@ -103,6 +108,132 @@ internal unsafe partial class SkottieApi { #region skottie_animation.h + // void skottie_animation_builder_delete(skottie_animation_builder_t* instance) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void skottie_animation_builder_delete (skottie_animation_builder_t instance); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void skottie_animation_builder_delete (skottie_animation_builder_t instance); + } + private static Delegates.skottie_animation_builder_delete skottie_animation_builder_delete_delegate; + internal static void skottie_animation_builder_delete (skottie_animation_builder_t instance) => + (skottie_animation_builder_delete_delegate ??= GetSymbol ("skottie_animation_builder_delete")).Invoke (instance); + #endif + + // void skottie_animation_builder_get_stats(skottie_animation_builder_t* instance, skottie_animation_builder_stats_t* stats) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void skottie_animation_builder_get_stats (skottie_animation_builder_t instance, AnimationBuilderStats* stats); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void skottie_animation_builder_get_stats (skottie_animation_builder_t instance, AnimationBuilderStats* stats); + } + private static Delegates.skottie_animation_builder_get_stats skottie_animation_builder_get_stats_delegate; + internal static void skottie_animation_builder_get_stats (skottie_animation_builder_t instance, AnimationBuilderStats* stats) => + (skottie_animation_builder_get_stats_delegate ??= GetSymbol ("skottie_animation_builder_get_stats")).Invoke (instance, stats); + #endif + + // skottie_animation_t* skottie_animation_builder_make_from_data(skottie_animation_builder_t* instance, const char* data, size_t length) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skottie_animation_t skottie_animation_builder_make_from_data (skottie_animation_builder_t instance, /* char */ void* data, /* size_t */ IntPtr length); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skottie_animation_t skottie_animation_builder_make_from_data (skottie_animation_builder_t instance, /* char */ void* data, /* size_t */ IntPtr length); + } + private static Delegates.skottie_animation_builder_make_from_data skottie_animation_builder_make_from_data_delegate; + internal static skottie_animation_t skottie_animation_builder_make_from_data (skottie_animation_builder_t instance, /* char */ void* data, /* size_t */ IntPtr length) => + (skottie_animation_builder_make_from_data_delegate ??= GetSymbol ("skottie_animation_builder_make_from_data")).Invoke (instance, data, length); + #endif + + // skottie_animation_t* skottie_animation_builder_make_from_file(skottie_animation_builder_t* instance, const char* path) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skottie_animation_t skottie_animation_builder_make_from_file (skottie_animation_builder_t instance, /* char */ void* path); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skottie_animation_t skottie_animation_builder_make_from_file (skottie_animation_builder_t instance, /* char */ void* path); + } + private static Delegates.skottie_animation_builder_make_from_file skottie_animation_builder_make_from_file_delegate; + internal static skottie_animation_t skottie_animation_builder_make_from_file (skottie_animation_builder_t instance, /* char */ void* path) => + (skottie_animation_builder_make_from_file_delegate ??= GetSymbol ("skottie_animation_builder_make_from_file")).Invoke (instance, path); + #endif + + // skottie_animation_t* skottie_animation_builder_make_from_stream(skottie_animation_builder_t* instance, sk_stream_t* stream) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skottie_animation_t skottie_animation_builder_make_from_stream (skottie_animation_builder_t instance, sk_stream_t stream); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skottie_animation_t skottie_animation_builder_make_from_stream (skottie_animation_builder_t instance, sk_stream_t stream); + } + private static Delegates.skottie_animation_builder_make_from_stream skottie_animation_builder_make_from_stream_delegate; + internal static skottie_animation_t skottie_animation_builder_make_from_stream (skottie_animation_builder_t instance, sk_stream_t stream) => + (skottie_animation_builder_make_from_stream_delegate ??= GetSymbol ("skottie_animation_builder_make_from_stream")).Invoke (instance, stream); + #endif + + // skottie_animation_t* skottie_animation_builder_make_from_string(skottie_animation_builder_t* instance, const char* data, size_t length) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skottie_animation_t skottie_animation_builder_make_from_string (skottie_animation_builder_t instance, /* char */ void* data, /* size_t */ IntPtr length); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skottie_animation_t skottie_animation_builder_make_from_string (skottie_animation_builder_t instance, /* char */ void* data, /* size_t */ IntPtr length); + } + private static Delegates.skottie_animation_builder_make_from_string skottie_animation_builder_make_from_string_delegate; + internal static skottie_animation_t skottie_animation_builder_make_from_string (skottie_animation_builder_t instance, /* char */ void* data, /* size_t */ IntPtr length) => + (skottie_animation_builder_make_from_string_delegate ??= GetSymbol ("skottie_animation_builder_make_from_string")).Invoke (instance, data, length); + #endif + + // skottie_animation_builder_t* skottie_animation_builder_new(skottie_animation_builder_flags_t flags) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern skottie_animation_builder_t skottie_animation_builder_new (AnimationBuilderFlags flags); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate skottie_animation_builder_t skottie_animation_builder_new (AnimationBuilderFlags flags); + } + private static Delegates.skottie_animation_builder_new skottie_animation_builder_new_delegate; + internal static skottie_animation_builder_t skottie_animation_builder_new (AnimationBuilderFlags flags) => + (skottie_animation_builder_new_delegate ??= GetSymbol ("skottie_animation_builder_new")).Invoke (flags); + #endif + + // void skottie_animation_builder_set_font_manager(skottie_animation_builder_t* instance, sk_fontmgr_t* fontManager) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void skottie_animation_builder_set_font_manager (skottie_animation_builder_t instance, sk_fontmgr_t fontManager); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void skottie_animation_builder_set_font_manager (skottie_animation_builder_t instance, sk_fontmgr_t fontManager); + } + private static Delegates.skottie_animation_builder_set_font_manager skottie_animation_builder_set_font_manager_delegate; + internal static void skottie_animation_builder_set_font_manager (skottie_animation_builder_t instance, sk_fontmgr_t fontManager) => + (skottie_animation_builder_set_font_manager_delegate ??= GetSymbol ("skottie_animation_builder_set_font_manager")).Invoke (instance, fontManager); + #endif + + // void skottie_animation_builder_set_resource_provider(skottie_animation_builder_t* instance, skottie_resource_provider_t* resourceProvider) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void skottie_animation_builder_set_resource_provider (skottie_animation_builder_t instance, skottie_resource_provider_t resourceProvider); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void skottie_animation_builder_set_resource_provider (skottie_animation_builder_t instance, skottie_resource_provider_t resourceProvider); + } + private static Delegates.skottie_animation_builder_set_resource_provider skottie_animation_builder_set_resource_provider_delegate; + internal static void skottie_animation_builder_set_resource_provider (skottie_animation_builder_t instance, skottie_resource_provider_t resourceProvider) => + (skottie_animation_builder_set_resource_provider_delegate ??= GetSymbol ("skottie_animation_builder_set_resource_provider")).Invoke (instance, resourceProvider); + #endif + // void skottie_animation_delete(skottie_animation_t* instance) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -201,20 +332,6 @@ internal static void skottie_animation_get_version (skottie_animation_t instance (skottie_animation_get_version_delegate ??= GetSymbol ("skottie_animation_get_version")).Invoke (instance, version); #endif - // void skottie_animation_keepalive() - #if !USE_DELEGATES - [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] - internal static extern void skottie_animation_keepalive (); - #else - private partial class Delegates { - [UnmanagedFunctionPointer (CallingConvention.Cdecl)] - internal delegate void skottie_animation_keepalive (); - } - private static Delegates.skottie_animation_keepalive skottie_animation_keepalive_delegate; - internal static void skottie_animation_keepalive () => - (skottie_animation_keepalive_delegate ??= GetSymbol ("skottie_animation_keepalive")).Invoke (); - #endif - // skottie_animation_t* skottie_animation_make_from_data(const char* data, size_t length) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -382,12 +499,68 @@ internal static void skottie_animation_unref (skottie_animation_t instance) => #region Structs +namespace SkiaSharp.Skottie { + + // skottie_animation_builder_stats_t + [StructLayout (LayoutKind.Sequential)] + public readonly unsafe partial struct AnimationBuilderStats : IEquatable { + // public float fTotalLoadTimeMS + private readonly Single fTotalLoadTimeMS; + + // public float fJsonParseTimeMS + private readonly Single fJsonParseTimeMS; + + // public float fSceneParseTimeMS + private readonly Single fSceneParseTimeMS; + + // public size_t fJsonSize + private readonly /* size_t */ IntPtr fJsonSize; + + // public size_t fAnimatorCount + private readonly /* size_t */ IntPtr fAnimatorCount; + + public readonly bool Equals (AnimationBuilderStats obj) => + fTotalLoadTimeMS == obj.fTotalLoadTimeMS && fJsonParseTimeMS == obj.fJsonParseTimeMS && fSceneParseTimeMS == obj.fSceneParseTimeMS && fJsonSize == obj.fJsonSize && fAnimatorCount == obj.fAnimatorCount; + + public readonly override bool Equals (object obj) => + obj is AnimationBuilderStats f && Equals (f); + + public static bool operator == (AnimationBuilderStats left, AnimationBuilderStats right) => + left.Equals (right); + + public static bool operator != (AnimationBuilderStats left, AnimationBuilderStats right) => + !left.Equals (right); + + public readonly override int GetHashCode () + { + var hash = new HashCode (); + hash.Add (fTotalLoadTimeMS); + hash.Add (fJsonParseTimeMS); + hash.Add (fSceneParseTimeMS); + hash.Add (fJsonSize); + hash.Add (fAnimatorCount); + return hash.ToHashCode (); + } + + } +} + #endregion #region Enums namespace SkiaSharp.Skottie { + // skottie_animation_builder_flags_t + public enum AnimationBuilderFlags { + // NONE_SKOTTIE_ANIMATION_BUILDER_FLAGS = 0 + None = 0, + // DEFER_IMAGE_LOADING_SKOTTIE_ANIMATION_BUILDER_FLAGS = 0x01 + DeferImageLoading = 1, + // PREFER_EMBEDDED_FONTS_SKOTTIE_ANIMATION_BUILDER_FLAGS = 0x02 + PreferEmbeddedFonts = 2, + } + // skottie_animation_renderflags_t [Flags] public enum AnimationRenderFlags { diff --git a/binding/SkiaSharp/GRBackendTexture.cs b/binding/SkiaSharp/GRBackendTexture.cs index 603731f457..254cc3c708 100644 --- a/binding/SkiaSharp/GRBackendTexture.cs +++ b/binding/SkiaSharp/GRBackendTexture.cs @@ -25,8 +25,6 @@ public GRBackendTexture (int width, int height, GRVkImageInfo vkInfo) CreateVulkan (width, height, vkInfo); } -#if __IOS__ || __MACOS__ - public GRBackendTexture (int width, int height, bool mipmapped, GRMtlTextureInfo mtlInfo) : this (IntPtr.Zero, true) { @@ -38,8 +36,6 @@ public GRBackendTexture (int width, int height, bool mipmapped, GRMtlTextureInfo } } -#endif - private void CreateGl (int width, int height, bool mipmapped, GRGlTextureInfo glInfo) { Handle = SkiaApi.gr_backendtexture_new_gl (width, height, mipmapped, &glInfo); diff --git a/binding/SkiaSharp/GRContext.cs b/binding/SkiaSharp/GRContext.cs index 70a50e67a4..55071e4187 100644 --- a/binding/SkiaSharp/GRContext.cs +++ b/binding/SkiaSharp/GRContext.cs @@ -63,8 +63,6 @@ public static GRContext CreateVulkan (GRVkBackendContext backendContext, GRConte } } -#if __IOS__ || __MACOS__ - // CreateMetal public static GRContext CreateMetal (GRMtlBackendContext backendContext) => @@ -75,19 +73,17 @@ public static GRContext CreateMetal (GRMtlBackendContext backendContext, GRConte if (backendContext == null) throw new ArgumentNullException (nameof (backendContext)); - var device = backendContext.Device; - var queue = backendContext.Queue; + var device = backendContext.DeviceHandle; + var queue = backendContext.QueueHandle; if (options == null) { - return GetObject (SkiaApi.gr_direct_context_make_metal ((void*)(IntPtr)device.Handle, (void*)(IntPtr)queue.Handle)); + return GetObject (SkiaApi.gr_direct_context_make_metal ((void*)device, (void*)queue)); } else { var opts = options.ToNative (); - return GetObject (SkiaApi.gr_direct_context_make_metal_with_options ((void*)(IntPtr)device.Handle, (void*)(IntPtr)queue.Handle, &opts)); + return GetObject (SkiaApi.gr_direct_context_make_metal_with_options ((void*)device, (void*)queue, &opts)); } } -#endif - // public override GRBackend Backend => base.Backend; diff --git a/binding/SkiaSharp/GRDefinitions.cs b/binding/SkiaSharp/GRDefinitions.cs index 54c9a46ad9..ed6c3facb0 100644 --- a/binding/SkiaSharp/GRDefinitions.cs +++ b/binding/SkiaSharp/GRDefinitions.cs @@ -74,24 +74,48 @@ public GRGlTextureInfo (uint target, uint id, uint format) } } -#if __IOS__ || __MACOS__ - public unsafe partial struct GRMtlTextureInfo { + private IntPtr _textureHandle; + + public GRMtlTextureInfo (IntPtr textureHandle) + { + TextureHandle = textureHandle; + } + + public IntPtr TextureHandle { + readonly get => _textureHandle; + set { + _textureHandle = value; +#if __IOS__ || __MACOS__ + _texture = null; +#endif + } + } + +#if __IOS__ || __MACOS__ + private Metal.IMTLTexture _texture; public GRMtlTextureInfo (Metal.IMTLTexture texture) { Texture = texture; } - public Metal.IMTLTexture Texture { get; set; } + public Metal.IMTLTexture Texture { + readonly get => _texture; + set { + _texture = value; + _textureHandle = _texture.Handle; + } + } +#endif internal GRMtlTextureInfoNative ToNative () => new GRMtlTextureInfoNative { - fTexture = (void*)(IntPtr)Texture.Handle + fTexture = (void*)TextureHandle }; public readonly bool Equals (GRMtlTextureInfo obj) => - Texture == obj.Texture; + TextureHandle == obj.TextureHandle; public readonly override bool Equals (object obj) => obj is GRMtlTextureInfo f && Equals (f); @@ -105,13 +129,11 @@ public readonly override bool Equals (object obj) => public readonly override int GetHashCode () { var hash = new HashCode (); - hash.Add (Texture); + hash.Add (TextureHandle); return hash.ToHashCode (); } } -#endif - public static partial class SkiaExtensions { public static uint ToGlSizedFormat (this SKColorType colorType) => diff --git a/binding/SkiaSharp/GRMtlBackendContext.cs b/binding/SkiaSharp/GRMtlBackendContext.cs index aba9670b9a..9c2aa28112 100644 --- a/binding/SkiaSharp/GRMtlBackendContext.cs +++ b/binding/SkiaSharp/GRMtlBackendContext.cs @@ -1,16 +1,56 @@ #nullable disable -#if __IOS__ || __MACOS__ using System; +#if __IOS__ || __MACOS__ using Metal; +#endif namespace SkiaSharp { public class GRMtlBackendContext : IDisposable { - public IMTLDevice Device { get; set; } + private IntPtr _deviceHandle, _queueHandle; + + public IntPtr DeviceHandle { + get => _deviceHandle; + set { + _deviceHandle = value; +#if __IOS__ || __MACOS__ + _device = null; +#endif + } + } + + public IntPtr QueueHandle { + get => _queueHandle; + set { + _queueHandle = value; +#if __IOS__ || __MACOS__ + _queue = null; +#endif + } + } - public IMTLCommandQueue Queue { get; set; } +#if __IOS__ || __MACOS__ + private IMTLDevice _device; + private IMTLCommandQueue _queue; + + public IMTLDevice Device { + get => _device; + set { + _device = value; + _deviceHandle = _device.Handle; + } + } + + public IMTLCommandQueue Queue { + get => _queue; + set { + _queue = value; + _queueHandle = _queue.Handle; + } + } +#endif protected virtual void Dispose (bool disposing) { @@ -23,4 +63,3 @@ public void Dispose () } } } -#endif diff --git a/binding/SkiaSharp/Properties/SkiaSharpAssemblyInfo.cs b/binding/SkiaSharp/Properties/SkiaSharpAssemblyInfo.cs index 5b6906f879..8d994ffb6c 100644 --- a/binding/SkiaSharp/Properties/SkiaSharpAssemblyInfo.cs +++ b/binding/SkiaSharp/Properties/SkiaSharpAssemblyInfo.cs @@ -45,6 +45,13 @@ "dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" + "65d016df")] +[assembly: InternalsVisibleTo("SkiaSharp.Resources, PublicKey=" + + "002400000480000094000000060200000024000052534131000400000100010079159977d2d03a" + + "8e6bea7a2e74e8d1afcc93e8851974952bb480a12c9134474d04062447c37e0e68c080536fcf3c" + + "3fbe2ff9c979ce998475e506e8ce82dd5b0f350dc10e93bf2eeecf874b24770c5081dbea7447fd" + + "dafa277b22de47d6ffea449674a4f9fccf84d15069089380284dbdd35f46cdff12a1bd78e4ef00" + + "65d016df")] + [assembly: AssemblyMetadata("IsTrimmable", "True")] #if __IOS__ || __TVOS__ || __MACOS__ diff --git a/binding/SkiaSharp/SKBlender.cs b/binding/SkiaSharp/SKBlender.cs new file mode 100644 index 0000000000..e4a82adede --- /dev/null +++ b/binding/SkiaSharp/SKBlender.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; + +namespace SkiaSharp; + +public unsafe class SKBlender : SKObject, ISKReferenceCounted +{ + private static readonly Dictionary blendModeBlenders; + + static SKBlender () + { + // TODO: This is not the best way to do this as it will create a lot of objects that + // might not be needed, but it is the only way to ensure that the static + // instances are created before any access is made to them. + // See more info: SKObject.EnsureStaticInstanceAreInitialized() + + var modes = Enum.GetValues (typeof (SKBlendMode)); + blendModeBlenders = new Dictionary (modes.Length); + foreach (SKBlendMode mode in modes) + { + blendModeBlenders [mode] = new SKBlenderStatic (SkiaApi.sk_blender_new_mode (mode)); + } + } + + internal static void EnsureStaticInstanceAreInitialized () + { + // IMPORTANT: do not remove to ensure that the static instances + // are initialized before any access is made to them + } + + internal SKBlender(IntPtr handle, bool owns) + : base (handle, owns) + { + } + + protected override void Dispose (bool disposing) => + base.Dispose (disposing); + + public static SKBlender CreateBlendMode (SKBlendMode mode) + { + if (!blendModeBlenders.TryGetValue (mode, out var value)) + throw new ArgumentOutOfRangeException (nameof (mode)); + return value; + } + + public static SKBlender CreateArithmetic (float k1, float k2, float k3, float k4, bool enforcePMColor) => + GetObject (SkiaApi.sk_blender_new_arithmetic (k1, k2, k3, k4, enforcePMColor)); + + internal static SKBlender GetObject (IntPtr handle) => + GetOrAddObject (handle, (h, o) => new SKBlender (h, o)); + + // + + private sealed class SKBlenderStatic : SKBlender + { + internal SKBlenderStatic (IntPtr x) + : base (x, false) + { + } + + protected override void Dispose (bool disposing) { } + } +} diff --git a/binding/SkiaSharp/SKCanvas.cs b/binding/SkiaSharp/SKCanvas.cs index b4124c5b96..e5a0dbfc68 100644 --- a/binding/SkiaSharp/SKCanvas.cs +++ b/binding/SkiaSharp/SKCanvas.cs @@ -856,6 +856,10 @@ public void ResetMatrix () public void SetMatrix (in SKMatrix matrix) => SetMatrix ((SKMatrix44)matrix); + [Obsolete("Use SetMatrix(in SKMatrix) instead.", true)] + public void SetMatrix (SKMatrix matrix) => + SetMatrix (in matrix); + public void SetMatrix (in SKMatrix44 matrix) { fixed (SKMatrix44* ptr = &matrix) { diff --git a/binding/SkiaSharp/SKColorSpace.cs b/binding/SkiaSharp/SKColorSpace.cs index 1b5680df8f..a639dac46f 100644 --- a/binding/SkiaSharp/SKColorSpace.cs +++ b/binding/SkiaSharp/SKColorSpace.cs @@ -12,6 +12,11 @@ public unsafe class SKColorSpace : SKObject, ISKNonVirtualReferenceCounted static SKColorSpace () { + // TODO: This is not the best way to do this as it will create a lot of objects that + // might not be needed, but it is the only way to ensure that the static + // instances are created before any access is made to them. + // See more info: SKObject.EnsureStaticInstanceAreInitialized() + srgb = new SKColorSpaceStatic (SkiaApi.sk_colorspace_new_srgb ()); srgbLinear = new SKColorSpaceStatic (SkiaApi.sk_colorspace_new_srgb_linear ()); } diff --git a/binding/SkiaSharp/SKData.cs b/binding/SkiaSharp/SKData.cs index 5bb53d47ca..af8f1f857f 100644 --- a/binding/SkiaSharp/SKData.cs +++ b/binding/SkiaSharp/SKData.cs @@ -19,6 +19,11 @@ public unsafe class SKData : SKObject, ISKNonVirtualReferenceCounted static SKData () { + // TODO: This is not the best way to do this as it will create a lot of objects that + // might not be needed, but it is the only way to ensure that the static + // instances are created before any access is made to them. + // See more info: SKObject.EnsureStaticInstanceAreInitialized() + empty = new SKDataStatic (SkiaApi.sk_data_new_empty ()); } @@ -156,7 +161,11 @@ public static SKData Create (SKStream stream, int length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr)length)); + try { + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr)length)); + } finally { + GC.KeepAlive(stream); + } } public static SKData Create (SKStream stream, ulong length) @@ -164,7 +173,11 @@ public static SKData Create (SKStream stream, ulong length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr)length)); + try { + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr)length)); + } finally { + GC.KeepAlive(stream); + } } public static SKData Create (SKStream stream, long length) @@ -172,7 +185,11 @@ public static SKData Create (SKStream stream, long length) if (stream == null) throw new ArgumentNullException (nameof (stream)); - return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr)length)); + try { + return GetObject (SkiaApi.sk_data_new_from_stream (stream.Handle, (IntPtr)length)); + } finally { + GC.KeepAlive(stream); + } } public static SKData Create (IntPtr address, int length) diff --git a/binding/SkiaSharp/SKFontManager.cs b/binding/SkiaSharp/SKFontManager.cs index 4fa74bac7f..737b875155 100644 --- a/binding/SkiaSharp/SKFontManager.cs +++ b/binding/SkiaSharp/SKFontManager.cs @@ -14,6 +14,11 @@ public unsafe class SKFontManager : SKObject, ISKReferenceCounted static SKFontManager () { + // TODO: This is not the best way to do this as it will create a lot of objects that + // might not be needed, but it is the only way to ensure that the static + // instances are created before any access is made to them. + // See more info: SKObject.EnsureStaticInstanceAreInitialized() + defaultManager = new SKFontManagerStatic (SkiaApi.sk_fontmgr_ref_default ()); } diff --git a/binding/SkiaSharp/SKImage.cs b/binding/SkiaSharp/SKImage.cs index 834b05519b..4f4f3ff612 100644 --- a/binding/SkiaSharp/SKImage.cs +++ b/binding/SkiaSharp/SKImage.cs @@ -415,6 +415,26 @@ public SKShader ToShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamp private SKShader ToShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamplingOptions sampling, SKMatrix* localMatrix) => SKShader.GetObject (SkiaApi.sk_image_make_shader (Handle, tileX, tileY, &sampling, localMatrix)); + // ToRawShader + + public SKShader ToRawShader () => + ToRawShader (SKShaderTileMode.Clamp, SKShaderTileMode.Clamp, SKSamplingOptions.Default, null); + + public SKShader ToRawShader (SKShaderTileMode tileX, SKShaderTileMode tileY) => + ToRawShader (tileX, tileY, SKSamplingOptions.Default, null); + + public SKShader ToRawShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKMatrix localMatrix) => + ToRawShader (tileX, tileY, SKSamplingOptions.Default, &localMatrix); + + public SKShader ToRawShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamplingOptions sampling) => + ToRawShader (tileX, tileY, sampling, null); + + public SKShader ToRawShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamplingOptions sampling, SKMatrix localMatrix) => + ToRawShader (tileX, tileY, sampling, &localMatrix); + + private SKShader ToRawShader (SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamplingOptions sampling, SKMatrix* localMatrix) => + SKShader.GetObject (SkiaApi.sk_image_make_raw_shader (Handle, tileX, tileY, &sampling, localMatrix)); + // PeekPixels public bool PeekPixels (SKPixmap pixmap) diff --git a/binding/SkiaSharp/SKImageFilter.cs b/binding/SkiaSharp/SKImageFilter.cs index 91f106f923..45eea572e3 100644 --- a/binding/SkiaSharp/SKImageFilter.cs +++ b/binding/SkiaSharp/SKImageFilter.cs @@ -14,6 +14,14 @@ protected override void Dispose (bool disposing) => // CreateMatrix + [Obsolete("Use SetMatrix(in SKMatrix) instead.", true)] + public static SKImageFilter CreateMatrix (SKMatrix matrix) => + CreateMatrix (in matrix); + + [Obsolete("Use SetMatrix(in SKMatrix, SKSamplingOptions, SKImageFilter) instead.", true)] + public static SKImageFilter CreateMatrix (SKMatrix matrix, SKFilterQuality quality, SKImageFilter? input) => + CreateMatrix (in matrix, quality.ToSamplingOptions (), input); + public static SKImageFilter CreateMatrix (in SKMatrix matrix) => CreateMatrix (matrix, SKSamplingOptions.Default, null); @@ -26,18 +34,6 @@ public static SKImageFilter CreateMatrix (in SKMatrix matrix, SKSamplingOptions return GetObject (SkiaApi.sk_imagefilter_new_matrix_transform (m, &sampling, input?.Handle ?? IntPtr.Zero)); } - - // CreateAlphaThreshold - - public static SKImageFilter CreateAlphaThreshold (SKRegion region, float innerThreshold, float outerThreshold) => - CreateAlphaThreshold (region, innerThreshold, outerThreshold, null); - - public static SKImageFilter CreateAlphaThreshold (SKRegion region, float innerThreshold, float outerThreshold, SKImageFilter? input) - { - _ = region ?? throw new ArgumentNullException (nameof (region)); - return GetObject (SkiaApi.sk_imagefilter_new_alpha_threshold (region.Handle, innerThreshold, outerThreshold, input?.Handle ?? IntPtr.Zero)); - } - // CreateBlur public static SKImageFilter CreateBlur (float sigmaX, float sigmaY) => @@ -345,6 +341,23 @@ public static SKImageFilter CreateBlendMode (SKBlendMode mode, SKImageFilter? ba private static SKImageFilter CreateBlendMode (SKBlendMode mode, SKImageFilter? background, SKImageFilter? foreground, SKRect* cropRect) => GetObject (SkiaApi.sk_imagefilter_new_blend (mode, background?.Handle ?? IntPtr.Zero, foreground?.Handle ?? IntPtr.Zero, cropRect)); + // CreateBlendMode (Blender) + + public static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background) => + CreateBlendMode (blender, background, null, null); + + public static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background, SKImageFilter? foreground) => + CreateBlendMode (blender, background, foreground, null); + + public static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background, SKImageFilter? foreground, SKRect cropRect) => + CreateBlendMode (blender, background, foreground, &cropRect); + + private static SKImageFilter CreateBlendMode (SKBlender blender, SKImageFilter? background, SKImageFilter? foreground, SKRect* cropRect) + { + _ = blender ?? throw new ArgumentNullException (nameof (blender)); + return GetObject (SkiaApi.sk_imagefilter_new_blender (blender.Handle, background?.Handle ?? IntPtr.Zero, foreground?.Handle ?? IntPtr.Zero, cropRect)); + } + // CreateArithmetic public static SKImageFilter CreateArithmetic (float k1, float k2, float k3, float k4, bool enforcePMColor, SKImageFilter? background) => @@ -376,6 +389,10 @@ public static SKImageFilter CreateImage (SKImage image, SKRect src, SKRect dst, return GetObject (SkiaApi.sk_imagefilter_new_image (image.Handle, &src, &dst, &sampling)); } + [Obsolete("Use CreateImage(SKImage, SKRect, SKRect, SKSamplingOptions) instead.", true)] + public static SKImageFilter CreateImage (SKImage image, SKRect src, SKRect dst, SKFilterQuality filterQuality) => + CreateImage (image, src, dst, filterQuality.ToSamplingOptions ()); + // CreateMagnifier public static SKImageFilter CreateMagnifier (SKRect lensBounds, float zoomAmount, float inset, SKSamplingOptions sampling) => @@ -390,6 +407,22 @@ public static SKImageFilter CreateMagnifier (SKRect lensBounds, float zoomAmount private static SKImageFilter CreateMagnifier (SKRect lensBounds, float zoomAmount, float inset, SKSamplingOptions sampling, SKImageFilter? input, SKRect* cropRect) => GetObject (SkiaApi.sk_imagefilter_new_magnifier (&lensBounds, zoomAmount, inset, &sampling, input?.Handle ?? IntPtr.Zero, cropRect)); + // CreatePaint + + [Obsolete("Use CreateShader(SKShader) instead.", true)] + public static SKImageFilter CreatePaint (SKPaint paint) + { + _ = paint ?? throw new ArgumentNullException (nameof (paint)); + return CreateShader(paint.Shader, paint.IsDither, null); + } + + [Obsolete("Use CreateShader(SKShader, bool, SKRect) instead.", true)] + public static SKImageFilter CreatePaint (SKPaint paint, SKRect cropRect) + { + _ = paint ?? throw new ArgumentNullException (nameof (paint)); + return CreateShader(paint.Shader, paint.IsDither, &cropRect); + } + // CreateShader public static SKImageFilter CreateShader (SKShader? shader) => diff --git a/binding/SkiaSharp/SKMatrix44.cs b/binding/SkiaSharp/SKMatrix44.cs index dfbe3754df..8c44538d4a 100644 --- a/binding/SkiaSharp/SKMatrix44.cs +++ b/binding/SkiaSharp/SKMatrix44.cs @@ -2,6 +2,7 @@ using System; using System.Numerics; +using System.Runtime.CompilerServices; namespace SkiaSharp { @@ -348,46 +349,46 @@ public static SKMatrix44 Multiply (SKMatrix44 value1, float value2) => public SKMatrix Matrix => new SKMatrix ( - m00, m01, m03, - m10, m11, m13, - m30, m31, m33); + m00, m10, m30, + m01, m11, m31, + m03, m13, m33); public float this[int row, int column] { - get => column switch { - 0 => row switch { + get => row switch { + 0 => column switch { 0 => m00, 1 => m01, 2 => m02, 3 => m03, - _ => throw new ArgumentOutOfRangeException (nameof (row)) + _ => throw new ArgumentOutOfRangeException (nameof (column)) }, - 1 => row switch { + 1 => column switch { 0 => m10, 1 => m11, 2 => m12, 3 => m13, - _ => throw new ArgumentOutOfRangeException (nameof (row)) + _ => throw new ArgumentOutOfRangeException (nameof (column)) }, - 2 => row switch { + 2 => column switch { 0 => m20, 1 => m21, 2 => m22, 3 => m23, - _ => throw new ArgumentOutOfRangeException (nameof (row)) + _ => throw new ArgumentOutOfRangeException (nameof (column)) }, - 3 => row switch { + 3 => column switch { 0 => m30, 1 => m31, 2 => m32, 3 => m33, - _ => throw new ArgumentOutOfRangeException (nameof (row)) + _ => throw new ArgumentOutOfRangeException (nameof (column)) }, - _ => throw new ArgumentOutOfRangeException (nameof (column)) + _ => throw new ArgumentOutOfRangeException (nameof (row)) }; set { - switch (column) { + switch (row) { case 0: - switch (row) { + switch (column) { case 0: m00 = value; break; @@ -401,11 +402,11 @@ public static SKMatrix44 Multiply (SKMatrix44 value1, float value2) => m03 = value; break; default: - throw new ArgumentOutOfRangeException (nameof (row)); + throw new ArgumentOutOfRangeException (nameof (column)); }; break; case 1: - switch (row) { + switch (column) { case 0: m10 = value; break; @@ -419,11 +420,11 @@ public static SKMatrix44 Multiply (SKMatrix44 value1, float value2) => m13 = value; break; default: - throw new ArgumentOutOfRangeException (nameof (row)); + throw new ArgumentOutOfRangeException (nameof (column)); }; break; case 2: - switch (row) { + switch (column) { case 0: m20 = value; break; @@ -437,11 +438,11 @@ public static SKMatrix44 Multiply (SKMatrix44 value1, float value2) => m23 = value; break; default: - throw new ArgumentOutOfRangeException (nameof (row)); + throw new ArgumentOutOfRangeException (nameof (column)); }; break; case 3: - switch (row) { + switch (column) { case 0: m30 = value; break; @@ -455,11 +456,11 @@ public static SKMatrix44 Multiply (SKMatrix44 value1, float value2) => m33 = value; break; default: - throw new ArgumentOutOfRangeException (nameof (row)); + throw new ArgumentOutOfRangeException (nameof (column)); }; break; default: - throw new ArgumentOutOfRangeException (nameof (column)); + throw new ArgumentOutOfRangeException (nameof (row)); }; } } @@ -468,23 +469,15 @@ public static SKMatrix44 Multiply (SKMatrix44 value1, float value2) => public static implicit operator SKMatrix44 (SKMatrix matrix) => new SKMatrix44 ( - matrix.ScaleX, matrix.SkewX, 0, matrix.TransX, - matrix.SkewY, matrix.ScaleY, 0, matrix.TransY, + matrix.ScaleX, matrix.SkewY, 0, matrix.Persp0, + matrix.SkewX, matrix.ScaleY, 0, matrix.Persp1, 0, 0, 1, 0, - matrix.Persp0, matrix.Persp1, 0, matrix.Persp2); + matrix.TransX, matrix.TransY, 0, matrix.Persp2); public static implicit operator Matrix4x4 (SKMatrix44 matrix) => - new Matrix4x4 ( - matrix.m00, matrix.m10, matrix.m20, matrix.m30, - matrix.m01, matrix.m11, matrix.m21, matrix.m31, - matrix.m02, matrix.m12, matrix.m22, matrix.m32, - matrix.m03, matrix.m13, matrix.m23, matrix.m33); + Unsafe.As (ref matrix); public static implicit operator SKMatrix44 (Matrix4x4 matrix) => - new SKMatrix44 ( - matrix.M11, matrix.M21, matrix.M31, matrix.M41, - matrix.M12, matrix.M22, matrix.M32, matrix.M42, - matrix.M13, matrix.M23, matrix.M33, matrix.M43, - matrix.M14, matrix.M24, matrix.M34, matrix.M44); + Unsafe.As (ref matrix); } } diff --git a/binding/SkiaSharp/SKObject.cs b/binding/SkiaSharp/SKObject.cs index aad6bf8cd7..ddaae8b879 100644 --- a/binding/SkiaSharp/SKObject.cs +++ b/binding/SkiaSharp/SKObject.cs @@ -44,6 +44,7 @@ static SKObject () SKData.EnsureStaticInstanceAreInitialized (); SKFontManager.EnsureStaticInstanceAreInitialized (); SKTypeface.EnsureStaticInstanceAreInitialized (); + SKBlender.EnsureStaticInstanceAreInitialized (); } internal SKObject (IntPtr handle, bool owns) @@ -195,7 +196,7 @@ internal static T Owned (T owner, SKObject child) return owner; } - // indicate that the chile should not be garbage collected while + // indicate that the child should not be garbage collected while // the owner still lives internal static T Referenced (T owner, SKObject child) where T : SKObject @@ -350,11 +351,19 @@ public static int GetReferenceCount (this ISKReferenceCounted obj) } } + /// + /// This should be implemented on all types that inherit directly or + /// indirectly from SkRefCnt or SkRefCntBase + /// internal interface ISKReferenceCounted { IntPtr Handle { get; } } + /// + /// This should be implemented on all types that inherit directly or + /// indirectly from SkNVRefCnt + /// internal interface ISKNonVirtualReferenceCounted : ISKReferenceCounted { void ReferenceNative (); @@ -362,6 +371,12 @@ internal interface ISKNonVirtualReferenceCounted : ISKReferenceCounted void UnreferenceNative (); } + /// + /// This should be implemented on all types that can skip the expensive + /// registration in the global dictionary. Typically this would be the case + /// if the type os _only_ constructed by the user and not provided as a + /// return type for _any_ member. + /// internal interface ISKSkipObjectRegistration { } diff --git a/binding/SkiaSharp/SKPaint.cs b/binding/SkiaSharp/SKPaint.cs index 09dde1ff23..1e8d1be424 100644 --- a/binding/SkiaSharp/SKPaint.cs +++ b/binding/SkiaSharp/SKPaint.cs @@ -203,6 +203,11 @@ public SKBlendMode BlendMode { set => SkiaApi.sk_paint_set_blendmode (Handle, value); } + public SKBlender Blender { + get => SKBlender.GetObject (SkiaApi.sk_paint_get_blender (Handle)); + set => SkiaApi.sk_paint_set_blender (Handle, value == null ? IntPtr.Zero : value.Handle); + } + [Obsolete ($"Use {nameof (SKSamplingOptions)} instead.")] public SKFilterQuality FilterQuality { get => (SKFilterQuality)SkiaApi.sk_compatpaint_get_filter_quality (Handle); diff --git a/binding/SkiaSharp/SKPath.cs b/binding/SkiaSharp/SKPath.cs index d1a0d7f0e1..d4b36fbe8c 100644 --- a/binding/SkiaSharp/SKPath.cs +++ b/binding/SkiaSharp/SKPath.cs @@ -181,8 +181,11 @@ public bool Contains (float x, float y) => public void Offset (SKPoint offset) => Offset (offset.X, offset.Y); - public void Offset (float dx, float dy) => - Transform (SKMatrix.CreateTranslation (dx, dy)); + public void Offset (float dx, float dy) + { + var matrix = SKMatrix.CreateTranslation (dx, dy); + Transform (in matrix); + } public void MoveTo (SKPoint point) => SkiaApi.sk_path_move_to (Handle, point.X, point.Y); @@ -340,6 +343,14 @@ public void Transform (in SKMatrix matrix, SKPath destination) SkiaApi.sk_path_transform_to_dest (Handle, m, destination.Handle); } + [Obsolete("Use Transform(in SKMatrix) instead.", true)] + public void Transform (SKMatrix matrix) => + Transform (in matrix); + + [Obsolete("Use Transform(in SKMatrix matrix, SKPath destination) instead.", true)] + public void Transform (SKMatrix matrix, SKPath destination) => + Transform (in matrix, destination); + public void AddPath (SKPath other, float dx, float dy, SKPathAddMode mode = SKPathAddMode.Append) { if (other == null) diff --git a/binding/SkiaSharp/SKRunBuffer.cs b/binding/SkiaSharp/SKRunBuffer.cs index 8f4916104e..65831136ef 100644 --- a/binding/SkiaSharp/SKRunBuffer.cs +++ b/binding/SkiaSharp/SKRunBuffer.cs @@ -1,10 +1,11 @@ #nullable disable using System; -using System.ComponentModel; namespace SkiaSharp { + // Base + public unsafe class SKRunBuffer { internal readonly SKRunBufferInternal internalBuffer; @@ -17,103 +18,142 @@ internal SKRunBuffer (SKRunBufferInternal buffer, int size) public int Size { get; } - public Span GetGlyphSpan () => - new Span (internalBuffer.glyphs, internalBuffer.glyphs == null ? 0 : Size); + public Span Glyphs => new (internalBuffer.glyphs, Size); + + public void SetGlyphs (ReadOnlySpan glyphs) => glyphs.CopyTo (Glyphs); - public void SetGlyphs (ReadOnlySpan glyphs) => - glyphs.CopyTo (GetGlyphSpan ()); + [Obsolete ("Use Glyphs instead.")] + public Span GetGlyphSpan () => Glyphs; } public sealed unsafe class SKHorizontalRunBuffer : SKRunBuffer { - internal SKHorizontalRunBuffer (SKRunBufferInternal buffer, int count) - : base (buffer, count) + internal SKHorizontalRunBuffer (SKRunBufferInternal buffer, int size) + : base (buffer, size) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + + [Obsolete ("Use Positions instead.")] + public Span GetPositionSpan () => Positions; } public sealed unsafe class SKPositionedRunBuffer : SKRunBuffer { - internal SKPositionedRunBuffer (SKRunBufferInternal buffer, int count) - : base (buffer, count) + internal SKPositionedRunBuffer (SKRunBufferInternal buffer, int size) + : base (buffer, size) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); + + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + [Obsolete ("Use Positions instead.")] + public Span GetPositionSpan () => Positions; } public sealed unsafe class SKRotationScaleRunBuffer : SKRunBuffer { - internal SKRotationScaleRunBuffer (SKRunBufferInternal buffer, int count) - : base (buffer, count) + internal SKRotationScaleRunBuffer (SKRunBufferInternal buffer, int size) + : base (buffer, size) { } - public Span GetRotationScaleSpan () => - new Span (internalBuffer.pos, Size); + public Span Positions => new (internalBuffer.pos, Size); - public void SetRotationScale (ReadOnlySpan positions) => - positions.CopyTo (GetRotationScaleSpan ()); + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + + [Obsolete ("Use Positions instead.")] + public Span GetRotationScaleSpan () => Positions; + + [Obsolete ("Use SetPositions instead.")] + public void SetRotationScale (ReadOnlySpan positions) => SetPositions (positions); } + // Text + public unsafe class SKTextRunBuffer : SKRunBuffer { - internal SKTextRunBuffer (SKRunBufferInternal buffer, int count, int textSize) - : base (buffer, count) + internal SKTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size) { TextSize = textSize; } public int TextSize { get; } - public Span GetTextSpan () => - new Span (internalBuffer.utf8text, internalBuffer.utf8text == null ? 0 : TextSize); + public Span Text => new (internalBuffer.utf8text, TextSize); - public Span GetClusterSpan () => - new Span (internalBuffer.clusters, internalBuffer.clusters == null ? 0 : Size); + public Span Clusters => new (internalBuffer.clusters, Size); - public void SetText (ReadOnlySpan text) => - text.CopyTo (GetTextSpan ()); + public void SetText (ReadOnlySpan text) => text.CopyTo (Text); - public void SetClusters (ReadOnlySpan clusters) => - clusters.CopyTo (GetClusterSpan ()); + public void SetClusters (ReadOnlySpan clusters) => clusters.CopyTo (Clusters); } public sealed unsafe class SKHorizontalTextRunBuffer : SKTextRunBuffer { - internal SKHorizontalTextRunBuffer (SKRunBufferInternal buffer, int count, int textSize) - : base (buffer, count, textSize) + internal SKHorizontalTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size, textSize) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); } public sealed unsafe class SKPositionedTextRunBuffer : SKTextRunBuffer { - internal SKPositionedTextRunBuffer (SKRunBufferInternal buffer, int count, int textSize) - : base (buffer, count, textSize) + internal SKPositionedTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size, textSize) { } - public Span GetPositionSpan () => - new Span (internalBuffer.pos, internalBuffer.pos == null ? 0 : Size); + public Span Positions => new (internalBuffer.pos, Size); + + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + } + + public sealed unsafe class SKRotationScaleTextRunBuffer : SKTextRunBuffer + { + internal SKRotationScaleTextRunBuffer (SKRunBufferInternal buffer, int size, int textSize) + : base (buffer, size, textSize) + { + } + + public Span Positions => new (internalBuffer.pos, Size); + + public void SetPositions (ReadOnlySpan positions) => positions.CopyTo (Positions); + } + + // Raw / Struct + + public unsafe readonly struct SKRawRunBuffer + { + internal readonly SKRunBufferInternal buffer; + private readonly int size; + private readonly int posSize; + private readonly int textSize; + + internal SKRawRunBuffer (SKRunBufferInternal buffer, int size, int posSize, int textSize) + { + this.buffer = buffer; + this.size = size; + this.posSize = posSize; + this.textSize = textSize; + } + + public Span Glyphs => new (buffer.glyphs, size); + + public Span Positions => new (buffer.pos, posSize); + + public Span Text => new (buffer.utf8text, textSize); - public void SetPositions (ReadOnlySpan positions) => - positions.CopyTo (GetPositionSpan ()); + public Span Clusters => new (buffer.clusters, size); } } diff --git a/binding/SkiaSharp/SKRuntimeEffect.cs b/binding/SkiaSharp/SKRuntimeEffect.cs index 8487aa8f86..9a26537938 100644 --- a/binding/SkiaSharp/SKRuntimeEffect.cs +++ b/binding/SkiaSharp/SKRuntimeEffect.cs @@ -41,6 +41,17 @@ public static SKRuntimeEffect CreateColorFilter (string sksl, out string errors) return effect; } + public static SKRuntimeEffect CreateBlender (string sksl, out string errors) + { + using var s = new SKString (sksl); + using var errorString = new SKString (); + var effect = GetObject (SkiaApi.sk_runtimeeffect_make_for_blender (s.Handle, errorString.Handle)); + errors = errorString?.ToString (); + if (errors?.Length == 0) + errors = null; + return effect; + } + // Build* public static SKRuntimeShaderBuilder BuildShader (string sksl) @@ -57,6 +68,13 @@ public static SKRuntimeColorFilterBuilder BuildColorFilter (string sksl) return new SKRuntimeColorFilterBuilder (effect); } + public static SKRuntimeBlenderBuilder BuildBlender (string sksl) + { + var effect = CreateBlender (sksl, out var errors); + ValidateResult (effect, errors); + return new SKRuntimeBlenderBuilder (effect); + } + private static void ValidateResult (SKRuntimeEffect effect, string errors) { if (effect is null) { @@ -148,6 +166,30 @@ private SKColorFilter ToColorFilter (SKData uniforms, SKObject[] children) } } + // ToBlender + + public SKBlender ToBlender () => + ToBlender ((SKData)null, null); + + public SKBlender ToBlender (SKRuntimeEffectUniforms uniforms) => + ToBlender (uniforms.ToData (), null); + + private SKBlender ToBlender (SKData uniforms) => + ToBlender (uniforms, null); + + public SKBlender ToBlender (SKRuntimeEffectUniforms uniforms, SKRuntimeEffectChildren children) => + ToBlender (uniforms.ToData (), children.ToArray ()); + + private SKBlender ToBlender (SKData uniforms, SKObject[] children) + { + var uniformsHandle = uniforms?.Handle ?? IntPtr.Zero; + using var childrenHandles = Utils.RentHandlesArray (children, true); + + fixed (IntPtr* ch = childrenHandles) { + return SKBlender.GetObject (SkiaApi.sk_runtimeeffect_make_blender (Handle, uniformsHandle, ch, (IntPtr)childrenHandles.Length)); + } + } + // internal static SKRuntimeEffect GetObject (IntPtr handle) => @@ -560,15 +602,24 @@ public SKRuntimeEffectChild (SKColorFilter colorFilter) value = colorFilter; } + public SKRuntimeEffectChild (SKBlender blender) + { + value = blender; + } + public SKObject Value => value; public SKShader Shader => value as SKShader; public SKColorFilter ColorFilter => value as SKColorFilter; + public SKBlender Blender => value as SKBlender; + public static implicit operator SKRuntimeEffectChild (SKShader shader) => new (shader); public static implicit operator SKRuntimeEffectChild (SKColorFilter colorFilter) => new (colorFilter); + + public static implicit operator SKRuntimeEffectChild (SKBlender blender) => new (blender); } public class SKRuntimeEffectBuilderException : ApplicationException @@ -627,4 +678,15 @@ public SKRuntimeColorFilterBuilder (SKRuntimeEffect effect) public SKColorFilter Build () => Effect.ToColorFilter (Uniforms, Children); } + + public class SKRuntimeBlenderBuilder : SKRuntimeEffectBuilder + { + public SKRuntimeBlenderBuilder (SKRuntimeEffect effect) + : base (effect) + { + } + + public SKBlender Build () => + Effect.ToBlender (Uniforms, Children); + } } diff --git a/binding/SkiaSharp/SKShader.cs b/binding/SkiaSharp/SKShader.cs index 9216985672..6069b57776 100644 --- a/binding/SkiaSharp/SKShader.cs +++ b/binding/SkiaSharp/SKShader.cs @@ -408,6 +408,23 @@ public static SKShader CreateCompose (SKShader shaderA, SKShader shaderB, SKBlen return GetObject (SkiaApi.sk_shader_new_blend (mode, shaderA.Handle, shaderB.Handle)); } + // CreateBlend + + public static SKShader CreateBlend (SKBlendMode mode, SKShader shaderA, SKShader shaderB) + { + _ = shaderA ?? throw new ArgumentNullException (nameof (shaderA)); + _ = shaderB ?? throw new ArgumentNullException (nameof (shaderB)); + return GetObject (SkiaApi.sk_shader_new_blend (mode, shaderA.Handle, shaderB.Handle)); + } + + public static SKShader CreateBlend (SKBlender blender, SKShader shaderA, SKShader shaderB) + { + _ = shaderA ?? throw new ArgumentNullException (nameof (shaderA)); + _ = shaderB ?? throw new ArgumentNullException (nameof (shaderB)); + _ = blender ?? throw new ArgumentNullException (nameof (blender)); + return GetObject (SkiaApi.sk_shader_new_blender (blender.Handle, shaderA.Handle, shaderB.Handle)); + } + // CreateColorFilter public static SKShader CreateColorFilter (SKShader shader, SKColorFilter filter) diff --git a/binding/SkiaSharp/SKTextBlob.cs b/binding/SkiaSharp/SKTextBlob.cs index 704b3e95b8..10193d25a0 100644 --- a/binding/SkiaSharp/SKTextBlob.cs +++ b/binding/SkiaSharp/SKTextBlob.cs @@ -1,7 +1,4 @@ -#nullable disable - -using System; -using System.ComponentModel; +using System; namespace SkiaSharp { @@ -31,27 +28,27 @@ public SKRect Bounds { // Create - public static SKTextBlob Create (string text, SKFont font, SKPoint origin = default) => + public static SKTextBlob? Create (string text, SKFont font, SKPoint origin = default) => Create (text.AsSpan (), font, origin); - public static SKTextBlob Create (ReadOnlySpan text, SKFont font, SKPoint origin = default) + public static SKTextBlob? Create (ReadOnlySpan text, SKFont font, SKPoint origin = default) { fixed (void* t = text) { return Create (t, text.Length * 2, SKTextEncoding.Utf16, font, origin); } } - public static SKTextBlob Create (IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin = default) => + public static SKTextBlob? Create (IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin = default) => Create (text.AsReadOnlySpan (length), encoding, font, origin); - public static SKTextBlob Create (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPoint origin = default) + public static SKTextBlob? Create (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPoint origin = default) { fixed (void* t = text) { return Create (t, text.Length, encoding, font, origin); } } - internal static SKTextBlob Create (void* text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin) + internal static SKTextBlob? Create (void* text, int length, SKTextEncoding encoding, SKFont font, SKPoint origin) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -61,35 +58,35 @@ internal static SKTextBlob Create (void* text, int length, SKTextEncoding encodi return null; using var builder = new SKTextBlobBuilder (); - var buffer = builder.AllocatePositionedRun (font, count); - font.GetGlyphs (text, length, encoding, buffer.GetGlyphSpan ()); - font.GetGlyphPositions (buffer.GetGlyphSpan (), buffer.GetPositionSpan (), origin); + var buffer = builder.AllocateRawPositionedRun (font, count); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + font.GetGlyphPositions (buffer.Glyphs, buffer.Positions, origin); return builder.Build (); } // CreateHorizontal - public static SKTextBlob CreateHorizontal (string text, SKFont font, ReadOnlySpan positions, float y) => + public static SKTextBlob? CreateHorizontal (string text, SKFont font, ReadOnlySpan positions, float y) => CreateHorizontal (text.AsSpan (), font, positions, y); - public static SKTextBlob CreateHorizontal (ReadOnlySpan text, SKFont font, ReadOnlySpan positions, float y) + public static SKTextBlob? CreateHorizontal (ReadOnlySpan text, SKFont font, ReadOnlySpan positions, float y) { fixed (void* t = text) { return CreateHorizontal (t, text.Length * 2, SKTextEncoding.Utf16, font, positions, y); } } - public static SKTextBlob CreateHorizontal (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) => + public static SKTextBlob? CreateHorizontal (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) => CreateHorizontal (text.AsReadOnlySpan (length), encoding, font, positions, y); - public static SKTextBlob CreateHorizontal (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) + public static SKTextBlob? CreateHorizontal (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) { fixed (void* t = text) { return CreateHorizontal (t, text.Length, encoding, font, positions, y); } } - internal static SKTextBlob CreateHorizontal (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) + internal static SKTextBlob? CreateHorizontal (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions, float y) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -99,35 +96,35 @@ internal static SKTextBlob CreateHorizontal (void* text, int length, SKTextEncod return null; using var builder = new SKTextBlobBuilder (); - var buffer = builder.AllocateHorizontalRun (font, count, y); - font.GetGlyphs (text, length, encoding, buffer.GetGlyphSpan ()); - positions.CopyTo (buffer.GetPositionSpan ()); + var buffer = builder.AllocateRawHorizontalRun (font, count, y); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + positions.CopyTo (buffer.Positions); return builder.Build (); } // CreatePositioned - public static SKTextBlob CreatePositioned (string text, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreatePositioned (string text, SKFont font, ReadOnlySpan positions) => CreatePositioned (text.AsSpan (), font, positions); - public static SKTextBlob CreatePositioned (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreatePositioned (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreatePositioned (t, text.Length * 2, SKTextEncoding.Utf16, font, positions); } } - public static SKTextBlob CreatePositioned (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreatePositioned (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => CreatePositioned (text.AsReadOnlySpan (length), encoding, font, positions); - public static SKTextBlob CreatePositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreatePositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreatePositioned (t, text.Length, encoding, font, positions); } } - internal static SKTextBlob CreatePositioned (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + internal static SKTextBlob? CreatePositioned (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -137,35 +134,35 @@ internal static SKTextBlob CreatePositioned (void* text, int length, SKTextEncod return null; using var builder = new SKTextBlobBuilder (); - var buffer = builder.AllocatePositionedRun (font, count); - font.GetGlyphs (text, length, encoding, buffer.GetGlyphSpan ()); - positions.CopyTo (buffer.GetPositionSpan ()); + var buffer = builder.AllocateRawPositionedRun (font, count); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + positions.CopyTo (buffer.Positions); return builder.Build (); } // CreateRotationScale - public static SKTextBlob CreateRotationScale (string text, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreateRotationScale (string text, SKFont font, ReadOnlySpan positions) => CreateRotationScale (text.AsSpan (), font, positions); - public static SKTextBlob CreateRotationScale (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreateRotationScale (ReadOnlySpan text, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreateRotationScale (t, text.Length * 2, SKTextEncoding.Utf16, font, positions); } } - public static SKTextBlob CreateRotationScale (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => + public static SKTextBlob? CreateRotationScale (IntPtr text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) => CreateRotationScale (text.AsReadOnlySpan (length), encoding, font, positions); - public static SKTextBlob CreateRotationScale (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + public static SKTextBlob? CreateRotationScale (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { fixed (void* t = text) { return CreateRotationScale (t, text.Length, encoding, font, positions); } } - internal static SKTextBlob CreateRotationScale (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) + internal static SKTextBlob? CreateRotationScale (void* text, int length, SKTextEncoding encoding, SKFont font, ReadOnlySpan positions) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -176,34 +173,34 @@ internal static SKTextBlob CreateRotationScale (void* text, int length, SKTextEn using var builder = new SKTextBlobBuilder (); var buffer = builder.AllocateRotationScaleRun (font, count); - font.GetGlyphs (text, length, encoding, buffer.GetGlyphSpan ()); - positions.CopyTo (buffer.GetRotationScaleSpan ()); + font.GetGlyphs (text, length, encoding, buffer.Glyphs); + positions.CopyTo (buffer.Positions); return builder.Build (); } // CreatePathPositioned - public static SKTextBlob CreatePathPositioned (string text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => + public static SKTextBlob? CreatePathPositioned (string text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => CreatePathPositioned (text.AsSpan (), font, path, textAlign, origin); - public static SKTextBlob CreatePathPositioned (ReadOnlySpan text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) + public static SKTextBlob? CreatePathPositioned (ReadOnlySpan text, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) { fixed (void* t = text) { return CreatePathPositioned (t, text.Length * 2, SKTextEncoding.Utf16, font, path, textAlign, origin); } } - public static SKTextBlob CreatePathPositioned (IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => + public static SKTextBlob? CreatePathPositioned (IntPtr text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) => CreatePathPositioned (text.AsReadOnlySpan (length), encoding, font, path, textAlign, origin); - public static SKTextBlob CreatePathPositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) + public static SKTextBlob? CreatePathPositioned (ReadOnlySpan text, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) { fixed (void* t = text) { return CreatePathPositioned (t, text.Length, encoding, font, path, textAlign, origin); } } - internal static SKTextBlob CreatePathPositioned (void* text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) + internal static SKTextBlob? CreatePathPositioned (void* text, int length, SKTextEncoding encoding, SKFont font, SKPath path, SKTextAlign textAlign = SKTextAlign.Left, SKPoint origin = default) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -228,7 +225,7 @@ internal static SKTextBlob CreatePathPositioned (void* text, int length, SKTextE // GetIntercepts - public float[] GetIntercepts (float upperBounds, float lowerBounds, SKPaint paint = null) + public float[] GetIntercepts (float upperBounds, float lowerBounds, SKPaint? paint = null) { var n = CountIntercepts (upperBounds, lowerBounds, paint); var intervals = new float[n]; @@ -236,7 +233,7 @@ public float[] GetIntercepts (float upperBounds, float lowerBounds, SKPaint pain return intervals; } - public void GetIntercepts (float upperBounds, float lowerBounds, Span intervals, SKPaint paint = null) + public void GetIntercepts (float upperBounds, float lowerBounds, Span intervals, SKPaint? paint = null) { var bounds = stackalloc float[2]; bounds[0] = upperBounds; @@ -248,7 +245,7 @@ public void GetIntercepts (float upperBounds, float lowerBounds, Span int // CountIntercepts - public int CountIntercepts (float upperBounds, float lowerBounds, SKPaint paint = null) + public int CountIntercepts (float upperBounds, float lowerBounds, SKPaint? paint = null) { var bounds = stackalloc float[2]; bounds[0] = upperBounds; @@ -258,7 +255,7 @@ public int CountIntercepts (float upperBounds, float lowerBounds, SKPaint paint // - internal static SKTextBlob GetObject (IntPtr handle) => + internal static SKTextBlob? GetObject (IntPtr handle) => handle == IntPtr.Zero ? null : new SKTextBlob (handle, true); } @@ -282,7 +279,7 @@ protected override void DisposeNative () => // Build - public SKTextBlob Build () + public SKTextBlob? Build () { var blob = SKTextBlob.GetObject (SkiaApi.sk_textblob_builder_make (Handle)); GC.KeepAlive (this); @@ -293,48 +290,36 @@ public SKTextBlob Build () public void AddRun (ReadOnlySpan glyphs, SKFont font, SKPoint origin = default) { - if (font == null) - throw new ArgumentNullException (nameof (font)); - - var buffer = AllocatePositionedRun (font, glyphs.Length); - glyphs.CopyTo (buffer.GetGlyphSpan ()); - font.GetGlyphPositions (buffer.GetGlyphSpan (), buffer.GetPositionSpan (), origin); + var buffer = AllocateRawPositionedRun (font, glyphs.Length); + glyphs.CopyTo (buffer.Glyphs); + font.GetGlyphPositions (buffer.Glyphs, buffer.Positions, origin); } // AddHorizontalRun public void AddHorizontalRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions, float y) { - if (font == null) - throw new ArgumentNullException (nameof (font)); - - var buffer = AllocateHorizontalRun (font, glyphs.Length, y); - glyphs.CopyTo (buffer.GetGlyphSpan ()); - positions.CopyTo (buffer.GetPositionSpan ()); + var buffer = AllocateRawHorizontalRun (font, glyphs.Length, y); + glyphs.CopyTo (buffer.Glyphs); + positions.CopyTo (buffer.Positions); } // AddPositionedRun public void AddPositionedRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { - if (font == null) - throw new ArgumentNullException (nameof (font)); - - var buffer = AllocatePositionedRun (font, glyphs.Length); - glyphs.CopyTo (buffer.GetGlyphSpan ()); - positions.CopyTo (buffer.GetPositionSpan ()); + var buffer = AllocateRawPositionedRun (font, glyphs.Length); + glyphs.CopyTo (buffer.Glyphs); + positions.CopyTo (buffer.Positions); } // AddRotationScaleRun public void AddRotationScaleRun (ReadOnlySpan glyphs, SKFont font, ReadOnlySpan positions) { - if (font == null) - throw new ArgumentNullException (nameof (font)); - - var buffer = AllocateRotationScaleRun (font, glyphs.Length); - glyphs.CopyTo (buffer.GetGlyphSpan ()); - positions.CopyTo (buffer.GetRotationScaleSpan ()); + var buffer = AllocateRawRotationScaleRun (font, glyphs.Length); + glyphs.CopyTo (buffer.Glyphs); + positions.CopyTo (buffer.Positions); } // AddPathPositionedRun @@ -390,9 +375,17 @@ public void AddPathPositionedRun (ReadOnlySpan glyphs, SKFont font, Read AddRotationScaleRun (glyphSubset, font, positions); } - // AllocateRun + // Allocate* + + // Allocate*Run public SKRunBuffer AllocateRun (SKFont font, int count, float x, float y, SKRect? bounds = null) + { + var buffer = AllocateRawRun (font, count, x, y, bounds); + return new SKRunBuffer (buffer.buffer, count); + } + + public SKRawRunBuffer AllocateRawRun (SKFont font, int count, float x, float y, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -403,10 +396,16 @@ public SKRunBuffer AllocateRun (SKFont font, int count, float x, float y, SKRect else SkiaApi.sk_textblob_builder_alloc_run (Handle, font.Handle, count, x, y, null, &runbuffer); - return new SKRunBuffer (runbuffer, count); + return new SKRawRunBuffer (runbuffer, count, 0, 0); } public SKTextRunBuffer AllocateTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds = null) + { + var buffer = AllocateRawTextRun (font, count, x, y, textByteCount, bounds); + return new SKTextRunBuffer (buffer.buffer, count, textByteCount); + } + + public SKRawRunBuffer AllocateRawTextRun (SKFont font, int count, float x, float y, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -417,12 +416,18 @@ public SKTextRunBuffer AllocateTextRun (SKFont font, int count, float x, float y else SkiaApi.sk_textblob_builder_alloc_run_text (Handle, font.Handle, count, x, y, textByteCount, null, &runbuffer); - return new SKTextRunBuffer (runbuffer, count, textByteCount); + return new SKRawRunBuffer (runbuffer, count, 0, textByteCount); } - // AllocateHorizontalRun + // Allocate*HorizontalRun public SKHorizontalRunBuffer AllocateHorizontalRun (SKFont font, int count, float y, SKRect? bounds = null) + { + var buffer = AllocateRawHorizontalRun (font, count, y, bounds); + return new SKHorizontalRunBuffer (buffer.buffer, count); + } + + public SKRawRunBuffer AllocateRawHorizontalRun (SKFont font, int count, float y, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -433,10 +438,16 @@ public SKHorizontalRunBuffer AllocateHorizontalRun (SKFont font, int count, floa else SkiaApi.sk_textblob_builder_alloc_run_pos_h (Handle, font.Handle, count, y, null, &runbuffer); - return new SKHorizontalRunBuffer (runbuffer, count); + return new SKRawRunBuffer (runbuffer, count, count, 0); } public SKHorizontalTextRunBuffer AllocateHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds = null) + { + var buffer = AllocateRawHorizontalTextRun (font, count, y, textByteCount, bounds); + return new SKHorizontalTextRunBuffer (buffer.buffer, count, textByteCount); + } + + public SKRawRunBuffer AllocateRawHorizontalTextRun (SKFont font, int count, float y, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -447,12 +458,19 @@ public SKHorizontalTextRunBuffer AllocateHorizontalTextRun (SKFont font, int cou else SkiaApi.sk_textblob_builder_alloc_run_text_pos_h (Handle, font.Handle, count, y, textByteCount, null, &runbuffer); - return new SKHorizontalTextRunBuffer (runbuffer, count, textByteCount); + return new SKRawRunBuffer (runbuffer, count, count, textByteCount); + } // AllocatePositionedRun public SKPositionedRunBuffer AllocatePositionedRun (SKFont font, int count, SKRect? bounds = null) + { + var buffer = AllocateRawPositionedRun (font, count, bounds); + return new SKPositionedRunBuffer (buffer.buffer, count); + } + + public SKRawRunBuffer AllocateRawPositionedRun (SKFont font, int count, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -463,10 +481,16 @@ public SKPositionedRunBuffer AllocatePositionedRun (SKFont font, int count, SKRe else SkiaApi.sk_textblob_builder_alloc_run_pos (Handle, font.Handle, count, null, &runbuffer); - return new SKPositionedRunBuffer (runbuffer, count); + return new SKRawRunBuffer (runbuffer, count, count, 0); } public SKPositionedTextRunBuffer AllocatePositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) + { + var buffer = AllocateRawPositionedTextRun (font, count, textByteCount, bounds); + return new SKPositionedTextRunBuffer (buffer.buffer, count, textByteCount); + } + + public SKRawRunBuffer AllocateRawPositionedTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -477,12 +501,18 @@ public SKPositionedTextRunBuffer AllocatePositionedTextRun (SKFont font, int cou else SkiaApi.sk_textblob_builder_alloc_run_text_pos (Handle, font.Handle, count, textByteCount, null, &runbuffer); - return new SKPositionedTextRunBuffer (runbuffer, count, textByteCount); + return new SKRawRunBuffer (runbuffer, count, count, textByteCount); } // AllocateRotationScaleRun public SKRotationScaleRunBuffer AllocateRotationScaleRun (SKFont font, int count, SKRect? bounds = null) + { + var buffer = AllocateRawRotationScaleRun (font, count, bounds); + return new SKRotationScaleRunBuffer (buffer.buffer, count); + } + + public SKRawRunBuffer AllocateRawRotationScaleRun (SKFont font, int count, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -493,10 +523,16 @@ public SKRotationScaleRunBuffer AllocateRotationScaleRun (SKFont font, int count else SkiaApi.sk_textblob_builder_alloc_run_rsxform (Handle, font.Handle, count, null, &runbuffer); - return new SKRotationScaleRunBuffer (runbuffer, count); + return new SKRawRunBuffer (runbuffer, count, count, 0); + } + + public SKRotationScaleTextRunBuffer AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) + { + var buffer = AllocateRawRotationScaleTextRun (font, count, textByteCount, bounds); + return new SKRotationScaleTextRunBuffer (buffer.buffer, count, textByteCount); } - public SKRotationScaleRunBuffer AllocateRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) + public SKRawRunBuffer AllocateRawRotationScaleTextRun (SKFont font, int count, int textByteCount, SKRect? bounds = null) { if (font == null) throw new ArgumentNullException (nameof (font)); @@ -507,7 +543,7 @@ public SKRotationScaleRunBuffer AllocateRotationScaleTextRun (SKFont font, int c else SkiaApi.sk_textblob_builder_alloc_run_text_rsxform (Handle, font.Handle, count, textByteCount, null, &runbuffer); - return new SKRotationScaleRunBuffer (runbuffer, count); + return new SKRawRunBuffer (runbuffer, count, count, textByteCount); } } } diff --git a/binding/SkiaSharp/SKTypeface.cs b/binding/SkiaSharp/SKTypeface.cs index 3455c8ec29..f9ea664166 100644 --- a/binding/SkiaSharp/SKTypeface.cs +++ b/binding/SkiaSharp/SKTypeface.cs @@ -14,6 +14,11 @@ public unsafe class SKTypeface : SKObject, ISKReferenceCounted static SKTypeface () { + // TODO: This is not the best way to do this as it will create a lot of objects that + // might not be needed, but it is the only way to ensure that the static + // instances are created before any access is made to them. + // See more info: SKObject.EnsureStaticInstanceAreInitialized() + defaultTypeface = new SKTypefaceStatic (SkiaApi.sk_typeface_ref_default ()); } diff --git a/binding/SkiaSharp/SkiaApi.generated.cs b/binding/SkiaSharp/SkiaApi.generated.cs index 662eb8cb8c..3dd311d4dc 100644 --- a/binding/SkiaSharp/SkiaApi.generated.cs +++ b/binding/SkiaSharp/SkiaApi.generated.cs @@ -17,6 +17,7 @@ using gr_vk_memory_allocator_t = System.IntPtr; using gr_vkinterface_t = System.IntPtr; using sk_bitmap_t = System.IntPtr; +using sk_blender_t = System.IntPtr; using sk_canvas_t = System.IntPtr; using sk_codec_t = System.IntPtr; using sk_colorfilter_t = System.IntPtr; @@ -84,6 +85,10 @@ using skottie_marker_observer_t = System.IntPtr; using skottie_property_observer_t = System.IntPtr; using skottie_resource_provider_t = System.IntPtr; +using skresources_external_track_asset_t = System.IntPtr; +using skresources_image_asset_t = System.IntPtr; +using skresources_multi_frame_image_asset_t = System.IntPtr; +using skresources_resource_provider_t = System.IntPtr; using sksg_invalidation_controller_t = System.IntPtr; using vk_device_t = System.IntPtr; using vk_instance_t = System.IntPtr; @@ -1410,6 +1415,66 @@ internal static bool sk_bitmap_try_alloc_pixels_with_flags (sk_bitmap_t cbitmap, #endregion + #region sk_blender.h + + // sk_blender_t* sk_blender_new_arithmetic(float k1, float k2, float k3, float k4, bool enforcePremul) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_blender_t sk_blender_new_arithmetic (Single k1, Single k2, Single k3, Single k4, [MarshalAs (UnmanagedType.I1)] bool enforcePremul); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_blender_t sk_blender_new_arithmetic (Single k1, Single k2, Single k3, Single k4, [MarshalAs (UnmanagedType.I1)] bool enforcePremul); + } + private static Delegates.sk_blender_new_arithmetic sk_blender_new_arithmetic_delegate; + internal static sk_blender_t sk_blender_new_arithmetic (Single k1, Single k2, Single k3, Single k4, [MarshalAs (UnmanagedType.I1)] bool enforcePremul) => + (sk_blender_new_arithmetic_delegate ??= GetSymbol ("sk_blender_new_arithmetic")).Invoke (k1, k2, k3, k4, enforcePremul); + #endif + + // sk_blender_t* sk_blender_new_mode(sk_blendmode_t mode) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_blender_t sk_blender_new_mode (SKBlendMode mode); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_blender_t sk_blender_new_mode (SKBlendMode mode); + } + private static Delegates.sk_blender_new_mode sk_blender_new_mode_delegate; + internal static sk_blender_t sk_blender_new_mode (SKBlendMode mode) => + (sk_blender_new_mode_delegate ??= GetSymbol ("sk_blender_new_mode")).Invoke (mode); + #endif + + // void sk_blender_ref(sk_blender_t* blender) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void sk_blender_ref (sk_blender_t blender); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void sk_blender_ref (sk_blender_t blender); + } + private static Delegates.sk_blender_ref sk_blender_ref_delegate; + internal static void sk_blender_ref (sk_blender_t blender) => + (sk_blender_ref_delegate ??= GetSymbol ("sk_blender_ref")).Invoke (blender); + #endif + + // void sk_blender_unref(sk_blender_t* blender) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void sk_blender_unref (sk_blender_t blender); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void sk_blender_unref (sk_blender_t blender); + } + private static Delegates.sk_blender_unref sk_blender_unref_delegate; + internal static void sk_blender_unref (sk_blender_t blender) => + (sk_blender_unref_delegate ??= GetSymbol ("sk_blender_unref")).Invoke (blender); + #endif + + #endregion + #region sk_canvas.h // void sk_canvas_clear(sk_canvas_t* ccanvas, sk_color_t color) @@ -4960,6 +5025,20 @@ internal static sk_shader_t sk_image_make_shader (sk_image_t image, SKShaderTile (sk_image_make_shader_delegate ??= GetSymbol ("sk_image_make_shader")).Invoke (image, tileX, tileY, sampling, cmatrix); #endif + // sk_shader_t* sk_image_make_raw_shader(const sk_image_t* image, sk_shader_tilemode_t tileX, sk_shader_tilemode_t tileY, const sk_sampling_options_t* sampling, const sk_matrix_t* cmatrix) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_shader_t sk_image_make_raw_shader (sk_image_t image, SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamplingOptions* sampling, SKMatrix* cmatrix); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_shader_t sk_image_make_raw_shader (sk_image_t image, SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamplingOptions* sampling, SKMatrix* cmatrix); + } + private static Delegates.sk_image_make_raw_shader sk_image_make_raw_shader_delegate; + internal static sk_shader_t sk_image_make_raw_shader (sk_image_t image, SKShaderTileMode tileX, SKShaderTileMode tileY, SKSamplingOptions* sampling, SKMatrix* cmatrix) => + (sk_image_make_raw_shader_delegate ??= GetSymbol ("sk_image_make_raw_shader")).Invoke (image, tileX, tileY, sampling, cmatrix); + #endif + // sk_image_t* sk_image_make_subset(const sk_image_t* cimage, gr_direct_context_t* context, const sk_irect_t* subset) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -5308,6 +5387,20 @@ internal static sk_imagefilter_t sk_imagefilter_new_blend (SKBlendMode mode, sk_ (sk_imagefilter_new_blend_delegate ??= GetSymbol ("sk_imagefilter_new_blend")).Invoke (mode, background, foreground, cropRect); #endif + // sk_imagefilter_t* sk_imagefilter_new_blender(sk_blender_t* blender, const sk_imagefilter_t* background, const sk_imagefilter_t* foreground, const sk_rect_t* cropRect) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_imagefilter_t sk_imagefilter_new_blender (sk_blender_t blender, sk_imagefilter_t background, sk_imagefilter_t foreground, SKRect* cropRect); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_imagefilter_t sk_imagefilter_new_blender (sk_blender_t blender, sk_imagefilter_t background, sk_imagefilter_t foreground, SKRect* cropRect); + } + private static Delegates.sk_imagefilter_new_blender sk_imagefilter_new_blender_delegate; + internal static sk_imagefilter_t sk_imagefilter_new_blender (sk_blender_t blender, sk_imagefilter_t background, sk_imagefilter_t foreground, SKRect* cropRect) => + (sk_imagefilter_new_blender_delegate ??= GetSymbol ("sk_imagefilter_new_blender")).Invoke (blender, background, foreground, cropRect); + #endif + // sk_imagefilter_t* sk_imagefilter_new_blur(float sigmaX, float sigmaY, sk_shader_tilemode_t tileMode, const sk_imagefilter_t* input, const sk_rect_t* cropRect) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -5688,6 +5781,24 @@ internal static void sk_imagefilter_unref (sk_imagefilter_t cfilter) => #endregion + #region sk_linker.h + + // void sk_linker_keep_alive() + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void sk_linker_keep_alive (); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void sk_linker_keep_alive (); + } + private static Delegates.sk_linker_keep_alive sk_linker_keep_alive_delegate; + internal static void sk_linker_keep_alive () => + (sk_linker_keep_alive_delegate ??= GetSymbol ("sk_linker_keep_alive")).Invoke (); + #endif + + #endregion + #region sk_maskfilter.h // sk_maskfilter_t* sk_maskfilter_new_blur(sk_blurstyle_t, float sigma) @@ -5980,6 +6091,20 @@ internal static void sk_paint_delete (sk_paint_t param0) => (sk_paint_delete_delegate ??= GetSymbol ("sk_paint_delete")).Invoke (param0); #endif + // sk_blender_t* sk_paint_get_blender(sk_paint_t* cpaint) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_blender_t sk_paint_get_blender (sk_paint_t cpaint); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_blender_t sk_paint_get_blender (sk_paint_t cpaint); + } + private static Delegates.sk_paint_get_blender sk_paint_get_blender_delegate; + internal static sk_blender_t sk_paint_get_blender (sk_paint_t cpaint) => + (sk_paint_get_blender_delegate ??= GetSymbol ("sk_paint_get_blender")).Invoke (cpaint); + #endif + // sk_blendmode_t sk_paint_get_blendmode(sk_paint_t*) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -6252,6 +6377,20 @@ internal static void sk_paint_set_antialias (sk_paint_t param0, [MarshalAs (Unma (sk_paint_set_antialias_delegate ??= GetSymbol ("sk_paint_set_antialias")).Invoke (param0, param1); #endif + // void sk_paint_set_blender(sk_paint_t* paint, sk_blender_t* blender) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern void sk_paint_set_blender (sk_paint_t paint, sk_blender_t blender); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate void sk_paint_set_blender (sk_paint_t paint, sk_blender_t blender); + } + private static Delegates.sk_paint_set_blender sk_paint_set_blender_delegate; + internal static void sk_paint_set_blender (sk_paint_t paint, sk_blender_t blender) => + (sk_paint_set_blender_delegate ??= GetSymbol ("sk_paint_set_blender")).Invoke (paint, blender); + #endif + // void sk_paint_set_blendmode(sk_paint_t*, sk_blendmode_t) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -9438,6 +9577,20 @@ private partial class Delegates { (sk_runtimeeffect_get_uniforms_size_delegate ??= GetSymbol ("sk_runtimeeffect_get_uniforms_size")).Invoke (effect); #endif + // sk_blender_t* sk_runtimeeffect_make_blender(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_blender_t sk_runtimeeffect_make_blender (sk_runtimeeffect_t effect, sk_data_t uniforms, sk_flattenable_t* children, /* size_t */ IntPtr childCount); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_blender_t sk_runtimeeffect_make_blender (sk_runtimeeffect_t effect, sk_data_t uniforms, sk_flattenable_t* children, /* size_t */ IntPtr childCount); + } + private static Delegates.sk_runtimeeffect_make_blender sk_runtimeeffect_make_blender_delegate; + internal static sk_blender_t sk_runtimeeffect_make_blender (sk_runtimeeffect_t effect, sk_data_t uniforms, sk_flattenable_t* children, /* size_t */ IntPtr childCount) => + (sk_runtimeeffect_make_blender_delegate ??= GetSymbol ("sk_runtimeeffect_make_blender")).Invoke (effect, uniforms, children, childCount); + #endif + // sk_colorfilter_t* sk_runtimeeffect_make_color_filter(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -9452,6 +9605,20 @@ internal static sk_colorfilter_t sk_runtimeeffect_make_color_filter (sk_runtimee (sk_runtimeeffect_make_color_filter_delegate ??= GetSymbol ("sk_runtimeeffect_make_color_filter")).Invoke (effect, uniforms, children, childCount); #endif + // sk_runtimeeffect_t* sk_runtimeeffect_make_for_blender(sk_string_t* sksl, sk_string_t* error) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_runtimeeffect_t sk_runtimeeffect_make_for_blender (sk_string_t sksl, sk_string_t error); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_runtimeeffect_t sk_runtimeeffect_make_for_blender (sk_string_t sksl, sk_string_t error); + } + private static Delegates.sk_runtimeeffect_make_for_blender sk_runtimeeffect_make_for_blender_delegate; + internal static sk_runtimeeffect_t sk_runtimeeffect_make_for_blender (sk_string_t sksl, sk_string_t error) => + (sk_runtimeeffect_make_for_blender_delegate ??= GetSymbol ("sk_runtimeeffect_make_for_blender")).Invoke (sksl, error); + #endif + // sk_runtimeeffect_t* sk_runtimeeffect_make_for_color_filter(sk_string_t* sksl, sk_string_t* error) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] @@ -9526,6 +9693,20 @@ internal static sk_shader_t sk_shader_new_blend (SKBlendMode mode, sk_shader_t d (sk_shader_new_blend_delegate ??= GetSymbol ("sk_shader_new_blend")).Invoke (mode, dst, src); #endif + // sk_shader_t* sk_shader_new_blender(sk_blender_t* blender, const sk_shader_t* dst, const sk_shader_t* src) + #if !USE_DELEGATES + [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] + internal static extern sk_shader_t sk_shader_new_blender (sk_blender_t blender, sk_shader_t dst, sk_shader_t src); + #else + private partial class Delegates { + [UnmanagedFunctionPointer (CallingConvention.Cdecl)] + internal delegate sk_shader_t sk_shader_new_blender (sk_blender_t blender, sk_shader_t dst, sk_shader_t src); + } + private static Delegates.sk_shader_new_blender sk_shader_new_blender_delegate; + internal static sk_shader_t sk_shader_new_blender (sk_blender_t blender, sk_shader_t dst, sk_shader_t src) => + (sk_shader_new_blender_delegate ??= GetSymbol ("sk_shader_new_blender")).Invoke (blender, dst, src); + #endif + // sk_shader_t* sk_shader_new_color(sk_color_t color) #if !USE_DELEGATES [DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)] diff --git a/binding/SkiaSharp/SkiaSharp.csproj b/binding/SkiaSharp/SkiaSharp.csproj index 4f0937b0b8..eb53cfa375 100644 --- a/binding/SkiaSharp/SkiaSharp.csproj +++ b/binding/SkiaSharp/SkiaSharp.csproj @@ -5,6 +5,7 @@ SkiaSharp SkiaSharp enable + true $(DefineConstants);USE_DELEGATES diff --git a/binding/libSkiaSharp.Resources.json b/binding/libSkiaSharp.Resources.json new file mode 100644 index 0000000000..ed53436df7 --- /dev/null +++ b/binding/libSkiaSharp.Resources.json @@ -0,0 +1,86 @@ +// configuration for the libSkiaSharp binary +{ + "dllName": "SKIA", + "namespace": "SkiaSharp", + "namespaces": { + "sk_": { + "prefix": "SK", + "exclude": true + }, + "gr_": { + "exclude": true + }, + "vk_": { + "exclude": true + }, + "sksg_": { + "exclude": true + }, + "skottie_": { + "exclude": true + }, + "skresources_": { + "cs": "Resources", + "prefix": "" + } + }, + "className": "ResourcesApi", + "includeDirs": [ + "." + ], + "headers": { + "include/c": [ "sk_*", "gr_*", "skottie*", "sksg_*", "skresources_*" ], + "include/xamarin": [ "sk_*" ] + }, + "source": { + "src/c": [ "sk_*", "gr_*", "skottie*", "sksg_*" ], + "src/xamarin": [ "sk_*" ] + }, + "mappings": { + "types": { + "skottie_animation_builder_flags_t": { + "flags": true + } + }, + "functions": { + "skottie_animation_builder_make_from_string": { + "parameters": { + "0": "[MarshalAs (UnmanagedType.LPStr)] String", + "1": "int" + + } + }, + "skottie_animation_builder_make_from_file": { + "parameters": { + "0": "[MarshalAs (UnmanagedType.LPStr)] String" + } + }, + "skresources_resource_provider_load": { + "parameters": { + "1": "[MarshalAs (UnmanagedType.LPStr)] String", + "2": "[MarshalAs (UnmanagedType.LPStr)] String" + } + }, + "skresources_resource_provider_load_audio_asset": { + "parameters": { + "1": "[MarshalAs (UnmanagedType.LPStr)] String", + "2": "[MarshalAs (UnmanagedType.LPStr)] String", + "3": "[MarshalAs (UnmanagedType.LPStr)] String" + } + }, + "skresources_resource_provider_load_image_asset": { + "parameters": { + "1": "[MarshalAs (UnmanagedType.LPStr)] String", + "2": "[MarshalAs (UnmanagedType.LPStr)] String", + "3": "[MarshalAs (UnmanagedType.LPStr)] String" + } + }, + "skresources_resource_provider_load_typeface": { + "parameters": { + "1": "[MarshalAs (UnmanagedType.LPStr)] String", + "2": "[MarshalAs (UnmanagedType.LPStr)] String" + } + } + } + } +} \ No newline at end of file diff --git a/binding/libSkiaSharp.SceneGraph.json b/binding/libSkiaSharp.SceneGraph.json index f90dc8e63d..0b432a4d72 100644 --- a/binding/libSkiaSharp.SceneGraph.json +++ b/binding/libSkiaSharp.SceneGraph.json @@ -19,6 +19,9 @@ }, "skottie_": { "exclude": true + }, + "skresources_": { + "exclude": true } }, "className": "SceneGraphApi", diff --git a/binding/libSkiaSharp.Skottie.json b/binding/libSkiaSharp.Skottie.json index e887c28e65..caceca9fb8 100644 --- a/binding/libSkiaSharp.Skottie.json +++ b/binding/libSkiaSharp.Skottie.json @@ -19,6 +19,9 @@ "skottie_": { "cs": "Skottie", "prefix": "" + }, + "skresources_": { + "exclude": true } }, "className": "SkottieApi", @@ -35,6 +38,10 @@ }, "mappings": { "types": { + "skottie_animation_builder_stats_t": { + "readonly": true, + "properties": false + }, "skottie_animation_renderflags_t": { "cs": "AnimationRenderFlags", "flags": true diff --git a/binding/libSkiaSharp.json b/binding/libSkiaSharp.json index 2e872b0b28..a67a69969c 100644 --- a/binding/libSkiaSharp.json +++ b/binding/libSkiaSharp.json @@ -17,6 +17,9 @@ }, "skottie_": { "exclude": true + }, + "skresources_": { + "exclude": true } }, "className": "SkiaApi", diff --git a/build.cake b/build.cake index 2812886d6d..ba206f5f67 100644 --- a/build.cake +++ b/build.cake @@ -101,6 +101,7 @@ var TRACKED_NUGETS = new Dictionary { { "SkiaSharp.NativeAssets.Tizen", new Version (1, 60, 0) }, { "SkiaSharp.NativeAssets.tvOS", new Version (1, 60, 0) }, { "SkiaSharp.NativeAssets.Win32", new Version (1, 60, 0) }, + { "SkiaSharp.NativeAssets.WinUI", new Version (1, 60, 0) }, { "SkiaSharp.Views", new Version (1, 60, 0) }, { "SkiaSharp.Views.Desktop.Common", new Version (1, 60, 0) }, { "SkiaSharp.Views.Gtk3", new Version (1, 60, 0) }, @@ -124,6 +125,7 @@ var TRACKED_NUGETS = new Dictionary { { "SkiaSharp.HarfBuzz", new Version (1, 60, 0) }, { "SkiaSharp.Skottie", new Version (1, 60, 0) }, { "SkiaSharp.SceneGraph", new Version (1, 60, 0) }, + { "SkiaSharp.Resources", new Version (1, 60, 0) }, { "SkiaSharp.Vulkan.SharpVk", new Version (1, 60, 0) }, }; diff --git a/changelogs/SkiaSharp.Views.Maui.Controls/3.0.0/SkiaSharp.Views.Maui.Controls.breaking.md b/changelogs/SkiaSharp.Views.Maui.Controls/3.0.0/SkiaSharp.Views.Maui.Controls.breaking.md new file mode 100644 index 0000000000..7ea6364fcb --- /dev/null +++ b/changelogs/SkiaSharp.Views.Maui.Controls/3.0.0/SkiaSharp.Views.Maui.Controls.breaking.md @@ -0,0 +1,29 @@ +# API diff: SkiaSharp.Views.Maui.Controls.dll + +## SkiaSharp.Views.Maui.Controls.dll + +> Assembly Version Changed: 3.0.0.0 vs 2.88.0.0 + +### Namespace SkiaSharp.Views.Maui.Controls + +#### Type Changed: SkiaSharp.Views.Maui.Controls.SKCanvasView + +Removed interface: + +```csharp +ISKCanvasViewController +``` + + +#### Type Changed: SkiaSharp.Views.Maui.Controls.SKGLView + +Removed interface: + +```csharp +ISKGLViewController +``` + + +#### Removed Type SkiaSharp.Views.Maui.Controls.ISKCanvasViewController +#### Removed Type SkiaSharp.Views.Maui.Controls.ISKGLViewController + diff --git a/changelogs/SkiaSharp.Views.Maui.Controls/3.0.0/SkiaSharp.Views.Maui.Controls.md b/changelogs/SkiaSharp.Views.Maui.Controls/3.0.0/SkiaSharp.Views.Maui.Controls.md index a650e725a6..99d1553c0f 100644 --- a/changelogs/SkiaSharp.Views.Maui.Controls/3.0.0/SkiaSharp.Views.Maui.Controls.md +++ b/changelogs/SkiaSharp.Views.Maui.Controls/3.0.0/SkiaSharp.Views.Maui.Controls.md @@ -4,3 +4,56 @@ > Assembly Version Changed: 3.0.0.0 vs 2.88.0.0 +### Namespace SkiaSharp.Views.Maui.Controls + +#### Type Changed: SkiaSharp.Views.Maui.Controls.SKCanvasView + +Removed interface: + +```csharp +ISKCanvasViewController +``` + +Removed method: + +```csharp +protected override Microsoft.Maui.SizeRequest OnMeasure (double widthConstraint, double heightConstraint); +``` + + +#### Type Changed: SkiaSharp.Views.Maui.Controls.SKGLView + +Removed interface: + +```csharp +ISKGLViewController +``` + +Added interface: + +```csharp +SkiaSharp.Views.Maui.ISKGLView +``` + +Added field: + +```csharp +public static Microsoft.Maui.Controls.BindableProperty IgnorePixelScalingProperty; +``` + +Added property: + +```csharp +public override bool IgnorePixelScaling { get; set; } +``` + +Removed method: + +```csharp +protected override Microsoft.Maui.SizeRequest OnMeasure (double widthConstraint, double heightConstraint); +``` + + +#### Removed Type SkiaSharp.Views.Maui.Controls.ISKCanvasViewController +#### Removed Type SkiaSharp.Views.Maui.Controls.ISKGLViewController + diff --git a/changelogs/SkiaSharp.Views.Maui.Core/3.0.0/SkiaSharp.Views.Maui.Core.md b/changelogs/SkiaSharp.Views.Maui.Core/3.0.0/SkiaSharp.Views.Maui.Core.md index c6137a6a83..c33e810f4c 100644 --- a/changelogs/SkiaSharp.Views.Maui.Core/3.0.0/SkiaSharp.Views.Maui.Core.md +++ b/changelogs/SkiaSharp.Views.Maui.Core/3.0.0/SkiaSharp.Views.Maui.Core.md @@ -4,3 +4,64 @@ > Assembly Version Changed: 3.0.0.0 vs 2.88.0.0 +### Namespace SkiaSharp.Views.Maui + +#### Type Changed: SkiaSharp.Views.Maui.SKPaintGLSurfaceEventArgs + +Added constructors: + +```csharp +public SKPaintGLSurfaceEventArgs (SkiaSharp.SKSurface surface, SkiaSharp.GRBackendRenderTarget renderTarget, SkiaSharp.GRSurfaceOrigin origin, SkiaSharp.SKImageInfo info); +public SKPaintGLSurfaceEventArgs (SkiaSharp.SKSurface surface, SkiaSharp.GRBackendRenderTarget renderTarget, SkiaSharp.GRSurfaceOrigin origin, SkiaSharp.SKImageInfo info, SkiaSharp.SKImageInfo rawInfo); +``` + +Added properties: + +```csharp +public SkiaSharp.SKImageInfo Info { get; } +public SkiaSharp.SKImageInfo RawInfo { get; } +``` + + +#### New Type: SkiaSharp.Views.Maui.ISKGLView + +```csharp +public interface ISKGLView : Microsoft.Maui.IElement, Microsoft.Maui.ITransform, Microsoft.Maui.IView { + // properties + public virtual SkiaSharp.SKSize CanvasSize { get; } + public virtual bool EnableTouchEvents { get; } + public virtual SkiaSharp.GRContext GRContext { get; } + public virtual bool HasRenderLoop { get; } + public virtual bool IgnorePixelScaling { get; } + // methods + public virtual void InvalidateSurface (); + public virtual void OnCanvasSizeChanged (SkiaSharp.SKSizeI size); + public virtual void OnGRContextChanged (SkiaSharp.GRContext context); + public virtual void OnPaintSurface (SKPaintGLSurfaceEventArgs e); + public virtual void OnTouch (SKTouchEventArgs e); +} +``` + + +### Namespace SkiaSharp.Views.Maui.Handlers + +#### New Type: SkiaSharp.Views.Maui.Handlers.SKGLViewHandler + +```csharp +public class SKGLViewHandler : Microsoft.Maui.Handlers.ViewHandler`2[SkiaSharp.Views.Maui.ISKGLView,System.Object], Microsoft.Maui.IElementHandler, Microsoft.Maui.IPlatformViewHandler, Microsoft.Maui.IViewHandler { + // constructors + public SKGLViewHandler (); + public SKGLViewHandler (Microsoft.Maui.PropertyMapper mapper, Microsoft.Maui.CommandMapper commands); + // fields + public static Microsoft.Maui.CommandMapper SKGLViewCommandMapper; + public static Microsoft.Maui.PropertyMapper SKGLViewMapper; + // methods + protected override object CreatePlatformView (); + public static void MapEnableTouchEvents (SKGLViewHandler handler, SkiaSharp.Views.Maui.ISKGLView view); + public static void MapHasRenderLoop (SKGLViewHandler handler, SkiaSharp.Views.Maui.ISKGLView view); + public static void MapIgnorePixelScaling (SKGLViewHandler handler, SkiaSharp.Views.Maui.ISKGLView view); + public static void OnInvalidateSurface (SKGLViewHandler handler, SkiaSharp.Views.Maui.ISKGLView view, object args); +} +``` + + diff --git a/changelogs/SkiaSharp.Views.WinUI/3.0.0/SkiaSharp.Views.Windows.md b/changelogs/SkiaSharp.Views.WinUI/3.0.0/SkiaSharp.Views.Windows.md index 82249503c2..bff6e56995 100644 --- a/changelogs/SkiaSharp.Views.WinUI/3.0.0/SkiaSharp.Views.Windows.md +++ b/changelogs/SkiaSharp.Views.WinUI/3.0.0/SkiaSharp.Views.Windows.md @@ -27,4 +27,39 @@ public SkiaSharp.GRBackendRenderTargetDesc RenderTarget { get; } #### Removed Type SkiaSharp.Views.Windows.Extensions +#### New Type: SkiaSharp.Views.Windows.AngleSwapChainPanel + +```csharp +public class AngleSwapChainPanel : Microsoft.UI.Xaml.Controls.SwapChainPanel { + // constructors + public AngleSwapChainPanel (); + // properties + public double ContentsScale { get; } + public bool DrawInBackground { get; set; } + public bool EnableRenderLoop { get; set; } + // methods + public void Invalidate (); + protected virtual void OnDestroyingContext (); + protected virtual void OnRenderFrame (Windows.Foundation.Rect rect); +} +``` + +#### New Type: SkiaSharp.Views.Windows.SKSwapChainPanel + +```csharp +public class SKSwapChainPanel : SkiaSharp.Views.Windows.AngleSwapChainPanel { + // constructors + public SKSwapChainPanel (); + // properties + public SkiaSharp.SKSize CanvasSize { get; } + public SkiaSharp.GRContext GRContext { get; } + // events + public event System.EventHandler PaintSurface; + // methods + protected override void OnDestroyingContext (); + protected virtual void OnPaintSurface (SKPaintGLSurfaceEventArgs e); + protected override void OnRenderFrame (Windows.Foundation.Rect rect); +} +``` + diff --git a/changelogs/SkiaSharp/3.0.0/SkiaSharp.humanreadable.md b/changelogs/SkiaSharp/3.0.0/SkiaSharp.humanreadable.md index 70e2d245d2..111da80d82 100644 --- a/changelogs/SkiaSharp/3.0.0/SkiaSharp.humanreadable.md +++ b/changelogs/SkiaSharp/3.0.0/SkiaSharp.humanreadable.md @@ -1,22 +1,28 @@ -# API diff: SkiaSharp.dll - -## SkiaSharp.dll - -> Assembly Version Changed: 3.0.0.0 vs 2.88.0.0 - -### Major Changes +# SkiaSharp 3.x Changes The diff below contains all the changes that are in addition to the removal of obsolete types and members. The 3.x release is a major upgrade and many of the obsolete types and members needed to go away. -#### Platform Reduction +**Contents** -SkiaSharp supports many platforms, however in 3.x we reduce the platforms to just the more modern ones: +* [Improvements](#improvements) + There are many new APIs and improvements to exisitng features. +* [Breaking Changes](#breaking-changes) + In order to update to the latest skia builds and to keep the library maintainable, we unfortunately had to make some hard choices and remove some old APIs. + * [Platform Reduction](#platform-reduction) + In order to move forward, we had to reduce our supported platforms. However, all the modern and supported .NET platforms are still there. + * [ABI Breaking Changes](#abi-breaking-changes) + Unfortunately several APIs had to be dropped. This could be that the new skia engine does not support a feature or it was not working previously. + * [Removed `[Obsolete]` Types and Members](#removed-obsolete-types-and-members) + Several obsolete APIs were removed as they have been marked for removal for several years now. In most cases, there are already alternatives that you can use instead. + * [Analysis and Tooling](#analysis-and-tooling) + Because some breaking changes are hard to detect and since SkiaSharp is so widely used, we have put together some tooling to help you detect those breaking APIs before you even update. +* [Newly Obsoleted Types and Members](#newly-obsoleted-types-and-members) + The new version of skia does things a bit differently in some places, so some existing APIs are no longer relevant or there are better APIs to use. +* [API diff: SkiaSharp.dll](#api-diff-skiasharpdll) + This is a more readable diff of SkiaSharp as the full diff is really long and has many changes that are not really relevant. -* .NET Standard 2.0+ -* .NET Framework 4.6.2+ -* .NET 7+ (All the platforms: Android, iOS, Mac Catalyst, macOS, Tizen, tvOS, Windows) -#### Improvements +## Improvements There are some small improvements in the initial release of 3.x, and many more will be added with later builds. @@ -26,13 +32,23 @@ There are some small improvements in the initial release of 3.x, and many more w * `SKPoint3` is now implicitly compatible with `System.Numerics.Vector3` in both directions. * `SKPointI` is now implicitly cast to `System.Numerics.Vector3`. * `SKRuntimeEffect` now works on both CPU and GPU: - * GPU is accelerated and support more targets: `SKColorFilter` and `SKShader` (there is also a new `SKBlender` that is not yet exposed in SkiaSharp). + * GPU is accelerated and support more targets: `SKColorFilter`, `SKShader` and the new `SKBlender`. * CPU is NOT accelerated and may be very slow. * `SKMatrix44` is now a high-performance struct that can be used on any `SKCanvas`. -#### Breaking Changes +## Breaking Changes -With the major update from 2x to 3x, some APIs were broken to make maintainance easier as well as to simplify things for consumers. +With the major update from 2.x to 3.x, some APIs were broken to make maintainance easier as well as to simplify things for consumers. + +### Platform Reduction + +SkiaSharp supports many platforms, however in 3.x we reduce the platforms to just the more modern ones: + +* .NET Standard 2.0+ +* .NET Framework 4.6.2+ +* .NET 7+ (All the platforms: Android, iOS, Mac Catalyst, macOS, Tizen, tvOS, Windows) + +### ABI Breaking Changes Below is a list of notable breaking changes. @@ -45,7 +61,7 @@ Below is a list of notable breaking changes. * `SK3dView` was removed because it was expensive to use The new `SKMatrix44` can do all the same things as well as just using `System.Numerics.Matrix4x4` and related `System.Numerics` types. -##### Removed [Obsolete] Types and Members +### Removed `[Obsolete]` Types and Members Many types and members were obsoleted at trhe start of the 2.x version (and some before). The 3.x release will be removing all the members that were previously marked `[Obsolete]`. @@ -63,9 +79,44 @@ Some of the notable removals are: * `SKMask` - All types and members relating to `SKMask` have been removed. * `SKXmlWriter` - All types and members relating to `SKXmlWriter` and `SKXmlStreamWriter` have been removed. -#### Obsoleted Types and Members +### Analysis and Tooling + +If you are upgrading to SkiaSharp 3.x, you may be interested in using the [`api-tools` .NET CLI tool](https://nuget.org/packages/api-tools) to help identify any usages of removed types. + +There is [full documentation available](https://github.com/mattleibow/Mono.ApiTools.NuGetDiff/blob/5c14bf43a6a587c2fd2878c7884ff1db6a9beca1/docs/api-tools.md#compat-command), but the `api-tools` CLI tool can be used to find all usages of missing types and members: + +```sh +dotnet api-tools compat Svg.Skia/Svg.Skia.dll SkiaSharp/v3/SkiaSharp.dll +``` + +This will produce an output similar to: + +```xml + + + + + + + + + + + + + + + + + +``` + +This output indicates that there are several usages of missing types and members. However, in many cases, there are overloads or alternate APIs that can be used that are present in both 2.x and 3.x versions of SkiaSharp. + + +## Newly Obsoleted Types and Members -With the major update from 2x to 3x, several APIs are no longer the recommeneded way to do something. There might be a better or cleaner way of doing something. For all of these types and members, they will be marked `[Obsolete]` and removed in the next major release. +With the major update from 2.x to 3.x, several APIs are no longer the recommeneded way to do something. There might be a better or cleaner way of doing something. For all of these types and members, they will be marked `[Obsolete]` and removed in the next major release. Some of the notable obsolete items are: @@ -74,6 +125,10 @@ Some of the notable obsolete items are: * `SKFont` & `SKPaint` - All the "font-related" members on `SKPaint` have been marked obsolete and now exist on `SKFont`. In previous skia versions, the `SKPaint` functionality was split into 2 objects: `SKPaint` and `SKFont`. SkiaSharp tried to maintain 100% backwards compatibility by re-merginf the types. However, this is getting hard to maintain. As a result, `SKFont` is now the correct replacement to work with typefaces and character styles. All APIs tha accepted just a `SKPaint` now also have an overload that accepts `SKFont` and `SKTextAlign`. +## API diff: SkiaSharp.dll + +> Assembly Version Changed: 3.0.0.0 vs 2.88.0.0 + ### Namespace SkiaSharp #### Type Changed: SkiaSharp.GRGlFramebufferInfo diff --git a/externals/.gitignore b/externals/.gitignore index df5b644fa9..d83a461853 100644 --- a/externals/.gitignore +++ b/externals/.gitignore @@ -1,3 +1,4 @@ angle/ package_cache/ vcpkg/ +winappsdk/ diff --git a/externals/skia b/externals/skia index 519e4b3025..f1c2f7b424 160000 --- a/externals/skia +++ b/externals/skia @@ -1 +1 @@ -Subproject commit 519e4b302588722e71ca71c2531749747a789cf0 +Subproject commit f1c2f7b4246141c6037820dc75d89496ac4aa8b3 diff --git a/interactive/README.dib b/interactive/README.dib index 75a567c83c..bbe466d809 100644 --- a/interactive/README.dib +++ b/interactive/README.dib @@ -4,7 +4,7 @@ Welcome to SkiaSharp, the most awesome, cross-platform 2D-graphics engine. It is powered by the same engine that powers Android and Chrome. -The first thing we need to do is intsall the package: +The first thing we need to do is install the package: #!csharp diff --git a/native/.gitignore b/native/.gitignore index 2a4fe393c9..2f11c1ce72 100644 --- a/native/.gitignore +++ b/native/.gitignore @@ -1,3 +1,4 @@ xcuserdata/ project.xcworkspace/ uwp/ANGLE/triplets +Generated Files/ diff --git a/native/linux/libSkiaSharp/libSkiaSharp.map b/native/linux/libSkiaSharp/libSkiaSharp.map index efb3ef0c45..c10403496d 100644 --- a/native/linux/libSkiaSharp/libSkiaSharp.map +++ b/native/linux/libSkiaSharp/libSkiaSharp.map @@ -4,6 +4,7 @@ libSkiaSharp { gr_*; skottie_*; sksg_*; + skresources_*; local: *; }; diff --git a/native/windows/build.cake b/native/windows/build.cake index 98f1bd2b8c..db7dfc7ff7 100644 --- a/native/windows/build.cake +++ b/native/windows/build.cake @@ -1,7 +1,8 @@ DirectoryPath ROOT_PATH = MakeAbsolute(Directory("../..")); DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native")); -DirectoryPath LLVM_HOME = Argument("llvm", EnvironmentVariable("LLVM_HOME") ?? "C:/Program Files/LLVM"); +var llvmHomeArg = Argument("llvm", EnvironmentVariable("LLVM_HOME") ?? "C:/Program Files/LLVM"); +DirectoryPath LLVM_HOME = string.IsNullOrEmpty(llvmHomeArg) || llvmHomeArg.ToLower() == "msvc" ? "" : llvmHomeArg; string VC_TOOLSET_VERSION = Argument("vcToolsetVersion", "14.2"); string SUPPORT_VULKAN_VAR = Argument ("supportVulkan", EnvironmentVariable ("SUPPORT_VULKAN") ?? "true"); @@ -13,7 +14,7 @@ bool SUPPORT_VULKAN = SUPPORT_VULKAN_VAR == "1" || SUPPORT_VULKAN_VAR.ToLower () string VARIANT = BUILD_VARIANT ?? "windows"; Information("Native Arguments:"); -Information($" {"LLVM_HOME".PadRight(30)} {{0}}", LLVM_HOME); +Information($" {"LLVM_HOME".PadRight(30)} {{0}}", string.IsNullOrEmpty(LLVM_HOME.FullPath) ? "(Using MSVC)" : LLVM_HOME); Information($" {"SUPPORT_VULKAN".PadRight(30)} {{0}}", SUPPORT_VULKAN); Information($" {"VARIANT".PadRight(30)} {{0}}", VARIANT); Information($" {"CONFIGURATION".PadRight(30)} {{0}}", CONFIGURATION); @@ -54,7 +55,7 @@ Task("libSkiaSharp") clang + win_vcvars_version + $"extra_cflags=[ '-DSKIA_C_DLL', '/MT{d}', '/EHsc', '/Z7', '-D_HAS_AUTO_PTR_ETC=1' ] " + - $"extra_ldflags=[ '/DEBUG:FULL' ] " + + $"extra_ldflags=[ '/DEBUG:FULL', '/DEBUGTYPE:CV,FIXUP' ] " + ADDITIONAL_GN_ARGS); var outDir = OUTPUT_PATH.Combine($"{VARIANT}/{dir}"); diff --git a/native/windows/libHarfBuzzSharp/libHarfBuzzSharp.vcxproj b/native/windows/libHarfBuzzSharp/libHarfBuzzSharp.vcxproj index 0589d79fb2..bd752caa19 100644 --- a/native/windows/libHarfBuzzSharp/libHarfBuzzSharp.vcxproj +++ b/native/windows/libHarfBuzzSharp/libHarfBuzzSharp.vcxproj @@ -148,6 +148,7 @@ Windows + /DEBUGTYPE:CV,FIXUP @@ -163,6 +164,7 @@ Windows + /DEBUGTYPE:CV,FIXUP @@ -178,6 +180,7 @@ Windows + /DEBUGTYPE:CV,FIXUP @@ -197,6 +200,7 @@ Windows true true + /DEBUGTYPE:CV,FIXUP @@ -216,6 +220,7 @@ Windows true true + /DEBUGTYPE:CV,FIXUP @@ -235,6 +240,7 @@ Windows true true + /DEBUGTYPE:CV,FIXUP diff --git a/native/winui/ANGLE.cake b/native/winui/ANGLE.cake new file mode 100644 index 0000000000..5fe7e4285d --- /dev/null +++ b/native/winui/ANGLE.cake @@ -0,0 +1,75 @@ +void InitializeAngle(string branch, DirectoryPath ANGLE_PATH, DirectoryPath WINAPPSDK_PATH) +{ + if (!DirectoryExists(ANGLE_PATH)) { + RunProcess("git", $"clone https://github.com/google/angle.git --branch {branch} --depth 1 --single-branch --shallow-submodules {ANGLE_PATH}"); + } + + var submodules = new[] { + "build", + "testing", + "third_party/zlib", + "third_party/jsoncpp", + "third_party/vulkan-deps", + "third_party/astc-encoder/src", + "tools/clang", + }; + foreach (var submodule in submodules) { + var sub = ANGLE_PATH.Combine(submodule); + if (FileExists(sub.CombineWithFilePath("BUILD.gn")) || FileExists(sub.CombineWithFilePath(".gitignore"))) + continue; + + RunProcess("git", new ProcessSettings { + Arguments = $"submodule update --init --recursive --depth 1 --single-branch {submodule}", + WorkingDirectory = ANGLE_PATH.FullPath, + }); + } + + { + var toolchain = ANGLE_PATH.CombineWithFilePath("build/toolchain/win/toolchain.gni"); + var contents = System.IO.File.ReadAllText(toolchain.FullPath); + var newContents = contents + .Replace("\"${dllname}.lib\"", "\"{{output_dir}}/{{target_output_name}}.lib\"") + .Replace("\"${dllname}.pdb\"", "\"{{output_dir}}/{{target_output_name}}.pdb\""); + if (contents != newContents) + System.IO.File.WriteAllText(toolchain.FullPath, newContents); + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/config/gclient_args.gni"))) { + var lines = new[] { + "checkout_angle_internal = false", + "checkout_angle_mesa = false", + "checkout_angle_restricted_traces = false", + "generate_location_tags = false" + }; + System.IO.File.WriteAllLines(ANGLE_PATH.CombineWithFilePath("build/config/gclient_args.gni").FullPath, lines); + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/util/LASTCHANGE"))) { + var lastchange = ANGLE_PATH.CombineWithFilePath("build/util/LASTCHANGE"); + RunPython(ANGLE_PATH, ANGLE_PATH.CombineWithFilePath("build/util/lastchange.py"), $"-o {lastchange}"); + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/toolchain/win/rc/win/rc.exe"))) { + var oldPath = EnvironmentVariable("PATH"); + try { + System.Environment.SetEnvironmentVariable("PATH", DEPOT_PATH.FullPath + System.IO.Path.PathSeparator + oldPath); + + RunPython(ANGLE_PATH, + DEPOT_PATH.CombineWithFilePath("download_from_google_storage.py"), + $"--no_resume --no_auth --bucket chromium-browser-clang/rc -s build/toolchain/win/rc/win/rc.exe.sha1"); + } finally { + System.Environment.SetEnvironmentVariable("PATH", oldPath); + } + } + + if (!FileExists(ANGLE_PATH.CombineWithFilePath("third_party/llvm-build/Release+Asserts/cr_build_revision"))) { + RunPython(ANGLE_PATH, ANGLE_PATH.CombineWithFilePath("tools/clang/scripts/update.py")); + } + + if (!FileExists(WINAPPSDK_PATH.CombineWithFilePath("Microsoft.WindowsAppSDK.nuspec"))) { + var setup = ANGLE_PATH.CombineWithFilePath("scripts/winappsdk_setup.py"); + RunProcess( + ROOT_PATH.CombineWithFilePath("scripts/vcvarsall.bat"), + $"\"{VS_INSTALL}\" \"x64\" \"{PYTHON_EXE}\" \"{setup}\" --output \"{WINAPPSDK_PATH}\""); + } +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.props b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.props new file mode 100644 index 0000000000..67ea2536c9 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.props @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.targets b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.targets new file mode 100644 index 0000000000..3d8b24a04d --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/Directory.Build.targets @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/SkiaSharp.Views.WinUI.Native.Projection.csproj b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/SkiaSharp.Views.WinUI.Native.Projection.csproj new file mode 100644 index 0000000000..85615cef2f --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.Projection/SkiaSharp.Views.WinUI.Native.Projection.csproj @@ -0,0 +1,26 @@ + + + + net7.0-windows10.0.19041.0 + 10.0.17763.0 + SkiaSharp.Views.WinUI + SkiaSharp.Views.WinUI + false + enable + enable + + + + None + SkiaSharp.Views.WinUI.Native + + + + + + + + + + + diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln new file mode 100644 index 0000000000..0435478c90 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln @@ -0,0 +1,61 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34310.174 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkiaSharp.Views.WinUI.Native", "SkiaSharp.Views.WinUI.Native\SkiaSharp.Views.WinUI.Native.vcxproj", "{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.WinUI.Native.Projection", "SkiaSharp.Views.WinUI.Native.Projection\SkiaSharp.Views.WinUI.Native.Projection.csproj", "{95E9FEB4-DCD3-4514-8208-A87688788BB2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|Any CPU.ActiveCfg = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|Any CPU.Build.0 = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|ARM64.Build.0 = Debug|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x64.ActiveCfg = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x64.Build.0 = Debug|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x86.ActiveCfg = Debug|Win32 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x86.Build.0 = Debug|Win32 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|Any CPU.ActiveCfg = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|Any CPU.Build.0 = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|ARM64.ActiveCfg = Release|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|ARM64.Build.0 = Release|ARM64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x64.ActiveCfg = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x64.Build.0 = Release|x64 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x86.ActiveCfg = Release|Win32 + {730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x86.Build.0 = Release|Win32 + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|ARM64.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x64.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x64.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x86.ActiveCfg = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x86.Build.0 = Debug|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|Any CPU.Build.0 = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|ARM64.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|ARM64.Build.0 = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x64.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x64.Build.0 = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x86.ActiveCfg = Release|Any CPU + {95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {FB8DA12F-84B5-4D7F-A6E1-7F0A53AA4535} + EndGlobalSection +EndGlobal diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.cpp b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.cpp new file mode 100644 index 0000000000..c2174e6cf7 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.cpp @@ -0,0 +1,19 @@ +#include "pch.h" +#include "PropertySetExtensions.h" +#include "PropertySetExtensions.g.cpp" + +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Foundation::Collections; + +namespace winrt::SkiaSharp::Views::WinUI::Native::implementation +{ + void PropertySetExtensions::AddSingle(PropertySet const& propertySet, hstring const& key, float value) + { + propertySet.Insert(key, PropertyValue::CreateSingle(value)); + } + + void PropertySetExtensions::AddSize(PropertySet const& propertySet, hstring const& key, Size const& height) + { + propertySet.Insert(key, PropertyValue::CreateSize(height)); + } +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.h b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.h new file mode 100644 index 0000000000..de60e32b45 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.h @@ -0,0 +1,24 @@ +#pragma once + +#include "PropertySetExtensions.g.h" + +using namespace winrt::Windows::Foundation; +using namespace winrt::Windows::Foundation::Collections; + +namespace winrt::SkiaSharp::Views::WinUI::Native::implementation +{ + struct PropertySetExtensions + { + PropertySetExtensions() = default; + + static void AddSingle(PropertySet const& propertySet, hstring const& key, float value); + static void AddSize(PropertySet const& propertySet, hstring const& key, Size const& value); + }; +} + +namespace winrt::SkiaSharp::Views::WinUI::Native::factory_implementation +{ + struct PropertySetExtensions : PropertySetExtensionsT + { + }; +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.idl b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.idl new file mode 100644 index 0000000000..278b3c896c --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/PropertySetExtensions.idl @@ -0,0 +1,8 @@ +namespace SkiaSharp.Views.WinUI.Native +{ + static runtimeclass PropertySetExtensions + { + static void AddSingle(Windows.Foundation.Collections.PropertySet propertySet, String key, Single value); + static void AddSize(Windows.Foundation.Collections.PropertySet propertySet, String key, Windows.Foundation.Size value); + } +} diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj new file mode 100644 index 0000000000..3906b7d76f --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj @@ -0,0 +1,184 @@ + + + + + + + true + true + true + {730af4c9-82d2-4fa7-aa32-154f3524ebd2} + SkiaSharp.Views.WinUI.Native + SkiaSharp.Views.WinUI.Native + en-US + 16.0 + false + Windows Store + 10.0 + 10.0.22621.0 + 10.0.17763.0 + true + true + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM64 + + + Release + Win32 + + + Release + x64 + + + Release + ARM64 + + + + DynamicLibrary + v143 + Unicode + false + true + + + true + true + + + false + true + false + + + + + + + + + + + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + false + $(ProjectDir)bin\$(Platform)\$(Configuration)\ + $(ProjectDir)obj\$(Platform)\$(Configuration)\ + + + + Use + pch.h + $(IntDir)pch.pch + Level4 + %(AdditionalOptions) /bigobj + _WINRT_DLL;%(PreprocessorDefinitions) + $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) + + + Console + true + SkiaSharp_Views_WinUI_Native.def + /DEBUGTYPE:CV,FIXUP + + + + + _DEBUG;%(PreprocessorDefinitions) + + + + + NDEBUG;%(PreprocessorDefinitions) + + + true + true + + + + + + PropertySetExtensions.cpp + + + + + Create + + + + + + + Code + PropertySetExtensions.cpp + + + + + + + + + false + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj.filters b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj.filters new file mode 100644 index 0000000000..099f47d334 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + accd3aa8-1ba0-4223-9bbe-0c431709210b + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tga;tiff;tif;png;wav;mfcribbon-ms + + + {926ab91d-31b4-48c3-b9a4-e681349f27f0} + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp_Views_WinUI_Native.def b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp_Views_WinUI_Native.def new file mode 100644 index 0000000000..24e7c1235c --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/SkiaSharp_Views_WinUI_Native.def @@ -0,0 +1,3 @@ +EXPORTS +DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE +DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/packages.config b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/packages.config new file mode 100644 index 0000000000..152b1d8ec4 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.cpp b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.cpp new file mode 100644 index 0000000000..1d9f38c57d --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.h b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.h new file mode 100644 index 0000000000..1533d96bb2 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/pch.h @@ -0,0 +1,26 @@ +#pragma once +#include +#include +#include +#include + +// Undefine GetCurrentTime macro to prevent +// conflict with Storyboard::GetCurrentTime +#undef GetCurrentTime + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/readme.txt b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/readme.txt new file mode 100644 index 0000000000..fd4c59a522 --- /dev/null +++ b/native/winui/SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native/readme.txt @@ -0,0 +1,27 @@ +======================================================================== + SkiaSharp.Views.WinUI.Native Project Overview +======================================================================== + +This project demonstrates how to get started authoring Windows Runtime +classes directly with standard C++, using the Windows App SDK and +C++/WinRT packages to generate implementation headers from interface +(IDL) files. The generated Windows Runtime component binary and WinMD +files should then be bundled with the app consuming them. + +Steps: +1. Create an interface (IDL) file to define your Windows Runtime class, + its default interface, and any other interfaces it implements. +2. Build the project once to generate module.g.cpp, module.h.cpp, and + implementation templates under the "Generated Files" folder, as + well as skeleton class definitions under "Generated Files\sources". +3. Use the skeleton class definitions for reference to implement your + Windows Runtime classes. + +======================================================================== +Learn more about Windows App SDK here: +https://docs.microsoft.com/windows/apps/windows-app-sdk/ +Learn more about WinUI3 here: +https://docs.microsoft.com/windows/apps/winui/winui3/ +Learn more about C++/WinRT here: +http://aka.ms/cppwinrt/ +======================================================================== diff --git a/native/winui/build.cake b/native/winui/build.cake new file mode 100644 index 0000000000..7409df544f --- /dev/null +++ b/native/winui/build.cake @@ -0,0 +1,93 @@ +DirectoryPath ROOT_PATH = MakeAbsolute(Directory("../..")); +DirectoryPath OUTPUT_PATH = MakeAbsolute(ROOT_PATH.Combine("output/native/winui")); + +#load "../../scripts/cake/native-shared.cake" +#load "../../scripts/cake/msbuild.cake" + +#load "ANGLE.cake" + +Task("ANGLE") + .IsDependentOn("git-sync-deps") + .WithCriteria(IsRunningOnWindows()) + .Does(() => +{ + var ANGLE_PATH = ROOT_PATH.Combine("externals/angle"); + var WINAPPSDK_PATH = ROOT_PATH.Combine("externals/winappsdk"); + + var branch = GetVersion("ANGLE", "release"); + + InitializeAngle(branch, ANGLE_PATH, WINAPPSDK_PATH); + + Build("x86"); + Build("x64"); + Build("arm64"); + + void Build(string arch) + { + if (Skip(arch)) return; + + try { + System.Environment.SetEnvironmentVariable("DEPOT_TOOLS_WIN_TOOLCHAIN", "0"); + + RunGn(ANGLE_PATH, $"out/winui/{arch}", + $"target_cpu='{arch}' " + + $"is_component_build=false " + + $"is_debug=false " + + $"is_clang=false " + + $"angle_is_winappsdk=true " + + $"winappsdk_dir='{WINAPPSDK_PATH}' " + + $"enable_precompiled_headers=false " + + $"angle_enable_null=false " + + $"angle_enable_wgpu=false " + + $"angle_enable_gl_desktop_backend=false " + + $"angle_enable_vulkan=false"); + + RunNinja(ANGLE_PATH, $"out/winui/{arch}", "libEGL libGLESv2"); + } finally { + System.Environment.SetEnvironmentVariable("DEPOT_TOOLS_WIN_TOOLCHAIN", ""); + } + + var outDir = OUTPUT_PATH.Combine(arch); + EnsureDirectoryExists(outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libEGL.dll"), outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libEGL.pdb"), outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libGLESv2.dll"), outDir); + CopyFileToDirectory(ANGLE_PATH.CombineWithFilePath($"out/winui/{arch}/libGLESv2.pdb"), outDir); + } +}); + +Task("SkiaSharp.Views.WinUI.Native") + .WithCriteria(IsRunningOnWindows()) + .Does(() => +{ + Build("x86", "Win32"); + Build("x64", "x64"); + Build("arm64", "arm64"); + + void Build(string arch, string nativeArch) + { + if (Skip(arch)) return; + + RunProcess("nuget", "restore SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln"); + RunMSBuild("SkiaSharp.Views.WinUI.Native/SkiaSharp.Views.WinUI.Native.sln", arch); + + var name = "SkiaSharp.Views.WinUI.Native"; + + var outDir = OUTPUT_PATH.Combine(arch); + EnsureDirectoryExists(outDir); + CopyFileToDirectory($"{name}/{name}/bin/{nativeArch}/{CONFIGURATION}/{name}.dll", outDir); + CopyFileToDirectory($"{name}/{name}/bin/{nativeArch}/{CONFIGURATION}/{name}.pdb", outDir); + CopyFileToDirectory($"{name}/{name}/bin/{nativeArch}/{CONFIGURATION}/{name}.winmd", outDir); + + var anyOutDir = OUTPUT_PATH.Combine("any"); + EnsureDirectoryExists(anyOutDir); + CopyFileToDirectory($"{name}/{name}.Projection/bin/{CONFIGURATION}/net7.0-windows10.0.19041.0/{name}.Projection.dll", anyOutDir); + CopyFileToDirectory($"{name}/{name}.Projection/bin/{CONFIGURATION}/net7.0-windows10.0.19041.0/{name}.Projection.pdb", anyOutDir); + } +}); + +Task("Default") + .IsDependentOn("ANGLE") + .IsDependentOn("SkiaSharp.Views.WinUI.Native"); + +RunTarget(TARGET); diff --git a/samples/Basic/Maui/SkiaSharpSample/SkiaSharpSample.csproj b/samples/Basic/Maui/SkiaSharpSample/SkiaSharpSample.csproj index 1fea779096..9b5b1c5498 100644 --- a/samples/Basic/Maui/SkiaSharpSample/SkiaSharpSample.csproj +++ b/samples/Basic/Maui/SkiaSharpSample/SkiaSharpSample.csproj @@ -37,5 +37,6 @@ + diff --git a/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj b/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj index c46e450c1e..40fc8e00b0 100644 --- a/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj +++ b/samples/Basic/WinUI/SkiaSharpSample/SkiaSharpSample.csproj @@ -12,7 +12,7 @@ - + @@ -32,5 +32,6 @@ + diff --git a/scripts/VERSIONS.txt b/scripts/VERSIONS.txt index a7c9249bfa..536f5bafc3 100644 --- a/scripts/VERSIONS.txt +++ b/scripts/VERSIONS.txt @@ -1,7 +1,7 @@ # dependencies mdoc release 5.8.9 harfbuzz release 8.3.0 -skia release m115 +skia release m116 xunit release 2.4.2 xunit.runner.console release 2.4.2 OpenTK release 3.1.0 @@ -17,17 +17,18 @@ Microsoft.WindowsAppSDK release 1.3.230602002 Microsoft.Maui.Graphics release 7.0.92 Microsoft.Windows.SDK.NET.Ref release 10.0.19041.27 Microsoft.AspNetCore.Components.Web release 6.0.0 +ANGLE release chromium/6275 # native milestones # this is related to the API versions, not the library versions # - milestone: the skia milestone determined by Google/Chromium # - increment: the C API version increment caused by new APIs (externals\skia\include\c\sk_types.h) -libSkiaSharp milestone 115 +libSkiaSharp milestone 116 libSkiaSharp increment 0 # native sonames # ..0 -libSkiaSharp soname 115.0.0 +libSkiaSharp soname 116.0.0 # 0.<60000 + major*100 + minor*10 + micro>.0 HarfBuzz soname 0.60830.0 @@ -53,6 +54,7 @@ SkiaSharp.NativeAssets.macOS nuget 3.0.0 SkiaSharp.NativeAssets.Tizen nuget 3.0.0 SkiaSharp.NativeAssets.tvOS nuget 3.0.0 SkiaSharp.NativeAssets.Win32 nuget 3.0.0 +SkiaSharp.NativeAssets.WinUI nuget 3.0.0 SkiaSharp.Views nuget 3.0.0 SkiaSharp.Views.Desktop.Common nuget 3.0.0 SkiaSharp.Views.Gtk3 nuget 3.0.0 @@ -66,6 +68,7 @@ SkiaSharp.Views.Blazor nuget 3.0.0 SkiaSharp.HarfBuzz nuget 3.0.0 SkiaSharp.Skottie nuget 3.0.0 SkiaSharp.SceneGraph nuget 3.0.0 +SkiaSharp.Resources nuget 3.0.0 SkiaSharp.Vulkan.SharpVk nuget 3.0.0 # HarfBuzzSharp HarfBuzzSharp nuget 8.3.0 diff --git a/scripts/azure-pipelines-complete-internal.yml b/scripts/azure-pipelines-complete-internal.yml index 56a0d9b61b..394a5de69d 100644 --- a/scripts/azure-pipelines-complete-internal.yml +++ b/scripts/azure-pipelines-complete-internal.yml @@ -4,43 +4,56 @@ pr: none parameters: - name: buildExternals - displayName: 'The specific native artifacts to use for this build.' + displayName: 'The Build ID containing the specific native artifacts to use:' type: string default: 'latest' - - name: VM_IMAGE_HOST + - name: buildAgentHost + displayName: 'The generic host build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: ubuntu-20.04 - - name: VM_IMAGE_WINDOWS + os: windows + - name: buildAgentWindows + displayName: 'The Windows build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: windows-2022 - - name: VM_IMAGE_MAC + os: windows + - name: buildAgentMac + displayName: 'The macOS build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: macos-13 - - name: VM_IMAGE_LINUX + os: macos + - name: buildAgentLinux + displayName: 'The Linux build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: ubuntu-20.04 + os: linux + - name: enableSigning + displayName: 'Enable package signing (Test signing)' + type: boolean + default: false - name: runCompliance + displayName: 'Run post-build compliance tasks (such as API Scan and PoliCheck)' + type: boolean + default: false + - name: use1ESPipelineTemplates + displayName: 'Run the build using the internal 1ES Pipeline Templates' type: boolean default: false - -pool: - name: Azure Pipelines - vmImage: ubuntu-20.04 variables: - - template: azure-pipelines-variables.yml + - template: /scripts/azure-pipelines-variables.yml@self resources: repositories: @@ -49,17 +62,51 @@ resources: name: xamarin/yaml-templates endpoint: xamarin ref: refs/heads/main + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release -stages: - - template: azure-templates-stages.yml - parameters: - buildPipelineType: 'both' - buildExternals: ${{ parameters.buildExternals }} - runCompliance: ${{ parameters.runCompliance }} - VM_IMAGE_HOST: ${{ parameters.VM_IMAGE_HOST }} - VM_IMAGE_WINDOWS: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_WINDOWS_NATIVE: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_MAC: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_MAC_NATIVE: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_LINUX: ${{ parameters.VM_IMAGE_LINUX }} - VM_IMAGE_LINUX_NATIVE: ${{ parameters.VM_IMAGE_LINUX }} +extends: + ${{ if eq('${{ parameters.use1ESPipelineTemplates }}', 'true') }}: + template: v1/1ES.Unofficial.PipelineTemplate.yml@1ESPipelineTemplates + ${{ if ne('${{ parameters.use1ESPipelineTemplates }}', 'true') }}: + template: /scripts/azure-template.yml@self + parameters: + pool: ${{ parameters.buildAgentHost.pool }} + customBuildTags: + - ES365AIMigrationTooling + stages: + - template: /scripts/azure-templates-stages.yml@self + parameters: + buildPipelineType: 'both' + buildExternals: ${{ parameters.buildExternals }} + enableSigning: ${{ parameters.enableSigning }} + ${{ if eq(parameters.runCompliance, 'true') }}: + sdl: + apiscan: + enabled: true + binskim: + break: false + codeInspector: + enabled: true + credscan: + suppressionsFile: $(Build.SourcesDirectory)\scripts\guardian\CredScanSuppressions.json + policheck: + enabled: true + exclusionsFile: $(Build.SourcesDirectory)\scripts\guardian\PoliCheckExclusions.xml + spotBugs: + enabled: false + suppression: + suppressionFile: $(Build.SourcesDirectory)\scripts\guardian\source.gdnsuppress + tsa: + enabled: true + configFile: $(Build.SourcesDirectory)\scripts\guardian\tsaoptions-v2.json + use1ESPipelineTemplates: ${{ parameters.use1ESPipelineTemplates }} + buildAgentHost: ${{ parameters.buildAgentHost }} + buildAgentWindows: ${{ parameters.buildAgentWindows }} + buildAgentWindowsNative: ${{ parameters.buildAgentWindows }} + buildAgentMac: ${{ parameters.buildAgentMac }} + buildAgentMacNative: ${{ parameters.buildAgentMac }} + buildAgentLinux: ${{ parameters.buildAgentLinux }} + buildAgentLinuxNative: ${{ parameters.buildAgentLinux }} \ No newline at end of file diff --git a/scripts/azure-pipelines-complete.yml b/scripts/azure-pipelines-complete.yml index f0c44874d6..f3deca19b0 100644 --- a/scripts/azure-pipelines-complete.yml +++ b/scripts/azure-pipelines-complete.yml @@ -10,50 +10,58 @@ pr: parameters: - name: buildExternals - displayName: 'The specific native artifacts to use for this build.' + displayName: 'The Build ID containing the specific native artifacts to use:' type: string default: 'latest' - - name: VM_IMAGE_HOST + - name: buildAgentHost + displayName: 'The generic host build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: ubuntu-20.04 - - name: VM_IMAGE_WINDOWS + os: windows + - name: buildAgentWindows + displayName: 'The Windows build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: windows-2022 - - name: VM_IMAGE_MAC + os: windows + - name: buildAgentMac + displayName: 'The macOS build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: macos-13 - - name: VM_IMAGE_LINUX + os: macos + - name: buildAgentLinux + displayName: 'The Linux build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: ubuntu-20.04 - -pool: - name: Azure Pipelines - vmImage: ubuntu-20.04 + os: linux variables: - - template: azure-pipelines-variables.yml + - template: /scripts/azure-pipelines-variables.yml@self -stages: - - template: azure-templates-stages.yml - parameters: - buildPipelineType: 'both' - buildExternals: ${{ parameters.buildExternals }} - VM_IMAGE_HOST: ${{ parameters.VM_IMAGE_HOST }} - VM_IMAGE_WINDOWS: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_WINDOWS_NATIVE: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_MAC: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_MAC_NATIVE: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_LINUX: ${{ parameters.VM_IMAGE_LINUX }} - VM_IMAGE_LINUX_NATIVE: ${{ parameters.VM_IMAGE_LINUX }} +extends: + template: /scripts/azure-template.yml@self + parameters: + pool: ${{ parameters.buildAgentHost.pool }} + stages: + - template: /scripts/azure-templates-stages.yml@self + parameters: + buildPipelineType: 'both' + buildExternals: ${{ parameters.buildExternals }} + buildAgentHost: ${{ parameters.buildAgentHost }} + buildAgentWindows: ${{ parameters.buildAgentWindows }} + buildAgentWindowsNative: ${{ parameters.buildAgentWindows }} + buildAgentMac: ${{ parameters.buildAgentMac }} + buildAgentMacNative: ${{ parameters.buildAgentMac }} + buildAgentLinux: ${{ parameters.buildAgentLinux }} + buildAgentLinuxNative: ${{ parameters.buildAgentLinux }} diff --git a/scripts/azure-pipelines-tests.yml b/scripts/azure-pipelines-tests.yml index 1127a2e8cb..f7dc37e227 100644 --- a/scripts/azure-pipelines-tests.yml +++ b/scripts/azure-pipelines-tests.yml @@ -3,33 +3,41 @@ trigger: none pr: none parameters: - - name: VM_IMAGE_HOST + - name: buildAgentHost + displayName: 'The generic host build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: ubuntu-20.04 - - name: VM_IMAGE_WINDOWS + os: windows + - name: buildAgentWindows + displayName: 'The Windows build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: windows-2022 - - name: VM_IMAGE_MAC + os: windows + - name: buildAgentMac + displayName: 'The macOS build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: macos-13 - - name: VM_IMAGE_LINUX + os: macos + - name: buildAgentLinux + displayName: 'The Linux build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: ubuntu-20.04 + os: linux variables: - - template: azure-pipelines-variables.yml + - template: /scripts/azure-pipelines-variables.yml@self resources: repositories: @@ -43,14 +51,18 @@ resources: source: SkiaSharp trigger: true -stages: - - template: azure-templates-stages.yml - parameters: - buildPipelineType: 'tests' - VM_IMAGE_HOST: ${{ parameters.VM_IMAGE_HOST }} - VM_IMAGE_WINDOWS: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_WINDOWS_NATIVE: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_MAC: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_MAC_NATIVE: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_LINUX: ${{ parameters.VM_IMAGE_LINUX }} - VM_IMAGE_LINUX_NATIVE: ${{ parameters.VM_IMAGE_LINUX }} +extends: + template: /scripts/azure-template.yml@self + parameters: + pool: ${{ parameters.buildAgentHost.pool }} + stages: + - template: /scripts/azure-templates-stages.yml@self + parameters: + buildPipelineType: 'tests' + buildAgentHost: ${{ parameters.buildAgentHost }} + buildAgentWindows: ${{ parameters.buildAgentWindows }} + buildAgentWindowsNative: ${{ parameters.buildAgentWindows }} + buildAgentMac: ${{ parameters.buildAgentMac }} + buildAgentMacNative: ${{ parameters.buildAgentMac }} + buildAgentLinux: ${{ parameters.buildAgentLinux }} + buildAgentLinuxNative: ${{ parameters.buildAgentLinux }} \ No newline at end of file diff --git a/scripts/azure-pipelines-variables.yml b/scripts/azure-pipelines-variables.yml index 53e405a4af..ef6f1c7c03 100644 --- a/scripts/azure-pipelines-variables.yml +++ b/scripts/azure-pipelines-variables.yml @@ -1,4 +1,5 @@ variables: + SKIASHARP_MAJOR_VERSION: 3 SKIASHARP_VERSION: 3.0.0 FEATURE_NAME_PREFIX: 'feature/' VERBOSITY: normal @@ -16,7 +17,7 @@ variables: VISUAL_STUDIO_VERSION: '' DOTNET_VERSION_PREVIEW: '' DOTNET_WORKLOAD_SOURCE: '' - DOTNET_WORKLOAD_TIZEN: '' + DOTNET_WORKLOAD_TIZEN: '7.0.123' CONFIGURATION: 'Release' DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true NUGET_DIFF_PRERELEASE: false diff --git a/scripts/azure-pipelines.yml b/scripts/azure-pipelines.yml index 3b72b46332..30e6bcb5e8 100644 --- a/scripts/azure-pipelines.yml +++ b/scripts/azure-pipelines.yml @@ -10,36 +10,48 @@ pr: parameters: - name: buildExternals - displayName: 'The specific native artifacts to use for this build.' + displayName: 'The Build ID containing the specific native artifacts to use:' type: string default: 'latest' - - name: VM_IMAGE_HOST + - name: buildAgentHost + displayName: 'The generic host build agent configuration:' type: object default: pool: - name: Azure Pipelines - vmImage: ubuntu-20.04 - - name: VM_IMAGE_WINDOWS + name: Maui-1ESPT + image: 1ESPT-Windows2022 + os: windows + - name: buildAgentWindows + displayName: 'The Windows build agent configuration:' type: object default: pool: - name: Azure Pipelines - vmImage: windows-2022 - - name: VM_IMAGE_MAC + name: Maui-1ESPT + image: 1ESPT-Windows2022 + os: windows + - name: buildAgentMac + displayName: 'The macOS build agent configuration:' type: object default: pool: name: Azure Pipelines vmImage: macos-13 - - name: VM_IMAGE_LINUX + os: macos + - name: buildAgentLinux + displayName: 'The Linuk build agent configuration:' type: object default: pool: - name: Azure Pipelines - vmImage: ubuntu-20.04 + name: Maui-1ESPT + image: 1ESPT-Ubuntu20.04 + os: linux + - name: runCompliance + displayName: 'Run post-build compliance tasks (such as API Scan and PoliCheck)' + type: boolean + default: false variables: - - template: azure-pipelines-variables.yml + - template: /scripts/azure-pipelines-variables.yml@self resources: repositories: @@ -48,16 +60,51 @@ resources: name: xamarin/yaml-templates endpoint: xamarin ref: refs/heads/main + - repository: 1ESPipelineTemplates + type: git + name: 1ESPipelineTemplates/1ESPipelineTemplates + ref: refs/tags/release -stages: - - template: azure-templates-stages.yml - parameters: - buildPipelineType: 'build' - buildExternals: ${{ parameters.buildExternals }} - VM_IMAGE_HOST: ${{ parameters.VM_IMAGE_HOST }} - VM_IMAGE_WINDOWS: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_WINDOWS_NATIVE: ${{ parameters.VM_IMAGE_WINDOWS }} - VM_IMAGE_MAC: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_MAC_NATIVE: ${{ parameters.VM_IMAGE_MAC }} - VM_IMAGE_LINUX: ${{ parameters.VM_IMAGE_LINUX }} - VM_IMAGE_LINUX_NATIVE: ${{ parameters.VM_IMAGE_LINUX }} +extends: + template: v1/1ES.Official.PipelineTemplate.yml@1ESPipelineTemplates + parameters: + pool: ${{ parameters.buildAgentHost.pool }} + customBuildTags: + - ES365AIMigrationTooling + stages: + - template: /scripts/azure-templates-stages.yml@self + parameters: + buildPipelineType: 'build' + buildExternals: ${{ parameters.buildExternals }} + ${{ if and(eq(variables['System.TeamProject'], 'devdiv'), ne(variables['System.PullRequest.IsFork'], 'true')) }}: + enableSigning: true + ${{ if or(parameters.runCompliance, and(eq(variables['Build.Reason'], 'Schedule'), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/')))) }}: + sdl: + apiscan: + enabled: true + binskim: + enabled: true + break: false + codeInspector: + enabled: true + credscan: + enabled: true + # suppressionsFile: $(Build.SourcesDirectory)\scripts\guardian\CredScanSuppressions.json + policheck: + enabled: true + exclusionsFile: $(Build.SourcesDirectory)\scripts\guardian\PoliCheckExclusions.xml + spotBugs: + enabled: false + suppression: + suppressionFile: $(Build.SourcesDirectory)\scripts\guardian\source.gdnsuppress + tsa: + enabled: true + configFile: $(Build.SourcesDirectory)\scripts\guardian\tsaoptions-v2.json + use1ESPipelineTemplates: true + buildAgentHost: ${{ parameters.buildAgentHost }} + buildAgentWindows: ${{ parameters.buildAgentWindows }} + buildAgentWindowsNative: ${{ parameters.buildAgentWindows }} + buildAgentMac: ${{ parameters.buildAgentMac }} + buildAgentMacNative: ${{ parameters.buildAgentMac }} + buildAgentLinux: ${{ parameters.buildAgentLinux }} + buildAgentLinuxNative: ${{ parameters.buildAgentLinux }} \ No newline at end of file diff --git a/scripts/azure-template.yml b/scripts/azure-template.yml new file mode 100644 index 0000000000..e7c203aa64 --- /dev/null +++ b/scripts/azure-template.yml @@ -0,0 +1,31 @@ +parameters: + - name: stages + type: stageList + default: [] + - name: pool + type: object + default: {} + - name: customBuildTags + type: object + default: null + +stages: + - ${{ each stage in parameters.stages }}: + - ${{ each stageProperty in stage }}: + ${{ if notIn(stageProperty.key, 'jobs', 'pool') }}: + ${{ stageProperty.key }}: ${{ stageProperty.value }} + pool: ${{ parameters.pool }} + jobs: + - ${{ each job in stage.jobs }}: + - ${{ each jobProperty in job }}: + ${{ if notIn(jobProperty.key, 'steps', 'templateContext') }}: + ${{ jobProperty.key }}: ${{ jobProperty.value }} + steps: + - ${{ job.steps }} + - ${{ each output in job.templateContext.outputs }}: + - task: PublishPipelineArtifact@1 + displayName: ${{ output.displayName }} + condition: ${{ coalesce(output.condition, 'succeeded()') }} + inputs: + artifactName: ${{ output.artifactName }} + targetPath: ${{ output.targetPath }} \ No newline at end of file diff --git a/scripts/azure-templates-bootstrapper.yml b/scripts/azure-templates-bootstrapper.yml index ab003209e0..5fe77fc96b 100644 --- a/scripts/azure-templates-bootstrapper.yml +++ b/scripts/azure-templates-bootstrapper.yml @@ -1,7 +1,7 @@ parameters: name: '' # in the form type_platform_host displayName: '' # the human name - vmImage: '' # the VM image + buildAgent: '' # the configuration for the build agent packages: '' # any additional packages target: '' # the bootstrapper target dependsOn: [] # the dependiencies @@ -30,26 +30,56 @@ parameters: installLlvm: true # whether or not to install the LLVM compiler installEmsdk: false # whether or not to install the Emscripten SDK installNinja: false # whether or not to install the ninja build system - artifactName: '' # the name of the artifact to merge this run into + publishArtifacts: [] # the additional artifacts to publish tools: [] # any additional .net global tools + skipInstall: false # whether or not to install any tools + skipSteps: false # whether or not to run any steps + use1ESPipelineTemplates: false # whether or not we are building using the internal 1ES Pipeline Templates + sdl: [] # the SDL properties to use for this job jobs: - job: ${{ parameters.name }} displayName: ${{ parameters.displayName }} timeoutInMinutes: 180 - pool: ${{ parameters.vmImage.pool }} + pool: ${{ parameters.buildAgent.pool }} dependsOn: ${{ parameters.dependsOn }} condition: ${{ parameters.condition }} variables: - ${{ if ne(parameters.vmImage.variables, '') }}: - ${{ parameters.vmImage.variables }} + ${{ if ne(parameters.buildAgent.variables, '') }}: + ${{ parameters.buildAgent.variables }} ${{ if ne(length(parameters.variables), 0) }}: ${{ parameters.variables }} + templateContext: + sdl: ${{ parameters.sdl }} + outputParentDirectory: 'output' + outputs: + - ${{ if eq(parameters.shouldPublish, 'true') }}: + - output: pipelineArtifact + displayName: 'Publish the ${{ parameters.name }} artifacts' + artifactName: ${{ parameters.name }} + targetPath: 'output' + - output: pipelineArtifact + displayName: 'Publish the failed ${{ parameters.name }} artifacts' + condition: failed() + artifactName: ${{ parameters.name }}_failed_$(System.JobAttempt) + targetPath: 'output' + - ${{ each additionalArtifact in parameters.publishArtifacts }}: + - output: pipelineArtifact + displayName: 'Publish the ${{ additionalArtifact.name }} artifacts' + artifactName: ${{ additionalArtifact.name }} + targetPath: ${{ additionalArtifact.path }} + - ${{ if eq(additionalArtifact.always, 'true') }}: + - output: pipelineArtifact + displayName: 'Publish the failed ${{ additionalArtifact.name }} artifacts' + condition: failed() + artifactName: ${{ additionalArtifact.name }}_failed_$(System.JobAttempt) + targetPath: ${{ additionalArtifact.path }} + steps: # prepare - checkout: self submodules: recursive - - template: azure-templates-variables.yml + - template: /scripts/azure-templates-variables.yml@self # checkout required skia PR - pwsh: .\scripts\checkout-skia.ps1 -GitHubToken $(GitHub.Token.PublicAccess) @@ -57,7 +87,7 @@ jobs: condition: eq(variables['Build.Reason'], 'PullRequest') - ${{ if eq(parameters.buildPipelineType, 'tests') }}: - - template: azure-templates-github-status.yml + - template: /scripts/azure-templates-github-status.yml@self parameters: state: 'pending' @@ -66,13 +96,13 @@ jobs: displayName: Determine build type # provisioning steps - - ${{ if ne(parameters.vmImage.provisioningSteps, '') }}: - - ${{ parameters.vmImage.provisioningSteps }} + - ${{ if ne(parameters.buildAgent.provisioningSteps, '') }}: + - ${{ parameters.buildAgent.provisioningSteps }} - ${{ if ne(length(parameters.provisioningSteps), 0) }}: - ${{ parameters.provisioningSteps }} # install any packages on linux - - ${{ if and(eq(parameters.docker, ''), endsWith(parameters.name, '_linux')) }}: + - ${{ if and(eq(parameters.docker, ''), endsWith(parameters.name, '_linux'), ne(parameters.skipInstall, 'true')) }}: - bash: | sudo apt update sudo apt install -y ${{ parameters.packages }} @@ -81,7 +111,7 @@ jobs: condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], ''), ne('${{ parameters.packages }}', '')) # install extra bits for the native builds - - ${{ if startsWith(parameters.name, 'native_') }}: + - ${{ if and(startsWith(parameters.name, 'native_'), ne(parameters.skipInstall, 'true')) }}: # switch to the correct Python version - task: UsePythonVersion@0 displayName: Switch to the correct Python version @@ -120,7 +150,7 @@ jobs: condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) # install extra bits for the managed builds - - ${{ if not(startsWith(parameters.name, 'native_')) }}: + - ${{ if and(not(startsWith(parameters.name, 'native_')), ne(parameters.skipInstall, 'true')) }}: # install ninja - ${{ if eq(parameters.installNinja, 'true') }}: - pwsh: .\scripts\install-ninja.ps1 @@ -158,13 +188,6 @@ jobs: - pwsh: Remove-Item "$env:AGENT_TOOLSDIRECTORY/dotnet" -Recurse -Force -ErrorAction SilentlyContinue displayName: Cleanup existing versions of .NET condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) - - task: UseDotNet@2 - condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) - inputs: - packageType: 'sdk' - version: 3.1.x - retryCountOnTaskFailure: 3 - displayName: Install .NET 3.1.x - task: UseDotNet@2 condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) inputs: @@ -201,7 +224,7 @@ jobs: displayName: Install the .NET workloads # install the mac tools - - ${{ if endsWith(parameters.name, '_macos') }}: + - ${{ if and(endsWith(parameters.name, '_macos'), ne(parameters.skipInstall, 'true')) }}: - ${{ if not(startsWith(parameters.name, 'native_')) }}: - bash: sudo ./scripts/select-xcode.sh $(XCODE_VERSION) displayName: Switch to the latest Xcode @@ -212,14 +235,14 @@ jobs: condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) # install the linux tools - - ${{ if and(eq(parameters.installEmsdk, 'true'), endsWith(parameters.name, '_linux')) }}: + - ${{ if and(eq(parameters.installEmsdk, 'true'), endsWith(parameters.name, '_linux'), ne(parameters.skipInstall, 'true')) }}: - bash: ./scripts/install-emsdk.sh $(EMSCRIPTEN_VERSION) displayName: Install the Emscripten SDK retryCountOnTaskFailure: 3 condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) # install the Windows tools - - ${{ if endsWith(parameters.name, '_windows') }}: + - ${{ if and(endsWith(parameters.name, '_windows'), ne(parameters.skipInstall, 'true')) }}: # select the correct/latest version of Visual Studio - pwsh: .\scripts\select-vs.ps1 displayName: Select Visual Studio @@ -245,18 +268,19 @@ jobs: condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) # install any .NET global tools - - ${{ each tool in parameters.tools }}: - - pwsh: dotnet tool install -g ${{ tool }} - displayName: Install ${{ tool }} - retryCountOnTaskFailure: 3 - condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) + - ${{ if ne(parameters.skipInstall, 'true') }}: + - ${{ each tool in parameters.tools }}: + - pwsh: dotnet tool install -g ${{ tool }} + displayName: Install ${{ tool }} + retryCountOnTaskFailure: 3 + condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) # download artifacts - - template: azure-templates-download-artifacts.yml + - template: /scripts/azure-templates-download-artifacts.yml@self parameters: condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) artifacts: ${{ parameters.requiredArtifacts }} - - template: azure-templates-download-artifacts.yml + - template: /scripts/azure-templates-download-artifacts.yml@self parameters: condition: and(succeeded(), ne(variables['DOWNLOAD_EXTERNALS'], '')) sourceBuildId: $(DOWNLOAD_EXTERNALS) @@ -264,88 +288,76 @@ jobs: - name: ${{ parameters.name }} # pre-build steps - - ${{ if ne(parameters.vmImage.preBuildSteps, '') }}: - - ${{ parameters.vmImage.preBuildSteps }} + - ${{ if ne(parameters.buildAgent.preBuildSteps, '') }}: + - ${{ parameters.buildAgent.preBuildSteps }} - ${{ if ne(length(parameters.preBuildSteps), 0) }}: - ${{ parameters.preBuildSteps }} - # build - - ${{ if eq(parameters.docker, '') }}: - - ${{ if endsWith(parameters.name, '_windows') }}: - - pwsh: | - Get-Content $PSCommandPath - dotnet tool restore - ${{ parameters.initScript }} - dotnet cake --target=${{ parameters.target }} --verbosity=${{ parameters.verbosity }} --configuration=${{ coalesce(parameters.configuration, 'Release') }} ${{ parameters.additionalArgs }} + # actual build + - ${{ if ne(parameters.skipSteps, 'true') }}: + - ${{ if eq(parameters.docker, '') }}: + - ${{ if endsWith(parameters.name, '_windows') }}: + - pwsh: | + Get-Content $PSCommandPath + dotnet tool restore + ${{ parameters.initScript }} + dotnet cake --target=${{ parameters.target }} --verbosity=${{ parameters.verbosity }} --configuration=${{ coalesce(parameters.configuration, 'Release') }} ${{ parameters.additionalArgs }} - env: - JavaSdkDirectory: $(JAVA_HOME) - LLVM_HOME: $(LLVM_HOME) - # There seems to be a bug in some verions of mspdbcmf.exe. This looks to be fixed in a VS preview. - AppxSymbolPackageEnabled: false - displayName: Run the bootstrapper for ${{ parameters.target }} - retryCountOnTaskFailure: ${{ parameters.retryCount }} + env: + JavaSdkDirectory: $(JAVA_HOME) + LLVM_HOME: $(LLVM_HOME) + # There seems to be a bug in some verions of mspdbcmf.exe. This looks to be fixed in a VS preview. + AppxSymbolPackageEnabled: false + displayName: Run the bootstrapper for ${{ parameters.target }} + retryCountOnTaskFailure: ${{ parameters.retryCount }} + condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) + - ${{ if not(endsWith(parameters.name, '_windows')) }}: + - bash: | + cat ${BASH_SOURCE[0]} + dotnet tool restore + ${{ parameters.initScript }} + dotnet cake --target=${{ parameters.target }} --verbosity=${{ parameters.verbosity }} --configuration=${{ coalesce(parameters.configuration, 'Release') }} ${{ parameters.additionalArgs }} + + env: + JavaSdkDirectory: $(JAVA_HOME) + displayName: Run the bootstrapper for ${{ parameters.target }} + retryCountOnTaskFailure: ${{ parameters.retryCount }} + condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) + - ${{ if ne(parameters.docker, '') }}: + - ${{ if eq(parameters.use1ESPipelineTemplates, 'true') }}: + - task: 1ES.BuildContainerImage@1 + displayName: Build the Docker image for ${{ parameters.docker }} + condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) + inputs: + dockerfile: ${{ parameters.docker }}/Dockerfile + context: ${{ parameters.docker }} + image: skiasharp:skiasharp + buildArguments: --tag skiasharp ${{ parameters.dockerArgs }} + enableNetwork: true + - ${{ if ne(parameters.use1ESPipelineTemplates, 'true') }}: + - task: Docker@2 + displayName: Build the Docker image for ${{ parameters.docker }} + condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) + inputs: + command: build + buildContext: ${{ parameters.docker }} + dockerfile: ${{ parameters.docker }}/Dockerfile + arguments: --tag skiasharp ${{ parameters.dockerArgs }} + - bash: | + echo dotnet tool restore > cmd.sh + echo dotnet cake --target=${{ parameters.target }} --verbosity=${{ parameters.verbosity }} --configuration=${{ coalesce(parameters.configuration, 'Release') }} ${{ parameters.additionalArgs }} >> cmd.sh + sed -i 's/--gnArgs=\" \"//' cmd.sh + cat cmd.sh + displayName: Generate the script for the Docker image condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) - - ${{ if not(endsWith(parameters.name, '_windows')) }}: - bash: | - cat ${BASH_SOURCE[0]} - dotnet tool restore - ${{ parameters.initScript }} - dotnet cake --target=${{ parameters.target }} --verbosity=${{ parameters.verbosity }} --configuration=${{ coalesce(parameters.configuration, 'Release') }} ${{ parameters.additionalArgs }} - - env: - JavaSdkDirectory: $(JAVA_HOME) - displayName: Run the bootstrapper for ${{ parameters.target }} + docker run --rm --name skiasharp --volume $(pwd):/work skiasharp /bin/bash /work/cmd.sh + displayName: Run the bootstrapper for ${{ parameters.target }} using the Docker image retryCountOnTaskFailure: ${{ parameters.retryCount }} condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) - - ${{ if ne(parameters.docker, '') }}: - - task: Docker@2 - displayName: Build the Docker image for ${{ parameters.docker }} - condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) - inputs: - command: build - buildContext: ${{ parameters.docker }} - dockerfile: ${{ parameters.docker }}/Dockerfile - arguments: --tag skiasharp ${{ parameters.dockerArgs }} - - bash: | - echo dotnet tool restore > cmd.sh - echo dotnet cake --target=${{ parameters.target }} --verbosity=${{ parameters.verbosity }} --configuration=${{ coalesce(parameters.configuration, 'Release') }} ${{ parameters.additionalArgs }} >> cmd.sh - sed -i 's/--gnArgs=\" \"//' cmd.sh - cat cmd.sh - displayName: Generate the script for the Docker image - condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) - - bash: | - docker run --rm --name skiasharp --volume $(pwd):/work skiasharp /bin/bash /work/cmd.sh - displayName: Run the bootstrapper for ${{ parameters.target }} using the Docker image - retryCountOnTaskFailure: ${{ parameters.retryCount }} - condition: and(succeeded(), eq(variables['DOWNLOAD_EXTERNALS'], '')) # post-build steps - ${{ parameters.postBuildSteps }} - # publish artifacts - - task: PublishBuildArtifacts@1 - displayName: Publish the ${{ parameters.name }} artifacts - condition: or(${{ parameters.shouldPublish }}, failed()) - retryCountOnTaskFailure: 3 - inputs: - artifactName: ${{ parameters.name }} - pathToPublish: 'output' - - ${{ if ne(parameters.artifactName, '') }}: - - task: PublishBuildArtifacts@1 - displayName: Publish the combined ${{ parameters.artifactName }} artifacts - retryCountOnTaskFailure: 3 - inputs: - artifactName: ${{ parameters.artifactName }} - pathToPublish: 'output' - - ${{ if eq(variables['System.TeamProject'], 'devdiv') }}: - - task: ComponentGovernanceComponentDetection@0 - displayName: Run component detection - condition: always() - inputs: - scanType: 'Register' - verbosity: 'Verbose' - alertWarningLevel: 'High' - - ${{ if eq(parameters.buildPipelineType, 'tests') }}: - - template: azure-templates-github-status.yml + - template: /scripts/azure-templates-github-status.yml@self diff --git a/scripts/azure-templates-download-artifacts.yml b/scripts/azure-templates-download-artifacts.yml index db94dadcbe..2300409591 100644 --- a/scripts/azure-templates-download-artifacts.yml +++ b/scripts/azure-templates-download-artifacts.yml @@ -54,9 +54,10 @@ steps: downloadType: 'single' allowPartiallySucceededBuilds: true artifactName: ${{ artifact.name }} - downloadPath: 'download-temp' + downloadPath: 'download-temp/${{ artifact.name }}' - pwsh: | + Get-ChildItem '.\download-temp\' New-Item '.\output\${{ artifact.dir }}\' -Type Directory -Force | Out-Null Get-ChildItem '.\download-temp\${{ artifact.name }}\' | Copy-Item -Destination '.\output\${{ artifact.dir }}\' -Recurse -Force Remove-Item '.\download-temp\${{ artifact.name }}\' -Recurse -Force diff --git a/scripts/azure-templates-linux-matrix.yml b/scripts/azure-templates-linux-matrix.yml index 6bad3fbbd1..26681ce2d0 100644 --- a/scripts/azure-templates-linux-matrix.yml +++ b/scripts/azure-templates-linux-matrix.yml @@ -1,8 +1,9 @@ parameters: - artifactName: '' # the name of the artifact to merge this run into buildExternals: '' # the build number to download externals from buildPipelineType: 'both' # the type of build pipeline setup - vmImage: '' # the VM image + buildAgent: '' # the configuration for the build agent + use1ESPipelineTemplates: false # whether or not we are building using the internal 1ES Pipeline Templates + sdl: [] # the SDL properties to use for this job builds: - name: '' desc: '' @@ -20,15 +21,16 @@ parameters: jobs: - ${{ each build in parameters.builds }}: - ${{ each item in parameters.matrix }}: - - template: azure-templates-bootstrapper.yml + - template: /scripts/azure-templates-bootstrapper.yml@self parameters: name: ${{ replace(replace(format('native_linux_{0}_{1}_{2}_{3}_linux', item.arch, item.variant, build.name, item.alt), '__', '_'), '__', '_') }} displayName: Linux ${{ replace(replace(replace(replace(replace(format('({0}|{1}|{2}|{3})', item.arch, item.variant, build.name, item.alt), '||', '|'), '||', '|'), '(|', '('), '|)', ')'), '|', ', ') }} + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.vmImage }} + buildAgent: ${{ parameters.buildAgent }} + use1ESPipelineTemplates: ${{ parameters.use1ESPipelineTemplates }} docker: ${{ item.docker }} dockerArgs: ${{ item.dockerArgs }} target: ${{ coalesce(item.target, 'externals-linux') }} - additionalArgs: --buildarch=${{ item.arch }} --variant=${{ coalesce(item.variant, 'linux') }}${{ build.name }} --gnArgs="\"${{ build.gnArgs }} ${{ item.gnArgs }}\"" ${{ build.additionalArgs }} ${{ item.additionalArgs }} - artifactName: ${{ parameters.artifactName }} + additionalArgs: --buildarch=${{ item.arch }} --variant=${{ coalesce(item.variant, 'linux') }}${{ build.name }} --gnArgs="\"${{ build.gnArgs }} ${{ item.gnArgs }}\"" ${{ build.additionalArgs }} ${{ item.additionalArgs }} \ No newline at end of file diff --git a/scripts/azure-templates-merger.yml b/scripts/azure-templates-merger.yml new file mode 100644 index 0000000000..23b9eb65c2 --- /dev/null +++ b/scripts/azure-templates-merger.yml @@ -0,0 +1,51 @@ +parameters: + name: '' # in the form type_platform_host + displayName: '' # the human name + buildAgent: '' # the configuration for the build agent + buildPipelineType: 'both' # the type of build pipeline setup + requiredArtifacts: [] # the artifacts that this build needs to download + matrixArtifacts: [] # the artifacts that this build needs to download + sdl: [] # the SDL properties to use for this job + +jobs: + - template: /scripts/azure-templates-bootstrapper.yml@self + parameters: + name: ${{ parameters.name }} + displayName: ${{ parameters.displayName }} + sdl: ${{ parameters.sdl }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgent }} + skipInstall: true + skipSteps: true + requiredArtifacts: ${{ parameters.requiredArtifacts }} + preBuildSteps: + - pwsh: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=$(System.TeamProject) --use-git-aliases true + displayName: Configure the az CLI tool + - ${{ each artifact in parameters.matrixArtifacts }}: + - pwsh: | + $artifactJson=@' + ${{ artifact.jobs }} + '@ + + echo $artifactJson + + $json = ConvertFrom-Json $artifactJson + $objects = $json | Get-Member -MemberType NoteProperty + $names = $objects | ForEach-Object { $json."$($_.Name)".name } + + Write-Host "Found $($names.Length) items:" + $names | ForEach-Object { Write-Host " - $_" } + + $dir = "$(Build.SourcesDirectory)/output" + New-Item "$dir" -Type Directory -Force | Out-Null + + $id = "$(Build.BuildId)" + foreach ($name in $names) { + Write-Host "Downloading '$name'..." + az pipelines runs artifact download --artifact-name "$name" --path "$dir" --run-id "$id" --verbose + } + Write-Host "Downloads complete." + Get-ChildItem "$dir" + env: + AZURE_DEVOPS_EXT_PAT: $(System.AccessToken) + displayName: Download the pre-built ${{ artifact.name }} artifacts diff --git a/scripts/azure-templates-stages.yml b/scripts/azure-templates-stages.yml index 3095f48a26..ebf702e81c 100644 --- a/scripts/azure-templates-stages.yml +++ b/scripts/azure-templates-stages.yml @@ -5,21 +5,33 @@ parameters: - name: buildExternals type: string default: 'latest' - - name: VM_IMAGE_HOST + - name: buildAgentHost type: object - - name: VM_IMAGE_WINDOWS + - name: buildAgentWindows type: object - - name: VM_IMAGE_WINDOWS_NATIVE + - name: buildAgentWindowsNative type: object - - name: VM_IMAGE_MAC + - name: buildAgentMac type: object - - name: VM_IMAGE_MAC_NATIVE + - name: buildAgentMacNative type: object - - name: VM_IMAGE_LINUX + - name: buildAgentLinux type: object - - name: VM_IMAGE_LINUX_NATIVE + - name: buildAgentLinuxNative type: object - - name: runCompliance + - name: sdl + type: object + default: + apiscan: + enabled: false + binskim: + break: false + spotBugs: + enabled: false + - name: use1ESPipelineTemplates + type: boolean + default: false + - name: enableSigning type: boolean default: false @@ -29,200 +41,268 @@ stages: jobs: - job: prepare # Prepare Build displayName: Prepare Build - pool: ${{ parameters.VM_IMAGE_HOST.pool }} + pool: ${{ parameters.buildAgentHost.pool }} steps: - checkout: none - - template: azure-templates-variables.yml + - template: /scripts/azure-templates-variables.yml@self parameters: updateBuild: true - ${{ if eq(parameters.buildPipelineType, 'build') }}: - - template: azure-templates-github-status.yml + - template: /scripts/azure-templates-github-status.yml@self parameters: context: 'SkiaSharp-Tests' state: 'pending' displayName: Queue up the status for the tests pipeline - ${{ if eq(parameters.buildPipelineType, 'tests') }}: - - template: azure-templates-github-status.yml + - template: /scripts/azure-templates-github-status.yml@self - ${{ if ne(parameters.buildPipelineType, 'tests') }}: - stage: native_windows displayName: Native Windows dependsOn: prepare jobs: - - template: azure-templates-bootstrapper.yml # Build Native Android|x86 (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|x86 (Win) parameters: name: native_android_x86_windows displayName: Android x86 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-android additionalArgs: --buildarch=x86 - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Android|x64 (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|x64 (Win) parameters: name: native_android_x64_windows displayName: Android x64 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-android additionalArgs: --buildarch=x64 - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Android|arm (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|arm (Win) parameters: name: native_android_arm_windows displayName: Android arm + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-android additionalArgs: --buildarch=arm - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Android|arm64 (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|arm64 (Win) parameters: name: native_android_arm64_windows displayName: Android arm64 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-android additionalArgs: --buildarch=arm64 - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Tizen (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Tizen (Win) parameters: name: native_tizen_windows displayName: Tizen + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-tizen - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Win32|x86 (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Win32|x86 (Win) parameters: name: native_win32_x86_windows displayName: Win32 x86 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-windows additionalArgs: --buildarch=x86 - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Win32|x64 (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Win32|x64 (Win) parameters: name: native_win32_x64_windows displayName: Win32 x64 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-windows additionalArgs: --buildarch=x64 - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Win32|arm64 (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Win32|arm64 (Win) parameters: name: native_win32_arm64_windows displayName: Win32 arm64 + sdl: ${{ parameters.sdl }} + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} + target: externals-windows + additionalArgs: --buildarch=arm64 + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Win32|x86 (Win + MSVC) + parameters: + name: native_win32_x86_msvc_windows + displayName: Win32 x86 [MSVC] + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-windows + additionalArgs: --buildarch=x86 --llvm="msvc" + installLlvm: false + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Win32|x64 (Win + MSVC) + parameters: + name: native_win32_x64_msvc_windows + displayName: Win32 x64 [MSVC] + sdl: ${{ parameters.sdl }} + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} + target: externals-windows + additionalArgs: --buildarch=x64 --llvm="msvc" + installLlvm: false + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Win32|arm64 (Win + MSVC) + parameters: + name: native_win32_arm64_msvc_windows + displayName: Win32 arm64 [MSVC] + sdl: ${{ parameters.sdl }} + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} + target: externals-windows + additionalArgs: --buildarch=arm64 --llvm="msvc" + installLlvm: false + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native WinUI|x86 (Win) + parameters: + name: native_winui_x86_windows + displayName: WinUI x86 + sdl: ${{ parameters.sdl }} + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} + target: externals-winui + additionalArgs: --buildarch=x86 + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native WinUI|x64 (Win) + parameters: + name: native_winui_x64_windows + displayName: WinUI x64 + sdl: ${{ parameters.sdl }} + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} + target: externals-winui + additionalArgs: --buildarch=x64 + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native WinUI|arm64 (Win) + parameters: + name: native_winui_arm64_windows + displayName: WinUI arm64 + sdl: ${{ parameters.sdl }} + buildExternals: ${{ parameters.buildExternals }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} + target: externals-winui additionalArgs: --buildarch=arm64 - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native NanoServer|x64 (Win) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native NanoServer|x64 (Win) parameters: name: native_win32_x64_nanoserver_windows displayName: Nano Server x64 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS_NATIVE }} + buildAgent: ${{ parameters.buildAgentWindowsNative }} target: externals-nanoserver additionalArgs: --buildarch=x64 - artifactName: native - ${{ if ne(parameters.buildPipelineType, 'tests') }}: - stage: native_macos displayName: Native macOS dependsOn: prepare jobs: - - template: azure-templates-bootstrapper.yml # Build Native Android|x86 (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|x86 (macOS) parameters: name: native_android_x86_macos displayName: Android x86 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-android additionalArgs: --buildarch=x86 - - template: azure-templates-bootstrapper.yml # Build Native Android|x64 (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|x64 (macOS) parameters: name: native_android_x64_macos displayName: Android x64 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-android additionalArgs: --buildarch=x64 - - template: azure-templates-bootstrapper.yml # Build Native Android|arm (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|arm (macOS) parameters: name: native_android_arm_macos displayName: Android arm + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-android additionalArgs: --buildarch=arm - - template: azure-templates-bootstrapper.yml # Build Native Android|arm64 (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Android|arm64 (macOS) parameters: name: native_android_arm64_macos displayName: Android arm64 + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-android additionalArgs: --buildarch=arm64 - - template: azure-templates-bootstrapper.yml # Build Native iOS (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native iOS (macOS) parameters: name: native_ios_macos displayName: iOS + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-ios - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Mac Catalyst (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Mac Catalyst (macOS) parameters: name: native_maccatalyst_macos displayName: Mac Catalyst + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-maccatalyst - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native macOS (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native macOS (macOS) parameters: name: native_macos_macos displayName: macOS + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-macos - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native tvOS (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native tvOS (macOS) parameters: name: native_tvos_macos displayName: tvOS + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-tvos - artifactName: native - - template: azure-templates-bootstrapper.yml # Build Native Tizen (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Tizen (macOS) parameters: name: native_tizen_macos displayName: Tizen + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC_NATIVE }} + buildAgent: ${{ parameters.buildAgentMacNative }} target: externals-tizen - ${{ if ne(parameters.buildPipelineType, 'tests') }}: @@ -230,12 +310,13 @@ stages: displayName: Native Linux dependsOn: prepare jobs: - - template: azure-templates-linux-matrix.yml # Build Native Linux (Linux) + - template: /scripts/azure-templates-linux-matrix.yml@self # Build Native Linux (Linux) parameters: - artifactName: native + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_LINUX_NATIVE }} + buildAgent: ${{ parameters.buildAgentLinuxNative }} + use1ESPipelineTemplates: ${{ parameters.use1ESPipelineTemplates }} builds: - name: '' - name: nodeps @@ -255,13 +336,13 @@ stages: docker: scripts/Docker/debian9/clang-cross dockerArgs: --build-arg TOOLCHAIN_ARCH=aarch64-linux-gnu --build-arg TOOLCHAIN_ARCH_SHORT=arm64 target: externals-linux-clang-cross - - template: azure-templates-bootstrapper.yml # Build Native Tizen (Linux) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Native Tizen (Linux) parameters: name: native_tizen_linux displayName: Tizen buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_LINUX_NATIVE }} + buildAgent: ${{ parameters.buildAgentLinuxNative }} packages: $(TIZEN_LINUX_PACKAGES) target: externals-tizen @@ -270,12 +351,13 @@ stages: displayName: Native WASM dependsOn: prepare jobs: - - template: azure-templates-wasm-matrix.yml # Build Native WASM (Linux) + - template: /scripts/azure-templates-wasm-matrix.yml@self # Build Native WASM (Linux) parameters: + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_LINUX_NATIVE }} - artifactName: native + buildAgent: ${{ parameters.buildAgentLinuxNative }} + use1ESPipelineTemplates: ${{ parameters.use1ESPipelineTemplates }} emscripten: - 2.0.6: displayName: 2.0.6 @@ -329,54 +411,131 @@ stages: features: _wasmeh,simd,mt - ${{ if ne(parameters.buildPipelineType, 'tests') }}: - - stage: managed - displayName: Build Managed + - stage: native + displayName: Native + variables: + nativeLinuxJobs: $[ convertToJson(stageDependencies.native_linux) ] + nativeWasmJobs: $[ convertToJson(stageDependencies.native_wasm) ] dependsOn: - native_windows - native_macos - native_linux - native_wasm jobs: - - template: azure-templates-bootstrapper.yml # Build Managed (Windows) + - template: /scripts/azure-templates-merger.yml@self # Merge Native Artifacts + parameters: + name: native + displayName: Merge Native Artifacts + sdl: ${{ parameters.sdl }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentHost }} + requiredArtifacts: + # Android + - name: native_android_x86_windows + - name: native_android_x64_windows + - name: native_android_arm_windows + - name: native_android_arm64_windows + # Tizen + - name: native_tizen_windows + # Win32 + - name: native_win32_x86_windows + - name: native_win32_x64_windows + - name: native_win32_arm64_windows + # WinUI + - name: native_winui_x86_windows + - name: native_winui_x64_windows + - name: native_winui_arm64_windows + # Nano Server + - name: native_win32_x64_nanoserver_windows + # iOS + - name: native_ios_macos + # Mac Catalyst + - name: native_maccatalyst_macos + # macOS + - name: native_macos_macos + # tvOS + - name: native_tvos_macos + matrixArtifacts: + - name: native_linux + jobs: $(nativeLinuxJobs) + - name: native_wasm + jobs: $(nativeWasmJobs) + - template: /scripts/azure-templates-merger.yml@self # Merge Native WASM Artifacts + parameters: + name: native_wasm + displayName: Merge Native WASM Artifacts + sdl: ${{ parameters.sdl }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentHost }} + matrixArtifacts: + - name: native_wasm + jobs: $(nativeWasmJobs) + - template: /scripts/azure-templates-merger.yml@self # Merge Native MSVC Artifacts + parameters: + name: native_msvc + displayName: Merge Native MSVC Artifacts + sdl: ${{ parameters.sdl }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentHost }} + requiredArtifacts: + - name: native_win32_x86_msvc_windows + - name: native_win32_x64_msvc_windows + - name: native_win32_arm64_msvc_windows + + - ${{ if ne(parameters.buildPipelineType, 'build') }}: + - stage: managed + displayName: Build Managed + ${{ if eq(parameters.buildPipelineType, 'tests') }}: + dependsOn: prepare + ${{ if eq(parameters.buildPipelineType, 'both') }}: + dependsOn: native + jobs: + - template: /scripts/azure-templates-bootstrapper.yml@self # Validate Interop + parameters: + name: managed_interop_windows + displayName: Validate Interop + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindows}} + target: externals-interop + additionalArgs: --skipExternals="all" + installAndroidSdk: false + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Managed (Windows) parameters: name: managed_windows displayName: Managed (Windows) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS}} + buildAgent: ${{ parameters.buildAgentWindows}} target: libs additionalArgs: --skipExternals="all" requiredArtifacts: - name: native - artifactName: managed postBuildSteps: - pwsh: Remove-Item ./output/native/ -Recurse -Force -ErrorAction Continue displayName: Delete the native folder - - template: azure-templates-bootstrapper.yml # Build Managed (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Managed (macOS) parameters: name: managed_macos displayName: Managed (macOS) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC }} + buildAgent: ${{ parameters.buildAgentMac }} target: libs additionalArgs: --skipExternals="all" requiredArtifacts: - name: native - artifactName: managed postBuildSteps: - pwsh: Remove-Item ./output/native/ -Recurse -Force -ErrorAction Continue displayName: Delete the native folder - - template: azure-templates-bootstrapper.yml # Build Managed (Linux) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Managed (Linux) parameters: name: managed_linux displayName: Managed (Linux) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_LINUX }} + buildAgent: ${{ parameters.buildAgentLinux }} packages: $(MANAGED_LINUX_PACKAGES) target: libs additionalArgs: --skipExternals="all" requiredArtifacts: - name: native - artifactName: managed postBuildSteps: - pwsh: Remove-Item ./output/native/ -Recurse -Force -ErrorAction Continue displayName: Delete the native folder @@ -384,49 +543,86 @@ stages: - ${{ if ne(parameters.buildPipelineType, 'tests') }}: - stage: package displayName: Package NuGets - dependsOn: - - native_windows - - native_macos - - native_linux - - native_wasm + dependsOn: native jobs: - - template: azure-templates-bootstrapper.yml # Package NuGets + - template: /scripts/azure-templates-bootstrapper.yml@self # Package NuGets parameters: - name: package_windows + name: package_normal_windows displayName: Package NuGets + sdl: ${{ parameters.sdl }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS}} - target: nuget + buildAgent: ${{ parameters.buildAgentWindows}} + target: nuget-normal additionalArgs: --skipExternals="all" + shouldPublish: false requiredArtifacts: - name: native postBuildSteps: - - task: PublishBuildArtifacts@1 - displayName: Publish the nuget artifacts - inputs: - artifactName: nuget - pathToPublish: 'output/nugets' - - task: PublishBuildArtifacts@1 - displayName: Publish the special nuget artifacts - inputs: - artifactName: nuget_special - pathToPublish: 'output/nugets-special' - - task: PublishBuildArtifacts@1 - displayName: Publish the special nuget artifacts - inputs: - artifactName: nuget_symbols - pathToPublish: 'output/nugets-symbols' - - task: PublishBuildArtifacts@1 - displayName: Publish the SignList.xml into nuget artifacts - inputs: - artifactName: nuget - pathToPublish: 'scripts\SignList.xml' - pwsh: | - Remove-Item ./output/native/ -Recurse -Force - Remove-Item ./output/nugets/ -Recurse -Force - Remove-Item ./output/nugets-special/ -Recurse -Force - Remove-Item ./output/nugets-symbols/ -Recurse -Force - displayName: Delete the pre-published folders + Remove-Item ./output/native/ -Recurse -Force -ErrorAction Continue + Move-Item -Path '.\output\' -Destination '$(Build.ArtifactStagingDirectory)\output\' + New-Item '.\output\' -Type Directory -Force | Out-Null + displayName: Re-organize the output folder for publishing + - pwsh: | + Move-Item -Path '$(Build.ArtifactStagingDirectory)\output\nugets\' -Destination '.\output\' + Copy-Item -Path '.\scripts\SignList.xml' -Destination '.\output\nugets\' + displayName: Prepare the nugets artifact for publishing + - pwsh: | + Move-Item -Path '$(Build.ArtifactStagingDirectory)\output\nugets-symbols\' -Destination '.\output\' + displayName: Prepare the nugets-symbols artifact for publishing + - pwsh: | + Move-Item -Path '$(Build.ArtifactStagingDirectory)\output\' -Destination '.\output\' + displayName: Prepare the build artifact for publishing + - pwsh: | + $nupkgs = (Get-ChildItem ".\output\nugets*\*.*nupkg") + foreach ($nupkg in $nupkgs) { + $filename = $nupkg.Name.TrimEnd('.nupkg') + $dest = ".\output\extracted_nugets\$filename" + Write-Host "Extracting '$nupkg' to '$dest'..." + Expand-Archive $nupkg $dest + } + displayName: Extract all the .nupkg files for scanning + publishArtifacts: + - name: package_normal_windows + path: '.\output\output\' + - name: nuget + path: '.\output\nugets' + - name: nuget_symbols + path: '.\output\nugets-symbols' + - template: /scripts/azure-templates-bootstrapper.yml@self # Package Special NuGets + parameters: + name: package_special_windows + displayName: Package Special NuGets + sdl: ${{ parameters.sdl }} + buildPipelineType: ${{ parameters.buildPipelineType }} + buildAgent: ${{ parameters.buildAgentWindows}} + dependsOn: package_normal_windows + target: nuget-special + additionalArgs: --skipExternals="all" --exclusive + shouldPublish: false + requiredArtifacts: + - name: nuget + dir: nugets + - name: nuget_symbols + dir: nugets-symbols + postBuildSteps: + - pwsh: | + Remove-Item ./output/nugets/ -Recurse -Force -ErrorAction Continue + Remove-Item ./output/nugets-symbols/ -Recurse -Force -ErrorAction Continue + Move-Item -Path '.\output\' -Destination '$(Build.ArtifactStagingDirectory)\output\' + New-Item '.\output\' -Type Directory -Force | Out-Null + displayName: Re-organize the output folder for publishing + - pwsh: | + Move-Item -Path '$(Build.ArtifactStagingDirectory)\output\nugets-special\' -Destination '.\output\' + displayName: Prepare the nugets-special artifact for publishing + - pwsh: | + Move-Item -Path '$(Build.ArtifactStagingDirectory)\output\' -Destination '.\output\' + displayName: Prepare the build artifact for publishing + publishArtifacts: + - name: package_special_windows + path: '.\output\output\' + - name: nuget_special + path: '.\output\nugets-special' - ${{ if ne(parameters.buildPipelineType, 'build') }}: - stage: api_diff @@ -436,37 +632,30 @@ stages: ${{ if eq(parameters.buildPipelineType, 'both') }}: dependsOn: package jobs: - - template: azure-templates-bootstrapper.yml # API Diff + - template: /scripts/azure-templates-bootstrapper.yml@self # API Diff parameters: name: api_diff_windows displayName: API Diff buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS}} + buildAgent: ${{ parameters.buildAgentWindows}} target: docs-api-diff additionalArgs: --nugetDiffPrerelease=$(NUGET_DIFF_PRERELEASE) shouldPublish: false requiredArtifacts: - - name: package_windows - name: nuget dir: nugets preBuildSteps: - pwsh: .\scripts\install-gtk.ps1 displayName: Install GTK# 2.12 - postBuildSteps: - - task: PublishBuildArtifacts@1 - displayName: Publish the API diffs - condition: always() - inputs: - artifactName: api-diff - pathToPublish: '$(Build.SourcesDirectory)\output\api-diff' - - task: PublishBuildArtifacts@1 - displayName: Publish the changelogs - condition: always() - inputs: - artifactName: changelogs - pathToPublish: '$(Build.SourcesDirectory)\changelogs' + publishArtifacts: + - name: api-diff + always: true + path: '$(Build.SourcesDirectory)\output\api-diff' + - name: changelogs + always: true + path: '$(Build.SourcesDirectory)\changelogs' - - ${{ if and(eq(variables['System.TeamProject'], 'devdiv'), ne(parameters.buildPipelineType, 'tests'), ne(variables['System.PullRequest.IsFork'], 'true')) }}: + - ${{ if eq(parameters.enableSigning, 'true') }}: - stage: signing displayName: Sign NuGets dependsOn: package @@ -477,17 +666,8 @@ stages: signType: 'Real' ${{ if not(or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))) }}: signType: 'Test' - - - ${{ if and(eq(variables['System.TeamProject'], 'devdiv'), ne(parameters.buildPipelineType, 'tests'), ne(variables['System.PullRequest.IsFork'], 'true')) }}: - - stage: sbom - displayName: 'Software Bill of Materials' - dependsOn: signing - jobs: - - template: compliance/sbom/job.v1.yml@xamarin-templates # Software Bill of Materials (SBOM): https://eng.ms/docs/cloud-ai-platform/devdiv/one-engineering-system-1es/1es-docs/secure-supply-chain/ado-sbom-generator - parameters: - artifactNames: ['nuget'] - packageName: 'SkiaSharp' - packageFilter: '*.nupkg' + use1ESTemplate: ${{ parameters.use1ESPipelineTemplates }} + usePipelineArtifactTasks: true - ${{ if ne(parameters.buildPipelineType, 'build') }}: - stage: tests @@ -495,18 +675,14 @@ stages: ${{ if eq(parameters.buildPipelineType, 'tests') }}: dependsOn: prepare ${{ if eq(parameters.buildPipelineType, 'both') }}: - dependsOn: - - native_windows - - native_macos - - native_linux - - native_wasm + dependsOn: native jobs: - - template: azure-templates-bootstrapper.yml # Tests|netfx (Windows) + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests|netfx (Windows) parameters: name: tests_netfx_windows displayName: Windows (.NET Framework) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS}} + buildAgent: ${{ parameters.buildAgentWindows}} target: tests-netfx additionalArgs: --skipExternals="all" --coverage=$(ENABLE_CODE_COVERAGE) shouldPublish: false @@ -522,18 +698,16 @@ stages: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/TestResults.xml' testRunTitle: 'Windows .NET Framework Tests' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_netfx_windows - pathToPublish: 'output/logs/testlogs' - - template: azure-templates-bootstrapper.yml # Tests|netcore (Windows) + publishArtifacts: + - name: testlogs_netfx_windows + always: true + path: 'output/logs/testlogs' + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests|netcore (Windows) parameters: name: tests_netcore_windows displayName: Windows (.NET Core) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS}} + buildAgent: ${{ parameters.buildAgentWindows}} target: tests-netcore additionalArgs: --skipExternals="all" --coverage=$(ENABLE_CODE_COVERAGE) shouldPublish: false @@ -549,23 +723,18 @@ stages: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/TestResults.xml' testRunTitle: 'Windows .NET Core Tests' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_netcore_windows - pathToPublish: 'output/logs/testlogs' - - task: PublishBuildArtifacts@1 - displayName: 'Publish the code coverage results' - inputs: - artifactName: coverage_netcore_windows - pathToPublish: 'output/coverage' - - template: azure-templates-bootstrapper.yml # Tests|netcore (macOS) + publishArtifacts: + - name: testlogs_netcore_windows + always: true + path: 'output/logs/testlogs' + - name: coverage_netcore_windows + path: 'output/coverage' + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests|netcore (macOS) parameters: name: tests_netcore_macos displayName: macOS (.NET Core) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC }} + buildAgent: ${{ parameters.buildAgentMac }} target: tests-netcore additionalArgs: --skipExternals="all" --coverage=$(ENABLE_CODE_COVERAGE) shouldPublish: false @@ -579,23 +748,18 @@ stages: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/TestResults.xml' testRunTitle: 'macOS .NET Core Tests' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_netcore_macos - pathToPublish: 'output/logs/testlogs' - - task: PublishBuildArtifacts@1 - displayName: 'Publish the code coverage results' - inputs: - artifactName: coverage_netcore_macos - pathToPublish: 'output/coverage' - - template: azure-templates-bootstrapper.yml # Tests|netcore (Linux) + publishArtifacts: + - name: testlogs_netcore_macos + always: true + path: 'output/logs/testlogs' + - name: coverage_netcore_macos + path: 'output/coverage' + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests|netcore (Linux) parameters: name: tests_netcore_linux displayName: Linux (.NET Core) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_LINUX }} + buildAgent: ${{ parameters.buildAgentLinux }} packages: $(MANAGED_LINUX_PACKAGES) target: tests-netcore additionalArgs: --skipExternals="all" --coverage=$(ENABLE_CODE_COVERAGE) @@ -611,23 +775,18 @@ stages: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/TestResults.xml' testRunTitle: 'Linux .NET Core Tests' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_netcore_linux - pathToPublish: 'output/logs/testlogs' - - task: PublishBuildArtifacts@1 - displayName: 'Publish the code coverage results' - inputs: - artifactName: coverage_netcore_linux - pathToPublish: 'output/coverage' - - template: azure-templates-bootstrapper.yml # Tests|android (macOS) + publishArtifacts: + - name: testlogs_netcore_linux + always: true + path: 'output/logs/testlogs' + - name: coverage_netcore_linux + path: 'output/coverage' + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests|android (macOS) parameters: name: tests_android_macos displayName: Android (macOS) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC }} + buildAgent: ${{ parameters.buildAgentMac }} target: tests-android additionalArgs: --device=android-emulator-64 --deviceVersion=$(ANDROID_TEST_DEVICE_VERSION) --skipExternals="all" --coverage=$(ENABLE_CODE_COVERAGE) shouldPublish: false @@ -649,25 +808,23 @@ stages: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/TestResults.xml' testRunTitle: 'Android Tests (API $(ANDROID_TEST_DEVICE_VERSION))' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_android_$(ANDROID_TEST_DEVICE_VERSION) - pathToPublish: 'output/logs/testlogs' - - template: azure-templates-bootstrapper.yml # Tests|ios (macOS) + publishArtifacts: + - name: testlogs_android_$(ANDROID_TEST_DEVICE_VERSION) + always: true + path: 'output/logs/testlogs' + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests|ios (macOS) parameters: name: tests_ios_macos displayName: iOS (macOS) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC }} + buildAgent: ${{ parameters.buildAgentMac }} target: tests-ios additionalArgs: --device=ios-simulator-64 --deviceVersion=$(IOS_TEST_DEVICE_VERSION) --skipExternals="all" --coverage=$(ENABLE_CODE_COVERAGE) shouldPublish: false requiredArtifacts: - name: native_ios_macos preBuildSteps: - - template: azure-templates-provisioning-profiles.yml + - template: /scripts/azure-templates-provisioning-profiles.yml@self postBuildSteps: - task: PublishTestResults@2 displayName: Publish the iOS test results @@ -676,51 +833,47 @@ stages: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/TestResults.xml' testRunTitle: 'iOS Tests (v$(IOS_TEST_DEVICE_VERSION))' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_ios_$(IOS_TEST_DEVICE_VERSION) - pathToPublish: 'output/logs/testlogs' - - template: azure-templates-bootstrapper.yml # Tests|maccatalyst (macOS) + publishArtifacts: + - name: testlogs_ios_$(IOS_TEST_DEVICE_VERSION) + always: true + path: 'output/logs/testlogs' + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests|maccatalyst (macOS) parameters: name: tests_maccatalyst_macos displayName: Mac Catalyst (macOS) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC }} + buildAgent: ${{ parameters.buildAgentMac }} target: tests-maccatalyst additionalArgs: --device=maccatalyst --skipExternals="all" --coverage=$(ENABLE_CODE_COVERAGE) shouldPublish: false requiredArtifacts: - name: native_maccatalyst_macos preBuildSteps: - - template: azure-templates-provisioning-profiles.yml + - template: /scripts/azure-templates-provisioning-profiles.yml@self postBuildSteps: - task: PublishTestResults@2 - displayName: Publish the iOMac CatalystS test results + displayName: Publish the Mac Catalyst test results condition: always() inputs: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/TestResults.xml' testRunTitle: 'Mac Catalyst Tests' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_maccatalyst - pathToPublish: 'output/logs/testlogs' - - template: azure-templates-bootstrapper.yml # Tests [WASM] (Linux) + publishArtifacts: + - name: testlogs_maccatalyst + always: true + path: 'output/logs/testlogs' + - template: /scripts/azure-templates-bootstrapper.yml@self # Tests [WASM] (Linux) parameters: name: tests_wasm_linux displayName: WASM (Linux) buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_LINUX }} + buildAgent: ${{ parameters.buildAgentLinux }} packages: $(MANAGED_LINUX_PACKAGES) ninja-build target: tests-wasm additionalArgs: --skipExternals="all" --coverage=false --chromedriver=$(CHROMEWEBDRIVER) shouldPublish: false requiredArtifacts: - - name: native_wasm_linux + - name: native_wasm installEmsdk: true initScript: source ~/emsdk/emsdk_env.sh postBuildSteps: @@ -731,27 +884,25 @@ stages: testResultsFormat: xUnit testResultsFiles: 'output/logs/testlogs/**/*.xml' testRunTitle: 'Linux WASM Tests' - - task: PublishBuildArtifacts@1 - displayName: Publish the test logs - condition: always() - inputs: - artifactName: testlogs_wasm - pathToPublish: 'output/logs/testlogs' + publishArtifacts: + - name: testlogs_wasm + always: true + path: 'output/logs/testlogs' # TODO: add tests for linux alpine # TODO: add tests for linux no dependencies # TODO: add tests for windows nano server - job: coverage_reports # Coverage Reports displayName: Coverage Reports - pool: ${{ parameters.VM_IMAGE_HOST.pool }} + pool: ${{ parameters.buildAgentHost.pool }} dependsOn: - tests_netcore_windows - tests_netcore_macos - tests_netcore_linux steps: - checkout: self - - template: azure-templates-variables.yml + - template: /scripts/azure-templates-variables.yml@self - ${{ if ne(parameters.buildPipelineType, 'both') }}: - - template: azure-templates-github-status.yml + - template: /scripts/azure-templates-github-status.yml@self parameters: state: 'pending' - task: DownloadBuildArtifacts@1 @@ -775,7 +926,7 @@ stages: codeCoverageTool: Cobertura summaryFileLocation: 'output/**/Cobertura.xml' - ${{ if ne(parameters.buildPipelineType, 'both') }}: - - template: azure-templates-github-status.yml + - template: /scripts/azure-templates-github-status.yml@self - ${{ if ne(parameters.buildPipelineType, 'build') }}: - stage: samples @@ -785,12 +936,12 @@ stages: ${{ if eq(parameters.buildPipelineType, 'both') }}: dependsOn: package jobs: - - template: azure-templates-bootstrapper.yml # Build Samples (Windows) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Samples (Windows) parameters: name: samples_windows displayName: Windows buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_WINDOWS}} + buildAgent: ${{ parameters.buildAgentWindows}} target: samples requiredArtifacts: - name: nuget @@ -798,12 +949,12 @@ stages: postBuildSteps: - pwsh: Remove-Item ./output/nugets/ -Recurse -Force -ErrorAction Continue displayName: Delete the nugets folder - - template: azure-templates-bootstrapper.yml # Build Samples (macOS) + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Samples (macOS) parameters: name: samples_macos displayName: macOS buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_MAC }} + buildAgent: ${{ parameters.buildAgentMac }} target: samples installNinja: true shouldPublish: false @@ -811,13 +962,13 @@ stages: - name: nuget dir: nugets preBuildSteps: - - template: azure-templates-provisioning-profiles.yml - - template: azure-templates-bootstrapper.yml # Build Samples (Linux) + - template: /scripts/azure-templates-provisioning-profiles.yml@self + - template: /scripts/azure-templates-bootstrapper.yml@self # Build Samples (Linux) parameters: name: samples_linux displayName: Linux buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.VM_IMAGE_LINUX }} + buildAgent: ${{ parameters.buildAgentLinux }} packages: $(MANAGED_LINUX_PACKAGES) target: samples shouldPublish: false @@ -827,49 +978,61 @@ stages: installEmsdk: true initScript: source ~/emsdk/emsdk_env.sh - - ${{ if and(eq(variables['System.TeamProject'], 'devdiv'), ne(parameters.buildPipelineType, 'tests'), ne(variables['System.PullRequest.IsFork'], 'true'), or(and(eq(variables['Build.Reason'], 'Schedule'), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'))), parameters.runCompliance)) }}: - - template: security/full/v1.yml@xamarin-templates + - ${{ if eq(parameters.sdl.apiscan.enabled, 'true') }}: + - template: security/apiscan/v0.yml@xamarin-templates parameters: + windowsPoolName: ${{ parameters.buildAgentHost.pool.name }} + windowsImageOverride: ${{ parameters.buildAgentHost.pool.image }} + timeoutInMinutes: 480 stageDependsOn: - - managed - - native_windows - - native_macos - - native_linux - - native_wasm - complianceEnabled: true - complianceTimeoutInMinutes: 480 + - package scanArtifacts: - - managed - - native - antiMalwareEnabled: true - binSkimEnabled: true - policheckExclusionFile: $(Build.SourcesDirectory)\scripts\guardian\PoliCheckExclusions.xml - policheckGdnSuppressionFilesFolder: $(Build.SourcesDirectory)\scripts\guardian - credScanEnabled: true - credScanSuppressionFile: $(Build.SourcesDirectory)\scripts\guardian\CredScanSuppressions.json - sourceGdnSuppressionFile: $(Build.SourcesDirectory)\scripts\guardian\source.gdnsuppress - tsaConfigFile: $(Build.SourcesDirectory)\scripts\guardian\tsaoptions-v2.json - tsaReportBranch: $(Build.SourceBranch) - enableCodeInspector: true - apiScanEnabled: true + - nuget + - nuget_symbols + - native_msvc apiScanSoftwareName: 'SkiaSharp' - apiScanSoftwareVersionNum: $(Build.BuildNumber) + apiScanSoftwareVersionNum: $(SKIASHARP_MAJOR_VERSION) + apiScanPreserveLogsFolder: true + apiScanAuthConnectionString: 'runAs=App;AppId=$(ApiScanClientId)' + apiScanSurrogateConfigurationFolder: $(Build.ArtifactStagingDirectory)\APIScanSurrogates + preScanSteps: + - pwsh: | + $softwareFolder = "$(Build.ArtifactStagingDirectory)\binaries-to-scan" + $surrogateFile = "$(Build.SourcesDirectory)\scripts\guardian\APIScanSurrogates.in.xml" + $destFolder = "$(Build.ArtifactStagingDirectory)\APIScanSurrogates" + $destFile = "$destFolder\APIScanSurrogates.xml" + New-Item -ItemType Directory -Force -Path $destFolder | Out-Null + $surrogateContents = (Get-Content $surrogateFile) + $surrogateContents = $surrogateContents.Replace("{SOFTWARE_FOLDER}", $softwareFolder) + $surrogateContents | Set-Content $destFile + displayName: Generate the surrogate files + - pwsh: | + $nupkgs = (Get-ChildItem "$(Build.ArtifactStagingDirectory)\binaries-to-scan\*\*.*nupkg") + foreach ($nupkg in $nupkgs) { + $filename = $nupkg.Name.TrimEnd('.nupkg') + $dest = "$(Build.ArtifactStagingDirectory)\binaries-to-scan\nuget_symbols-extracted\$filename" + Write-Host "Extracting '$nupkg' to '$dest'..." + Expand-Archive $nupkg $dest + Remove-Item $nupkg + } + displayName: Extract all the .nupkg files - ${{ if eq(parameters.buildPipelineType, 'tests') }}: - stage: finalize displayName: Finalize Build dependsOn: - api_diff + - managed - samples - tests jobs: - job: finalize # Finalize Build displayName: Finalize Build - pool: ${{ parameters.VM_IMAGE_HOST.pool }} + pool: ${{ parameters.buildAgentHost.pool }} steps: - checkout: none - - template: azure-templates-variables.yml - - template: azure-templates-github-status.yml + - template: /scripts/azure-templates-variables.yml@self + - template: /scripts/azure-templates-github-status.yml@self parameters: context: 'SkiaSharp-Tests' displayName: Update the final status for the tests pipeline diff --git a/scripts/azure-templates-wasm-matrix.yml b/scripts/azure-templates-wasm-matrix.yml index 52730c71e4..9a383a54b5 100644 --- a/scripts/azure-templates-wasm-matrix.yml +++ b/scripts/azure-templates-wasm-matrix.yml @@ -1,27 +1,23 @@ parameters: - artifactName: '' # the name of the artifact to merge this run into buildExternals: '' # the build number to download externals from - buildPipelineType: false - vmImage: '' # the VM image + buildPipelineType: 'both' # the type of build pipeline setup + buildAgent: '' # the configuration for the build agent + use1ESPipelineTemplates: false # whether or not we are building using the internal 1ES Pipeline Templates + sdl: [] # the SDL properties to use for this job emscripten: [ ] jobs: - ${{ each version in parameters.emscripten }}: - - template: azure-templates-bootstrapper.yml + - template: /scripts/azure-templates-bootstrapper.yml@self parameters: name: native_wasm_${{ replace(version.displayName, '.', '_') }}_linux displayName: WASM (${{ version.displayName }}) + sdl: ${{ parameters.sdl }} buildExternals: ${{ parameters.buildExternals }} buildPipelineType: ${{ parameters.buildPipelineType }} - vmImage: ${{ parameters.vmImage }} + buildAgent: ${{ parameters.buildAgent }} + use1ESPipelineTemplates: ${{ parameters.use1ESPipelineTemplates }} docker: scripts/Docker/wasm target: externals-wasm dockerArgs: --build-arg EMSCRIPTEN_VERSION=${{ version.version }} - additionalArgs: --emscriptenVersion=${{ version.version }} --emscriptenFeatures="${{ version.features }}" - artifactName: ${{ parameters.artifactName }} - postBuildSteps: - - task: PublishBuildArtifacts@1 - displayName: Publish the native_wasm_linux artifacts - inputs: - artifactName: native_wasm_linux - pathToPublish: 'output' \ No newline at end of file + additionalArgs: --emscriptenVersion=${{ version.version }} --emscriptenFeatures="${{ version.features }}" \ No newline at end of file diff --git a/scripts/cake/externals.cake b/scripts/cake/externals.cake index d5b4df53ed..0ee5c74526 100644 --- a/scripts/cake/externals.cake +++ b/scripts/cake/externals.cake @@ -40,6 +40,33 @@ Task("externals-download") await DownloadPackageAsync("_nativeassets", "./output/native"); }); +//////////////////////////////////////////////////////////////////////////////////////////////////// +// EXTERNALS INTEROP - re-generate the interop files +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Task("externals-interop") + .IsDependentOn("git-sync-deps") + .Does(() => +{ + RunProcess("pwsh", "./utils/generate.ps1"); + + RunProcess("git", "diff --name-only binding/*/*.generated.cs", out var files); + + if (files.Any()) { + Information("Generated files have changed:"); + foreach (var file in files) { + Information($" - {file}"); + } + + if (Argument("validateInterop", false)) { + throw new Exception("Generated interop files are out of date. Please run `pwsh ./utils/generate.ps1`."); + } else { + Warning("Generated interop files are out of date. Please run `pwsh ./utils/generate.ps1`."); + Warning("##vso[task.logissue type=warning]Generated interop files are out of date. Please run `pwsh ./utils/generate.ps1`."); + } + } +}); + //////////////////////////////////////////////////////////////////////////////////////////////////// // CLEAN - remove all the build artefacts //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/scripts/cake/native-shared.cake b/scripts/cake/native-shared.cake index 17ea4f05e6..8c3703e3e5 100644 --- a/scripts/cake/native-shared.cake +++ b/scripts/cake/native-shared.cake @@ -38,23 +38,43 @@ Task("git-sync-deps") if (actualIncrement != expectedIncrement) throw new Exception($"The libSkiaSharp C API version did not match the expected '{expectedIncrement}', instead was '{actualIncrement}'."); - RunProcess(PYTHON_EXE, new ProcessSettings { - Arguments = SKIA_PATH.CombineWithFilePath("tools/git-sync-deps").FullPath, - WorkingDirectory = SKIA_PATH.FullPath, - }); + RunPython(SKIA_PATH, SKIA_PATH.CombineWithFilePath("tools/git-sync-deps")); }); //////////////////////////////////////////////////////////////////////////////////////////////////// // HELPERS //////////////////////////////////////////////////////////////////////////////////////////////////// -void GnNinja(DirectoryPath outDir, string target, string skiaArgs) +void RunPython(DirectoryPath working, FilePath script, string args = "") +{ + RunProcess(PYTHON_EXE, new ProcessSettings { + Arguments = $"{script.FullPath} {args}", + WorkingDirectory = working.FullPath, + }); +} + +void RunGn(DirectoryPath working, DirectoryPath outDir, string args = "") { var isCore = Context.Environment.Runtime.IsCoreClr; var quote = IsRunningOnWindows() || isCore ? "\"" : "'"; var innerQuote = IsRunningOnWindows() || isCore ? "\\\"" : "\""; + RunProcess(GN_EXE, new ProcessSettings { + Arguments = $"gen {outDir} --script-executable={quote}{PYTHON_EXE}{quote} --args={quote}{args.Replace("'", innerQuote)}{quote}", + WorkingDirectory = working.FullPath, + }); +} + +void RunNinja(DirectoryPath working, DirectoryPath outDir, string target = "") +{ + var script = DEPOT_PATH.CombineWithFilePath("ninja.py"); + + RunPython(working, script, $"-C {outDir} {target}"); +} + +void GnNinja(DirectoryPath outDir, string target, string skiaArgs) +{ // override win_vc with the command line args if (!string.IsNullOrEmpty(VS_INSTALL)) { DirectoryPath win_vc = VS_INSTALL; @@ -67,16 +87,10 @@ void GnNinja(DirectoryPath outDir, string target, string skiaArgs) $" is_official_build={CONFIGURATION.ToLower() == "release"} ".ToLower(); // generate native skia build files - RunProcess(GN_EXE, new ProcessSettings { - Arguments = $"gen out/{outDir} --script-executable={quote}{PYTHON_EXE}{quote} --args={quote}{skiaArgs.Replace("'", innerQuote)}{quote}", - WorkingDirectory = SKIA_PATH.FullPath, - }); + RunGn(SKIA_PATH, $"out/{outDir}", skiaArgs); // build native skia - RunProcess(PYTHON_EXE, new ProcessSettings { - Arguments = DEPOT_PATH.CombineWithFilePath("ninja.py").FullPath + $" -C out/{outDir} {target}", - WorkingDirectory = SKIA_PATH.FullPath, - }); + RunNinja(SKIA_PATH, $"out/{outDir}", target); } bool Skip(string arch) diff --git a/scripts/get-build-type.ps1 b/scripts/get-build-type.ps1 index 0274f9008b..ba6ccdbb36 100644 --- a/scripts/get-build-type.ps1 +++ b/scripts/get-build-type.ps1 @@ -23,26 +23,30 @@ if ($intBuildId -gt 0) { if (("$ExternalsBuildId" -eq 'latest') -and ("$env:BUILD_REASON" -eq 'PullRequest')) { Write-Host "All changes:" $all = (git diff-tree --no-commit-id --name-only -r HEAD~ HEAD) - foreach ($d in $all) { - Write-Host " - $d" - } + if ($?) { + foreach ($d in $all) { + Write-Host " - $d" + } - Write-Host "Matching changes:" - $matching = @( - 'externals', - 'native', - 'scripts', - '.gitmodules' - ) - $requiresFull = (git diff-tree --no-commit-id --name-only -r HEAD~ HEAD @matching) - foreach ($d in $requiresFull) { - Write-Host " - $d" - } + Write-Host "Matching changes:" + $matching = @( + 'externals', + 'native', + 'scripts', + '.gitmodules' + ) + $requiresFull = (git diff-tree --no-commit-id --name-only -r HEAD~ HEAD @matching) + if ($?) { + foreach ($d in $requiresFull) { + Write-Host " - $d" + } - if (-not $requiresFull) { - Write-Host "Download-only build." - Write-Host "##vso[task.setvariable variable=DOWNLOAD_EXTERNALS]latest" - exit 0 + if (-not $requiresFull) { + Write-Host "Download-only build." + Write-Host "##vso[task.setvariable variable=DOWNLOAD_EXTERNALS]latest" + exit 0 + } + } } } diff --git a/scripts/guardian/APIScanSurrogates.in.xml b/scripts/guardian/APIScanSurrogates.in.xml new file mode 100644 index 0000000000..f08a175c43 --- /dev/null +++ b/scripts/guardian/APIScanSurrogates.in.xml @@ -0,0 +1,63 @@ + + + + + + + + + {SOFTWARE_FOLDER} + SRV*https://symweb + + + + + + + + + + + + + {SOFTWARE_FOLDER} + SRV*https://symweb + + + + + + + + + + + + + + {SOFTWARE_FOLDER} + SRV*https://symweb + + + + + + + + + + + + + {SOFTWARE_FOLDER} + SRV*https://symweb + + + + + + + + + + \ No newline at end of file diff --git a/scripts/install-android-package.ps1 b/scripts/install-android-package.ps1 index d646abfb89..eda63e2606 100644 --- a/scripts/install-android-package.ps1 +++ b/scripts/install-android-package.ps1 @@ -21,7 +21,7 @@ $sdkmanager = Join-Path "$latest" "bin" "sdkmanager$ext" Set-Content -Value "y" -Path "yes.txt" try { if ($IsMacOS -or $IsLinux) { - sh -c "`"$sdkmanager`" `"$($Package.Replace(';', '\;'))`" < yes.txt" + sh -c "'$sdkmanager' '$Package' < yes.txt" } else { cmd /c "`"$sdkmanager`" `"$Package`" < yes.txt" } diff --git a/scripts/install-android-platform.ps1 b/scripts/install-android-platform.ps1 index 3876ae015e..0e418e1cef 100644 --- a/scripts/install-android-platform.ps1 +++ b/scripts/install-android-platform.ps1 @@ -27,7 +27,7 @@ $sdkmanager = Join-Path "$latest" "bin" "sdkmanager$ext" Set-Content -Value "y" -Path "yes.txt" try { if ($IsMacOS -or $IsLinux) { - sh -c "`"$sdkmanager`" `"platforms\;android-$API`" < yes.txt" + sh -c "'$sdkmanager' 'platforms;android-$API' < yes.txt" } else { cmd /c "`"$sdkmanager`" `"platforms;android-$API`" < yes.txt" } diff --git a/scripts/install-openjdk.ps1 b/scripts/install-openjdk.ps1 index 9291f86cb8..3feb68f36f 100644 --- a/scripts/install-openjdk.ps1 +++ b/scripts/install-openjdk.ps1 @@ -6,50 +6,56 @@ Param( $ErrorActionPreference = 'Stop' -Add-Type -AssemblyName System.IO.Compression.FileSystem +if (Test-Path (Join-Path "$env:JAVA_HOME_17_X64" "bin")) { + Write-Host "Java is already installed to '$env:JAVA_HOME_17_X64'..." + $java_home = $env:JAVA_HOME_17_X64 +} else { + Add-Type -AssemblyName System.IO.Compression.FileSystem -$HOME_DIR = if ($env:HOME) { $env:HOME } else { $env:USERPROFILE } + $HOME_DIR = if ($env:HOME) { $env:HOME } else { $env:USERPROFILE } -if ($IsMacOS) { - $ext = "tar.gz" - $url = "https://aka.ms/download-jdk/microsoft-jdk-$Version-macOS-x64.tar.gz" -} elseif ($IsLinux) { - $ext = "tar.gz" - $url = "https://aka.ms/download-jdk/microsoft-jdk-$Version-linux-x64.tar.gz" -} else { - $ext = "zip" - $url = "https://aka.ms/download-jdk/microsoft-jdk-$Version-windows-x64.zip" -} + if ($IsMacOS) { + $ext = "tar.gz" + $url = "https://aka.ms/download-jdk/microsoft-jdk-$Version-macOS-x64.tar.gz" + } elseif ($IsLinux) { + $ext = "tar.gz" + $url = "https://aka.ms/download-jdk/microsoft-jdk-$Version-linux-x64.tar.gz" + } else { + $ext = "zip" + $url = "https://aka.ms/download-jdk/microsoft-jdk-$Version-windows-x64.zip" + } -$jdk = Join-Path "$HOME_DIR" "openjdk" -if ($InstallDestination) { - $jdk = $InstallDestination -} -Write-Host "Install destination is '$jdk'..." + $jdk = Join-Path "$HOME_DIR" "openjdk" + if ($InstallDestination) { + $jdk = $InstallDestination + } + Write-Host "Install destination is '$jdk'..." -$jdkTemp = Join-Path "$HOME_DIR" "openjdk-temp" -$archive = Join-Path "$jdkTemp" "openjdk.$ext" + $jdkTemp = Join-Path "$HOME_DIR" "openjdk-temp" + $archive = Join-Path "$jdkTemp" "openjdk.$ext" -# download -Write-Host "Downloading OpenJDK to '$archive'..." -New-Item -ItemType Directory -Force -Path "$jdkTemp" | Out-Null -(New-Object System.Net.WebClient).DownloadFile("$url", "$archive") + # download + Write-Host "Downloading OpenJDK to '$archive'..." + New-Item -ItemType Directory -Force -Path "$jdkTemp" | Out-Null + (New-Object System.Net.WebClient).DownloadFile("$url", "$archive") -# install -Write-Host "Extracting OpenJDK to '$jdk'..." -New-Item -ItemType Directory -Force -Path "$jdk" | Out-Null -if ($IsMacOS -or $IsLinux) { - tar -vxzf "$archive" -C "$jdk" -} else { - [System.IO.Compression.ZipFile]::ExtractToDirectory("$archive", "$jdk") -} + # install + Write-Host "Extracting OpenJDK to '$jdk'..." + New-Item -ItemType Directory -Force -Path "$jdk" | Out-Null + if ($IsMacOS -or $IsLinux) { + tar -vxzf "$archive" -C "$jdk" + } else { + [System.IO.Compression.ZipFile]::ExtractToDirectory("$archive", "$jdk") + } -# set the JAVA_HOME -if ($IsMacOS) { - $java_home = Join-Path "$jdk" "jdk-$FolderVersion/Contents/Home" -} else { - $java_home = Join-Path "$jdk" "jdk-$FolderVersion" + # set the JAVA_HOME + if ($IsMacOS) { + $java_home = Join-Path "$jdk" "jdk-$FolderVersion/Contents/Home" + } else { + $java_home = Join-Path "$jdk" "jdk-$FolderVersion" + } } + Write-Host "##vso[task.setvariable variable=JAVA_HOME;]$java_home" $env:JAVA_HOME = "$java_home" diff --git a/scripts/install-python.ps1 b/scripts/install-python.ps1 index 029a0869c7..6002b96e5e 100644 --- a/scripts/install-python.ps1 +++ b/scripts/install-python.ps1 @@ -31,12 +31,9 @@ if ($IsMacOS) { } else { $platform = "win32" } - -$downloadUrl = (($pythonManifest - | Where-Object { $_.version -eq $Version } - | Select-Object -First 1).files - | Where-Object { $_.platform -eq $platform -and $_.arch -eq $Arch } - | Select-Object -First 1).download_url +$manifestFileVersion = $pythonManifest | Where-Object { $_.version -eq $Version } | Select-Object -First 1 +$manifestFileItem = $manifestFileVersion.files | Where-Object { $_.platform -eq $platform -and $_.arch -eq $Arch } | Select-Object -First 1 +$downloadUrl = $manifestFileItem.download_url # download $tempDir = Join-Path "$HOME_DIR" "python-temp" diff --git a/scripts/vcvarsall.bat b/scripts/vcvarsall.bat new file mode 100644 index 0000000000..52a6e62855 --- /dev/null +++ b/scripts/vcvarsall.bat @@ -0,0 +1,33 @@ +@echo off + +REM Check if all three arguments are provided +if "%~2"=="" ( + echo Usage: %0 ^ ^ ^ + exit /b 1 +) + +set __VSCMD_ARG_NO_LOGO=1 +set VSCMD_START_DIR=%CD% + +REM Run vcvarsall.bat script +call "%~1\VC\Auxiliary\Build\vcvarsall.bat" %~2 +shift +shift + +REM drop the path to the VS install +set "args=" +:getRemainingArgs +if "%~1" neq "" ( + set ^"args=%args% %1" + shift /1 + goto :getRemainingArgs +) + +REM Check if vcvarsall.bat ran successfully +if %errorlevel% neq 0 ( + echo Error: Failed to run vcvarsall.bat + exit /b 1 +) + +REM Run the provided command +%args% diff --git a/source/SkiaSharp.Build.props b/source/SkiaSharp.Build.props index 0cb92531a1..7d20b27460 100644 --- a/source/SkiaSharp.Build.props +++ b/source/SkiaSharp.Build.props @@ -160,9 +160,13 @@ + portable true + True + + false diff --git a/source/SkiaSharp.Build.targets b/source/SkiaSharp.Build.targets index 94ccde57bc..3f83ca44cf 100644 --- a/source/SkiaSharp.Build.targets +++ b/source/SkiaSharp.Build.targets @@ -104,9 +104,9 @@ $(_VersionNuGetMatch) $(Version)-$(VersionSuffix) - $(Version)+$(AssemblyVersionGitBranch.Replace('/', '-').Replace('\', '-')) - $(Version).$(AssemblyVersionGitSha) $(Version) + $(InformationalVersion)+$(AssemblyVersionGitBranch.Replace('/', '-').Replace('\', '-')) + $(InformationalVersion).$(AssemblyVersionGitSha) $(_VersionAssemblyMatch) $(_VersionFileMatch) @@ -138,6 +138,22 @@ internal partial class VersionConstants { + + + + + + + + - + <_SignAssemblyVerifyAfterTargets> Build + Condition=" $(IsWindows) and '$(SignAssembly)' == 'true' and '$(Configuration)' == 'Release' and '$(TargetPath)' != '' and '$(BuildingInsideVisualStudio)' != 'true' "> + - + @@ -34,23 +40,74 @@ $(PackageNotes) - + + + + + + + + + + + + + + + <_IncludeAdditionalTfmSpecificPackageFilesDependsOn> + _IncludeAdditionalTfmSpecificPackageFilesPrepare; + IncludeMDocTfmSpecificPackageFiles; + IncludeReferenceAssemblyTfmSpecificPackageFiles; + IncludeAdditionalTfmSpecificPackageFiles; + + + DependsOnTargets="$(_IncludeAdditionalTfmSpecificPackageFilesDependsOn)" /> + + + Set the package version properties. + =================================================================================================================== + --> $(Version) diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/AppHostBuilderExtensions.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/AppHostBuilderExtensions.cs index 9fb132aba5..cc28dcf9e6 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/AppHostBuilderExtensions.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/AppHostBuilderExtensions.cs @@ -13,6 +13,7 @@ public static MauiAppBuilder UseSkiaSharp(this MauiAppBuilder builder) => .ConfigureMauiHandlers(handlers => { handlers.AddHandler(); + handlers.AddHandler(); }) .ConfigureImageSources(sources => { diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKCanvasView.HandlerImpl.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKCanvasView.HandlerImpl.cs deleted file mode 100644 index e1c4b27bde..0000000000 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKCanvasView.HandlerImpl.cs +++ /dev/null @@ -1,38 +0,0 @@ -#nullable enable - -using System; - -namespace SkiaSharp.Views.Maui.Controls -{ - public partial class SKCanvasView : ISKCanvasView - { - private SKSizeI lastCanvasSize; - - public SKCanvasView() - { - var controller = (ISKCanvasViewController)this; - - controller.GetCanvasSize += OnGetCanvasSize; - controller.SurfaceInvalidated += OnSurfaceInvalidated; - - void OnGetCanvasSize(object? sender, GetPropertyValueEventArgs e) - { - e.Value = lastCanvasSize; - } - - void OnSurfaceInvalidated(object? sender, EventArgs e) - { - Handler?.Invoke(nameof(ISKCanvasView.InvalidateSurface)); - } - } - - void ISKCanvasView.OnCanvasSizeChanged(SKSizeI size) => - lastCanvasSize = size; - - void ISKCanvasView.OnPaintSurface(SKPaintSurfaceEventArgs e) => - OnPaintSurface(e); - - void ISKCanvasView.OnTouch(SKTouchEventArgs e) => - OnTouch(e); - } -} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKCanvasView.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKCanvasView.cs index e1b21e1082..9f4cb6172a 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKCanvasView.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKCanvasView.cs @@ -8,7 +8,7 @@ namespace SkiaSharp.Views.Maui.Controls { - public partial class SKCanvasView : View, ISKCanvasViewController + public partial class SKCanvasView : View, ISKCanvasView { public static readonly BindableProperty IgnorePixelScalingProperty = BindableProperty.Create(nameof(IgnorePixelScaling), typeof(bool), typeof(SKCanvasView), false); @@ -16,99 +16,52 @@ public partial class SKCanvasView : View, ISKCanvasViewController public static readonly BindableProperty EnableTouchEventsProperty = BindableProperty.Create(nameof(EnableTouchEvents), typeof(bool), typeof(SKCanvasView), false); - // the user can subscribe to repaint + private SKSizeI lastCanvasSize; + + public SKCanvasView() + { + } + public event EventHandler? PaintSurface; - // the user can subscribe to touch events public event EventHandler? Touch; - // the native listens to this event - private event EventHandler? SurfaceInvalidated; - private event EventHandler>? GetCanvasSize; - - // the user asks the for the size - public SKSize CanvasSize - { - get - { - // send a mesage to the native view - var args = new GetPropertyValueEventArgs(); - GetCanvasSize?.Invoke(this, args); - return args.Value; - } - } + public SKSize CanvasSize => lastCanvasSize; public bool IgnorePixelScaling { - get { return (bool)GetValue(IgnorePixelScalingProperty); } - set { SetValue(IgnorePixelScalingProperty, value); } + get => (bool)GetValue(IgnorePixelScalingProperty); + set => SetValue(IgnorePixelScalingProperty, value); } public bool EnableTouchEvents { - get { return (bool)GetValue(EnableTouchEventsProperty); } - set { SetValue(EnableTouchEventsProperty, value); } + get => (bool)GetValue(EnableTouchEventsProperty); + set => SetValue(EnableTouchEventsProperty, value); } - // the user asks to repaint public void InvalidateSurface() { - // send a mesage to the native view - SurfaceInvalidated?.Invoke(this, EventArgs.Empty); + Handler?.Invoke(nameof(ISKCanvasView.InvalidateSurface)); } - // the native view tells the user to repaint protected virtual void OnPaintSurface(SKPaintSurfaceEventArgs e) { PaintSurface?.Invoke(this, e); } - // the native view responds to a touch protected virtual void OnTouch(SKTouchEventArgs e) { Touch?.Invoke(this, e); } - // ISKViewController implementation - - event EventHandler ISKCanvasViewController.SurfaceInvalidated - { - add { SurfaceInvalidated += value; } - remove { SurfaceInvalidated -= value; } - } - - event EventHandler> ISKCanvasViewController.GetCanvasSize - { - add { GetCanvasSize += value; } - remove { GetCanvasSize -= value; } - } + void ISKCanvasView.OnCanvasSizeChanged(SKSizeI size) => + lastCanvasSize = size; - void ISKCanvasViewController.OnPaintSurface(SKPaintSurfaceEventArgs e) - { + void ISKCanvasView.OnPaintSurface(SKPaintSurfaceEventArgs e) => OnPaintSurface(e); - } - void ISKCanvasViewController.OnTouch(SKTouchEventArgs e) - { + void ISKCanvasView.OnTouch(SKTouchEventArgs e) => OnTouch(e); - } - - protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint) - { - return new SizeRequest(new Size(40.0, 40.0)); - } - } - - public interface ISKCanvasViewController : IViewController - { - // the native listens to this event - event EventHandler SurfaceInvalidated; - event EventHandler> GetCanvasSize; - - // the native view tells the user to repaint - void OnPaintSurface(SKPaintSurfaceEventArgs e); - - // the native view responds to a touch - void OnTouch(SKTouchEventArgs e); } } diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKGLView.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKGLView.cs index 519cbfc92d..373f1a6ed2 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKGLView.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKGLView.cs @@ -8,127 +8,71 @@ namespace SkiaSharp.Views.Maui.Controls { - public partial class SKGLView : View, ISKGLViewController + public partial class SKGLView : View, ISKGLView { + public static readonly BindableProperty IgnorePixelScalingProperty = + BindableProperty.Create(nameof(IgnorePixelScaling), typeof(bool), typeof(SKGLView), false); + public static readonly BindableProperty HasRenderLoopProperty = BindableProperty.Create(nameof(HasRenderLoop), typeof(bool), typeof(SKGLView), false); public static readonly BindableProperty EnableTouchEventsProperty = BindableProperty.Create(nameof(EnableTouchEvents), typeof(bool), typeof(SKGLView), false); + private SKSizeI lastCanvasSize; + private GRContext? lastGRContext; + + public bool IgnorePixelScaling + { + get => (bool)GetValue(IgnorePixelScalingProperty); + set => SetValue(IgnorePixelScalingProperty, value); + } + public bool HasRenderLoop { - get { return (bool)GetValue(HasRenderLoopProperty); } - set { SetValue(HasRenderLoopProperty, value); } + get => (bool)GetValue(HasRenderLoopProperty); + set => SetValue(HasRenderLoopProperty, value); } public bool EnableTouchEvents { - get { return (bool)GetValue(EnableTouchEventsProperty); } - set { SetValue(EnableTouchEventsProperty, value); } + get => (bool)GetValue(EnableTouchEventsProperty); + set => SetValue(EnableTouchEventsProperty, value); } - // the user can subscribe to repaint public event EventHandler? PaintSurface; - // the user can subscribe to touch events public event EventHandler? Touch; - // the native listens to this event - private event EventHandler? SurfaceInvalidated; - private event EventHandler>? GetCanvasSize; - private event EventHandler>? GetGRContext; + public SKSize CanvasSize => lastCanvasSize; - // the user asks the for the size - public SKSize CanvasSize - { - get - { - // send a mesage to the native view - var args = new GetPropertyValueEventArgs(); - GetCanvasSize?.Invoke(this, args); - return args.Value; - } - } + public GRContext? GRContext => lastGRContext; - // the user asks the for the current GRContext - public GRContext GRContext - { - get - { - // send a mesage to the native view - var args = new GetPropertyValueEventArgs(); - GetGRContext?.Invoke(this, args); - return args.Value; - } - } - - // the user asks to repaint public void InvalidateSurface() { - // send a mesage to the native view - SurfaceInvalidated?.Invoke(this, EventArgs.Empty); + Handler?.Invoke(nameof(ISKGLView.InvalidateSurface)); } - // the native view tells the user to repaint protected virtual void OnPaintSurface(SKPaintGLSurfaceEventArgs e) { PaintSurface?.Invoke(this, e); } - // the native view responds to a touch protected virtual void OnTouch(SKTouchEventArgs e) { Touch?.Invoke(this, e); } - // ISKViewController implementation - - event EventHandler ISKGLViewController.SurfaceInvalidated - { - add { SurfaceInvalidated += value; } - remove { SurfaceInvalidated -= value; } - } - - event EventHandler> ISKGLViewController.GetCanvasSize - { - add { GetCanvasSize += value; } - remove { GetCanvasSize -= value; } - } + void ISKGLView.OnCanvasSizeChanged(SKSizeI size) => + lastCanvasSize = size; - event EventHandler> ISKGLViewController.GetGRContext - { - add { GetGRContext += value; } - remove { GetGRContext -= value; } - } + void ISKGLView.OnGRContextChanged(GRContext? context) => + lastGRContext = context; - void ISKGLViewController.OnPaintSurface(SKPaintGLSurfaceEventArgs e) - { + void ISKGLView.OnPaintSurface(SKPaintGLSurfaceEventArgs e) => OnPaintSurface(e); - } - void ISKGLViewController.OnTouch(SKTouchEventArgs e) - { + void ISKGLView.OnTouch(SKTouchEventArgs e) => OnTouch(e); - } - - protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint) - { - return new SizeRequest(new Size(40.0, 40.0)); - } - } - - public interface ISKGLViewController : IViewController - { - // the native listens to this event - event EventHandler SurfaceInvalidated; - event EventHandler> GetCanvasSize; - event EventHandler> GetGRContext; - - // the native view tells the user to repaint - void OnPaintSurface(SKPaintGLSurfaceEventArgs e); - - // the native view responds to a touch - void OnTouch(SKTouchEventArgs e); } } diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKImageSource.HandlerImpl.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKImageSource.HandlerImpl.cs deleted file mode 100644 index 695fa33f77..0000000000 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKImageSource.HandlerImpl.cs +++ /dev/null @@ -1,20 +0,0 @@ -#nullable enable - -namespace SkiaSharp.Views.Maui.Controls -{ - partial class SKImageImageSource : ISKImageImageSource - { - } - - partial class SKBitmapImageSource : ISKBitmapImageSource - { - } - - partial class SKPixmapImageSource : ISKPixmapImageSource - { - } - - partial class SKPictureImageSource : ISKPictureImageSource - { - } -} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKImageSource.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKImageSource.cs index 86bcb3e2fb..aa0ad8b876 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKImageSource.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Controls/SKImageSource.cs @@ -5,7 +5,7 @@ namespace SkiaSharp.Views.Maui.Controls { - public sealed partial class SKImageImageSource : ImageSource + public sealed partial class SKImageImageSource : ImageSource, ISKImageImageSource { public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(Image), typeof(SKImage), typeof(SKImageImageSource), default(SKImage)); @@ -41,7 +41,7 @@ protected override void OnPropertyChanged(string propertyName = null) } } - public sealed partial class SKBitmapImageSource : ImageSource + public sealed partial class SKBitmapImageSource : ImageSource, ISKBitmapImageSource { public static readonly BindableProperty BitmapProperty = BindableProperty.Create(nameof(Bitmap), typeof(SKBitmap), typeof(SKBitmapImageSource), default(SKBitmap)); @@ -77,7 +77,7 @@ protected override void OnPropertyChanged(string propertyName = null) } } - public sealed partial class SKPixmapImageSource : ImageSource + public sealed partial class SKPixmapImageSource : ImageSource, ISKPixmapImageSource { public static readonly BindableProperty PixmapProperty = BindableProperty.Create(nameof(Pixmap), typeof(SKPixmap), typeof(SKPixmapImageSource), default(SKPixmap)); @@ -113,7 +113,7 @@ protected override void OnPropertyChanged(string propertyName = null) } } - public sealed partial class SKPictureImageSource : ImageSource + public sealed partial class SKPictureImageSource : ImageSource, ISKPictureImageSource { public static readonly BindableProperty PictureProperty = BindableProperty.Create(nameof(Picture), typeof(SKPicture), typeof(SKPictureImageSource), default(SKPicture)); diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Android.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Android.cs index 82bf3bd614..d9d67f8fa6 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Android.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Android.cs @@ -34,19 +34,16 @@ protected override void DisconnectHandler(SKCanvasView platformView) public static void OnInvalidateSurface(SKCanvasViewHandler handler, ISKCanvasView canvasView, object? args) { - handler.PlatformView?.Invalidate(); + handler.PlatformView.Invalidate(); } public static void MapIgnorePixelScaling(SKCanvasViewHandler handler, ISKCanvasView canvasView) { - handler.PlatformView?.UpdateIgnorePixelScaling(canvasView); + handler.PlatformView.IgnorePixelScaling = canvasView.IgnorePixelScaling; } public static void MapEnableTouchEvents(SKCanvasViewHandler handler, ISKCanvasView canvasView) { - if (handler.PlatformView == null) - return; - handler.touchHandler ??= new SKTouchHandler( args => canvasView.OnTouch(args), (x, y) => handler.OnGetScaledCoord(x, y)); diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.iOS.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Apple.cs similarity index 92% rename from source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.iOS.cs rename to source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Apple.cs index 33c3025314..a40ac0b1a2 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.iOS.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Apple.cs @@ -33,19 +33,16 @@ protected override void DisconnectHandler(SKCanvasView platformView) public static void OnInvalidateSurface(SKCanvasViewHandler handler, ISKCanvasView canvasView, object? args) { - handler.PlatformView?.SetNeedsDisplay(); + handler.PlatformView.SetNeedsDisplay(); } public static void MapIgnorePixelScaling(SKCanvasViewHandler handler, ISKCanvasView canvasView) { - handler.PlatformView?.UpdateIgnorePixelScaling(canvasView); + handler.PlatformView.IgnorePixelScaling = canvasView.IgnorePixelScaling; } public static void MapEnableTouchEvents(SKCanvasViewHandler handler, ISKCanvasView canvasView) { - if (handler.PlatformView == null) - return; - handler.touchHandler ??= new SKTouchHandler( args => canvasView.OnTouch(args), (x, y) => handler.OnGetScaledCoord(x, y)); diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Tizen.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Tizen.cs index 08cd85f944..ad5bd55ce1 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Tizen.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Tizen.cs @@ -33,19 +33,16 @@ protected override void DisconnectHandler(SKCanvasView platformView) public static void OnInvalidateSurface(SKCanvasViewHandler handler, ISKCanvasView canvasView, object? args) { - handler.PlatformView?.Invalidate(); + handler.PlatformView.Invalidate(); } public static void MapIgnorePixelScaling(SKCanvasViewHandler handler, ISKCanvasView canvasView) { - handler.PlatformView?.UpdateIgnorePixelScaling(canvasView); + handler.PlatformView.IgnorePixelScaling = canvasView.IgnorePixelScaling; } public static void MapEnableTouchEvents(SKCanvasViewHandler handler, ISKCanvasView canvasView) { - if (handler.PlatformView == null) - return; - handler.touchHandler ??= new SKTouchHandler( args => canvasView.OnTouch(args), (x, y) => handler.OnGetScaledCoord(x, y)); diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Windows.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Windows.cs index 9b6ba30935..8518413d5d 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Windows.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.Windows.cs @@ -1,4 +1,5 @@ using Microsoft.Maui.Handlers; +using Microsoft.UI.Xaml; using SkiaSharp.Views.Maui.Platform; using SkiaSharp.Views.Windows; @@ -32,12 +33,12 @@ protected override void DisconnectHandler(SKXamlCanvas platformView) public static void OnInvalidateSurface(SKCanvasViewHandler handler, ISKCanvasView canvasView, object? args) { - handler.PlatformView?.Invalidate(); + handler.PlatformView.Invalidate(); } public static void MapIgnorePixelScaling(SKCanvasViewHandler handler, ISKCanvasView canvasView) { - handler.PlatformView?.UpdateIgnorePixelScaling(canvasView); + handler.PlatformView.IgnorePixelScaling = canvasView.IgnorePixelScaling; } public static void MapEnableTouchEvents(SKCanvasViewHandler handler, ISKCanvasView canvasView) diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.cs index dd9deea98e..90ea1bcd4f 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKCanvasView/SKCanvasViewHandler.cs @@ -13,7 +13,7 @@ public partial class SKCanvasViewHandler }; public static CommandMapper SKCanvasViewCommandMapper = - new CommandMapper() + new CommandMapper(ViewHandler.ViewCommandMapper) { [nameof(ISKCanvasView.InvalidateSurface)] = OnInvalidateSurface, }; diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Android.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Android.cs new file mode 100644 index 0000000000..aff64caa15 --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Android.cs @@ -0,0 +1,136 @@ +using Android.Content; +using Android.Opengl; +using Microsoft.Maui; +using Microsoft.Maui.Handlers; +using Microsoft.Maui.Platform; +using SkiaSharp.Views.Android; +using SkiaSharp.Views.Maui.Platform; + +namespace SkiaSharp.Views.Maui.Handlers +{ + public partial class SKGLViewHandler : ViewHandler + { + private SKSizeI lastCanvasSize; + private GRContext? lastGRContext; + private SKTouchHandler? touchHandler; + + protected override SKGLTextureView CreatePlatformView() + { + var view = new MauiSKGLTextureView(Context); + view.SetOpaque(false); + return view; + } + + protected override void ConnectHandler(SKGLTextureView platformView) + { + platformView.PaintSurface += OnPaintSurface; + + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(SKGLTextureView platformView) + { + touchHandler?.Detach(platformView); + touchHandler = null; + + platformView.PaintSurface -= OnPaintSurface; + + base.DisconnectHandler(platformView); + } + + // Mapper actions / properties + + public static void OnInvalidateSurface(SKGLViewHandler handler, ISKGLView view, object? args) + { + if (handler.PlatformView.RenderMode == Rendermode.WhenDirty) + handler.PlatformView.RequestRender(); + } + + public static void MapIgnorePixelScaling(SKGLViewHandler handler, ISKGLView view) + { + if (handler.PlatformView is not MauiSKGLTextureView pv) + return; + + pv.IgnorePixelScaling = view.IgnorePixelScaling; + pv.RequestRender(); + } + + public static void MapHasRenderLoop(SKGLViewHandler handler, ISKGLView view) + { + handler.PlatformView.RenderMode = view.HasRenderLoop + ? Rendermode.Continuously + : Rendermode.WhenDirty; + } + + public static void MapEnableTouchEvents(SKGLViewHandler handler, ISKGLView view) + { + handler.touchHandler ??= new SKTouchHandler( + args => view.OnTouch(args), + (x, y) => handler.OnGetScaledCoord(x, y)); + + handler.touchHandler?.SetEnabled(handler.PlatformView, view.EnableTouchEvents); + } + + // helper methods + + private void OnPaintSurface(object? sender, Android.SKPaintGLSurfaceEventArgs e) + { + var newCanvasSize = e.Info.Size; + if (lastCanvasSize != newCanvasSize) + { + lastCanvasSize = newCanvasSize; + VirtualView?.OnCanvasSizeChanged(newCanvasSize); + } + if (sender is SKGLTextureView platformView) + { + var newGRContext = platformView.GRContext; + if (lastGRContext != newGRContext) + { + lastGRContext = newGRContext; + VirtualView?.OnGRContextChanged(newGRContext); + } + } + + VirtualView?.OnPaintSurface(new SKPaintGLSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info, e.RawInfo)); + } + + private SKPoint OnGetScaledCoord(double x, double y) + { + if (VirtualView?.IgnorePixelScaling == true && Context != null) + { + x = Context.FromPixels(x); + y = Context.FromPixels(y); + } + + return new SKPoint((float)x, (float)y); + } + + private class MauiSKGLTextureView : SKGLTextureView + { + private float density; + + public MauiSKGLTextureView(Context context) + : base(context) + { + density = Resources?.DisplayMetrics?.Density ?? 1; + } + + public bool IgnorePixelScaling { get; set; } + + protected override void OnPaintSurface(Android.SKPaintGLSurfaceEventArgs e) + { + if (IgnorePixelScaling) + { + var userVisibleSize = new SKSizeI((int)(e.Info.Width / density), (int)(e.Info.Height / density)); + var canvas = e.Surface.Canvas; + canvas.Scale(density); + canvas.Save(); + + e = new Android.SKPaintGLSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info.WithSize(userVisibleSize), e.Info); + } + + base.OnPaintSurface(e); + } + } + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.MacCatalyst.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.MacCatalyst.cs new file mode 100644 index 0000000000..8b1a067929 --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.MacCatalyst.cs @@ -0,0 +1,127 @@ +using System; +using Microsoft.Maui.Handlers; +using SkiaSharp.Views.iOS; +using SkiaSharp.Views.Maui.Platform; +using UIKit; + +namespace SkiaSharp.Views.Maui.Handlers +{ + public partial class SKGLViewHandler : ViewHandler + { + private SKSizeI lastCanvasSize; + private GRContext? lastGRContext; + private SKTouchHandler? touchHandler; + + protected override SKMetalView CreatePlatformView() => + new MauiSKMetalView + { + BackgroundColor = UIColor.Clear, + Opaque = false, + }; + + protected override void ConnectHandler(SKMetalView platformView) + { + platformView.PaintSurface += OnPaintSurface; + + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(SKMetalView platformView) + { + touchHandler?.Detach(platformView); + touchHandler = null; + + platformView.PaintSurface -= OnPaintSurface; + + base.DisconnectHandler(platformView); + } + + // Mapper actions / properties + + public static void OnInvalidateSurface(SKGLViewHandler handler, ISKGLView view, object? args) + { + if (handler.PlatformView.Paused && handler.PlatformView.EnableSetNeedsDisplay) + handler.PlatformView.SetNeedsDisplay(); + } + + public static void MapIgnorePixelScaling(SKGLViewHandler handler, ISKGLView view) + { + if (handler.PlatformView is MauiSKMetalView pv) + { + pv.IgnorePixelScaling = view.IgnorePixelScaling; + handler.PlatformView.SetNeedsDisplay(); + } + } + + public static void MapHasRenderLoop(SKGLViewHandler handler, ISKGLView view) + { + handler.PlatformView.Paused = !view.HasRenderLoop; + handler.PlatformView.EnableSetNeedsDisplay = !view.HasRenderLoop; + } + + public static void MapEnableTouchEvents(SKGLViewHandler handler, ISKGLView view) + { + handler.touchHandler ??= new SKTouchHandler( + args => view.OnTouch(args), + (x, y) => handler.OnGetScaledCoord(x, y)); + + handler.touchHandler?.SetEnabled(handler.PlatformView, view.EnableTouchEvents); + } + + // helper methods + + private void OnPaintSurface(object? sender, iOS.SKPaintMetalSurfaceEventArgs e) + { + var newCanvasSize = e.Info.Size; + if (lastCanvasSize != newCanvasSize) + { + lastCanvasSize = newCanvasSize; + VirtualView?.OnCanvasSizeChanged(newCanvasSize); + } + if (sender is SKMetalView platformView) + { + var newGRContext = platformView.GRContext; + if (lastGRContext != newGRContext) + { + lastGRContext = newGRContext; + VirtualView?.OnGRContextChanged(newGRContext); + } + } + + VirtualView?.OnPaintSurface(new SKPaintGLSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info, e.RawInfo)); + } + + private SKPoint OnGetScaledCoord(double x, double y) + { + if (VirtualView?.IgnorePixelScaling == false && PlatformView != null) + { + var scale = PlatformView.ContentScaleFactor; + + x *= scale; + y *= scale; + } + + return new SKPoint((float)x, (float)y); + } + + private class MauiSKMetalView : SKMetalView + { + public bool IgnorePixelScaling { get; set; } + + protected override void OnPaintSurface(iOS.SKPaintMetalSurfaceEventArgs e) + { + if (IgnorePixelScaling) + { + var userVisibleSize = new SKSizeI((int)Bounds.Width, (int)Bounds.Height); + var canvas = e.Surface.Canvas; + canvas.Scale((float)ContentScaleFactor); + canvas.Save(); + + e = new iOS.SKPaintMetalSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info.WithSize(userVisibleSize), e.Info); + } + + base.OnPaintSurface(e); + } + } + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Ref.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Ref.cs new file mode 100644 index 0000000000..c9ef2d859f --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Ref.cs @@ -0,0 +1,18 @@ +using System; +using Microsoft.Maui.Handlers; + +namespace SkiaSharp.Views.Maui.Handlers +{ + public partial class SKGLViewHandler : ViewHandler + { + protected override object CreatePlatformView() => throw new NotImplementedException(); + + public static void MapIgnorePixelScaling(SKGLViewHandler handler, ISKGLView view) { } + + public static void MapHasRenderLoop(SKGLViewHandler handler, ISKGLView view) { } + + public static void MapEnableTouchEvents(SKGLViewHandler handler, ISKGLView view) { } + + public static void OnInvalidateSurface(SKGLViewHandler handler, ISKGLView view, object? args) { } + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Tizen.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Tizen.cs new file mode 100644 index 0000000000..42a948c453 --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Tizen.cs @@ -0,0 +1,21 @@ +using System; +using Microsoft.Maui.Handlers; +using SkiaSharp.Views.Maui.Platform; +using SkiaSharp.Views.Tizen.NUI; +using ScalingInfo = SkiaSharp.Views.Tizen.ScalingInfo; + +namespace SkiaSharp.Views.Maui.Handlers +{ + public partial class SKGLViewHandler : ViewHandler + { + protected override SKGLSurfaceView CreatePlatformView() => throw new PlatformNotSupportedException("SKGLView is not yet implemented for Tizen."); + + public static void MapIgnorePixelScaling(SKGLViewHandler handler, ISKGLView view) { } + + public static void MapHasRenderLoop(SKGLViewHandler handler, ISKGLView view) { } + + public static void MapEnableTouchEvents(SKGLViewHandler handler, ISKGLView view) { } + + public static void OnInvalidateSurface(SKGLViewHandler handler, ISKGLView view, object? args) { } + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Windows.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Windows.cs new file mode 100644 index 0000000000..58026f6a59 --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.Windows.cs @@ -0,0 +1,129 @@ +using Microsoft.Maui.Handlers; +using SkiaSharp.Views.Maui.Platform; +using SkiaSharp.Views.Windows; + +namespace SkiaSharp.Views.Maui.Handlers +{ + public partial class SKGLViewHandler : ViewHandler + { + private SKSizeI lastCanvasSize; + private GRContext? lastGRContext; + private SKTouchHandler? touchHandler; + + protected override SKSwapChainPanel CreatePlatformView() => new MauiSKSwapChainPanel(); + + protected override void ConnectHandler(SKSwapChainPanel platformView) + { + platformView.PaintSurface += OnPaintSurface; + + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(SKSwapChainPanel platformView) + { + touchHandler?.Detach(platformView); + touchHandler = null; + + platformView.PaintSurface -= OnPaintSurface; + + base.DisconnectHandler(platformView); + } + + // Mapper actions / properties + + public static void OnInvalidateSurface(SKGLViewHandler handler, ISKGLView view, object? args) + { + if (!handler.PlatformView.EnableRenderLoop) + handler.PlatformView.Invalidate(); + } + + public static void MapIgnorePixelScaling(SKGLViewHandler handler, ISKGLView view) + { + if (handler.PlatformView is not MauiSKSwapChainPanel pv) + return; + + pv.IgnorePixelScaling = view.IgnorePixelScaling; + pv.Invalidate(); + } + + public static void MapHasRenderLoop(SKGLViewHandler handler, ISKGLView view) + { + handler.PlatformView.EnableRenderLoop = view.HasRenderLoop; + } + + public static void MapEnableTouchEvents(SKGLViewHandler handler, ISKGLView view) + { + if (handler.PlatformView == null) + return; + + handler.touchHandler ??= new SKTouchHandler( + args => view.OnTouch(args), + (x, y) => handler.OnGetScaledCoord(x, y)); + + handler.touchHandler?.SetEnabled(handler.PlatformView, view.EnableTouchEvents); + } + + public static void MapBackground(SKGLViewHandler handler, ISKGLView view) + { + // WinUI 3 limitation: + // Setting 'Background' property is not supported on SwapChainPanel.'. + } + + // helper methods + + private void OnPaintSurface(object? sender, Windows.SKPaintGLSurfaceEventArgs e) + { + var newCanvasSize = e.Info.Size; + if (lastCanvasSize != newCanvasSize) + { + lastCanvasSize = newCanvasSize; + VirtualView?.OnCanvasSizeChanged(newCanvasSize); + } + if (sender is SKSwapChainPanel platformView) + { + var newGRContext = platformView.GRContext; + if (lastGRContext != newGRContext) + { + lastGRContext = newGRContext; + VirtualView?.OnGRContextChanged(newGRContext); + } + } + + VirtualView?.OnPaintSurface(new SKPaintGLSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info, e.RawInfo)); + } + + private SKPoint OnGetScaledCoord(double x, double y) + { + if (VirtualView?.IgnorePixelScaling == false && PlatformView != null) + { + var scale = PlatformView.ContentsScale; + + x *= scale; + y *= scale; + } + + return new SKPoint((float)x, (float)y); + } + + private class MauiSKSwapChainPanel : SKSwapChainPanel + { + public bool IgnorePixelScaling { get; set; } + + protected override void OnPaintSurface(Windows.SKPaintGLSurfaceEventArgs e) + { + if (IgnorePixelScaling) + { + var density = (float)ContentsScale; + var userVisibleSize = new SKSizeI((int)(e.Info.Width / density), (int)(e.Info.Height / density)); + var canvas = e.Surface.Canvas; + canvas.Scale(density); + canvas.Save(); + + e = new Windows.SKPaintGLSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info.WithSize(userVisibleSize), e.Info); + } + + base.OnPaintSurface(e); + } + } + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.cs new file mode 100644 index 0000000000..493691e456 --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.cs @@ -0,0 +1,35 @@ +using Microsoft.Maui; +using Microsoft.Maui.Handlers; + +namespace SkiaSharp.Views.Maui.Handlers +{ + public partial class SKGLViewHandler + { + public static PropertyMapper SKGLViewMapper = + new PropertyMapper(ViewHandler.ViewMapper) + { + [nameof(ISKGLView.EnableTouchEvents)] = MapEnableTouchEvents, + [nameof(ISKGLView.IgnorePixelScaling)] = MapIgnorePixelScaling, + [nameof(ISKGLView.HasRenderLoop)] = MapHasRenderLoop, +#if WINDOWS + [nameof(ISKGLView.Background)] = MapBackground, +#endif + }; + + public static CommandMapper SKGLViewCommandMapper = + new CommandMapper(ViewHandler.ViewCommandMapper) + { + [nameof(ISKGLView.InvalidateSurface)] = OnInvalidateSurface, + }; + + public SKGLViewHandler() + : base(SKGLViewMapper, SKGLViewCommandMapper) + { + } + + public SKGLViewHandler(PropertyMapper? mapper, CommandMapper? commands) + : base(mapper ?? SKGLViewMapper, commands ?? SKGLViewCommandMapper) + { + } + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.iOS.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.iOS.cs new file mode 100644 index 0000000000..c19a2463a6 --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKGLView/SKGLViewHandler.iOS.cs @@ -0,0 +1,219 @@ +using System; +using System.Runtime.Versioning; +using CoreAnimation; +using Foundation; +using Microsoft.Maui.Handlers; +using SkiaSharp.Views.iOS; +using SkiaSharp.Views.Maui.Platform; +using UIKit; + +namespace SkiaSharp.Views.Maui.Handlers +{ + [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] + [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("macos")] + public partial class SKGLViewHandler : ViewHandler + { + private SKSizeI lastCanvasSize; + private GRContext? lastGRContext; + private SKTouchHandler? touchHandler; + private RenderLoopManager? renderLoopManager; + + protected override SKGLView CreatePlatformView() => + new MauiSKGLView + { + BackgroundColor = UIColor.Clear, + Opaque = false, + }; + + protected override void ConnectHandler(SKGLView platformView) + { + renderLoopManager = new RenderLoopManager(this); + + platformView.PaintSurface += OnPaintSurface; + + base.ConnectHandler(platformView); + } + + protected override void DisconnectHandler(SKGLView platformView) + { + renderLoopManager?.StopRenderLoop(); + + touchHandler?.Detach(platformView); + touchHandler = null; + + platformView.PaintSurface -= OnPaintSurface; + + base.DisconnectHandler(platformView); + } + + // Mapper actions / properties + + public static void OnInvalidateSurface(SKGLViewHandler handler, ISKGLView view, object? args) + { + handler.renderLoopManager?.RequestDisplay(); + } + + public static void MapIgnorePixelScaling(SKGLViewHandler handler, ISKGLView view) + { + if (handler.PlatformView is MauiSKGLView pv) + { + pv.IgnorePixelScaling = view.IgnorePixelScaling; + handler.renderLoopManager?.RequestDisplay(); + } + } + + public static void MapHasRenderLoop(SKGLViewHandler handler, ISKGLView view) + { + if (view.HasRenderLoop) + handler.renderLoopManager?.RequestRenderLoop(); + else + handler.renderLoopManager?.StopRenderLoop(); + } + + public static void MapEnableTouchEvents(SKGLViewHandler handler, ISKGLView view) + { + handler.touchHandler ??= new SKTouchHandler( + args => view.OnTouch(args), + (x, y) => handler.OnGetScaledCoord(x, y)); + + handler.touchHandler?.SetEnabled(handler.PlatformView, view.EnableTouchEvents); + } + + // helper methods + + private void OnPaintSurface(object? sender, iOS.SKPaintGLSurfaceEventArgs e) + { + var newCanvasSize = e.Info.Size; + if (lastCanvasSize != newCanvasSize) + { + lastCanvasSize = newCanvasSize; + VirtualView?.OnCanvasSizeChanged(newCanvasSize); + } + if (sender is SKGLView platformView) + { + var newGRContext = platformView.GRContext; + if (lastGRContext != newGRContext) + { + lastGRContext = newGRContext; + VirtualView?.OnGRContextChanged(newGRContext); + } + } + + VirtualView?.OnPaintSurface(new SKPaintGLSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info, e.RawInfo)); + } + + private SKPoint OnGetScaledCoord(double x, double y) + { + if (VirtualView?.IgnorePixelScaling == false && PlatformView != null) + { + var scale = PlatformView.ContentScaleFactor; + + x *= scale; + y *= scale; + } + + return new SKPoint((float)x, (float)y); + } + + private class MauiSKGLView : SKGLView + { + public bool IgnorePixelScaling { get; set; } + + protected override void OnPaintSurface(iOS.SKPaintGLSurfaceEventArgs e) + { + if (IgnorePixelScaling) + { + var userVisibleSize = new SKSizeI((int)Bounds.Width, (int)Bounds.Height); + var canvas = e.Surface.Canvas; + canvas.Scale((float)ContentScaleFactor); + canvas.Save(); + + e = new iOS.SKPaintGLSurfaceEventArgs(e.Surface, e.BackendRenderTarget, e.Origin, e.Info.WithSize(userVisibleSize), e.Info); + } + + base.OnPaintSurface(e); + } + } + + private class RenderLoopManager + { + private CADisplayLink? displayLink; + private WeakReference weakHandler; + + public RenderLoopManager(SKGLViewHandler handler) + { + weakHandler = new WeakReference(handler); + } + + public SKGLViewHandler? Handler + { + get + { + if (weakHandler.TryGetTarget(out var handler)) + return handler; + return null; + } + } + + public SKGLView? PlatformView => Handler?.PlatformView; + + public ISKGLView? VirtualView => Handler?.VirtualView; + + public void RequestDisplay() + { + // skip if there is a render loop + if (displayLink is not null) + return; + + var nativeView = PlatformView; + nativeView?.BeginInvokeOnMainThread(() => + { + if (nativeView is not null && nativeView.Handle != IntPtr.Zero) + nativeView.Display(); + }); + } + + public void RequestRenderLoop() + { + // skip if there is already a render loop + if (displayLink is not null) + return; + + // bail out if we are requesting something that the view doesn't want to + if (VirtualView?.HasRenderLoop != true) + return; + + displayLink = CADisplayLink.Create(() => + { + var nativeView = PlatformView; + var virtualView = VirtualView; + + // stop the render loop if the loop was disabled, or the views are disposed + if (nativeView is null || virtualView is null || nativeView.Handle == IntPtr.Zero || !virtualView.HasRenderLoop) + { + StopRenderLoop(); + return; + } + + // redraw the view + nativeView.Display(); + }); + displayLink.AddToRunLoop(NSRunLoop.Current, NSRunLoopMode.Default); + } + + public void StopRenderLoop() + { + // skip if there is no render loop + if (displayLink is null) + return; + + displayLink.Invalidate(); + displayLink.Dispose(); + displayLink = null; + } + } + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKImageSourceService/SKImageSourceService.iOS.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKImageSourceService/SKImageSourceService.Apple.cs similarity index 100% rename from source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKImageSourceService/SKImageSourceService.iOS.cs rename to source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Handlers/SKImageSourceService/SKImageSourceService.Apple.cs diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/ISKGLView.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/ISKGLView.cs new file mode 100644 index 0000000000..55d517a5f0 --- /dev/null +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/ISKGLView.cs @@ -0,0 +1,27 @@ +using Microsoft.Maui; + +namespace SkiaSharp.Views.Maui +{ + public interface ISKGLView : IView + { + SKSize CanvasSize { get; } + + GRContext? GRContext { get; } + + bool HasRenderLoop { get; } + + bool IgnorePixelScaling { get; } + + bool EnableTouchEvents { get; } + + void InvalidateSurface(); + + void OnCanvasSizeChanged(SKSizeI size); + + void OnGRContextChanged(GRContext? context); + + void OnPaintSurface(SKPaintGLSurfaceEventArgs e); + + void OnTouch(SKTouchEventArgs e); + } +} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Android/SKCanvasViewExtensions.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Android/SKCanvasViewExtensions.cs deleted file mode 100644 index c292e76bed..0000000000 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Android/SKCanvasViewExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -using SkiaSharp.Views.Android; - -namespace SkiaSharp.Views.Maui.Platform -{ - public static class SKCanvasViewExtensions - { - public static void UpdateIgnorePixelScaling(this SKCanvasView nativeView, ISKCanvasView canvasView) => - nativeView.IgnorePixelScaling = canvasView?.IgnorePixelScaling ?? false; - } -} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/iOS/SKTouchHandler.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Apple/SKTouchHandler.cs similarity index 100% rename from source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/iOS/SKTouchHandler.cs rename to source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Apple/SKTouchHandler.cs diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Tizen/SKCanvasViewExtensions.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Tizen/SKCanvasViewExtensions.cs deleted file mode 100644 index fa6ba11eef..0000000000 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Tizen/SKCanvasViewExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -using SkiaSharp.Views.Tizen.NUI; - -namespace SkiaSharp.Views.Maui.Platform -{ - public static class SKCanvasViewExtensions - { - public static void UpdateIgnorePixelScaling(this SKCanvasView nativeView, ISKCanvasView canvasView) => - nativeView.IgnorePixelScaling = canvasView?.IgnorePixelScaling ?? false; - } -} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Windows/SKCanvasViewExtensions.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Windows/SKCanvasViewExtensions.cs deleted file mode 100644 index 5977efb5a8..0000000000 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/Windows/SKCanvasViewExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -using SkiaSharp.Views.Windows; - -namespace SkiaSharp.Views.Maui.Platform -{ - public static class SKCanvasViewExtensions - { - public static void UpdateIgnorePixelScaling(this SKXamlCanvas nativeView, ISKCanvasView canvasView) => - nativeView.IgnorePixelScaling = canvasView?.IgnorePixelScaling ?? false; - } -} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/iOS/SKCanvasViewExtensions.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/iOS/SKCanvasViewExtensions.cs deleted file mode 100644 index 8a495cc783..0000000000 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/Platform/iOS/SKCanvasViewExtensions.cs +++ /dev/null @@ -1,10 +0,0 @@ -using SkiaSharp.Views.iOS; - -namespace SkiaSharp.Views.Maui.Platform -{ - public static class SKCanvasViewExtensions - { - public static void UpdateIgnorePixelScaling(this SKCanvasView nativeView, ISKCanvasView canvasView) => - nativeView.IgnorePixelScaling = canvasView?.IgnorePixelScaling ?? false; - } -} diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SKPaintGLSurfaceEventArgs.cs b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SKPaintGLSurfaceEventArgs.cs index de5039c76e..f1b7e3bc3d 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SKPaintGLSurfaceEventArgs.cs +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SKPaintGLSurfaceEventArgs.cs @@ -18,6 +18,23 @@ public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget render BackendRenderTarget = renderTarget; ColorType = colorType; Origin = origin; + Info = new SKImageInfo(renderTarget.Width, renderTarget.Height, ColorType); + RawInfo = Info; + } + + public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKImageInfo info) + : this(surface, renderTarget, origin, info, info) + { + } + + public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKImageInfo info, SKImageInfo rawInfo) + { + Surface = surface; + BackendRenderTarget = renderTarget; + ColorType = info.ColorType; + Origin = origin; + Info = info; + RawInfo = rawInfo; } public SKSurface Surface { get; private set; } @@ -27,5 +44,9 @@ public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget render public SKColorType ColorType { get; private set; } public GRSurfaceOrigin Origin { get; private set; } + + public SKImageInfo Info { get; private set; } + + public SKImageInfo RawInfo { get; private set; } } } diff --git a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SkiaSharp.Views.Maui.Core.csproj b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SkiaSharp.Views.Maui.Core.csproj index c9c164a391..ee09f8be26 100644 --- a/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SkiaSharp.Views.Maui.Core.csproj +++ b/source/SkiaSharp.Views.Maui/SkiaSharp.Views.Maui.Core/SkiaSharp.Views.Maui.Core.csproj @@ -27,11 +27,23 @@ + + + + + + + + + + + + diff --git a/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI.Shared/SKXamlCanvas.cs b/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI.Shared/SKXamlCanvas.cs index 2697be3009..9fb3626263 100644 --- a/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI.Shared/SKXamlCanvas.cs +++ b/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI.Shared/SKXamlCanvas.cs @@ -125,12 +125,12 @@ private void OnUnloaded(object sender, RoutedEventArgs e) display.DpiChanged -= OnDpiChanged; } - public new async void Invalidate() + public new void Invalidate() { if (Dispatcher.HasThreadAccess) DoInvalidate(); else - await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, DoInvalidate); + _ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, DoInvalidate); } partial void DoLoaded(); diff --git a/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI/SkiaSharp.Views.Uno.WinUI.csproj b/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI/SkiaSharp.Views.Uno.WinUI.csproj index d325665ab0..2fd3ed249a 100644 --- a/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI/SkiaSharp.Views.Uno.WinUI.csproj +++ b/source/SkiaSharp.Views.Uno/SkiaSharp.Views.Uno.WinUI/SkiaSharp.Views.Uno.WinUI.csproj @@ -65,7 +65,7 @@ - + diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs index b1c7afa6a4..7d803f3496 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs @@ -60,6 +60,8 @@ public bool IgnorePixelScaling [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary? AdditionalAttributes { get; set; } + public double Dpi => dpi; + protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs index 6864aff219..6473fb1e8e 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs @@ -67,6 +67,8 @@ public bool IgnorePixelScaling [Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary? AdditionalAttributes { get; set; } + public double Dpi => dpi; + protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs index ab79c6bd4a..4df486b4e5 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/GlesInterop/Gles.cs @@ -1,4 +1,4 @@ -#if !__WASM__ && (!UNO_REFERENCE_API || (NET6_0_OR_GREATER && (__IOS__ || __MACOS__))) +#if !__WASM__ && (!UNO_REFERENCE_API || (NET6_0_OR_GREATER && (__IOS__ || __MACOS__))) && !MACCATALYST // Note that `(!UNO_REFERENCE_API || (NET6_0_OR_GREATER && (__IOS__ || __MACOS__)))` is required // because of https://github.com/unoplatform/uno/issues/8814, where !UNO_REFERENCE_API should be enough. @@ -73,6 +73,18 @@ internal static class Gles public const int GL_UNSIGNED_INT_24_8_OES = 0x84FA; public const int GL_DEPTH24_STENCIL8_OES = 0x88F0; + [DllImport(libGLESv2)] + public static extern void glGetIntegerv(uint pname, out int data); + [DllImport(libGLESv2)] + public static extern System.IntPtr glGetString(uint value); + [DllImport(libGLESv2)] + public static extern void glViewport(int x, int y, int width, int height); + [DllImport(libGLESv2)] + public static extern void glClearColor(float red, float green, float blue, float alpha); + [DllImport(libGLESv2)] + public static extern void glClear(uint mask); + +#if !__DESKTOP__ [DllImport(libGLESv2)] public static extern void glGenRenderbuffers(int n, [In, Out] uint[] buffers); [DllImport(libGLESv2)] @@ -82,18 +94,10 @@ internal static class Gles [DllImport(libGLESv2)] public static extern void glGenFramebuffers(int n, ref uint buffer); [DllImport(libGLESv2)] - public static extern void glGetIntegerv(uint pname, out int data); - [DllImport(libGLESv2)] public static extern void glGetRenderbufferParameteriv(uint target, int pname, out int param); [DllImport(libGLESv2)] public static extern void glBindRenderbuffer(uint target, uint buffer); [DllImport(libGLESv2)] - public static extern void glViewport(int x, int y, int width, int height); - [DllImport(libGLESv2)] - public static extern void glClearColor(float red, float green, float blue, float alpha); - [DllImport(libGLESv2)] - public static extern void glClear(uint mask); - [DllImport(libGLESv2)] public static extern void glBindFramebuffer(uint target, uint framebuffer); [DllImport(libGLESv2)] public static extern void glDeleteFramebuffers(int n, [In, Out] uint[] framebuffers); @@ -105,8 +109,7 @@ internal static class Gles public static extern void glDeleteRenderbuffers(int n, ref uint renderbuffer); [DllImport(libGLESv2)] public static extern void glFramebufferRenderbuffer(uint target, uint attachment, uint renderbuffertarget, uint renderbuffer); - [DllImport(libGLESv2)] - public static extern System.IntPtr glGetString(uint value); +#endif } } #endif diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs index 08122bdccf..cc86bfb368 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.Shared/SKPaintGLSurfaceEventArgs.cs @@ -1,4 +1,5 @@ -using System; +#if !MACCATALYST || HAS_UNO_WINUI +using System; using System.ComponentModel; #if HAS_UNO_WINUI @@ -68,3 +69,4 @@ public SKPaintGLSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget render public SKImageInfo RawInfo { get; private set; } } } +#endif diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WPF/SKGLElement.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WPF/SKGLElement.cs new file mode 100644 index 0000000000..00993eab5d --- /dev/null +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WPF/SKGLElement.cs @@ -0,0 +1,221 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using OpenTK.Graphics; +using System.Windows.Media.Media3D; +using SkiaSharp.Views.Desktop; +using OpenTK.Wpf; +using SkiaSharp; +using OpenTK.Graphics.OpenGL; +using OpenTK.Platform.Windows; +using OpenTK; +using System.Windows.Interop; +using OpenTK.Platform; +#if NETCOREAPP || NET +using OpenTK.Mathematics; +#endif + +namespace SkiaSharp.Views.WPF +{ + [DefaultEvent("PaintSurface")] + [DefaultProperty("Name")] + public class SKGLElement : GLWpfControl, IDisposable + { + private const SKColorType colorType = SKColorType.Rgba8888; + private const GRSurfaceOrigin surfaceOrigin = GRSurfaceOrigin.BottomLeft; + + private bool designMode; + + private GRContext grContext; + private GRGlFramebufferInfo glInfo; + private GRBackendRenderTarget renderTarget; + private SKSurface surface; + private SKCanvas canvas; + + private SKSizeI lastSize; + + public SKGLElement() + : base() + { + Initialize(); + } + + private void Initialize() + { + designMode = DesignerProperties.GetIsInDesignMode(this); + var settings = new GLWpfControlSettings() { MajorVersion = 2, MinorVersion = 1, RenderContinuously = false }; + + this.Render += OnPaint; + + this.Loaded += SKGLElement_Loaded; + this.Unloaded += SKGLElement_Unloaded; + +#if NETCOREAPP + this.RegisterToEventsDirectly = false; +#endif + + Start(settings); + } + + private void SKGLElement_Unloaded(object sender, RoutedEventArgs e) + { + Release(); + } + private void SKGLElement_Loaded(object sender, RoutedEventArgs e) + { + InvalidateVisual(); + } + + public SKSize CanvasSize => lastSize; + + public GRContext GRContext => grContext; + + [Category("Appearance")] + public event EventHandler PaintSurface; + + private SKSizeI GetSize() + { + var currentWidth = ActualWidth; + var currentHeight = ActualHeight; + + if (currentWidth < 0 || + currentHeight < 0) + { + currentWidth = 0; + currentHeight = 0; + } + + PresentationSource source = PresentationSource.FromVisual(this); + + double dpiX = 1.0; + double dpiY = 1.0; + if (source != null) + { + dpiX = source.CompositionTarget.TransformToDevice.M11; + dpiY = source.CompositionTarget.TransformToDevice.M22; + } + + return new SKSizeI((int)(currentWidth * dpiX), (int)(currentHeight * dpiY)); + } + + protected override void OnRender(DrawingContext drawingContext) + { + if (grContext != null) + { + grContext.ResetContext(); + } + base.OnRender(drawingContext); + } + + protected virtual void OnPaint(TimeSpan e) + { + if (disposed) + { + return; + } + if (designMode) + { + return; + } + + // create the contexts if not done already + if (grContext == null) + { + var glInterface = GRGlInterface.Create(); + grContext = GRContext.CreateGl(glInterface); + } + + // get the new surface size + var newSize = GetSize(); + + GL.ClearColor(Color4.Transparent); + GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit); + + // manage the drawing surface + if (renderTarget == null || lastSize != newSize || !renderTarget.IsValid) + { + + // create or update the dimensions + lastSize = newSize; + + GL.GetInteger(GetPName.FramebufferBinding, out var framebuffer); + GL.GetInteger(GetPName.StencilBits, out var stencil); + GL.GetInteger(GetPName.Samples, out var samples); + var maxSamples = grContext.GetMaxSurfaceSampleCount(colorType); + if (samples > maxSamples) + samples = maxSamples; + glInfo = new GRGlFramebufferInfo((uint)framebuffer, colorType.ToGlSizedFormat()); + + // destroy the old surface + surface?.Dispose(); + surface = null; + canvas = null; + + // re-create the render target + renderTarget?.Dispose(); + renderTarget = new GRBackendRenderTarget(newSize.Width, newSize.Height, samples, stencil, glInfo); + } + + // create the surface + if (surface == null) + { + surface = SKSurface.Create(grContext, renderTarget, surfaceOrigin, colorType); + canvas = surface.Canvas; + } + + using (new SKAutoCanvasRestore(canvas, true)) + { + // start drawing + OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType)); + } + + // update the control + canvas.Flush(); + } + + protected virtual void OnPaintSurface(SKPaintGLSurfaceEventArgs e) + { + // invoke the event + PaintSurface?.Invoke(this, e); + } + + private bool disposed = false; + + + protected virtual void Dispose(bool disposing) + { + if (disposed) + { + return; + } + + Release(); + + disposed = true; + } + + private void Release() + { + canvas = null; + surface?.Dispose(); + surface = null; + renderTarget?.Dispose(); + renderTarget = null; + grContext?.Dispose(); + grContext = null; + } + + public void Dispose() + { + Dispose(true); + } + } + +} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WPF/SkiaSharp.Views.WPF.csproj b/source/SkiaSharp.Views/SkiaSharp.Views.WPF/SkiaSharp.Views.WPF.csproj index 8108387533..cc8ba3e40c 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WPF/SkiaSharp.Views.WPF.csproj +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WPF/SkiaSharp.Views.WPF.csproj @@ -7,8 +7,17 @@ SkiaSharp.Views.WPF $(DefineConstants);__DESKTOP__;__WPF__ SkiaSharp Views & Layers for Windows Presentation Foundation (WPF) + false wpf + + + + + + + + diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/AngleSwapChainPanel.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/AngleSwapChainPanel.cs index 9491cae729..613bb8b9d5 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/AngleSwapChainPanel.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/AngleSwapChainPanel.cs @@ -1,14 +1,14 @@ -#if !WINDOWS - -using System; +using System; +using System.Threading.Tasks; +using Microsoft.UI.Dispatching; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Data; using SkiaSharp.Views.GlesInterop; using Windows.ApplicationModel; using Windows.Foundation; using Windows.System.Threading; using Windows.UI.Core; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Data; #if WINDOWS namespace SkiaSharp.Views.Windows @@ -293,11 +293,15 @@ private void RenderLoop(IAsyncAction action) else { // run in the main thread, block this one - Dispatcher.RunAsync(CoreDispatcherPriority.Normal, RenderFrame).AsTask().Wait(); + var tcs = new TaskCompletionSource(); + DispatcherQueue.TryEnqueue(DispatcherQueuePriority.Normal, () => + { + RenderFrame(); + tcs.SetResult(); + }); + tcs.Task.Wait(); } } } } } - -#endif diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs index ecd7d27168..957a824600 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/Egl.cs @@ -6,7 +6,7 @@ using EGLConfig = System.IntPtr; using EGLSurface = System.IntPtr; using EGLNativeDisplayType = System.IntPtr; -using EGLNativeWindowType = System.Object; +using EGLNativeWindowType = System.IntPtr; using glbool = System.Int32; namespace SkiaSharp.Views.GlesInterop @@ -94,7 +94,7 @@ internal static class Egl [DllImport(libEGL)] public static extern EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, int[] attrib_list); [DllImport(libEGL)] - public static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, [MarshalAs(UnmanagedType.IInspectable)] EGLNativeWindowType win, int[] attrib_list); + public static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, int[] attrib_list); [DllImport(libEGL)] public static extern glbool eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value); [DllImport(libEGL)] diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs index 8acfaa520e..6d39bfebc3 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/GlesInterop/GlesContext.cs @@ -19,6 +19,8 @@ using EGLContext = System.IntPtr; using EGLConfig = System.IntPtr; using EGLSurface = System.IntPtr; +using SkiaSharp.Views.WinUI.Native; +using WinRT; namespace SkiaSharp.Views.GlesInterop { @@ -102,7 +104,7 @@ public void CreateSurface(SwapChainPanel panel, Size? renderSurfaceSize, float? PropertySetExtensions.AddSingle(surfaceCreationProperties, Egl.EGLRenderResolutionScaleProperty, resolutionScale.Value); } - surface = Egl.eglCreateWindowSurface(eglDisplay, eglConfig, surfaceCreationProperties, surfaceAttributes); + surface = Egl.eglCreateWindowSurface(eglDisplay, eglConfig, surfaceCreationProperties.As().ThisPtr, surfaceAttributes); if (surface == Egl.EGL_NO_SURFACE) { throw new Exception("Failed to create EGL surface"); diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/Interop/PropertySetExtensions.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/Interop/PropertySetExtensions.cs deleted file mode 100644 index 6b4ef50030..0000000000 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/Interop/PropertySetExtensions.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Runtime.InteropServices; -using Windows.Foundation; -using Windows.Foundation.Collections; - -#if WINDOWS -namespace SkiaSharp.Views.Windows -#else -namespace SkiaSharp.Views.UWP -#endif -{ - internal static class PropertySetExtensions - { - private const string libInterop = "SkiaSharp.Views.Interop.UWP.dll"; - - public static void AddSingle(this PropertySet properties, string key, float value) - { - PropertySet_AddSingle(properties, key, value); - } - - public static void AddSize(this PropertySet properties, string key, Size size) - { - PropertySet_AddSize(properties, key, (float)size.Width, (float)size.Height); - } - - public static void AddSize(this PropertySet properties, string key, float width, float height) - { - PropertySet_AddSize(properties, key, width, height); - } - - [DllImport(libInterop)] - private static extern void PropertySet_AddSingle( - [MarshalAs(UnmanagedType.IInspectable)] object properties, - [MarshalAs(UnmanagedType.HString)] string key, - float value); - - [DllImport(libInterop)] - private static extern void PropertySet_AddSize( - [MarshalAs(UnmanagedType.IInspectable)] object properties, - [MarshalAs(UnmanagedType.HString)] string key, - float width, float height); - } -} diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs index d82f07fd3c..ce872b5db0 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SKSwapChainPanel.cs @@ -1,6 +1,4 @@ -#if !WINDOWS - -using System; +using System; using SkiaSharp.Views.GlesInterop; using Windows.Foundation; @@ -91,9 +89,7 @@ protected override void OnRenderFrame(Rect rect) using (new SKAutoCanvasRestore(canvas, true)) { // start drawing -#pragma warning disable CS0612 // Type or member is obsolete - OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType, glInfo)); -#pragma warning restore CS0612 // Type or member is obsolete + OnPaintSurface(new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType)); } // update the control @@ -127,5 +123,3 @@ protected override void OnDestroyingContext() } } } - -#endif diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj index 76514d596b..61d49d9946 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj +++ b/source/SkiaSharp.Views/SkiaSharp.Views.WinUI/SkiaSharp.Views.WinUI.csproj @@ -20,6 +20,12 @@ + + + + + + diff --git a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKMetalView.cs b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKMetalView.cs index f9c1dc97ff..fe0dabc5b9 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKMetalView.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKMetalView.cs @@ -83,6 +83,7 @@ private void Initialize() ColorPixelFormat = MTLPixelFormat.BGRA8Unorm; DepthStencilPixelFormat = MTLPixelFormat.Depth32Float_Stencil8; SampleCount = 1; + FramebufferOnly = false; Device = device; backendContext = new GRMtlBackendContext { diff --git a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKPaintMetalSurfaceEventArgs.cs b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKPaintMetalSurfaceEventArgs.cs index b81803f403..fa840facd4 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKPaintMetalSurfaceEventArgs.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/Apple/SKPaintMetalSurfaceEventArgs.cs @@ -20,6 +20,23 @@ public SKPaintMetalSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget ren BackendRenderTarget = renderTarget; ColorType = colorType; Origin = origin; + Info = new SKImageInfo(renderTarget.Width, renderTarget.Height, ColorType); + RawInfo = Info; + } + + public SKPaintMetalSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKImageInfo info) + : this(surface, renderTarget, origin, info, info) + { + } + + public SKPaintMetalSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget renderTarget, GRSurfaceOrigin origin, SKImageInfo info, SKImageInfo rawInfo) + { + Surface = surface; + BackendRenderTarget = renderTarget; + ColorType = info.ColorType; + Origin = origin; + Info = info; + RawInfo = rawInfo; } public SKSurface Surface { get; private set; } @@ -29,6 +46,10 @@ public SKPaintMetalSurfaceEventArgs(SKSurface surface, GRBackendRenderTarget ren public SKColorType ColorType { get; private set; } public GRSurfaceOrigin Origin { get; private set; } + + public SKImageInfo Info { get; private set; } + + public SKImageInfo RawInfo { get; private set; } } } #endif diff --git a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLLayer.cs b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLLayer.cs index ee1a8eba55..f27b363442 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLLayer.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLLayer.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel; +using System.Runtime.Versioning; using CoreAnimation; using CoreGraphics; using OpenGLES; @@ -13,6 +14,12 @@ namespace SkiaSharp.Views.tvOS namespace SkiaSharp.Views.iOS #endif { + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("macos")] + [UnsupportedOSPlatform("maccatalyst")] public class SKGLLayer : CAEAGLLayer { private const SKColorType colorType = SKColorType.Rgba8888; diff --git a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLView.cs b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLView.cs index 58e10521ee..de4b9d2455 100644 --- a/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLView.cs +++ b/source/SkiaSharp.Views/SkiaSharp.Views/Platform/iOS/SKGLView.cs @@ -2,6 +2,8 @@ using System; using System.ComponentModel; +using System.Runtime.Versioning; +using CoreAnimation; using CoreGraphics; using Foundation; using GLKit; @@ -18,6 +20,11 @@ namespace SkiaSharp.Views.tvOS namespace SkiaSharp.Views.iOS #endif { + [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] + [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("macos")] [DesignTimeVisible(true)] #if HAS_UNO internal diff --git a/source/SkiaSharpSource.Linux.slnf b/source/SkiaSharpSource.Linux.slnf index e3884ef0d3..aa198819f1 100644 --- a/source/SkiaSharpSource.Linux.slnf +++ b/source/SkiaSharpSource.Linux.slnf @@ -13,6 +13,7 @@ "..\\binding\\SkiaSharp.NativeAssets.WebAssembly\\SkiaSharp.NativeAssets.WebAssembly.csproj", "..\\binding\\SkiaSharp.NativeAssets.Win32\\SkiaSharp.NativeAssets.Win32.csproj", "..\\binding\\SkiaSharp.NativeAssets.macOS\\SkiaSharp.NativeAssets.macOS.csproj", + "..\\binding\\SkiaSharp.Resources\\SkiaSharp.Resources.csproj", "..\\binding\\SkiaSharp.SceneGraph\\SkiaSharp.SceneGraph.csproj", "..\\binding\\SkiaSharp.Skottie\\SkiaSharp.Skottie.csproj", "..\\binding\\SkiaSharp\\SkiaSharp.csproj", diff --git a/source/SkiaSharpSource.Mac.slnf b/source/SkiaSharpSource.Mac.slnf index 3a1c5f8fb2..5d046513e3 100644 --- a/source/SkiaSharpSource.Mac.slnf +++ b/source/SkiaSharpSource.Mac.slnf @@ -23,6 +23,7 @@ "..\\binding\\SkiaSharp.NativeAssets.iOS\\SkiaSharp.NativeAssets.iOS.csproj", "..\\binding\\SkiaSharp.NativeAssets.macOS\\SkiaSharp.NativeAssets.macOS.csproj", "..\\binding\\SkiaSharp.NativeAssets.tvOS\\SkiaSharp.NativeAssets.tvOS.csproj", + "..\\binding\\SkiaSharp.Resources\\SkiaSharp.Resources.csproj", "..\\binding\\SkiaSharp.SceneGraph\\SkiaSharp.SceneGraph.csproj", "..\\binding\\SkiaSharp.Skottie\\SkiaSharp.Skottie.csproj", "..\\binding\\SkiaSharp\\SkiaSharp.csproj", diff --git a/source/SkiaSharpSource.Windows.slnf b/source/SkiaSharpSource.Windows.slnf index 3fc282a63b..4d17afd5e7 100644 --- a/source/SkiaSharpSource.Windows.slnf +++ b/source/SkiaSharpSource.Windows.slnf @@ -20,9 +20,11 @@ "..\\binding\\SkiaSharp.NativeAssets.Tizen\\SkiaSharp.NativeAssets.Tizen.csproj", "..\\binding\\SkiaSharp.NativeAssets.WebAssembly\\SkiaSharp.NativeAssets.WebAssembly.csproj", "..\\binding\\SkiaSharp.NativeAssets.Win32\\SkiaSharp.NativeAssets.Win32.csproj", + "..\\binding\\SkiaSharp.NativeAssets.WinUI\\SkiaSharp.NativeAssets.WinUI.csproj", "..\\binding\\SkiaSharp.NativeAssets.iOS\\SkiaSharp.NativeAssets.iOS.csproj", "..\\binding\\SkiaSharp.NativeAssets.macOS\\SkiaSharp.NativeAssets.macOS.csproj", "..\\binding\\SkiaSharp.NativeAssets.tvOS\\SkiaSharp.NativeAssets.tvOS.csproj", + "..\\binding\\SkiaSharp.Resources\\SkiaSharp.Resources.csproj", "..\\binding\\SkiaSharp.SceneGraph\\SkiaSharp.SceneGraph.csproj", "..\\binding\\SkiaSharp.Skottie\\SkiaSharp.Skottie.csproj", "..\\binding\\SkiaSharp\\SkiaSharp.csproj", diff --git a/source/SkiaSharpSource.sln b/source/SkiaSharpSource.sln index 0586d94f8f..55d2de312a 100644 --- a/source/SkiaSharpSource.sln +++ b/source/SkiaSharpSource.sln @@ -85,6 +85,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NativeAssets.WebA EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NativeAssets.Win32", "..\binding\SkiaSharp.NativeAssets.Win32\SkiaSharp.NativeAssets.Win32.csproj", "{3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.NativeAssets.WinUI", "..\binding\SkiaSharp.NativeAssets.WinUI\SkiaSharp.NativeAssets.WinUI.csproj", "{3D2711DC-EAD2-4EE8-8A4D-83FB64897435}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp.NativeAssets.Android", "..\binding\HarfBuzzSharp.NativeAssets.Android\HarfBuzzSharp.NativeAssets.Android.csproj", "{BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp.NativeAssets.iOS", "..\binding\HarfBuzzSharp.NativeAssets.iOS\HarfBuzzSharp.NativeAssets.iOS.csproj", "{8C8F8386-9359-42F9-A5F5-83FB64897435}" @@ -107,6 +109,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "binding", "binding", "{937A EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source", "source", "{21E35524-DFEB-462F-84DD-A81213A38EEA}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SkiaSharp.Resources", "SkiaSharp.Resources", "{1EE838FE-13D6-4837-B7DE-35DD2805F092}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Resources", "..\binding\SkiaSharp.Resources\SkiaSharp.Resources.csproj", "{542CD60D-B619-4555-9A2E-A8C2A85C9CC8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -233,6 +239,10 @@ Global {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}.Debug|Any CPU.Build.0 = Debug|Any CPU {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}.Release|Any CPU.ActiveCfg = Release|Any CPU {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C}.Release|Any CPU.Build.0 = Release|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435}.Release|Any CPU.Build.0 = Release|Any CPU {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}.Debug|Any CPU.Build.0 = Debug|Any CPU {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -269,6 +279,10 @@ Global {1DE3BDD6-344B-4927-BC67-DAA80C691F6C}.Debug|Any CPU.Build.0 = Debug|Any CPU {1DE3BDD6-344B-4927-BC67-DAA80C691F6C}.Release|Any CPU.ActiveCfg = Release|Any CPU {1DE3BDD6-344B-4927-BC67-DAA80C691F6C}.Release|Any CPU.Build.0 = Release|Any CPU + {542CD60D-B619-4555-9A2E-A8C2A85C9CC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {542CD60D-B619-4555-9A2E-A8C2A85C9CC8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {542CD60D-B619-4555-9A2E-A8C2A85C9CC8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {542CD60D-B619-4555-9A2E-A8C2A85C9CC8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -315,6 +329,7 @@ Global {4A0AF7AC-E18D-41A9-801D-F2BA659B20EB} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} {694D48BE-B381-45A3-BF94-4E3D439145D8} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} {3D2711DC-EAD2-4EE8-8A4D-950A4FC9CC5C} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} + {3D2711DC-EAD2-4EE8-8A4D-83FB64897435} = {C335869B-7CC8-4239-B4A5-8031AA9758D3} {BAF3A8BA-AC8A-4D28-811B-6A60F818E75B} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} {8C8F8386-9359-42F9-A5F5-83FB64897435} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} {59D12575-1395-4D08-BA5B-73A614F2AF6B} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} @@ -324,6 +339,8 @@ Global {DD1EAB2E-29FD-4971-8440-055A1A1E69BA} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} {2B4DCCF7-8BF3-4027-9A79-344BFBD21B6D} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} {1DE3BDD6-344B-4927-BC67-DAA80C691F6C} = {2F28C1EB-D020-4A3A-948F-DF0AD0FDCC53} + {1EE838FE-13D6-4837-B7DE-35DD2805F092} = {937A3EE4-3719-452F-AA5C-2942F5C72D7D} + {542CD60D-B619-4555-9A2E-A8C2A85C9CC8} = {1EE838FE-13D6-4837-B7DE-35DD2805F092} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {67EACD19-0CEA-4127-9842-549AA6FB84C9} diff --git a/tests/Content/images/lottie-base64_dotnet-bot.json b/tests/Content/images/lottie-base64_dotnet-bot.json new file mode 100644 index 0000000000..b8c6e506d2 --- /dev/null +++ b/tests/Content/images/lottie-base64_dotnet-bot.json @@ -0,0 +1 @@ +{"v":"4.8.0","meta":{"g":"LottieFiles AE ","a":"","k":"","d":"","tc":""},"fr":60,"ip":0,"op":239,"w":1200,"h":1200,"nm":"works","ddd":0,"assets":[{"id":"image_0","w":93,"h":51,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_1","w":94,"h":94,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF4AAABeCAYAAACq0qNuAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAQOUlEQVR4nO1dzY4cRRL+oqbN7gHJfgN84IDVRh4OKyHErvsNtuGIkGgQD+B9AoY3ME/AzGXFigX6DXa4rbSrpb14GPAF+8bRvmGZqdhDVWZGREZmVfd0jwe0IfVU5U9lRX7x5ZdZ1dU1hEtqi9mDfZzxdVC7D9A1APuxkEVF7v60AMD8GEwrZn7Me7SaTH5eHR6/9vhCHR9p9LwdCLaYnc4aYIaWZiDclmXsHcAR81SHAY4FADMAxqMWvAJwfMa0/OyfNx7uqAtr2XMDfjH78VqDn+cEmjPw5+hQwSO26LMICEvgoQMQNmn/ETMv0fLhX/81XW23V+PtwoFfzB7sE/gOgedEdNXzxDrFboJTMEQQBMAqAFk+M5jxiFvc/d0vTw8PVxcrSRcG/Iez01kLOiCi2+HM8eQV0IOx2dHpFAS1jUCzSsf9FIAnAJa8RwcXJUU7B/7D2ekMRAcMum3BpoIHVcaLDCsvQAekKz09yF0dF/zQ5tHPz57eWe54BOwM+MXs9HoDOiQSgBuwPeDJEXm2Al/Q965ul4jgwoAspMcFv0s/AfHdz/49PTgHBFXbCfAfzE4PiJqPioDHra8x0ilf30UwavruMTwcm4HPTjDwiNqzxWerV483hKJoWwV+MXuw36A9JKJbAWwiKOAj2HqTp4V54GfyAg/4bicDFMPgp3wGgE/+9p/pnY2BcWxrwH8wO10Q0V2ArkawBcMl4GoUCC9qzljwR+l7voqpgh+AtuAzM7jFvT00889W25l8twL8+7MfDhvi90BUZrkjO+6qZk2NtywP9f1VjAN+m4LFbcozkhNXP4x2/vctSM+5gO8ugp4eE+FWBrpgeRYIcWar89XlpKPx/vJRgIwxWm6B9iVHTNjvf76aHm4IW+jqZraY/Xit4afHINyipgD6CJ1fS+MV8GFb1ncpPWPBdyXHjIT+88kX/91c9zcCfjH78Rpxx3Qi6oFGHXTB8EhyZy0/ZnLVshK2GuQ6+L6OQwI9JhjMR198e3OxCYZrAz8a9PABEstLOm9ob2WeFdK5vof9QfA9bc91vLrKMaxHy3z01QbgN+tUtqCjB3wM6LE66Q+I+nICNUDT5HWogahDWZk8vyy3fkH45fsPdax3x07V6wB87+2b3x7sFHjip8cAbiEAirwjMk+CjghgACyBnQFtPo09NgYrD6YKtAE/AarzSkBnRIm5pgLoo/n0ZLET4Bd/+uEQwK3osPSTjKPQAEimBYZnLKsEwGOkZbg+hweqyTMYKv9lnQxo3d+w0xB/Op+epC9rBmwU8Is/ni4I/J7ypcocB/S+V3V2CzkJH8luZ+RYQBMzXaxSfhwtFdY7QKtqpNsm4Hi+/821MZgOAr9448E+iO4qQG1nCoHQTK3ISpPAha3TIGm8rOcELddrP08SpMp6B2h3GRaDxVfp2QvLrQCPvfYQgP7CwjLb9iEwJLKPEjuyAJECuamOCP+4MTruAZ1ANRKUUdyLDvI8AADffnt6f3B9XwV+8ebpAaKua5Bz76EDEUCX7DGAZOx2mSyYn9X1L9ys7GVuymBYq+WLItlHGx8GHcxfOb1ew7YI/OL10+tM9FHJCRuI0CE3EAVmeqA1FY23+l4kAwb8soAKcihQPWDJNOHhA75KnVIUrQh8O0F+YMXxErPG6z/5zG7kcaRHkUTEGTkl33yJTG2k2rK/ouOS3l4aAMC35ze/nXnYAgXgF2+ezgi4nQ1PD1Rplc52H9L5/Z9RUhMDUZpc7bnL/iosPcaW+jVkpg4xHZaqusC3LQ5ymuRO1AITx6T5RIIa0KuAe/KStWuBdnz3+lPLszamjraXShdWGfDvvnk6Q3igaGyUHYdyfbRgldb0ei2fjYh4ChPoEtAVH+2uVQ8xQDPueVvbRlfGB45HOfDU4iBrLaQLzM/qVY6TjJSBUJOuw3BPkrLohrEWg5TLjZcWRyp3vW0A1garBAcKrFfAv/PGyT6gH58bbdXAWOQpqxb0v6bvEuhsRIni2PbYEVtMU96vwWO8U3C2rlfAN9zc8RqyUfbOOcgcKxUOYiV994AedKiWPieQG9gtex8nAr+YfXMNwNzTLWvxK71iWtR1tnY/DgKRiGt4GKAvB5Brm2V9BP7s59/PIW8NxAP0dsOzjkr7gaBLCWRn6zhCc5mKwLfE87xyMq4Vrmu2Mafx+GBBfEZjV86cx9ZxhK/Ob3wXMU4azzSTTdlttcnwhXNM5/557ck89yu4lvPze0G4tIHRRg3Pwn4DAO++fjqDlBnjePxCOaYT0H6gOJbFOpwDnb64TicsfbcpHq0Qjjm92yQwFxYo1oxv23Z2/jadNJvCGAnW9aCB1d/sF77lZ7jB3cjPMX7XjhlvL4W7lr3UdDJTtU2HuFMvlxb0oLJ4tMIpt00Z9FmOtCBZwoUxIzXLGxj9MjEqHnsdySd98jYYepIOrdg8O5GPOM52gMSBubOs2+R0fDYi4ABQIoQDjjc3WdCzUWW21o9MDo1R/yO6yTt/CAt7BthZulWAjUU929QCntOBRH2aSDUBMIg98FUlFTj7ABJEOmvHC4KXX6pX8clNj7MOeG7pOu3ljTExKDCSASIGQwNLRDIOuSOStQF8kMyGiqw3otLp+m3+QKmSGxMIJTNjAS+NmiEbF4geeOJ9j+lkBgBzuvQvnohMtmR9yTcCKLK1hHpgPSvZScNbgxxPZDJtILR02MAUhpxsSPk4lv58FQAmxHQNBJ9tis65P0Fu9Mkpr07pOEIaOWIQpNoFaZOaq/U+BSOx3puIzcd0x1sl2SUsq2OdRkbafHqyP2HGfup332sJBCie3JWbbKhoX0jMHVG24DCcuynAkkv1LYINBXAmMZn0jBsRWb7MckeNDtg6NgmtMdLcqEaNJzfQ5SXWp3wvr8uP88iAaeA5Y78/4eo8b0RE2VHsHpAVOHlmdNSMgBcnoQ057BW4trERrGcBdGpCNM5SfYSeeXInOwYDeNgKgIdI7AXCdje/UrZ0LwyHkcbAy5M8V/eeyaDhsD4uJQO2ASSp5X1NxXDVNDt5Ojvs5MAL0C2zWedB7LJscEwgZLVN9EXYpDuxWF87q5vMDOvjWl5M0lKeQh0OGWF5FDI9sHNd0leNkZH6905yBLhan8mOxd1D2JgTwDVJj0nL0N8wBe/XYL1ks/BL7InackR4F2z2UJnFcptYLgGUTE+Aa4mxE3EWDJnMyoVjsUKhDxWbpJ6MY70GNZcSO4l2+yJfxDCtblAPQjhOUI3tNgYl/2Wf9FhJjC3LRgTnx8rAZa2Mt4mR9DLr0Q2NSH5GkhyugO9oPmTzMVugVLieYJHOge/PbkEvMFtNoAMgD8nOujIDiOWkBNplfd8rFpNoB3ifF7KcoCkvU2tlk4fb0cbOvjO52hGgpcf9+fx2AjHOVhO0eMwNqqyXzXuX/rm0dDW8NXqSHtmaM5f65NJg92lPdgbf1MHpGLvEXDsQG1jDDVapNa6cOHfcTlxeJyHz7L32NtyDZ7SFb5zc+gU/x/qjwWOdhiSGDM7W2I4rwE8TtPS40+reek0G9W2LFU2S4i7PXp0SKC4p3eWj6IwnZRzrGmO1iYmc6Ynl7gjIQMwDlJEvNph8OC/bPz+Z/jRBc7ZibsR1TNJxSughrttJygX1E2dyi+JfxPpKIyyyNghe2u7KQFjAY54uT5qfQLejuiQx7oja3B4BwOQX/LLa4xdUibyDKPOk3mfLRFVboMfi5lcsQ6b/Cu9Cv9iUDek8YCZR5KC7MgpdP5OYc7Ad6KS96V4BxY/sxOJPNvnQ9DU/1NU/QVd1hF77v7J2PuaYev3CUwoG9DAypK5XJWZjvDsj4hWQlpMrJrwEyJtlPQfZrjj0asVjvndnspSM2czZVKArmE7LtGI69+0hbSN7HeI4+Z4U2TlhU2uBY6B/yoBbHGe3RgNrkDroMl/WLbCsWNbKTuV5tp5bJ+y3zmpH1dsMdCkxCp8NbXn/1QR8e7a39CYS74RDQ1nlZyCOlInWfPr81gXID2oaBXlAspWOAdmXovODDtDXYa8BgOX3Nx4y45EdTiUGVIdjGzoktD+yshCEtjZazPmUztfrewGugS6JgxSHWPfcsIPjj4/F8/G05IJTNfDLk6sAt8TqjOWSwebTMlpzTCuO9SfuNX2SoDtYnNfas70ceEb6eWWItAs+bN5QZ/JyT6utjFSD5IEtRgPMeSybLbgQ/u0KdAD3lt+nF8lF4Jcn0xUQ5KZ30gF/mOF9mQErSBC3jNYJkgpGQeNdX0bJVHniRSEYWwYdBP274cYU3g0nL4HvMRyFMi8AKggKuGF5aEP9kXNCaSKXKxo/qNsFHQDaK8/KwHeF9ESB7y3T1BCts2wYHMtsT+O7cnjzgthXkuKtnFpdXhq12wYdwJF9V7ECvr+KjRNADqTPDheILACcAVUGxs9vnTzY8xjAla/wyeKt6bdpfLZ3YPOy37l6lVyQFQCsO1Rkpi8rmfauofFRfhjZqkeDq4PiTcy7AB3AkZxUi8D3lY488Gv6noZpHoDa1WSabIc/sZ7U+MGr3/oFmx0B2zaPyEDhXQZ85dmdoPUqX3TOG7J6ZKTytiYjfVmNrdloKElJheFDPu7IXLYDBeCXq9ceE7V3vbKi8668hCHMeZkH4EBwMpBbu/73V0fF9XwYkTsxelJiOzDwrfNb0/sPge6uZbEBQnqAKbwbIKZFHdj9/HGOga/A86v2HjUWhRLIuM9QE6uttwsj4o+/vP/qQak8f4RPGBMviOkf1TpsH+0AahAyB/B7NMTDVGOwkCDLNmUFltu+wkUB3tu9GujAwDvJuluY9MnQWXK9NcO9tjJxZKf0aYfqlm7CSdm5AGPQYqjO0OgGALw1vb9CeMPqSIuSImRIndA+TjLkDauNn8cs9mPWhRoBf/ny5KY7P0qrSk0wPtub0167Qv8zklHHCH2NX2uJZ6H0U2ryWZ5Km4WTWPm5aLCFHY0BHRj5ptXl9zceMrXVdx3UzF2ZqHsuw2t5Vd4aCbErpOdj97pl+DgbJTXB5tOTBYE/Xd+nEY6M8OQ5gjpg9ITPmv3Smt2ztd6mvTyZHo6ZbDexMZPr5TR6wsBsHdCBNRkf7K3p/UMA721y7G/LetBP1v9njRsBD/wf/POADqwpNdK+Orm5IOKPNz3+123nAx04B+OD7XLCvaR2j8/25utqurWNGR9seTI9ZNBr3t3M36Ad8ZVna0+knp2b8cHm+99c615az7e31eZlsrFXpGu0t117e3r/DoMO1rnKveR2j0GL8+i5Z1sHHgDmr5xe796f/mtmPz0hau8O3WXcuPVdNBpsfvPbWf8q7+o9/UtoR3y2d7ANLS/ZToEP1q98DnD5A7BzwINdCPDB+gDcwZq3mC/ALgzwYBcKfLD59GS/CwDNn+MkfI+Aw/bKs8Nd/2N0z54L8NLmN76bd28g5Tl2LkX0NYGX7dne8iLZ7XryPE9ubf7K6XXstTPqXpjWfzYeEY8ArIh41QLH4ZcYl8UuFfAlC+9eJ+BFBl4uVFsB3Y93Pz+Z/nRhzm1o/wPG7agWmLPcLwAAAABJRU5ErkJggg==","e":1},{"id":"image_2","w":195,"h":352,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_3","w":41,"h":68,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAABECAYAAAAcChxyAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAFNUlEQVRogdWaz28bRRTHv29217HjqE6jpKiVohpoIWGD6oorEr5wQahs4QBHI3FEpX+Ckei9IMGpEuEfoFsOiBupxBFUR41JpRIloVTQVpQa2iT2eudx8I/YXnu9nh2b8j1Yu+Pdmc/Oe29m3s4SYspZ2swKw3cYyAGUPfyHdwgoSd9w3VvLO3HaIGW4lZt5YlEE+LUIzVxnkkV34+U1lbZGhnSWNrNkyNVocAFdY8sruKWzj0a5aSRIZ/lnhwSvApwZCa27yQoDebdsl6LeIaJe6NjlAgl5NR4gAHCGwDccu1yIekeknnTscoHAXypzDRBLcd7dfMkddt1QyEaA0Pd6sALNRzJ9KGQzSErxTRyqXba8XFgwhfpkM4rHCQgAJ8lLFMMuGAj5tr1xUXGYURB/5KzczA/61+xX6ORuzLJHRYC14xgmIZUWSE0LGOaht5GAiw3MRoZsdL8+MxsmYW7BxNFjFlLpgcbLXDh3+8pn35z+IMDTW9AIFn9bF9zCcQvzJywYxvDRzquhfumrrNVbHngsMuRFHYCZORPLr0zjmcVEJEAAsBIwL5y7faW3vAvSyd2YBVCIC7h4KonsUjIyXKfSGePd3rLunvQSThxfNEzCC2emMXesr6tH0lRSzFx4Z+uNzrIuSALHMvXzdiosMCLLAi51nrdrdJY2swDOqFa8eCqpBRAAkjPGSud5u1Zh+I5qpZk5M5aJe2UlYH745i9t32xDMkgJ0jAJi6endLD11Iv3Wscd9lGbAheORxsDR1VyWrzaOhZAYzmmUpFhEuZPBMZeLUqlxXzrWDR/8ioVZebMsfRiSy2/FADATDmVSo5qDJZ+EoJfBw59Ugly5oihDaifhEmngEPIk6NWMJMZLyAATCWFDQBCNWhS03oG7iEygRFS2l51LljHpVRazAKAUI3sSWoiNoujYmF79qmHfPCgXhCqY6Rf15+kDZIAqG+GNkz7e1I3y0Apm3v/yf8A0q/zxEBjBc5f9z1dHKESAI/01rVTlYe+Tpa+Yl/+KIg48hvXXtWqEg/v13UyBfTFdy/+EHucvHenBt8f73AUG7JWlbj3a00HS0BeDXUAENI3lM3d0oPfPTz+W79/1j35GAAEDF85cDq1c+tA+5BU9/hPABCqG0C98uuMrfK+VlDf59+Atk9SRUulTVBdpveq7AKHgRPbL1vy64ytjX3cu6MhmNi4CjQhieRa/Bq79cedGjZ/2lPuVa+G+uffPrcLNHMI6RslEvrn4VpVYmtjH4kpgYUTFo7MmUhMRUs7Dvb83dZxI3Geqq7BG8+bCKABe3e7irvbVaTSAjNHDBgmId2TcR48kagdSOzvSfxTkZ+0ytuPdd4ur01uS2S42Deebe2Tt2ccAg/d45ug1js38tuQ0jeeGkgCVjvP25BN8vUJ8/SVtLzVzvOuBQaDLk+Upr+u9W6Gdq+CrJqra/ZRFRMHOqoLsvkEq5MCCoqu91tLBNaT7Iv/zORMstivPADp3lreIeKPx04UUP9eBAaszKVZvzxp32Rg4EZXX0i3dPYRSyqMjSgg+jTsO4zQ2f68veECeEs7U7fWr5ZXQt9HhSZibHkFALth18QTVRjDLRYK6ZbOPmrslI3HP5mkE+VLq6EprVu2SwzkdYMy6P2o+VXkF9+OXc4RsBb/2wyqMElnlAQw8ssBt2yX2KplAbqugtbUOvsiN2qGqrSF0Px2rYjI+z9UIXDx6/KK0mwWa5+j8amiLACUD7oBVQBeY5Drlu3VOO1olbNyM6+6eRWmfwEoLsOjMRWeQgAAAABJRU5ErkJggg==","e":1},{"id":"image_4","w":41,"h":68,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAABECAYAAAAcChxyAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAFM0lEQVRogd2azW8bRRiHf++M13ZSNw4GKjhEjWhLP2xIInFBQmAkDohKsCniwKk+IipBkPgDfOAPCAe4gIS5cWoWDogbjsSRqqkSE6pGba2oAiIUOdDEsde7LwevXXvttb27Y1fiOa1nJ7OP3jc7HztDCImeLi0KcBbEs8wiCwBEdhFMFRtUNErpjbDPoBByOQLnAZweUrVMwOr1UmY16LN8S+qZzSwxFTBczk2ZbbFibF8y/D5T+Kl8JbOZJ6af4V8QAE6TsNeW0yXfER05ksvprQKAq34f4PHYddbqurGxVBmp9iiV1Aq2ucWamR1FdGi6nfSoFgSABTK1kVI/UFK/+JsO8MdqnPpy9UpmMz+skme69cWbs2RG7wOcVGnVDyZ+3dh6oeh13zOSZGqFSQgCADEV9MWbs173+0rqmc0sgHfGJdWH06IRWfG62Tfdy+lSEeDXxmUUjQlE44TEjOw0qRHzG1/+dP4Xd/2Iu0DPbGbB6gUTSYknntaQSEpEY31jE/u3YhUAnHXf6Ek3scirlEumInh+YRpn0lNInYp4CQIATs7KMx++efsVd3lXJPUL2/OApSSK0ZjA3LlYd0pH+btp+RmAbGdZlyRJ2/Of1w/JVARz52KQ0v8k6+SsfNVd5ko364HNHFKnNMxfiAcSBAApiT56+87XnWVtST1dWkSw2U2X4NzZWJgmAACxKXG583dbkoBcmIaTqYgSQQA4MSOfufbW3XbAOtLN2aCNyghh7pwawXab0vqgdS2A5jgNYCFog3Nng70kg9Di4r3WdTOStVg2aGOJpEQy1TMmhCY+LbvTLaS1GLSxp57VVDj1oEUR+fTduy8CjmRrKeqXaEyMJYot6nXrfaD94vB8kEaSKX+jiV+ERi8Dj97uQP3jzJPjiyIAaBqdBwDhdOKB8Dsu+yWiURIABMj2nBEPIhrztWQPRGxKTAGAgCWDScbV9ouDEGG6n0lw7fKdlfHnTAH/b0mrwSo9PIlolAgsWT20Vbp4IjXxUqh0T0LUtuzZUJKH/1iqXDwRUlRCSe7vmapcPLFM+1dhWzLwh/fqoY16bbwvUMPkhwLSGulrqxd/7dZV+XgSup/c3zPH/gIRACynt0LlLJGUOJOeUmPkIv/VPDmRpIMwDT08sMaa9la6Q+9a/blbx/5eI2wzXdSqdhVQKAkAuzvHSkUbJh8ArYWYIklArahp8m2gFUlLFJW06rC7c4zdnRosK1wfatbYABxJ4/eL9wGUQ9t1sL9nYvvGUbioslwDuvvJYjitXqwGY3fnGNs3jvD3H6av0alWtatf/PhcGej4iMqgIoHHsfOFes3Gg3s1PLhXw9QJgcSMRDQuED/RO5YcH9qoHtqoHtnftcoeLZy1ugFT+2Yckp1UHYlhsC1+aF13LfmW01sGJrt/4wEdrJXS7VVsV7zZFoWJ+/SFuzbuuySbu/rhhkgVMHGh83fvPg7Zgc9KKKLs3gztkbQjjdXHGU0G5d1lPZLGxlLlMUazbJTSBXdh30nv44pmvygCHpLGxlLFOfMzSfpGERiwfGgeNqL1sSm5YOKc172Baxy2RG4yaafPAx1vAJqzI7Ypp1rJxS3W6vlBFYauFo3tSwYBnyhT6oIO2JJDDzGNtKR1DsN9q8SrDR0wkHXmsgMZed29Vsrk1EXUERzx2KKvjwPXS5lVtsVyuJeJ1lmrz/s5Vxno63zzYJPm93hYmUF5r75wEKG2EPQL2/Mi0sgxkw7vXd7vGWQEkWuhdJ/DOfTUhEVFxVFZAPgPgCmz6jQxijgAAAAASUVORK5CYII=","e":1},{"id":"image_5","w":76,"h":117,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_6","w":504,"h":509,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfgAAAH9CAYAAAD25W7MAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAgAElEQVR4nOy9f7Adx3XfefriASD4QwAlk5YoawHEW7YYKUswFSfZbGqJOJVs/kiWqGS3nD+S5ZNLlCk5LkGpTaLEkXXlrKN4d1OkLP9aW2uBjp21NnYCRYptySsJTDmSLdshKFsSnTL1APGHZEIiAOIH8R7eu71/vPtjpvuc7tM9PXfm3vv9sC7fTP843XNxZ759TvfMGAIA9J5H371xhGjtyDRhZI4R2UM0qJYyx1XGDNWrMfnupiV7pl7EnDMDe26yv722ffZdw6OXVO0DAOaCiRcBALTFo//guWPb1h4aGHuEjDlCRGQsHR9nHyFDh6unqfE26pjQGW0CJ7wJmhUrC+WfImMvWWMuGUtnxyXPEu1c2l5bO/eu4evOBXoJACgEBB6AFnn05Mah7bW1Y4ORPTIamCMDomNEdIh2/x4kItZj3t3QCbsR0ieZMVGXq/uV2XKRq4hQ57wle87YwTk7sOdotDsA+IH/7Q1nwtYAAFog8AAU4P0nN46sra0doREdp7E3biw9MC3ACW3Hwp4t6oGrRs4AgKlw2dLo7MDQWWsH56zdOYspAADSgcADkMj/fvK5YzQYHSNrjhlDx2jijQdE3DBptc0UYQ8JbEDwBXPkinqKSKeIf7C+rt55InuOyJwxA3PWkDn7doT7ARCBwAMQoCrmtCvkD7AiKoi7TvAbCnuWt54n6rmCnijkCZjLRKOzEH0AfCDwAFR4/8lnjw9odJzIHDdEx8jQwZpn7Z4xpb32EsKuFHW2TEzUFVeMUmIeXDAY7sB5Q3TWkjljaXTm+4ffdrZZTwBYTCDwYGV59OTGoS3ac9ySOW7IHiei+4hcoU0X92LCLqQ3FfbSot5E0PNEPKchesKSPTOgwZm3D193JqdVABYNCDxYKd5/8tnjhugEkT1u7K6ge+LnCrDGqw547anh+GLC7nQyJtpaUc8RdJ2Qp4QHGvMEEZ2Ghw+WGQg8WGp+5ORzx9Z2do5bY44T0YM1MRSFtV2vPXmePUnY07z1JFHXzrdHywkF0pJLcpmIThOZMzfoxmms1gfLAgQeLB3//O999YQZmONEdMKQPUxEgpfO7SeIu8Zr14bjE4U9KQwf8tYLiHpY0GOhgl5ehJ4isqdHZE/DuweLTA/PLQDSGJ7cOLR/Z88JIjpBRMfJ7D5AhhMxjbiX89oV4XjJaxUE3zehF3aNt95c1OVGsy42XV6hLBERnSeiM5bo9DuG95zusDcAJAOBBwvJ8OTGob1jUR8QPTjNYD3omNj3x2tvVdgbiLpK0HPEXDOY0NoqiOWTLxPRaWsh9mAxgMCDhWEm6vaEseZBTnzjwlvZzBD31rx2IUrgV9cJewlvnRd1fvSgupCE+pFDiauXoOSKahB70Hsg8KDXDE9uHNq7tecEGXvCmImnbtTiy4p7LCTPpak8+bDXzgoqJ+xsehlhbyzqWi9daltDH69K4YHAZUt0emDp9PdB7EGP6OOpBAD987/31RMja0+Y3Xn1gzVRThF31mufbTSZb+dC8ileu96TZ6ICzk7TMLzfF994UUFPuPL0KEQfLWyIzu+K/ejU27BAD3QMBB70hvc/snFkNBicJEMniOjwJL0zcQ9FAfzONfPaWxD2eYu6WDZylVFdhOZ5pVKoe7TIboGnjKFT+0abp96CW+9AB0DgQadMQvAjGq0PyDwge74lxL0imApx785rN357zk4rwh4T9QKCnjsI6BWCuodE31p6HCF8MG8W6bQCS8T7H9k4srNnMCQ7DsETBQSyXXHP8+SNu8m0GbDJprUn7NneukbUpTYTympo7OmX8MwTK7tJhuj8yNpTt9itx+DVg7aBwIO58sPv+Oq6saN143jrsuj2TdxNPSvHa2dF3LjZsrhqBhRifxTeeqaoNxX00Bgk0wJDhoTb4G5SU9Uka+hxInPq7e/Bs/FBO0DgQesMT24c2rM1OEmWThLjrXci7iov3U0zYhnuONr22tsUdo3Y5gq6dJzJhuZGPCavEn1Z8J+yZB57+w+97lRixwAI0qezCCwZw3dsHNszGpwkQw9N0roQ99zFdPV9424y7XHHIdisFGpP2OvGkkVdajuYEMhu6OKHjrsINtW/D7voyoV41d3L1trHyA5O4Z32oAQQeFCcf/b2r56wdnTSC8NP/zfe74m4x8U+IO6cZxv15BmvXSHsUnt+ekNhbyDqct/jl5rWBbwp6gEAH9MP1nUyR4Yepx0zhNCDJvT5dAILxg8/srFONBgS0WHWG144cTf1LIWXzulam147K+xctIAvwvZBk+8lJwh674U8lajwJwp+PeOJkTFDzNODHJbpNAMdMFzfODS4hU7QyAxpYA4T+Rd9WYjH+04F9Vz5HMRd9LCTxT7Pay8i7LneepKo84Ubizl37A3MSbBi22RJfVD0/Ti+QuyfIEOPfd97cJsd0AOBB1kM1zcOmX100hhzkogOep73sop7VGw5+wqvXWOXTZt1Xi3sLYp6lqCHBiA9woo7usp8lWSxP2/IDN+GBXlAQZ/PJ9BDJsJOZE6SGa+IJyIyhhd3d7/P4l6147SjtV2vNh+vvS1hV4t6ylVEijKkMDcXPrFqgg0bCxmExB5CD5RA4IGKmrATHax767woyoJOjjAFvH93v5S4s23oxV3rtXPHIbbBpPltFRT2kLdeStS5fkbKFyiSTO5tbsGiyvIasQ949RB6IAKBB0GG6xuHaB+dNBNhJ3KEsiKKlY2guNf2l1fcm3rtJYU93VvPFHWtoIcGFz1FuShOLqIpFxL7sFd/ngydxBw9qNLn8wl0zPDhjXUiMyRTXxWv8rxzxN2137G4a8Se+z58+5E0jdfu2nVsNRL2QKGoqEv9EsoFuqKuOxdSvfWEutqQvi/2Cq/eYtU9mAGBBx5TYR+/0Y0PrSvF3d3vlbjXpDksvIzdehGFuHMiFxxAzAy2K+wmkMegEfVUQU+4ErVx0cp9PawqW1M++KYaLtsG8ojI0hNmNDqJV9auNhB4MGX41o3jZMyQiB6YpInz5op59yLiztprWdxT7FYqiMLOpXGiK3Q2PLAQ2mPa8PviCHsTUU8R9EBm8gWpyRUscWFdyoNqglmxJ9+GbEnG5PD94yM8MGdlgcADGj6ycYR2Bo8R2Qer6Spxr2wEhXJanxHnDHEP2ojanKO4c8LnpgkK7p2cWnFPEHZpsFEtoBF1rfArs8Ijlbmge+ZsjuhrbrdL9+ojQj+y79uHN9itHBD4FWaygI6sea+X6VzYVYviAkIZqi96qC2KOyvIQeF12zGMbecwYvZqaT0S9hZEPV42/VJU4uKVd3dc+Ib1lIfmNBb7NKG/bKw5iRX3qwMEfkUZz7M/RpOV8Q4h7z0q7u6+ZnAQsucU6LO454m9IO6Zwu63KQyMmEpsdkzUtYKuFPOUgUNxUkSbKxF+/0wwMSb2Ma/ecgb4bj01InMSC/GWHwj8isHNs7t0Pu++AOIeFOJUceeENSDukuD77SmEXRJ1qT2hXTZJIeihY+klusg9ScqaLPYZXr0k9Nz8/L6dzZMI2y8vi3BKgQIM1zcO0drgMTL2oWBBRyRjAtmquDuJnYt70fn2WSdTRFzSzGLCzrUVapMtwzdaWsy1A48pWu86FZXo8wobW4DXxKtXCv1lsjT8vh+65zHeClhkIPArQCwcX6XRLXGiABvdojqtuAfbcu1XexHoL7PfSNyD++ninizsTFm2zVDboTa9Hb9mE0EPmJ0f4an2aD25rm9Ys9I+5NWLQh+Yo0fYfvmBwC8xu6vjzSkKhOOrpITmZUF2bfmDA5XnXUTcKzbE/mls6sU9LvbGty8ch7cpinsLwt5U1JVXFrG/fUe6/1woW/kTzVR79U2FnjkGO6IP7LebQ4Ttl4NFPLWAguHbNobs6ngJSYRLhuYFb5S3lSfurA2xfxqbgeN37Tr7dduzimKfFW347VTEvbCw83nGTxIrCKaX8aqj9faD3r2vuKEQfY7Qq8P2ROt47O3is4yn2kozXkR3isZPodNSKjQ/t0V10cHCAoo7J65iG3MSdu7AhP7llFlqYl5+gth3IfTG0kd3RuYkHpKzuKzqqbd0DNc3DtFeGhKZd6bWbRSaD4ha0Xn3pMFCz8SdE9sEsffb4I9PtM3ZZ9qJCbta1HFV8VGKfZLQOwmS0OvC9liEt4zgVFwCcr12IvKEMiTu7r4soCZgt/ZHFucccQ/1uy1xD9nlxD02UODSmAy1184JOzd48BsT+8Q2gSuJngJiX1LoVWF7S0+MRmYd3vxigdNygWnitU/oQ2g+KO5iH536lYLdi/usUpK4c8LrFGbFVCvsXJuC0ZiwQ9QLERL7VK9eGbqPCz28+WUBp+iCMnx44xiROU05XvuY8qH5iPcdtMV7p43FXdVvxkagv2E7srhrxZ61x7SpssvYjwo7RL0bImKv9ui1Qq/05r1ylp7YN9o8gZX2/WfQdQdAOsO3bQyJzJPUQNxdWKGMla1X8TM14p5jy83OFPe6/X6Iu2Hs1dMqNjXiburp0+MxplaSSVLlgYJw/6bBvFli7Z/H+bcKDiKZtPqvgv2dPbA12H/u//pnL5yIHxToEpyyC8TYaz9FRPc1tRXy3qOizG4bx07tT0TsZxcStk+K+qxYqu21JO4RIWfTnEY5r10aqHBi77flSYR4FRCfggfmBudl72bkefSNvHl/Xp7I4HG3fQan8IKQ8jS6KI4IsUKnEPdZ3YhAM7ZKiru+n5y9QuLOtMHZjdsOiLvbBpfGCTtjTBL2kOCDDpHC91x6RZmDQq+Ym1eG7M+b0ejE24bfdpbrIugOnMo9Z3ch3eAUOe9qb0LuwjpZRP26McEM3e9edFFdj8Q9LvbMYCdwHF43xTQj7UbTQc9QC318IV6eNy+usiey9n3f997XD4Wegw7AKd1jSiykc+ksNM+KGiNomoFCpVJQ3IO2A+KutllK3CsC7J6Rrn0uzbXJ2XXKxdJBz8kQ+uLePCfyhAV4fQKL7HrK8K0bJ6nwQjoXV+zqicQLR8iOZ1coqxR3sZ3Gt8MtqLgbIW2WVTFk6unucdSLgUXDEL8gzzi/hUlBcn8jtSpuJf434/7w+N/iA1uD/ed+6p997bj6WEBr4PTuGW2E5Cfkeu+ykDonOSPQfF1G3IP9c20Z367YR8cW0+da1Q7EPX4xdY+BsccY4uyytsHiw87FF/Lm/Tn3+hPweE+eRta+7+0I2XcKTvUe0UZIfoooxL7IhMSyrdB8irjr++jYalHcRbEP2WHa8WzF7DMNQdhXF3bVvUboNfP1ovCLi+9oRPTELQjZdwZC9D1hvEq+tZA8f203gbxQPT6PE8pakuS9i4LsZsfFXd1huZFWxN24dph2WFsJ4m6Ydv22wTKjD9tPt2YboQGvsz9pq1qQey7DgOiBzcH+cz8zfO5Y2pGAEuC075jh+sYhWhs8RsY+1Fojjtc62/YFU+cZ+56w7HFX6/LiLgpmpK+erZBt5Yr5tsTdbVgj7kFhd4xIwo4zfIXRhO25W+oCnrvGk+dC9paILJm3vP2HXndK2XtQAJz+HTJ8ZOMI7ZjTVODBNSHK3hYXEemgTb/uXObdteIu2ish7hUxDg1KYrYde+4xiTbBysKFzit/SBWyj8zLa1bYWyKyhh5/+3vuWdf2HTQDl4GOGM+3n6ESD64JEfCI08V9ZkQn6GFxV9mpVAoJeta8e9/E3T1uLg1eO8ghwZtXz8tnijwRPbV/tHkc8/Ltgzn4DqjMt7cr7lS/1hsuVRAnfjtN3N2EYGhe6rfyYTa83QLi7pj3Oq0Ud+P2WTiGWtNm+sczwIq78dMAIKLd3xLz263/tg3zm5sWdTb437N47tXbuw/z8vMBAj9nhm89f4rIfHgujalEMFwtZCal+WAeI8K72wpxD7UT846DtpkKwsVOI+7e96+1y9hyhZwbPADAwS2E44R5vFXbEEVeO8Cu5x8cDQZP/tQPf20960CAClwW5sTu/e3mNBE9MK822RD2nBbWeSInXQSCdtL6WrdVqautP92fFY5d5LLEncL7fjuCLab/AGjR3N8+3nI2FIvvFPfKV+x+4JH33nMytf8gDi4Pc2Bei+lqiCKaP/ceFWlpYEAkDBrC/Qz3py1xnxnrXtxNPQviDgoTFvlZgbZF3lp6/BaLt9KVBpeIlpnbYjqHvnrvulXzcXF3xVElzqwYJ9RX2Wtf3DmxByCbkHdNNDeRJ0tP7bdYfFcSzMG3yHgx3Rmas7i7wiJlhaq5qa7AVbc5MePEXRQ8yU6gb5w4avunFnfX5DzE3cw6NN2EuIM2MczguXZ+MoNe5blV/60z51fd7n1bZv9ZLL4rBy4VLTEW9/kspnNYRO/d9Vx1fVPWFfpatxW9+FT/yMfr2E+3Kdip9RWAdsidl2/kyfs2Lw/s6DjeL98cePAtMNeV8i6SN+vvKvLKiXvMe5dsqu1UhdEtLtSP3Q4HcQerRvhWOqM4F/j9oCfv2zw4MlhhXwIIfGGGbz1/qtXHzkZgtcy4Z55W+Frul7fvNyyX9TOiFx3tCEcadITKMXklxN3E+g1AYdhb6ZidHJGvN+Rv15wJaz8MkW8GLh2F6OI2OA/R205YOT+t54+ydTbMpMlZtyThq9UVBE5lx6+rF/uoNxGvH+qb11fOvizuOENBZwQX3+WH64NvoeND9x94O26jywKXjwKMxf0MzfM2OAZWZFqae/cEq5KQe897qF+inZBAp4p7tI9+n4P9DNlzbYhtANAh8xD58Mr6yZ/H3/5ePMM+FYToG9IXcXfDXUbIClVzFTQkzNVt4yYktx1XMrGEQpCDnneiraC4a+25Nrg+QtxBHzChAawRftfxAWvGIPuhn3rfC6eyjmGFwWWkAeN73E9R1+JO0klYOXmi3iyleeFevYg3GxTPsPeeHJrPubBExVgh7oFj9+0FxB2AHiKG0lM8eWeVvujJy/Yev2E3T74L98qrwOUkk64eYCMxux2uLoChkbUo1GphDote7m1xpR5okyLubF3lccb67LcFcQeLSdciP95+6obdPA6Rj4MQfQa9Ffd6qrfpCkqOuPA2eO+9uu0KZrWCZ1MwE7OpOz5H3Ll2hPZqwlzNgriDFSEpXE+V/cBvnbPBGpol3XeL2X/m0eHGIWW3VxYIfCJ9E3cXVkhD5dzUiPcet6HM0ww0REGPD17E43PzFAMF7t7g6DabB3EHi49G5Ce79YqK7ZD9+gDivlsIIh8DAp9AL8WdPVF4T7NX3rvUR8FMcr3kQYNQ121Xd/Fh7EHcwfIQE3n9eeHaSxqEQ+QjQOCV9FLcKajvte1I5Iva8t5DJ3ZI7GJCKtl0y8Tm3aV+1+1GxN2tD3EHK0C2yFeTNedq3YybCJEPAIFX0FdxD4a5lPXa9t75Zv1GdQMGf3SvuggIXn9o0DDbZo7RtRW8mEHcwfISFHkSzgtDTinOnomcl7UkiLwABD5Cb8WdpBGtf/Z4XnPMXkveu9Qnt0zuM+yb2IldeKrow/SCuAdsA7BoyINdpcgHTgjdUzCJCCLPAoEP0GdxrxEY7HJlp5vSaFmuUkloyXsXT+jwwMUr4hxbyoDF1P+nfNmNk614sx0AS4F7HoREflZEMTAP1OXrQ+QdIPACvRd33n33NrWCEjOXFAGg4EkYPrlT+6jIE8sG+8aLu9iOJqKQ2lEAFgVG5N1t9vcfHawnD9Ah8hUg8AzD9Y1DROY09VXcSSGmkTrknEAk7IaMFPHeNd5x9tvw/IuD+12lDDZkL8W1xXseEHew1ITOe4WzEDvfWHP8eXzfftr/WLzDyw8E3qHybPnDXfdFRCWm4bIBE7VE424LNbK991g/JLHU1IsMVuQLCnMFUl9gjLM/zoe4gxUga2V91GngrwGR69ZDPznEs+sh8BV68+KYCPwPW/ByQ3VSvXehuXa9d7+Mznt3G9PaNGzf2CiAZw7iDkDTlfXaaJxbnjnNVl7kIfBVFkDca/CRL7HsdFMpOPyJF/be2cSC3rsnrk0uBtJFRdU3YtvwxF2qC8ASo3pBlFQ3You365cZ/3nop4YvrGy4HgI/ZvjW86doEcQ9pqYKMWVrSidLqFk3Q4wAlPPeq9sp4hkcJAQM6x+4w9RN7SQAS4SRdhQD7tD7NUIDcC7PWnrnTwyfWw/3djmBwNNY3I19qOt+aGB/zBER4U80UY1nxQQRY2YDojaKee8ZoTzdgME/ttjAwx0YeMcBcQerjJF2nfNFE1WTrlvK6Jyxgw+vosivvMAP37pxclHEvYZ48oTLhka7UmKy9y4O3SPZGjGO9SkxT+fZB+xI97tD3AEoG6pX5kl2xiJ/LFB06VhpgR8+vLFOxjzadT/UxBSZGcGK3rF04olNZHjvfnUvsw3vnbjd4Eif+bKy7Lj9AQA0ea+EuKo+0c4sfXBmlUR+ZQV++NaN40Tmw133IwXpt66urywbHyD4FfiTbZ7euzMoUJ/0/sDF7Ytr0xsYRPsGwGoTcjTk88uv3Hgwb+mgIXN6VR6Es5ICP3x44xgZc7rrfmRjgrtRgawlSycGV0dhN6U/Zb1336A2wpCXV+mn8nsBYGWRxJg530NVi+RZOryf9q3E0+5WTuAX4Sl1LOyv1VfLuNaY4FkR8nKl7kRHzjFKeO9ZITvee9f2y7WJ0DwAMm29AjrdpiGydN++0b5TKf1fRFZO4Hv/lDqBqKBGKkXFRy2mUmfcXWZQEO1PA+9d30VdXnCwEh7wAAB4VFE7haOQe37Xyhl68Cd+6Lmlvkd+pQR+Ye51DxELQyuURhoA8wV9LzfahDQKF8q27b3z2/GQBz+oqlyMtFcSAMAuosctDO6r+5KXk3D+m/r/iMi88yfes7y3z62MwC/s7XBEgnj4ihvXm7CiqwRZMmecDLeoUgzjAw7GXsCGenTvHEvKgAGheQD0qB5zLTkJSkcjwYsnMmZpb59bCYEfvm3jxELdDucgDVy1laLed8RbzhHn0GAh5BlXEyVH2y2YPXpPvljEvQwAQBz+HPLPr1C9cl48EY0GZ35q+LUjwU4vIEsv8MOHN46RNae67kcRAiFkPiFsK+4tM554rF+Jt8ZFbTOZ2pXz0ZG7UCl0oQh5FAAAJYXOudxIXq2cISKyB+1otHS3zy21wI9XzJ+iRVsxXyWmqIyHK3q7sZMh6C0nmWOMh2yHvXeV6ZxRe7BPbl5aPQBAGFVULqVeqhfvYInu2ztarvfIL7XA097BKVrwRXV8OFtfKSc8X8tOCc+niLN0Mkq2vf74I4z2vPfKRQfeOwBlEM89xYC/hBdfMWqm7diHfvw9L5wMdXuRWFqBH75tY0hkH+y6H8XoWXieF2emTlQQ/RG7VkijA5YS3nvGRQUAoCN5sC0nTSs18eJ3+2QfXZZFd0t5mRq+deM4GfOZrvvRGOfHaiobksfsipIxTh3JriCG0xMwVr9SWLrfnd1mvOOmxyPbMBmPpOW9dwg8AIWwRJbdtrX06R9me1x8aoC3F7Jhx/UnZc3lrT2bR941PHop86h6wdJ58MNHNo4s9GNoK0Q91Fj9WNlIfpKIRUbFIY88Hk1Q9kcYFCR570Ebyn4AAPS04MVrbdRq1urZg2s7exdeR5ZO4GlnAR9Dq0ARsQ5msp6qWDAshvwJw9QxoVwnVRJWro7keYdbkLsr2jBcUQBAYfhzTDj/pIG3YI9tS4hYVhmQeWDRn3S3VAI/fHjjMVrwRXUsgV+rVhA19Yt43woFVI+oq9tKZQ1679EBR8iGoiIAIA/N+Rbz4qVRf8ypqRZ1Clpr3vnBf/rCCWX13rE0Aj9828YJIvPOrvtRjFh8Xv1jT7Ffye4gPB8UVi454eRXee9MIWg7APMh5MV75XK9eKZA7LplDJ1a1IfgLIXADx/ZOLI0D7MZE/1xRvKlkHqfw/Nhi+PU2ADBy4T3DsBCEDjvouest9PgWuGVswe3d3ZOBbrQW5ZC4GlnwR9mEyH+w2xgN8NTz+6LCZ5/oq2kxYKxUXmgP64RaDsA8yXqxVfPb8VJqY321eqw1xPzwAf/6fPDeIv9YuEFfvd+d3qg6360RuDHGP/N6iefVOH1QH52/WqxmOKnDBCqNZUnd3DAAoUHoH0yvfgkh6BaxRswyJWNofd+8J8+e1xnvR8s9GVr+PDGMSLzZNf9KA4rZBWBY0axtW2nsmcrWN+I967z9Y1Tn+L1Sx4L069ZPSP3h/Hea9+B0B8AQMvk3hfv3RO/m1m/v12+l946CdN69f6cv7m2dWxR7o9fWA9+/Jz5hb9PkYPVkpQwNZesGgGH3dugQ6voX1pfAskRz1rMVnnvTEgC4g7A/Aice2ovPlaHKaCMQh7es7PvVKgbfWJhBZ7WBo8R0eGuu9E2+aIaVlHPQ401HsjPrs/0RSwRONH578XvXOMTHQAwd3IG9iFvQn3tEDozsPTgj73nuXW5UH9YSIHffb+7fajrfrSOyuMsK0hpT7/zC5dcPV/0Vj2nLP/9hY8HADAf+PPOVP5fSVGco9pBgtQHt6ixg8ceXYBb5xZO4IfrG4eW7Za4GjE3s8GPUkwUzpKSgwj2BAsWVNRP+C6SohEQdQD6g8m7frT2LA8iIrIH17b7f+vcwgn8+BWwS3tLHEumKFbzG2lWLMSV2L+0+mVCbGzELhaNCHULANAq2ghgfLqxfJh+HEt44Md/sN+vll0ogd99Wt0SvQKWQfrh8T/CgJVYeD95xBrPj+glcSenVKXove/KqQ7JLgCgAwLnYuzyF0wuFKYnIrKGho++u7+h+oUR+KUPzbsoRamkBqWF98MKzfaxZHg+ZqrhAAHaDkD3RK8jTR0FpmKao2APrq31N1S/MAK/kqF5Isqdf4+ZqqdpwlGZ9DU8H+pktF8AgLkQ9zRmKXO4lrDmbH9D9Qsh8KsQmieiPFFReL1FvXx3Wxw05NvNqZgdnofbDsBiYBKuawWjgVGzhshSP0P1vRf4VRxmaAYAACAASURBVArNKwerzdtoef496iW3EYloWB86D0A/iZ6PJdfzcNmqC4I9uKeHofreC/yqhubj4aNAzRwPOukk0Ie0S86/x0fsCM8DsHQEPJ/iU35NnB9rHvixf9KvB+D0WuCHb904vhKheZdYWDleLMlmsTYibTY9GT1bhcLz8b4AAHqBE6aPlQ0mq+or5+GnxQePPTrcOBSxPDd6K/DD9Y1DZFYjNC9TMKwtmleOJkgp0E3D4x2E5xOyAQAdkBOmr2UXvK6Ep1LtwbWb+x+LtDY3eivwtI9O0go8a35KtkAHknOi9Q0FOs9opFbmSBvheQCWhLCq1lOCkT3FRTEWGYxgrX2oL6+V7aXADx/ZOELWvLfrfnROYbFRhbV1VsQkNrzfcPQs2s0kbU0DAKBXBCKLTc3x14bEBg2RHfUj+txLgaedfnw580T6kaX9eHNc9pTwU1pXpN2m8+9Vg+J31bQ+AKBXNHUesuorOiVcQw5/4J88O2xovTG9E/jde97pga770VsKhvIbVSukhklmMk9mPhHheQAWithJHTul256H98yZk13fG98rgR/f896bBQqdoFzzlvTDFY01WGCnqOMl5pxAmfPv1fx4CA4AsFB0ECFM65MhIjo4GGx3qme9EviVW1gXJEEYFdtFiIyQs8L7c55/rxpBeB6AxaKVMLtkV1shmG8efPTd3S24643AY2FdIonCGR/VKvIT6uSfcy3Nv0PBAVh8cq5hTefhVRdPueqgw9u9eyPwq7iwbsqcBalh2Cm5gbTwmc5mKD9uHvPvACwP4ZO35Dy8VCcyDXj4x/7xc528jKYXAr/7xDosrGuGwvPlasVGty1Sa6+NBjH/DsDy0nQePqfJxIV2EyzRsIsn3PVC4Mms9sI69Rz6vAQpcOKI/Wi4wI6t1UboDPPvACw0xebhw2tzSy20m3BwcGPvMMVUCToX+OHDG+tEdF/X/eg72YIkinH+nFIxchbYtRFiAwAsDi1N8SWbTa1g6J3zvm2uU4Efrm8cIlpt771GGz/cUiSsoM8fVevPsqQBT2wSDoMCABYcfbQwy1kqFC2c921z3Xrwu7fFrdyrYJPI+bHOYzSqrFNkmiFzgV0LU3AAgD6RE2bvYqHdBDvf2+Y6E/jxQ206WVnYf8qqT4OIvGulUbG5ampsHQEAYOmY93meFgGY7gyLd0SgOw9+Lw0J3nseDX7FjefvC9F4BT0W2AGwssxtSpCb0Wt40TBED8zLi+9E4IePbBwhMu/sou3eoV6R3kLT8wptZ66gTxbiPq9hAACUYw5TimUWNks15/Pcl248+O3BsJN2l5acSXe15cxCCYsHtDSuAzUHYHnRL7Rja83xmmSIDj/67ufWM2onMXeBHz6ycYSMfWje7faV3i0K62wOvaUV9ACA5SbjIpB13WgwLSgwzOlGCvP34OG9qygiXGL4v7n18rfINe+IOryPUQEAS4t37uespC8Mdz2ahxc/V4GH955H5x5rh+sEIMYAgBjFLxMFwvVKE8OMltTM14OH916WUr/qOczfFwocCNb1xTsfLAEAipCz9IetUPBCkGqqbS9+bgIP7z1Cw3mkdoWr+T3wUrH8W+QAAKAbsl46IxccNulLiPl58PDe01lV8etkhT0AYKFYluuEbc+Ln4vAw3vvDnGRiapiqQ6kFy0SkcAtcgCsGHm3ygkWCt0Lr2KYXEPBfDx4eO8JQIhY8LUAANqmq+uMpcOP/oPyXnzrAg/vvTCFfoCF55ByCybT2LPHQAGA5aPgGqbyKK3vKe/Ft+/Bw3tfKHIWobbfCAAANKfxrF2pW4a5OpYOP/oPXziRYU2kVYEfrm8cImOLdhgsI5m3quQ85AYAsPT06hbdBCyNir5htV0PHu97D7No97EDAABoDVP4TXPtCjze957OXGLkLZvq6WgAAxYAlotWz+mOrod2ZNYLtdyewA8f3lgneO+gCUs+4AAAtMACnO+RgclDj75740iJdlr04M2wPdugS+b3BD0AAFgOUq6PdmetSPS7FYEfvnXjOBEdbsM2AAAAUI5euibrj57cONTUSDsevBlg7h20SC9PSADAqlNuWvHgaG3velMzxQV++MjGESL7YGm7IBHxh5b3FjYAAOgdS7xOxxjb2FEu78HvELx34NO3E7GHJzQAYAWRr0WH/89/+NVGz5EpKvDD9Y1DROWW+AMAAACLRMmFx8Y209OyHvxeOkG4NQ4AAAAowYNNbpkrHKLHg20AAACAUjS5Za6YwA8f3jhGRPeVsgcAAAAsGlbYzrZnaT23bjkP3uLWOBCgxC+9j3YAAKAJ8WvRwX/5D766nmO6iMDjrXE9RPzRJCobhBAA0FdWZcBvTZa+lvHgsbgOzJW+n40AgJWkvQFH1mK7QiF63BoHAABgEVkMh2F7e209tU5jgd99ch090NQOWBykRSSLcZoAAMD8aXp9NJS+2K65Bz/KX+EHQJBVmV8DAJRjAc73TMfo8P/xvz57PKWd5gLf8Ek7wCH5x1nw17zkgopoAwDLRavndA+vh8ba9ZTyjQQer4VtSA9/QJJZCCIAALRL8DpriYjSVtM39OAH683qA0BEZPNGEJbZtBiYALDqeNeAoheC+VxVhFYO/su/r78nvpnA4973paCRIDYUZgAAmBdW3MkxUNiOGr0Xny3ww7dt4N73LigkjrbVH2V7Ct7YO8fgAoDlI+O8nl+kT2k9UKyaNTL04KMnNw5pTOZ78KMBvPdWgAKx4GsBALTNglxnbg72qPQ3X+ARnl8IqvNPSb/dDhYAFr+/vnE8DgCwWHALc7It5F+HWr7cGGWYPkvgEZ6fE6s6vz2v416G7wqAVWUVrhNy26owfZ4Hj/B8eQrOIZX/PTafQ5KKtbsWAAAAymNzAgWFC2rC9HkCj/B8P1i0++i7vFWFmabAOAGAxYU9f3NuA+rhs8I0jWjC9MkCj/D8/OlclErdGlKqbQAAqNCLp9jZ4G65dmZEw/TpHjzC83OhyA9WFObm1qPTAx0MANQPu8GgAYClRYocdrnmNmk6NaFvsTB9usAjPF8UtXfeA4+59XtFc+bwW+kLAGBhaLh+Ka1S3tRgWxhLx0P5SQI/fvY8wvO9o+w8kmM5s1CkZicrYDEcAGB5ybtFrlHUsWCdnKijjczDp3nwhuC9l6bD+W1pJWjxSELmyZbsqWNFPgCrQUvnevl74JvfgST2aXfn4I+e/Kqoy4kh+rQ32YCWaCBK+T/UspS5VQ4r6QFYRcqs+1FEPpn8rOtVixhjjkt5aoEfPrJxhPBq2DlR9hdUZl1d2ZFo6+SsaAUALDTzPs/V7eUU1B9MAQ9+G+H5TkiYypbC2yXaya1TZAV7wii7d4sWAQDtEXMoclbQZ16j5hIZ5Nc7HX7/yY0jXI5e4M3geE5/QAJ9nkPmQlWx7TZCZpG2o4VjBwIAWED0nm+WELcwJciG+jOvRQPib19PmIO3D+Y1DUpQZsFHNS3vl1RUC3MWvbQx+gYALA4tRQHnEvUszm7HDfHz8CqBH98eB1pCvXKzI29d1Q8+dBTJjzSvEnMstANglSgTLQzXEcP7STb10cKm131LxDrgOg8et8ctADlDUMq7Va4Q0XBVgQZ6MWACAJQn4IjEx/6ZEcw8nyViVJcVu16+/+Szx900ZYheXoYPClBwLia3OV3hjAlySj3xdDZD+XHzmIcHYHkIn7ydL7BreW3VpKhhVtNHBX64vnGIiO7TNwfmQuIPtbX5a0XIKdmgsp/iSZUxYIK+A7AA5FzDYlHKNqYCY6ZjU5oZGLLH3bS4B78v/Kxb0BZ6l1Q9h9+UiOOb9ZvNWWjXlJy5NQBA5xSbf9fY1VZQ5rd+rbR0n/t2ubjARx5mDwqTMR+T73krGwu1He1HwkCFK9p0dI15eACWj6bz7xlRwrQ+6acB8x0Y/zi2aM/x6r5iDh7z772i5fkcdbVCwph/AoXz4yNkzMMDsFBkOBAl5987WWCX2JB19Doo8Jh/nx9lwuyKkSlXK0kY9V2RdtsaYeeczK1OaQAAipE/f96gvqJTxSOEsfB++Np5vLoX9uAx/94thRWnKqz5psO/vqYnoaZIgXMyuX0AQE8IOA9NzfHXhsQGY9fYYl5U/Ro77mptHj4s8Jh/nx8FQ+/eP3rJfmRFtpv/eOMF/ULx7wFhegAWAqUoxp2YlubfdSZluwWcoAk3aO3YZDsyB2+OhfNBu+gnfVp55WpOmL3hACF6HE2/h1j9SHUAwPyJnpdtXxeSpjGVjkOj8H5goDIaHZ9sxhbZPRDJB22g1NwkMUooXCwc3uI8vGq6IaU+lB2A/lO9LGSKdtPIINsXrmSDa0qz6/xsoZ0o8Hj+fLe0MrIL1Uo6WfSh7ZInY+ywEaYHYAkJuMxNnQapfo7TUM1Pq182UmsqjrnswQ8w/z5vsuZmctoo9COWkqJCOsdwmrZ+sagFAKAoOeH5uU77RYxFry0tOD8/cvK5Y0QhgbcDzL/Pmxxlaer5NmhOHDHnRBDyulMsTN+sEwCA1rEJ17WmEcUUs00FOr87ot3Bzigi8GQh8L2gZc83cZ4pGWVITNt4fOoCYXoAlgalos7rWiKZ4+uHuxPMSjwWz+b4DjhW4McPuDkc7iFoldgPIF4svcnYWMKKO14S28cCoSgtSYMdJgoAfQege6LXkabheaZi06lLsXuxi2rJYzEU8ODXCN57R0g/jrQRYtjtro4Qm/6YxaS2f8wRgZY7FsmCygPQDwLnYrHwfEJUtKTTo21fcyxCkfuIJIHHArt+0SDcM8nvLszetH6LYfrIyQl9B6A7otNp1YF9cJDfv/B8a1HYisH3/71nj/MCjwV23ZHh+dZK5owYY6IYbzZKK2H6hO8iKbwGZQegP4iDcr7sdLPj8HwOOYMVqbA1o2NrQjMQ+D5gicjEswLF0pu0RCZkrNaY33K1Pt+vSipToHZcsb4wFVXfhSWyhvv+wscDAJgPvDjbyv8rKQpVLRmev/UOolvvmAmtrRSW+sY7G5b35it2b94wdPFC4mClgifwWGDXL4JCHlQzR8U4uzFRjKll0/pMX8QSzrHEvxe/c2wTjKGSA6a2uf3gHrr9VXu67kYr7Ntv6NV3723NvmXdHkWpQIIVy9UrWSK6+/V7BHtM2zY1LdgzTzGsmBboU7Wkk/iqVxPt3csctVfUEcrqVu2Pr7aWKev10Pk3iP378N8j871Eyrjkevabr9BT3/4d/1W2w+178Fhg1zlRIVJXqiSH9T6usqLXq+/ftL6qL4HkoLoHssOHV/fiI22kcPvBPfTaN+yj175hL91591569V1C4AzMF8uJt5smixInSNYpM8sNiNb0DydiroBVaialOb1l1NsybqKfZtg06bv0yhlLpvY97aaR3T3F7CStkrD7Z5ZbqTlLr2QbMrPvrVatluPl1Vqpnvv1Hb8M0e4FbbbjfhPZl49bDthGr2vnrjQQ+K6JKXxEcNLC7OH68cGGX6KLML03PhEGLOyAhxHzEvr+2jfso2N/4Tb61jfsy6gNWscYX4Q8HfGFhTHEl2EEJGylJj/1Wv4Gb1JsxpFPtpzOIPe1SVXrYh4orvmaWTHnv+KwyFM9j6j23Xo2a/k0LUN8VmWnViKbr21sHHnd0aPncur6Am/oSKPegLKovM6AkAZdZUUzMXVjBDGpfrVYsOzusaijANWa1UGC8vv0EhJU/vaDe+gv/rVXQdiXBZX4KKv7GtXYfsiALOZMPaYcK+aCmrPDE0/hhTTXO2a9eD/d609I5KmeR8R582a8a6vFmfZmuXFtly4cmoEj0fba2hEiOhcpzMKsoscrYvuGFbb5hES7KfVtcDduq3peCyN7zlbRe+ID/XGNBL93gVffvUZ/4395DcR9YTHs5di4e8Lg0jBbobbiWYZJi7Udb1+uH7dMJETVhCbZZO/7myV436GXzmVL35NTy9R3TCBv8v/aP4VXxnh7bBF1pl9wQLPXv6bC3SYHge8BrKAkCB0rTipR9UtItkIdi96uJ3U2VicwyOAHHL7ih74D7ytIUPlX371G/8P3vJr27Ve6+qBzit4hUcAWN7wIpiiE1tT/x2UE7fHfEd8w21dOzCUrYRUXxbyoyDOKHtD1SgIv9sm67nx2dsx3UCY1gR+voD+YawwUJKbwMVFM8Xq57AzPXqwSEEkvSyGo7CAj8n2I300hL37ffkN/6cQhiPvCwSmaoozGTiXZ+DsB7zG//RQvXmtFsmU45Te6IQqj+lT9YkLH0Y7Ix7x544t1VL39JnM+OzfpT3rGlNQ9eKyg7ycBZYmH2cNuu+Dkyu03DdOTJKiRZpUDDn6Q0L4Xf+y/u31pb1cDFNNvIa3BwMDJMsyGn6bpmGF2c714Aa2es+kZ3n1lMybyRsiblXDMCwk6XQ/68Wr27ivkwRPC871FHSlWeL19DtNrByza45mHF79vv6F7//StgV6APsP5WnHNFBQrmha/yPOta0jxvzOsMCrPevHsEZgEMZ8V9EpI6V6eLOSeyGu8+YjQB3WdQpnxz2APHXCtaBk4e4dyDYHyZM3DV4suYJg+VE97PEEvXtluyIt3+/Ffvzn7/AN9gA01RxM4Q/pcT6iE6pybHvTs3bqcd57pxTNNiOnqRMm1J+Y7aijyjjcf7ppxq0Td9oKa7n2+9uyzx12zGuoCb02WEdASynn4uHffjzB9NAoQW1dQTZU88Aji8+kTvHiX12LF/GogCFHYY84bGCQvtlO0V8KLl+bdOQvSSvsk776hyHsy7Yh8zJsPCr1S7FnRnxNuiB4efF8pMPddLdtFmD40YAk63IoBQ6iTtv6/uA1FP6rHhVviFh+dxDIipNXYgKuuv/jzJVX99HbzvHixZ41C9bUsvwOsS8xlS0Iu57G91Ap9tawo9mHR135y3/DqCnyjx+KB8sRFNVwp6+1y1Wzl5L8XBVD0UXs8tS4EJt+VXU334qsvkmDqYuX8EtBCmD5N5yUxq6cZeSOSJpuX2NV8pRcv2Q4ouSTmqemTPyEhZ/NC3jxTZib0wiqJoLveRN7zry9TgR/fIgf6Rp/C9HpzjPGQbeF4FA1EQ/0lvHihVErQBCwJnNBwHqms5AlN6etFBxOs0html6vFDX6UaSSE6lmkwZFO5GebMZEPDYA0Ql8vqdbzBmzfNH8tp97Mg8ctcv2nozB9UhSAe2GFWDZQLmAkFFVoz4uv/KmkH7iVe1YUWEQYXzVbmkPJxt+Jjwcq3rnOi5ftScckHqsmuDFJbxyqN/x3kiXynnsve/oNhH5WOiD41foZn50dukUyG2JQ2YIH31O6CNOL5mNRgOq2Yu58djxhLz7k+Wd78dHIgpvntEdE16+NAjXBQtEwTB/WVs1QodwQw5Mxpcee4sWnheq7EHkxUfbmU4Q+4Lq7gt/Qgae1PXRPTr2q+wEPvq90EKbX9osfcDBefMpcviIzdMtcqCkxzzkW7aABrCCcwCg8Zz8t34vn0oKevRJO88OmuEGRUDgg5rki7wm54617Flg9j3vq4sx7VMFnBfj/JKe9/t/aPnOX1EKImcBbePALQYEwPStkYkFlmJ5pQDVg0IhpsF2bLshSaEAT7pcW3IGloJwPHfbdU+IA2oe/RtvSevGMpd1inBcv9EN/j9w0PUfk63m+utdF3B8EzHZZVReFPir26h+NJPFlqHjweItcnykZpo82EDOvEsWwF8/3xw+Be0LaphdPwnfrjQWg7EuLNkwvO6mBBKWQqorzXryUFmjFS5OEn/V2SRJzSfylRXelRJ5PFL35TKEnioh9tV6uhjvlv/a1Z48ratXACqFFoaswveCqRgccwbnzQJda8uJDx1VqwR1YVnLviQ+PAmQxL+TFK0IHkgOvdOxnyerFdeH0VkQ+5M37FeNCHxF7dcyn6QBAQVXgHyhjErROSpheEKDofDNXJ3ceXfLAA7WzvPjY91I0z+8nWA5011a5lMI/1luOePG+mMsVgl68UtF3i0WHFpUkcUQwJ5GPefP+QKCeKyhuRIjlGfc8DBka2D3J0+jw4BeIrDB9tY6yrDRFHarAe7phzz/FWxZtOKmlvPjQAMg6dcGSoQrTEyNErDIF04y/I1bKui9e68VLxRjh54YLRCEtn4fIG/eP12NZzx31F7Q84L6rvW5J+GP/7Va2ydPoAyKi4SMbR1Irgg5ICdMHBdrK4io24Quh1gsOeuCB2ulefOC4goLPfFmZgw+wrKQEyfkyvfLiHeEOirnomHMiL0h2aZGX8vw/lTzem2fFmxHtWVJA0Q3z6ZBdD36bjnTbDZBMQjhaEtTYeCFqWyOCTO32vPj0vFAzKjtJr9wDiwL/UhWuIJPAiU+rXjyfJgk/693WdpVtJHrsRUV+li3mTf7EvPn6btCF95L8G934wyjyyQAh+gUjJ0zPC2rYbdeGs6MiKIXHpf45qblefCjEHjKcsuAO0r5q6OVVKtGOFx9x3lUNyFXD3r0s2nxySZGf5bHeOu+0k5cRFPqwV+8m83e3F8Kk3+k2GPfwSLlegFbJCNOrzIkeeKBZN0McMzBefJNweIbA6jx133Bobh4sN9Kt3F6CUK4zL94wJZVefFjMpXTJj5ZEnk3OEPlZHt+axpuPCT1fM6bhnOiHHmsT+xgytHk9Xach8IuMP+UcLDvdVIpTyIsXTPOJpb346r7Si4/2JRCVCA1uoPPLjCgpkbRwida9eKlIsD4jYKLIcyYYeZUqkHQvPDUT+brTXuldPSNH6A2zx5qIOO25Ep8LQvQLCC+oghcfqsOMELSCFfLAid0t58XrQvVuY1qbfKiejXSApUf0CqNpQk6guvF3Ar3glL3JgjupNd3xyovumOpjG01Env93MfzXV01JFXqV2CsEv4laN6i7K/B4TO1ioRLUcNmo+DNiGhRrbrslL15dLyLGKaF61QAELB9Fb5kzwS2pgYjWK1CE6h2Blpxvo8usJwfum88TecN/vdP82h+ng4lCzxdgNDdByTPd9737zGtlozxjDx6PqV00ooIaqSO6pDEPNTA/zTdUwosXohNRL94P1bvfVXaoHp78CpN2y1y6F8+Va+LFe0UC3eFEnikRTPfJFnnxa42IfNSbTxF64+8y+q8Tfc0ggC+7Z818q1BBBCH6RSXkdlc2Qx5zijnOqVUUbzz/He2jIk8s2yRUD1aGlFvmPIEIqDu35ZWr/fEVK2XBXbBcqGyyyAuyGxT58ABAFHITkspZJl8mLPRBsZcLellhWU/LTQUCvwz4Tniw7HRTObHMh/15AZQqacP7Tbz45AV3QlJM5Nn+gRUjwYsP67yXFvLrNPVlG9pQPWMnKPJMnWSRDw8A2O9wmhfJzxR6ZtdJFUYFCkWODQByBd1lIvCYg19AeK87LIQqLzhREKW8bC8+de67gB1vsEAy2mfyg+WhkRcfqOhtcSoeUfbmoXpO5Lk+8u1LElhe5EMP652JfHOhN7VNJ0e2zZXQKnlLij8R+PvSq4LOUXnM4Xolbpkr7sWLeTbWhGDHr1fbD/afOUaxHbBatODFR7Ikrc8O1Qd3HZGXxjhCZlzk0wcAk3l5UWiD3vykVzGhr5SrbjK7OsEv4ZPn1UeIfsFJ8piZ7Fqq49m24cV70YRoiD3Ql6RoQPlQPUR+tZi3F2+YNG9Hq+u1HcXAhBkQSGKeL/J8nd283AV2lfyiQi+re5qMN3PdL168mBRth8AvOgE19QRIE8qONZXhxfOiKvRRMJNcr3ioHiIPOLRePCdKpiYSwbreH65VTtkV72R3NqT06dacRJ4oJvKR/Mp3nir0Os+cT+KS0wYBso3t7RtJd7xB4JeMkIfKlnNTW/Di2TzNYEMUY1+BZWH2e+WOM6IiH5oHsEQvvbjNtgaWj3wvPlA8rulhGzVh4Y0xWl3fjYo814GCIp+1wn6SHxHwStheK/Rxsa/UCQl+wEjyAEAzKnCAwC8BvAceF8HOvXhbEVyhfcbpF21mheq5doT2pOjB5o0RVxusDIIXzyl5QN29rdofTvENu8mncWUlMefSmX6WFHkSBk+T/OgCu8JCnyz2Tl2uRkzRkxU/zmC4voEV9MuE5IHzRSMGfHs6Gyl5fqnQKnUvZB5rQyPyTHvy4IEZzICVQu3Fy8khnQ+1zPzhhJQXfl7vnfrSbnGRF4Q+usAu9EWNhT5QQi/0k96GxV6nu02VvfpZU7U4YUBrhKfYLQGhkHR1M+jlRu2FbOR68bxN3YK73FC9rn+slw+RByyyF+/JX0DdvS3jpks16zvZ8/HBPgnpWSLP5xFNRD7gY8dEPOrNj9ueCH0DsecEv4HDXRyE6JcFSawoLHJ8CNz3cFXeLueNq9qOK6VYokmo3rWrsAWRB0SyFx8SynDZWUJYWjnFl9x0vuGo864v0Ejkw6voC3nzGqGvqLROnBUKzySV+KQCgV8i+HnkfC8+qa2Ax13dDgloyIuXBzCBUH3UrjOQcZuKRgWg7qCKoCacmHtbUkKgUO0PJ6KS8PPePbMbTfeTBJEXvPLwAruIyI/zw0VShd5U/yhFlZHiNtQ9Q+Eh8MtEwG1vw4vnxdn3bFUPwpEW3DUJ1QtN1av4x8mVl/sCkV9VePFJu21OKudtGTedq+kXypmPb0XkhbxZckTkoyvpY+qnFfpJj3ix12tsPxQeAr9ksNqY/Ta2/LZV/fL24yH+JqH64HFFBiGhKQqwurCXXK2es8VnBcMiz4k5b1Q1Hz8HkTdC3ixZFjFD0oCqUiYath9bGpfTSWZd7PMFvxsg8MtGCS++mprgxbsJbSy4Sw3V6wYyTN2QVy8dO1g9Urx4T+TVqh8uJCs736OORL6ezOeFH3yj8ea1Qj9uTO3VT3tIMcHvk/BD4JeQ4l5844FCSl7zUH1IeOXBgzOY8Wx73Yi2BVYDQeMleWML+v6usMVpupeeIi/yynp+t12RJ5o48hpvXiP0wSIzixOvXi32055M67tKiZYoPwAAIABJREFULwl/k0/aTXIQ+OWktBdPvtBVt0t58VFhlvY14XV3fKMVeUrrJ1hF1Aqf4LTPCoZFXhpG+COB0KI7RqfdGskiXxdyZggTEPLYIIBooqkxOTZ6j37S8kTok8S+Up8V/qaKP66fCAR+SSnrxduoOPNt+yKve4kM74lnPQAnJPJ+k9NOITwPUkhacOcJh1r1vQRZzPkq8xT56V4gLyTkM/3nBwHTckrxSxZ6xrNPl1jBbvInDwj8stJFiD3QZnobhUL1lY3ggCFoz2kaIg8Y2Muw+tosCL9kRkpQiHmrIs+ItQnk1fKFL2uq8SGRp3ShT3OIZ16464z3GQj8EjNvL96y2y2H6rUiLxkJFdCKPABEgrhovfharle2nm64P1xCfUcp8lJ6TOTrSXX58/PqzKrIsqny5kkv9ESz8H2aUM+8+5qHXxH9vog/BH6Z0YhqpFrITErzwbwmoXrGVmibPTZpQBOzAXUHDrzGp4fq4w66JPJcdprIqzz8Wp4k5KE8XwLrTn7Emy8q9FQR6lxZros+K/7CICD6qdRNXWUHgV9yeL1L8+Jrima9XYUd3otXDQCazscr+hgTeXEAwe2DFUcQCDaZ9/gV6s6me2JOQnoBkdcLuZ9nhLxaSsybn2aHBXki9CnCbUyuZx/sxezjKX7kU6u/di6lZQj8shMIh+tC7OP9hBA7bzMzVO8V5OvLgwdHpHNE3h2MRAYnYLXRL7gjXs/ZdCOke9VqZdl0bzNd5GtJiSI/3TPeRi0/5s3PssPe/LTsVOgTZLsq9pHvfh7ceeed51LKQ+BXAF6MAnPUhes1D9VX/vjBh9m+OGBIEHnWHkQepNE4VO9tSek67362KXnEJUWeyWOEPDYImKYkefMaoae08H21pZrgpy7Umz8DMnSp606AlsnyuP0yuQvu3AR1qF4Saclzp4AIC4vuovYg8iAL4covuetcGqvdXLrh/nAJooe/uyuLPK/BkpDX82Kevu/Nu/1qSeip4tU3mHs3nuj3w9snIhoMf/bo2a47AdqnrBfP57EDh2pSaqjey1aIvLbDgTBDqsh/4+s3A42CVUUM1Yf1PJY4zar88RLiIs/thD32mJD79fTeej2ZF+j6GEAp9HMVe8ciK/zNPqkgRL8qRMLX1TIpXrxO1MUijF23f64twUpA8K2zw9oO2aDAcRPR5g348YCHvyan3DrHpfMeeJrIS0KuFPlanonkscWrG0JyQOgjZao5KV79zH5VVPvgi+cBgV8hUp4vL0TXHTsFQ/WhPiimEry6cxZ5AHhSFtdJIs+VN9H0yh8v2+tZY5Gf5fHeunG22I16mbrL7qEZDNRs1oReL9qTOftFFHwI/IrBajzjxbvb8wrVR+tWKgVD9SHb7tQERB60iT4mL6QzXrAmvfaHF+w2RL6WxCt61Jv3yoS8+Ygdr7xJ9+prNhzBNxmDhhyuX7NPpdaBwK8aAUHVed/jzSKhel7kpf7VsksvunPtV6tFRB6AGEnz8SR7936elM7Z60jkazvCoCTJm5eFXhO6r9UZi3Wu2E9tGV7467Zz2xjXazAHfzmjVbCg8JpkA3l8vUaPnw00JIuym68QeVeDtSIfigbU9iHyQIcUaJbEvJnI+wWTRF41ADCBesatybr1TBW/A2yWLJY1oU9aZOeKfRmPvBo1kAYB4c9uvRxvfFIHK+lXCVGMfTc75iFXC6tC9Z7dSKje6yNf321n7iIPQIyAu54j8lxW5Q+XoBD5vAFAyJvnRdzvqZ9cQOinG3rRrgqy/zS57his0XZynTY6AvqPasFdG6F6d18r8pKhQGg9GDEoLvIAxJFC9Tki70uf94dLiIh8KM/pCSPkUp6QRK5wygMB9miThN736pViT3XvuyvR33+L+c3UOhB4QEQBsQuVrVfxMxWh+ixbbrY0H+/uiwaomcgTAHpCIi+lB7LqCf4fLmF+Iu8ocdibN6FktzGhXFh0vWI5q+orVT3RbzzfHmCU/lC6scAbPM1uBVGtYG8aqleIPKuiyj6qRF6y5/U1IvLR4wdAh3h/vKTkUloRkU8dADBz73KuzptnRFwr4IbNDossW6eBV16T9ZreG38AkPvJcMd3q5gR5uBXFEFW2bysUL2i8WCo3u1HjsiHPHC3r7HV9RB5UATpTWWJ982zeakiH8qThNzpqaeLMZH3Zvw5Nff3Ip46r+9h0XbFuabShTxx16/P+RBle/BgZRE9ZF4spaqVKuSpZkiUq8mSyHsiHLLXgchD6EEO4qK7xJX13lZlrw2Rr+16qk9irqDovID7FXhbvAiHBwVhwWbHBm2H3xUMRumL4SHwoIVQvV89bT5eIfIUsjdfkQcgF/H54pKYB9LHW/V0/089QTkACAl5VsieEXFtGU05N0X26vViP9H5sOh3I/4SuwI/ojPddgN0jSpULwhzSqg+xVbdXrgcRB4sKiVX1o+36un+n3opxQBgd9dLcFqSPX1miMAqtVbAPSmNCL1XJ0PsOTu+6FcSgwOAnE868ODBLppQfaiqRuRFtSdRoL22IqF7rlNtiXygmwAkUWZlfY7I6wcAs02lyHv5MW++3gKTzFaKC32C2GeG4YPSXEDrjSG64847z6g7NGa8yA7vhAcNQ/WuLdaQvyvWrQp0kiDz/U4W+dAgJ3DcAOSSvLK+iMjzeSEhZ/Nqu6En3LElRJWWxdtPCGu7Uuy9hDKeNGc65ZPLgIgI74QHE0qF6r1Qu7MTsxUVecmemx+oGH1oDUQezJXAyvo5i/xs04h5SSF7Jp89XkHAdeIdyU4Ue1nfS8twnJtb9kJOPYToQZ3EUH1VmNWhes+2UN/Zyl5ZHxLnVJF324G6g5KwK+iJuhV5J2+u3nw9IezE+0IrlleIvZsb1/e2/HFD21uDFzIq1gQ++VV0YDmRQ/VxtzVJ5EkQZal+qG9eX137hUS+chycLQAaI741LFPkvbx6ou//1hO9PHYz7K2z3nzrQh/w6tlEnRA31veUyXiz++802GuTn0NPRLRW2cY8PJhiqfITr+5YIju5NozTLRGZSplaXdoVTGNmld36bqOuPbfczJ7Tn1D/KhVn+5U+V20y+/V2ZjvQdtAGxhiy7D2ohoyxzO2phshYMt4g2hCRnWTT5qal557Zomef2aKLF7bp2sujWum7X79Gd961Rn/iT+6jO+/aU61ORER2klAxPdkkMvXJvOr5SzORt9UeVmzMSjmDcceO2xs2a5roJTApTiJbt1aaReubs6YjdvffQh/X15hREXhzCZcrMMUVVaqIG/ki6Ym8K5hVc9KAQejDzHalFwVEnmJ9HuexdidufMY7mgHQEBT5ukxO0yWRv/ryDn3hc9fpK1/aDLb54vPb9OLz2/SHZ2/Q3a9foz/15w/Qt37bmqPplRPPE3FnEDBLrPV+two/EBCGCwGhn5XVlufEXiw6zZDO9TTdnOcVYybwZnSWrHlwjm2DniOKqOsJz4rInrczInAFXxbkyr7XQL3xVJHn+hz23Ll9Sxe+dpP9/gBoiijyxpCxcZHf2rT0u2euRoWd48Xnt+lTv3KF7n79Gv23f/U2uu2OyU1XVXnM8+Z3k5xhSrbQ1xMVui4l6gU/mskWzGZgTdZC+NkcfMabasDyk3LrnFfXyctadMfas37fXBsxm5XKbD+l467sT9I2X6mHOQEoify0u/Cc/HPPbNG/+79fyhL3Ki8+v02/+q9fpue+cnOqZYZm8sskTnc98fN2vZl3z84kQUgWEyPZQmK9L25OsBpvIlJQ9xmZvBfCVRfZ4VY5wMLrt5UF1NZK1WvliLxrr6jIV7wDtp2KHXdQ47YFQEuIIk++yG9tWvrsr1+lM//+Zbq5WeYXenPT0n/8+FX6vSeuMyJe33I32dvpGgm9cHtdIDFN14NqPS9Nr33W1rbPeR1RUAnRw4MHAk6ovTYPTRnz8dP9XWPuHHzU3nR/3H5KWN0L11fsMO2Q2PdKZwGYA5qFdy9d2KbP/voVungha9F1lD88u0k3Ny396QdupX37d0+k2aWhcpGobO72cPf/mrD9blIodC+W9C8kTKJ4+roqrYvPi9VDaC4bVXsHDtx5LsH8lKkHj4fdgBCxW+fkcDpTv5YViAS4+6158hU7zMFEb6MDYE6EPPmvfOkGffL/vdSauE/4ype36FO/fGV3BX6CNz/bjXnqWo++XjLoRbOJxtkL1I96+bLHz6Fx3CfkPuSGyH/QzeVcQ2D5kQUzFJNXbCvziou8nf7JEnnoPOgCTuR/5zNX6T/9+pViIfkYF7+xQ7/6r1+mP35uu6ZIflCcPMWqSyu5GU6SXuiF0vU6kVFAVKpVmq6Rb/1n5yZlPeSGyBd4ePFAhhFMNs/1kKvJrFfPCLTQVlGR5+xWIxKWhP5WbEHlQQdMRH5r09LHfv4l+vJ/vj73PtzctPSpX7lCTz85XsSn8ebbEHrRq28i9rzgi/65Vq8zWNtvvpRX0xV4a87lGgIrQijUXt2PCvJ4v28iXzHgHss0CyF70AMuXtihf/uz32g9JB/jP//H6/Rbn7xOW5s27s2Luw2EXihbr6EQe5Un3lC/M5z4tb30XzSmOdZqe4PRObKZwwywMqjvjx9vWCL9k+4ocI98zGYlMf1+9opd51iIaYtc+wDMkS/93nX6nc9c6bobU77y5U26eGGb/vu/cTvd9qrB7rkyPnlml4rKRWOSURkcT+TTGV6TW203aXbysQvynPJcLaFInWiBeuE2LgmWBtmR9boHP6IzTTsDVoPii+6q7nJqWN1ro6Qn74Ts2T4DMB+2Ni395q+93Ctxn1CblydiPXUvQ3TcdR49kcKrD7ju1QV6Kg8/qOCp7nmM3XKD0Sj7Dre6wONWOZCAKJbuPHa1fE9Fnp1acG05bU3tQ+jBHLh6eYc+8Usv0TNffKXrrojU5+V9Ea9LW0OhF8L3uWKvEnzXVnKMXmtoZuzAHXecSbU8oSbwuFUOJCGIbmi7K5FXz+07+1MzocV3BEC7fP3ZLfrYz3+TXup4vl3L7rz8NdqqPkTP8ebzhD7Nq4+KvUrwFaIv2W742RlRo9Ec9z54vDYW6HEFurplfdHk6s1D5L12GNH3+suG7B3hB6Blzn72Kn3iIxd3F7EtEF/58iZ96pdfpmsvW5IEPCr0TNkUr54oIvZuXYXbbogX/mQHXsHWjVH2AjsiVuCxkh6kIXvHvMizl6kuRJ7ZbzovD0AptjYtffr0JXrqs9e67ko2u/Pyl+m5Z7Yo5KmLQs/szpIiXn1E7NWCH1TuekH/v2ZO/IHbzJlQ6zF8gTcjhOlBMkGRJ0HkA6H7us32RV5t27EHkQdt8NKL2/SJX3qJnv2jZi+K6QOT59j//m9Nos2lhV7w6usFWFSC79pJctmbSvzgnKYViTUmDQIPsihy+1xlv25z16D6VjfW7kSJ9bfREdNnmpqaHRcApfjqH23Sf/q1ywsXko/x+7/9Cl28sEN//q/etvsce6pcLCqbRO6ukFlJmiWzb4YP1qsXqas290Je0SZHw39CY/JeEzvB9+AHEHiQj+gJCw+Pmb8nP9tQhefdKYZAyB6Appz97FX6zOlLSyfuE577yhb92i9epksXdiqpcY/eMHtc+XqpYKxe5YlzQfegpx9rJ/Fz48aNsgI//Omj55oYBCtOSIC7EvnKPvfkvODiu5h9AAqwtWnp1z9ycaHn27VcuzKi3/iVl2njS5uOVDJCnxq+D4h9kuBHNFwS/iTxj7CzbW/ceeedjW5d51bRExE90cQoWHH6JvKu7ano23qa0xZn3/XmIfKgKS+9uE0fe/yb9MfPbnXdlblxc9PS537jGv3eE9cZPQ176WqvPqjjCjVPFP1ZtTL/3dyiP9S1KCMIvEWYHjQj5AW3LPKsXdG2LPIqzx0KDxrwR3/wCn3iIy/R1Zd34oWXkKfP3qBf/de76w1Shd5PyhV7peD7lZLFP4UDB5qtoCeSPXgIPGgMJ5huZhsiL9mVbc+GBcnz8kz/ANDw+U9fof/06y8v7Xy7losXduj0hy/RxW/sDnJkoY+H79VirxD85LvcG863ux/bcIEdEQQetIwX+mYyi4i8M4/O2Y3bDs/LB6MFACiZzLd38YrXvnJz09Kv/uJlevrsjZCO+ym5Yu8mq6L0obvbW+FcUwOswOORtaAkuY+JTRJ5pp36tEDYtmZeXuXNAxBgFefbU/i9J67T5z55jba2LOu0z9CF430ZDghzgm77RXMebxPC0IEDB85ECkWRPHgiLLQDBYk97W68VdvIFXnO064b8SLzjv2IyIemHgAQWPX5di1f+dIm/X+/fIUuTm6lC0fn+VSFhvsp0bh94Wi9/N/WDftMvJU4AYHHQjtQllIiH3x2vWeb3+faqrdXn5ePrrIHIMBv/trLmG9P4OKFbfqNX36Znn3mJknqXlLsZQ9fFbsvHrEf7KHPN7cSEniDd8OD8pQQec8OuSJvRZHnbBcL2QPgsLVp6WOPf7PXr3jtKzc3Lf3Hj12hL/zWdRLVneq7SWKvcNj51KwYftJnba8pIvDco2p3GdBZQiQJtID4SNuJYioea+vZ8fZ3DYuPsp3sk2OfZm3M2pxlsI+4hcoDhpde3KZPfOQleO0N+f3feoX++LlteuBv3OE84pYq5yZNz2fn9CQ/VSjsVxIlXLYbLq3F2jIRdNGDHz/R7nyJRgBwCS+8s5Nkqm6w8+bB0DnvyeeF7Gcbbsj+5YsYCYM6f/QHr9DHfv6bEPdCvPjcTfrVX7xEFy9sOznhmL3sawc8cYWjrnXG00rPPiUW2BGFF9kRUfP78ACQyBb52kY1nF6xVS1omTnzgMinhuwvv+RedMAqM5lvB2W59vKIfvUXL9NXvsS9Yc8RSUZpw5odUfXM+facCH2pBXZEMYG3ozOlGgKAI1fkORGOrbDXzsvX7LFtzDK4BXhgNcF8+3z43Cev0uc+eZVujp9+xxNX97hOKxU9Rb11/Ia6ZAR5Dp6ICAvtwBzw5uSJpoNw6VWz083Aft32ROQT5+WZNsmOdyuNXbuyQ7fdsafJ1wAWGMy3z5evfGmTLl7YoQf+xzvo9jtmfir/7TOz8syUfGQ6XrDHEfgNKER+/4HBb8dL6Qh68OMH3lwu1RgAEsEV6oInP93kwumO7Sbz8mx0oPY/SxtP32COCqwCmG/vhosXtuk//MIlevYrW6HIvIPgVgsV85zxnMD87LOzs3NG+RVEiczBExE1f+A9ABpKibxoSzkvX2ujOvfPhOwnc/Of/9QV+cDA0oL59m65uWnpiX9/hb7wuVfIU3jKFWQmKXFaPi0iP2Nn275y4MCBcxlVWeICj3l4MEeiIm8jIl9Nc/br9mduewlv/tOnL9G1K1hNvypgvr1ffOG3rtNv/JvLtLVJJLnzzT3wQFaB6XlDRDdv2GLheSKNwGMeHsyZ8ANlZqLsinqed8+IfKVNrTd//eoOffAHnw8cFVgWXnpxm37lZy7QS94tW6BL/vi5m/QffuFi5Va6gML7uQqPW6HszaLzdMvtg4/mHLtEVOAxDw+6IHxbmxVFnfOy1fPyAc+dS3OF/vOfvkIf/1ffjB0aWGC+9HvXMd/eY669PKL/8AuX6JkvcmtiqmLPu/T5YfaGyj7+mAKviK2imIMnIszDgy6IinzGvHw1zZ2Xj4TsRW++ws/96NfhyS8hW5uWfvPXXqbf+QzWWiwCn/vkVfrsJ65EBmKRGL4iKl+avXv3nilpTynwo9MlGwVATVDkSSfyOSH7RG++ymc+eon+/t96hv7gd655hwMWj6uXd+gTv/QS5tsXjK98aZN+499cpmsv7yjFmJHwghH5GJs3Rr+n6mYCOoHfg3l40CHWEWFXgDmRj4TsOZHXPBgn5M1XOfeHN+iH3nKOPviDz0PoF5ivP7tFH/v5b2K+fUG5eGGbPv4Ll+jZZ7a8qLwOQa65EH/DwcD+WwYfb3CoYu9VDB8+d5aI7ivdAQBSMO4v1lR/xLMdU0mqbTr12TTjlXDaIa+d3/5U+Fapu+7ZS3/uu19Ff/Yv30FH33gLHorTIS8+f5NefGErWu78f9mkp5+8PocedcP1qzt0/eqo627MjW/9tr302jfsrSdaohdfuEkvvnCzm05V+Nr5raevXhn9m61r5udOP33vuRI2EwR+4zEi884SjQLQhLDIzwqIIs+lxQYOXDuVrM9HBN7l1tv30NE33pJUpykbT9+g61dxKx8AfWdtr3nBjujHtwdbP3X67P2Xcu3oBf5tGyfImn+X2xAARWE86qDIOztxz51Lk4X+85/Gw04AAGUxA9ocGPO+X/7Cm96fVT+l8PDhc5eI6GBOQwAUR/CoS4fs/XaMlwaBBwC0xdpe88WbtPUXU7155Sr6CbhdDvQId/HdJI3ZSVllH37M7cyut9IeAABaYPumfdNes+8LJ449eSilXqLA43Y50D/iIp+2yn5qM7rS3jLiDwAA5dnesm/YY/c9mVInTeBvEgQe9JL4i2Msk1YrrvPmvTSoOwBgPoy27ZH/6b/54j/Wlk8S+OGpo5eI6KnkXgEwDwL3rc8KtOXNAwDAHDD0j7RFE0P0RGTtqeQ6AMyL6Lw81UQ+2ZsPCj0AALTLzrY9eOLNv39cUzZd4NcQpgf9hw3Zu0+/iyzAY715Jo2I6OBr1hr2GAAAdOy/Ze1va8olC/zwp4+eI4TpwSKgWmXvePOM567x5tf2tvHqCQAA8BmsWdVTstI9eCKE6cFCIYl81JuPzc3TTOjv/BZ48ACA+bB/7+C1mnJ5Ao8wPVgw2LfDxbx5oqjnPkk/9Jo12ndL3ukEAAAp7OyQ6oE3WVckhOnBQhII2Wu9+Wk6k/aGb99fuMMAAOCzPRrd0JTLdzkQpgcLSjFv3ilw6FvW6DXf6rytCgAACmOs+aymXL7AI0wPFhm1Ny/fN1/bHacdeeMtEHkAQKtcv0yf1JRrtPQX74gHS0H0pTX1hOAb6sYbl76xTef+8AbtbOMmeQBAOfbsMRd/+QtverWmbMNVQfaxZvUB6AGSN68N2zOr7Q+9Zo3+1J+7jV53eB8W3wEAijEY6KPnze7tuUmnaS99uJENAHqCteR77pbIVj33yUjAmKnIm3G5ScVJ+p49hu45vJ/uObKfrl8d0aVv3KSrl3do84alrRujNg8FALCkbN2kH9OWbfx0juHD508T2Qeb2gGgTxjuzMgI29d2GZvu++evXNoJ90EDN20g5ItJkbbjXUvo/CI+Iyhp5iVcOGqKe5qiwoi3kDQD8THM7kJVpx1Vc87DJaSnROJR0DNeubLzoz/xa9/xbm355k/nMKNTZA0EHiwVFUe9kji+/kx1fZZQ9/KpslPZddKneXYm9Hcc2uN3hlsj4IwsRI3MEHs2WSHCoUFOkiGp5hwGAs3ERKjs3mKZaEaskynq/l0h1s8vJezcsUPYc7l8+62Df5FSocgpM3z43CUiOljCFgC9Q1iEV/njFSzl0Xv5IeVtKvaBjBzBZ4tG6/XZnY8oTqqQC4VTBN1LVou6XzgoqCWE3WlEGF+EBxirjDWPDz90eD2lSqHVP7gnHiwxwiI877Y6xUK82q6TPk1i0qf53OI/pzPeff5yUf7CzGR6yW5C4IJcK2ZnH96GlKH5aGhgn0uqfjQ9UZgVywpZoYZrvyemcPXfROov+3ty+u51zO2Sc8up9QrMiqn/KVeO0anUGmUeoL2HHqMdemcRWwD0FClsT0Rkq15+aCHedKey66RP82wl2XVsKxfdWX+qijxrm41A1IvWcBcZcpncNdiwiUyaYFpK1Pv05ZShiCVBcHMaZQU2VNZTXadMqCOcoDumQv2pN239Ytz3AlGPcX74oaNnUisV8eDx6FqwSkgejf+EPMZr8XYqPlXIWwt4NjWv2Lda9zQ5M1qPkikbyvIcxqBhmZCJtj4lOhe1m/BdqspOfgNehXE59ndSNxT01rnfTyWh/huvNyT9hqfpIIzNuyW94A26uCcerBCBi2Gu0NeSAhfDtBB+1djsCi2KvVM8WfAjQhUUrcZqWxhF39TdTvyeYt9BVdT5SpVyGlEPCXvoeNwWU4Ud4q4j88mx5QT+Jp0mosvF7AGwCJQUelurLgr9NDkkguKFOyz2OYKvErOQSEU+6oIFP+53ojwkVUHVMYbMihUrZS3JAuoco5jvVneaquVD2FvEfHQcJU+mmMAPTx29RNbg+fRgNZEumFx6RXm9y7Nz8eMv6oH8UN/q12CqtV5RtKB371RzxSBL/CIX/AY6nf3J7oyiuLZB9t/eMzAuW/33jf0OuCKhf/tKgt+N+o9K+i1Gf6NAxo6yo+Nln6G5NhoWtQfAolG5SErpVihcy5MukkLeNDl2ka+UUXv3luoXdtao/wl5wVobZVS53TaCxXNsVP8NWSPjOpV/n9DxiiH4imm2a4ywz3a8XzKEvR2yFtdNKCrw4zDCEyVtArCQBITev6AqhN56JoIhek8oYv30hMJV68omI94h+6z4y1lJeq1pq4lRlckmAwJXzJWCXkTUOWF3mg0Ju/c7dM1A2JuTubhuQpnb5GrYU0TmgfJ2AVhAJhdZ5hn3RFR/Ah5VrsiVW+ym+ba6UzNDZOUH6NhKwdBDdoh84WBvwZsmzYxMczUP0xHMsUW6fO5NAXHyxDOhERvO9kxEB1qhMpbdHCfUU6xYMKHPQMNl2qZTTQy0cvoMHz53jogOt2EbgIWGfexsKM+ERTP2XHnNM+VTnkqX+yS60L32C44viOqS9dwUYZS8c6E5zdjCH4xA2Dsl48l1Lu28x9LgyXYAsERCp/I8vRMWrWS7cVY3BBwNF7th4lD3rf9hLPofd9cJI3OfPiD1zVvUVut4/Iji3yPfkWDo3S3Htewk+r+n6kHFf0e1PFCWAmva2hH4LcI98QCECF3YHU2cpdev7hqxryVHFNQVL63ScmLlVxOlUlR51m5kUJD1CbQjVghadI6iZ/GWAAASuUlEQVQ6VcwrX5d7vKGvNbZCPvy7qXdsmi/9VqrfD2iDJ3JvjavSisCPb5l7vA3bACwboiiKF25fSfmLNnlGa8kREXcFUCv4XhcZcQ60pvsUU/mcSkzPhWNN+b5Ugu58VWKvkkTd1suEfjv1cQBoC1PmwXHtePBEuGUOgFRCAuhc0P1KzcQ+5t2TUzZL9LkuCwMAnckSCq9sIdDfnOP3voOQGevUkXqfIerVclInar8PMA/OD3/maJFnyrQm8LhlDoBMfM2u5bkX+lDFoNg3FHxyyjcWfu4YO/60chwxkzmCninqKm8dwj5n7LCUpfY8eCIiW66jAKwkktCP8xqJvZjoZ7GR7HC3w8K/DMLhHEtWJIKzQYG6TGYpUSc3H3TB5eHPHj1VylirAj9+Ag+8eACa4uu1l58r9taxofLwKU+wORvRQcA8BUdoOzSVoO5eRMw9G8J3IP/bNRN1CHsPKDT3PqGFB9244ME3ABSlKvKBd73bcX7lj1N5ZsC9rovPt+EeouMkhO7z1yBqzCKIj9BH9QBAm2zlCtbbSKoOuuNy6TvQ5vK8CTz4BoA5EHqIzjif2VQZ0dqNUcpOZ8REsy07GkHX2IWo9xdj3zf8maPDkibbnYOfgrl4AFpHGcYPz/Uyceh6Vb9OQkg9FIGPhuhTP9EG9R8pLB853GhhMav6hTCx8+p3FuqE972C/tLC82PmNmaGFw9AR8Q8+0q5yp+sQuoLyiJ461qUwhkcBEQMacLutSIQ88WiwGNpOebkwRPBiwegI2KefaWc5K3KhWytkNrDTfHCuyKjj9FiVddbuBfPMsVi3wc89QWnpefGzHUcDS8egJ6h9e7HZQO7cgVlA4vg1Ku1U+lyswMfrXkI+XLQkvdONFcPnghePAA9g3HGQ2W9eWknma0gPkmmXknrMHf58TsrHJsc+6hV1UYsWKcfLActPvV17oNmePEALBBpTrhXL5LUpcFdWKFMV89Xro3oua9sNu5Ow25kcfXlnfk0pOS+v3B7112YHy1670RzuQ/exQ6JzIfn3y4AIBlb+7OLJqzPiNM0KWuBXsjg/JCa3L5p6erlfgklWABafmfLnEP0ROPH8J2fd7sAgELEo+3R+twn9qS4Tj5S5F0ZWgdAxn6gxCthQ8xd4HfBXDwAS4Uk0qniz9jsx6Q7AEW5TDdp2HYjnQj82It/qou2AQBzRiH+i6KlQe8eAC3GPjY8dfRS28105METkbUnO2sbANAPQiH60IcKfhLaXbgRCegjxZ85L9GZwONNcwCAbBCGB4vKnLx3oi49eCIivC8eAADA6nC+9AtlQnQq8MMPHT1D1jzeZR8AAACA+TBfp7ZbD56o9fsAAQAAgB7wxHiB+dzoXOCHP330HBn7vq77AQAAALRGB1PSnQs8EU3eg3u5624AAAAAxbHm8fHC8rnSmxc4DR/eWMcjbAEAi8jVyzv0zBdf6bobS8Ff+Z9fPbe2brtjD912x55W2xgMaPPwd97y07fevufSHto5/R3333621QYr9EbgiYiGD587S0T3dd0P0H/ufv2+rrvQGnffs5zHtm+/oUPf0sHrL+bA17+6Rf/Pj/9x191YCt7/C9/edRfa4vJ+unHk6P13zuUWOaJOXjbD8+UnXxlevHDz7AvntuYq8Hd+yxrt3d+rcU4x7vyWvbR333IeGwB9Ai+aATEs0cl5ijtRjwTekD306rv2PvTqu/Z23RUAAACgJE/ce/+BU/NutB+L7IhoP20OCQvtAAAALBkD2unk0ey9Efij9995yRLh+fQAAACWCPuBeS6sq9IbgSciGocw8Hx6AAAAy8DlcXS6E3ol8ERElmi96z4AAAAATTE0Wp/3wroqvRP4e+8/cM4S4cl2AAAAFpknvvP+20532YHeCTwR0b33HxgS0fmu+wEAAGC+fO38ZtddKMHlPkSjeynwRAjVAwDAKvLK9VHXXSiAHd57/4FzXfeitwJ/7/0HzhDZD3TdDwAAACCBJ954/62Pdd0Joh4LPNH03niE6gEAACwEXd3zztGbJ9lxHL3/zktffvKVdUP0ma77AgAA8+J73nE3fc877pruX3jhJv39v/UMXbsSfiTum7/rNvrhDx+Z7n/kJy/QR37yRTYvxt988xe9fqTwN9/8xax6i4wlel9X97xz9NqDJ0KoHgAA7rpnL33P9+cJ7YQXX9gq1BvAY58aLxDvDb0XeCKE6gEA4K//ndfQm7/rtuz6Lz5/s2BvgMuARutd98FlIQR+/Bjb9a77AQAAXfIDP/L6Vt9ffv3qDn3xd6/RF3/3Gpt/4YWbdO4PbwRtXHjhplh/ebHv6lNofkKv5+Cr3Hv/gTNPP3n9A0TmnV33BQAAuuCue/bSX/+7r5nOqzfhi797jd6zfi5Y5iM/+aLXljuXr7Gz5PRm1bzLQnjwE954/60niexTXfcDAADmyYUXZuH173nHXXT0jbd02BtQoRcPtJFYKIEn6uc8BwAAtInrRf/Aj7y+o56AKpboZB8eaCOxcAK/O89h39V1PwAAYF68+PxN+vynr0z3j3znLfQ977i7wx4BIvvR8RtQe8vCCTwR0Xi+A6+VBQCsDB/8wefp+tXZffAI1XfK+f20ud51J2IszCI7l/1048Qm3XKOiA523RcAAGiba1d26Jd+4gJ97z967TTte9/92uwFbm/6M7fRv/2DN4n5q/igGi0D2jnR5WtgtSykB080vXXuRNf9AACAefHxf/XN2i1ob/ozt9Ff/7uv6bBHq0ffnlYXYmEFnghPuQMA9IN7Du+fW1sf/MHna/t/+/vvortfv3du7a84T/TtaXUhFjZEP+GN99968uknrx8nMvd13RcAwGpyy63z85VefP4mfeQnL0yfEX/r7XvoB37k9cmh+utXd2jj6fBDa0CNy/vpxkJFjRde4ImILJkThugsYT4eALACfOQnX6Q/95fvoCPfubvI7k1/5jb67hOHkh5Hu/H0jVV/QE0Slmgh5t2rLHSIfsK99x84h/l4AMAq8XP/4uu1/e9992vptlctxSW9d1ii9+1OCS8WS/NruPf+A2cs0fu67gcAAMyDP/ida/TxX/jmdP/W2/fQ9/6j13XYo2XFfnSR5t2rLI3AExGN/xFwfzwAYCX4yE9cqD3G9q57sNiuMAtxv7vEUgk80e798YRXywIAFoA3f9dt9L3vfi1994lDWfWvXdmhn/vRrxXuFRhzeVHud5dYikV2VY7ef+el//Lk1RMj2nOGsOgOANBT7n793tpb2YiIPn06XUt++1NX6POfvkJ/9rvvSKqHB92EsUQnF+V+d4ml8+CJdp9Xb4lOdt0PAACQ+LPf/argfgruY2xBU+wH+v6ceQ1L58FPuPf+A6eefvL6Mbw/HgDQRz5z+hL97e+/i269fQ8R7T6lLpdrV3bo7/z5p6PlVt0rV/LE7qvJF5+lFXii6UNwjhCZB7vuCwAAVJmI8pu/6zbaePoGXbsy88AvvLBVeyRtNa9rrl3ZqfVtuR6WY5/aT5tLc8u16boDbbPx5MVDm7T/DJ50BwBok3/8d57pugtLwcM/eA/9iXsPdNH05QHtHF/0efcqSzkHX2X3pTTmBBFd7rovAAAA+oklOrFM4k60AgJPtPukuwHtHO+6HwAAAPqHJXrLIj6pLsZKCDzRdGX9W7ruBwAAgP5giB5fhhXzHCsj8ES7K+vxOFsAAAC72I9+5/0H1rvuRVuslMAT7T7O1hA93nU/AAAAdIl9apEfQ6th5QSeiGg8YsMz6wEAYDU5v582jy/yY2g1rKTAE02eWW+f6rofAAAA5srCP2Ney8oK/NH777y0nzaPE15MAwAAq8LS3eseYmUFnmhX5Ae0g3vkAQBgBVjGe91DrLTAE+3ePje+Rx4iDwAAS8qy3useYuUFnggiDwAAy8xY3E913Y95s9Qvm0nhO+6//eyXn3zlpCH6cNd9AQCAVWXj6Rt0/eqokY3BgDZf/yf2n3rVnWtfH9Do7Bvvv+10oe4tFBD4Cvfef+DUl598hZZN5K9d2enV26hKcnPT0sVvbHfdjdZ48YWtrrvQGi8+v7zHBvLZePoVuvC1Rr+Ny0T2+N9867eszFy7xNK/Ta4Jw7eeP0XGPtR1PwAA/eepz17tugtLwbe/6QDdfnBPbvXLRPb48GePrry4E2EOPsjwQ4fXyRo89Q4AABYCexLiPgMCHwEiDwAAi4B9y/Bnj57quhd9AgKvACIPAAB9BuLOAYFXApEHAIA+AnGXgMAnAJEHAIA+AXEPAYFPBCIPAAB9AOIeAwKfAUQeAAA64zJZ+5cg7nEg8Jnsirx9V9f9AACAFWL3PvcPHT3TdUcWAQh8A4YfOvoYkX1L1/0AAIAVAA+xSQQC35DdMBFEHgAAWgTingEEvgAVkcfb6AAAoCxP0R57DOKeDp5FX5DhwxvHiMwZIjrYdV8AAPPlmT94xUvbd4uhvfuX0486cNuA9uwpLyEHbhvQnrWp3afopj0+PHX0UvGGVgAIfGEg8gAAUIQn6KY9AXHPBwLfAsNHNo7QjjlNRPd13RcAAFg4rHl8+KHD6113Y9GBwLfEcH3jEO01ZwgiDwAACdgPDH/26Mmue7EMQOBbBu+UBwAALXg6XUmWc/VHjxh+6PA6Gfu+rvsBAAA9Bk+nawF48HNi+PDGOpH5cNf9AACAnnGeyJ7AbXDlgcDPEaywBwCAGrgNrkUg8HMGK+wBAICwUn4OYA5+zgx/+ug5ummP4210AICVxdp3QdzbBx58hwzftjEka97bdT8AAGBOXCZrT+BtcPMBAt8xw7dtnCBrThHm5QEAy81TtMeeGP700XNdd2RVQIi+Y4Y/c/Q0kT1ORE913RcAAGgFax6nm/9/e3dz28YRxmH8mZWSMzsw2QE7CDsIO8gepEC3MB2MO+DZ9oHpgOqA7ICqYKUOxGvs7OTAjUIjhkyFH/v1/AABFAQIc/vzfeedmTQx3C/LCr4hYl4MuM7mXoojqVNS+j1+Gs3rXkYfGfAN43l5SR3h+faaGfANVJ2XXwLv6l6LJL1duOdzmXu+vV4GfEPtHqvJFpB+rnstknQwW/KNYcA3XLwpZoQQccpeUrPZkm8YA74Fqpb9Am+/k9RItuSbyIBvkXhbzCH8Vvc6JKmyhTTzFbhmMuBbJt4UE0JYYsteUr3WXKXcs+3NZcC3kAN4kmoV0vv4YRTrXoZeZ8C3mNfcSrqwB0i5g3TtYMC3nNW8pIuwam8dA74jrOYlnYlVe0sZ8B1iNS/ppKzaW82A7yCreUlHWlfH36zaW8yA76hdNU/03LykN9iSUvSq2W4w4DuuOjc/x1vwJL0q3HNVzjzX3h0GfE/EX4tICjNs20v62hMp5fHTaFX3QnRaBnyPxLtiyF/Z3CE8ScCWkOYO0XWXAd9Dtu2lvrMd3wcGfI/5FK3UO7bje8SA7zmn7aVecDq+hwx4Ae7PS50V0nv+ZO5b7f1jwOsr1f58BH6qey2SjpDCH1yX0X32/jLg9U3xtsghROBdzUuR9DbeQifAgNd3GPRSa6yrffZV3QtRMxjwOkgV9HOcuJeaxmDXNxnwOljMiwE/MvNGPKkRDHa9yoDXm+0FfY6te+nSDHYdxIDXUdyjly7GYNebGPA6CYNeOhuDXf+LAa+T8hy9dCKeY9eRDHidRbwtxqRsRki/1L0WqUW2hDQnY2Gw61gGvM4q3hVDSnIn76VXPUGKfGbplbI6FQNeF1Pt08/wmVqpEu5J5dz9dZ2DAa+LizfFBLLc9r16yja8LsKAV21iXgy4JieEGU7fq/vWkBbx42hR90LUDwa8GmFvKG+Ke/XqjidCWlitqw4GvBol5sWAH5hCyPGondppSwpLsnIZP4yWdS9G/WXAq7HiXTHkC1NCyHEwT40X7qFcOgmvpjDg1QrxthgDOYQp7terOR5IacE1S1vwahoDXq1j2KtmhrpawYBXq+2F/QTb+DqfNSktDXW1iQGvztjbs5/igJ6Os4Wwck9dbWbAq5OqN+snlNmUkCbYytf3PUBakVh6s5y6wIBXL+zO2TOxutee3XG2UK64YmXrXV1jwKuX4k0xIWNCChMM/L7Ytd1TuSKwih9Hm7oXJJ2TAS9h4HfUE4SNga6+MuClb3hp6ZONCWmME/ptsIa0ATa23CUDXjpI9TDOeFflZ2NIYxzcq9OaFB6h3AAbh+Kk/zLgpSPsnr5lTGAIYQyM8bGcU3oCHglpReIR2Nhqlw5jwEsn9lLtw5iMQbWvP8A2/2vWEJ4Ju4qckmercuk4Brx0QdVlPENC9VNmQ0Ia0v0vAGsAQlpVv28oeeYLGy+Rkc7DgJcaphrwGwCQMXn5w64T8I+6vxCs//34UnlDyTOw+3zNo4NuUn0MeKkj9rYGTvt/bZVLkiRJzfA3oB6MypRiEO8AAAAASUVORK5CYII=","e":1},{"id":"image_7","w":132,"h":390,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIQAAAGGCAYAAAC6+ykYAAAACXBIWXMAAAABAAAAAQBPJcTWAAAAJHpUWHRDcmVhdG9yAAAImXNMyU9KVXBMK0ktUnBNS0tNLikGAEF6Bs5qehXFAAAgAElEQVR4nO2dbagk2VnH/091z53x072LEHc1Mj0hMYQ1zI0aXGFxW1AI+eC2IRuTsCEtMTCEQDrIrgmCuQFldFbcuxJ00ZDcoJg1+DL7QQwY2DsiKCLODGF3TFa5s2bNxPXDZkTJ3Jnb9fih6+W81Vt3VZ1zus9/t+ZWnTpVdeqcXz3Pc069NCGodb3nwZdmTDzi4d29y9fe8V3b5Wkisl2AddNk98ZoMI+vMbAN4DaA2V9+/cEDy8Wqrch2AdZNgzjeB2GbABCwTcAX3/P2Fw8fe/DFXdtlq6NgIVrUe3dvjBHzC2o6gxczMZ6ZO+5GgoVoUcTYJwIoMQ/pROl/EX1iGJ+++djbb0ztlrRYwUK0pMd2b0wJ/EUWE1nOIy4S6DoTZn9+7W2H3ZeuvgIQLWiye3XnNJ2+xsBZAKUgiAu8+OdLJ9HxzBU3ElxGCzoTnZmB6CwRgYgkd4HEhWSLgkshAijCh0/x6Zvv3X1pZvMcUgULsaKmu1d37gzO3GRgW7UMopgNKzVLQtcZdt1IsBAr6s6pM3k3k+RJvNxS6yFOuiXh8xH4hfftvnQw2b26Y+N8goVYQe9/6MaITnCkprM2o6yrZ0lug3j/K//y4N5KhWyoAMQK+sA7v3FA4A/n7cvSH1ErQPIKxZg+15MbCUAsqQ++85u7RPHV0h6EOLcqJMTP05xmz117280liltbIYZYUhHF+5U9CHFQSgowkjzKduKAlhaTgB7lAa69/8du7HV5XsFCLKHHH7oxBigbojZ1IBqNRYhz9SzJKyBMn/vn9t1IAGIJfein/vUQoEeMXclEvUDC/DxadiMBiIZ6/OEbY5pH2g2sVKtAoq2uCQkBn906ubN/0MJoZ4ghGiqKaa/xeEO2rmCsQos78hhCX6fHJEz4zPHWmWsf+PGXJqueX7AQDTR9+MaYOXqh7EqWkpqOXGbrTIklh5PXXeEBT5/7x+XcSACigaYPf/OQgUdMZts5SMCf3bp7Zv/g2rlGbiQAUVPTh18eg5SHX7jctzsAySsMmn35n956ufgIsgIQNfVLP/2NywA9ChQ0RCoHISHGlZOonhsJQNTQdHxjFPHgqAwEHyBh4Jmt49N7ZW4k9DJqiDDYA8jcS0jzlKyTegnS3c7FVNa7KBy5XKJ3ExE+cXLm+OaHHip+hC9YiApNxzdGAwylO5ry1WoI53ywJES/8Cf/oMcWw5LiBQEYRKdmlFRiWtkECJcSSesAgKgYEjJcghkkJF6h+Vy+mtUEre2JoV3mctkIAF/5YwMMQACiVNPx0Q7hZJpWsMmcOg+JVjYginjPcCoAAhCl2hqezJixnSUwwErjOQ8JyesAfOng74tvigUgSkXThYVNKpSEyk61IiRqKNIxJLfpJN4zFC9TAKJAF37u36YxJ4/Vmyq7CJL04qwJCbGaoUNIiPcPKsYiAhAFYvCMDLVdekUK1sI9SPgVRFv7hkNKCkAYdOFdL48R03lA7102NtuOQBKB9r5wWH1fIwBhEGEwBbHSENoIgUeQ8Ctf+Lu3Hhh2oykAoejCu45GQPxhuSEBsZfgGyRAVPutsACEoiiKp2DUbAj3IQFw5fMvvLn23c4AhCICpoDYEII8hAQR9vQjFCsAIehj7z6aAny2arzBI0iu/NHX3nKo761YAQhBEXiqjSxKDeEXJHHJEHWRCtzO5mk2ORrNT/goXa5/x9IAiXEjY24tUQVBXGlIKivblT/82pvHxTnNChYiUXwSz8TL0BjFG6/WCkuiWIsqS6IfN99bE0tC3Nw6AAGITBRFUwBCq+sX4lKQ1AgA24YEwJVn/7ZZ7JAqAAFgNjmacLz4xgObrIRnkIDKb2CVKQCx0BSlDeETJHzlD766nHUAAhCYTY5GAB6VGqpWQ7gJSYTlYodUGw9EFGEi9hrkhhDkBSR85XN/s7x1AAIQAGhGaWNx2hBy0/kCCcAHhs0baaPHIWaPHe1GMV0FYOzbs5RugMSkGuMN5nWGrmRhgvH4r3zur980KihVbW20hRhwNMs78IarVbr68pFFJy0J0Z6atIw2GggCT8TKzhsiT/AEktuDAWrf0SzTxgLxK+/7jwmYt4Hyym4bElZ23AokiPf3L7+plU8jbywQBJ5kddvwilwFkvwI7UFCUXSAlrSRQeVscrSzdTp6vesAsFZwKKUbIKkoGxG+tH/53LQkdyNtpIU4c2YwiYXK78q392RJDtCiNhIIBiYEUm8ISY3lCSTXn/6rc4doURsHxN70aOfOMRYf/hCblpMK9wgSgCvfs2iqjQPi7t3BRAvehMr2CJLbv/sX5w7QsjYOCBAmZZXtDySrD1ObtFFA7E2Pdu6e0KPZ9x6E1vENkpMhWncXwIYBcXc+mCxuZC2qWG4InyDhK/vPnbuJDrRRQBBoAsD8BLNPkHB7A1GqNmZgam96tHMSD19Plw1jQZrM34Hk4s1qDkqxMd0w2GU8Pm5f+srZzn5+aWMsxBynJunb0QwY3oHUG8KWJSl7uppaHohStTFAMDBOv/cg9+n9giQezA/0ErSnjQEiIkzMfXoSfHua5iwk15/603PX9KO1p40AYu8j354wx9vG4E26IoW1DkJC1M3Yg6iNAAJxPAYVNVIu1yHhedzKQzBl2gwgIspHJ9NGLG2kXA5B8vzFjsYeRK09EHsffXWXGGfzhkgq29DhdxoSaucRuSqtPRARR2MmrmgIxyEh3N6K5gGIVkRx8uxDnqR1852HhC/vHTT7ZZxltdZA7E2PdoiiRwCAxaYoAcFFSPpyF8CaAzHYOj1OK5bE2s9m7UAiv21VCcnt3zj44QBEG6II8s8WJhWet68dSAo/D2SGpDcYgHUHgjBO50tfmFEhURrbJiQRol6BMBRjPXTxwq0RR7zc72Sx9MewIEOirpOSGq6TIAFu733hjZ3d2TRpbS0ED3gCpuYBYJElkfbQlyWhXq0DsMZAEDDWArRlewm2IOk5fgDWGAgQjbPZLrqSPUCCk+NDw6471VoCcWn26m48F34aKZE0HuA+JM9/pqfBKFFrCQTHgwlRXumc1HBZIwFuQcLcf/wArCkQQOIu1EEpwBtI4giHhlWday2BIMIjapr+oqw7kBhe4r2+9+wDNw3F6FxrB8RTs1tj4w+iF12pgHVItLIRW3EXwBoCEQPjuqNtzkKCAERrIuTdzaW2tw/J7V/7/Td2+iBtmdYOCDB2295lz5BYsw7AmgFxafbaLjjWxh+6UGeQkJ3eRaq1AoIQj0vuZXV//BYgOT24EyxEW2Lkt7tdUUNIrn9yv//RSVFrBQTQfvzQhYogYdh1F8AaAXFxdmuE9MfbPRQRAKJD2+WIbBegLUWIvLAOZfrV/R+wGj8AawQEgce2y7CSCFdsFwFYIyDgSfxQJAYf2i4DsE5AsH5DyydFDgSUwJo8ZJsMSF21XY5V9OQz9zvRFmthIQjx2HYZVpIj8QOwJkAAFOKHlrQmQLDXQACRtbubqtYCCGact12GVbSFrUPLRcjkPRBPzW6NbZdhFRHh+if377N6/0KU90D4Hj8A5Iy7AAIQ1sWID22XQZT3QDB4ZLsMq2kQLESr8nuE8vaT+28IQLSlS7PXvHYXIDgFA+A5EL67C5cGpFJ5DQQQ+20hHBqQSuU1EKu+g2FbMeIARMsa2S7ACrr96X0772+WyW8gPH6G0sWAEvAYCN+HrF0MKAGPgWC/3QUIuGm7DCYFIKzJrRHKVN4C4XsPw7URylTeAgGfLYRDj8yp8hcIj3sYBLppuwxF8hII3+9hxIhv2i5DkbwEwvd7GK68g2GSl0D4fg/jxNEuJ+ApEBGike0yrCIXh6xTeQmE1y7D4R4G4CkQXXxYrC+53MMAfAUC+ofNfZHLPQzAQyB8v6nl4kMxorwDwndFiJ15Kcck74CIHfzSXBM9sf/Aoe0ylMk7IDzXbdsFqJJ3QHh9l9PRp6REeQeEz3K9ywn4CITHb2q53uUEfATCY7n62Jwor4DwfQwiABEkaYgzIahsV35/C8KlL8UUySsgYnCvP4zeqgiv2C5CHXkFhOfPQdy0XYA68goIr5+DAJx3F4BnQPgsBjsfUAK+AeHxoJQv8gsIj+Xyk9aivAHi4uzWyHYZNkHeADH0+dU9uP3ovShvgPBdLj96L8ojIPwepfRF3gDh+Sil0+9iiPIGiKB+5A0QFFxGL/IGCADeugxXPzBmkk9ABPUgn4AY2S7AJsgfIDz+hJDrr++J8gcIj+X663uiAhBBkrwAwvePjPkkL4AgzL3tcgLuv+ArygsggvpTACJIkidAhGHrvuQFEJ7f6fTifYxUXgDhuW7aLkATBSCCJAUggiR5AYTnr/B5JS+A8PwVPq/kBRCey5sbW0AAonP58k5nqgBEkKQARJCkAESQJF+AGNkuwKbIDyC8fp7SL/kBRFBvCkAESQpABEkKQARJCkAESQpABEkKQARJCkAESQpABEkKQARJCkAESQpABEkKQARJCkAESQpABEkKQARJCkB0LN9+q3xouwB19N/fPv7M1hn6icEgeitF+JG+j3/8vRjzOS+1bTzn11suTqfyAoh/v/G/n7VdhhV0n+0CNJHzQLz3R78+ZrJdipXk1e+EOQ8EhgDi/g5H8Ju+VeV8UEnz4YjQ33/lhVluemz3RW8+ieS8haBBPILnPoMRefNJJOctRAwaLXtl2p4omQbgYCHaUkT+v7XF5M9H05wHgohGtsuwqnwanHLeZQD+v8bHHv0akNMW4oPvfHE37rHL2aHO2y5AXTltIWKOdkxBmo/T+x+6MbJcnbXktIWIgHGtOwg+9EpPMIIHHzF1GggQ7fjQ1nVEEY8BHFouRqUcBwKd9d/7B82Pb206DQR1CETfIvbjW5uuA7Ftuwytify46+lsL+Pxh26MbZehroio1jT1oKfhrIUgDEag5Z5SclUnFO3C8Z6Gu0BE6xM/pCJgF8Bl2+Uok7NAAPEuaF06nZmch9xZICiiXayXxwB7AISTl+B0fLSDk3tePa1cW8NT9x0cnnP2C/lu9jJOTnZtP9zS2XRy4rSVcNJlRFE8ZjeN18pKAstD2+UokpNAMGjUxn5cjEk5cvtxOieB6GfI2g4txG4Hlg5eQ8BHxi+vWf9C1hxDZwNL5yzEL49fdvJNrTaLNOQTZ+MI54BAhF0HeWhXhDECEDXFvEsuRoPLqPg0nI0jnAOCItp1NLRpTeQwEM4NTBHRedsPxHY9gXD2wruORrbr2iSnLMSFn3UzoOxCcTx38la4UxYiRuSsKW1bxBjbLoNJTlmIaPFk8qbISfidAgJES1WSp17GyWcsnanL2eRo5/hOvJ63vAvEiH/m2a++5dB2OUQ5YyGOj+fj3j7n48hlEC1ipkPb5RDlTFBJRP09A1FWjh4nsHufCXDGQkTgMTs9QtlB2ci9noYzFgIUPVL3/QY7UyeDVNszxwaonADiY+8+crILtorqQjE/5ZaVcMJlDAhjVwK9XiScK4PHAA4slUSTE0CQ44+VdSmCWxbCCZeBiMbW7zjZm87OJu7EEdYtxGxyNOJY+LDYJrmOXGM44jZcsBDy+EOB+hobsDHBIbdh3UIAGNNmWgVRY9sFSGXdQhAtgNjwyZk4wqqFmE2OdkDU+zccXTRIRG50P61aiMEAY0s+2yyLgQRRNG5Sd13JdgwR4odMbjwcZDeGiGhsPcRf+cpubTr7qffbjyOsWYjZ5GiHQOeddOiWNJ9HY1iOI6xZiK2tgZX4wfpUYiWY7LsNaxbChZN3TREwcaAMdkSgMP6gTCBsP/GY3UcBrFiI2fRoB3fYOP5AfRfGNQ2jMYBr1g5v46Bbx4v4oZE2hJTkBZ59W8e3AkQEGq/bV2pbE+FRm4e3FEPw2LMxgl6nTz3+rXFvTaGodwuxNz3aOb7nz29QWVGMCSy9r9E7EHfvDibkajzgSMEii4/n9+4yKMLYuk0u7PcVlLnvYhDO702PrPy0Y/8xBPk3/mBDd+cDK4NUvbqMvenR6CT2/4dZ+xBZes6yVyDu4dSENry7Wd/gkBUL0avLiMBjwmb/h6JJ91Xbe9NXex/G7rmXsXj+wY1Y3n3F4Al6HsbuzULsTb81JsI2lVwkYVKn/t1Gfy4jCk9XLzH13v3s0WV0Q7utbmFvik5N0GNvoxcg9qaLx+3Xve06EdEY6wZEdOrUhDe7t7mKeo0jeokhmKOx/QCtenIgZjBMvL330f66n70AQYSJA+1dORWfgN2JIkyr6rgtde4yfvOjr+7GhO2KKg8qEfX4tbrOLUQ8oIntK8zKVd3udP7ihVujVhqkQp1bCEICRNBKmhNP0MOzlp0CsTc72qHj8HRUK+rp4dtOXcapu2esv3iyDqJFYPno3qz7UctOLQQRxiGYbE9bx6fHAC53eYyuY4jW4oeAFYDFzS4/gbj48VtjMLa72n+mzSKlcxfcWQxB4EkvI3komPo4dv/T9sWP3xp31WZAly7DwS+9pyKfzUrU7TsbnQBxcXZrRHH/HxPbBNHCbcy62n8nLmMI6sddbOZ09tLstc5udnUCBDv0Ic51FGPeWXDZOhBPz17fAdt9g3ndFXX4iH7rQNzDnTA62bGYcf7irJubXa0DQYjGbe8zSNewIyvROhDMHCxEP5p2sdNWgfjt2X9NgB5GJ4M6cxutAkGOfJ53U9SF22jbZQR30aO66N63NoZ7afbaLji+2tb+gurpFJ2+75P79323rf21aCHiaXv7Cqqrtrv5rQFBYXTSktqNI1pxGRdnt0YDpqM29hXUXG26jVYsRFeDJEH11KbbaMtlTFvaT9BSau+CXNllBHfhhtpyGytbiOAu3FBbbmNlIDgMRjmidi7MlVzG07PXd+7x8ettFCRodbXhNlayEOHZB7fURnus6DJC/OCWVm+PpV1GcBdualW3sbSFCO7CTa3aLiu4jOAu3BRNV9p6mY2Cu3Bbc+Jzn95/4OYy2y5lIYK7cFurDBYu6TKCu3Bc02U3bOwygrvwQ8u6jcYWIrgLP7Ss21jCZQR34YN4yTfEG7mM4C48E0XveHL/DY1+gKWRhQjuwjc1f/C5octYbdAjqHc1voBrA3FxdmsExiNNDxBkUYyzT82afZOqNhDhyShfFU0b5W6Qt9GOg9xQ07fxawFxcXZrxBy+We2ptpO38mupFhDBXfgtAk/r5q3rMmrvMMhBMR59evZ6rQ+nVwJxafbabnAX/qvuGFINCxHe6l4HEajWUHYdlxHihzVQ3U8QlQKx+AgIzrZWqiCrimrEghUWIriLdRLVuPVQDgSH3sVaiau/k10IRPjE4HqKwKXBZSEQUQgm11JVQ9lGIJ6evb4Tvki7ttq+NLs1LVppBCIZxAjuYm1VfCuiwGWEexdrrZKhbA2I5EGY8HsXa64THE9N6RoQ4c7mxmhqSjS5DGPGoPUSM86bxiQkIMKdzc2SaUxCsRBhqHqTxMwTNbhUXUaIHzZL2+pzEhkQ4c7mporMQBDice9lCbIvZUwiytODu9hU3cXdcTqfxxDhrayNlfhbaREANH3dK2i9JP74TQQAcfg1nI2WOPYUAQCBOvu1+SA/lHqJRQzBwUJsuhgYAcAw+SqMk88+nNxjMHNxBpb+9C5mgGOu/A6PtpoI9+7GiOeLbUnLTHkaaavE3UgbSsvifknZFQGDQYThqXyDDIgT3NlNs87njPkJI46BeJ43BvNiC04W0jaS/jIn65H/TWaM+dP0gnV6mrDvtBx5VmSz4rJESk7PKgCpjZIukNLqxY1D0j5Ia2ChYSk/HinbEsnbSHmzdULZkvVE6X7moAg4830DDIaUhQ1DgHbBwN2EWLFSiRaVSgCYAGKAQSBKGpPyvHJmMSnPn2XJ0oHkiNlmi78EMKTtwEkZkM6nVxHnRUh2kJ6DegWlZU63ay651VUITFd7IQjivNqo4r5LYIC6XREM0vHyBGbgzvfmOH0mwnAr2gGAYQzeuXeXwXGyw+QKShttUbPIWwvI6CChkRYNR2DmpKGRNUoxFEnBmXPgSGjYZDsox8kqQAQjgZGRb59kkQCVWis9nTI21EauWq+ZZ938m6yCbg3k9aRuS1g4FnU7IY/0V80vrL97zIgivBkAhvEJfj5t7BQGEQCC0MiStSBwCgXkBm4KBYhAChTZdqlJhmAtYAYDAEgAY7Estk6ybfaP3kClUhu7KD0ti7reBIKYrkGhXOVVMBAKAdLyZeVYzJ2cxD8EAEPE+MHczCtXftbYSSMD2pUsW4jloMiudAEK9WrPrIVwrHTeCEaWMcmXtgTnlbK0TGAIra3uXwdhkUEDQZwvgKHMoqRnbrYQpOcX1sfzRQ0NGXw6TVw0QNGVnzdQDkPSiGq+hlBA3B8WmcVj5fEAJdvpYEgxRrIMotxSZBtAUt1IQrcKpK+nkmWlxXUAxO3MgWclDFQAg0qwCUosXr8YphtpwaN25dPCbGsWgiRz3ggKoWxZQKm6EGG95EYUMKRKTkFK959RQRoA+TYGNEp8CWkzwmITEMR5xSqI86orqAODmEEHRShA8vfeveOHhxFFmHOcwSBd7mlmFnYu9iTSvygPGlMoIG1GCVAsgALZhQBSwKm6kdxipHsuh0M497wwas0XqWC1CoC+uxogJBuYrILJFehmnxQI0jzysSUYhLKLxx1KOxEbBoLrSK0BlKtecCWo6ElwApIWfyQLpu6laC1UGESLsZiVrQZggCNbkYdMTVRkFcTKFTNIjJG+fV2roLmVWlZD3k6DQSpDkh/AEEmjMPRGluIJoZGWhaKqeyn6e1YbG8jcyGIeORjCMkAKLAogauMsKdmgUEG6ciwTCGK6BoXSqFJepWGLLAPpeeRg02QhYGhk5FdwZfeyJhRSbKD4+dSFSNYCxW4ksxhANpOBIJwgZyvECq8bShaJpFkNLjWtCgRxXgVB3N8yMEDMU9QdTep1mFoI9WqGatZNQWZzKPJGZakx5fEHwVpIVkLMn1YqywGkEKXqlkNuoQyJumyQ9Kd6nZpmAEFIFhpPblBxGwmoujBkFqIg6CS5oJmFkCgA5KAxvbJhgMcAxWJzueFld5AMWxviisUFLViLpCwaGMl+shNXB6SUzFK7c76Pxr6DjLNSggpBlmYCIZuvsgqLBT3NsH0JDBD+pnGDWJYsqBSDPC2eSEmA3iMwQZHvzzDYVBRXJAWSA8cSMIR544AU0n0I9SAt6FKNRSkrVLBYBoG6LCSoDVZmFXSXoMCgQmTcjgx5EyBE48BJZs0VpA2/FBSo7F6q1gKoD4Z0ZQlwZBUrdqFR7CXqGgspnxJFqo2uZREbUVxWQMi3k2HQG7fcajSBAQCGGgxZ8LgaFGpsoHYvZRdisBYVYACQrQQMcGT7MTSalAHFMrVwjdWkpilXs7qtPq9YBXFebFRxu+xvmUUxw5Buk3c763Yva0Ihu6G0cYW4QnEhQBp3oBYYYrdStRqpCschkvxpbbExQ1aXFQnCqkII8gUSFrM/BhDE2arAU4aiBgza/vNjChaiXSjERs1iuyIXkqwT45V6YCzOlIQDpPsyNhBy7yE2bEkbF8q073RnKgTSMQwg5PurZxXE7ctgKO2BGPIAiYWQexSoN+aQNrzSk0j/ZtZAamjoLgQF1qIEjBQGdVmFI1UVJCtJBUD/o8OnQVEFQj4jAyD+rQFD0XbCOcg3twRzD0C5+s1QQOlJ6COQ0OOKbPdysJilV4CRnb5oNZLldCeczwiVKAcLxtDBYEEMi3KKCoBptbYsYGQCIclYbRXyxCZWw7QdII1UGhoeqIRCdQPaAy4mF6JYi/TKFt0IUAKGMCCV1Z9kKXRAFotys5KJiDILojNQvV5r7Log5DMmq7CYVyyLBkV9GCQLIRaqKRSqG0ihEF1A7kIKrEU2v1ihBol6b0I4GXW0MklKF8Q214xEWeOXybCdCYBsUbQGSp7aIIjzwkJZ8Ciu1wLIAosiAZFuqHUhYQgoK6BIj6HHCHmjyzCk8+WjlFJvgpOrvgAOqe4VV2B0FxXSOCgCQ211KA2vLptAEHZRyypk88VWpbIHAgMQ6QZaFxJC0GgCBmIeyl2EyVqoQ9cQwEK6P+HhVKWrCkP+RRppaWm3Qu1aLmscjPswAWA4iApB/qcABHG+0irkK5aCochCiIUvHFdA3vCmrmdZ99JoLbRYQbYeQLHVyLZRKzzbl1BJ8lrpT6VMLVxjtdarUayBtFlTELJ5UvLXtCqkrysEIs1UNdhECSGFLiTBR4dhcYy0J9IMDGT71ODI/jE0RpqHAWitUU8VXOgWSktTQCApmxEEHQBxFelpUsPL6+V8CiioACLNnPcU5J6E3KMocCFp7yC1Fmk6ANFyoAAMNcZAmt8EByC5FeS7kCxBESiNZWp85McnfUGzBmp5KkHI5nWrIM5XBY8mGIAaQKQb5Ve+/mid6AKKXUhyEgJUaePKj8XJYOhWogCOLC2JGcTyGyBpVZqxqQGBulwbhHzGaBVgaGwJCjNIqWoBkW2s9CSEizi76lUXYuxemkYphXlAdCXIA1TkByzuZpIhPcejMGQoWmGoNDItUUGeEgiA+iAs/lRZhXxDbT81YAAaACHuPAsoDXGFZi2S8xGvdtnk62CoYxDigJT5drdURAWQLFVfr5xb3TooTTKBUQYBlMapAkFMN1iFQhdhsComNQNCOIGiuELuUSjWArobqQ0GILiTRUrx7W6hrMo6PbG8o1FYdwUriipchUArdxMQxPkKq7DIQ0Leci0FRLpzLa5I1lV2Lw1upAgMdX/psgwHUAhItoEMinQuy5x/xcYk/5MlmqxJXRAAKHFBgVUQ1xusSZGYaGtpIMSDFLmQ9FzEBhTdSB0wAMVqCMvZiSTdSBWQ5H+94juQZgGyFYZUozWQVxSCAIN7EOdVq1BQLJOimFcDIi+gwYUAQhCJrEFFN5KdhAgGzD0HoYepWAqd/mycwdQYooNgaan8HLN/pBljRsvbrqYAAALISURBVBMA2lYGa6AfpwAEMX1Fq6CqFSCyg0vdy5I3uZGbOwkMwDgGIcLBQo/B9Ni9CRB5fYkJb3TCJduWALCYJT1fKRSGMhu2NQLTUK0BsShF4iLSnoHQgOaHZwUwhPELZPsQ6kWELVmW3EqWlhdHggRixhZV5o5Ud6BkLLMGi+UCeDUoVrMKotoFIpEaW5jcCGB2JVLwmeYHJPcC6JYj3aHoAkiiRVZdVyGdV82VRQBkiyVQZGZfWlbmTSBUFrCeOgEiVeEoJVAIhth7UN2JNiClpElVKQQdpcMOdcgoqWhSM1QAkKVr1kDIqECg7oeUHbQ2FI+OgQCguJEmYIgm09ylLBqHAAogEdaL5au5sn6yCQBDeunYRMGV30acUKT/+5/vXe4eiER6bKCDkbsPZJVQOCAFvUJY2E6rK8F9FBuF6hqmwgVDvkLLUACBsKovi5CKwVf3Ds7dGQK4CaC3TxuXgQGgdMyhdEAK5opq67H7MpU2kBoTZGnyslQuQ4xQeZwVRYTfAxafNv6t7g5TWgC5L02UV0CyjpJ8WZq4XTqBFttmE7RKrD1BmWpulx8sTRPKo55T2sal57nYNgNDPU77+s8n9x84AIDoyWfu/zMA3+30cCVSK6mwIqFUWhkgGiRmWPTCKFNBHq3RxTIXAFAXghQE6dw6FhF+J51PY4gLAL6M8urqVoJ1lNwJILuUZDldKBuHELOmfdesYVoqs2FWSyRDWlYaZcM+AFCOd/2J/fv30+UIABIr8etYrnveujRzXGA5pKsNiqWQL9Z6pl/db9VUcFxpvVYe2RIYz7cvEa4McXosJwm69Inv/CKAZwEYfyjcttiEKxeMNNRLWlplFkFO0q0AYKHxgcsAXQX4J0F4GeBradwglcu05VOz78yY8XEA3991KZdW0Y0pNs72ItJmlHW2HDLhiSf37/+8paMH+az/B/aPm+SpKWB+AAAAAElFTkSuQmCC","e":1},{"id":"image_8","w":199,"h":389,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_9","w":245,"h":343,"u":"","p":"data:image/png;base64,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","e":1}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"ball head","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[535.095,255.22,0],"ix":2},"a":{"a":0,"k":[46.001,25.171,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"ball","refId":"image_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[394.924,534.767,0],"ix":2},"a":{"a":0,"k":[46.798,46.798,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"Hand","refId":"image_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[11]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":178,"s":[11]},{"t":238,"s":[0]}],"ix":10},"p":{"a":0,"k":[389.117,535.861,0],"ix":2},"a":{"a":0,"k":[175.131,18.657,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"Layer 11","refId":"image_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[753.222,512.085,0],"ix":2},"a":{"a":0,"k":[20.262,33.699,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":75,"s":[100,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":90,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":179,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":194,"s":[100,0,100]},{"t":209,"s":[100,100,100]}],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"Layer 8","refId":"image_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[593.544,512.897,0],"ix":2},"a":{"a":0,"k":[20.428,33.795,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":60,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":75,"s":[100,0,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":90,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":179,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":194,"s":[100,0,100]},{"t":209,"s":[100,100,100]}],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"Layer 12","refId":"image_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":90,"s":[-10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":150,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":180,"s":[-10]},{"t":210,"s":[0]}],"ix":10},"p":{"a":0,"k":[532.132,249.678,0],"ix":2},"a":{"a":0,"k":[47.909,118.344,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"Layer 1","refId":"image_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[557.993,501.428,0],"ix":2},"a":{"a":0,"k":[251.852,254.048,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":2,"nm":"Layer 10","refId":"image_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[488.203,863.677,0],"ix":2},"a":{"a":0,"k":[65.677,194.503,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":2,"nm":"Layer 9","refId":"image_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":42,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":90,"s":[5]},{"t":151,"s":[0]}],"ix":10},"p":{"a":0,"k":[629.371,718.723,0],"ix":2},"a":{"a":0,"k":[74.03,67.009,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":2,"nm":"Layer 2","refId":"image_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[124]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":120,"s":[124]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":180,"s":[0]},{"t":240,"s":[0]}],"ix":10},"p":{"a":0,"k":[747.941,545.162,0],"ix":2},"a":{"a":0,"k":[14.418,315.027,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/tests/Content/images/lottie-base64_women-thinking.json b/tests/Content/images/lottie-base64_women-thinking.json new file mode 100644 index 0000000000..6d29326fb5 --- /dev/null +++ b/tests/Content/images/lottie-base64_women-thinking.json @@ -0,0 +1 @@ +{"v":"5.7.3","fr":60,"ip":0,"op":361,"w":1878,"h":1878,"nm":"women-thinking","ddd":0,"assets":[{"id":"image_0","w":174,"h":569,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_1","w":501,"h":1188,"u":"","p":"data:image/png;base64,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YXRvcgAACJlzTMlPSlVwTCtJLVJwTUtLTS4pBgBBegbOanoVxQAAIABJREFUeJzs3V9wXNedJ/bv73YDIERYAGnJElczIjylP5yRRPZaVU5SNWsiL6ps7LHlrZqUFVk26IxSrmw8Ep2k9m3E2Ye87FaGzstOameH8Eoa7dOa2kyqplKVErR5mMlmPAbHdkzLrjXosa1/tgRIIAEC3ffkoQGyAXT3/XfuOb9z7vdTZRkAgb6/7nvu+d1z7vkDEBERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERKSe+AyCKWWd+cQ5H0OkCANpoo4tUkk5qMNf/jRTJrf8CSZICaf9fDJJVg3QVu38LAN+7+ifL7qInotAwqRNV8OipxQVJMWeSpANJ5wTSMQYQ4OzovxIApuqh1wGs9F9NllOkANrL7VZ3beX7SytVX5yIwsSkTpRDp7M4191CJwEWjKAjRjoGOOk7rlEEuGaAVYEsG5GVHdNbuXp1adV3XERULyZ1ohE684tzvSN4EiJPwuBzvuM5qER7fx2CFTFmOUV7ub3VXVlZXVqrJTgi8oJJneiAU6cW5ycgFwB5EjCzvuMppmCqN7giIpdTpMvfu7q0XFdUROQGkzrRrkcfXVyQrlzA2Ofh9bLytL28dQiWYczl1hFcXllhK54oNEzq1HiPnvq9BUHvAjwmc6WuiJilbYPLfB5PFAYmdWqsR08tLgj8tsyDYfAqRC63tu68vLJ6kS14IqWY1KlxOqcW53uQJTCZF2dkXcRcTlrmIqfOEenDpE6N0R/NLhcBfNl3LDEw/UF2F7979U+XfMdCRH1M6tQIpx/+yvMQc8EAgY1m10+A9RRycWPrzour7Jon8opJnaL26KnFBRi5KIIzvmNpgHVjzFJXcJED64j8YFKnKHU6i3Pdm3JBDJ5zd1TPE9J0+WYL5sIKkzuRU0zqFJ1HT/3eAtBbkmHLuBqw1LuzbhJzsX0DF7lyHZEbrN4oGn5a55RFjKxDcPFvr/7pBd+xEMWOSZ2i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","e":1},{"id":"image_2","w":687,"h":773,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_3","w":114,"h":276,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_4","w":91,"h":175,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFsAAACvCAYAAACSNaKWAAAKP2lDQ1BBZnRlciBFZmZlY3RzIElDQyBQcm9maWxlAABIiZ2Wd1RT2RaHz703vVCSEIqU0GtoUgJIDb1IkS4qMQkQSsCQACI2RFRwRFGRpggyKOCAo0ORsSKKhQFRsesEGUTUcXAUG5ZJZK0Z37x5782b3x/3fmufvc/dZ+991roAkPyDBcJMWAmADKFYFOHnxYiNi2dgBwEM8AADbADgcLOzQhb4RgKZAnzYjGyZE/gXvboOIPn7KtM/jMEA/5+UuVkiMQBQmIzn8vjZXBkXyTg9V5wlt0/JmLY0Tc4wSs4iWYIyVpNz8ixbfPaZZQ858zKEPBnLc87iZfDk3CfjjTkSvoyRYBkX5wj4uTK+JmODdEmGQMZv5LEZfE42ACiS3C7mc1NkbC1jkigygi3jeQDgSMlf8NIvWMzPE8sPxc7MWi4SJKeIGSZcU4aNkxOL4c/PTeeLxcwwDjeNI+Ix2JkZWRzhcgBmz/xZFHltGbIiO9g4OTgwbS1tvijUf138m5L3dpZehH/uGUQf+MP2V36ZDQCwpmW12fqHbWkVAF3rAVC7/YfNYC8AirK+dQ59cR66fF5SxOIsZyur3NxcSwGfaykv6O/6nw5/Q198z1K+3e/lYXjzkziSdDFDXjduZnqmRMTIzuJw+Qzmn4f4Hwf+dR4WEfwkvogvlEVEy6ZMIEyWtVvIE4gFmUKGQPifmvgPw/6k2bmWidr4EdCWWAKlIRpAfh4AKCoRIAl7ZCvQ730LxkcD+c2L0ZmYnfvPgv59V7hM/sgWJH+OY0dEMrgSUc7smvxaAjQgAEVAA+pAG+gDE8AEtsARuAAP4AMCQSiIBHFgMeCCFJABRCAXFIC1oBiUgq1gJ6gGdaARNIM2cBh0gWPgNDgHLoHLYATcAVIwDp6AKfAKzEAQhIXIEBVSh3QgQ8gcsoVYkBvkAwVDEVAclAglQ0JIAhVA66BSqByqhuqhZuhb6Ch0GroADUO3oFFoEvoVegcjMAmmwVqwEWwFs2BPOAiOhBfByfAyOB8ugrfAlXADfBDuhE/Dl+ARWAo/gacRgBAROqKLMBEWwkZCkXgkCREhq5ASpAJpQNqQHqQfuYpIkafIWxQGRUUxUEyUC8ofFYXiopahVqE2o6pRB1CdqD7UVdQoagr1EU1Ga6LN0c7oAHQsOhmdiy5GV6Cb0B3os+gR9Dj6FQaDoWOMMY4Yf0wcJhWzArMZsxvTjjmFGcaMYaaxWKw61hzrig3FcrBibDG2CnsQexJ7BTuOfYMj4nRwtjhfXDxOiCvEVeBacCdwV3ATuBm8Et4Q74wPxfPwy/Fl+EZ8D34IP46fISgTjAmuhEhCKmEtoZLQRjhLuEt4QSQS9YhOxHCigLiGWEk8RDxPHCW+JVFIZiQ2KYEkIW0h7SedIt0ivSCTyUZkD3I8WUzeQm4mnyHfJ79RoCpYKgQo8BRWK9QodCpcUXimiFc0VPRUXKyYr1iheERxSPGpEl7JSImtxFFapVSjdFTphtK0MlXZRjlUOUN5s3KL8gXlRxQsxYjiQ+FRiij7KGcoY1SEqk9lU7nUddRG6lnqOA1DM6YF0FJppbRvaIO0KRWKip1KtEqeSo3KcRUpHaEb0QPo6fQy+mH6dfo7VS1VT1W+6ibVNtUrqq/V5qh5qPHVStTa1UbU3qkz1H3U09S3qXep39NAaZhphGvkauzROKvxdA5tjssc7pySOYfn3NaENc00IzRXaO7THNCc1tLW8tPK0qrSOqP1VJuu7aGdqr1D+4T2pA5Vx01HoLND56TOY4YKw5ORzqhk9DGmdDV1/XUluvW6g7ozesZ6UXqFeu169/QJ+iz9JP0d+r36UwY6BiEGBQatBrcN8YYswxTDXYb9hq+NjI1ijDYYdRk9MlYzDjDON241vmtCNnE3WWbSYHLNFGPKMk0z3W162Qw2szdLMasxGzKHzR3MBea7zYct0BZOFkKLBosbTBLTk5nDbGWOWtItgy0LLbssn1kZWMVbbbPqt/pobW+dbt1ofceGYhNoU2jTY/OrrZkt17bG9tpc8lzfuavnds99bmdux7fbY3fTnmofYr/Bvtf+g4Ojg8ihzWHS0cAx0bHW8QaLxgpjbWadd0I7eTmtdjrm9NbZwVnsfNj5FxemS5pLi8ujecbz+PMa54256rlyXOtdpW4Mt0S3vW5Sd113jnuD+wMPfQ+eR5PHhKepZ6rnQc9nXtZeIq8Or9dsZ/ZK9ilvxNvPu8R70IfiE+VT7XPfV8832bfVd8rP3m+F3yl/tH+Q/zb/GwFaAdyA5oCpQMfAlYF9QaSgBUHVQQ+CzYJFwT0hcEhgyPaQu/MN5wvnd4WC0IDQ7aH3wozDloV9H44JDwuvCX8YYRNRENG/gLpgyYKWBa8ivSLLIu9EmURJonqjFaMTopujX8d4x5THSGOtYlfGXorTiBPEdcdj46Pjm+KnF/os3LlwPME+oTjh+iLjRXmLLizWWJy++PgSxSWcJUcS0YkxiS2J7zmhnAbO9NKApbVLp7hs7i7uE54Hbwdvku/KL+dPJLkmlSc9SnZN3p48meKeUpHyVMAWVAuep/qn1qW+TgtN25/2KT0mvT0Dl5GYcVRIEaYJ+zK1M/Myh7PMs4qzpMucl+1cNiUKEjVlQ9mLsrvFNNnP1IDERLJeMprjllOT8yY3OvdInnKeMG9gudnyTcsn8n3zv16BWsFd0VugW7C2YHSl58r6VdCqpat6V+uvLlo9vsZvzYG1hLVpa38otC4sL3y5LmZdT5FW0ZqisfV+61uLFYpFxTc2uGyo24jaKNg4uGnupqpNH0t4JRdLrUsrSt9v5m6++JXNV5VffdqStGWwzKFsz1bMVuHW69vctx0oVy7PLx/bHrK9cwdjR8mOlzuX7LxQYVdRt4uwS7JLWhlc2V1lULW16n11SvVIjVdNe61m7aba17t5u6/s8djTVqdVV1r3bq9g7816v/rOBqOGin2YfTn7HjZGN/Z/zfq6uUmjqbTpw37hfumBiAN9zY7NzS2aLWWtcKukdfJgwsHL33h/093GbKtvp7eXHgKHJIcef5v47fXDQYd7j7COtH1n+F1tB7WjpBPqXN451ZXSJe2O6x4+Gni0t8elp+N7y+/3H9M9VnNc5XjZCcKJohOfTuafnD6Vderp6eTTY71Leu+ciT1zrS+8b/Bs0Nnz53zPnen37D953vX8sQvOF45eZF3suuRwqXPAfqDjB/sfOgYdBjuHHIe6Lztd7hmeN3ziivuV01e9r567FnDt0sj8keHrUddv3ki4Ib3Ju/noVvqt57dzbs/cWXMXfbfkntK9ivua9xt+NP2xXeogPT7qPTrwYMGDO2PcsSc/Zf/0frzoIflhxYTORPMj20fHJn0nLz9e+Hj8SdaTmafFPyv/XPvM5Nl3v3j8MjAVOzX+XPT806+bX6i/2P/S7mXvdNj0/VcZr2Zel7xRf3PgLett/7uYdxMzue+x7ys/mH7o+Rj08e6njE+ffgP3hPP7gmwEFwAAAAlwSFlzAAAAAQAAAAEATyXE1gAAACR6VFh0Q3JlYXRvcgAACJlzTMlPSlVwTCtJLVJwTUtLTS4pBgBBegbOanoVxQAACwdJREFUeJztnVty20YWhr8GQNdMnMTMCsyswMwKhrOCMCsIvQOqbNnlp4GfVJGUoryCUCuwtANqB9IOpBXIjGO7ygRw5gGUTEm8AOhuEAT7e7Epoy/6fXhw+nYaHA6Hw+FwOBxbglp3B5Yh7LdBNaM7P40I+Ne5YufDmrpVmEqI/YW9VgO/I9BWqDbwn4xFr4BLBaMERg12R/Z6qc/axBYG7Yi4p5Au8NRcvZx6MPL4NFSElbL+0sWO2O8Jqq/gmdjvwKnAUVUsvjSxI/7sQRJi0IqzouBK8MKAF8Oy277XD7tMOOgoGLIGke8jcAH012Xp1sQWBs2IaKjgV1ttaHDsE/TLjmisiB1x2AUZAk9s1G+IMSS9gNcnZTXoma4w5vAI5D3VFhrgCXjv0/6WgzHLFgbNmOiE7DFylTj7SND9ybJbMSJ26p/jkUKeLW5GTDRlDYW68PA7Nv24thsRBu2Y6HKx0OlTVUeQZwnR6JpB01YbWpb9hUGrQXRO9f1zZlIL/6djY/RZ2LKFQfNR6qM3RuhV3y8htfCI70dCaNzCC4l946MFlriO6rHqa6xu/5RnMY+HptsvJHZMdLTcR9eCX2MO+iYrzO2zYw76AgOTnVhFOrexnuF+gvzyiFfnJuoK8jycRh6T0OIofwycgDdKiM/n/ZJC2Ix43AY6HnTzubL8IaiPOgFauQotaT0zEfsjUDYGLVfghT4fT/JGAcJea0LQ9aFvy/oF3jbYDXXrySy2JfcxTiB8xK6RIXPEfg/UERYiJJ/gZ8XOpU4dmV6QQtgUJPz2WR+BM59PLVNCAwS8GvoELUHemarzhpgo1K0jk2VPOAgV/E+3sRmOA3Z7But7QMQfXVBDUMasXNe6V1q2MGgqxFgIpOCtbaEBAl6f+NCZLhgYIdG07pViT4h6N9ZhwH0c+wZeNFlRvDoPCDqCMiK4wO+iMXeyUmwfbq1aL+CTszIs+j6KnQ8Bfoc0rNQmIeoVLbtUbGHQNhNOydgn7unXUwzFzocE6ZioS2aMLy9LxY6Y9IpWPItChYo3lybqKsojXp0LvF3+VKbv7tN0p1Z+loqtUN0ilc4iqAvfYHinQ4PdUC3139neSgmqU6T9hWJPXwQmXIjRyRxdEgP9SaCQES4UOyIq9FWZtQ0FV1XZjXRDg92RWhEOrrJvVXCddZkb6eTtxLQjM89/G3VWiRhvqVvL4rknHHTytrtE7KRQJ2YY+3wubU9GHhp42v3yIPc3f6HYCq+QG5kh9wxeWSh2PqxyJatIUK28ZZa8INFcg1OVtOobEtRIp7xCTFq2zuBcxgEvKy22ItFafZEC+izx2eqyeFeqbdUAovX7gSqwiLLEstHoTFJ5sQOi1Q8ZZlnoV/jl9pFHo6JlS+Sy7AYXiu1BIZ8mcGF7g6IZfGvbzBaxxI0UG/l5G+BCACJUdcROkdP8FSajgn0pmWr5bIC8VnqleDMq2JdSEfxW2W0uFTvg1RA4y15dNedC5qGQll75/CPQDMtin7qCZBH8ePqfsxEovI5O+QTJHQSsFFsRfmjwqgPynPT48r1/VxeQ/LaO9UU98g+3Z1EFBkWZ9/pNrXYoDFoRUSv9WbCRB/a/pgkItPaTFBn05dpYmTayc8kaBgRmKbasNYugco9DjB/N2wS8OQsjefGZ5Ba7EikwymR6hPBapw4FY5/d3IOirbPsmMTAjgFGRcptndiKxMTq+qhIua0SW9hrmTh01UhPyeVmq8SOCULdOlQ6JXFZpOzWiD3ddKTtrxONVaitETsi6mPg+EeAPyxaditCPyFsxjy+RFNsBRc+u4WH+Vth2QmPtax6Zh19qNOP2lv2dBBziQEX4hP8pDMXVHvLjoj6skLojDtAjnUn3Wot9vX08FXWBAHLSBDtPea1FvsH4iMTR/MEzkycX6+t2OmWXvndUHWhiUpqKzYw87UvHgcInJna0F9LsWMO+urOHIjWCc5Qszu31C70E/ZaCcH5qggkI2cBux0D9QAFlsWqTkwwxFBWBt+gVUPN3MjXNM2QqXwoZ0W34C2iNmJ/Ya/lGbREE0f47lMbsRvpbJypdBfHpvJCzVILsSf8ERpMpzT2CawclN14sYWDjsIzlngmgdDWxqONDv1MzVPfZEVTqAufl7pHEhey0ZYd852h9KTpoMfGS3GWjRXbsJ9GIe9sn7PfyEFNmmzLnJ8GrjwaocH65rJxli0M2mlWM5N1Rr0yduNulNjXDJoJ0XB2jvrhFFO+d37qPso5mrJRYv9AdLJ6R1P2GT5BXXh8DvV6lZ2NETviYMiceQ+d2DUg6ZWZOWIjxI75sw+YWnUBQMGOsjAkX9FmtZneSfaX4WpPA3a1t6LlpdKWnZ59MSu0gquPBD2TdWalsmIL+22v4D7oZXiI9ct/FlHJQc0X9lrTTDeG82B7zxUvSvXTs1RO7OlNISeCmE44frzu+yArJbakg5aRMnwli4ILz9Icdc5+VIPV95MVZuwTtKpwOLYSL8jpRZ0WhJZxgli9nC0Pa3cj17dC27jNye8/WuML8T5rFTu9cya2IrSQvG2wOzRdrw7rvHe9mRDZup/M+gUWRViL2NeEze95bMmiOWsY3DJmktLdyDWD5o8GLVqYve2OC5+g9DmPrJQajXxhr/Wj4asNb4RO56aDykQe8yjNsoX9dgwjCyNDQMaC9BQvKys0lOSzp/f8jrBw55eC8dSiKxPiLcK6G4nY79kSGhjH6aCl8kKDZbHTLbzqLyxZdIJ0bGyAtIU1nz1dMzS6lDWLIP1NEhos+Gxh0EoyrYJrtfJ8k3II3mDUjUQcdmOic0E5oedgTOwJh0cg74EnZq7nnIe3sUKDAZ/9lf22whtavhp8LNBt8GJksQ3raFl2zEHfQ9mY8J9lnCCdqt3kVIRCL8hpWokjLEYbkIZ38YaFd8vI7UaEvVZEfGJnsv8bCq48pOvXRGjIadlf2W97VrYY3GW6QFvpSaUiZPbZUpLQwNnffKqd0JDRstMZuzKEVscBL3t221gfKy37C4NWGUKnV4TXV2jI8IIMmAwF9cTiXOwYpO9v8GAlK0vFjjkYirmD9/O4SpBuXUK7VSwUO+agLxbj6JuII6jhi3ARc72DcNiNkfey6AH9Zmv9IlzEAy1NJh2cz+bO2unywI3ETLom0rN9Iz0XDlz5SLfscyxVYk7op3/TxV0E4NTnU3ubhYb5L8iWyQYU7Pjsamd7rAMPLFsQI9aXppOQX5zQ33hg2QLneSKQeRGLkLwNeB3qdKyOPLDsTzROgDFkW9y6J/SxT/Rzwwk9l7lGHHHYna4nriTdYydDj+ik6MUL28JCjxFx2FXIcEHmx9MERg0ncC6Wuud0gPO1I3htj4SEZFRWugiHw+FwOBwOh8PhcDgcDofD4XA4HA6Hw+FwOBwOh8PhcDgcwIq9fhH7PVBdkObMox9ATrb1EJIOc8WecNDxYCjwdEnBK2/LDyTl5YHYefZmAwj8tw5ZbsrgjtjFrmmVsc/nVpl3dG0qd455RHwXMiN0thxm6knEv9d+U8YmcEdsherd/Zy1Eq+38iHHN7GF/TYFj1ALPBX2WqY6VVduxY6Imzd/L5ICMSJomehQnbkVO5g5ElmZm4Jqxoxl66JfQ92ZtWytwYk7RbaaW7Gnqd1OC9ZTtNxWcSf0kzTlZ258cMkAMnBH7AZvRgp1nKXgTcSiUO+UG65nYsHZ9cwp9Ct5rVRVmZtEMRVQ/SZwsaDcGajfnND5WBlST+9qbN98/ofgfF0XDm86/wdoXYedUD5FuQAAAABJRU5ErkJggg==","e":1},{"id":"image_5","w":144,"h":160,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_6","w":184,"h":174,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_7","w":77,"h":74,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_8","w":62,"h":57,"u":"","p":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAAA5CAYAAABuxJj8AAAKP2lDQ1BBZnRlciBFZmZlY3RzIElDQyBQcm9maWxlAABIiZ2Wd1RT2RaHz703vVCSEIqU0GtoUgJIDb1IkS4qMQkQSsCQACI2RFRwRFGRpggyKOCAo0ORsSKKhQFRsesEGUTUcXAUG5ZJZK0Z37x5782b3x/3fmufvc/dZ+991roAkPyDBcJMWAmADKFYFOHnxYiNi2dgBwEM8AADbADgcLOzQhb4RgKZAnzYjGyZE/gXvboOIPn7KtM/jMEA/5+UuVkiMQBQmIzn8vjZXBkXyTg9V5wlt0/JmLY0Tc4wSs4iWYIyVpNz8ixbfPaZZQ858zKEPBnLc87iZfDk3CfjjTkSvoyRYBkX5wj4uTK+JmODdEmGQMZv5LEZfE42ACiS3C7mc1NkbC1jkigygi3jeQDgSMlf8NIvWMzPE8sPxc7MWi4SJKeIGSZcU4aNkxOL4c/PTeeLxcwwDjeNI+Ix2JkZWRzhcgBmz/xZFHltGbIiO9g4OTgwbS1tvijUf138m5L3dpZehH/uGUQf+MP2V36ZDQCwpmW12fqHbWkVAF3rAVC7/YfNYC8AirK+dQ59cR66fF5SxOIsZyur3NxcSwGfaykv6O/6nw5/Q198z1K+3e/lYXjzkziSdDFDXjduZnqmRMTIzuJw+Qzmn4f4Hwf+dR4WEfwkvogvlEVEy6ZMIEyWtVvIE4gFmUKGQPifmvgPw/6k2bmWidr4EdCWWAKlIRpAfh4AKCoRIAl7ZCvQ730LxkcD+c2L0ZmYnfvPgv59V7hM/sgWJH+OY0dEMrgSUc7smvxaAjQgAEVAA+pAG+gDE8AEtsARuAAP4AMCQSiIBHFgMeCCFJABRCAXFIC1oBiUgq1gJ6gGdaARNIM2cBh0gWPgNDgHLoHLYATcAVIwDp6AKfAKzEAQhIXIEBVSh3QgQ8gcsoVYkBvkAwVDEVAclAglQ0JIAhVA66BSqByqhuqhZuhb6Ch0GroADUO3oFFoEvoVegcjMAmmwVqwEWwFs2BPOAiOhBfByfAyOB8ugrfAlXADfBDuhE/Dl+ARWAo/gacRgBAROqKLMBEWwkZCkXgkCREhq5ASpAJpQNqQHqQfuYpIkafIWxQGRUUxUEyUC8ofFYXiopahVqE2o6pRB1CdqD7UVdQoagr1EU1Ga6LN0c7oAHQsOhmdiy5GV6Cb0B3os+gR9Dj6FQaDoWOMMY4Yf0wcJhWzArMZsxvTjjmFGcaMYaaxWKw61hzrig3FcrBibDG2CnsQexJ7BTuOfYMj4nRwtjhfXDxOiCvEVeBacCdwV3ATuBm8Et4Q74wPxfPwy/Fl+EZ8D34IP46fISgTjAmuhEhCKmEtoZLQRjhLuEt4QSQS9YhOxHCigLiGWEk8RDxPHCW+JVFIZiQ2KYEkIW0h7SedIt0ivSCTyUZkD3I8WUzeQm4mnyHfJ79RoCpYKgQo8BRWK9QodCpcUXimiFc0VPRUXKyYr1iheERxSPGpEl7JSImtxFFapVSjdFTphtK0MlXZRjlUOUN5s3KL8gXlRxQsxYjiQ+FRiij7KGcoY1SEqk9lU7nUddRG6lnqOA1DM6YF0FJppbRvaIO0KRWKip1KtEqeSo3KcRUpHaEb0QPo6fQy+mH6dfo7VS1VT1W+6ibVNtUrqq/V5qh5qPHVStTa1UbU3qkz1H3U09S3qXep39NAaZhphGvkauzROKvxdA5tjssc7pySOYfn3NaENc00IzRXaO7THNCc1tLW8tPK0qrSOqP1VJuu7aGdqr1D+4T2pA5Vx01HoLND56TOY4YKw5ORzqhk9DGmdDV1/XUluvW6g7ozesZ6UXqFeu169/QJ+iz9JP0d+r36UwY6BiEGBQatBrcN8YYswxTDXYb9hq+NjI1ijDYYdRk9MlYzDjDON241vmtCNnE3WWbSYHLNFGPKMk0z3W162Qw2szdLMasxGzKHzR3MBea7zYct0BZOFkKLBosbTBLTk5nDbGWOWtItgy0LLbssn1kZWMVbbbPqt/pobW+dbt1ofceGYhNoU2jTY/OrrZkt17bG9tpc8lzfuavnds99bmdux7fbY3fTnmofYr/Bvtf+g4Ojg8ihzWHS0cAx0bHW8QaLxgpjbWadd0I7eTmtdjrm9NbZwVnsfNj5FxemS5pLi8ujecbz+PMa54256rlyXOtdpW4Mt0S3vW5Sd113jnuD+wMPfQ+eR5PHhKepZ6rnQc9nXtZeIq8Or9dsZ/ZK9ilvxNvPu8R70IfiE+VT7XPfV8832bfVd8rP3m+F3yl/tH+Q/zb/GwFaAdyA5oCpQMfAlYF9QaSgBUHVQQ+CzYJFwT0hcEhgyPaQu/MN5wvnd4WC0IDQ7aH3wozDloV9H44JDwuvCX8YYRNRENG/gLpgyYKWBa8ivSLLIu9EmURJonqjFaMTopujX8d4x5THSGOtYlfGXorTiBPEdcdj46Pjm+KnF/os3LlwPME+oTjh+iLjRXmLLizWWJy++PgSxSWcJUcS0YkxiS2J7zmhnAbO9NKApbVLp7hs7i7uE54Hbwdvku/KL+dPJLkmlSc9SnZN3p48meKeUpHyVMAWVAuep/qn1qW+TgtN25/2KT0mvT0Dl5GYcVRIEaYJ+zK1M/Myh7PMs4qzpMucl+1cNiUKEjVlQ9mLsrvFNNnP1IDERLJeMprjllOT8yY3OvdInnKeMG9gudnyTcsn8n3zv16BWsFd0VugW7C2YHSl58r6VdCqpat6V+uvLlo9vsZvzYG1hLVpa38otC4sL3y5LmZdT5FW0ZqisfV+61uLFYpFxTc2uGyo24jaKNg4uGnupqpNH0t4JRdLrUsrSt9v5m6++JXNV5VffdqStGWwzKFsz1bMVuHW69vctx0oVy7PLx/bHrK9cwdjR8mOlzuX7LxQYVdRt4uwS7JLWhlc2V1lULW16n11SvVIjVdNe61m7aba17t5u6/s8djTVqdVV1r3bq9g7816v/rOBqOGin2YfTn7HjZGN/Z/zfq6uUmjqbTpw37hfumBiAN9zY7NzS2aLWWtcKukdfJgwsHL33h/093GbKtvp7eXHgKHJIcef5v47fXDQYd7j7COtH1n+F1tB7WjpBPqXN451ZXSJe2O6x4+Gni0t8elp+N7y+/3H9M9VnNc5XjZCcKJohOfTuafnD6Vderp6eTTY71Leu+ciT1zrS+8b/Bs0Nnz53zPnen37D953vX8sQvOF45eZF3suuRwqXPAfqDjB/sfOgYdBjuHHIe6Lztd7hmeN3ziivuV01e9r567FnDt0sj8keHrUddv3ki4Ib3Ju/noVvqt57dzbs/cWXMXfbfkntK9ivua9xt+NP2xXeogPT7qPTrwYMGDO2PcsSc/Zf/0frzoIflhxYTORPMj20fHJn0nLz9e+Hj8SdaTmafFPyv/XPvM5Nl3v3j8MjAVOzX+XPT806+bX6i/2P/S7mXvdNj0/VcZr2Zel7xRf3PgLett/7uYdxMzue+x7ys/mH7o+Rj08e6njE+ffgP3hPP7gmwEFwAAAAlwSFlzAAAAAQAAAAEATyXE1gAAACR6VFh0Q3JlYXRvcgAACJlzTMlPSlVwTCtJLVJwTUtLTS4pBgBBegbOanoVxQAABU9JREFUaIHtml1r21YYx//nSHEX6rReAyGFQX3RlrTOiHq13Yzocs0Sql6OMWJ9grrfwN9g6SdQ3DB2WZW+bHdTYTeFjSl0hjIKs7fSlkGCk6Y1c3TOs4s2jmVbtixLjtnyu5Kso+c8f5+X55xHBzjmmP8FLAmjmmVkPXhZCejgBxWRBvAMAzkAByAhJHM5RKVsPnST8KMXsQjXLCMjFGEIkgYn6MTY6QiOPCLAFRL2U/O+E4dffeqLzpy1rCuc5QFajckfAAAjtkOM1iHV9bJpJ9IbIgmf31jWiVAEYTFuh7rwiEux9sT83o7T6EDCtTtGZn/XKwK4EcYwRXQqwOCmECjENQxCC89ZSxo4twGci6Pi6NBdIUXhqflDZRgrPEyh3O2VPBTFwZGLBgB2TVUU99LGijGUlX4FPrZW8pKTNUwlyUGl8uqDfJQ3ewqf31jWSeLHSD4liG/+YNh8I/b0iunUBrXRlbnvPs8q/ygumjGZehU/ajYnTqm6e90OLT5wjKsNdR2+hcjYigaAhf1dz9EsIxP2ha7Cc7dX8oSRxOg4WdjnnpO19FDiu7c4UTFOj0bIQpqnQy10OoTnrKU8xiJsRYOAxfnS8lq/cp0trvBCIh6NEAJuzFvLeq8yvhlrzjKyCvf+SNSrEUFA9a3c04LCnK/FFUUMtRoaJxhwLs3Tgb3XJ5wAPXGPYiB0YGVUCApxbWOctMHdoIDr5AhbCxE73eBe11b3CWcUZTZnAdfjAQ9o9VC7s1GRxN9GxE4LdM5dTeE5aylCN4+XpAaK5DJY+H8bdq39l6bwRFO8YzD059oWNOpIao2hD7fn8NIpgQvTdcxONQAAr16nUK2dwHZ9ouv7nEMH4Bzc+4UzVBFpZk+eVtGffLSLyzNvfc9n0w1oZ/fwbGsSj59PoSH8o5iBZVvv/U+JRv5FY1A+O7fTIbqV89N1XL243eUJZVvv/MIld8ZgOAZyYbqO89P1vuXOTHq4cnbP/2ObsLZZXTijWXtFQ2sX04PLM2+QUmTgc5/w9zN7NbJnCXJmch/plAAQbq5MKdSc+IDOwNIRxxmwPoR/iZE+IZrXYYfj9KTXvKa2f6tDuJpS16M4ljStIqJAYL59eYdw90u7ArDSULUkwFZ9uCUHl/6I1XXJKqRSHKqWBNh+231h0ouXe6nmNQPrL/ypaVcA3OppdcRxb6+h4FWLkFDlXx+WV6A4rc8DNykTUi2CsZ1Ay0cQ9359mQ5d9vHzqcMbxu66pt17jB/gmnaNCRqrHNyr1yn8VO1/yuTZ1iT+qn1w+IMQHbl2pZeBv+/+Xpm5fvFDAJ8O7mYybNcnsF1XMXNyHynF3+0aguGXF1P4+UVra1O1nH+Yb7cTaqTmSisOQIsHL4zL6m52qoGz6XeLlK26ij9bW/kASTfL5oOODwyhhGuWkfG45xCwMKSvIYj1q2y1vHo/2+1BqAyMa9o1Vao6gM24PAomxnAhO1NOB4ROPbmmXZs4pepgoxAfA5Ju9soqDZRzc6/btQmh6uO4svPDSt3Gta9EVNM564sCOPsm6vtdiWXmZKXy6r18v1KRs6xl88EapHol1q4/fLi4FUY0ENNMMl9aLhJjBRCFO8Mad0wktsMJ+SfmvdCnH2ObQrN3jMzJ3f01gMV6rrU/rPRGKoWKGf7gD5DAVkOzjIwHr0AK8gNnbAfrCY8YR/G3r6Md8Ux0j3Vp46rBJTfAYIAGP8rdhSoAW0hvbdgjnSPbXOa+XdIgmA7i+vtUb5hVYJVALmPcgSKc8lfxfe050mzyu2EBDfCnlTyolfc5gWOOOWY4/gWU4LyzXX2G+QAAAABJRU5ErkJggg==","e":1},{"id":"image_9","w":161,"h":177,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_10","w":134,"h":149,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_11","w":135,"h":186,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_12","w":133,"h":137,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_13","w":131,"h":111,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_14","w":188,"h":139,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_15","w":134,"h":121,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_16","w":67,"h":50,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_17","w":141,"h":116,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_18","w":252,"h":164,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_19","w":164,"h":175,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_20","w":139,"h":141,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_21","w":90,"h":113,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_22","w":37,"h":40,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_23","w":144,"h":134,"u":"","p":"data:image/png;base64,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","e":1},{"id":"image_24","w":166,"h":195,"u":"","p":"data:image/png;base64,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","e":1}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"Layer 32","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":29,"s":[-10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":59,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":91,"s":[-10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":121,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":150,"s":[-10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":180,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":210,"s":[-10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":240,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":270,"s":[-10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":300,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":330,"s":[-10]},{"t":360,"s":[0]}],"ix":10},"p":{"a":0,"k":[834.039,1285.384,0],"ix":2},"a":{"a":0,"k":[48.541,524.26,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":2425,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":2,"nm":"Layer 6","refId":"image_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[984.285,1080.978,0],"ix":2},"a":{"a":0,"k":[250.402,593.69,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":2425,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":2,"nm":"Layer 33","refId":"image_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[11]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":119,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":180,"s":[11]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":240,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":300,"s":[11]},{"t":360,"s":[0]}],"ix":10},"p":{"a":0,"k":[1002.549,568.705,0],"ix":2},"a":{"a":0,"k":[501.25,56.409,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":2425,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":2,"nm":"Layer 14","refId":"image_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":61,"s":[15]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":109,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[1],"y":[0]},"t":300,"s":[0]},{"t":360,"s":[376]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":61,"s":[1165.74,-495.207,0],"to":[-26,138.667,0],"ti":[26,-138.667,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"t":109,"s":[1009.74,336.793,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":300,"s":[1009.74,336.793,0],"to":[-271.333,-56,0],"ti":[271.333,56,0]},{"t":360,"s":[-618.26,0.793,0]}],"ix":2},"a":{"a":0,"k":[56.984,137.852,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":61,"op":2486,"st":37,"bm":0},{"ddd":0,"ind":5,"ty":2,"nm":"Layer 15","refId":"image_4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":53,"s":[15]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":101,"s":[0]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[1],"y":[0]},"t":300,"s":[0]},{"t":360,"s":[364]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":53,"s":[1267.7,-434.106,0],"to":[-26,138.667,0],"ti":[26,-138.667,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"t":101,"s":[1111.7,397.894,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":300,"s":[1111.7,397.894,0],"to":[207.333,-76,0],"ti":[-207.333,76,0]},{"t":360,"s":[2355.7,-58.106,0]}],"ix":2},"a":{"a":0,"k":[45.056,87.197,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":53,"op":2478,"st":29,"bm":0},{"ddd":0,"ind":6,"ty":2,"nm":"Layer 19","refId":"image_5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":22,"s":[923.463,980.12,0],"to":[-55.333,-49,0],"ti":[55.333,49,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":82,"s":[591.463,686.12,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":262,"s":[591.463,686.12,0],"to":[55.333,49,0],"ti":[-55.333,-49,0]},{"t":322,"s":[923.463,980.12,0]}],"ix":2},"a":{"a":0,"k":[71.899,79.72,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":22,"op":2447,"st":22,"bm":0},{"ddd":0,"ind":7,"ty":2,"nm":"Layer 2","refId":"image_6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":3,"s":[909.806,970.321,0],"to":[111,-21,0],"ti":[-111,21,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":63,"s":[1575.806,844.321,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":243,"s":[1575.806,844.321,0],"to":[-111,21,0],"ti":[111,-21,0]},{"t":303,"s":[909.806,970.321,0]}],"ix":2},"a":{"a":0,"k":[91.632,86.741,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":3,"op":2428,"st":3,"bm":0},{"ddd":0,"ind":8,"ty":2,"nm":"Layer 3","refId":"image_7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":17,"s":[947.498,934.079,0],"to":[-28,-62,0],"ti":[28,62,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":77,"s":[779.498,562.079,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":257,"s":[779.498,562.079,0],"to":[28,62,0],"ti":[-28,-62,0]},{"t":317,"s":[947.498,934.079,0]}],"ix":2},"a":{"a":0,"k":[38.274,36.981,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":17,"op":2442,"st":17,"bm":0},{"ddd":0,"ind":9,"ty":2,"nm":"Layer 4","refId":"image_8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":2,"s":[915.599,969.942,0],"to":[-38.667,-54.667,0],"ti":[38.667,54.667,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":62,"s":[683.599,641.942,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":242,"s":[683.599,641.942,0],"to":[38.667,54.667,0],"ti":[-38.667,-54.667,0]},{"t":302,"s":[915.599,969.942,0]}],"ix":2},"a":{"a":0,"k":[30.853,28.307,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":2,"op":2427,"st":2,"bm":0},{"ddd":0,"ind":10,"ty":2,"nm":"Layer 5","refId":"image_9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":6,"s":[904.285,955.754,0],"to":[-33.667,-77.667,0],"ti":[33.667,77.667,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":66,"s":[702.285,489.754,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":246,"s":[702.285,489.754,0],"to":[33.667,77.667,0],"ti":[-33.667,-77.667,0]},{"t":306,"s":[904.285,955.754,0]}],"ix":2},"a":{"a":0,"k":[80.336,88.382,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":6,"op":2431,"st":6,"bm":0},{"ddd":0,"ind":11,"ty":2,"nm":"Layer 16","refId":"image_10","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":14,"s":[941.34,941.283,0],"to":[52,-4.333,0],"ti":[-52,4.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":74,"s":[1253.34,915.283,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":254,"s":[1253.34,915.283,0],"to":[-52,4.333,0],"ti":[52,-4.333,0]},{"t":314,"s":[941.34,941.283,0]}],"ix":2},"a":{"a":0,"k":[66.598,74.152,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":14,"op":2439,"st":14,"bm":0},{"ddd":0,"ind":12,"ty":2,"nm":"Layer 17","refId":"image_11","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[903.727,966.582,0],"to":[56,-47,0],"ti":[-56,47,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":60,"s":[1239.727,684.582,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":240,"s":[1239.727,684.582,0],"to":[-56,47,0],"ti":[56,-47,0]},{"t":300,"s":[903.727,966.582,0]}],"ix":2},"a":{"a":0,"k":[67.313,92.977,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":2425,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":2,"nm":"Layer 18","refId":"image_12","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":22,"s":[902.245,959.29,0],"to":[-91,-2.667,0],"ti":[91,2.667,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":82,"s":[356.245,943.29,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":262,"s":[356.245,943.29,0],"to":[91,2.667,0],"ti":[-91,-2.667,0]},{"t":322,"s":[902.245,959.29,0]}],"ix":2},"a":{"a":0,"k":[66.241,68.049,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":22,"op":2447,"st":22,"bm":0},{"ddd":0,"ind":14,"ty":2,"nm":"Layer 20","refId":"image_13","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":29,"s":[933.839,976.188,0],"to":[-114,-19.333,0],"ti":[114,19.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":89,"s":[249.839,860.188,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":269,"s":[249.839,860.188,0],"to":[114,19.333,0],"ti":[-114,-19.333,0]},{"t":329,"s":[933.839,976.188,0]}],"ix":2},"a":{"a":0,"k":[65.371,55.049,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":29,"op":2454,"st":29,"bm":0},{"ddd":0,"ind":15,"ty":2,"nm":"Layer 21","refId":"image_14","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[896.696,968.016,0],"to":[-70,-24.667,0],"ti":[70,24.667,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":65,"s":[476.696,820.016,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":245,"s":[476.696,820.016,0],"to":[70,24.667,0],"ti":[-70,-24.667,0]},{"t":305,"s":[896.696,968.016,0]}],"ix":2},"a":{"a":0,"k":[93.922,69.435,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":5,"op":2430,"st":5,"bm":0},{"ddd":0,"ind":16,"ty":2,"nm":"Layer 22","refId":"image_15","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[929.73,939.986,0],"to":[-95.333,-44.333,0],"ti":[95.333,44.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":60,"s":[357.73,673.986,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":240,"s":[357.73,673.986,0],"to":[95.333,44.333,0],"ti":[-95.333,-44.333,0]},{"t":300,"s":[929.73,939.986,0]}],"ix":2},"a":{"a":0,"k":[66.88,60.28,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":2425,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":2,"nm":"Layer 23","refId":"image_16","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":28,"s":[925.782,936.967,0],"to":[-74.333,-51.333,0],"ti":[74.333,51.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":88,"s":[479.782,628.967,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":268,"s":[479.782,628.967,0],"to":[74.333,51.333,0],"ti":[-74.333,-51.333,0]},{"t":328,"s":[925.782,936.967,0]}],"ix":2},"a":{"a":0,"k":[33.215,24.757,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":28,"op":2453,"st":28,"bm":0},{"ddd":0,"ind":18,"ty":2,"nm":"Layer 24","refId":"image_17","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[956.3,894.969,0],"to":[54.333,-62,0],"ti":[-54.333,62,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":65,"s":[1282.3,522.969,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":245,"s":[1282.3,522.969,0],"to":[-54.333,62,0],"ti":[54.333,-62,0]},{"t":305,"s":[956.3,894.969,0]}],"ix":2},"a":{"a":0,"k":[70.492,57.92,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":5,"op":2430,"st":5,"bm":0},{"ddd":0,"ind":19,"ty":2,"nm":"Layer 25","refId":"image_18","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":6,"s":[908.046,955.314,0],"to":[120.333,-55,0],"ti":[-120.333,55,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":66,"s":[1630.046,625.314,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":246,"s":[1630.046,625.314,0],"to":[-120.333,55,0],"ti":[120.333,-55,0]},{"t":306,"s":[908.046,955.314,0]}],"ix":2},"a":{"a":0,"k":[125.576,81.636,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":6,"op":2431,"st":6,"bm":0},{"ddd":0,"ind":20,"ty":2,"nm":"Layer 26","refId":"image_19","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":2,"s":[935.79,868.205,0],"to":[83.667,-23.333,0],"ti":[-83.667,23.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":62,"s":[1437.79,728.205,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":242,"s":[1437.79,728.205,0],"to":[-83.667,23.333,0],"ti":[83.667,-23.333,0]},{"t":302,"s":[935.79,868.205,0]}],"ix":2},"a":{"a":0,"k":[81.6,87.08,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":2,"op":2427,"st":2,"bm":0},{"ddd":0,"ind":21,"ty":2,"nm":"Layer 27","refId":"image_20","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[963.953,926.261,0],"to":[84.667,-70.333,0],"ti":[-84.667,70.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":64,"s":[1471.953,504.261,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":244,"s":[1471.953,504.261,0],"to":[-84.667,70.333,0],"ti":[84.667,-70.333,0]},{"t":304,"s":[963.953,926.261,0]}],"ix":2},"a":{"a":0,"k":[69.384,70.155,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":4,"op":2429,"st":4,"bm":0},{"ddd":0,"ind":22,"ty":2,"nm":"Layer 28","refId":"image_21","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":16,"s":[925.304,981.72,0],"to":[-66.667,-87.333,0],"ti":[66.667,87.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":76,"s":[525.304,457.72,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":256,"s":[525.304,457.72,0],"to":[66.667,87.333,0],"ti":[-66.667,-87.333,0]},{"t":316,"s":[925.304,981.72,0]}],"ix":2},"a":{"a":0,"k":[44.801,56.096,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":16,"op":2441,"st":16,"bm":0},{"ddd":0,"ind":23,"ty":2,"nm":"Layer 29","refId":"image_22","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":13,"s":[937.312,948.256,0],"to":[-74.333,0,0],"ti":[74.333,0,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":73,"s":[491.312,948.256,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":253,"s":[491.312,948.256,0],"to":[74.333,0,0],"ti":[-74.333,0,0]},{"t":313,"s":[937.312,948.256,0]}],"ix":2},"a":{"a":0,"k":[18.395,19.881,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":13,"op":2438,"st":13,"bm":0},{"ddd":0,"ind":24,"ty":2,"nm":"Layer 30","refId":"image_23","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":5,"s":[905.527,924.306,0],"to":[-85.333,-67.333,0],"ti":[85.333,67.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":65,"s":[393.527,520.306,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":245,"s":[393.527,520.306,0],"to":[85.333,67.333,0],"ti":[-85.333,-67.333,0]},{"t":305,"s":[905.527,924.306,0]}],"ix":2},"a":{"a":0,"k":[71.97,66.794,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":5,"op":2430,"st":5,"bm":0},{"ddd":0,"ind":25,"ty":2,"nm":"Layer 31","refId":"image_24","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[900.969,954.77,0],"to":[-116,-43.333,0],"ti":[116,43.333,0]},{"i":{"x":0,"y":0},"o":{"x":0.333,"y":0.333},"t":60,"s":[204.969,694.77,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":240,"s":[204.969,694.77,0],"to":[116,43.333,0],"ti":[-116,-43.333,0]},{"t":300,"s":[900.969,954.77,0]}],"ix":2},"a":{"a":0,"k":[82.801,97.357,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":2425,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/tests/SkiaSharp.Tests.Console.sln b/tests/SkiaSharp.Tests.Console.sln index 4ecd3f584e..f2a39ff7c7 100644 --- a/tests/SkiaSharp.Tests.Console.sln +++ b/tests/SkiaSharp.Tests.Console.sln @@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Vulkan.SharpVk", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.SceneGraph", "..\binding\SkiaSharp.SceneGraph\SkiaSharp.SceneGraph.csproj", "{978AD2C6-E592-4F5E-B565-26C357877B2C}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Resources", "..\binding\SkiaSharp.Resources\SkiaSharp.Resources.csproj", "{AD2C6978-4F5E-E592-B565-26C357877B2C}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Skottie", "..\binding\SkiaSharp.Skottie\SkiaSharp.Skottie.csproj", "{D35696BA-3038-41F2-9BE9-181439E6EF9E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source", "source", "{9FAA974B-A671-40BC-82EA-8EF77F463ECB}" @@ -115,6 +117,18 @@ Global {978AD2C6-E592-4F5E-B565-26C357877B2C}.Release|x64.Build.0 = Release|Any CPU {978AD2C6-E592-4F5E-B565-26C357877B2C}.Release|x86.ActiveCfg = Release|Any CPU {978AD2C6-E592-4F5E-B565-26C357877B2C}.Release|x86.Build.0 = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|x64.ActiveCfg = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|x64.Build.0 = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|x86.ActiveCfg = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|x86.Build.0 = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.Build.0 = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|x64.ActiveCfg = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|x64.Build.0 = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|x86.ActiveCfg = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|x86.Build.0 = Release|Any CPU {D35696BA-3038-41F2-9BE9-181439E6EF9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D35696BA-3038-41F2-9BE9-181439E6EF9E}.Debug|Any CPU.Build.0 = Debug|Any CPU {D35696BA-3038-41F2-9BE9-181439E6EF9E}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -137,6 +151,7 @@ Global {0DE402FA-A101-438E-8528-6EA82E0FF803} = {9FAA974B-A671-40BC-82EA-8EF77F463ECB} {A53DD2E5-55C4-4F7C-9316-D7FAD9A6F19F} = {9FAA974B-A671-40BC-82EA-8EF77F463ECB} {978AD2C6-E592-4F5E-B565-26C357877B2C} = {9FAA974B-A671-40BC-82EA-8EF77F463ECB} + {AD2C6978-4F5E-E592-B565-26C357877B2C} = {9FAA974B-A671-40BC-82EA-8EF77F463ECB} {D35696BA-3038-41F2-9BE9-181439E6EF9E} = {9FAA974B-A671-40BC-82EA-8EF77F463ECB} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj b/tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj index 9344683577..394deb1828 100644 --- a/tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj +++ b/tests/SkiaSharp.Tests.Console/SkiaSharp.Tests.Console.csproj @@ -25,6 +25,7 @@ + diff --git a/tests/SkiaSharp.Tests.Console/SkiaSharp/SKBitmapThreadingTest.cs b/tests/SkiaSharp.Tests.Console/SkiaSharp/SKBitmapThreadingTest.cs index c92dc2526a..5c345c9961 100644 --- a/tests/SkiaSharp.Tests.Console/SkiaSharp/SKBitmapThreadingTest.cs +++ b/tests/SkiaSharp.Tests.Console/SkiaSharp/SKBitmapThreadingTest.cs @@ -12,6 +12,7 @@ namespace SkiaSharp.Tests public class SKBitmapThreadingTest : SKTest { [SkippableTheory] + [InlineData(10, 10)] [InlineData(100, 1000)] public static void ImageScalingMultipleThreadsTest(int numThreads, int numIterationsPerThread) { diff --git a/tests/SkiaSharp.Tests.Devices.sln b/tests/SkiaSharp.Tests.Devices.sln index a27222c5cb..265ff46f70 100644 --- a/tests/SkiaSharp.Tests.Devices.sln +++ b/tests/SkiaSharp.Tests.Devices.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HarfBuzzSharp", "..\binding EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.SceneGraph", "..\binding\SkiaSharp.SceneGraph\SkiaSharp.SceneGraph.csproj", "{8CD906F8-B3E4-48E6-8B16-EAFC0C34EAE1}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Resources", "..\binding\SkiaSharp.Resources\SkiaSharp.Resources.csproj", "{AD2C6978-4F5E-E592-B565-26C357877B2C}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Skottie", "..\binding\SkiaSharp.Skottie\SkiaSharp.Skottie.csproj", "{915D1D57-B059-4301-9A35-2E5EB68DED99}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.HarfBuzz", "..\source\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz\SkiaSharp.HarfBuzz.csproj", "{6F999CA5-B67F-46A3-9A94-9E99527060F6}" @@ -55,6 +57,10 @@ Global {8CD906F8-B3E4-48E6-8B16-EAFC0C34EAE1}.Debug|Any CPU.Build.0 = Debug|Any CPU {8CD906F8-B3E4-48E6-8B16-EAFC0C34EAE1}.Release|Any CPU.ActiveCfg = Release|Any CPU {8CD906F8-B3E4-48E6-8B16-EAFC0C34EAE1}.Release|Any CPU.Build.0 = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.Build.0 = Release|Any CPU {915D1D57-B059-4301-9A35-2E5EB68DED99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {915D1D57-B059-4301-9A35-2E5EB68DED99}.Debug|Any CPU.Build.0 = Debug|Any CPU {915D1D57-B059-4301-9A35-2E5EB68DED99}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -87,6 +93,7 @@ Global {9D753C4C-D7FC-4D1B-ABF0-BF1C089B987A} = {6779122B-72B0-42ED-A1E7-5029C1C0A78D} {D48557C5-795D-4948-84EE-A7531DDD91DC} = {6779122B-72B0-42ED-A1E7-5029C1C0A78D} {8CD906F8-B3E4-48E6-8B16-EAFC0C34EAE1} = {6779122B-72B0-42ED-A1E7-5029C1C0A78D} + {AD2C6978-4F5E-E592-B565-26C357877B2C} = {6779122B-72B0-42ED-A1E7-5029C1C0A78D} {915D1D57-B059-4301-9A35-2E5EB68DED99} = {6779122B-72B0-42ED-A1E7-5029C1C0A78D} {6F999CA5-B67F-46A3-9A94-9E99527060F6} = {6779122B-72B0-42ED-A1E7-5029C1C0A78D} {398936B0-1B68-4F2D-B91C-6880CAC9F168} = {6779122B-72B0-42ED-A1E7-5029C1C0A78D} diff --git a/tests/SkiaSharp.Tests.Devices/SkiaSharp.Tests.Devices.csproj b/tests/SkiaSharp.Tests.Devices/SkiaSharp.Tests.Devices.csproj index d464186f28..9eb1a63ee2 100644 --- a/tests/SkiaSharp.Tests.Devices/SkiaSharp.Tests.Devices.csproj +++ b/tests/SkiaSharp.Tests.Devices/SkiaSharp.Tests.Devices.csproj @@ -46,6 +46,7 @@ + diff --git a/tests/SkiaSharp.Tests.Wasm.sln b/tests/SkiaSharp.Tests.Wasm.sln index ec7f300759..ad2b61529a 100644 --- a/tests/SkiaSharp.Tests.Wasm.sln +++ b/tests/SkiaSharp.Tests.Wasm.sln @@ -13,6 +13,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.HarfBuzz", "..\so EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.SceneGraph", "..\binding\SkiaSharp.SceneGraph\SkiaSharp.SceneGraph.csproj", "{2A777BD2-9108-4747-BBD2-0240B8D7CCC3}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Resources", "..\binding\SkiaSharp.Resources\SkiaSharp.Resources.csproj", "{AD2C6978-4F5E-E592-B565-26C357877B2C}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Skottie", "..\binding\SkiaSharp.Skottie\SkiaSharp.Skottie.csproj", "{3FCCE93A-727E-4891-8449-468F13E8052A}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "source", "source", "{5C42DB9F-1771-4F1D-8247-E58AEB9D9094}" @@ -43,6 +45,10 @@ Global {2A777BD2-9108-4747-BBD2-0240B8D7CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A777BD2-9108-4747-BBD2-0240B8D7CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A777BD2-9108-4747-BBD2-0240B8D7CCC3}.Release|Any CPU.Build.0 = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD2C6978-4F5E-E592-B565-26C357877B2C}.Release|Any CPU.Build.0 = Release|Any CPU {3FCCE93A-727E-4891-8449-468F13E8052A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3FCCE93A-727E-4891-8449-468F13E8052A}.Debug|Any CPU.Build.0 = Debug|Any CPU {3FCCE93A-727E-4891-8449-468F13E8052A}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -56,6 +62,7 @@ Global {B020BCC5-FC01-4ADC-839E-18E63BC6D4C5} = {5C42DB9F-1771-4F1D-8247-E58AEB9D9094} {6E6DF00F-30EF-479B-92FB-B07DDE6B1259} = {5C42DB9F-1771-4F1D-8247-E58AEB9D9094} {2A777BD2-9108-4747-BBD2-0240B8D7CCC3} = {5C42DB9F-1771-4F1D-8247-E58AEB9D9094} + {AD2C6978-4F5E-E592-B565-26C357877B2C} = {5C42DB9F-1771-4F1D-8247-E58AEB9D9094} {3FCCE93A-727E-4891-8449-468F13E8052A} = {5C42DB9F-1771-4F1D-8247-E58AEB9D9094} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/tests/SkiaSharp.Tests.Wasm/SkiaSharp.Tests.Wasm.csproj b/tests/SkiaSharp.Tests.Wasm/SkiaSharp.Tests.Wasm.csproj index ba495e41e8..dc12070831 100644 --- a/tests/SkiaSharp.Tests.Wasm/SkiaSharp.Tests.Wasm.csproj +++ b/tests/SkiaSharp.Tests.Wasm/SkiaSharp.Tests.Wasm.csproj @@ -28,6 +28,7 @@ + diff --git a/tests/SkiaSharp.Tests/SkiaSharp.Tests.csproj b/tests/SkiaSharp.Tests/SkiaSharp.Tests.csproj index bf617ca98d..a5013ed9fe 100644 --- a/tests/SkiaSharp.Tests/SkiaSharp.Tests.csproj +++ b/tests/SkiaSharp.Tests/SkiaSharp.Tests.csproj @@ -17,6 +17,7 @@ + diff --git a/tests/Tests/GarbageCleanupFixture.cs b/tests/Tests/GarbageCleanupFixture.cs index a3518a83ee..4f1cfaa582 100644 --- a/tests/Tests/GarbageCleanupFixture.cs +++ b/tests/Tests/GarbageCleanupFixture.cs @@ -16,6 +16,7 @@ public class GarbageCleanupFixture : IDisposable "SkiaSharp.SKFontStyle+SKFontStyleStatic", "SkiaSharp.SKTypeface+SKTypefaceStatic", "SkiaSharp.SKColorSpace+SKColorSpaceStatic", + "SkiaSharp.SKBlender+SKBlenderStatic", }; public GarbageCleanupFixture() diff --git a/tests/Tests/Resources/ResourceProviderTest.cs b/tests/Tests/Resources/ResourceProviderTest.cs new file mode 100644 index 0000000000..93bc337b7e --- /dev/null +++ b/tests/Tests/Resources/ResourceProviderTest.cs @@ -0,0 +1,81 @@ +using System; +using System.IO; +using System.Runtime.InteropServices; +using SkiaSharp.Resources; +using Xunit; + +namespace SkiaSharp.Tests +{ + public class ResourceProviderTest : SKTest + { + [SkippableFact] + public void FileResourceProviderCanReadFiles() + { + var fullPath = Path.Combine(PathToImages, "baboon.png"); + var expectedData = SKData.Create(fullPath); + + using var rp = new FileResourceProvider(PathToImages); + + using var data = rp.Load("baboon.png"); + + Assert.Equal(expectedData.ToArray(), data.ToArray()); + } + + [SkippableFact] + public void ProxyProviderCanReadFiles() + { + var fullPath = Path.Combine(PathToImages, "baboon.png"); + var expectedData = SKData.Create(fullPath); + + using var files = new FileResourceProvider(PathToImages); + using var datauri = new DataUriResourceProvider(files); + using var caching = new CachingResourceProvider(datauri); + + using var data = caching.Load("baboon.png"); + + Assert.Equal(expectedData.ToArray(), data.ToArray()); + } + + [SkippableFact] + public void CanCreateDefaultDataUri() + { + using var datauri = new DataUriResourceProvider(); + + Assert.NotNull(datauri); + } + + [SkippableFact] + public void CanCreateNullDataUri() + { + using var datauri = new DataUriResourceProvider(null); + + Assert.NotNull(datauri); + } + + [SkippableFact] + public void WrappedResourceManagersAreNotCollectedPrematurely() + { + var fullPath = Path.Combine(PathToImages, "baboon.png"); + var expectedData = SKData.Create(fullPath); + + var (caching, weak) = CreateProvider(); + + CollectGarbage(); + + Assert.True(weak.IsAlive); + + using var data = caching.Load("baboon.png"); + + Assert.Equal(expectedData.ToArray(), data.ToArray()); + + static (CachingResourceProvider, WeakReference) CreateProvider() + { + var files = new FileResourceProvider(PathToImages); + var datauri = new DataUriResourceProvider(files); + var caching = new CachingResourceProvider(datauri); + + return (caching, new WeakReference(files)); + } + } + } +} diff --git a/tests/Tests/SkiaSharp/SKBlenderTest.cs b/tests/Tests/SkiaSharp/SKBlenderTest.cs new file mode 100644 index 0000000000..b7a01ad8b5 --- /dev/null +++ b/tests/Tests/SkiaSharp/SKBlenderTest.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using Xunit; + +namespace SkiaSharp.Tests; + +public class SKBlenderTest +{ + [SkippableFact] + public void SameBlendModeReturnsSameBlenderInstance() + { + var blender1 = SKBlender.CreateBlendMode(SKBlendMode.Src); + var blender2 = SKBlender.CreateBlendMode(SKBlendMode.Src); + + Assert.Same(blender1, blender2); + } + + [SkippableFact] + public void BlendModeBlenderIsNotDisposed() + { + var blender = SKBlender.CreateBlendMode(SKBlendMode.Src); + Assert.True(SKObject.GetInstance(blender.Handle, out _)); + + blender.Dispose(); + Assert.True(SKObject.GetInstance(blender.Handle, out _)); + } + + [SkippableFact] + public void ArithmeticBlendModeBlenderIsBlendModeBlender() + { + var blendmode = SKBlender.CreateBlendMode(SKBlendMode.Src); + + var arithmetic = SKBlender.CreateArithmetic(0, 1, 0, 0, false); + + Assert.Same(blendmode, arithmetic); + } + + [SkippableFact] + public void InvalidBlendModeThrowsArgumentException() + { + Assert.Throws(() => SKBlender.CreateBlendMode((SKBlendMode)100)); + } + + public abstract class SurfaceTestBase : SKTest + { + protected SKSurface Surface { get; set; } + + protected SKImageInfo Info { get; set; } + + protected abstract void CreateSurface(int width, int height); + + [SkippableTheory] + [MemberData(nameof(GetAllBlendModes))] + public void BlenderMatchesBlendModeWhenUsingOpaqueColor(SKBlendMode mode) + { + var blendModeColor = GetColor(p => ApplyColor(p, false), p => ApplyBlendMode(p, mode)); + var blenderColor = GetColor(p => ApplyColor(p, false), p => ApplyBlender(p, mode)); + Assert.Equal(blendModeColor, blenderColor); + } + + [SkippableTheory] + [MemberData(nameof(GetAllBlendModes))] + public void BlenderMatchesBlendModeWhenUsingransparentColor(SKBlendMode mode) + { + var blendModeColor = GetColor(p => ApplyColor(p, true), p => ApplyBlendMode(p, mode)); + var blenderColor = GetColor(p => ApplyColor(p, true), p => ApplyBlender(p, mode)); + Assert.Equal(blendModeColor, blenderColor); + } + + [SkippableTheory] + [MemberData(nameof(GetAllBlendModes))] + public void BlenderMatchesBlendModeWhenUsingOpaqueShader(SKBlendMode mode) + { + var blendModeColor = GetColor(p => ApplyColorShader(p, false), p => ApplyBlendMode(p, mode)); + var blenderColor = GetColor(p => ApplyColorShader(p, false), p => ApplyBlender(p, mode)); + Assert.Equal(blendModeColor, blenderColor); + } + + [SkippableTheory] + [MemberData(nameof(GetAllBlendModes))] + public void BlenderMatchesBlendModeWhenUsingransparentShader(SKBlendMode mode) + { + var blendModeColor = GetColor(p => ApplyColorShader(p, true), p => ApplyBlendMode(p, mode)); + var blenderColor = GetColor(p => ApplyColorShader(p, true), p => ApplyBlender(p, mode)); + Assert.Equal(blendModeColor, blenderColor); + } + + private SKColor GetColor(Action applyColor, Action applyBlend) + { + // Draw a solid red pixel. + using var paint = new SKPaint + { + Shader = null, + Color = SKColors.Red, + Blender = null, + BlendMode = SKBlendMode.Src, + }; + Surface.Canvas.DrawRect(SKRect.Create(1, 1), paint); + + // Draw a blue pixel on top of it, using the passed-in blend mode. + applyColor(paint); + applyBlend(paint); + Surface.Canvas.DrawRect(SKRect.Create(1, 1), paint); + + // Read the pixels out of the surface and into the bitmap. + using var bmp = new SKBitmap(new SKImageInfo(1, 1)); + Surface.ReadPixels(bmp.Info, bmp.GetPixels(), bmp.RowBytes, 0, 0); + + // Get the pixel color. + return bmp.GetPixel(0, 0); + } + + private static void ApplyBlendMode(SKPaint paint, SKBlendMode mode) => + paint.BlendMode = mode; + + private static void ApplyBlender(SKPaint paint, SKBlendMode mode) => + paint.Blender = GetRuntimeBlenderForBlendMode(mode); + + private static void ApplyColor(SKPaint paint, bool useTransparent) + { + var alpha = GetAlpha(useTransparent); + paint.Color = new SKColor(0x00, 0x00, 0xFF, alpha); + } + + private static void ApplyColorShader(SKPaint paint, bool useTransparent) + { + // Install a different color in the paint, to ensure we're using the shader + paint.Color = SKColors.Green; + + var alpha = GetAlpha(useTransparent); + paint.Shader = SKShader.CreateColor(new SKColor(0x00, 0x00, 0xFF, alpha)); + } + + private static byte GetAlpha(bool useTransparent) => + useTransparent ? (byte)0x80 : (byte)0xFF; + + public static IEnumerable GetAllBlendModes() + { + foreach (SKBlendMode mode in Enum.GetValues(typeof(SKBlendMode))) + yield return new object[] { mode }; + } + + private static SKBlender GetRuntimeBlenderForBlendMode(SKBlendMode mode) + { + using var builder = SKRuntimeEffect.BuildBlender( + """ + uniform blender b; + half4 main(half4 src, half4 dst) { + return b.eval(src, dst); + } + """); + + Assert.NotNull(builder.Effect); + + builder.Children["b"] = SKBlender.CreateBlendMode(mode); + + return builder.Build(); + } + } + + [Trait(Traits.Category.Key, Traits.Category.Values.Gpu)] + public unsafe class Gpu : SurfaceTestBase, IDisposable + { + GlContext glContext; + GRContext grContext; + + public Gpu() + { + glContext = CreateGlContext(); + glContext.MakeCurrent(); + + grContext = GRContext.CreateGl(); + + CreateSurface(1, 1); + } + + protected override void CreateSurface(int width, int height) + { + Surface?.Dispose(); + + Info = new SKImageInfo(width, height, SKColorType.Rgba8888); + Surface = SKSurface.Create(grContext, false, Info); + } + + public void Dispose() + { + Surface.Dispose(); + grContext.Dispose(); + glContext.Destroy(); + } + } + + public unsafe class Raster : SurfaceTestBase, IDisposable + { + public Raster() + { + CreateSurface(1, 1); + } + + protected override void CreateSurface(int width, int height) + { + Surface?.Dispose(); + + Info = new SKImageInfo(width, height, SKColorType.Rgba8888); + Surface = SKSurface.Create(Info); + } + + public void Dispose() + { + Surface.Dispose(); + } + } +} diff --git a/tests/Tests/SkiaSharp/SKDrawableTest.cs b/tests/Tests/SkiaSharp/SKDrawableTest.cs index bc2466ae08..91110e4731 100644 --- a/tests/Tests/SkiaSharp/SKDrawableTest.cs +++ b/tests/Tests/SkiaSharp/SKDrawableTest.cs @@ -6,6 +6,41 @@ public class SKDrawableTest : SKTest { [SkippableFact] public void CanInstantiateDrawable() + { + using (var drawable = new TestDrawable()) + { + } + } + + [SkippableFact] + public void CanAccessBounds() + { + using (var drawable = new TestDrawable()) + { + Assert.Equal(SKRect.Create(100, 100), drawable.Bounds); + Assert.Equal(1, drawable.BoundsFireCount); + } + } + + [Trait(Traits.FailingOn.Key, Traits.FailingOn.Values.macOS)] // Something with sk_sp SkDrawable::onMakePictureSnapshot() is causing issues + [Trait(Traits.FailingOn.Key, Traits.FailingOn.Values.iOS)] // Something with sk_sp SkDrawable::onMakePictureSnapshot() is causing issues + [Trait(Traits.FailingOn.Key, Traits.FailingOn.Values.MacCatalyst)] // Something with sk_sp SkDrawable::onMakePictureSnapshot() is causing issues + [SkippableFact] + public void CanCreateSnapshot() + { + using (var drawable = new TestDrawable()) + { + var picture = drawable.Snapshot(); + Assert.NotNull(picture); + Assert.Equal(1, drawable.SnapshotFireCount); + } + } + + [Trait(Traits.FailingOn.Key, Traits.FailingOn.Values.macOS)] // Something with sk_sp SkDrawable::onMakePictureSnapshot() is causing issues + [Trait(Traits.FailingOn.Key, Traits.FailingOn.Values.iOS)] // Something with sk_sp SkDrawable::onMakePictureSnapshot() is causing issues + [Trait(Traits.FailingOn.Key, Traits.FailingOn.Values.MacCatalyst)] // Something with sk_sp SkDrawable::onMakePictureSnapshot() is causing issues + [SkippableFact] + public void CanUseAllMembers() { using (var drawable = new TestDrawable()) { diff --git a/tests/Tests/SkiaSharp/SKImageTest.cs b/tests/Tests/SkiaSharp/SKImageTest.cs index ce350854a3..e8942b5ef2 100644 --- a/tests/Tests/SkiaSharp/SKImageTest.cs +++ b/tests/Tests/SkiaSharp/SKImageTest.cs @@ -900,5 +900,30 @@ public void CanDecodePotentiallyCorruptPngFiles(string filename, int x, int y, u Assert.Equal((SKColor)color, pixmap.GetPixelColor(x, y)); } + + [SkippableFact] + public void CanCreateRawShader() + { + var path = Path.Combine(PathToImages, "baboon.png"); + + using var image = SKImage.FromEncodedData(path); + Assert.NotNull(image); + + using var shader = image.ToRawShader(); + Assert.NotNull(shader); + } + + [SkippableFact] + public void CannotCreateRawShaderWithBicubicSampling() + { + var path = Path.Combine(PathToImages, "baboon.png"); + + using var image = SKImage.FromEncodedData(path); + Assert.NotNull(image); + + var sampling = new SKSamplingOptions(SKCubicResampler.Mitchell); + using var shader = image.ToRawShader(SKShaderTileMode.Clamp, SKShaderTileMode.Clamp, sampling); + Assert.Null(shader); + } } } diff --git a/tests/Tests/SkiaSharp/SKMatrix44Tests.cs b/tests/Tests/SkiaSharp/SKMatrix44Tests.cs index f8dc0ac381..371b81f759 100644 --- a/tests/Tests/SkiaSharp/SKMatrix44Tests.cs +++ b/tests/Tests/SkiaSharp/SKMatrix44Tests.cs @@ -60,6 +60,74 @@ public void MatrixGoesFullCircle() Assert.Equal(rowMajor, result); } + [SkippableFact] + public void TranslationFieldsAreCorrectForMatrix() + { + var skm44 = SKMatrix44.CreateTranslation(10, 20, 30); + + var matrix = skm44.Matrix; + + Assert.Equal(10, matrix.TransX); + Assert.Equal(20, matrix.TransY); + } + + [SkippableFact] + public void ScaleFieldsAreCorrectForMatrix() + { + var skm44 = SKMatrix44.CreateScale(10, 20, 30); + + var matrix = skm44.Matrix; + + Assert.Equal(10, matrix.ScaleX); + Assert.Equal(20, matrix.ScaleY); + } + + [SkippableFact] + public void TranslateConvertsToMatrix() + { + var matrix44 = SKMatrix44.CreateTranslation(10, 20, 30); + var matrix = SKMatrix.CreateTranslation(10, 20); + + AssertSimilar(matrix.Values, matrix44.Matrix.Values, 6); + } + + [SkippableFact] + public void ScaleConvertsToMatrix() + { + var matrix44 = SKMatrix44.CreateScale(10, 20, 30); + var matrix = SKMatrix.CreateScale(10, 20); + + AssertSimilar(matrix.Values, matrix44.Matrix.Values, 6); + } + + [SkippableFact] + public void RotationConvertsToMatrix() + { + var matrix44 = SKMatrix44.CreateRotationDegrees(0, 0, 1, 45); + var matrix = SKMatrix.CreateRotationDegrees(45); + + AssertSimilar(matrix.Values, matrix44.Matrix.Values, 6); + } + + [SkippableFact] + public void ImplicitFromMatrix() + { + var matrix = SKMatrix.CreateRotationDegrees(45); + var matrix44 = (SKMatrix44)matrix; + + Assert.Equal(matrix.Values, matrix44.Matrix.Values); + } + + [SkippableFact] + public void ImplicitFromRotationScale() + { + var rs = SKRotationScaleMatrix.CreateRotationDegrees(45, 0, 0); + var matrix = SKMatrix.CreateRotationDegrees(45); + var matrix44 = (SKMatrix44)rs.ToMatrix(); + + Assert.Equal(matrix.Values, matrix44.Matrix.Values); + } + [SkippableFact] public void TransposeWorks() { @@ -136,108 +204,32 @@ public void Matrix44Inverts() } [SkippableFact] - public void Matrix44ConvertsToMatrix() - { - var rowMajor44 = new float[] { - 2, 3, 4, 5, - 4, 6, 8, 10, - 6, 9, 12, 15, - 8, 12, 16, 20, - }; - var rowMajor = new float[] { - rowMajor44[0], rowMajor44[1], rowMajor44[3], - rowMajor44[4], rowMajor44[5], rowMajor44[7], - rowMajor44[12], rowMajor44[13], rowMajor44[15], - }; - - var matrix44 = SKMatrix44.FromRowMajor(rowMajor44); - - Assert.Equal(rowMajor, matrix44.Matrix.Values); - } - - [SkippableFact] - public void TransformConvertsToMatrix() - { - var matrix44 = SKMatrix44.CreateRotationDegrees(0, 0, 1, 45); - var matrix = SKMatrix.CreateRotationDegrees(45); - - AssertSimilar(matrix.Values, matrix44.Matrix.Values, 6); - } - - [SkippableFact] - public void ImplicitFromMatrix() - { - var matrix = SKMatrix.CreateRotationDegrees(45); - var matrix44 = (SKMatrix44)matrix; - - Assert.Equal(matrix.Values, matrix44.Matrix.Values); - } - - [SkippableFact] - public void ImplicitFromRotationScale() - { - var rs = SKRotationScaleMatrix.CreateRotationDegrees(45, 0, 0); - var matrix = SKMatrix.CreateRotationDegrees(45); - var matrix44 = (SKMatrix44)rs.ToMatrix(); - - Assert.Equal(matrix.Values, matrix44.Matrix.Values); - } - -#if NET5_0_OR_GREATER - - [SkippableFact] - public void IndicesAreCorrectOnIdentity() + public void IndicesAreCorrectOnIdentityUsingFields() { var skm = SKMatrix44.CreateIdentity(); var m4x4 = Matrix4x4.Identity; - for (var row = 0; row < 4; row++) - { - for (var col = 0; col < 4; col++) - { - var sk = skm[row, col]; - var m = m4x4[row, col]; - Assert.Equal(m, sk); - } - } + AssertEqualFields(skm, m4x4); } [SkippableFact] - public void IndicesAreCorrectOnTranslate() + public void IndicesAreCorrectOnTranslateUsingFields() { var skm = SKMatrix44.CreateTranslation(10, 20, 30); var m4x4 = Matrix4x4.CreateTranslation(10, 20, 30); - for (var row = 0; row < 4; row++) - { - for (var col = 0; col < 4; col++) - { - var sk = skm[row, col]; - var m = m4x4[row, col]; - Assert.Equal(m, sk); - } - } + AssertEqualFields(skm, m4x4); } [SkippableFact] - public void IndicesAreCorrectOnScale() + public void IndicesAreCorrectOnScaleUsingFields() { var skm = SKMatrix44.CreateScale(10, 20, 30); var m4x4 = Matrix4x4.CreateScale(10, 20, 30); - for (var row = 0; row < 4; row++) - { - for (var col = 0; col < 4; col++) - { - var sk = skm[row, col]; - var m = m4x4[row, col]; - Assert.Equal(m, sk); - } - } + AssertEqualFields(skm, m4x4); } -#endif - [SkippableFact] public void TranslationMapsScalars() { @@ -350,6 +342,87 @@ public void ScaleIsCorrectLayoutWithOriginTopLeft(int x, int y, int z) AssertMatrixBitmap(bmp, SKRectI.Create(30 * x, 30 * y, 10 * x, 10 * y)); } + [SkippableTheory] + [InlineData(1, 0, 0, 30)] + [InlineData(0, 1, 0, 30)] + [InlineData(0, 0, 1, 30)] + [InlineData(1, 0, 0, -30)] + [InlineData(0, 1, 0, -30)] + [InlineData(0, 0, 1, -30)] + public void RotationIsCorrectLayoutWithOriginTopLeft(int x, int y, int z, int angle) + { + var matrix = SKMatrix44.CreateRotationDegrees(x, y, z, angle); + + using var bmp = DrawMatrixBitmap(SKRectI.Create(25, 25, 50, 50), matrix); + } + +#if NET5_0_OR_GREATER + + [SkippableFact] + public void IndicesAreCorrectOnIdentity() + { + var skm = SKMatrix44.CreateIdentity(); + var m4x4 = Matrix4x4.Identity; + + AssertEqualIndices(skm, m4x4); + } + + [SkippableFact] + public void IndicesAreCorrectOnTranslate() + { + var skm = SKMatrix44.CreateTranslation(10, 20, 30); + var m4x4 = Matrix4x4.CreateTranslation(10, 20, 30); + + AssertEqualIndices(skm, m4x4); + } + + [SkippableFact] + public void IndicesAreCorrectOnScale() + { + var skm = SKMatrix44.CreateScale(10, 20, 30); + var m4x4 = Matrix4x4.CreateScale(10, 20, 30); + + AssertEqualIndices(skm, m4x4); + } + + private static void AssertEqualIndices(SKMatrix44 skm, Matrix4x4 m4x4) + { + for (var row = 0; row < 4; row++) + { + for (var col = 0; col < 4; col++) + { + var sk = skm[row, col]; + var m = m4x4[row, col]; + Assert.Equal(m, sk); + } + } + } + +#endif + + private static void AssertEqualFields(SKMatrix44 skm, Matrix4x4 m4x4) + { + Assert.Equal(skm.M00, m4x4.M11); + Assert.Equal(skm.M01, m4x4.M12); + Assert.Equal(skm.M02, m4x4.M13); + Assert.Equal(skm.M03, m4x4.M14); + + Assert.Equal(skm.M10, m4x4.M21); + Assert.Equal(skm.M11, m4x4.M22); + Assert.Equal(skm.M12, m4x4.M23); + Assert.Equal(skm.M13, m4x4.M24); + + Assert.Equal(skm.M20, m4x4.M31); + Assert.Equal(skm.M21, m4x4.M32); + Assert.Equal(skm.M22, m4x4.M33); + Assert.Equal(skm.M23, m4x4.M34); + + Assert.Equal(skm.M30, m4x4.M41); + Assert.Equal(skm.M31, m4x4.M42); + Assert.Equal(skm.M32, m4x4.M43); + Assert.Equal(skm.M33, m4x4.M44); + } + private static SKBitmap DrawMatrixBitmap(SKRect rect, SKMatrix44 matrix) { var bmp = new SKBitmap(100, 100); diff --git a/tests/Tests/SkiaSharp/SKTextBlobTest.cs b/tests/Tests/SkiaSharp/SKTextBlobTest.cs index 32cb3e35cd..58785b35c7 100644 --- a/tests/Tests/SkiaSharp/SKTextBlobTest.cs +++ b/tests/Tests/SkiaSharp/SKTextBlobTest.cs @@ -16,6 +16,36 @@ public void TestEmptyBuilderReturnsNull() Assert.Null(blob); } + [SkippableFact] + public void RunsAllocateNoPositions() + { + var font = new SKFont(); + + using var builder = new SKTextBlobBuilder(); + + var run = builder.AllocateRun(font, 100, 0, 0); + Assert.Equal(100, run.Glyphs.Length); + + using var blob = builder.Build(); + Assert.NotNull(blob); + } + + [SkippableFact] + public void RawRunsAllocateNoPositions() + { + var font = new SKFont(); + + using var builder = new SKTextBlobBuilder(); + + var run = builder.AllocateRawRun(font, 100, 0, 0); + Assert.Equal(100, run.Glyphs.Length); + Assert.Equal(0, run.Positions.Length); + Assert.Equal(0, run.Text.Length); + + using var blob = builder.Build(); + Assert.NotNull(blob); + } + [SkippableFact] public void TextRunsAllocateTextSpan() { @@ -24,8 +54,23 @@ public void TextRunsAllocateTextSpan() using var builder = new SKTextBlobBuilder(); var run = builder.AllocateTextRun(font, 100, 0, 0, 50); - Assert.Equal(100, run.GetGlyphSpan().Length); - Assert.Equal(50, run.GetTextSpan().Length); + Assert.Equal(100, run.Glyphs.Length); + Assert.Equal(50, run.Text.Length); + + using var blob = builder.Build(); + Assert.NotNull(blob); + } + + [SkippableFact] + public void RawTextRunsAllocateTextSpan() + { + var font = new SKFont(); + + using var builder = new SKTextBlobBuilder(); + + var run = builder.AllocateRawTextRun(font, 100, 0, 0, 50); + Assert.Equal(100, run.Glyphs.Length); + Assert.Equal(50, run.Text.Length); using var blob = builder.Build(); Assert.NotNull(blob); @@ -112,7 +157,7 @@ public unsafe void TestPositionedRunIsBothPointsAndFloats() run.SetPositions(positions); - var span = run.GetPositionSpan(); + var span = run.Positions; Assert.Equal(positions, span.ToArray()); var floats = new float[6]; diff --git a/tests/Tests/Skottie/AnimationBuilderTest.cs b/tests/Tests/Skottie/AnimationBuilderTest.cs new file mode 100644 index 0000000000..a2644e1c2b --- /dev/null +++ b/tests/Tests/Skottie/AnimationBuilderTest.cs @@ -0,0 +1,141 @@ +using System; +using System.IO; +using SkiaSharp.Resources; +using SkiaSharp.SceneGraph; +using SkiaSharp.Skottie; +using Xunit; + +namespace SkiaSharp.Tests +{ + public class AnimationBuilderTest : SKTest + { + public static TheoryData DefaultLottieFiles => + AnimationTest.DefaultLottieFiles; + + public static TheoryData Base64Files => + new TheoryData + { + "lottie-base64_dotnet-bot.json", + "lottie-base64_women-thinking.json", + }; + + [SkippableTheory] + [MemberData(nameof(DefaultLottieFiles))] + public void DefaultBuilderIsTheSameAsDefaultCreate(string filename) + { + var path = Path.Combine(PathToImages, filename); + using var data = SKData.Create(path); + var directAnimation = Animation.Create(data); + + var builderAnimation = Animation.CreateBuilder().Build(data); + Assert.NotNull(builderAnimation); + Assert.NotEqual(IntPtr.Zero, builderAnimation.Handle); + + Assert.Equal(directAnimation.Duration, builderAnimation.Duration); + Assert.Equal(directAnimation.Fps, builderAnimation.Fps); + Assert.Equal(directAnimation.InPoint, builderAnimation.InPoint); + Assert.Equal(directAnimation.OutPoint, builderAnimation.OutPoint); + Assert.Equal(directAnimation.Version, builderAnimation.Version); + Assert.Equal(directAnimation.Size, builderAnimation.Size); + } + + [SkippableTheory] + [MemberData(nameof(DefaultLottieFiles))] + public void DefaultBuilderHasStats(string filename) + { + var path = Path.Combine(PathToImages, filename); + using var data = SKData.Create(path); + + var builder = Animation.CreateBuilder(); + var animation = builder.Build(data); + Assert.NotNull(animation); + + var stats = builder.Stats; + Assert.True(stats.SceneParseTime >= TimeSpan.Zero); + Assert.True(stats.JsonParseTime >= TimeSpan.Zero); + Assert.True(stats.TotalLoadTime >= TimeSpan.Zero); + Assert.True(stats.JsonSize > 0); + Assert.True(stats.AnimatorCount > 0); + } + + [SkippableTheory] + [MemberData(nameof(Base64Files))] + public void CanLoadBase64ImagesFromData(string filename) + { + var path = Path.Combine(PathToImages, filename); + using var data = SKData.Create(path); + + var animation = Animation + .CreateBuilder() + .SetResourceProvider(new DataUriResourceProvider()) + .Build(data); + + Assert.NotNull(animation); + Assert.True(animation.Duration > TimeSpan.Zero); + } + + [SkippableTheory] + [MemberData(nameof(Base64Files))] + public void CanLoadBase64ImagesFromFilename(string filename) + { + var path = Path.Combine(PathToImages, filename); + + var animation = Animation + .CreateBuilder() + .SetResourceProvider(new DataUriResourceProvider()) + .Build(path); + + Assert.NotNull(animation); + Assert.True(animation.Duration > TimeSpan.Zero); + } + + [SkippableTheory] + [MemberData(nameof(Base64Files))] + public void CanRenderWithBase64(string filename) + { + var animation = Animation + .CreateBuilder() + .SetResourceProvider(new DataUriResourceProvider()) + .Build(Path.Combine(PathToImages, filename)); + + using var bmp = new SKBitmap((int)animation.Size.Width, (int)animation.Size.Height); + bmp.Erase(SKColors.Red); + var beforePixels = bmp.Pixels; + + using var canvas = new SKCanvas(bmp); + animation.Seek(0.1); + animation.Render(canvas, bmp.Info.Rect); + var afterPixels = bmp.Pixels; + + Assert.NotEqual(beforePixels, afterPixels); + } + + [SkippableFact] + public void WrappedResourceManagersAreNotCollectedPrematurely() + { + var (builder, weak) = CreateBuilder(); + + CollectGarbage(); + + Assert.True(weak.IsAlive); + + using var animation = builder.Build(Path.Combine(PathToImages, "lottie-base64_dotnet-bot.json")); + + builder.Dispose(); + CollectGarbage(); + + Assert.False(weak.IsAlive); + + static (AnimationBuilder, WeakReference) CreateBuilder() + { + var provider = new DataUriResourceProvider(); + + var builder = Animation + .CreateBuilder() + .SetResourceProvider(provider); + + return (builder, new WeakReference(provider)); + } + } + } +} diff --git a/tests/Tests/Skottie/AnimationTest.cs b/tests/Tests/Skottie/AnimationTest.cs index 02a7b4f0ff..3c115e619b 100644 --- a/tests/Tests/Skottie/AnimationTest.cs +++ b/tests/Tests/Skottie/AnimationTest.cs @@ -177,9 +177,12 @@ public void When_Default_Create_From_File(string filename) Assert.NotEqual(IntPtr.Zero, animation.Handle); } - private Animation BuildDefaultAnimation() + private Animation BuildDefaultAnimation() => + BuildAnimation("LottieLogo1.json"); + + private Animation BuildAnimation(string filename) { - var path = Path.Combine(PathToImages, "LottieLogo1.json"); + var path = Path.Combine(PathToImages, filename); var result = Animation.TryCreate(path, out var animation); Assert.True(result); @@ -307,5 +310,39 @@ public void When_Size() Assert.Equal(new SKSize(375, 667), animation.Size); } + + [SkippableFact] + public void Can_Render() + { + var animation = BuildDefaultAnimation(); + + using var bmp = new SKBitmap((int)animation.Size.Width, (int)animation.Size.Height); + bmp.Erase(SKColors.Red); + var beforePixels = bmp.Pixels; + + using var canvas = new SKCanvas(bmp); + animation.Seek(0.1); + animation.Render(canvas, bmp.Info.Rect); + var afterPixels = bmp.Pixels; + + Assert.NotEqual(beforePixels, afterPixels); + } + + [SkippableFact] + public void Can_Not_Render_With_Base64() + { + var animation = BuildAnimation("lottie-base64_dotnet-bot.json"); + + using var bmp = new SKBitmap((int)animation.Size.Width, (int)animation.Size.Height); + bmp.Erase(SKColors.Red); + var beforePixels = bmp.Pixels; + + using var canvas = new SKCanvas(bmp); + animation.Seek(0.1); + animation.Render(canvas, bmp.Info.Rect); + var afterPixels = bmp.Pixels; + + Assert.Equal(beforePixels, afterPixels); + } } } diff --git a/utils/NativeLibraryMiniTest/docker/NativeLibraryMiniTest.csproj b/utils/NativeLibraryMiniTest/docker/NativeLibraryMiniTest.csproj index 21aa313d61..f40c99436d 100644 --- a/utils/NativeLibraryMiniTest/docker/NativeLibraryMiniTest.csproj +++ b/utils/NativeLibraryMiniTest/docker/NativeLibraryMiniTest.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + net7.0 True diff --git a/utils/README.md b/utils/README.md index 665466f169..f40d2a413f 100644 --- a/utils/README.md +++ b/utils/README.md @@ -11,10 +11,7 @@ This is a small set of tools that help with generating the p/invoke layer from t This can be run with: ```pwsh -dotnet run --project=utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj -- generate --config binding/libSkiaSharp.json --skia externals/skia --output binding/SkiaSharp/SkiaApi.generated.cs -dotnet run --project=utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj -- generate --config binding/libSkiaSharp.Skottie.json --skia externals/skia --output binding/SkiaSharp.Skottie/SkottieApi.generated.cs -dotnet run --project=utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj -- generate --config binding/libSkiaSharp.SceneGraph.json --skia externals/skia --output binding/SkiaSharp.SceneGraph/SceneGraphApi.generated.cs -dotnet run --project=utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj -- generate --config binding/libHarfBuzzSharp.json --skia externals/skia/third_party/externals/harfbuzz --output binding/HarfBuzzSharp/HarfBuzzApi.generated.cs +.\utils\generate.ps1 ``` * `--config binding/libSkiaSharp.json` diff --git a/utils/SkiaSharpGenerator/Generate/GenerateCommand.cs b/utils/SkiaSharpGenerator/Generate/GenerateCommand.cs index 105da78e10..bc7404e7f6 100644 --- a/utils/SkiaSharpGenerator/Generate/GenerateCommand.cs +++ b/utils/SkiaSharpGenerator/Generate/GenerateCommand.cs @@ -20,7 +20,7 @@ public GenerateCommand() protected override OptionSet OnCreateOptions() => new OptionSet { - { "s|skia=", "The root of the skia source", v => SourceRoot = v }, + { "r|root=", "The root of the source", v => SourceRoot = v }, { "c|config=", "The config file path", v => ConfigPath = v }, { "o|output=", "The output path", v => OutputPath = v }, }; @@ -31,7 +31,7 @@ protected override bool OnValidateArguments(IEnumerable extras) if (string.IsNullOrEmpty(SourceRoot)) { - Program.Log.LogError($"{Program.Name}: Path to the skia source was not provided: `--skia=`."); + Program.Log.LogError($"{Program.Name}: Path to the skia source was not provided: `--root=`."); hasError = true; } else if (!Directory.Exists(SourceRoot)) diff --git a/utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj b/utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj index 4e74a576f7..25df0ee165 100644 --- a/utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj +++ b/utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj @@ -2,12 +2,18 @@ Exe - net6.0 + net7.0 enable + LatestMajor + + + + + $(NETCoreSdkRuntimeIdentifier) - + diff --git a/utils/generate.ps1 b/utils/generate.ps1 new file mode 100644 index 0000000000..12d937313b --- /dev/null +++ b/utils/generate.ps1 @@ -0,0 +1,25 @@ +$ErrorActionPreference = "Stop" + +$projects = @( + @{ Json="libSkiaSharp.json"; Root="externals/skia"; Output="SkiaSharp/SkiaApi.generated.cs" }, + @{ Json="libSkiaSharp.Skottie.json"; Root="externals/skia"; Output="SkiaSharp.Skottie/SkottieApi.generated.cs" }, + @{ Json="libSkiaSharp.SceneGraph.json"; Root="externals/skia"; Output="SkiaSharp.SceneGraph/SceneGraphApi.generated.cs" }, + @{ Json="libSkiaSharp.Resources.json"; Root="externals/skia"; Output="SkiaSharp.Resources/ResourcesApi.generated.cs" }, + @{ Json="libHarfBuzzSharp.json"; Root="externals/skia/third_party/externals/harfbuzz"; Output="HarfBuzzSharp/HarfBuzzApi.generated.cs" } +) + +New-Item -ItemType Directory -Force -Path "output/generated/" | Out-Null + +foreach ($proj in $projects) { + $json = $proj.Json; + $output = $proj.Output; + $root = $proj.Root; + $filename = Split-Path $output -Leaf + + dotnet run --project=utils/SkiaSharpGenerator/SkiaSharpGenerator.csproj -- generate --config binding/$json --root $root --output binding/$output + if (!$?) { + exit $LASTEXITCODE + } + + Copy-Item -Path binding/$output -Destination output/generated/$filename -Force +}