зеркало из https://github.com/SixLabors/Fonts.git
migrate to github actions and fix warnings
This commit is contained in:
Родитель
122bb27135
Коммит
aa7b7313fd
|
@ -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
|
||||
|
|
|
@ -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!
|
|
@ -0,0 +1 @@
|
|||
open_collective: imagesharp
|
|
@ -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
|
|
@ -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! -->
|
|
@ -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
|
|
@ -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! -->
|
|
@ -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
|
|
@ -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>
|
|
@ -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}"
|
||||
|
|
29
appveyor.yml
29
appveyor.yml
|
@ -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
|
17
build.cmd
17
build.cmd
|
@ -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
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 }
|
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -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 Apple’s 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 Apple’s 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 don’t 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 don’t 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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче