migrate to github actions and fix warnings

This commit is contained in:
Scott Williams 2020-01-18 16:12:49 +00:00
Родитель 122bb27135
Коммит aa7b7313fd
99 изменённых файлов: 1554 добавлений и 1027 удалений

Просмотреть файл

@ -370,3 +370,6 @@ csharp_style_unused_value_assignment_preference = discard_variable:suggestion
csharp_style_var_for_built_in_types = false:warning
csharp_style_var_elsewhere = false:warning
csharp_style_var_when_type_is_apparent = true:warning
# SA1011: Closing square brackets should be spaced correctly
dotnet_diagnostic.SA1011.severity = none

34
.github/CONTRIBUTING.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,34 @@
# How to contribute to ImageSharp
#### **Did you find a bug?**
- Please **ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/SixLabors/Fonts/issues).
- If you're unable to find an open issue addressing the problem, please [open a new one](https://github.com/SixLabors/Fonts/issues/new). Be sure to include a **title, the applicable version, a clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. Please do not hijack existing issues.
#### **Did you write a patch that fixes a bug?**
* Open a new GitHub pull request with the patch.
* Ensure the PR description clearly describes the problem and solution. Include the relevant issue number if applicable.
* Before submitting, please ensure that your code matches the existing coding patterns and practise as demonstrated in the repository. These follow strict Stylecop rules :cop:.
#### **Do you intend to add a new feature or change an existing one?**
* Suggest your change in the [ImageSharp Gitter Chat Room](https://gitter.im/ImageSharp/General) and start writing code.
* Do not open an issue on GitHub until you have collected positive feedback about the change. GitHub issues are primarily intended for bug reports and fixes.
#### **Do you have questions about consuming the library or the source code?**
* Ask any question about how to use ImageSharp in the [ImageSharp Gitter Chat Room](https://gitter.im/ImageSharp/General).
#### Code of Conduct
This project has adopted the code of conduct defined by the [Contributor Covenant](https://contributor-covenant.org/) to clarify expected behavior in our community.
For more information, see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
And please remember. SixLabors.Fonts is the work of a very, very, small number of developers who struggle balancing time to contribute to the project with family time and work commitments. We encourage you to pitch in and help make our vision of simple accessible imageprocessing available to all. Open Source can only exist with your help.
Thanks for reading!

1
.github/FUNDING.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
open_collective: imagesharp

13
.github/ISSUE_TEMPLATE/ask-question.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,13 @@
---
name: Ask question
about: Ask a question about this project.
---
You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General
You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General
You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General
You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General

29
.github/ISSUE_TEMPLATE/bug-report.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve
---
### Prerequisites
- [ ] I have written a descriptive issue title
- [ ] I have verified that I am running the latest version of SixLabors.Fonts
- [ ] I have verified if the problem exist in both `DEBUG` and `RELEASE` mode
- [ ] I have searched [open](https://github.com/SixLabors/Fonts/issues) and [closed](https://github.com/SixLabors/Fonts/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported
### Description
<!-- A description of the bug or feature -->
### Steps to Reproduce
<!-- List of steps, sample code, failing test or link to a project that reproduces the behavior -->
### System Configuration
<!-- Tell us about the environment where you are experiencing the bug -->
- SixLabors.Fonts version:
- Other SixLabors packages and versions:
- Environment (Operating system, version and so on):
- .NET Framework version:
- Additional information:
<!-- Thanks for reporting the issue to SixLabors.Fonts! -->

13
.github/ISSUE_TEMPLATE/feature-request.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,13 @@
---
name: Feature request
about: Suggest an idea for this project
---
You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General
You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General
You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General
You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General

11
.github/PULL_REQUEST_TEMPLATE.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,11 @@
### Prerequisites
- [ ] I have written a descriptive pull-request title
- [ ] I have verified that there are no overlapping [pull-requests](https://github.com/SixLabors/Fonts/pulls) open
- [ ] I have verified that I am following matches the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules :cop:.
- [ ] I have provided test coverage for my change (where applicable)
### Description
<!-- A description of the changes proposed in the pull-request -->
<!-- Thanks for contributing to SixLabors.Fonts! -->

105
.github/workflows/build-and-test.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,105 @@
name: Build
on:
push:
branches:
- master
tags:
- "v*"
pull_request:
branches:
- master
jobs:
Build:
strategy:
matrix:
options:
- os: ubuntu-latest
framework: netcoreapp3.1
runtime: -x64
codecov: false
- os: windows-latest
framework: netcoreapp3.1
runtime: -x64
codecov: true
- os: windows-latest
framework: netcoreapp2.1
runtime: -x64
codecov: false
- os: windows-latest
framework: net472
runtime: -x64
codecov: false
- os: windows-latest
framework: net472
runtime: -x86
codecov: false
runs-on: ${{matrix.options.os}}
steps:
- uses: actions/checkout@v2
- name: Install NuGet
uses: NuGet/setup-nuget@v1
- name: Setup Git
shell: bash
run: |
git config --global core.autocrlf false
git config --global core.longpaths true
git fetch --prune --unshallow
git submodule -q update --init --recursive
- name: Fetch Tags for GitVersion
run: |
git fetch --tags
- name: Fetch master for GitVersion
if: github.ref != 'refs/heads/master'
run: git branch --create-reflog master origin/master
- name: Install GitVersion
uses: gittools/actions/setup-gitversion@v0.3
with:
versionSpec: "5.1.x"
- name: Use GitVersion
id: gitversion # step id used as reference for output values
uses: gittools/actions/execute-gitversion@v0.3
- name: Setup DotNet SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: "3.1.101"
- name: Build
shell: pwsh
run: ./ci-build.ps1 "${{steps.gitversion.outputs.nuGetVersion}}" "${{matrix.options.framework}}"
- name: Test
shell: pwsh
run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}"
env:
CI : True
XUNIT_PATH: .\tests\SixLabors.Fonts.Tests # Required for xunit
- name: Update Codecov
uses: iansu/codecov-action-node@v1.0.0
if: matrix.options.codecov == true
with:
token: ${{secrets.CODECOV_TOKEN}}
file: "coverage.${{matrix.options.framework}}.xml"
flags: unittests
- name: Pack # We can use this filter as we know it happens only once and takes the most time to complete.
if: (github.event_name == 'push') && (matrix.options.codecov == true)
shell: pwsh
run: ./ci-build.ps1 "${{steps.gitversion.outputs.nuGetVersion}}"
- name: Publish to MyGet
if: (github.event_name == 'push') && (matrix.options.codecov == true)
shell: pwsh
run: nuget.exe push .\artifacts\*.nupkg ${{secrets.MYGET_TOKEN}} -Source https://www.myget.org/F/sixlabors/api/v2/package
# TODO: If github.ref starts with 'refs/tags' then it was tag push and we can optionally push out package to nuget.org

112
Directory.Build.props Normal file
Просмотреть файл

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.props is automatically picked up and imported by
Microsoft.Common.props. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly early and only Sdk.props will have been imported
beforehand. We also don't need to add ourselves to MSBuildAllProjects, as
that is done by the file that imports us.
-->
<!-- Default settings that are used by other settings -->
<PropertyGroup>
<BaseArtifactsPath>$(MSBuildThisFileDirectory)artifacts/</BaseArtifactsPath>
<BaseArtifactsPathSuffix>$(ImageSharpProjectCategory)/$(MSBuildProjectName)</BaseArtifactsPathSuffix>
<RepositoryUrl Condition="'$(RepositoryUrl)' == ''">https://github.com/SixLabors/Fonts/</RepositoryUrl>
</PropertyGroup>
<!-- Default settings that explicitly differ from the Sdk.props defaults -->
<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<BaseIntermediateOutputPath>$(BaseArtifactsPath)obj/$(BaseArtifactsPathSuffix)/</BaseIntermediateOutputPath>
<DebugType>portable</DebugType>
<DebugType Condition="'$(codecov)' != ''">full</DebugType>
<NullableContextOptions>disable</NullableContextOptions>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<SignAssembly>false</SignAssembly>
<SuppressNETCoreSdkPreviewMessage>true</SuppressNETCoreSdkPreviewMessage>
</PropertyGroup>
<!--
https://apisof.net/
+===================+=======+==========+=====================+=============+=================+====================+==============+
| SUPPORTS | MATHF | HASHCODE | EXTENDED_INTRINSICS | SPAN_STREAM | ENCODING_STRING | RUNTIME_INTRINSICS | CODECOVERAGE |
+===================+=======+==========+=====================+=============+=================+====================+==============+
| netcoreapp3.1 | Y | Y | Y | Y | Y | Y | Y |
| netcoreapp2.1 | Y | Y | Y | Y | Y | N | Y |
| netcoreapp2.0 | Y | N | N | N | N | N | Y |
| netstandard2.1 | Y | Y | N | Y | Y | N | Y |
| netstandard2.0 | N | N | N | N | N | N | Y |
| netstandard1.3 | N | N | N | N | N | N | N |
| net472 | N | N | Y | N | N | N | Y |
+===================+=======+==========+=====================+=============+=================+====================+==============+
-->
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp3.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING;SUPPORTS_RUNTIME_INTRINSICS;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.1'">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF;SUPPORTS_HASHCODE;SUPPORTS_SPAN_STREAM;SUPPORTS_ENCODING_STRING;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<DefineConstants>$(DefineConstants);SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net472'">
<DefineConstants>$(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS;SUPPORTS_CODECOVERAGE</DefineConstants>
</PropertyGroup>
<!-- Default settings that explicitly differ from the Sdk.targets defaults-->
<PropertyGroup>
<Authors>Six Labors and contributors</Authors>
<BaseOutputPath>$(BaseArtifactsPath)bin/$(BaseArtifactsPathSuffix)/</BaseOutputPath>
<Company>Six Labors</Company>
<PackageOutputPath>$(BaseArtifactsPath)pkg/$(BaseArtifactsPathSuffix)/$(Configuration)/</PackageOutputPath>
<Product>SixLabors.Fonts</Product>
<VersionPrefix>0.0.1</VersionPrefix>
<VersionPrefix Condition="'$(packageversion)' != ''">$(PackageVersion)</VersionPrefix>
<VersionSuffix></VersionSuffix>
</PropertyGroup>
<!-- Default settings that are otherwise undefined -->
<PropertyGroup>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)shared-infrastructure/SixLabors.snk</AssemblyOriginatorKeyFile>
<Copyright>Copyright © Six Labors and Contributors</Copyright>
<Features>strict;IOperation</Features>
<HighEntropyVA>true</HighEntropyVA>
<LangVersion>8.0</LangVersion>
<NeutralLanguage>en</NeutralLanguage>
<OverwriteReadOnlyFiles>true</OverwriteReadOnlyFiles>
<PackageIcon>icon.png</PackageIcon>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>$(RepositoryUrl)</PackageProjectUrl>
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
<RepositoryType>git</RepositoryType>
<RestoreSources>
https://www.myget.org/F/sixlabors/api/v3/index.json;
https://dotnetfeed.blob.core.windows.net/dotnet-core/index.json;
https://api.nuget.org/v3/index.json;
</RestoreSources>
<SixLaborsPublicKey>002400000c8000009400000006020000002400005253413100040000010001000147e6fe6766715eec6cfed61f1e7dcdbf69748a3e355c67e9d8dfd953acab1d5e012ba34b23308166fdc61ee1d0390d5f36d814a6091dd4b5ed9eda5a26afced924c683b4bfb4b3d64b0586a57eff9f02b1f84e3cb0ddd518bd1697f2c84dcbb97eb8bb5c7801be12112ed0ec86db934b0e9a5171e6bb1384b6d2f7d54dfa97</SixLaborsPublicKey>
<UseSharedCompilation>true</UseSharedCompilation>
</PropertyGroup>
<!-- Package references and additional files which are consumed by all projects -->
<ItemGroup>
<PackageReference Include="Microsoft.Net.Compilers.Toolset" IsImplicitlyDefined="true" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" IsImplicitlyDefined="true" />
<!--TODO: Enable this once tests Stylecop issues are fixed-->
<!--<PackageReference Include="StyleCop.Analyzers" IsImplicitlyDefined="true" />-->
<AdditionalFiles Include="$(MSBuildThisFileDirectory)shared-infrastructure\stylecop.json" Visible="false" />
<!--NuGet package icon source-->
<None Include="$(MSBuildThisFileDirectory)shared-infrastructure\branding\icons\fonts\sixlabors.fonts.128.png" Pack="true" PackagePath="\icon.png" Visible="false" />
</ItemGroup>
</Project>

37
Directory.Build.targets Normal file
Просмотреть файл

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly late and most other props/targets will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<!-- Settings that append the existing setting value -->
<PropertyGroup>
<DefineConstants>$(DefineConstants);$(OS)</DefineConstants>
</PropertyGroup>
<!-- Package versions for package references across all projects -->
<ItemGroup>
<!--Global Dependencies-->
<PackageReference Update="Microsoft.Net.Compilers.Toolset" Version="3.3.1" />
<PackageReference Update="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" Version="1.0.0" />
<PackageReference Update="StyleCop.Analyzers" PrivateAssets="All" Version="1.1.118" />
<!--Src Dependencies-->
<PackageReference Update="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Update="System.IO.Compression" Version="4.3.0" />
<PackageReference Update="System.IO.UnmanagedMemoryStream" Version="4.3.0" />
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="4.5.1" />
<PackageReference Update="System.Threading.Tasks.Parallel" Version="4.3.0" />
<PackageReference Update="System.ValueTuple" Version="4.5.0" />
<PackageReference Update="System.Buffers" Version="4.4.0" />
<PackageReference Update="System.Memory" Version="4.5.1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,24 +1,27 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.15
# Visual Studio Version 16
VisualStudioVersion = 16.0.29512.175
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{C317F1B1-D75E-4C6D-83EB-80367343E0D7}"
ProjectSection(SolutionItems) = preProject
standards\.editorconfig = standards\.editorconfig
.github\workflows\build-and-test.yml = .github\workflows\build-and-test.yml
Directory.Build.props = Directory.Build.props
Directory.Build.targets = Directory.Build.targets
NuGet.config = NuGet.config
README.md = README.md
standards\SixLabors.ruleset = standards\SixLabors.ruleset
standards\stylecop.json = standards\stylecop.json
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{815C0625-CD3D-440F-9F80-2D83856AB7AE}"
ProjectSection(SolutionItems) = preProject
src\Directory.Build.props = src\Directory.Build.props
src\Directory.Build.targets = src\Directory.Build.targets
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{56801022-D71A-4FBE-BC5B-CBA08E2284EC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{9E574A07-F879-4811-9C41-5CBDC6BAFDB7}"
ProjectSection(SolutionItems) = preProject
src\Shared\AssemblyInfo.Common.cs = src\Shared\AssemblyInfo.Common.cs
stylecop.json = stylecop.json
tests\Directory.Build.props = tests\Directory.Build.props
tests\Directory.Build.targets = tests\Directory.Build.targets
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SixLabors.Fonts", "src\SixLabors.Fonts\SixLabors.Fonts.csproj", "{09E744EC-4852-4FC7-BE78-C1B399F17967}"

Просмотреть файл

@ -1,29 +0,0 @@
version: 0.0.{build}
image: Visual Studio 2017
before_build:
- git submodule -q update --init
- cmd: dotnet --version
build_script:
- cmd: build.cmd
- cmd: tests\CodeCoverage\CodeCoverage.cmd
after_build:
- cmd: appveyor PushArtifact "artifacts\SixLabors.Fonts.%APPVEYOR_BUILD_VERSION%.nupkg"
deploy:
- provider: NuGet
server: https://www.myget.org/F/sixlabors/api/v2/package
symbol_server: https://www.myget.org/F/sixlabors/symbols/api/v2/package
api_key:
secure: V/lEHP0UeMWIpWd0fiNlY2IgbCnJKQlGdRksECdJbOBdaE20Fl0RNL7WyqHe02o4
artifact: /.*\.nupkg/
on:
branch: master
# prevent the double build when a branch has an active PR
skip_branch_with_pr: true
test: off

Просмотреть файл

@ -1,17 +0,0 @@
@echo Off
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& '.\build.ps1'"
if not "%errorlevel%"=="0" goto failure
:success
ECHO successfully built project
REM exit 0
goto end
:failure
ECHO failed to build.
REM exit -1
goto end
:end

110
build.ps1
Просмотреть файл

@ -1,110 +0,0 @@
# lets calulat the correct version here
$fallbackVersion = "1.0.0";
$version = ''
$tagRegex = '^v?(\d+\.\d+\.\d+)(-([a-zA-Z]+)\.?(\d*))?$'
# we are running on the build server
$isVersionTag = $env:APPVEYOR_REPO_TAG_NAME -match $tagRegex
if($isVersionTag){
Write-Debug "Building commit tagged with a compatable version number"
$version = $matches[1]
$postTag = $matches[3]
$count = $matches[4]
Write-Debug "version number: ${version} post tag: ${postTag} count: ${count}"
if("$postTag" -ne ""){
$version = "${version}-${postTag}"
}
if("$count" -ne ""){
# for consistancy with previous releases we pad the counter to only 4 places
$padded = $count.Trim().Trim('0').PadLeft(4,"0");
Write-Debug "count '$count', padded '${padded}'"
$version = "${version}${padded}"
}
}else {
Write-Debug "Untagged"
$lastTag = (git tag --list --sort=-taggerdate) | Out-String
$list = $lastTag.Split("`n")
foreach ($tag in $list) {
Write-Debug "testing ${tag}"
$tag = $tag.Trim();
if($tag -match $tagRegex){
Write-Debug "matched ${tag}"
$version = $matches[1];
break;
}
}
if("$version" -eq ""){
$version = $fallbackVersion
Write-Debug "Failed to discover base version Fallback to '${version}'"
}else{
Write-Debug "Discovered base version from tags '${version}'"
}
$buildNumber = $env:APPVEYOR_BUILD_NUMBER
# build number replacement is padded to 6 places
$buildNumber = "$buildNumber".Trim().Trim('0').PadLeft(6,"0");
if("$env:APPVEYOR_PULL_REQUEST_NUMBER" -ne ""){
Write-Debug "building a PR"
$prNumber = "$env:APPVEYOR_PULL_REQUEST_NUMBER".Trim().Trim('0').PadLeft(5,"0");
# this is a PR
$version = "${version}-PullRequest${prNumber}${buildNumber}";
}else{
Write-Debug "building a branch commit"
# this is a general branch commit
$branch = $env:APPVEYOR_REPO_BRANCH
if("$branch" -eq ""){
$branch = ((git rev-parse --abbrev-ref HEAD) | Out-String).Trim()
if("$branch" -eq ""){
$branch = "unknown"
}
}
$branch = $branch.Replace("/","-").ToLower()
if($branch.ToLower() -eq "master"){
$branch = "dev"
}
$version = "${version}-${branch}${buildNumber}";
}
}
if("$env:APPVEYOR_API_URL" -ne ""){
# update appveyor build number for this build
Invoke-RestMethod -Method "PUT" `
-Uri "${env:APPVEYOR_API_URL}api/build" `
-Body "{version:'${version}'}" `
-ContentType "application/json"
}
Write-Host "Building version '${version}'"
dotnet restore /p:packageversion=$version
Write-Host "Building projects"
dotnet build -c Release /p:packageversion=$version
if ($LASTEXITCODE ){ Exit $LASTEXITCODE }
if ( $env:CI -ne "True") {
dotnet test ./tests/SixLabors.Fonts.Tests/SixLabors.Fonts.Tests.csproj --no-build -c Release
}
if ($LASTEXITCODE ){ Exit $LASTEXITCODE }
Write-Host "Packaging projects"
dotnet pack ./src/SixLabors.Fonts/ -c Release --output ../../artifacts --no-build /p:packageversion=$version
if ($LASTEXITCODE ){ Exit $LASTEXITCODE }

20
ci-build.ps1 Normal file
Просмотреть файл

@ -0,0 +1,20 @@
param(
[Parameter(Mandatory, Position = 0)]
[string]$version,
[Parameter(Mandatory = $false, Position = 1)]
[string]$targetFramework = 'ALL'
)
dotnet clean -c Release
$repositoryUrl = "https://github.com/$env:GITHUB_REPOSITORY"
if ($targetFramework -ne 'ALL') {
# Building for a specific framework.
dotnet build -c Release -f $targetFramework /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl
}
else {
# Building for packing and publishing.
dotnet pack -c Release --output "$PSScriptRoot/artifacts" /p:packageversion=$version /p:RepositoryUrl=$repositoryUrl
}

41
ci-test.ps1 Normal file
Просмотреть файл

@ -0,0 +1,41 @@
param(
[Parameter(Mandatory, Position = 0)]
[string]$os,
[Parameter(Mandatory, Position = 1)]
[string]$targetFramework,
[Parameter(Mandatory, Position = 2)]
[string]$platform,
[Parameter(Mandatory, Position = 3)]
[string]$codecov,
[Parameter(Position = 4)]
[string]$codecovProfile = 'Release'
)
$netFxRegex = '^net\d+'
if ($codecov -eq 'true') {
# Allow toggling of profile to workaround any potential JIT errors caused by code injection.
dotnet clean -c $codecovProfile
dotnet test -c $codecovProfile -f $targetFramework /p:codecov=true
}
elseif ($platform -eq '-x86' -and $targetFramework -match $netFxRegex) {
# xunit doesn't run on core with NET SDK 3.1+.
# xunit doesn't actually understand -x64 as an option.
#
# xunit requires explicit path.
Set-Location $env:XUNIT_PATH
dotnet xunit --no-build -c Release -f $targetFramework ${fxVersion} $platform
Set-Location $PSScriptRoot
}
else {
dotnet test --no-build -c Release -f $targetFramework
}
# Explicitly exit with 0 to ignore errors caused by coverlet attempting to read
# project files that dotnet test is set to ignore.
exit 0

Просмотреть файл

@ -1,31 +1,6 @@
# to create a new package you create a new release/tag
# in github appveyor will build it without the -cixxx tag
# it will then be deployable cleanly to nuget.org
branches:
master:
tag: ci
mode: ContinuousDeployment
increment: Minor
prevent-increment-of-merged-branch-version: false
track-merge-target: true
pull-request:
regex: (pull|pull\-requests|pr)[/-]
mode: ContinuousDelivery
tag: PullRequest
increment: Inherit
prevent-increment-of-merged-branch-version: false
tag-number-pattern: '[/-](?<number>\d+)[-/]'
track-merge-target: false
tracks-release-branches: false
is-release-branch: false
otherbranches:
regex: '.*'
mode: ContinuousDeployment
tag: ci
increment: Patch
prevent-increment-of-merged-branch-version: false
track-merge-target: true
is-release-branch: false
ignore:
sha: []
continuous-delivery-fallback-tag: ci
branches:
master:
tag: unstable
pull-request:
tag: pr

Просмотреть файл

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.props is automatically picked up and imported by
Microsoft.Common.props. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly early and only Sdk.props will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props</MSBuildAllProjects>
<ImageSharpProjectCategory>samples</ImageSharpProjectCategory>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.Tests.ruleset</CodeAnalysisRuleSet>
<!--TODO: We should remove all obsolete code from the solution-->
<NoWarn>$(NoWarn);CS0618</NoWarn>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
</Project>

Просмотреть файл

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly late and most other props/targets will have
been imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.targets</MSBuildAllProjects>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.targets" />
<!-- Tool versions for tool references across all projects -->
<ItemGroup>
<!--dotnet tools does not have an x86 runner. You have to use separate SDKs-->
<!--https://github.com/actions/setup-dotnet/issues/72-->
<DotNetCliToolReference Update="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
<!--Code coverage specific settings-->
<!--https://github.com/tonerdo/coverlet-->
<PropertyGroup Condition="'$(codecov)' == 'true'">
<CollectCoverage>true</CollectCoverage>
<UseSourceLink>true</UseSourceLink>
<CoverletOutputFormat>opencover</CoverletOutputFormat>
<!--Output injects target framework into name despite explicit config. See build yml-->
<CoverletOutput>$(MSBuildThisFileDirectory)..\coverage.xml</CoverletOutput>
<!--Used by coverlet dues to reference issues with SixLabors.Core-->
<!--https://github.com/tonerdo/coverlet/blob/master/Documentation/KnowIssues.md#4-failed-to-resolve-assembly-during-instrumentation-->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<!--Test Dependencies-->
<PackageReference Update="BenchmarkDotNet" Version="0.12.0" />
<PackageReference Update="coverlet.collector" Version="1.1.0" PrivateAssets="All"/>
<PackageReference Update="coverlet.msbuild" Version="2.8.0" PrivateAssets="All"/>
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Update="Moq" Version="4.10.0" />
<!--TODO: Fix implicit conversion issues so we can move to 2.4.1-->
<PackageReference Update="xunit" Version="2.3.1" />
<PackageReference Update="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -11,7 +11,7 @@ namespace DrawWithImageSharp
{
public static void Generate(string text, Font font)
{
using (Image<Rgba32> img = new Image<Rgba32>(1000, 1000))
using (var img = new Image<Rgba32>(1000, 1000))
{
img.Mutate(x=>x.Fill(Rgba32.White));

Просмотреть файл

@ -18,7 +18,7 @@ namespace SixLabors.Fonts.DrawWithImageSharp
{
public static void Main(string[] args)
{
FontCollection fonts = new FontCollection();
var fonts = new FontCollection();
FontFamily font = fonts.Install(@"..\..\tests\SixLabors.Fonts.Tests\Fonts\SixLaborsSampleAB.ttf");
FontFamily fontWoff = fonts.Install(@"..\..\tests\SixLabors.Fonts.Tests\Fonts\SixLaborsSampleAB.woff");
FontFamily font2 = fonts.Install(@"..\..\tests\SixLabors.Fonts.Tests\Fonts\OpenSans-Regular.ttf");
@ -66,7 +66,7 @@ namespace SixLabors.Fonts.DrawWithImageSharp
TextAlignment.Generate(SystemFonts.CreateFont("arial", 50f));
TextAlignmentWrapped.Generate(SystemFonts.CreateFont("arial", 50f));
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
for (char c = 'a'; c <= 'z'; c++)
{
sb.Append(c);
@ -93,7 +93,7 @@ namespace SixLabors.Fonts.DrawWithImageSharp
string path = System.IO.Path.GetInvalidFileNameChars().Aggregate(text, (x, c) => x.Replace($"{c}", "-"));
string fullPath = System.IO.Path.GetFullPath(System.IO.Path.Combine("Output", System.IO.Path.Combine(path)));
using (Image<Rgba32> img = new Image<Rgba32>(width, height))
using (var img = new Image<Rgba32>(width, height))
{
img.Mutate(x=>x.Fill(Rgba32.White));
@ -111,9 +111,9 @@ namespace SixLabors.Fonts.DrawWithImageSharp
public static void RenderText(RendererOptions font, string text)
{
GlyphBuilder builder = new GlyphBuilder();
TextRenderer renderer = new TextRenderer(builder);
var size = TextMeasurer.Measure(text, font);
var builder = new GlyphBuilder();
var renderer = new TextRenderer(builder);
FontRectangle size = TextMeasurer.Measure(text, font);
renderer.RenderText(text, font);
builder.Paths
@ -129,7 +129,7 @@ namespace SixLabors.Fonts.DrawWithImageSharp
path = path.Select(p => System.IO.Path.GetInvalidFileNameChars().Aggregate(p, (x, c) => x.Replace($"{c}", "-"))).ToArray();
string fullPath = System.IO.Path.GetFullPath(System.IO.Path.Combine("Output", System.IO.Path.Combine(path)));
using (Image<Rgba32> img = new Image<Rgba32>(width, height))
using (var img = new Image<Rgba32>(width, height))
{
img.Mutate(x => x.Fill(Rgba32.DarkBlue));
@ -156,7 +156,7 @@ namespace SixLabors.Fonts.DrawWithImageSharp
shape = shape.Translate(shape.Bounds.Location * -1) // touch top left
.Translate(new Vector2(10)); // move in from top left
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
IEnumerable<ISimplePath> converted = shape.Flatten();
converted.Aggregate(sb, (s, p) =>
{
@ -186,7 +186,7 @@ namespace SixLabors.Fonts.DrawWithImageSharp
{
height = 1;
}
using (Image<Rgba32> img = new Image<Rgba32>(width, height))
using (var img = new Image<Rgba32>(width, height))
{
img.Mutate(x => x.Fill(Rgba32.DarkBlue));

Просмотреть файл

@ -14,7 +14,7 @@ namespace DrawWithImageSharp
public static void Generate(Font font)
{
using (Image<Rgba32> img = new Image<Rgba32>(1000, 1000))
using (var img = new Image<Rgba32>(1000, 1000))
{
img.Mutate(x => x.Fill(Rgba32.White));
@ -63,11 +63,11 @@ namespace DrawWithImageSharp
break;
}
GlyphBuilder glyphBuilder = new GlyphBuilder();
var glyphBuilder = new GlyphBuilder();
TextRenderer renderer = new TextRenderer(glyphBuilder);
var renderer = new TextRenderer(glyphBuilder);
RendererOptions style = new RendererOptions(font, 72, location)
var style = new RendererOptions(font, 72, location)
{
ApplyKerning = true,
TabWidth = 4,

Просмотреть файл

@ -16,7 +16,7 @@ namespace DrawWithImageSharp
{
int wrappingWidth = 400;
int size = (wrappingWidth + wrappingWidth/3) * 3;
using (Image<Rgba32> img = new Image<Rgba32>(size, size))
using (var img = new Image<Rgba32>(size, size))
{
img.Mutate(x => x.Fill(Rgba32.White));
@ -64,11 +64,11 @@ namespace DrawWithImageSharp
break;
}
GlyphBuilder glyphBuilder = new GlyphBuilder();
var glyphBuilder = new GlyphBuilder();
TextRenderer renderer = new TextRenderer(glyphBuilder);
var renderer = new TextRenderer(glyphBuilder);
RendererOptions style = new RendererOptions(font, 72, location)
var style = new RendererOptions(font, 72, location)
{
ApplyKerning = true,
TabWidth = 4,

Просмотреть файл

@ -18,9 +18,9 @@ namespace SixLabors.Shapes.Temp
/// <returns></returns>
public static (IPathCollection paths, IPathCollection boxes, IPath textBox) GenerateGlyphsWithBox(string text, Vector2 location, RendererOptions style)
{
GlyphBuilder glyphBuilder = new GlyphBuilder(location);
var glyphBuilder = new GlyphBuilder(location);
TextRenderer renderer = new TextRenderer(glyphBuilder);
var renderer = new TextRenderer(glyphBuilder);
renderer.RenderText(text, style);
@ -70,9 +70,9 @@ namespace SixLabors.Shapes.Temp
/// <returns></returns>
public static IPathCollection GenerateGlyphs(string text, IPath path, RendererOptions style)
{
PathGlyphBuilder glyphBuilder = new PathGlyphBuilder(path);
var glyphBuilder = new PathGlyphBuilder(path);
TextRenderer renderer = new TextRenderer(glyphBuilder);
var renderer = new TextRenderer(glyphBuilder);
renderer.RenderText(text, style);

Просмотреть файл

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
@ -9,4 +9,4 @@
<ProjectReference Include="..\..\src\SixLabors.Fonts\SixLabors.Fonts.csproj" />
</ItemGroup>
</Project>
</Project>

@ -1 +1 @@
Subproject commit faf84e44ec90e8a42a7271bcd04fea76279efb08
Subproject commit 7730e662d25d78566aed7a6e2b78a16592feee7c

38
src/Directory.Build.props Normal file
Просмотреть файл

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.props is automatically picked up and imported by
Microsoft.Common.props. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly early and only Sdk.props will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props</MSBuildAllProjects>
<ImageSharpProjectCategory>src</ImageSharpProjectCategory>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.ruleset</CodeAnalysisRuleSet>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<ItemGroup>
<!--TODO: Delete this once tests Stylecop issues are fixed-->
<PackageReference Include="StyleCop.Analyzers" IsImplicitlyDefined="true" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" PublicKey="0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2, PublicKeyToken=null" />
<InternalsVisibleTo Include="SixLabors.Fonts.Tests" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly late and most other props/targets will have
been imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.targets</MSBuildAllProjects>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.targets" />
<PropertyGroup>
<GeneratedInternalsVisibleToFile Condition="'$(GeneratedInternalsVisibleToFile)' == ''">$(IntermediateOutputPath)$(MSBuildProjectName).InternalsVisibleTo$(DefaultLanguageSourceExtension)</GeneratedInternalsVisibleToFile>
</PropertyGroup>
<ItemDefinitionGroup>
<InternalsVisibleTo>
<Visible>false</Visible>
</InternalsVisibleTo>
</ItemDefinitionGroup>
<Target Name="GenerateInternalsVisibleTo"
BeforeTargets="CoreCompile"
DependsOnTargets="PrepareForBuild;CoreGenerateInternalsVisibleTo"
Condition="'@(InternalsVisibleTo)' != ''" />
<Target Name="CoreGenerateInternalsVisibleTo"
Condition="'$(Language)' == 'VB' or '$(Language)' == 'C#'"
Inputs="$(MSBuildAllProjects)"
Outputs="$(GeneratedInternalsVisibleToFile)">
<CreateItem Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute" AdditionalMetadata="_Parameter1=%(InternalsVisibleTo.Identity)" Condition="'%(InternalsVisibleTo.PublicKey)' == ''">
<Output TaskParameter="Include" ItemName="InternalsVisibleToAttribute" />
</CreateItem>
<CreateItem Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute" AdditionalMetadata="_Parameter1=%(InternalsVisibleTo.Identity), PublicKey=%(InternalsVisibleTo.PublicKey)" Condition="'%(InternalsVisibleTo.PublicKey)' != ''">
<Output TaskParameter="Include" ItemName="InternalsVisibleToAttribute" />
</CreateItem>
<WriteCodeFragment AssemblyAttributes="@(InternalsVisibleToAttribute)" Language="$(Language)" OutputFile="$(GeneratedInternalsVisibleToFile)">
<Output TaskParameter="OutputFile" ItemName="Compile" />
<Output TaskParameter="OutputFile" ItemName="FileWrites" />
</WriteCodeFragment>
</Target>
<!-- Empty target so that `dotnet test` will work on the solution -->
<!-- https://github.com/Microsoft/vstest/issues/411 -->
<Target Name="VSTest" />
</Project>

Просмотреть файл

@ -1,33 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyDescription("A cross-platform library for loading and laying out for processing and measuring; written in C#")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Six Labors")]
[assembly: AssemblyProduct("SixLabors.Fonts")]
[assembly: AssemblyCopyright("Copyright (c) Six Labors and contributors.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
// Version information for an assembly consists of the following four values:
// Major Version
// Minor Version
// Build Number
// Revision
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
// Ensure the internals can be tested.
[assembly: InternalsVisibleTo("SixLabors.Fonts.Tests")]

Просмотреть файл

@ -259,7 +259,7 @@ namespace SixLabors.Fonts
public TEnum[] ReadUInt8Array<TEnum>(int length)
where TEnum : Enum
{
TEnum[] data = new TEnum[length];
var data = new TEnum[length];
for (int i = 0; i < length; i++)
{
data[i] = CastTo<TEnum>.From(this.ReadUInt8());
@ -408,7 +408,7 @@ namespace SixLabors.Fonts
/// </returns>
public string ReadString(int bytesToRead, Encoding encoding)
{
var data = new byte[bytesToRead];
byte[] data = new byte[bytesToRead];
this.ReadInternal(data, bytesToRead);
return encoding.GetString(data, 0, data.Length);
}

Просмотреть файл

@ -0,0 +1,28 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.Fonts.Exceptions
{
/// <summary>
/// Exception font loading can throw if it finds a required table is missing during font loading.
/// </summary>
/// <seealso cref="System.Exception" />
public class MissingFontTableException : InvalidFontFileException
{
/// <summary>
/// Initializes a new instance of the <see cref="MissingFontTableException"/> class.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="table">The table.</param>
public MissingFontTableException(string message, string table)
: base(message)
{
this.Table = table;
}
/// <summary>
/// Gets the table where the error originated.
/// </summary>
public string Table { get; }
}
}

Просмотреть файл

@ -1,7 +1,8 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using SixLabors.Fonts.Exceptions;
namespace SixLabors.Fonts
{
@ -11,7 +12,7 @@ namespace SixLabors.Fonts
public sealed class Font
{
private readonly FontStyle requestedStyle;
private readonly Lazy<IFontInstance> instance;
private readonly Lazy<IFontInstance?> instance;
/// <summary>
/// Initializes a new instance of the <see cref="Font"/> class.
@ -24,7 +25,7 @@ namespace SixLabors.Fonts
this.Family = family ?? throw new ArgumentNullException(nameof(family));
this.requestedStyle = style;
this.Size = size;
this.instance = new Lazy<IFontInstance>(this.LoadInstanceInternal);
this.instance = new Lazy<IFontInstance?>(this.LoadInstanceInternal);
}
/// <summary>
@ -82,7 +83,7 @@ namespace SixLabors.Fonts
/// <value>
/// The name.
/// </value>
public string Name => this.instance.Value.Description.FontName;
public string Name => this.Instance.Description.FontName;
/// <summary>
/// Gets the size.
@ -98,7 +99,7 @@ namespace SixLabors.Fonts
/// <value>
/// <c>true</c> if bold; otherwise, <c>false</c>.
/// </value>
public bool Bold => (this.instance.Value.Description.Style & FontStyle.Bold) == FontStyle.Bold;
public bool Bold => (this.Instance.Description.Style & FontStyle.Bold) == FontStyle.Bold;
/// <summary>
/// Gets a value indicating whether this <see cref="Font"/> is italic.
@ -106,7 +107,7 @@ namespace SixLabors.Fonts
/// <value>
/// <c>true</c> if italic; otherwise, <c>false</c>.
/// </value>
public bool Italic => (this.instance.Value.Description.Style & FontStyle.Italic) == FontStyle.Italic;
public bool Italic => (this.Instance.Description.Style & FontStyle.Italic) == FontStyle.Italic;
/// <summary>
/// Gets the size of the em.
@ -114,27 +115,27 @@ namespace SixLabors.Fonts
/// <value>
/// The size of the em.
/// </value>
public ushort EmSize => this.instance.Value.EmSize;
public ushort EmSize => this.Instance.EmSize;
/// <summary>
/// Gets the ascender (from the OS/2 table field <c>TypoAscender</c>).
/// </summary>
public short Ascender => this.instance.Value.Ascender;
public short Ascender => this.Instance.Ascender;
/// <summary>
/// Gets the descender (from the OS/2 table field <c>TypoDescender</c>).
/// </summary>
public short Descender => this.instance.Value.Descender;
public short Descender => this.Instance.Descender;
/// <summary>
/// Gets the line gap (from the OS/2 table field <c>TypoLineGap</c>).
/// </summary>
public short LineGap => this.instance.Value.LineGap;
public short LineGap => this.Instance.LineGap;
/// <summary>
/// Gets the line height.
/// </summary>
public int LineHeight => this.instance.Value.LineHeight;
public int LineHeight => this.Instance.LineHeight;
/// <summary>
/// Gets the font instance.
@ -142,7 +143,7 @@ namespace SixLabors.Fonts
/// <value>
/// The font instance.
/// </value>
public IFontInstance Instance => this.instance.Value;
public IFontInstance Instance => this.instance.Value ?? throw new FontException("Font instance not found");
/// <summary>
/// Gets the glyph.
@ -151,12 +152,12 @@ namespace SixLabors.Fonts
/// <returns>Returns the glyph</returns>
public Glyph GetGlyph(int codePoint)
{
return new Glyph(this.instance.Value.GetGlyph(codePoint), this.Size);
return new Glyph(this.Instance.GetGlyph(codePoint), this.Size);
}
private IFontInstance LoadInstanceInternal()
private IFontInstance? LoadInstanceInternal()
{
IFontInstance instance = this.Family.Find(this.requestedStyle);
IFontInstance? instance = this.Family.Find(this.requestedStyle);
if (instance is null && this.requestedStyle.HasFlag(FontStyle.Italic))
{

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -73,7 +73,7 @@ namespace SixLabors.Fonts
/// <returns>the description of the font just loaded.</returns>
public FontFamily Install(Stream fontStream, out FontDescription fontDescription)
{
FontInstance instance = FontInstance.LoadFont(fontStream);
var instance = FontInstance.LoadFont(fontStream);
fontDescription = instance.Description;
return this.Install(instance);
@ -140,7 +140,7 @@ namespace SixLabors.Fonts
return this.families[instance.Description.FontFamily];
}
internal IFontInstance Find(string fontFamily, FontStyle style)
internal IFontInstance? Find(string fontFamily, FontStyle style)
{
return this.instances.TryGetValue(fontFamily, out List<IFontInstance> inFamily)
? inFamily.FirstOrDefault(x => x.Description.Style == style)

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -41,6 +41,13 @@ namespace SixLabors.Fonts
/// </value>
public IEnumerable<FontStyle> AvailableStyles => this.collection.AvailableStyles(this.Name);
internal FontStyle DefaultStyle => this.IsStyleAvailable(FontStyle.Regular) ? FontStyle.Regular : this.AvailableStyles.First();
internal IFontInstance? Find(FontStyle style)
{
return this.collection.Find(this.Name, style);
}
/// <summary>
/// Determines whether the specified <see cref="FontStyle"/> is available.
/// </summary>
@ -50,13 +57,6 @@ namespace SixLabors.Fonts
/// </returns>
public bool IsStyleAvailable(FontStyle style) => this.AvailableStyles.Contains(style);
internal FontStyle DefaultStyle => this.IsStyleAvailable(FontStyle.Regular) ? FontStyle.Regular : this.AvailableStyles.First();
internal IFontInstance Find(FontStyle style)
{
return this.collection.Find(this.Name, style);
}
/// <summary>
/// Returns a <see cref="string" /> that represents this instance.
/// </summary>

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -22,29 +22,6 @@ namespace SixLabors.Fonts
private readonly GlyphInstance[] glyphCache;
private readonly KerningTable kerning;
/// <summary>
/// Gets the height of the line.
/// </summary>
/// <value>
/// The height of the line.
/// </value>
public int LineHeight { get; }
/// <summary>
/// Gets the ascender.
/// </summary>
public short Ascender { get; }
/// <summary>
/// Gets the descender.
/// </summary>
public short Descender { get; }
/// <summary>
/// Gets the line gap.
/// </summary>
public short LineGap { get; }
/// <summary>
/// Initializes a new instance of the <see cref="FontInstance"/> class.
/// </summary>
@ -74,6 +51,29 @@ namespace SixLabors.Fonts
this.Description = new FontDescription(nameTable, os2, head);
}
/// <summary>
/// Gets the height of the line.
/// </summary>
/// <value>
/// The height of the line.
/// </value>
public int LineHeight { get; }
/// <summary>
/// Gets the ascender.
/// </summary>
public short Ascender { get; }
/// <summary>
/// Gets the descender.
/// </summary>
public short Descender { get; }
/// <summary>
/// Gets the line gap.
/// </summary>
public short LineGap { get; }
/// <summary>
/// Gets the size of the em.
/// </summary>
@ -82,6 +82,7 @@ namespace SixLabors.Fonts
/// </value>
public ushort EmSize { get; }
/// <inheritdoc/>
public FontDescription Description { get; }
internal ushort GetGlyphIndex(int codePoint)
@ -152,7 +153,7 @@ namespace SixLabors.Fonts
/// <returns>a <see cref="FontInstance"/>.</returns>
public static FontInstance LoadFont(Stream stream)
{
FontReader reader = new FontReader(stream);
var reader = new FontReader(stream);
return LoadFont(reader);
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -13,7 +13,6 @@ namespace SixLabors.Fonts
internal sealed class FontReader
{
private readonly Dictionary<Type, Table> loadedTables = new Dictionary<Type, Table>();
private readonly Stream stream;
private readonly TableLoader loader;
@ -94,6 +93,12 @@ namespace SixLabors.Fonts
{
}
internal enum OutlineTypes : uint
{
TrueType = 0x00010000,
CFF = 0x4F54544F
}
public IReadOnlyDictionary<string, TableHeader> Headers { get; }
public bool CompressedTableData { get; }
@ -109,15 +114,21 @@ namespace SixLabors.Fonts
}
else
{
table = this.loader.Load<TTableType>(this);
TTableType? loadedTable = this.loader.Load<TTableType>(this);
if (loadedTable is null)
{
string tag = this.loader.GetTag<TTableType>();
throw new MissingFontTableException($"Table '{tag}' is missing", tag);
}
this.loadedTables.Add(typeof(TTableType), table);
table = loadedTable;
this.loadedTables.Add(typeof(TTableType), loadedTable);
}
return (TTableType)table;
}
public TableHeader GetHeader(string tag)
public TableHeader? GetHeader(string tag)
{
return this.Headers.TryGetValue(tag, out TableHeader header)
? header
@ -126,7 +137,7 @@ namespace SixLabors.Fonts
public BinaryReader GetReaderAtTablePosition(string tableName)
{
var reader = this.TryGetReaderAtTablePosition(tableName);
BinaryReader? reader = this.TryGetReaderAtTablePosition(tableName);
if (reader == null)
{
throw new InvalidFontTableException("Unable to find table", tableName);
@ -135,16 +146,10 @@ namespace SixLabors.Fonts
return reader;
}
public BinaryReader TryGetReaderAtTablePosition(string tableName)
public BinaryReader? TryGetReaderAtTablePosition(string tableName)
{
TableHeader header = this.GetHeader(tableName);
TableHeader? header = this.GetHeader(tableName);
return header?.CreateReader(this.stream);
}
internal enum OutlineTypes : uint
{
TrueType = 0x00010000,
CFF = 0x4F54544F
}
}
}
}

Просмотреть файл

@ -1,3 +1,5 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.ComponentModel;

Просмотреть файл

@ -0,0 +1,8 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "style cop not liking nullable arrays", Scope = "type", Target = "~T:SixLabors.Fonts.IO.ZlibInflateStream")]

Просмотреть файл

@ -13,6 +13,12 @@ namespace SixLabors.Fonts
private readonly GlyphInstance instance;
private readonly float pointSize;
internal Glyph(GlyphInstance instance, float pointSize)
{
this.instance = instance;
this.pointSize = pointSize;
}
/// <summary>
/// Gets the glyph instance.
/// </summary>
@ -21,12 +27,12 @@ namespace SixLabors.Fonts
/// </value>
public GlyphInstance Instance => this.instance;
internal Glyph(GlyphInstance instance, float pointSize)
{
this.instance = instance;
this.pointSize = pointSize;
}
/// <summary>
/// Calculates the bounding box
/// </summary>
/// <param name="location">location to calualte from.</param>
/// <param name="dpi">dpi to calualtes in relation to</param>
/// <returns>The bounding box</returns>
public FontRectangle BoundingBox(Vector2 location, Vector2 dpi)
{
return this.instance.BoundingBox(location, this.pointSize * dpi);

Просмотреть файл

@ -12,6 +12,8 @@ namespace SixLabors.Fonts
/// </summary>
public partial class GlyphInstance
{
private static readonly Vector2 Scale = new Vector2(1, -1);
private readonly ushort sizeOfEm;
private readonly Vector2[] controlPoints;
private readonly bool[] onCurves;
@ -75,7 +77,35 @@ namespace SixLabors.Fonts
/// </value>
internal ushort Index { get; }
private static readonly Vector2 Scale = new Vector2(1, -1);
/// <summary>
/// Gets the size of the EM
/// </summary>
public ushort SizeOfEm => this.sizeOfEm;
/// <summary>
/// Gets the points defining the shape of this glyph
/// </summary>
public Vector2[] ControlPoints => this.controlPoints;
/// <summary>
/// Gets wether or not the corresponding control point is on a curve
/// </summary>
public bool[] OnCurves => this.onCurves;
/// <summary>
/// Gets the end points
/// </summary>
public ushort[] EndPoints => this.endPoints;
/// <summary>
/// Gets the distance from the bounding box start
/// </summary>
public short LeftSideBearing => this.leftSideBearing;
/// <summary>
/// Gets the scale factor that is applied to the glyph
/// </summary>
public float ScaleFactor => this.scaleFactor;
internal FontRectangle BoundingBox(Vector2 origin, Vector2 scaledPointSize)
{
@ -258,32 +288,5 @@ namespace SixLabors.Fonts
this.Count = 0;
}
}
public ushort SizeOfEm => this.sizeOfEm;
/// <summary>
/// The points defining the shape of this glyph
/// </summary>
public Vector2[] ControlPoints => this.controlPoints;
/// <summary>
/// Wether or not the corresponding control point is on a curve
/// </summary>
public bool[] OnCurves => this.onCurves;
/// <summary>
/// The end points
/// </summary>
public ushort[] EndPoints => this.endPoints;
/// <summary>
/// The distance from the bounding box start
/// </summary>
public short LeftSideBearing => this.leftSideBearing;
/// <summary>
/// The scale factor that is applied to the glyph
/// </summary>
public float ScaleFactor => this.scaleFactor;
}
}

Просмотреть файл

@ -0,0 +1,133 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
using System.Text;
namespace SixLabors.Fonts
{
/// <summary>
/// A glyphs layout and location
/// </summary>
internal readonly struct GlyphLayout
{
internal GlyphLayout(int codePoint, Glyph glyph, Vector2 location, float width, float height, float lineHeight, bool startOfLine, bool isWhiteSpace, bool isControlCharacter)
{
this.LineHeight = lineHeight;
this.CodePoint = codePoint;
this.Glyph = glyph;
this.Location = location;
this.Width = width;
this.Height = height;
this.StartOfLine = startOfLine;
this.IsWhiteSpace = isWhiteSpace;
this.IsControlCharacter = isControlCharacter;
}
/// <summary>
/// Gets a value indicating whether gets the glyphe represents a whitespace character.
/// </summary>
/// <value>
/// The bounds.
/// </value>
public bool IsWhiteSpace { get; }
/// <summary>
/// Gets the glyph.
/// </summary>
/// <value>
/// The glyph.
/// </value>
public Glyph Glyph { get; }
/// <summary>
/// Gets the location.
/// </summary>
/// <value>
/// The location.
/// </value>
public Vector2 Location { get; }
/// <summary>
/// Gets the width.
/// </summary>
/// <value>
/// The width.
/// </value>
public float Width { get; }
/// <summary>
/// Gets the height.
/// </summary>
/// <value>
/// The height.
/// </value>
public float Height { get; }
/// <summary>
/// Gets a value indicating whether this glyph is the first glyph on a new line.
/// </summary>
public bool StartOfLine { get; }
/// <summary>
/// Gets the Unicode code point of the character.
/// </summary>
public int CodePoint { get; }
public float LineHeight { get; }
public bool IsControlCharacter { get; }
internal FontRectangle BoundingBox(Vector2 dpi)
{
FontRectangle box = this.Glyph.BoundingBox(this.Location * dpi, dpi);
if (this.IsWhiteSpace)
{
box = new FontRectangle(box.X, box.Y, this.Width * dpi.X, box.Height);
}
return box;
}
public override string ToString()
{
var sb = new StringBuilder();
if (this.StartOfLine)
{
sb.Append('@');
sb.Append(' ');
}
if (this.IsWhiteSpace)
{
sb.Append('!');
}
sb.Append('\'');
switch (this.CodePoint)
{
case '\t': sb.Append("\\t"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case ' ': sb.Append(" "); break;
default:
sb.Append(char.ConvertFromUtf32(this.CodePoint));
break;
}
sb.Append('\'');
sb.Append(' ');
sb.Append(this.Location.X);
sb.Append(',');
sb.Append(this.Location.Y);
sb.Append(' ');
sb.Append(this.Width);
sb.Append('x');
sb.Append(this.Height);
return sb.ToString();
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -14,7 +14,7 @@ namespace SixLabors.Fonts
{
internal GlyphRendererParameters(GlyphInstance glyph, float pointSize, Vector2 dpi)
{
this.Font = glyph.Font.Description.FontName?.ToUpper();
this.Font = glyph.Font.Description.FontName?.ToUpper() ?? string.Empty;
this.FontStyle = glyph.Font.Description.Style;
this.GlyphIndex = glyph.Index;
this.PointSize = pointSize;
@ -109,4 +109,4 @@ namespace SixLabors.Fonts
this.DpiY);
}
}
}
}

Просмотреть файл

@ -1,26 +1,58 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
namespace SixLabors.Fonts
{
/// <summary>
/// Represents a font instance, which is a set of glyphs under a specific style (regular, italic, bold etc)
/// </summary>
public interface IFontInstance
{
/// <summary>
/// Gets the basic descripton of the font instance type.
/// </summary>
FontDescription Description { get; }
/// <summary>
/// Gets the EM size of the font
/// </summary>
ushort EmSize { get; }
/// <summary>
/// Gets the line height
/// </summary>
int LineHeight { get; }
/// <summary>
/// Gets the ascender
/// </summary>
short Ascender { get; }
/// <summary>
/// Gets the descender
/// </summary>
short Descender { get; }
/// <summary>
/// Gets the line gap
/// </summary>
short LineGap { get; }
/// <summary>
/// Gets a specific glyph
/// </summary>
/// <param name="codePoint">the code point to get the glyph from</param>
/// <returns>The glyph to find.</returns>
GlyphInstance GetGlyph(int codePoint);
/// <summary>
/// Get the kerning offset that should be applied between 2 glyphs.
/// </summary>
/// <param name="glyph">the new glyph</param>
/// <param name="previousGlyph">the previous glyph in the rendered font</param>
/// <returns>Returns the offset that should be offset between the 2 glyphs</returns>
Vector2 GetOffset(GlyphInstance glyph, GlyphInstance previousGlyph);
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -32,12 +32,12 @@ namespace SixLabors.Fonts.IO
/// <summary>
/// The read crc data.
/// </summary>
private byte[] crcread;
private byte[]? crcread;
/// <summary>
/// The stream responsible for decompressing the input stream.
/// </summary>
private DeflateStream deflateStream;
private DeflateStream? deflateStream;
/// <summary>
/// Initializes a new instance of the <see cref="ZlibInflateStream"/> class.
@ -137,6 +137,11 @@ namespace SixLabors.Fonts.IO
/// <inheritdoc/>
public override int Read(byte[] buffer, int offset, int count)
{
if (this.deflateStream is null)
{
throw new ObjectDisposedException("inner stream");
}
// We dont't check CRC on reading
int read = this.deflateStream.Read(buffer, offset, count);
if (read < 1 && this.crcread is null)

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.Fonts
@ -15,6 +15,7 @@ namespace SixLabors.Fonts
/// <param name="fontFamily">The family.</param>
/// <param name="size">The size.</param>
/// <param name="style">The style.</param>
/// <returns>The font for the representing the configured options.</returns>
public static Font CreateFont(this IReadOnlyFontCollection collection, string fontFamily, float size, FontStyle style)
{
return new Font(collection.Find(fontFamily), size, style);
@ -26,6 +27,7 @@ namespace SixLabors.Fonts
/// <param name="collection">The the ont collection to retrieve the font family from.</param>
/// <param name="fontFamily">The family.</param>
/// <param name="size">The size.</param>
/// <returns>The font for the representing the configured options.</returns>
public static Font CreateFont(this IReadOnlyFontCollection collection, string fontFamily, float size)
{
return new Font(collection.Find(fontFamily), size);

Просмотреть файл

@ -1,4 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// Common values read from `AssemblyInfo.Common.cs`

Просмотреть файл

@ -1,68 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>A cross-platform library for loading and laying out fonts for processing and measuring; written in C#</Description>
<AssemblyTitle>SixLabors.Fonts</AssemblyTitle>
<VersionPrefix Condition="$(packageversion) != ''">$(packageversion)</VersionPrefix>
<VersionPrefix Condition="$(packageversion) == ''">0.1.0-alpha1</VersionPrefix>
<Authors>Six Labors and contributors</Authors>
<TargetFrameworks>netstandard2.0;netstandard1.3</TargetFrameworks>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>SixLabors.Fonts</AssemblyName>
<AssemblyTitle>SixLabors.Fonts</AssemblyTitle>
<Description>A cross-platform library for loading and laying out fonts for processing and measuring; written in C#</Description>
<NeutralLanguage>en</NeutralLanguage>
<TargetFrameworks>netstandard2.1;netstandard2.0;netstandard1.3;</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageId>SixLabors.Fonts</PackageId>
<PackageTags>font;truetype;opentype;woff</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/SixLabors/Branding/master/icons/fonts/sixlabors.fonts.128.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/SixLabors/Fonts</PackageProjectUrl>
<PackageLicenseUrl>http://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/SixLabors/Fonts</RepositoryUrl>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<GenerateNeutralResourcesLanguageAttribute>false</GenerateNeutralResourcesLanguageAttribute>
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<DebugType Condition="$(codecov) != ''">full</DebugType>
<LangVersion>8.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- TODO: Include .NETSTANDARD2.1 when released-->
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netcoreapp2')) ">
<DefineConstants>$(DefineConstants);SUPPORTS_MATHF</DefineConstants>
</PropertyGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
<PackageReference Include="System.Numerics.Vectors" />
</ItemGroup>
<PropertyGroup Condition=" $(TargetFramework.StartsWith('netcoreapp2.1')) ">
<DefineConstants>$(DefineConstants);SUPPORTS_HASHCODE</DefineConstants>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'netstandard2.1' ">
<PackageReference Include="System.Buffers" />
<PackageReference Include="System.Memory" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\Shared\*.cs" Exclude="bin\**;obj\**;**\*.xproj;packages\**" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe"/>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\shared-infrastructure\**\*.cs" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\shared-infrastructure\SixLabors.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\shared-infrastructure\stylecop.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<PackageReference Include="System.Memory" Version="4.5.1" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.1" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
</ItemGroup>
<Import Project="..\..\shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems" Label="Shared" />
</Project>

Просмотреть файл

@ -22,7 +22,7 @@ namespace SixLabors.Fonts.Tables.General.CMap
public static EncodingRecord Read(BinaryReader reader)
{
PlatformIDs platform = (PlatformIDs)reader.ReadUInt16();
var platform = (PlatformIDs)reader.ReadUInt16();
ushort encoding = reader.ReadUInt16();
uint offset = reader.ReadOffset32();

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
@ -12,16 +12,14 @@ namespace SixLabors.Fonts.Tables.General
internal sealed class CMapTable : Table
{
private const string TableName = "cmap";
private readonly CMapSubTable table;
internal CMapSubTable[] Tables { get; }
private readonly CMapSubTable? table;
public CMapTable(CMapSubTable[] tables)
{
this.Tables = tables;
// lets just pick the best table for us.. lets jsut treat everything as windows and get the format 4 if possible
CMapSubTable table = null;
CMapSubTable? table = null;
foreach (CMapSubTable t in this.Tables)
{
if (t != null)
@ -40,10 +38,12 @@ namespace SixLabors.Fonts.Tables.General
this.table = table;
}
internal CMapSubTable[] Tables { get; }
public ushort GetGlyphId(int codePoint)
{
// use the best match only
if (this.table != null)
if (this.table is object)
{
return this.table.GetGlyphId(codePoint);
}
@ -103,4 +103,4 @@ namespace SixLabors.Fonts.Tables.General
return new CMapTable(tables.ToArray());
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.Fonts.Tables.General.Glyphs;
@ -11,13 +11,13 @@ namespace SixLabors.Fonts.Tables.General
private const string TableName = "glyf";
private readonly GlyphLoader[] loaders;
public int GlyphCount => this.loaders.Length;
public GlyphTable(GlyphLoader[] glyphLoaders)
{
this.loaders = glyphLoaders;
}
public int GlyphCount => this.loaders.Length;
internal virtual GlyphVector GetGlyph(int index)
{
return this.loaders[index].CreateGlyph(this);
@ -60,4 +60,4 @@ namespace SixLabors.Fonts.Tables.General
return new GlyphTable(glyphs);
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -19,6 +19,24 @@ namespace SixLabors.Fonts.Tables.General.Glyphs
this.bounds = bounds;
}
[Flags]
private enum CompositeFlags : ushort
{
ArgsAreWords = 1, // If this is set, the arguments are words; otherwise, they are bytes.
ArgsAreXYValues = 2, // If this is set, the arguments are xy values; otherwise, they are points.
RoundXYToGrid = 4, // For the xy values if the preceding is true.
WeHaveAScale = 8, // This indicates that there is a simple scale for the component. Otherwise, scale = 1.0.
Reserved = 16, // This bit is reserved. Set it to 0.
MoreComponents = 32, // Indicates at least one more glyph after this one.
WeHaveXAndYScale = 64, // The x direction will use a different scale from the y direction.
WeHaveATwoByTwo = 128, // There is a 2 by 2 transformation that will be used to scale the component.
WeHaveInstructions = 256, // Following the last component are instructions for the composite character.
UseMyMetrics = 512, // If set, this forces the aw and lsb (and rsb) for the composite to be equal to those from this original glyph. This works for hinted and unhinted characters.
OverlapCompound = 1024, // If set, the components of the compound glyph overlap. Use of this flag is not required in OpenType — that is, it is valid to have components overlap without having this flag set. It may affect behaviors in some platforms, however. (See Apples specification for details regarding behavior in Apple platforms.)
ScaledComponentOffset = 2048, // The composite is designed to have the component offset scaled.
UnscaledComponentOffset = 4096 // The composite is designed not to have the component offset scaled.
}
public override GlyphVector CreateGlyph(GlyphTable table)
{
var controlPoints = new List<Vector2>();
@ -121,24 +139,6 @@ namespace SixLabors.Fonts.Tables.General.Glyphs
return new CompositeGlyphLoader(result, bounds);
}
[Flags]
private enum CompositeFlags : ushort
{
ArgsAreWords = 1, // If this is set, the arguments are words; otherwise, they are bytes.
ArgsAreXYValues = 2, // If this is set, the arguments are xy values; otherwise, they are points.
RoundXYToGrid = 4, // For the xy values if the preceding is true.
WeHaveAScale = 8, // This indicates that there is a simple scale for the component. Otherwise, scale = 1.0.
Reserved = 16, // This bit is reserved. Set it to 0.
MoreComponents = 32, // Indicates at least one more glyph after this one.
WeHaveXAndYScale = 64, // The x direction will use a different scale from the y direction.
WeHaveATwoByTwo = 128, // There is a 2 by 2 transformation that will be used to scale the component.
WeHaveInstructions = 256, // Following the last component are instructions for the composite character.
UseMyMetrics = 512, // If set, this forces the aw and lsb (and rsb) for the composite to be equal to those from this original glyph. This works for hinted and unhinted characters.
OverlapCompound = 1024, // If set, the components of the compound glyph overlap. Use of this flag is not required in OpenType — that is, it is valid to have components overlap without having this flag set. It may affect behaviors in some platforms, however. (See Apples specification for details regarding behavior in Apple platforms.)
ScaledComponentOffset = 2048, // The composite is designed to have the component offset scaled.
UnscaledComponentOffset = 4096 // The composite is designed not to have the component offset scaled.
}
public readonly struct Composite
{
public Composite(ushort glyphIndex, Matrix3x2 transformation)

Просмотреть файл

@ -10,7 +10,7 @@ namespace SixLabors.Fonts.Tables.General.Glyphs
public static GlyphLoader Load(BinaryReader reader)
{
short contoursCount = reader.ReadInt16();
Bounds bounds = Bounds.Load(reader);
var bounds = Bounds.Load(reader);
if (contoursCount >= 0)
{

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -31,6 +31,18 @@ namespace SixLabors.Fonts.Tables.General.Glyphs
this.bounds = bounds;
}
[Flags]
private enum Flags : byte
{
ControlPoint = 0,
OnCurve = 1,
XByte = 2,
YByte = 4,
Repeat = 8,
XSignOrSame = 16,
YSignOrSame = 32
}
public override GlyphVector CreateGlyph(GlyphTable table)
{
// lets build some shapes ??? here from
@ -144,17 +156,5 @@ namespace SixLabors.Fonts.Tables.General.Glyphs
return xs;
}
[Flags]
private enum Flags : byte
{
ControlPoint = 0,
OnCurve = 1,
XByte = 2,
YByte = 4,
Repeat = 8,
XSignOrSame = 16,
YSignOrSame = 32
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -24,6 +24,63 @@ namespace SixLabors.Fonts.Tables.General
this.IndexLocationFormat = indexToLocFormat;
}
internal enum IndexLocationFormats : short
{
Offset16 = 0,
Offset32 = 1,
}
[Flags]
internal enum HeadFlags : ushort
{
// Bit 0: Baseline for font at y = 0;
// Bit 1: Left sidebearing point at x = 0(relevant only for TrueType rasterizers) — see the note below regarding variable fonts;
// Bit 2: Instructions may depend on point size;
// Bit 3: Force ppem to integer values for all internal scaler math; may use fractional ppem sizes if this bit is clear;
// Bit 4: Instructions may alter advance width(the advance widths might not scale linearly);
// Bit 5: This bit is not used in OpenType, and should not be set in order to ensure compatible behavior on all platforms.If set, it may result in different behavior for vertical layout in some platforms. (See Apple's specification for details regarding behavior in Apple platforms.)
// Bits 6–10: These bits are not used in Opentype and should always be cleared. (See Apple's specification for details regarding legacy used in Apple platforms.)
// Bit 11: Font data is lossless as a results of having been subjected to optimizing transformation and/or compression (such as e.g.compression mechanisms defined by ISO/IEC 14496-18, MicroType Express, WOFF 2.0 or similar) where the original font functionality and features are retained but the binary compatibility between input and output font files is not guaranteed.As a result of the applied transform, the DSIG Table may also be invalidated.
// Bit 12: Font converted (produce compatible metrics)
// Bit 13: Font optimized for ClearType™. Note, fonts that rely on embedded bitmaps (EBDT) for rendering should not be considered optimized for ClearType, and therefore should keep this bit cleared.
// Bit 14: Last Resort font.If set, indicates that the glyphs encoded in the cmap subtables are simply generic symbolic representations of code point ranges and dont truly represent support for those code points.If unset, indicates that the glyphs encoded in the cmap subtables represent proper support for those code points.
// Bit 15: Reserved, set to 0
None = 0,
BaslineY0 = 1 << 0,
LeftSidebearingPointAtX0 = 1 << 1,
InstructionDependOnPointSize = 1 << 2,
ForcePPEMToInt = 1 << 3,
InstructionAlterAdvancedWidth = 1 << 4,
// 1<<5 not used
// 1<<6 - 1<<10 not used
FontDataLossLess = 1 << 11,
FontConverted = 1 << 12,
OptimizedForClearType = 1 << 13,
LastResortFont = 1 << 14,
}
[Flags]
internal enum HeadMacStyle : ushort
{
// Bit 0: Bold (if set to 1);
// Bit 1: Italic(if set to 1)
// Bit 2: Underline(if set to 1)
// Bit 3: Outline(if set to 1)
// Bit 4: Shadow(if set to 1)
// Bit 5: Condensed(if set to 1)
// Bit 6: Extended(if set to 1)
// Bits 7–15: Reserved(set to 0).
None = 0,
Bold = 1 << 0,
Italic = 1 << 1,
Underline = 1 << 2,
Outline = 1 << 3,
Shaddow = 1 << 4,
Condensed = 1 << 5,
Extended = 1 << 6,
}
public DateTime Created { get; }
public HeadFlags Flags { get; }
@ -40,9 +97,9 @@ namespace SixLabors.Fonts.Tables.General
public ushort UnitsPerEm { get; }
public static HeadTable Load(FontReader reader)
public static HeadTable? Load(FontReader reader)
{
using (BinaryReader binaryReader = reader.TryGetReaderAtTablePosition(TableName))
using (BinaryReader? binaryReader = reader.TryGetReaderAtTablePosition(TableName))
{
if (binaryReader is null)
{
@ -136,7 +193,7 @@ namespace SixLabors.Fonts.Tables.General
modified = startDate.AddSeconds(seconds);
}
Bounds bounds = Bounds.Load(reader); // xMin, yMin, xMax, yMax
var bounds = Bounds.Load(reader); // xMin, yMin, xMax, yMax
HeadMacStyle macStyle = reader.ReadUInt16<HeadMacStyle>();
ushort lowestRecPPEM = reader.ReadUInt16();
@ -154,62 +211,5 @@ namespace SixLabors.Fonts.Tables.General
lowestRecPPEM,
indexToLocFormat);
}
internal enum IndexLocationFormats : short
{
Offset16 = 0,
Offset32 = 1,
}
[Flags]
internal enum HeadFlags : ushort
{
// Bit 0: Baseline for font at y = 0;
// Bit 1: Left sidebearing point at x = 0(relevant only for TrueType rasterizers) — see the note below regarding variable fonts;
// Bit 2: Instructions may depend on point size;
// Bit 3: Force ppem to integer values for all internal scaler math; may use fractional ppem sizes if this bit is clear;
// Bit 4: Instructions may alter advance width(the advance widths might not scale linearly);
// Bit 5: This bit is not used in OpenType, and should not be set in order to ensure compatible behavior on all platforms.If set, it may result in different behavior for vertical layout in some platforms. (See Apple's specification for details regarding behavior in Apple platforms.)
// Bits 6–10: These bits are not used in Opentype and should always be cleared. (See Apple's specification for details regarding legacy used in Apple platforms.)
// Bit 11: Font data is lossless as a results of having been subjected to optimizing transformation and/or compression (such as e.g.compression mechanisms defined by ISO/IEC 14496-18, MicroType Express, WOFF 2.0 or similar) where the original font functionality and features are retained but the binary compatibility between input and output font files is not guaranteed.As a result of the applied transform, the DSIG Table may also be invalidated.
// Bit 12: Font converted (produce compatible metrics)
// Bit 13: Font optimized for ClearType™. Note, fonts that rely on embedded bitmaps (EBDT) for rendering should not be considered optimized for ClearType, and therefore should keep this bit cleared.
// Bit 14: Last Resort font.If set, indicates that the glyphs encoded in the cmap subtables are simply generic symbolic representations of code point ranges and dont truly represent support for those code points.If unset, indicates that the glyphs encoded in the cmap subtables represent proper support for those code points.
// Bit 15: Reserved, set to 0
None = 0,
BaslineY0 = 1 << 0,
LeftSidebearingPointAtX0 = 1 << 1,
InstructionDependOnPointSize = 1 << 2,
ForcePPEMToInt = 1 << 3,
InstructionAlterAdvancedWidth = 1 << 4,
// 1<<5 not used
// 1<<6 - 1<<10 not used
FontDataLossLess = 1 << 11,
FontConverted = 1 << 12,
OptimizedForClearType = 1 << 13,
LastResortFont = 1 << 14,
}
[Flags]
internal enum HeadMacStyle : ushort
{
// Bit 0: Bold (if set to 1);
// Bit 1: Italic(if set to 1)
// Bit 2: Underline(if set to 1)
// Bit 3: Outline(if set to 1)
// Bit 4: Shadow(if set to 1)
// Bit 5: Condensed(if set to 1)
// Bit 6: Extended(if set to 1)
// Bits 7–15: Reserved(set to 0).
None = 0,
Bold = 1 << 0,
Italic = 1 << 1,
Underline = 1 << 2,
Outline = 1 << 3,
Shaddow = 1 << 4,
Condensed = 1 << 5,
Extended = 1 << 6,
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.Fonts.Exceptions;
@ -47,9 +47,9 @@ namespace SixLabors.Fonts.Tables.General
public short XMaxExtent { get; }
public static HorizontalHeadTable Load(FontReader reader)
public static HorizontalHeadTable? Load(FontReader reader)
{
using (BinaryReader binaryReader = reader.TryGetReaderAtTablePosition(TableName))
using (BinaryReader? binaryReader = reader.TryGetReaderAtTablePosition(TableName))
{
if (binaryReader == null)
{
@ -120,4 +120,4 @@ namespace SixLabors.Fonts.Tables.General
numberOfHMetrics);
}
}
}
}

Просмотреть файл

@ -55,8 +55,8 @@ namespace SixLabors.Fonts.Tables.General
// longHorMetric | hMetrics[numberOfHMetrics] | Paired advance width and left side bearing values for each glyph. Records are indexed by glyph ID.
// int16 | leftSideBearing[numGlyphs - numberOfHMetrics] | Left side bearings for glyph IDs greater than or equal to numberOfHMetrics.
int bearingCount = glyphCount - metricCount;
var advancedWidth = new ushort[metricCount];
var leftSideBearings = new short[glyphCount];
ushort[] advancedWidth = new ushort[metricCount];
short[] leftSideBearings = new short[glyphCount];
for (int i = 0; i < metricCount; i++)
{

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.Fonts.Exceptions;
@ -17,7 +17,7 @@ namespace SixLabors.Fonts.Tables.General
public uint[] GlyphOffsets { get; }
public static IndexLocationTable Load(FontReader reader)
public static IndexLocationTable? Load(FontReader reader)
{
HeadTable head = reader.GetTable<HeadTable>();
if (head == null)
@ -28,7 +28,7 @@ namespace SixLabors.Fonts.Tables.General
MaximumProfileTable maxp = reader.GetTable<MaximumProfileTable>();
// must not get a binary reader untill all depended data is retrieved in case they need to use the stream
using (BinaryReader binaryReader = reader.TryGetReaderAtTablePosition(TableName))
using (BinaryReader? binaryReader = reader.TryGetReaderAtTablePosition(TableName))
{
if (binaryReader == null)
{
@ -49,7 +49,7 @@ namespace SixLabors.Fonts.Tables.General
// ---------|-------------|---------------------------------------
// Offset16 | offsets[n] | The actual local offset divided by 2 is stored. The value of n is numGlyphs + 1. The value for numGlyphs is found in the 'maxp' table.
ushort[] data = reader.ReadUInt16Array(entrycount);
var convertedData = new uint[entrycount];
uint[] convertedData = new uint[entrycount];
for (int i = 0; i < entrycount; i++)
{
convertedData[i] = (uint)(data[i] * 2);
@ -72,4 +72,4 @@ namespace SixLabors.Fonts.Tables.General
}
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Numerics;
@ -14,7 +14,7 @@ namespace SixLabors.Fonts.Tables.General.Kern
this.coverage = coverage;
}
public static KerningSubTable Load(BinaryReader reader)
public static KerningSubTable? Load(BinaryReader reader)
{
// Kerning subtables will share the same header format. This header is used to identify the format of the subtable and the kind of information it contains:
// Type | Field | Description
@ -25,7 +25,7 @@ namespace SixLabors.Fonts.Tables.General.Kern
ushort subVersion = reader.ReadUInt16();
ushort length = reader.ReadUInt16();
KerningCoverage coverage = KerningCoverage.Read(reader);
var coverage = KerningCoverage.Read(reader);
if (coverage.Format == 0)
{

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
@ -21,7 +21,7 @@ namespace SixLabors.Fonts.Tables.General
public static KerningTable Load(FontReader reader)
{
using (BinaryReader binaryReader = reader.TryGetReaderAtTablePosition(TableName))
using (BinaryReader? binaryReader = reader.TryGetReaderAtTablePosition(TableName))
{
if (binaryReader is null)
{
@ -46,7 +46,7 @@ namespace SixLabors.Fonts.Tables.General
var tables = new List<KerningSubTable>(subtableCount);
for (int i = 0; i < subtableCount; i++)
{
KerningSubTable t = KerningSubTable.Load(reader); // returns null for unknown/supported table format
var t = KerningSubTable.Load(reader); // returns null for unknown/supported table format
if (t != null)
{
tables.Add(t);
@ -67,4 +67,4 @@ namespace SixLabors.Fonts.Tables.General
return result;
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Text;
@ -26,7 +26,7 @@ namespace SixLabors.Fonts.Tables.General.Name
public NameIds NameID { get; }
internal StringLoader StringReader { get; private set; }
internal StringLoader? StringReader { get; private set; }
public string Value => this.StringReader?.Value ?? this.value;
@ -38,9 +38,9 @@ namespace SixLabors.Fonts.Tables.General.Name
ushort languageID = reader.ReadUInt16();
NameIds nameID = reader.ReadUInt16<NameIds>();
StringLoader stringReader = StringLoader.Create(reader, encoding);
var stringReader = StringLoader.Create(reader, encoding);
return new NameRecord(platform, languageID, nameID, null)
return new NameRecord(platform, languageID, nameID, string.Empty)
{
StringReader = stringReader
};

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
@ -16,59 +16,6 @@ namespace SixLabors.Fonts.Tables.General
private const string TableName = "name";
private readonly NameRecord[] names;
public static NameTable Load(FontReader reader)
{
using (BinaryReader r = reader.GetReaderAtTablePosition(TableName))
{
// move to start of table
return Load(r);
}
}
public static NameTable Load(BinaryReader reader)
{
List<StringLoader> strings = new List<StringLoader>();
ushort format = reader.ReadUInt16();
ushort nameCount = reader.ReadUInt16();
ushort stringOffset = reader.ReadUInt16();
var names = new NameRecord[nameCount];
for (int i = 0; i < nameCount; i++)
{
names[i] = NameRecord.Read(reader);
strings.Add(names[i].StringReader);
}
StringLoader[] langs = null;
if (format == 1)
{
// format 1 adds language data
ushort langCount = reader.ReadUInt16();
langs = new StringLoader[langCount];
for (int i = 0; i < langCount; i++)
{
langs[i] = StringLoader.Create(reader);
strings.Add(langs[i]);
}
}
foreach (StringLoader readable in strings.OrderBy(x => x.Offset))
{
int diff = stringOffset + readable.Offset;
// only seek forward, if we find issues with this we will consume forwards as the idea is we will never need to backtrack
reader.Seek(diff, SeekOrigin.Begin);
readable.LoadValue(reader);
}
string[] langNames = langs?.Select(x => x.Value).ToArray() ?? new string[0];
return new NameTable(names, langNames);
}
internal NameTable(NameRecord[] names, string[] languages)
{
this.names = names;
@ -142,12 +89,69 @@ namespace SixLabors.Fonts.Tables.General
}
}
return null;
return string.Empty;
}
public string GetNameById(ushort nameId)
{
return this.GetNameById((NameIds)nameId);
}
public static NameTable Load(FontReader reader)
{
using (BinaryReader r = reader.GetReaderAtTablePosition(TableName))
{
// move to start of table
return Load(r);
}
}
public static NameTable Load(BinaryReader reader)
{
var strings = new List<StringLoader>();
ushort format = reader.ReadUInt16();
ushort nameCount = reader.ReadUInt16();
ushort stringOffset = reader.ReadUInt16();
var names = new NameRecord[nameCount];
for (int i = 0; i < nameCount; i++)
{
names[i] = NameRecord.Read(reader);
StringLoader? sr = names[i].StringReader;
if (sr is object)
{
strings.Add(sr);
}
}
var langs = new StringLoader[0];
if (format == 1)
{
// format 1 adds language data
ushort langCount = reader.ReadUInt16();
langs = new StringLoader[langCount];
for (int i = 0; i < langCount; i++)
{
langs[i] = StringLoader.Create(reader);
strings.Add(langs[i]);
}
}
foreach (StringLoader readable in strings.OrderBy(x => x.Offset))
{
int diff = stringOffset + readable.Offset;
// only seek forward, if we find issues with this we will consume forwards as the idea is we will never need to backtrack
reader.Seek(diff, SeekOrigin.Begin);
readable.LoadValue(reader);
}
string[] langNames = langs?.Select(x => x.Value).ToArray() ?? new string[0];
return new NameTable(names, langNames);
}
}
}
}

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.Fonts.Tables.General
@ -8,8 +8,6 @@ namespace SixLabors.Fonts.Tables.General
{
private const string TableName = "OS/2";
public FontStyleSelection FontStyle { get; }
private ushort styleType;
private byte[] panose;
private short capHeight;
@ -45,180 +43,6 @@ namespace SixLabors.Fonts.Tables.General
private short superscriptYOffset;
private short superscriptYSize;
public short TypoAscender { get; }
public short TypoDescender { get; }
public short TypoLineGap { get; }
public static OS2Table Load(FontReader reader)
{
using (BinaryReader r = reader.TryGetReaderAtTablePosition(TableName))
{
if (r is null)
{
return null;
}
return Load(r);
}
}
public static OS2Table Load(BinaryReader reader)
{
// Version 1.0
// Type | Name | Comments
// -------|------------------------|-----------------------
// uint16 |version | 0x0005
// int16 |xAvgCharWidth |
// uint16 |usWeightClass |
// uint16 |usWidthClass |
// uint16 |fsType |
// int16 |ySubscriptXSize |
// int16 |ySubscriptYSize |
// int16 |ySubscriptXOffset |
// int16 |ySubscriptYOffset |
// int16 |ySuperscriptXSize |
// int16 |ySuperscriptYSize |
// int16 |ySuperscriptXOffset |
// int16 |ySuperscriptYOffset |
// int16 |yStrikeoutSize |
// int16 |yStrikeoutPosition |
// int16 |sFamilyClass |
// uint8 |panose[10] |
// uint32 |ulUnicodeRange1 | Bits 0–31
// uint32 |ulUnicodeRange2 | Bits 32–63
// uint32 |ulUnicodeRange3 | Bits 64–95
// uint32 |ulUnicodeRange4 | Bits 96–127
// Tag |achVendID |
// uint16 |fsSelection |
// uint16 |usFirstCharIndex |
// uint16 |usLastCharIndex |
// int16 |sTypoAscender |
// int16 |sTypoDescender |
// int16 |sTypoLineGap |
// uint16 |usWinAscent |
// uint16 |usWinDescent |
// uint32 |ulCodePageRange1 | Bits 0–31
// uint32 |ulCodePageRange2 | Bits 32–63
// int16 |sxHeight |
// int16 |sCapHeight |
// uint16 |usDefaultChar |
// uint16 |usBreakChar |
// uint16 |usMaxContext |
// uint16 |usLowerOpticalPointSize |
// uint16 |usUpperOpticalPointSize |
ushort version = reader.ReadUInt16(); // assert 0x0005
short averageCharWidth = reader.ReadInt16();
ushort weightClass = reader.ReadUInt16();
ushort widthClass = reader.ReadUInt16();
ushort styleType = reader.ReadUInt16();
short subscriptXSize = reader.ReadInt16();
short subscriptYSize = reader.ReadInt16();
short subscriptXOffset = reader.ReadInt16();
short subscriptYOffset = reader.ReadInt16();
short superscriptXSize = reader.ReadInt16();
short superscriptYSize = reader.ReadInt16();
short superscriptXOffset = reader.ReadInt16();
short superscriptYOffset = reader.ReadInt16();
short strikeoutSize = reader.ReadInt16();
short strikeoutPosition = reader.ReadInt16();
short familyClass = reader.ReadInt16();
byte[] panose = reader.ReadUInt8Array(10);
uint unicodeRange1 = reader.ReadUInt32(); // Bits 0–31
uint unicodeRange2 = reader.ReadUInt32(); // Bits 32–63
uint unicodeRange3 = reader.ReadUInt32(); // Bits 64–95
uint unicodeRange4 = reader.ReadUInt32(); // Bits 96–127
string tag = reader.ReadTag();
FontStyleSelection fontStyle = reader.ReadUInt16<FontStyleSelection>();
ushort firstCharIndex = reader.ReadUInt16();
ushort lastCharIndex = reader.ReadUInt16();
short typoAscender = reader.ReadInt16();
short typoDescender = reader.ReadInt16();
short typoLineGap = reader.ReadInt16();
ushort winAscent = reader.ReadUInt16();
ushort winDescent = reader.ReadUInt16();
OS2Table version0Table = new OS2Table(
averageCharWidth,
weightClass,
widthClass,
styleType,
subscriptXSize,
subscriptYSize,
subscriptXOffset,
subscriptYOffset,
superscriptXSize,
superscriptYSize,
superscriptXOffset,
superscriptYOffset,
strikeoutSize,
strikeoutPosition,
familyClass,
panose,
unicodeRange1,
unicodeRange2,
unicodeRange3,
unicodeRange4,
tag,
fontStyle,
firstCharIndex,
lastCharIndex,
typoAscender,
typoDescender,
typoLineGap,
winAscent,
winDescent);
if (version == 0)
{
return version0Table;
}
ushort codePageRange1 = 0;
ushort codePageRange2 = 0;
short heightX = 0;
short capHeight = 0;
ushort defaultChar = 0;
ushort breakChar = 0;
ushort maxContext = 0;
codePageRange1 = reader.ReadUInt16(); // Bits 0–31
codePageRange2 = reader.ReadUInt16(); // Bits 32–63
heightX = reader.ReadInt16();
capHeight = reader.ReadInt16();
defaultChar = reader.ReadUInt16();
breakChar = reader.ReadUInt16();
maxContext = reader.ReadUInt16();
OS2Table versionLessthan5Table = new OS2Table(
version0Table,
codePageRange1,
codePageRange2,
heightX,
capHeight,
defaultChar,
breakChar,
maxContext);
if (version < 5)
{
return versionLessthan5Table;
}
ushort lowerOpticalPointSize = reader.ReadUInt16();
ushort upperOpticalPointSize = reader.ReadUInt16();
return new OS2Table(
versionLessthan5Table,
lowerOpticalPointSize,
upperOpticalPointSize);
}
public OS2Table(short averageCharWidth, ushort weightClass, ushort widthClass, ushort styleType, short subscriptXSize, short subscriptYSize, short subscriptXOffset, short subscriptYOffset, short superscriptXSize, short superscriptYSize, short superscriptXOffset, short superscriptYOffset, short strikeoutSize, short strikeoutPosition, short familyClass, byte[] panose, uint unicodeRange1, uint unicodeRange2, uint unicodeRange3, uint unicodeRange4, string tag, FontStyleSelection fontStyle, ushort firstCharIndex, ushort lastCharIndex, short typoAscender, short typoDescender, short typoLineGap, ushort winAscent, ushort winDescent)
{
this.averageCharWidth = averageCharWidth;
@ -342,5 +166,181 @@ namespace SixLabors.Fonts.Tables.General
// 10–15 <reserved> Reserved; set to 0.
}
public FontStyleSelection FontStyle { get; }
public short TypoAscender { get; }
public short TypoDescender { get; }
public short TypoLineGap { get; }
public static OS2Table? Load(FontReader reader)
{
using (BinaryReader? r = reader.TryGetReaderAtTablePosition(TableName))
{
if (r is null)
{
return null;
}
return Load(r);
}
}
public static OS2Table Load(BinaryReader reader)
{
// Version 1.0
// Type | Name | Comments
// -------|------------------------|-----------------------
// uint16 |version | 0x0005
// int16 |xAvgCharWidth |
// uint16 |usWeightClass |
// uint16 |usWidthClass |
// uint16 |fsType |
// int16 |ySubscriptXSize |
// int16 |ySubscriptYSize |
// int16 |ySubscriptXOffset |
// int16 |ySubscriptYOffset |
// int16 |ySuperscriptXSize |
// int16 |ySuperscriptYSize |
// int16 |ySuperscriptXOffset |
// int16 |ySuperscriptYOffset |
// int16 |yStrikeoutSize |
// int16 |yStrikeoutPosition |
// int16 |sFamilyClass |
// uint8 |panose[10] |
// uint32 |ulUnicodeRange1 | Bits 0–31
// uint32 |ulUnicodeRange2 | Bits 32–63
// uint32 |ulUnicodeRange3 | Bits 64–95
// uint32 |ulUnicodeRange4 | Bits 96–127
// Tag |achVendID |
// uint16 |fsSelection |
// uint16 |usFirstCharIndex |
// uint16 |usLastCharIndex |
// int16 |sTypoAscender |
// int16 |sTypoDescender |
// int16 |sTypoLineGap |
// uint16 |usWinAscent |
// uint16 |usWinDescent |
// uint32 |ulCodePageRange1 | Bits 0–31
// uint32 |ulCodePageRange2 | Bits 32–63
// int16 |sxHeight |
// int16 |sCapHeight |
// uint16 |usDefaultChar |
// uint16 |usBreakChar |
// uint16 |usMaxContext |
// uint16 |usLowerOpticalPointSize |
// uint16 |usUpperOpticalPointSize |
ushort version = reader.ReadUInt16(); // assert 0x0005
short averageCharWidth = reader.ReadInt16();
ushort weightClass = reader.ReadUInt16();
ushort widthClass = reader.ReadUInt16();
ushort styleType = reader.ReadUInt16();
short subscriptXSize = reader.ReadInt16();
short subscriptYSize = reader.ReadInt16();
short subscriptXOffset = reader.ReadInt16();
short subscriptYOffset = reader.ReadInt16();
short superscriptXSize = reader.ReadInt16();
short superscriptYSize = reader.ReadInt16();
short superscriptXOffset = reader.ReadInt16();
short superscriptYOffset = reader.ReadInt16();
short strikeoutSize = reader.ReadInt16();
short strikeoutPosition = reader.ReadInt16();
short familyClass = reader.ReadInt16();
byte[] panose = reader.ReadUInt8Array(10);
uint unicodeRange1 = reader.ReadUInt32(); // Bits 0–31
uint unicodeRange2 = reader.ReadUInt32(); // Bits 32–63
uint unicodeRange3 = reader.ReadUInt32(); // Bits 64–95
uint unicodeRange4 = reader.ReadUInt32(); // Bits 96–127
string tag = reader.ReadTag();
FontStyleSelection fontStyle = reader.ReadUInt16<FontStyleSelection>();
ushort firstCharIndex = reader.ReadUInt16();
ushort lastCharIndex = reader.ReadUInt16();
short typoAscender = reader.ReadInt16();
short typoDescender = reader.ReadInt16();
short typoLineGap = reader.ReadInt16();
ushort winAscent = reader.ReadUInt16();
ushort winDescent = reader.ReadUInt16();
var version0Table = new OS2Table(
averageCharWidth,
weightClass,
widthClass,
styleType,
subscriptXSize,
subscriptYSize,
subscriptXOffset,
subscriptYOffset,
superscriptXSize,
superscriptYSize,
superscriptXOffset,
superscriptYOffset,
strikeoutSize,
strikeoutPosition,
familyClass,
panose,
unicodeRange1,
unicodeRange2,
unicodeRange3,
unicodeRange4,
tag,
fontStyle,
firstCharIndex,
lastCharIndex,
typoAscender,
typoDescender,
typoLineGap,
winAscent,
winDescent);
if (version == 0)
{
return version0Table;
}
ushort codePageRange1 = 0;
ushort codePageRange2 = 0;
short heightX = 0;
short capHeight = 0;
ushort defaultChar = 0;
ushort breakChar = 0;
ushort maxContext = 0;
codePageRange1 = reader.ReadUInt16(); // Bits 0–31
codePageRange2 = reader.ReadUInt16(); // Bits 32–63
heightX = reader.ReadInt16();
capHeight = reader.ReadInt16();
defaultChar = reader.ReadUInt16();
breakChar = reader.ReadUInt16();
maxContext = reader.ReadUInt16();
var versionLessthan5Table = new OS2Table(
version0Table,
codePageRange1,
codePageRange2,
heightX,
capHeight,
defaultChar,
breakChar,
maxContext);
if (version < 5)
{
return versionLessthan5Table;
}
ushort lowerOpticalPointSize = reader.ReadUInt16();
ushort upperOpticalPointSize = reader.ReadUInt16();
return new OS2Table(
versionLessthan5Table,
lowerOpticalPointSize,
upperOpticalPointSize);
}
}
}
}

Просмотреть файл

@ -12,6 +12,10 @@ namespace SixLabors.Fonts.Tables
{
internal class TableLoader
{
private readonly Dictionary<string, Func<FontReader, Table?>> loaders = new Dictionary<string, Func<FontReader, Table?>>();
private readonly Dictionary<Type, string> types = new Dictionary<Type, string>();
private readonly Dictionary<Type, Func<FontReader, Table?>> typesLoaders = new Dictionary<Type, Func<FontReader, Table?>>();
public TableLoader()
{
// we will hard code mapping registration in here for all the tables
@ -29,10 +33,6 @@ namespace SixLabors.Fonts.Tables
public static TableLoader Default { get; } = new TableLoader();
private readonly Dictionary<string, Func<FontReader, Table>> loaders = new Dictionary<string, Func<FontReader, Table>>();
private readonly Dictionary<Type, string> types = new Dictionary<Type, string>();
private readonly Dictionary<Type, Func<FontReader, Table>> typesLoaders = new Dictionary<Type, Func<FontReader, Table>>();
public string GetTag(Type type)
{
this.types.TryGetValue(type, out string value);
@ -40,11 +40,18 @@ namespace SixLabors.Fonts.Tables
return value;
}
public string GetTag<TType>()
{
this.types.TryGetValue(typeof(TType), out string value);
return value;
}
internal IEnumerable<Type> RegisterdTypes() => this.types.Keys;
internal IEnumerable<string> RegisterdTags() => this.types.Values;
private void Register<T>(string tag, Func<FontReader, T> createFunc)
private void Register<T>(string tag, Func<FontReader, T?> createFunc)
where T : Table
{
lock (this.loaders)
@ -58,7 +65,7 @@ namespace SixLabors.Fonts.Tables
}
}
private void Register<T>(Func<FontReader, T> createFunc)
private void Register<T>(Func<FontReader, T?> createFunc)
where T : Table
{
string name =
@ -70,24 +77,24 @@ namespace SixLabors.Fonts.Tables
this.Register(name, createFunc);
}
internal Table Load(string tag, FontReader reader)
internal Table? Load(string tag, FontReader reader)
{
// loader missing register an unknow type loader and carry on
return this.loaders.TryGetValue(tag, out var func)
return this.loaders.TryGetValue(tag, out Func<FontReader, Table?> func)
? func.Invoke(reader)
: new UnknownTable(tag);
}
internal TTable Load<TTable>(FontReader reader)
internal TTable? Load<TTable>(FontReader reader)
where TTable : Table
{
// loader missing register an unknow type loader and carry on
if (this.typesLoaders.TryGetValue(typeof(TTable), out var func))
if (this.typesLoaders.TryGetValue(typeof(TTable), out Func<FontReader, Table?> func))
{
return (TTable)func.Invoke(reader);
return (TTable?)func.Invoke(reader);
}
throw new Exception("font table not registered");
}
}
}
}

Просмотреть файл

@ -65,7 +65,7 @@ namespace SixLabors.Fonts
float top = 0;
bool firstLine = true;
GlyphInstance previousGlyph = null;
GlyphInstance? previousGlyph = null;
float scale = 0;
int lastWrappableLocation = -1;
bool startOfLine = true;
@ -305,129 +305,4 @@ namespace SixLabors.Fonts
return layout;
}
}
/// <summary>
/// A glyphs layout and location
/// </summary>
internal readonly struct GlyphLayout
{
internal GlyphLayout(int codePoint, Glyph glyph, Vector2 location, float width, float height, float lineHeight, bool startOfLine, bool isWhiteSpace, bool isControlCharacter)
{
this.LineHeight = lineHeight;
this.CodePoint = codePoint;
this.Glyph = glyph;
this.Location = location;
this.Width = width;
this.Height = height;
this.StartOfLine = startOfLine;
this.IsWhiteSpace = isWhiteSpace;
this.IsControlCharacter = isControlCharacter;
}
/// <summary>
/// Gets a value indicating whether gets the glyphe represents a whitespace character.
/// </summary>
/// <value>
/// The bounds.
/// </value>
public bool IsWhiteSpace { get; }
/// <summary>
/// Gets the glyph.
/// </summary>
/// <value>
/// The glyph.
/// </value>
public Glyph Glyph { get; }
/// <summary>
/// Gets the location.
/// </summary>
/// <value>
/// The location.
/// </value>
public Vector2 Location { get; }
/// <summary>
/// Gets the width.
/// </summary>
/// <value>
/// The width.
/// </value>
public float Width { get; }
/// <summary>
/// Gets the height.
/// </summary>
/// <value>
/// The height.
/// </value>
public float Height { get; }
/// <summary>
/// Gets a value indicating whether this glyph is the first glyph on a new line.
/// </summary>
public bool StartOfLine { get; }
/// <summary>
/// Gets the Unicode code point of the character.
/// </summary>
public int CodePoint { get; }
public float LineHeight { get; }
public bool IsControlCharacter { get; }
internal FontRectangle BoundingBox(Vector2 dpi)
{
FontRectangle box = this.Glyph.BoundingBox(this.Location * dpi, dpi);
if (this.IsWhiteSpace)
{
box = new FontRectangle(box.X, box.Y, this.Width * dpi.X, box.Height);
}
return box;
}
public override string ToString()
{
var sb = new StringBuilder();
if (this.StartOfLine)
{
sb.Append('@');
sb.Append(' ');
}
if (this.IsWhiteSpace)
{
sb.Append('!');
}
sb.Append('\'');
switch (this.CodePoint)
{
case '\t': sb.Append("\\t"); break;
case '\n': sb.Append("\\n"); break;
case '\r': sb.Append("\\r"); break;
case ' ': sb.Append(" "); break;
default:
sb.Append(char.ConvertFromUtf32(this.CodePoint));
break;
}
sb.Append('\'');
sb.Append(' ');
sb.Append(this.Location.X);
sb.Append(',');
sb.Append(this.Location.Y);
sb.Append(' ');
sb.Append(this.Width);
sb.Append('x');
sb.Append(this.Height);
return sb.ToString();
}
}
}

Просмотреть файл

@ -75,8 +75,8 @@ namespace SixLabors.Fonts
float top = glyphLayouts.Min(x => x.Location.Y - x.LineHeight);
float bottom = glyphLayouts.Max(x => x.Location.Y - x.LineHeight + x.Height);
var topLeft = new Vector2(left, top) * dpi;
var bottomRight = new Vector2(right, bottom) * dpi;
Vector2 topLeft = new Vector2(left, top) * dpi;
Vector2 bottomRight = new Vector2(right, bottom) * dpi;
Vector2 size = bottomRight - topLeft;
return new FontRectangle(topLeft.X, topLeft.Y, size.X, size.Y);

Просмотреть файл

@ -71,7 +71,7 @@ namespace SixLabors.Fonts
{
IReadOnlyList<GlyphLayout> glyphsToRender = this.layoutEngine.GenerateLayout(text, options);
Vector2 dpi = new Vector2(options.DpiX, options.DpiY);
var dpi = new Vector2(options.DpiX, options.DpiY);
FontRectangle rect = TextMeasurer.GetBounds(glyphsToRender, dpi);

Просмотреть файл

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Text;
@ -12,6 +12,7 @@ namespace SixLabors.Fonts.Utilities
this.Length = length;
this.Offset = offset;
this.Encoding = encoding;
this.Value = string.Empty;
}
public ushort Length { get; }

Просмотреть файл

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.props is automatically picked up and imported by
Microsoft.Common.props. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly early and only Sdk.props will have been
imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.props</MSBuildAllProjects>
<ImageSharpProjectCategory>tests</ImageSharpProjectCategory>
<IsPackable>false</IsPackable>
</PropertyGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)..\shared-infrastructure\SixLabors.Tests.ruleset</CodeAnalysisRuleSet>
<!--TODO: We should remove all obsolete code from the solution-->
<NoWarn>$(NoWarn);CS0618</NoWarn>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" IsImplicitlyDefined="true" />
<PackageReference Include="xunit" IsImplicitlyDefined="true" />
<PackageReference Include="xunit.runner.visualstudio" IsImplicitlyDefined="true" />
<PackageReference Include="coverlet.collector" IsImplicitlyDefined="true" />
<PackageReference Include="coverlet.msbuild" IsImplicitlyDefined="true" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!--
Directory.Build.targets is automatically picked up and imported by
Microsoft.Common.targets. This file needs to exist, even if empty so that
files in the parent directory tree, with the same name, are not imported
instead. The import fairly late and most other props/targets will have
been imported beforehand. We also don't need to add ourselves to
MSBuildAllProjects, as that is done by the file that imports us.
-->
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileDirectory)..\Directory.Build.targets</MSBuildAllProjects>
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.targets" />
<!-- Tool versions for tool references across all projects -->
<ItemGroup>
<!--dotnet tools does not have an x86 runner. You have to use separate SDKs-->
<!--https://github.com/actions/setup-dotnet/issues/72-->
<DotNetCliToolReference Update="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
<!--Code coverage specific settings-->
<!--https://github.com/tonerdo/coverlet-->
<PropertyGroup Condition="'$(codecov)' == 'true'">
<CollectCoverage>true</CollectCoverage>
<UseSourceLink>true</UseSourceLink>
<CoverletOutputFormat>opencover</CoverletOutputFormat>
<!--Output injects target framework into name despite explicit config. See build yml-->
<CoverletOutput>$(MSBuildThisFileDirectory)..\coverage.xml</CoverletOutput>
<!--Used by coverlet dues to reference issues with SixLabors.Core-->
<!--https://github.com/tonerdo/coverlet/blob/master/Documentation/KnowIssues.md#4-failed-to-resolve-assembly-during-instrumentation-->
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<!--Test Dependencies-->
<PackageReference Update="BenchmarkDotNet" Version="0.12.0" />
<PackageReference Update="coverlet.collector" Version="1.1.0" PrivateAssets="All"/>
<PackageReference Update="coverlet.msbuild" Version="2.8.0" PrivateAssets="All"/>
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Update="Moq" Version="4.10.0" />
<!--TODO: Fix implicit conversion issues so we can move to 2.4.1-->
<PackageReference Update="xunit" Version="2.3.1" />
<PackageReference Update="xunit.runner.visualstudio" Version="2.3.1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -16,9 +16,9 @@ namespace SixLabors.Fonts.Tests
public void MeasuringAccentedCharacterDoesNotThrow(char c)
{
FontFamily arial = SystemFonts.Find("Arial");
Font font = new Font(arial, 1f, FontStyle.Regular);
var font = new Font(arial, 1f, FontStyle.Regular);
var size = TextMeasurer.Measure(c.ToString(), new RendererOptions(font, 72));
FontRectangle size = TextMeasurer.Measure(c.ToString(), new RendererOptions(font, 72));
}
[Theory]
@ -33,9 +33,9 @@ namespace SixLabors.Fonts.Tests
public void MeasuringWordWithAccentedCharacterDoesNotThrow(char c)
{
FontFamily arial = SystemFonts.Find("Arial");
Font font = new Font(arial, 1f, FontStyle.Regular);
var font = new Font(arial, 1f, FontStyle.Regular);
var size = TextMeasurer.Measure($"abc{c}def", new RendererOptions(font, 72));
FontRectangle size = TextMeasurer.Measure($"abc{c}def", new RendererOptions(font, 72));
}
}
}

Просмотреть файл

@ -77,7 +77,7 @@ namespace SixLabors.Fonts.Tests
long p = this.BaseStream.Position;
this.BaseStream.Position = 0;
MemoryStream ms = new MemoryStream();
var ms = new MemoryStream();
this.BaseStream.CopyTo(ms);
ms.Position = 0;
this.BaseStream.Position = 0;

Просмотреть файл

@ -33,7 +33,7 @@ namespace SixLabors.Fonts.Tests.Fakes
/// </summary>
public static FakeFontInstance CreateFontWithVaryingVerticalFontMetrics(string text) {
List<FakeGlyphSource> glyphs = GetGlyphs(text);
FakeFontInstance result = new FakeFontInstance(
var result = new FakeFontInstance(
GenerateNameTable(),
GenerateCMapTable(glyphs),
new FakeGlyphTable(glyphs),
@ -46,7 +46,7 @@ namespace SixLabors.Fonts.Tests.Fakes
}
private static List<FakeGlyphSource> GetGlyphs(string text) {
List<FakeGlyphSource> glyphs = text.Distinct().Select((x, i) => new FakeGlyphSource(x, (ushort)i)).ToList();
var glyphs = text.Distinct().Select((x, i) => new FakeGlyphSource(x, (ushort)i)).ToList();
return glyphs;
}

Просмотреть файл

@ -19,7 +19,7 @@ namespace SixLabors.Fonts.Tests
[Fact]
public void InstallViaStreamReturnsDecription()
{
FontCollection sut = new FontCollection();
var sut = new FontCollection();
using (System.IO.Stream s = TestFonts.CarterOneFileData())
{
FontFamily family = sut.Install(s, out FontDescription description);

Просмотреть файл

@ -20,7 +20,7 @@ namespace SixLabors.Fonts.Tests
{ WellKnownIds.NameIds.FontFamilyName, "fam" }
});
FontDescription description = FontDescription.LoadDescription(writer.GetStream());
var description = FontDescription.LoadDescription(writer.GetStream());
Assert.Equal("name", description.FontName);
Assert.Equal("sub", description.FontSubFamilyName);
Assert.Equal("fam", description.FontFamily);

Просмотреть файл

@ -17,7 +17,7 @@ namespace SixLabors.Fonts.Tests
[Fact]
public void LoadFontMetadata()
{
FontDescription description = FontDescription.LoadDescription(TestFonts.SimpleFontFileData());
var description = FontDescription.LoadDescription(TestFonts.SimpleFontFileData());
Assert.Equal("SixLaborsSampleAB regular", description.FontName);
Assert.Equal("Regular", description.FontSubFamilyName);
@ -26,7 +26,7 @@ namespace SixLabors.Fonts.Tests
[Fact]
public void LoadFontMetadataWoff()
{
FontDescription description = FontDescription.LoadDescription(TestFonts.SimpleFontFileWoffData());
var description = FontDescription.LoadDescription(TestFonts.SimpleFontFileWoffData());
Assert.Equal("SixLaborsSampleAB regular", description.FontName);
Assert.Equal("Regular", description.FontSubFamilyName);

Просмотреть файл

@ -14,7 +14,7 @@ namespace SixLabors.Fonts.Tests
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader(0, 0, 0, 0);
FontReader reader = new FontReader(writer.GetStream());
var reader = new FontReader(writer.GetStream());
Assert.Equal(FontReader.OutlineTypes.TrueType, reader.OutlineType);
}

Просмотреть файл

@ -15,7 +15,7 @@ namespace SixLabors.Fonts.Tests
{
var glyph = new Glyph(new GlyphInstance((FontInstance)CreateFont("A").Instance, new Vector2[0], new bool[0], new ushort[0], new Bounds(0, 1, 0, 1), 0, 0, 1, 0), 10);
var locationInFontSpace = new Vector2(99, 99) / 72; // glyp ends up 10px over due to offiset in fake glyph
Vector2 locationInFontSpace = new Vector2(99, 99) / 72; // glyp ends up 10px over due to offiset in fake glyph
glyph.RenderTo(renderer, locationInFontSpace, 72, 0);
Assert.Equal(new FontRectangle(99, 89, 0, 0), this.renderer.GlyphRects.Single());
@ -71,7 +71,7 @@ namespace SixLabors.Fonts.Tests
// Get letter A
Glyph g = font.GetGlyph(41);
var instance = g.Instance;
GlyphInstance instance = g.Instance;
Assert.Equal(20, instance.ControlPoints.Length);
Assert.Equal(20, instance.OnCurves.Length);

Просмотреть файл

@ -12,7 +12,7 @@ namespace SixLabors.Fonts.Tests.Issues
var r = new GlyphRenderer();
var size = TextMeasurer.MeasureBounds(" ", new RendererOptions(new Font(font, 30), 72));
FontRectangle size = TextMeasurer.MeasureBounds(" ", new RendererOptions(new Font(font, 30), 72));
Assert.Equal(60, size.Width, 1);
Assert.Equal(31.6, size.Height, 1);

Просмотреть файл

@ -10,7 +10,7 @@ namespace SixLabors.Fonts.Tests.Issues
{
string text = "Hello\tworld";
Font font = CreateFont(text);
var size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize)
FontRectangle size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize)
{
TabWidth = 0
});

Просмотреть файл

@ -15,7 +15,7 @@ namespace SixLabors.Fonts.Tests.Issues
public void WhiteSpaceAtStartOfLineNotMeasured(string text, float width, float height)
{
Font font = CreateFont(text);
var size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, (72 * font.EmSize))
FontRectangle size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, (72 * font.EmSize))
{
});

Просмотреть файл

@ -9,10 +9,10 @@ namespace SixLabors.Fonts.Tests.Issues
public void RenderingTabAtStartOrLineTooShort()
{
Font font = CreateFont("\t x");
var xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
var tabWidth = TextMeasurer.MeasureBounds("\t", new RendererOptions(font, (72 * font.EmSize)));
var doublTabWidth = TextMeasurer.MeasureBounds("\t\t", new RendererOptions(font, (72 * font.EmSize)));
var tabWithXWidth = TextMeasurer.MeasureBounds("\tx", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWidth = TextMeasurer.MeasureBounds("\t", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle doublTabWidth = TextMeasurer.MeasureBounds("\t\t", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWithXWidth = TextMeasurer.MeasureBounds("\tx", new RendererOptions(font, (72 * font.EmSize)));
Assert.Equal(tabWidth.Width + xWidth.Width, tabWithXWidth.Width, 2);
}
@ -22,9 +22,9 @@ namespace SixLabors.Fonts.Tests.Issues
public void Rendering2TabsAtStartOfLineTooShort()
{
Font font = CreateFont("\t x");
var xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
var tabWidth = TextMeasurer.MeasureBounds("\t\t", new RendererOptions(font, (72 * font.EmSize)));
var tabWithXWidth = TextMeasurer.MeasureBounds("\t\tx", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWidth = TextMeasurer.MeasureBounds("\t\t", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWithXWidth = TextMeasurer.MeasureBounds("\t\tx", new RendererOptions(font, (72 * font.EmSize)));
Assert.Equal(tabWidth.Width + xWidth.Width, tabWithXWidth.Width, 2);
}
@ -33,9 +33,9 @@ namespace SixLabors.Fonts.Tests.Issues
public void TwoTabsAreDoubleWidthOfOneTab()
{
Font font = CreateFont("\t x");
var xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
var tabWidth = TextMeasurer.MeasureBounds("\t", new RendererOptions(font, (72 * font.EmSize)));
var twoTabWidth = TextMeasurer.MeasureBounds("\t\t", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWidth = TextMeasurer.MeasureBounds("\t", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle twoTabWidth = TextMeasurer.MeasureBounds("\t\t", new RendererOptions(font, (72 * font.EmSize)));
Assert.Equal(twoTabWidth.Width, tabWidth.Width * 2, 2);
}
@ -45,16 +45,16 @@ namespace SixLabors.Fonts.Tests.Issues
public void TwoTabsAreDoubleWidthOfOneTabMinusXWidth()
{
Font font = CreateFont("\t x");
var xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
var tabWidth = TextMeasurer.MeasureBounds("\tx", new RendererOptions(font, (72 * font.EmSize)));
var twoTabWidth = TextMeasurer.MeasureBounds("\t\tx", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWidth = TextMeasurer.MeasureBounds("\tx", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle twoTabWidth = TextMeasurer.MeasureBounds("\t\tx", new RendererOptions(font, (72 * font.EmSize)));
Assert.Equal(twoTabWidth.Width - xWidth.Width, (tabWidth.Width - xWidth.Width) * 2, 2);
}
public static Font CreateFont(string text)
{
FontCollection fc = new FontCollection();
var fc = new FontCollection();
Font d = fc.Install(new FakeFontInstance(text)).CreateFont(12);
return new Font(d, 1);
}

Просмотреть файл

@ -16,9 +16,9 @@ namespace SixLabors.Fonts.Tests.Issues
{
Font font = CreateFont("\t x");
var tabWidth = TextMeasurer.MeasureBounds("\t", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWidth = TextMeasurer.MeasureBounds("\t", new RendererOptions(font, (72 * font.EmSize)));
string tabString = "".PadRight(tabCount, '\t');
var tabCountWidth = TextMeasurer.MeasureBounds(tabString, new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabCountWidth = TextMeasurer.MeasureBounds(tabString, new RendererOptions(font, (72 * font.EmSize)));
Assert.Equal(tabWidth.Width * tabCount, tabCountWidth.Width, 2);
}
@ -33,10 +33,10 @@ namespace SixLabors.Fonts.Tests.Issues
{
Font font = CreateFont("\t x");
var xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
var tabWidth = TextMeasurer.MeasureBounds("\tx", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle xWidth = TextMeasurer.MeasureBounds("x", new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabWidth = TextMeasurer.MeasureBounds("\tx", new RendererOptions(font, (72 * font.EmSize)));
string tabString = "x".PadLeft(tabCount + 1, '\t');
var tabCountWidth = TextMeasurer.MeasureBounds(tabString, new RendererOptions(font, (72 * font.EmSize)));
FontRectangle tabCountWidth = TextMeasurer.MeasureBounds(tabString, new RendererOptions(font, (72 * font.EmSize)));
float singleTabWidth = tabWidth.Width - xWidth.Width;
float finalTabWidth = tabCountWidth.Width - xWidth.Width;

Просмотреть файл

@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using SixLabors.Fonts.Tests.Fakes;
using Xunit;
@ -14,7 +15,7 @@ namespace SixLabors.Fonts.Tests.Issues
var r = new GlyphRenderer();
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text, new RendererOptions(new Font(font, 30), 72)
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text.AsSpan(), new RendererOptions(new Font(font, 30), 72)
{
WrappingWidth = 350,
HorizontalAlignment = HorizontalAlignment.Left
@ -42,7 +43,7 @@ namespace SixLabors.Fonts.Tests.Issues
var r = new GlyphRenderer();
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text, new RendererOptions(new Font(font, 30), 72)
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text.AsSpan(), new RendererOptions(new Font(font, 30), 72)
{
WrappingWidth = 350,
HorizontalAlignment = horiAlignment
@ -69,7 +70,7 @@ namespace SixLabors.Fonts.Tests.Issues
var r = new GlyphRenderer();
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text, new RendererOptions(new Font(font, 30), 72)
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text.AsSpan(), new RendererOptions(new Font(font, 30), 72)
{
WrappingWidth = 350
});
@ -87,7 +88,7 @@ namespace SixLabors.Fonts.Tests.Issues
var r = new GlyphRenderer();
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text, new RendererOptions(new Font(font, 30), 72)
IReadOnlyList<GlyphLayout> layout = new TextLayout().GenerateLayout(text.AsSpan(), new RendererOptions(new Font(font, 30), 72)
{
WrappingWidth = 350
});

Просмотреть файл

@ -1,38 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<VersionPrefix>0.0.0</VersionPrefix>
<TargetFrameworks>netcoreapp2.1</TargetFrameworks>
<LangVersion>7.3</LangVersion>
<AssemblyName>SixLabors.Fonts.Tests</AssemblyName>
<PackageId>SixLabors.Fonts.Tests</PackageId>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Description>A cross-platform library for processing of image files written in C#</Description>
<Copyright>Copyright © Scott Williams and contributors.</Copyright>
<DebugType Condition="$(codecov) != ''">full</DebugType>
<TargetFrameworks>netcoreapp3.1;netcoreapp2.1;net472</TargetFrameworks>
<DebugSymbols>True</DebugSymbols>
<Platforms>AnyCPU;x64;x86</Platforms>
</PropertyGroup>
<ItemGroup>
<DotNetCliToolReference Include="dotnet-xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\SixLabors.Fonts\SixLabors.Fonts.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="Moq" Version="4.9.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="Moq" />
<PackageReference Include="System.Numerics.Vectors" />
</ItemGroup>
<PropertyGroup>
<CodeAnalysisRuleSet>..\..\shared-infrastructure\SixLabors.Tests.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\shared-infrastructure\stylecop.json" />
</ItemGroup>
<ItemGroup>
<None Update="Fonts\**\*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>

Просмотреть файл

@ -37,7 +37,7 @@ namespace SixLabors.Fonts.Tests.Tables.General.CMap
[Fact]
public void GetCharacter()
{
Format0SubTable format = new Format0SubTable(0, PlatformIDs.Windows, 2, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
var format = new Format0SubTable(0, PlatformIDs.Windows, 2, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
ushort id = format.GetGlyphId(4);
@ -47,7 +47,7 @@ namespace SixLabors.Fonts.Tests.Tables.General.CMap
[Fact]
public void GetCharacter_missing()
{
Format0SubTable format = new Format0SubTable(0, PlatformIDs.Windows, 2, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
var format = new Format0SubTable(0, PlatformIDs.Windows, 2, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 });
ushort id = format.GetGlyphId(99);

Просмотреть файл

@ -66,7 +66,7 @@ namespace SixLabors.Fonts.Tests.Tables.General.CMap
// idRangeOffset: 0 0 0 0
ushort[] glyphs = Enumerable.Range(0, expected).Select(x => (ushort)x).ToArray();
Format4SubTable table = new Format4SubTable(
var table = new Format4SubTable(
0,
PlatformIDs.Windows,
0,

Просмотреть файл

@ -19,7 +19,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
new Format0SubTable(0, PlatformIDs.Windows, 9, new byte[] { 0, 1, 2 })
});
CMapTable table = CMapTable.Load(writer.GetReader());
var table = CMapTable.Load(writer.GetReader());
Assert.Single(table.Tables.Where(x => x != null));
@ -33,9 +33,9 @@ namespace SixLabors.Fonts.Tests.Tables.General
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader();
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
var exception = Assert.Throws<InvalidFontTableException>(() => CMapTable.Load(new FontReader(stream)));
InvalidFontTableException exception = Assert.Throws<InvalidFontTableException>(() => CMapTable.Load(new FontReader(stream)));
Assert.Equal("cmap", exception.Table);
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
new DateTime(2017, 02, 07, 07, 47, 00),
new Bounds(0, 0, 1024, 1022), 0, HeadTable.IndexLocationFormats.Offset16));
HeadTable head = HeadTable.Load(writer.GetReader());
var head = HeadTable.Load(writer.GetReader());
Assert.Equal(HeadTable.HeadFlags.None, head.Flags);
Assert.Equal(HeadTable.HeadMacStyle.Italic | HeadTable.HeadMacStyle.Bold, head.MacStyle);

Просмотреть файл

@ -13,7 +13,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
writer.WriteHorizontalHeadTable(new HorizontalHeadTable(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
HorizontalHeadTable tbl = HorizontalHeadTable.Load(writer.GetReader());
var tbl = HorizontalHeadTable.Load(writer.GetReader());
Assert.Equal(1, tbl.Ascender);
Assert.Equal(2, tbl.Descender);
@ -34,7 +34,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader();
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
Assert.Null(HorizontalHeadTable.Load(new FontReader(stream)));
}

Просмотреть файл

@ -14,9 +14,9 @@ namespace SixLabors.Fonts.Tests.Tables.General
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader();
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
var exception = Assert.Throws<InvalidFontTableException>(() => IndexLocationTable.Load(new FontReader(stream)));
InvalidFontTableException exception = Assert.Throws<InvalidFontTableException>(() => IndexLocationTable.Load(new FontReader(stream)));
Assert.Equal("head", exception.Table);
}
@ -35,9 +35,9 @@ namespace SixLabors.Fonts.Tests.Tables.General
new DateTime(2017, 02, 07, 07, 47, 00),
new Bounds(0, 0, 1024, 1022), 0, HeadTable.IndexLocationFormats.Offset16));
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
var exception = Assert.Throws<InvalidFontTableException>(() => IndexLocationTable.Load(new FontReader(stream)));
InvalidFontTableException exception = Assert.Throws<InvalidFontTableException>(() => IndexLocationTable.Load(new FontReader(stream)));
Assert.Equal("maxp", exception.Table);
}
@ -56,7 +56,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
new DateTime(2017, 02, 07, 07, 47, 00),
new Bounds(0, 0, 1024, 1022), 0, HeadTable.IndexLocationFormats.Offset16));
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
Assert.Null(IndexLocationTable.Load(new FontReader(stream)));
}

Просмотреть файл

@ -11,7 +11,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader();
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
var table = KerningTable.Load(new FontReader(stream));
Assert.NotNull(table);

Просмотреть файл

@ -12,9 +12,9 @@ namespace SixLabors.Fonts.Tests.Tables.General
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader();
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
var exception = Assert.Throws<InvalidFontTableException>(() => MaximumProfileTable.Load(new FontReader(stream)));
InvalidFontTableException exception = Assert.Throws<InvalidFontTableException>(() => MaximumProfileTable.Load(new FontReader(stream)));
Assert.Equal("maxp", exception.Table);
}

Просмотреть файл

@ -25,7 +25,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
{ (NameIds)91, "other2" }
});
NameTable table = NameTable.Load(writer.GetReader());
var table = NameTable.Load(writer.GetReader());
Assert.Equal("fullname", table.FontName);
Assert.Equal("family", table.FontFamilyName);
@ -56,7 +56,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
"lang2"
});
NameTable table = NameTable.Load(writer.GetReader());
var table = NameTable.Load(writer.GetReader());
Assert.Equal("fullname", table.FontName);
Assert.Equal("family", table.FontFamilyName);
@ -73,9 +73,9 @@ namespace SixLabors.Fonts.Tests.Tables.General
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader();
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
var exception = Assert.Throws<InvalidFontTableException>(() => NameTable.Load(new FontReader(stream)));
InvalidFontTableException exception = Assert.Throws<InvalidFontTableException>(() => NameTable.Load(new FontReader(stream)));
Assert.Equal("name", exception.Table);
}

Просмотреть файл

@ -11,7 +11,7 @@ namespace SixLabors.Fonts.Tests.Tables.General
var writer = new BinaryWriter();
writer.WriteTrueTypeFileHeader();
using (var stream = writer.GetStream())
using (System.IO.MemoryStream stream = writer.GetStream())
{
Assert.Null(OS2Table.Load(new FontReader(stream)));
}

Просмотреть файл

@ -20,7 +20,7 @@ namespace SixLabors.Fonts.Tests.Tables
var writer = new BinaryWriter();
writer.WriteTableHeader(tag, checksum, offset, length);
TableHeader header = TableHeader.Read(writer.GetReader());
var header = TableHeader.Read(writer.GetReader());
Assert.Equal(checksum, header.CheckSum);
Assert.Equal(length, header.Length);

Просмотреть файл

@ -30,7 +30,7 @@ namespace SixLabors.Fonts.Tests.Tables
[MemberData(nameof(RegisterableTableTypes))]
public void AllNamedTablesAreRegistered(Type type, string name)
{
TableLoader tl = new TableLoader();
var tl = new TableLoader();
Assert.Contains(type, tl.RegisterdTypes());
Assert.Equal(name, tl.GetTag(type));
}
@ -44,7 +44,7 @@ namespace SixLabors.Fonts.Tests.Tables
[Fact]
public void TryingToLoadUnregisteredTagReturnsUnknownTable()
{
TableLoader loader = new TableLoader();
var loader = new TableLoader();
string tag = Guid.NewGuid().ToString();
Table result = loader.Load(tag, null);
@ -57,7 +57,7 @@ namespace SixLabors.Fonts.Tests.Tables
[Fact]
public void NullForUnknownTypes()
{
TableLoader loader = new TableLoader();
var loader = new TableLoader();
string tag = loader.GetTag(typeof(TableLoaderTests));
Assert.Null(tag);
}

Просмотреть файл

@ -51,7 +51,7 @@ namespace SixLabors.Fonts.Tests
private static Stream Clone(this Stream src)
{
MemoryStream ms = new MemoryStream();
var ms = new MemoryStream();
src.Position = 0;
src.CopyTo(ms);
ms.Position = 0;

Просмотреть файл

@ -77,7 +77,7 @@ namespace SixLabors.Fonts.Tests
VerticalAlignment = vertical
};
IReadOnlyList<GlyphLayout> glyphsToRender = new TextLayout().GenerateLayout(text, span);
IReadOnlyList<GlyphLayout> glyphsToRender = new TextLayout().GenerateLayout(text.AsSpan(), span);
IFontInstance fontInst = span.Font.Instance;
float lineHeight = (fontInst.LineHeight * span.Font.Size) / (fontInst.EmSize * 72);
lineHeight *= scaleFactor;
@ -93,13 +93,13 @@ namespace SixLabors.Fonts.Tests
[Fact]
public unsafe void MeasureTextWithSpan()
{
var font = CreateFont("hello");
Font font = CreateFont("hello");
Span<char> text = stackalloc char[] { 'h', 'e', 'l', 'l', 'o' };
int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px
var size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize));
FontRectangle size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize));
Assert.Equal(10, size.Height, 4);
Assert.Equal(130, size.Width, 4);
@ -118,7 +118,7 @@ namespace SixLabors.Fonts.Tests
Font font = CreateFont(text);
int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px
var size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize));
FontRectangle size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize));
Assert.Equal(height, size.Height, 4);
Assert.Equal(width, size.Width, 4);
@ -138,7 +138,7 @@ namespace SixLabors.Fonts.Tests
Font font = CreateFont(text);
int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px
Assert.True(TextMeasurer.TryMeasureCharacterBounds(text, new RendererOptions(font, 72 * font.EmSize), out GlyphMetric[] glyphMetrics));
Assert.True(TextMeasurer.TryMeasureCharacterBounds(text.AsSpan(), new RendererOptions(font, 72 * font.EmSize), out GlyphMetric[] glyphMetrics));
Assert.Equal(text.Length, glyphMetrics.Length);
for (int i = 0; i < glyphMetrics.Length; i++)
@ -165,7 +165,7 @@ namespace SixLabors.Fonts.Tests
Font font = CreateFont(text);
int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px
var size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize)
FontRectangle size = TextMeasurer.MeasureBounds(text, new RendererOptions(font, 72 * font.EmSize)
{
WrappingWidth = 350
});
@ -181,11 +181,11 @@ namespace SixLabors.Fonts.Tests
[InlineData("AB", 465, 654, true)]
public void MeasureTextWithKerning(string text, float height, float width, bool enableKerning)
{
FontCollection c = new FontCollection();
var c = new FontCollection();
Font font = c.Install(TestFonts.SimpleFontFileData()).CreateFont(12);
int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px
var size = TextMeasurer.MeasureBounds(text, new RendererOptions(new Font(font, 1), 72 * font.EmSize) { ApplyKerning = enableKerning });
FontRectangle size = TextMeasurer.MeasureBounds(text, new RendererOptions(new Font(font, 1), 72 * font.EmSize) { ApplyKerning = enableKerning });
Assert.Equal(height, size.Height, 4);
Assert.Equal(width, size.Width, 4);
@ -195,7 +195,7 @@ namespace SixLabors.Fonts.Tests
[InlineData("a", 100, 100, 125, 452)]
public void LayoutWithLocation(string text, float x, float y, float expectedX, float expectedY)
{
FontCollection c = new FontCollection();
var c = new FontCollection();
Font font = c.Install(TestFonts.SimpleFontFileData()).CreateFont(12);
int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px

Просмотреть файл

@ -125,7 +125,7 @@ namespace SixLabors.Fonts.Tests
// Offset16 | offset | String offset from start of storage area(in bytes).
Encoding encoding = Encoding.BigEndianUnicode; // this is Unicode2
int stringOffset = 0;
List<int> offsets = new List<int>();
var offsets = new List<int>();
foreach (KeyValuePair<NameIds, string> n in names)
{
writer.WriteUInt16(0); // hard code platform
@ -421,7 +421,7 @@ namespace SixLabors.Fonts.Tests
writer.WriteUInt16((ushort)table.Flags);
writer.WriteUInt16(table.UnitsPerEm);
DateTime startDate = new DateTime(1904, 01, 01, 0, 0, 0, DateTimeKind.Utc);
var startDate = new DateTime(1904, 01, 01, 0, 0, 0, DateTimeKind.Utc);
writer.WriteInt64((long)table.Created.Subtract(startDate).TotalSeconds);
writer.WriteInt64((long)table.Modified.Subtract(startDate).TotalSeconds);
writer.WriteInt16((short)table.Bounds.Min.X);