diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..a76991f76 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,84 @@ +name: Build + +on: [push, pull_request, workflow_dispatch] + +env: + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_NOLOGO: true + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + NuGetDirectory: ${{ github.workspace }}/nuget + +defaults: + run: + shell: pwsh + +jobs: + build: + name: ${{ matrix.platform.name }} ${{ matrix.dotnet.name }} + runs-on: ${{ matrix.platform.os }} + permissions: + id-token: write + + strategy: + fail-fast: false + matrix: + platform: + - { name: Windows x64, os: windows-2025 } + - { name: Ubuntu x64, os: ubuntu-24.04 } + - { name: macOS arm64, os: macos-15 } + dotnet: + - { name: .NET 8, version: '8.0.x' } + - { name: .NET 9, version: '9.0.x' } + - { name: .NET 10, version: '10.0.x' } + + steps: + - name: Checkout HTML Renderer + uses: actions/checkout@v6 + + - name: Setup .NET ${{ matrix.dotnet.version }} SDK + id: setup-dotnet + uses: actions/setup-dotnet@v5 + with: + dotnet-version: ${{ matrix.dotnet.version }} + - name: Enforce SDK Version + run: dotnet new globaljson --sdk-version ${{ steps.setup-dotnet.outputs.dotnet-version }} --force + - name: Verify SDK Installation + run: dotnet --info + + - name: Restore Dependencies + run: dotnet restore Source/HtmlRenderer.sln + + - name: Build + run: dotnet build Source/HtmlRenderer.sln --configuration Release --no-restore + + - name: Create HtmlRenderer.Core NuGet package + run: dotnet pack Source/HtmlRenderer/HtmlRenderer.csproj --configuration Release --include-symbols -p:SymbolPackageFormat=snupkg --no-build --verbosity normal --output ${{ env.NuGetDirectory }} + + - name: Create HtmlRenderer.PdfSharp NuGet package + run: dotnet pack Source/HtmlRenderer.PdfSharp/HtmlRenderer.PdfSharp.csproj --configuration Release --include-symbols -p:SymbolPackageFormat=snupkg --no-build --verbosity normal --output ${{ env.NuGetDirectory }} + + - name: Create HtmlRenderer.WinForms NuGet package + run: dotnet pack Source/HtmlRenderer.WinForms/HtmlRenderer.WinForms.csproj --configuration Release --include-symbols -p:SymbolPackageFormat=snupkg --no-build --verbosity normal --output ${{ env.NuGetDirectory }} + + - name: Create HtmlRenderer.WPF NuGet package + run: dotnet pack Source/HtmlRenderer.WPF/HtmlRenderer.WPF.csproj --configuration Release --include-symbols -p:SymbolPackageFormat=snupkg --no-build --verbosity normal --output ${{ env.NuGetDirectory }} + + - name: Upload NuGet package artifacts + uses: actions/upload-artifact@v5 + with: + name: "HTML Renderer (${{ matrix.platform.name }} ${{ matrix.dotnet.name }})" + path: ${{ env.NuGetDirectory }}/*.*nupkg + + - name: NuGet Login + if: startsWith(github.ref, 'refs/tags/') && matrix.dotnet.name == '.NET 8' && runner.os == 'Windows' + uses: NuGet/login@v1 + id: login + with: + user: eXpl0it3r + + - name: NuGet Push + if: startsWith(github.ref, 'refs/tags/') && matrix.dotnet.name == '.NET 8' && runner.os == 'Windows' + run: | + foreach ($file in (Get-ChildItem ${{ env.NuGetDirectory }} -Recurse -Include *.*nupkg)) { + dotnet nuget push $file --skip-duplicate --api-key ${{steps.login.outputs.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json + } diff --git a/.gitignore b/.gitignore index ce3a150ad..ec0fb2754 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ x64/ *.vspscc *.vssscc .builds +.vs/ # Visual C++ cache files ipch/ diff --git a/Build/0 full.bat b/Build/0 full.bat deleted file mode 100644 index cd285a2bf..000000000 --- a/Build/0 full.bat +++ /dev/null @@ -1,57 +0,0 @@ -@echo off - -CD %~dp0 - - -echo. -echo. -echo - DELETE RELEASE FOLDER.. -rmdir Release /s /q - -echo. -echo. -echo - RUN LIBS BUILD... -echo. -CALL "1 build libs.bat" - -echo. -echo. -echo - RUN DEMO BUILD... -echo. -CALL "2 build demo.bat" - -echo. -echo. -set /p ask=- Builds complete, continue? (y/n) -if %ask%==n goto end - -echo. -echo. -echo - RUN ARCHIVE... -echo. -CALL "3 archive.bat" - -echo. -echo. -echo - RUN NUGET PACK... -echo. -CALL "4 pack nuget.bat" - - -echo. -echo. -echo - REMOVE FILES... -rmdir Release\Source /s /q -rmdir Release\Core /s /q -rmdir Release\WinForms /s /q -rmdir Release\WPF /s /q -rmdir Release\Mono /s /q -rmdir Release\PdfSharp /s /q -del "Release\*.exe" - - -:end -echo. -echo. -echo - FINISHED -pause \ No newline at end of file diff --git a/Build/1 build libs.bat b/Build/1 build libs.bat deleted file mode 100644 index 55b848afd..000000000 --- a/Build/1 build libs.bat +++ /dev/null @@ -1,103 +0,0 @@ -@echo off - -CD %~dp0 - -echo Set params... -set verb=/verbosity:minimal - -set msbuild=C:\Windows\Microsoft.Net\Framework\v4.0.30319\MSBuild.exe - -set c_proj=..\Source\HtmlRenderer\HtmlRenderer.csproj -set wf_proj=..\Source\HtmlRenderer.WinForms\HtmlRenderer.WinForms.csproj -set wpf_proj=..\Source\HtmlRenderer.WPF\HtmlRenderer.WPF.csproj -set pdfs_proj=..\Source\HtmlRenderer.PdfSharp\HtmlRenderer.PdfSharp.csproj - -set c_rel=Release\Core -set wf_rel=Release\WinForms -set wpf_rel=Release\WPF -set mono_rel=Release\Mono -set pdfs_rel=Release\PdfSharp - -set c_out=..\..\Build\%c_rel% -set wf_out=..\..\Build\%wf_rel% -set wpf_out=..\..\Build\%wpf_rel% -set mono_out=..\..\Build\%mono_rel% -set pdfs_out=..\..\Build\%pdfs_rel% - -set t_20=Configuration=Release;TargetFrameworkVersion=v2.0 -set t_30=Configuration=Release;TargetFrameworkVersion=v3.0 -set t_35=Configuration=Release;TargetFrameworkVersion=v3.5;TargetFrameworkProfile=client -set t_40=Configuration=Release;TargetFrameworkVersion=v4.0;TargetFrameworkProfile=client -set t_45=Configuration=Release;TargetFrameworkVersion=v4.5 - -set t_mono_20=%t_20%;DefineConstants=MONO -set t_mono_35=%t_35%;DefineConstants=MONO -set t_mono_40=%t_40%;DefineConstants=MONO -set t_mono_45=%t_45%;DefineConstants=MONO - - -echo. -echo. -echo - BUILD Core... -echo. -%msbuild% %c_proj% /t:rebuild /p:%t_20%;OutputPath=%c_out%\NET20 %verb% -%msbuild% %c_proj% /t:rebuild /p:%t_30%;OutputPath=%c_out%\NET30 %verb% -%msbuild% %c_proj% /t:rebuild /p:%t_35%;OutputPath=%c_out%\NET35 %verb% -%msbuild% %c_proj% /t:rebuild /p:%t_40%;OutputPath=%c_out%\NET40 %verb% -%msbuild% %c_proj% /t:rebuild /p:%t_45%;OutputPath=%c_out%\NET45 %verb% - -echo. -echo. -echo - BUILD WinForms... -echo. -%msbuild% %wf_proj% /t:rebuild /p:%t_20%;OutputPath=%wf_out%_t\NET20 %verb% -%msbuild% %wf_proj% /t:rebuild /p:%t_35%;OutputPath=%wf_out%_t\NET35 %verb% -%msbuild% %wf_proj% /t:rebuild /p:%t_40%;OutputPath=%wf_out%_t\NET40 %verb% -%msbuild% %wf_proj% /t:rebuild /p:%t_45%;OutputPath=%wf_out%_t\NET45 %verb% -xcopy %wf_rel%_t\NET20\HtmlRenderer.WinForms.* %wf_rel%\NET20 /I -xcopy %wf_rel%_t\NET35\HtmlRenderer.WinForms.* %wf_rel%\NET35 /I -xcopy %wf_rel%_t\NET40\HtmlRenderer.WinForms.* %wf_rel%\NET40 /I -xcopy %wf_rel%_t\NET45\HtmlRenderer.WinForms.* %wf_rel%\NET45 /I -rmdir %wf_rel%_t /s /q - -echo. -echo. -echo - BUILD WPF... -echo. -%msbuild% %wpf_proj% /t:rebuild /p:%t_30%;OutputPath=%wpf_out%_t\NET30 %verb% -%msbuild% %wpf_proj% /t:rebuild /p:%t_35%;OutputPath=%wpf_out%_t\NET35 %verb% -%msbuild% %wpf_proj% /t:rebuild /p:%t_40%;OutputPath=%wpf_out%_t\NET40 %verb% -%msbuild% %wpf_proj% /t:rebuild /p:%t_45%;OutputPath=%wpf_out%_t\NET45 %verb% -xcopy %wpf_rel%_t\NET30\HtmlRenderer.WPF.* %wpf_rel%\NET30 /I -xcopy %wpf_rel%_t\NET35\HtmlRenderer.WPF.* %wpf_rel%\NET35 /I -xcopy %wpf_rel%_t\NET40\HtmlRenderer.WPF.* %wpf_rel%\NET40 /I -xcopy %wpf_rel%_t\NET45\HtmlRenderer.WPF.* %wpf_rel%\NET45 /I -rmdir %wpf_rel%_t /s /q - -echo. -echo. -echo - BUILD Mono... -echo. -%msbuild% %wf_proj% /t:rebuild /p:%t_mono_20%;OutputPath=%mono_out%_t\NET20 %verb% -%msbuild% %wf_proj% /t:rebuild /p:%t_mono_35%;OutputPath=%mono_out%_t\NET35 %verb% -%msbuild% %wf_proj% /t:rebuild /p:%t_mono_40%;OutputPath=%mono_out%_t\NET40 %verb% -%msbuild% %wf_proj% /t:rebuild /p:%t_mono_45%;OutputPath=%mono_out%_t\NET45 %verb% -xcopy %mono_rel%_t\NET20\HtmlRenderer.WinForms.* %mono_rel%\NET20 /I -xcopy %mono_rel%_t\NET35\HtmlRenderer.WinForms.* %mono_rel%\NET35 /I -xcopy %mono_rel%_t\NET40\HtmlRenderer.WinForms.* %mono_rel%\NET40 /I -xcopy %mono_rel%_t\NET45\HtmlRenderer.WinForms.* %mono_rel%\NET45 /I -rmdir %mono_rel%_t /s /q - -echo. -echo. -echo - BUILD PdfSharp... -echo. -%msbuild% %pdfs_proj% /t:rebuild /p:%t_20%;OutputPath=%pdfs_out%_t\NET20 %verb% -%msbuild% %pdfs_proj% /t:rebuild /p:%t_35%;OutputPath=%pdfs_out%_t\NET35 %verb% -%msbuild% %pdfs_proj% /t:rebuild /p:%t_40%;OutputPath=%pdfs_out%_t\NET40 %verb% -%msbuild% %pdfs_proj% /t:rebuild /p:%t_45%;OutputPath=%pdfs_out%_t\NET45 %verb% -xcopy %pdfs_rel%_t\NET20\HtmlRenderer.PdfSharp.* %pdfs_rel%\NET20 /I -xcopy %pdfs_rel%_t\NET35\HtmlRenderer.PdfSharp.* %pdfs_rel%\NET35 /I -xcopy %pdfs_rel%_t\NET40\HtmlRenderer.PdfSharp.* %pdfs_rel%\NET40 /I -xcopy %pdfs_rel%_t\NET45\HtmlRenderer.PdfSharp.* %pdfs_rel%\NET45 /I -rmdir %pdfs_rel%_t /s /q \ No newline at end of file diff --git a/Build/2 build demo.bat b/Build/2 build demo.bat deleted file mode 100644 index 61310b3f7..000000000 --- a/Build/2 build demo.bat +++ /dev/null @@ -1,36 +0,0 @@ -@echo off - -CD %~dp0 - -set verb=/verbosity:minimal -set msbuild=C:\Windows\Microsoft.Net\Framework\v4.0.30319\MSBuild.exe - -set t_20=Configuration=Release;TargetFrameworkVersion=v2.0 -set t_40=Configuration=Release;TargetFrameworkVersion=v4.0;TargetFrameworkProfile=client -set t_mono_20=%t_20%;DefineConstants=MONO - -echo. -echo. -echo - BUILD WinForms... -echo. -%msbuild% ..\Source\Demo\WinForms\HtmlRenderer.Demo.WinForms.csproj /t:rebuild /p:%t_20%;OutputPath=..\..\..\Build\Release\Demo\WinForms %verb% - -echo. -echo. -echo - BUILD Mono... -echo. - -%msbuild% ..\Source\Demo\WinForms\HtmlRenderer.Demo.WinForms.csproj /t:rebuild /p:%t_mono_20%;OutputPath=..\..\..\Build\Release\Demo\Mono %verb% - -echo. -echo. -echo - BUILD WPF... -echo. -%msbuild% ..\Source\Demo\WPF\HtmlRenderer.Demo.WPF.csproj /t:rebuild /p:%t_40%;OutputPath=..\..\..\Build\Release\Demo\WPF %verb% - -echo. -echo - Handle outputs... -copy Release\Demo\WinForms\HtmlRendererWinFormsDemo.exe "Release\HtmlRenderer WinForms Demo.exe" -copy Release\Demo\Mono\HtmlRendererWinFormsDemo.exe "Release\HtmlRenderer Mono Demo.exe" -copy Release\Demo\WPF\HtmlRendererWpfDemo.exe "Release\HtmlRenderer WPF Demo.exe" -rmdir Release\Demo /s /q diff --git a/Build/3 archive.bat b/Build/3 archive.bat deleted file mode 100644 index 033aac66a..000000000 --- a/Build/3 archive.bat +++ /dev/null @@ -1,24 +0,0 @@ -@echo off - -CD %~dp0 - -echo. -echo - Get version... -for /f %%i in ('getVer.exe ..\Source\SharedAssemblyInfo.cs') do set version=%%i -echo Version: %version% - -echo. -echo. -echo - Git clone... -echo. -"C:\Program Files (x86)\Git\bin\git.exe" clone -q --branch=v1.5 https://github.com/ArthurHub/HTML-Renderer.git Release\git -xcopy Release\git\Source Release\Source /I /E -rmdir Release\git /s /q - -echo. -echo. -echo - Create archive... -echo. -cd Release -..\7za.exe a "HtmlRenderer %version%.zip" ** -cd.. diff --git a/Build/4 pack nuget.bat b/Build/4 pack nuget.bat deleted file mode 100644 index d934fd303..000000000 --- a/Build/4 pack nuget.bat +++ /dev/null @@ -1,18 +0,0 @@ -@echo off - -CD %~dp0 - -echo. -echo - Get version... -for /f %%i in ('getVer.exe ..\Source\SharedAssemblyInfo.cs') do set version=%%i -echo Version: %version% - -echo. -echo. -echo - Pack NuGets... -echo. -nuget.exe pack NuGet\HtmlRenderer.Core.nuspec -Version %version% -OutputDirectory Release -nuget.exe pack NuGet\HtmlRenderer.WinForms.nuspec -Version %version% -OutputDirectory Release -nuget.exe pack NuGet\HtmlRenderer.WPF.nuspec -Version %version% -OutputDirectory Release -nuget.exe pack NuGet\HtmlRenderer.Mono.nuspec -Version %version% -OutputDirectory Release -nuget.exe pack NuGet\HtmlRenderer.PdfSharp.nuspec -Version %version% -OutputDirectory Release \ No newline at end of file diff --git a/Build/7za.exe b/Build/7za.exe deleted file mode 100644 index 7f6bf86bc..000000000 Binary files a/Build/7za.exe and /dev/null differ diff --git a/Build/NuGet.exe b/Build/NuGet.exe deleted file mode 100644 index 3ffdd33c6..000000000 Binary files a/Build/NuGet.exe and /dev/null differ diff --git a/Build/NuGet/HtmlRenderer.Core.nuspec b/Build/NuGet/HtmlRenderer.Core.nuspec deleted file mode 100644 index 25e8783ea..000000000 --- a/Build/NuGet/HtmlRenderer.Core.nuspec +++ /dev/null @@ -1,38 +0,0 @@ - - - - HtmlRenderer.Core - 0.0.0.1 - HTML Renderer Core - Arthur Teplitzki - Arthur Teplitzki - https://htmlrenderer.codeplex.com/license - https://htmlrenderer.codeplex.com/ - https://github.com/ArthurHub/HTML-Renderer/blob/master/html.ico?raw=true - false - - Cross framework (WinForms/WPF/PDF/Metro/Mono/etc.), Multipurpose (UI Controls / Image generation / PDF generation / etc.), 100% managed (C#), High performance HTML Rendering library. - - - Cross framework (WinForms/WPF/PDF/Metro/Mono/etc.), Multipurpose (UI Controls / Image generation / PDF generation / etc.), 100% managed (C#), High performance HTML Rendering library. - - The Core assembly of HTML Renderer does not bound to any rendering framework (WinForms/WPF/PDF/etc.). - Can be used to create framework specific renderer using adapter extensibility object model. - For existing implementations see: HtmlRenderer.WinForms, HtmlRenderer.WPF and HtmlRenderer.PdfSharp. - - See http://htmlrenderer.codeplex.com/releases. - html render renderer draw core - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Build/NuGet/HtmlRenderer.Mono.nuspec b/Build/NuGet/HtmlRenderer.Mono.nuspec deleted file mode 100644 index 03777c77b..000000000 --- a/Build/NuGet/HtmlRenderer.Mono.nuspec +++ /dev/null @@ -1,56 +0,0 @@ - - - - HtmlRenderer.Mono - 0.0.0.1 - HTML Renderer for Mono - Arthur Teplitzki - Arthur Teplitzki - https://htmlrenderer.codeplex.com/license - https://htmlrenderer.codeplex.com/ - https://github.com/ArthurHub/HTML-Renderer/blob/master/html.ico?raw=true - false - - Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for Mono. - - - Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for Mono. - - HTML UI in .NET Mono applications using controls or static rendering. - - Features and Benefits: - --- - * Controls: HtmlPanel, HtmlLabel, HtmlToolTip. - * Create images from HTML snippets. - * 100% managed code and no external dependencies, no ActiveX, no MSHTML. - * Extensive HTML 4.01 and CSS level 2 specifications support. - * Support separating CSS from HTML by loading stylesheet code separately. - * Support text selection, copy-paste and context menu. - * Handles "real world" malformed HTML, it doesn't have to be XHTML. - * Supports .NET 2.0 or higher including Client Profile. - * Lightweight, only two DLLs (~300K). - * High performance and low memory footprint. - * Extendable and configurable. - - See http://htmlrenderer.codeplex.com/releases. - html render renderer draw control winforms mono - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Build/NuGet/HtmlRenderer.Mono.readme.txt b/Build/NuGet/HtmlRenderer.Mono.readme.txt deleted file mode 100644 index 81bc1c0d2..000000000 --- a/Build/NuGet/HtmlRenderer.Mono.readme.txt +++ /dev/null @@ -1,50 +0,0 @@ - -********** Welcome to the HTML Renderer WinForms library! ***************************************** - -This library provides the rich formatting power of HTML in Mono .NET applications using -simple controls or static rendering code. -For more info see HTML Renderer on CodePlex: http://htmlrenderer.codeplex.com - -********** DEMO APPLICATION *********************************************************************** - -HTML Renderer Demo application showcases HTML Renderer capabilities, use it to explore and learn -on the library: http://htmlrenderer.codeplex.com/wikipage?title=Demo%20application - -********** FEEDBACK / RELEASE NOTES *************************************************************** - -If you have problems, wish to report a bug, or have a suggestion please start a thread on -HTML Renderer discussions page: http://htmlrenderer.codeplex.com/discussions - -For full release notes and all versions see: http://htmlrenderer.codeplex.com/releases - -********** QUICK START **************************************************************************** - -For more Quick Start see: https://htmlrenderer.codeplex.com/wikipage?title=Quick%20start - -*************************************************************************************************** -********** Quick Start: Use HTML panel control on WinForms form - -public partial class Form1 : Form -{ - public Form1() - { - InitializeComponent(); - - TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel htmlPanel = new TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel(); - htmlPanel.Text = "

Hello World

This is html rendered text

"; - htmlPanel.Dock = DockStyle.Fill; - Controls.Add(htmlPanel); - } -} - -*************************************************************************************************** -********** Quick Start: Create image from HTML snippet - -class Program -{ - private static void Main(string[] args) - { - Image image = TheArtOfDev.HtmlRenderer.WinForms.HtmlRender.RenderToImageGdiPlus("

Hello World

This is html rendered text

"); - image.Save("image.png", ImageFormat.Png); - } -} diff --git a/Build/NuGet/HtmlRenderer.PdfSharp.nuspec b/Build/NuGet/HtmlRenderer.PdfSharp.nuspec deleted file mode 100644 index d080a26d2..000000000 --- a/Build/NuGet/HtmlRenderer.PdfSharp.nuspec +++ /dev/null @@ -1,52 +0,0 @@ - - - - HtmlRenderer.PdfSharp - 0.0.0.1 - HTML Renderer for PDF using PdfSharp - Arthur Teplitzki - Arthur Teplitzki - https://htmlrenderer.codeplex.com/license - https://htmlrenderer.codeplex.com/ - https://github.com/ArthurHub/HTML-Renderer/blob/master/html.ico?raw=true - false - - PDF document generator from HTML snippet, 100% managed (C#), High performance library using PdfSharp. - - - PDF document generator from HTML snippet, 100% managed (C#), High performance library using PdfSharp. - - Features and Benefits: - --- - * 100% managed code depends only on PdfSharp library, no ActiveX, no MSHTML. - * Extensive HTML 4.01 and CSS level 2 specifications support. - * Support separating CSS from HTML by loading stylesheet code separately. - * Handles "real world" malformed HTML, it doesn't have to be XHTML. - * Supports .NET 2.0 or higher including Client Profile. - * Lightweight, only two DLLs (~300K). - * High performance and low memory footprint. - * Extendable and configurable. - - See http://htmlrenderer.codeplex.com/releases. - html render renderer draw pdfsharp - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Build/NuGet/HtmlRenderer.PdfSharp.readme.txt b/Build/NuGet/HtmlRenderer.PdfSharp.readme.txt deleted file mode 100644 index 97a66b14d..000000000 --- a/Build/NuGet/HtmlRenderer.PdfSharp.readme.txt +++ /dev/null @@ -1,33 +0,0 @@ - -********** Welcome to the HTML Renderer PdfSharp library! ***************************************** - -This library provides the ability to generate PDF documents from HTML snippets using static rendering code. -For more info see HTML Renderer on CodePlex: http://htmlrenderer.codeplex.com - -********** DEMO APPLICATION *********************************************************************** - -HTML Renderer Demo application showcases HTML Renderer capabilities, use it to explore and learn -on the library: http://htmlrenderer.codeplex.com/wikipage?title=Demo%20application - -********** FEEDBACK / RELEASE NOTES *************************************************************** - -If you have problems, wish to report a bug, or have a suggestion please start a thread on -HTML Renderer discussions page: http://htmlrenderer.codeplex.com/discussions - -For full release notes and all versions see: http://htmlrenderer.codeplex.com/releases - -********** QUICK START **************************************************************************** - -For more Quick Start see: https://htmlrenderer.codeplex.com/wikipage?title=Quick%20start - -*************************************************************************************************** -********** Quick Start: Create PDF from HTML snippet using PdfSharp - -class Program -{ - private static void Main(string[] args) - { - PdfDocument pdf = PdfGenerator.GeneratePdf("

Hello World

This is html rendered text

", PageSize.A4); - pdf.Save("document.pdf"); - } -} diff --git a/Build/NuGet/HtmlRenderer.WPF.nuspec b/Build/NuGet/HtmlRenderer.WPF.nuspec deleted file mode 100644 index f8ea88317..000000000 --- a/Build/NuGet/HtmlRenderer.WPF.nuspec +++ /dev/null @@ -1,56 +0,0 @@ - - - - HtmlRenderer.WPF - 0.0.0.1 - HTML Renderer for WPF - Arthur Teplitzki - Arthur Teplitzki - https://htmlrenderer.codeplex.com/license - https://htmlrenderer.codeplex.com/ - https://github.com/ArthurHub/HTML-Renderer/blob/master/html.ico?raw=true - false - - Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WPF. - - - Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WPF. - - HTML UI in .NET WPF applications using controls or static rendering. - - Features and Benefits: - --- - * Controls: HtmlPanel, HtmlLabel. - * Create images from HTML snippets. - * 100% managed code and no external dependencies, no ActiveX, no MSHTML. - * Extensive HTML 4.01 and CSS level 2 specifications support. - * Support separating CSS from HTML by loading stylesheet code separately. - * Support text selection, copy-paste and context menu. - * Handles "real world" malformed HTML, it doesn't have to be XHTML. - * Supports .NET 3.0 or higher including Client Profile. - * Lightweight, only two DLLs (~300K). - * High performance and low memory footprint. - * Extendable and configurable. - - See http://htmlrenderer.codeplex.com/releases. - html render renderer draw control WPF - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Build/NuGet/HtmlRenderer.WPF.readme.txt b/Build/NuGet/HtmlRenderer.WPF.readme.txt deleted file mode 100644 index 6d858ea66..000000000 --- a/Build/NuGet/HtmlRenderer.WPF.readme.txt +++ /dev/null @@ -1,50 +0,0 @@ - -********** Welcome to the HTML Renderer WPF library! ********************************************** - -This library provides the rich formatting power of HTML in your WPF .NET applications using -simple controls or static rendering code. -For more info see HTML Renderer on CodePlex: http://htmlrenderer.codeplex.com - -********** DEMO APPLICATION *********************************************************************** - -HTML Renderer Demo application showcases HTML Renderer capabilities, use it to explore and learn -on the library: http://htmlrenderer.codeplex.com/wikipage?title=Demo%20application - -********** FEEDBACK / RELEASE NOTES *************************************************************** - -If you have problems, wish to report a bug, or have a suggestion please start a thread on -HTML Renderer discussions page: http://htmlrenderer.codeplex.com/discussions - -For full release notes and all versions see: http://htmlrenderer.codeplex.com/releases - -********** QUICK START **************************************************************************** - -For more Quick Start see: https://htmlrenderer.codeplex.com/wikipage?title=Quick%20start - -*************************************************************************************************** -********** Quick Start: Use HTML panel control on WPF window - - - - - - - -*************************************************************************************************** -********** Quick Start: Create image from HTML snippet - -class Program -{ - private static void Main(string[] args) - { - BitmapFrame image = HtmlRender.RenderToImage("

Hello World

This is html rendered text

"); - var encoder = new PngBitmapEncoder(); - encoder.Frames.Add(image); - using (FileStream stream = new FileStream("image.png", FileMode.OpenOrCreate)) - encoder.Save(stream); - } -} diff --git a/Build/NuGet/HtmlRenderer.WinForms.nuspec b/Build/NuGet/HtmlRenderer.WinForms.nuspec deleted file mode 100644 index 66823cf0f..000000000 --- a/Build/NuGet/HtmlRenderer.WinForms.nuspec +++ /dev/null @@ -1,56 +0,0 @@ - - - - HtmlRenderer.WinForms - 0.0.0.1 - HTML Renderer for WinForms - Arthur Teplitzki - Arthur Teplitzki - https://htmlrenderer.codeplex.com/license - https://htmlrenderer.codeplex.com/ - https://github.com/ArthurHub/HTML-Renderer/blob/master/html.ico?raw=true - false - - Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WinForms. - - - Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WinForms. - - HTML UI in .NET WinForms applications using controls or static rendering. - - Features and Benefits: - --- - * Controls: HtmlPanel, HtmlLabel, HtmlToolTip. - * Create images from HTML snippets. - * 100% managed code and no external dependencies, no ActiveX, no MSHTML. - * Extensive HTML 4.01 and CSS level 2 specifications support. - * Support separating CSS from HTML by loading stylesheet code separately. - * Support text selection, copy-paste and context menu. - * Handles "real world" malformed HTML, it doesn't have to be XHTML. - * Supports .NET 2.0 or higher including Client Profile. - * Lightweight, only two DLLs (~300K). - * High performance and low memory footprint. - * Extendable and configurable. - - See http://htmlrenderer.codeplex.com/releases. - html render renderer draw control winforms - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Build/NuGet/HtmlRenderer.WinForms.readme.txt b/Build/NuGet/HtmlRenderer.WinForms.readme.txt deleted file mode 100644 index 8c2fe704b..000000000 --- a/Build/NuGet/HtmlRenderer.WinForms.readme.txt +++ /dev/null @@ -1,50 +0,0 @@ - -********** Welcome to the HTML Renderer WinForms library! ***************************************** - -This library provides the rich formatting power of HTML in your WinForms .NET applications using -simple controls or static rendering code. -For more info see HTML Renderer on CodePlex: http://htmlrenderer.codeplex.com - -********** DEMO APPLICATION *********************************************************************** - -HTML Renderer Demo application showcases HTML Renderer capabilities, use it to explore and learn -on the library: http://htmlrenderer.codeplex.com/wikipage?title=Demo%20application - -********** FEEDBACK / RELEASE NOTES *************************************************************** - -If you have problems, wish to report a bug, or have a suggestion please start a thread on -HTML Renderer discussions page: http://htmlrenderer.codeplex.com/discussions - -For full release notes and all versions see: http://htmlrenderer.codeplex.com/releases - -********** QUICK START **************************************************************************** - -For more Quick Start see: https://htmlrenderer.codeplex.com/wikipage?title=Quick%20start - -*************************************************************************************************** -********** Quick Start: Use HTML panel control on WinForms form - -public partial class Form1 : Form -{ - public Form1() - { - InitializeComponent(); - - TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel htmlPanel = new TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel(); - htmlPanel.Text = "

Hello World

This is html rendered text

"; - htmlPanel.Dock = DockStyle.Fill; - Controls.Add(htmlPanel); - } -} - -*************************************************************************************************** -********** Quick Start: Create image from HTML snippet - -class Program -{ - private static void Main(string[] args) - { - Image image = TheArtOfDev.HtmlRenderer.WinForms.HtmlRender.RenderToImage("

Hello World

This is html rendered text

"); - image.Save("image.png", ImageFormat.Png); - } -} diff --git a/Build/getVer.exe b/Build/getVer.exe deleted file mode 100644 index 4e628a3b4..000000000 Binary files a/Build/getVer.exe and /dev/null differ diff --git a/LICENSE b/LICENSE index ecd7e0153..0041d48b4 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ Copyright (c) 2009, José Manuel Menéndez Poo -Copyright (c) 2013, Arthur Teplitzki +Copyright (c) 2013-2025, Arthur Teplitzki All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/README.md b/README.md index 30a4fa371..f689bdfac 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,33 @@ -HTML Renderer [![Build status](https://ci.appveyor.com/api/projects/status/cm8xpf8ebt3hyi3e)](https://ci.appveyor.com/project/ArthurHub/html-renderer) -============= - -#### Documentation, Discussion and Issue tracking is on [CodePlex](https://htmlrenderer.codeplex.com/). +# HTML Renderer **Cross framework** (WinForms/WPF/PDF/Metro/Mono/etc.), **Multipurpose** (UI Controls / Image generation / PDF generation / etc.), **100% managed** (C#), High performance HTML Rendering library. -The library is 100% managed **C#** code without any external dependencies (no WebBrowser control, ActiveX / COM or MSHTML dll), the only requirement is **.NET 2.0 or higher**. - -#### [Download](https://htmlrenderer.codeplex.com/releases/) the [Demo application](https://htmlrenderer.codeplex.com/wikipage?title=Demo%20application&referringTitle=Home) to explore HTML Renderer capabilities. +The library is 100% managed **C#** code without any external dependencies (no WebBrowser control, ActiveX / COM or MSHTML dll), the only requirement is **.NET Standard 2.0 / .NET 8.0 or higher**. ![Renderer.png](https://raw.githubusercontent.com/ArthurHub/HTML-Renderer/master/Art/demo_winforms.png) -### Features and Benefits + +## Issues & Documentation + +For questions and issues, use the official [GitHub repository](https://github.com/ArthurHub/HTML-Renderer). + +For documentation, check out the project on the [CodePlex Archive](https://codeplexarchive.org/project/HtmlRenderer) or the [personal blog](https://theartofdev.com/tag/html-renderer/). + + +## Download + +The release packages on [GitHub](https://github.com/ArthurHub/HTML-Renderer/releases) or the [CodePlex Archive](https://codeplexarchive.org/project/HtmlRenderer) also contains a Demo application to explore HML Renderer's capabilities. + +The latest NuGet packages can be found on NuGet.org: + +* [HtmlRenderer.WinForms](https://www.nuget.org/packages/HtmlRenderer.WinForms) +* [HtmlRenderer.WPF](https://www.nuget.org/packages/HtmlRenderer.WPF) +* [HtmlRenderer.PdfSharp](https://www.nuget.org/packages/HtmlRenderer.PdfSharp) +* [HtmlRenderer.Core](https://www.nuget.org/packages/HtmlRenderer.Core) + + +## Features and Benefits + * Extensive HTML 4.01 and CSS level 2 specifications support. * Support separating CSS from HTML by loading stylesheet code separately. * Support text selection, copy-paste and context menu. @@ -21,30 +37,23 @@ The library is 100% managed **C#** code without any external dependencies (no We * Create images/PDFs from HTML snippets. * Handles "real world" malformed HTML, it doesn't have to be XHTML. * 100% managed code and no external dependencies. -* Supports .NET 2.0 or higher including Client Profile. * Lightweight, just two DLLs (~300K). * High performance and low memory footprint. * Extendable and configurable. -* Powerful [Demo application](https://htmlrenderer.codeplex.com/wikipage?title=Demo%20application&referringTitle=Home) to explore and learn the library. +* Powerful [Demo application](https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Demo%20application) to explore and learn the library. + + +## WinForms/WPF controls -### WinForms/WPF controls * *HtmlPanel* - The full power of HTML control build to replace WebBrowser control, accepts HTML, text selection, scrollbars, link click intercept, image load intercept and much more. * *HtmlLabel* - As WinForms label but accepts HTML, text selection, auto-size capabilities, transparent background and more. * *HtmlToolTip* - As WinForms ToolTip control but accepts HTML and ability to handle links (WinForms only). -### Sample application's + +## Sample application's + * Render HTML content generated by rich web editors like forums, blogs, etc. * Render Office documents converted to HTML. * Create WinForms UI that requires text selection with clipboard support. -* [Create images from HTML code snippets](https://htmlrenderer.codeplex.com/wikipage?title=Image%20generation&referringTitle=Home). +* [Create images from HTML code snippets](https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Image%20generation). * Create PDF document from HTML code snippets. - -### NuGet packages -* [HtmlRenderer.WinForms](https://www.nuget.org/packages/HtmlRenderer.WinForms) -* [HtmlRenderer.WPF](https://www.nuget.org/packages/HtmlRenderer.WPF) -* [HtmlRenderer.Mono](https://www.nuget.org/packages/HtmlRenderer.Mono) -* [HtmlRenderer.PdfSharp](https://www.nuget.org/packages/HtmlRenderer.PdfSharp) -* [HtmlRenderer.Core](https://www.nuget.org/packages/HtmlRenderer.Core) - -#### HTML Renderer on my blog -[TheArtOfDev / HTML Renderer](http://theartofdev.com/html-renderer/) diff --git a/Source/.nuget/NuGet.Config b/Source/.nuget/NuGet.Config deleted file mode 100644 index 67f8ea046..000000000 --- a/Source/.nuget/NuGet.Config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Source/.nuget/NuGet.exe b/Source/.nuget/NuGet.exe deleted file mode 100644 index c41a0d0de..000000000 Binary files a/Source/.nuget/NuGet.exe and /dev/null differ diff --git a/Source/.nuget/NuGet.targets b/Source/.nuget/NuGet.targets deleted file mode 100644 index 3f8c37b22..000000000 --- a/Source/.nuget/NuGet.targets +++ /dev/null @@ -1,144 +0,0 @@ - - - - $(MSBuildProjectDirectory)\..\ - - - false - - - false - - - true - - - false - - - - - - - - - - - $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) - - - - - $(SolutionDir).nuget - - - - $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config - $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config - - - - $(MSBuildProjectDirectory)\packages.config - $(PackagesProjectConfig) - - - - - $(NuGetToolsPath)\NuGet.exe - @(PackageSource) - - "$(NuGetExePath)" - mono --runtime=v4.0.30319 "$(NuGetExePath)" - - $(TargetDir.Trim('\\')) - - -RequireConsent - -NonInteractive - - "$(SolutionDir) " - "$(SolutionDir)" - - - $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir) - $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols - - - - RestorePackages; - $(BuildDependsOn); - - - - - $(BuildDependsOn); - BuildPackage; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Source/Demo/Common/DemoUtils.cs b/Source/Demo/Common/DemoUtils.cs index f695886bc..682f325f5 100644 --- a/Source/Demo/Common/DemoUtils.cs +++ b/Source/Demo/Common/DemoUtils.cs @@ -29,7 +29,7 @@ public static String SampleHtmlLabelText get { return "This is an HtmlLabel on transparent background with colors and links: " + - "HTML Renderer"; + "HTML Renderer"; } } @@ -40,7 +40,7 @@ public static String SampleHtmlPanelText { get { - return "This is an HtmlPanel with colors and links: HTML Renderer" + + return "This is an HtmlPanel with colors and links: HTML Renderer" + "
If there is more text than the size of the control scrollbars will appear.
" + "
Click me to change my Text property."; } diff --git a/Source/Demo/Common/HtmlRenderer.Demo.Common.csproj b/Source/Demo/Common/HtmlRenderer.Demo.Common.csproj index a8ffe8490..b2b829640 100644 --- a/Source/Demo/Common/HtmlRenderer.Demo.Common.csproj +++ b/Source/Demo/Common/HtmlRenderer.Demo.Common.csproj @@ -1,166 +1,100 @@ - - - + - Debug - AnyCPU - {2390B71F-9400-47F4-B23A-7F2649C87D35} + netstandard2.0;net8.0 Library - Properties TheArtOfDev.HtmlRenderer.Demo.Common HtmlRendererDemoCommon - v2.0 - 512 - + true + true - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - + Resources.resx True True - - - - - - - - - + PublicResXFileCodeGenerator Resources.Designer.cs Designer - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - {FE611685-391F-4E3E-B27E-D3150E51E49B} - HtmlRenderer - + - + - - \ No newline at end of file diff --git a/Source/Demo/Common/HtmlSyntaxHighlighter.cs b/Source/Demo/Common/HtmlSyntaxHighlighter.cs index d68f2c1c8..e77cdb474 100644 --- a/Source/Demo/Common/HtmlSyntaxHighlighter.cs +++ b/Source/Demo/Common/HtmlSyntaxHighlighter.cs @@ -26,7 +26,7 @@ namespace TheArtOfDev.HtmlRenderer.Demo.Common /// /// /// The MIT License (MIT) Copyright (c) 2014 Arthur Teplitzki.
- /// Based on work by Alun Evans 2006 (http://www.codeproject.com/Articles/15038/C-Formatting-Text-in-a-RichTextBox-by-Parsing-the). + /// Based on work by Alun Evans 2006 (https://web.archive.org/web/20170426121905/http://www.codeproject.com/Articles/15038/C-Formatting-Text-in-a-RichTextBox-by-Parsing-the). ///
public static class HtmlSyntaxHighlighter { diff --git a/Source/Demo/Common/PerfSamples/1.Big table.htm b/Source/Demo/Common/PerfSamples/1.Big table.htm index 9aad29719..cb4cb2ef0 100644 --- a/Source/Demo/Common/PerfSamples/1.Big table.htm +++ b/Source/Demo/Common/PerfSamples/1.Big table.htm @@ -46,7 +46,7 @@

foinobpjg + foinobpjg

@@ -62,8 +62,8 @@

- opmqjeqf mj - pdkfd ddooekeh pc denopnjgcirn pe oqemmcg fla lnmaba 2.1 - + opmqjeqf mj + pdkfd ddooekeh pc denopnjgcirn pe oqemmcg fla lnmaba 2.1 - khon gac ioof phpdigja


@@ -71,9 +71,9 @@

iigm nnk frmjfl + href='https://www.google.com'>iigm nnk frmjfl ejk + data-containertype="-2" data-objectid="2471" data-objecttype="700" href='https://www.google.com'> lppf rnp rnpjihp

&ppbg;

@@ -140,7 +140,7 @@

- fcb: j onq'p eoapl jmin leo halnbcmam ei cfri... m´h qnlpll lnha ohhrrjbcf jghl + fcb: j onq'p eoapl jmin leo halnbcmam ei cfri... m´h qnlpll lnha ohhrrjbcf jghl bqcrgpk lb abp qkqo gralcp kfeildpd, dbjbj ril eppg n hfcbqd gqj fnjd &gpnp;egoppa&foaq; fn &ncon;ccrb hm rjelnn&jgkl; qhlj kpkfoe qead odr obepl ij gfk dekfm, gmo fifdf kle cnnj bpjon fgn frbcf'e haerd qfgimmkn le gfol nifmojh rrjghcqa dkac (koen hpccjmi, @@ -149,7 +149,7 @@

- qcpciiahbq + qcpciiahbq @@ -176,7 +176,7 @@

- jcrrnagrqq + jcrrnagrqq @@ -200,12 +200,12 @@

&ofik;

nkm: + data-objectid="3512" data-objecttype="3" href='https://www.google.com'> ogqkq lblhhk, amcdon? pm rel bll irdffld dgfgl gdine lc &opoc;ljmmblicf&eqil; qgc ng pfooch ldda aq poloknkqbj... qcagh no pqj hhaigo hf aqi hchhco pfkjoef... - gmoorqgfcj + gmoorqgfcj @@ -225,7 +225,7 @@

- lqafmgjder + lqafmgjder @@ -247,7 +247,7 @@

- lmmacdienr + lmmacdienr @@ -269,7 +269,7 @@

- ndlrhbegpd + ndlrhbegpd @@ -291,7 +291,7 @@

- iefmkkidri + iefmkkidri @@ -387,7 +387,7 @@

- jffdkrloia + jffdkrloia @@ -417,7 +417,7 @@

- ocdnikrcij + ocdnikrcij @@ -438,7 +438,7 @@

- mlkgdjqbrb + mlkgdjqbrb @@ -472,7 +472,7 @@

- ngjpkefafq + ngjpkefafq @@ -495,7 +495,7 @@

- cmjekieppq + cmjekieppq @@ -517,7 +517,7 @@

- dafomhjllq + dafomhjllq @@ -540,7 +540,7 @@

giedc heaarh'e + href='https://www.google.com'>giedc heaarh'e dqcpcipck icdbp pk nbbk riel)

&jbhp;

@@ -573,7 +573,7 @@

fekjk rrekjm'e + href='https://www.google.com'>fekjk rrekjm'e dcolmagp abgep gb alhk rddm)

&gnpe;

hfapi: ppo kbl'd pefl dqgmdqrkdq nb rhhppnr ka {dpgrj irae}. @@ -602,7 +602,7 @@

aqckk idkjob'o + href='https://www.google.com'>aqckk idkjob'o pmqapakp migeq pcrg)

&mpib;

@@ -631,7 +631,7 @@

- lplfhiceem + lplfhiceem @@ -655,7 +655,7 @@

eefgj rhnmcr

+ href='https://www.google.com'>eefgj rhnmcr

&crmk;

@@ -671,7 +671,7 @@

ijqnna • rrgbk + mn lfrlhoc.ijqnna • rrgbk ko 2.7.2013 nn 3.57.34 nq.fpf

&ignd;

@@ -702,7 +702,7 @@

dgobg hrhlrm

+ href='https://www.google.com'>dgobg hrhlrm

&rhfd;

@@ -733,7 +733,7 @@

qpefa nflrrd

+ href='https://www.google.com'>qpefa nflrrd

&ikkb;

cpage: mornan. @@ -785,10 +785,10 @@

- obm: r´c&pjfi; pfe &lgrl;hcag enkdefl jkfalcch in iqfardi&mccr; lc clrdqbj &jmpe;amcolbiq + obm: r´c&pjfi; pfe &lgrl;hcag enkdefl jkfalcch in iqfardi&mccr; lc clrdqbj &jmpe;amcolbiq jp rdngfkc&jccl; (pidh &mrdg;qeoba&aeal; ablac eche). plj hrjmkcd rhrcfkkl ccmfa jjjbikmea... + data-containertype="-1" data-objectid="3512" data-objecttype="3" href='https://www.google.com'> rhbjp jeegip

&abdb;

@@ -826,7 +826,7 @@

cronf dhgobi

+ href='https://www.google.com'>cronf dhgobi

&mggq;

@@ -1066,7 +1066,7 @@

- foigbphcoa + foigbphcoa @@ -1087,7 +1087,7 @@

- erkeokamgb + erkeokamgb @@ -1132,7 +1132,7 @@

- grilrdagid + grilrdagid @@ -1154,7 +1154,7 @@

- grcohqpnor + grcohqpnor @@ -1175,7 +1175,7 @@

- lljaghklrq + lljaghklrq @@ -1196,7 +1196,7 @@

- hgiircibcr + hgiircibcr @@ -1218,7 +1218,7 @@

- dlkgodbdcb + dlkgodbdcb @@ -1284,7 +1284,7 @@

- erkmioomnd + erkmioomnd @@ -1306,7 +1306,7 @@

- ljqbcalnff + ljqbcalnff @@ -1336,7 +1336,7 @@

- hahdjkmlda + hahdjkmlda @@ -1357,7 +1357,7 @@

gdl: hlioq fjcflcph, + href='https://www.google.com'>hlioq fjcflcph, f ahlbk ro cadqohcid qq agdal mfimik pnrk kja kf od pfkeq cq h lcnepa croq nb efkciqd:

  • 2 okilkcojphgo: djfpicickhje ljmqjni @@ -1376,7 +1376,7 @@

    farohbqrgo + href='https://www.google.com'>farohbqrgo @@ -1399,7 +1399,7 @@

    poihpkqmjj + href='https://www.google.com'>poihpkqmjj @@ -1420,7 +1420,7 @@

    - jbcmbmblrd + jbcmbmblrd @@ -1440,7 +1440,7 @@

    - qicilgnpmc + qicilgnpmc @@ -1460,7 +1460,7 @@

    - idgpecqqbe + idgpecqqbe @@ -1484,7 +1484,7 @@

    - dfbggcmpci + dfbggcmpci @@ -1505,7 +1505,7 @@

    - nalofqmbfj + nalofqmbfj @@ -1526,7 +1526,7 @@

    - pnkaqjoffq + pnkaqjoffq @@ -1547,7 +1547,7 @@

    - qrqrkgdcqr + qrqrkgdcqr @@ -1568,7 +1568,7 @@

    - gnlikhjdnp + gnlikhjdnp @@ -1589,7 +1589,7 @@

    - iabjqrghmc + iabjqrghmc @@ -1610,7 +1610,7 @@

    - krccimirgr + krccimirgr @@ -1631,7 +1631,7 @@

    - qdlabffkab + qdlabffkab @@ -1652,7 +1652,7 @@

    - bokbkcafha + bokbkcafha @@ -1828,7 +1828,7 @@

    + data-objectid="3512" data-objecttype="3" href='https://www.google.com'> abnaf ajllna @@ -1854,7 +1854,7 @@

    gekjn ofkcmr + href='https://www.google.com'>gekjn ofkcmr @@ -1899,7 +1899,7 @@

    nrg: {0} pkmcf'j bnpo apjcnfcbfg ip akmr dmgicpk jj ind faleekdg ccaeo (bhkqr jbhfgh) + href='https://www.google.com'>bhkqr jbhfgh) @@ -1944,7 +1944,7 @@

    - ermkrcjhph + ermkrcjhph @@ -1965,7 +1965,7 @@

    - pjlooeoecc + pjlooeoecc @@ -1987,7 +1987,7 @@

    - gjcaoddide + gjcaoddide @@ -2029,7 +2029,7 @@

    - cbmqpeodaj + cbmqpeodaj @@ -2050,7 +2050,7 @@

    - kariaiqbfn + kariaiqbfn @@ -2071,7 +2071,7 @@

    - fffjecboen + fffjecboen @@ -2093,7 +2093,7 @@

    + data-objectid="3512" data-objecttype="3" href='https://www.google.com'> qfplf drmjhc, eei olh ldfjb qq n hmaomb eijbocg (nkn apieq)

    &kdgl;

    @@ -2101,7 +2101,7 @@

    - kpgbarfmmq + kpgbarfmmq @@ -2122,7 +2122,7 @@

    - ffpqbmpdrj + ffpqbmpdrj @@ -2143,7 +2143,7 @@

    - fchijmeomh + fchijmeomh @@ -2165,7 +2165,7 @@

    - qbaqglhbcp + qbaqglhbcp @@ -2207,7 +2207,7 @@

    - kkpoghnaeg + kkpoghnaeg @@ -2228,7 +2228,7 @@

    - effijocbfm + effijocbfm @@ -2249,7 +2249,7 @@

    nal: &jldk;mdnmq qhk ig gpmmmhe nkqh ree gech rfobr. eqmm le bcbaob&hfda; (khobe dmqjgm), + href='https://www.google.com'>khobe dmqjgm), orkc, jep'h nrn liio fridrq r ggq aan? beode jfci peok qhapof lipm ighnok deiec fi dkgrclo bdghajgj. @@ -2447,7 +2447,7 @@

    + data-objectid="3512" data-objecttype="3" href='https://www.google.com'> roloc aeemag, mi cqr kdcr &oapr;ghp cmj mjln qlf rarl kr flrff eeq phciqr mhmcbjd foandfmlcd gebj fhckphko?&bjea; mk jfpjaoa pq kc r kendoep? h'h akjd bkinjiclb bpgo &deji;jki qpg bpna ded jnff qd jcgbr? fjdp prakprj rbfe eg pohr&gpkb;. bieaa, @@ -2585,7 +2585,7 @@

    - rkiqjcqpgc + rkiqjcqpgc @@ -2707,13 +2707,13 @@

    pjmrkf - • rgmdf rq 2.7.2013 fe 5.09.21 rl.mhe bhr rmqo jhrfbrao im bmda dhijpfi - cdirfk gi kmem ihqm qdrpjn, fjre - epriip • kggei fo 2.7.2013 hm 5.10.26 fq.rpa... mk emk fphqg prab...

    + bmppeohdc lmph pjmrkf + • rgmdf rq 2.7.2013 fe 5.09.21 rl.mhe bhr rmqo jhrfbrao im bmda dhijpfi + cdirfk gi kmem ihqm qdrpjn, fjre + epriip � kggei fo 2.7.2013 hm 5.10.26 fq.rpa... mk emk fphqg prab...

    - fiicehbcam + fiicehbcam @@ -2758,7 +2758,7 @@

    - adnkmldmig + adnkmldmig @@ -3054,20 +3054,20 @@

    - cganbif ma lrbffrkl or ehlj ehnof, pr jr qf qpr jpdfnnjf gc ddrdrphci - pngfmr o bba dahbkcro ql qaralkcqojci ch addkifq mie dcobgb 2.1 aa - jjjpo, gm bp + jjjpo, gm bp qejpnprah - qhfkmejmp iobknjbqlqdg pp hiahqhh epb rclnqo 2.1 ff ciden gjaooda: pabjq diff --git a/Source/Demo/Common/Properties/AssemblyInfo.cs b/Source/Demo/Common/Properties/AssemblyInfo.cs deleted file mode 100644 index bb96bf22f..000000000 --- a/Source/Demo/Common/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// 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: AssemblyTitle("HtmlRenderer.Demo.Common")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("HtmlRenderer.Demo.Common")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("5d5516c9-aa2c-44cc-883c-467ff9a3d9b9")] - -// 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")] \ No newline at end of file diff --git a/Source/Demo/Common/Properties/Resources.Designer.cs b/Source/Demo/Common/Properties/Resources.Designer.cs index 8b1aa6a38..f9f272e58 100644 --- a/Source/Demo/Common/Properties/Resources.Designer.cs +++ b/Source/Demo/Common/Properties/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34014 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -19,7 +19,7 @@ namespace TheArtOfDev.HtmlRenderer.Demo.Common.Properties { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class Resources { diff --git a/Source/Demo/Common/Properties/Resources.resx b/Source/Demo/Common/Properties/Resources.resx index 081d86fd7..1f6a9275d 100644 --- a/Source/Demo/Common/Properties/Resources.resx +++ b/Source/Demo/Common/Properties/Resources.resx @@ -137,6 +137,6 @@ ..\Resources\code.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\resources\browser.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\browser.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a \ No newline at end of file diff --git a/Source/Demo/Common/Resources/Tooltip.html b/Source/Demo/Common/Resources/Tooltip.html index 85892877a..1c00962e2 100644 --- a/Source/Demo/Common/Resources/Tooltip.html +++ b/Source/Demo/Common/Resources/Tooltip.html @@ -14,5 +14,5 @@
    This is an HtmlToolTip and it's very COOL!!!
    - You can even click on the links! + You can even click on the links!
    \ No newline at end of file diff --git a/Source/Demo/Common/Samples/00.Intro.htm b/Source/Demo/Common/Samples/00.Intro.htm index ae8a64361..d310818b4 100644 --- a/Source/Demo/Common/Samples/00.Intro.htm +++ b/Source/Demo/Common/Samples/00.Intro.htm @@ -22,7 +22,7 @@

    This project allows you to have the rich format power of HTML on your desktop applications without WebBrowser control or MSHTML.
    The library is 100% managed code without any external dependencies, the only - requirement is .NET 2.0 or higher, including support for Client Profile. + requirement is .NET Framework 4.6.2 or higher, including support for Client Profile. @@ -63,7 +63,6 @@

    • 100% managed code and no external dependencies.
    • -
    • Supports .NET 2.0 or higher including Client Profile.
    • Handles "real world" malformed HTML, it doesn't have to be XHTML.
    • Lightweight (~300K).
    • High performance and low memory footprint.
    • @@ -104,14 +103,11 @@

      2012 - Arthur Teplitzki

      - http://TheArtOfDev.com + https://TheArtOfDev.com

      2009 - Jose Manuel Menendez Poo

      -
      - www.menendezpoo.com -
      \ No newline at end of file diff --git a/Source/Demo/Common/Samples/02.Text.htm b/Source/Demo/Common/Samples/02.Text.htm index b7aee3fa9..85e201024 100644 --- a/Source/Demo/Common/Samples/02.Text.htm +++ b/Source/Demo/Common/Samples/02.Text.htm @@ -2,11 +2,11 @@ Text - @@ -23,7 +23,7 @@

      Formatting
    • Colors, Colors, Colors
    • Back colors, Back colors, Back colors
    • -
    • Font style, Font style, Font style, Font style, Font style
    • +
    • Font style, Font style, Font style, Font style, Font style, Font style

    Lorem ipsum dolor sit amet, @@ -80,7 +80,7 @@

    Justifed


    Breakable lines

    - http://www.google.com/sjkdhgfasdfgfg/asdfadfsgaefg/adfgafdgadfg/asdfgaedfgsdfg/dasfgasfdgasdfg/adfgadfgasfdg/adfsgafgafg/afdgaddfgadfg/afsdgafdgaddfg/afsdgafgadqfdgaeddfg + https://www.google.com/sjkdhgfasdfgfg/asdfadfsgaefg/adfgafdgadfg/asdfgaedfgsdfg/dasfgasfdgasdfg/adfgadfgasfdg/adfsgafgafg/afdgaddfgadfg/afsdgafdgaddfg/afsdgafgadqfdgaeddfg

    Transparent text

    diff --git a/Source/Demo/Common/Samples/03.Tables.htm b/Source/Demo/Common/Samples/03.Tables.htm index 7f8a07eb7..e923bacce 100644 --- a/Source/Demo/Common/Samples/03.Tables.htm +++ b/Source/Demo/Common/Samples/03.Tables.htm @@ -77,7 +77,7 @@

  • Back colors, Back colors, Back colors
  • Font style, - Font style, Font style, + Font style, Font style, Font style, Font style, Font style
diff --git a/Source/Demo/Common/Samples/04.Links.htm b/Source/Demo/Common/Samples/04.Links.htm index 05c8a5c79..e84a45f1b 100644 --- a/Source/Demo/Common/Samples/04.Links.htm +++ b/Source/Demo/Common/Samples/04.Links.htm @@ -16,7 +16,7 @@

URI href


Check the context menu options on the link as well by right clicking on it.
- This is a URI link to HTML Renderer (href="https://htmlrenderer.codeplex.com/") + This is a URI link to HTML Renderer (href="https://codeplexarchive.org/project/HtmlRenderer")

File path href

diff --git a/Source/Demo/Common/Samples/05.Images.htm b/Source/Demo/Common/Samples/05.Images.htm index 6d41f3e79..9c6c08077 100644 --- a/Source/Demo/Common/Samples/05.Images.htm +++ b/Source/Demo/Common/Samples/05.Images.htm @@ -64,7 +64,7 @@

img tag

Loaded from web: - + diff --git a/Source/Demo/Common/Samples/06.Embeded video.htm b/Source/Demo/Common/Samples/06.Embeded video.htm index dc64330d9..af499d19b 100644 --- a/Source/Demo/Common/Samples/06.Embeded video.htm +++ b/Source/Demo/Common/Samples/06.Embeded video.htm @@ -27,13 +27,14 @@

Note: Because this technique requires server API it is currently supported - only for YouTube and + only for YouTube and Vimeo.

Example

-

diff --git a/Source/Demo/Common/TestSamples/15.MaxWidth.htm b/Source/Demo/Common/TestSamples/15.MaxWidth.htm index d8b98e9ba..f84db35d2 100644 --- a/Source/Demo/Common/TestSamples/15.MaxWidth.htm +++ b/Source/Demo/Common/TestSamples/15.MaxWidth.htm @@ -14,7 +14,7 @@

Long line without whitespaces:
- http://www.google.com/sjkdhgfasdfgfg/asdfadfsgaefg/adfgafdgadfg/asdfgaedfgsdfg/dasfgasfdgasdfg/adfgadfgasfdg/adfsgafgafg/afdgaddfgadfg/afsdgafdgaddfg/afsdgafgadqfdgaeddfg/afsdgadfgafg + https://www.google.com/sjkdhgfasdfgfg/asdfadfsgaefg/adfgafdgadfg/asdfgaedfgsdfg/dasfgasfdgasdfg/adfgadfgasfdg/adfsgafgafg/afdgaddfgadfg/afsdgafdgaddfg/afsdgafgadqfdgaeddfg/afsdgadfgafg

The text should not exceed max width:
@@ -26,10 +26,10 @@

metus. Integer leo dolor, tristique a, dignissim ac, iaculis eget, elit. Donec arcu.

The image should also be limited by size because it has: style="width:90%"
- - + +

- +

diff --git a/Source/Demo/Common/TestSamples/19.Many images.htm b/Source/Demo/Common/TestSamples/19.Many images.htm index a7cd2582c..659319ed0 100644 --- a/Source/Demo/Common/TestSamples/19.Many images.htm +++ b/Source/Demo/Common/TestSamples/19.Many images.htm @@ -2,102 +2,102 @@

Contains many images that should not load until in scroll view

Image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- +

Another image

- + \ No newline at end of file diff --git a/Source/Demo/Common/TestSamples/32.Image in css content.htm b/Source/Demo/Common/TestSamples/32.Image in css content.htm new file mode 100644 index 000000000..c3b7a86ec --- /dev/null +++ b/Source/Demo/Common/TestSamples/32.Image in css content.htm @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/Source/Demo/Common/TestSamples/33.Fixed position.htm b/Source/Demo/Common/TestSamples/33.Fixed position.htm new file mode 100644 index 000000000..728999a9c --- /dev/null +++ b/Source/Demo/Common/TestSamples/33.Fixed position.htm @@ -0,0 +1,83 @@ + + + + + +
+ + + + + +
+ + + Microsoft Corporation
+ One Microsoft Way
+ Redmond, WA 98052-7329
+ USA
+ Tel: (425) 882-8080
+ Fax: (425) 706-7329
+
+
+ +

+ Lorem ipsum dolor sit amet, eam labores interpretaris id. Usu ut posse labore, et quem lobortis vim. Eu laudem euismod delicatissimi pri, nusquam torquatos eu mei, utamur commune deterruisset et vix. Sit mollis appareat salutatus eu. Vel eu facete repudiare honestatis, quo ut erant blandit. Oratio consectetuer id eam, ridens tamquam impedit no quo. + + Te qui eros melius inimicus, ex vel accusata electram salutatus, hinc prima brute te usu. Audiam prodesset cotidieque at eum, sale noster rationibus eu mei, quas invidunt usu id. Idque aperiri invenire no his, alia alterum vix in. Cum solum mundi ea, mea ut legere putent. Sit fugit maiorum eu, clita contentiones in eos, populo evertitur maiestatis ut ius. + + Ut quot petentium definiebas est, magna commune ex est, te magna voluptaria vis. Ne omnis probatus postulant ius, modus nemore suscipiantur cum eu. Et vocent discere recusabo eos, iudicabit deseruisse vix et. No sed discere voluptaria. Ad vis autem dicat delenit. Ut vim noluisse reprehendunt, mea velit veritus platonem ei, duo in legere contentiones. In alii sapientem contentiones vel. + + Te mea nibh eius philosophia, ubique tibique vel an, mei at error nullam aliquid. Bonorum delenit tibique ei sed. In partem convenire pro, ad summo appareat mediocrem cum. In ornatus accusam vel, nam veritus consectetuer id. + + Explicari voluptatum interpretaris et mea. Ex vix malorum blandit, nam elit animal ad, ne diam timeam probatus ius. Volumus lucilius sapientem pro ad. Pri ea sale possit. Blandit pertinax praesent per an, dolor saperet an vis. + + Duo possim luptatum interesset an. Quas omnes moderatius vis ad, cu dissentiet theophrastus ius. Quem doming eirmod nec id, quo quas democritum cu, duo no singulis delicata convenire. Vix eu perpetua honestatis, eos iuvaret scribentur an, in nisl alterum cum. Eu mandamus laboramus voluptatum usu. His ipsum invenire te, tation tamquam perfecto at ius, in elit clita iisque per. Sit conceptam adipiscing ex. + + Hinc utamur epicurei vis an, nec magna nostro ne. Vis ea viris legere interpretaris, eos regione laoreet eligendi id. Duo te partem vituperata disputando. Usu dicat verear an, pro ea inani legere dolorem. An cum assentior gloriatur honestatis. Eu nonumes repudiare mel, inani interesset sea at, ius cu fabellas convenire liberavisse. Delicata abhorreant ne quo, an cum case integre delicatissimi. + + Duo ea legimus blandit, duo ne persius insolens rationibus. Sed aeque putent maiorum ex. Appareat iracundia vis at, laoreet molestiae eu nam, eu docendi scriptorem efficiantur qui. Facer quaerendum ex eam. + + Ei debet bonorum sapientem mei, cu corpora qualisque similique his. Ex mel volumus argumentum, aeterno adversarium vim id. Vidit probo consetetur id ius, sit case copiosae ne. Per at antiopam forensibus, eu dicant offendit ius, sea ad liber graeco. + + Vitae nullam delenit vel in. Ne vim choro sadipscing, eos ad everti aliquando. Cu legere laoreet nec, wisi quaerendum has an. Sed ut agam eripuit delectus, eu integre fuisset reprehendunt vim. Cum quod viris appellantur at, ea ius virtute conceptam, sed esse aeque neglegentur in. Alienum verterem nam id, eu purto duis disputando est. + + Eros perfecto at est. Quas complectitur pri ad. Eam cu discere phaedrum, sit ut dicam dolore. Eu putant minimum postulant sit. Agam corpora aliquando nec ut, noluisse lobortis intellegebat sit id, cu omnis conceptam eum. + + Eius autem adolescens ius an, pro populo mandamus eu. Falli adipisci ea sed, laboramus signiferumque sea ea. Ex labores percipit qui, vidit scaevola evertitur sed eu, mutat mandamus explicari in mel. Patrioque instructior consequuntur ea sea, cu cum iudico graeco dissentias. + + Ea ancillae invidunt reprimique duo, cu quando euismod eum, eos cu simul causae pertinacia. Ea vix fierent hendrerit. Agam dolore volutpat id his, noster graeco praesent ea per. Purto tritani explicari mei id. An sed utroque consequat contentiones. An duo eros debet, ea quo veritus interpretaris. Ne harum pertinacia honestatis eum, mei no facer erant. + + Nullam numquam salutandi usu no, in omnesque expetendis efficiendi vix. Ius erat vivendum ea. Vis an ferri omittam scripserit, te his erat quaeque. Ne his doming indoctum maiestatis, vis id dicat nostrud placerat. Eu tempor appareat dissentias mei, eos novum ignota aperiri ea. + + Ex dicant tibique sapientem cum, id pro liber facilis aliquando. Mel no everti abhorreant, te utroque eleifend vel. Id harum suscipit suscipiantur eum. Cu sed tritani deleniti urbanitas, vim id saepe fabellas. Vel autem aperiam democritum id, nisl inciderint at his. Mea ubique argumentum ei. + + Malis semper usu ei. Simul phaedrum conceptam ad duo, id pro cibo doctus deleniti, erat persius quo ne. Cu quo novum partem blandit. Ad usu alterum euismod. Ex nec tamquam deserunt nominati, dicit option ut sed. + + Duo ei posse officiis, in fabulas nusquam usu. Vel impetus principes ad, mel ferri pertinax ex, ad vel nemore hendrerit repudiandae. Diam hinc eius vix ex, iisque percipit evertitur ea per. Summo minim discere an mea, vim dicam semper ne, cu vix virtute noluisse maiestatis. + + Facer possim mea id. An usu omnis noster laboramus. Graeco tritani eam an, cu sea ignota habemus recteque, an vis simul posidonium. Te omnis evertitur vim, pro ad equidem postulant. Eum soleat fuisset cu, an sit bonorum omnesque. Est an dicant omittantur, id pri mutat impedit partiendo, et eirmod corpora rationibus vix. + + Duo commune philosophia te. An vero sale tempor vis, odio similique gloriatur ex pri, quo id meis appareat. Ei vel wisi iracundia assentior, sed ex nostro invidunt elaboraret, te justo atomorum vis. Sed quaeque nonumes detraxit et, no dolores definitiones vix. + + Vide mutat facilisis ei sea. Ut ubique sanctus pri. Nonumy ubique ius id, vis paulo putent dolorem ea. Cum at offendit liberavisse, ex est deleniti iracundia. At facer aeterno habemus vix. Has sale porro mnesarchum ea. Vix in sumo veniam eripuit, sea no erat scripta. +

+ + \ No newline at end of file diff --git a/Source/Demo/Common/TestSamples/34.Breaking pages 1 - Paragraphs.htm b/Source/Demo/Common/TestSamples/34.Breaking pages 1 - Paragraphs.htm new file mode 100644 index 000000000..8d84f88c6 --- /dev/null +++ b/Source/Demo/Common/TestSamples/34.Breaking pages 1 - Paragraphs.htm @@ -0,0 +1,177 @@ + + + + + +

Default page breaks

+

+ Lorem ipsum dolor sit amet, eam labores interpretaris id. Usu ut posse labore, et quem lobortis vim. Eu laudem euismod delicatissimi pri, nusquam torquatos eu mei, utamur commune deterruisset et vix. Sit mollis appareat salutatus eu. Vel eu facete repudiare honestatis, quo ut erant blandit. Oratio consectetuer id eam, ridens tamquam impedit no quo. + + Te qui eros melius inimicus, ex vel accusata electram salutatus, hinc prima brute te usu. Audiam prodesset cotidieque at eum, sale noster rationibus eu mei, quas invidunt usu id. Idque aperiri invenire no his, alia alterum vix in. Cum solum mundi ea, mea ut legere putent. Sit fugit maiorum eu, clita contentiones in eos, populo evertitur maiestatis ut ius. + + Ut quot petentium definiebas est, magna commune ex est, te magna voluptaria vis. Ne omnis probatus postulant ius, modus nemore suscipiantur cum eu. Et vocent discere recusabo eos, iudicabit deseruisse vix et. No sed discere voluptaria. Ad vis autem dicat delenit. Ut vim noluisse reprehendunt, mea velit veritus platonem ei, duo in legere contentiones. In alii sapientem contentiones vel. + + Te mea nibh eius philosophia, ubique tibique vel an, mei at error nullam aliquid. Bonorum delenit tibique ei sed. In partem convenire pro, ad summo appareat mediocrem cum. In ornatus accusam vel, nam veritus consectetuer id. + + Explicari voluptatum interpretaris et mea. Ex vix malorum blandit, nam elit animal ad, ne diam timeam probatus ius. Volumus lucilius sapientem pro ad. Pri ea sale possit. Blandit pertinax praesent per an, dolor saperet an vis. + + Duo possim luptatum interesset an. Quas omnes moderatius vis ad, cu dissentiet theophrastus ius. Quem doming eirmod nec id, quo quas democritum cu, duo no singulis delicata convenire. Vix eu perpetua honestatis, eos iuvaret scribentur an, in nisl alterum cum. Eu mandamus laboramus voluptatum usu. His ipsum invenire te, tation tamquam perfecto at ius, in elit clita iisque per. Sit conceptam adipiscing ex. + + Hinc utamur epicurei vis an, nec magna nostro ne. Vis ea viris legere interpretaris, eos regione laoreet eligendi id. Duo te partem vituperata disputando. Usu dicat verear an, pro ea inani legere dolorem. An cum assentior gloriatur honestatis. Eu nonumes repudiare mel, inani interesset sea at, ius cu fabellas convenire liberavisse. Delicata abhorreant ne quo, an cum case integre delicatissimi. + + Duo ea legimus blandit, duo ne persius insolens rationibus. Sed aeque putent maiorum ex. Appareat iracundia vis at, laoreet molestiae eu nam, eu docendi scriptorem efficiantur qui. Facer quaerendum ex eam. + + Ei debet bonorum sapientem mei, cu corpora qualisque similique his. Ex mel volumus argumentum, aeterno adversarium vim id. Vidit probo consetetur id ius, sit case copiosae ne. Per at antiopam forensibus, eu dicant offendit ius, sea ad liber graeco. + + Vitae nullam delenit vel in. Ne vim choro sadipscing, eos ad everti aliquando. Cu legere laoreet nec, wisi quaerendum has an. Sed ut agam eripuit delectus, eu integre fuisset reprehendunt vim. Cum quod viris appellantur at, ea ius virtute conceptam, sed esse aeque neglegentur in. Alienum verterem nam id, eu purto duis disputando est. + + Eros perfecto at est. Quas complectitur pri ad. Eam cu discere phaedrum, sit ut dicam dolore. Eu putant minimum postulant sit. Agam corpora aliquando nec ut, noluisse lobortis intellegebat sit id, cu omnis conceptam eum. + + Eius autem adolescens ius an, pro populo mandamus eu. Falli adipisci ea sed, laboramus signiferumque sea ea. Ex labores percipit qui, vidit scaevola evertitur sed eu, mutat mandamus explicari in mel. Patrioque instructior consequuntur ea sea, cu cum iudico graeco dissentias. + + Ea ancillae invidunt reprimique duo, cu quando euismod eum, eos cu simul causae pertinacia. Ea vix fierent hendrerit. Agam dolore volutpat id his, noster graeco praesent ea per. Purto tritani explicari mei id. An sed utroque consequat contentiones. An duo eros debet, ea quo veritus interpretaris. Ne harum pertinacia honestatis eum, mei no facer erant. + + Nullam numquam salutandi usu no, in omnesque expetendis efficiendi vix. Ius erat vivendum ea. Vis an ferri omittam scripserit, te his erat quaeque. Ne his doming indoctum maiestatis, vis id dicat nostrud placerat. Eu tempor appareat dissentias mei, eos novum ignota aperiri ea. + + Ex dicant tibique sapientem cum, id pro liber facilis aliquando. Mel no everti abhorreant, te utroque eleifend vel. Id harum suscipit suscipiantur eum. Cu sed tritani deleniti urbanitas, vim id saepe fabellas. Vel autem aperiam democritum id, nisl inciderint at his. Mea ubique argumentum ei. + + Malis semper usu ei. Simul phaedrum conceptam ad duo, id pro cibo doctus deleniti, erat persius quo ne. Cu quo novum partem blandit. Ad usu alterum euismod. Ex nec tamquam deserunt nominati, dicit option ut sed. + + Duo ei posse officiis, in fabulas nusquam usu. Vel impetus principes ad, mel ferri pertinax ex, ad vel nemore hendrerit repudiandae. Diam hinc eius vix ex, iisque percipit evertitur ea per. Summo minim discere an mea, vim dicam semper ne, cu vix virtute noluisse maiestatis. + + Facer possim mea id. An usu omnis noster laboramus. Graeco tritani eam an, cu sea ignota habemus recteque, an vis simul posidonium. Te omnis evertitur vim, pro ad equidem postulant. Eum soleat fuisset cu, an sit bonorum omnesque. Est an dicant omittantur, id pri mutat impedit partiendo, et eirmod corpora rationibus vix. + + Duo commune philosophia te. An vero sale tempor vis, odio similique gloriatur ex pri, quo id meis appareat. Ei vel wisi iracundia assentior, sed ex nostro invidunt elaboraret, te justo atomorum vis. Sed quaeque nonumes detraxit et, no dolores definitiones vix. + + Vide mutat facilisis ei sea. Ut ubique sanctus pri. Nonumy ubique ius id, vis paulo putent dolorem ea. Cum at offendit liberavisse, ex est deleniti iracundia. At facer aeterno habemus vix. Has sale porro mnesarchum ea. Vix in sumo veniam eripuit, sea no erat scripta. + + Lorem ipsum dolor sit amet, eam labores interpretaris id. Usu ut posse labore, et quem lobortis vim. Eu laudem euismod delicatissimi pri, nusquam torquatos eu mei, utamur commune deterruisset et vix. Sit mollis appareat salutatus eu. Vel eu facete repudiare honestatis, quo ut erant blandit. Oratio consectetuer id eam, ridens tamquam impedit no quo. + + Te qui eros melius inimicus, ex vel accusata electram salutatus, hinc prima brute te usu. Audiam prodesset cotidieque at eum, sale noster rationibus eu mei, quas invidunt usu id. Idque aperiri invenire no his, alia alterum vix in. Cum solum mundi ea, mea ut legere putent. Sit fugit maiorum eu, clita contentiones in eos, populo evertitur maiestatis ut ius. + + Ut quot petentium definiebas est, magna commune ex est, te magna voluptaria vis. Ne omnis probatus postulant ius, modus nemore suscipiantur cum eu. Et vocent discere recusabo eos, iudicabit deseruisse vix et. No sed discere voluptaria. Ad vis autem dicat delenit. Ut vim noluisse reprehendunt, mea velit veritus platonem ei, duo in legere contentiones. In alii sapientem contentiones vel. + + Te mea nibh eius philosophia, ubique tibique vel an, mei at error nullam aliquid. Bonorum delenit tibique ei sed. In partem convenire pro, ad summo appareat mediocrem cum. In ornatus accusam vel, nam veritus consectetuer id. + + Explicari voluptatum interpretaris et mea. Ex vix malorum blandit, nam elit animal ad, ne diam timeam probatus ius. Volumus lucilius sapientem pro ad. Pri ea sale possit. Blandit pertinax praesent per an, dolor saperet an vis. + + Duo possim luptatum interesset an. Quas omnes moderatius vis ad, cu dissentiet theophrastus ius. Quem doming eirmod nec id, quo quas democritum cu, duo no singulis delicata convenire. Vix eu perpetua honestatis, eos iuvaret scribentur an, in nisl alterum cum. Eu mandamus laboramus voluptatum usu. His ipsum invenire te, tation tamquam perfecto at ius, in elit clita iisque per. Sit conceptam adipiscing ex. + + Hinc utamur epicurei vis an, nec magna nostro ne. Vis ea viris legere interpretaris, eos regione laoreet eligendi id. Duo te partem vituperata disputando. Usu dicat verear an, pro ea inani legere dolorem. An cum assentior gloriatur honestatis. Eu nonumes repudiare mel, inani interesset sea at, ius cu fabellas convenire liberavisse. Delicata abhorreant ne quo, an cum case integre delicatissimi. + + Duo ea legimus blandit, duo ne persius insolens rationibus. Sed aeque putent maiorum ex. Appareat iracundia vis at, laoreet molestiae eu nam, eu docendi scriptorem efficiantur qui. Facer quaerendum ex eam. + + Ei debet bonorum sapientem mei, cu corpora qualisque similique his. Ex mel volumus argumentum, aeterno adversarium vim id. Vidit probo consetetur id ius, sit case copiosae ne. Per at antiopam forensibus, eu dicant offendit ius, sea ad liber graeco. + + Vitae nullam delenit vel in. Ne vim choro sadipscing, eos ad everti aliquando. Cu legere laoreet nec, wisi quaerendum has an. Sed ut agam eripuit delectus, eu integre fuisset reprehendunt vim. Cum quod viris appellantur at, ea ius virtute conceptam, sed esse aeque neglegentur in. Alienum verterem nam id, eu purto duis disputando est. + + Eros perfecto at est. Quas complectitur pri ad. Eam cu discere phaedrum, sit ut dicam dolore. Eu putant minimum postulant sit. Agam corpora aliquando nec ut, noluisse lobortis intellegebat sit id, cu omnis conceptam eum. + + Eius autem adolescens ius an, pro populo mandamus eu. Falli adipisci ea sed, laboramus signiferumque sea ea. Ex labores percipit qui, vidit scaevola evertitur sed eu, mutat mandamus explicari in mel. Patrioque instructior consequuntur ea sea, cu cum iudico graeco dissentias. + + Ea ancillae invidunt reprimique duo, cu quando euismod eum, eos cu simul causae pertinacia. Ea vix fierent hendrerit. Agam dolore volutpat id his, noster graeco praesent ea per. Purto tritani explicari mei id. An sed utroque consequat contentiones. An duo eros debet, ea quo veritus interpretaris. Ne harum pertinacia honestatis eum, mei no facer erant. + + Nullam numquam salutandi usu no, in omnesque expetendis efficiendi vix. Ius erat vivendum ea. Vis an ferri omittam scripserit, te his erat quaeque. Ne his doming indoctum maiestatis, vis id dicat nostrud placerat. Eu tempor appareat dissentias mei, eos novum ignota aperiri ea. + + Ex dicant tibique sapientem cum, id pro liber facilis aliquando. Mel no everti abhorreant, te utroque eleifend vel. Id harum suscipit suscipiantur eum. Cu sed tritani deleniti urbanitas, vim id saepe fabellas. Vel autem aperiam democritum id, nisl inciderint at his. Mea ubique argumentum ei. + + Malis semper usu ei. Simul phaedrum conceptam ad duo, id pro cibo doctus deleniti, erat persius quo ne. Cu quo novum partem blandit. Ad usu alterum euismod. Ex nec tamquam deserunt nominati, dicit option ut sed. + + Duo ei posse officiis, in fabulas nusquam usu. Vel impetus principes ad, mel ferri pertinax ex, ad vel nemore hendrerit repudiandae. Diam hinc eius vix ex, iisque percipit evertitur ea per. Summo minim discere an mea, vim dicam semper ne, cu vix virtute noluisse maiestatis. + + Facer possim mea id. An usu omnis noster laboramus. Graeco tritani eam an, cu sea ignota habemus recteque, an vis simul posidonium. Te omnis evertitur vim, pro ad equidem postulant. Eum soleat fuisset cu, an sit bonorum omnesque. Est an dicant omittantur, id pri mutat impedit partiendo, et eirmod corpora rationibus vix. + + Duo commune philosophia te. An vero sale tempor vis, odio similique gloriatur ex pri, quo id meis appareat. Ei vel wisi iracundia assentior, sed ex nostro invidunt elaboraret, te justo atomorum vis. Sed quaeque nonumes detraxit et, no dolores definitiones vix. + + Vide mutat facilisis ei sea. Ut ubique sanctus pri. Nonumy ubique ius id, vis paulo putent dolorem ea. Cum at offendit liberavisse, ex est deleniti iracundia. At facer aeterno habemus vix. Has sale porro mnesarchum ea. Vix in sumo veniam eripuit, sea no erat scripta. +

+ +

Proper page breaks

+

+ Lorem ipsum dolor sit amet, eam labores interpretaris id. Usu ut posse labore, et quem lobortis vim. Eu laudem euismod delicatissimi pri, nusquam torquatos eu mei, utamur commune deterruisset et vix. Sit mollis appareat salutatus eu. Vel eu facete repudiare honestatis, quo ut erant blandit. Oratio consectetuer id eam, ridens tamquam impedit no quo. + + Te qui eros melius inimicus, ex vel accusata electram salutatus, hinc prima brute te usu. Audiam prodesset cotidieque at eum, sale noster rationibus eu mei, quas invidunt usu id. Idque aperiri invenire no his, alia alterum vix in. Cum solum mundi ea, mea ut legere putent. Sit fugit maiorum eu, clita contentiones in eos, populo evertitur maiestatis ut ius. + + Ut quot petentium definiebas est, magna commune ex est, te magna voluptaria vis. Ne omnis probatus postulant ius, modus nemore suscipiantur cum eu. Et vocent discere recusabo eos, iudicabit deseruisse vix et. No sed discere voluptaria. Ad vis autem dicat delenit. Ut vim noluisse reprehendunt, mea velit veritus platonem ei, duo in legere contentiones. In alii sapientem contentiones vel. + + Te mea nibh eius philosophia, ubique tibique vel an, mei at error nullam aliquid. Bonorum delenit tibique ei sed. In partem convenire pro, ad summo appareat mediocrem cum. In ornatus accusam vel, nam veritus consectetuer id. + + Explicari voluptatum interpretaris et mea. Ex vix malorum blandit, nam elit animal ad, ne diam timeam probatus ius. Volumus lucilius sapientem pro ad. Pri ea sale possit. Blandit pertinax praesent per an, dolor saperet an vis. + + Duo possim luptatum interesset an. Quas omnes moderatius vis ad, cu dissentiet theophrastus ius. Quem doming eirmod nec id, quo quas democritum cu, duo no singulis delicata convenire. Vix eu perpetua honestatis, eos iuvaret scribentur an, in nisl alterum cum. Eu mandamus laboramus voluptatum usu. His ipsum invenire te, tation tamquam perfecto at ius, in elit clita iisque per. Sit conceptam adipiscing ex. + + Hinc utamur epicurei vis an, nec magna nostro ne. Vis ea viris legere interpretaris, eos regione laoreet eligendi id. Duo te partem vituperata disputando. Usu dicat verear an, pro ea inani legere dolorem. An cum assentior gloriatur honestatis. Eu nonumes repudiare mel, inani interesset sea at, ius cu fabellas convenire liberavisse. Delicata abhorreant ne quo, an cum case integre delicatissimi. + + Duo ea legimus blandit, duo ne persius insolens rationibus. Sed aeque putent maiorum ex. Appareat iracundia vis at, laoreet molestiae eu nam, eu docendi scriptorem efficiantur qui. Facer quaerendum ex eam. + + Ei debet bonorum sapientem mei, cu corpora qualisque similique his. Ex mel volumus argumentum, aeterno adversarium vim id. Vidit probo consetetur id ius, sit case copiosae ne. Per at antiopam forensibus, eu dicant offendit ius, sea ad liber graeco. + + Vitae nullam delenit vel in. Ne vim choro sadipscing, eos ad everti aliquando. Cu legere laoreet nec, wisi quaerendum has an. Sed ut agam eripuit delectus, eu integre fuisset reprehendunt vim. Cum quod viris appellantur at, ea ius virtute conceptam, sed esse aeque neglegentur in. Alienum verterem nam id, eu purto duis disputando est. + + Eros perfecto at est. Quas complectitur pri ad. Eam cu discere phaedrum, sit ut dicam dolore. Eu putant minimum postulant sit. Agam corpora aliquando nec ut, noluisse lobortis intellegebat sit id, cu omnis conceptam eum. + + Eius autem adolescens ius an, pro populo mandamus eu. Falli adipisci ea sed, laboramus signiferumque sea ea. Ex labores percipit qui, vidit scaevola evertitur sed eu, mutat mandamus explicari in mel. Patrioque instructior consequuntur ea sea, cu cum iudico graeco dissentias. + + Ea ancillae invidunt reprimique duo, cu quando euismod eum, eos cu simul causae pertinacia. Ea vix fierent hendrerit. Agam dolore volutpat id his, noster graeco praesent ea per. Purto tritani explicari mei id. An sed utroque consequat contentiones. An duo eros debet, ea quo veritus interpretaris. Ne harum pertinacia honestatis eum, mei no facer erant. + + Nullam numquam salutandi usu no, in omnesque expetendis efficiendi vix. Ius erat vivendum ea. Vis an ferri omittam scripserit, te his erat quaeque. Ne his doming indoctum maiestatis, vis id dicat nostrud placerat. Eu tempor appareat dissentias mei, eos novum ignota aperiri ea. + + Ex dicant tibique sapientem cum, id pro liber facilis aliquando. Mel no everti abhorreant, te utroque eleifend vel. Id harum suscipit suscipiantur eum. Cu sed tritani deleniti urbanitas, vim id saepe fabellas. Vel autem aperiam democritum id, nisl inciderint at his. Mea ubique argumentum ei. + + Malis semper usu ei. Simul phaedrum conceptam ad duo, id pro cibo doctus deleniti, erat persius quo ne. Cu quo novum partem blandit. Ad usu alterum euismod. Ex nec tamquam deserunt nominati, dicit option ut sed. + + Duo ei posse officiis, in fabulas nusquam usu. Vel impetus principes ad, mel ferri pertinax ex, ad vel nemore hendrerit repudiandae. Diam hinc eius vix ex, iisque percipit evertitur ea per. Summo minim discere an mea, vim dicam semper ne, cu vix virtute noluisse maiestatis. + + Facer possim mea id. An usu omnis noster laboramus. Graeco tritani eam an, cu sea ignota habemus recteque, an vis simul posidonium. Te omnis evertitur vim, pro ad equidem postulant. Eum soleat fuisset cu, an sit bonorum omnesque. Est an dicant omittantur, id pri mutat impedit partiendo, et eirmod corpora rationibus vix. + + Duo commune philosophia te. An vero sale tempor vis, odio similique gloriatur ex pri, quo id meis appareat. Ei vel wisi iracundia assentior, sed ex nostro invidunt elaboraret, te justo atomorum vis. Sed quaeque nonumes detraxit et, no dolores definitiones vix. + + Vide mutat facilisis ei sea. Ut ubique sanctus pri. Nonumy ubique ius id, vis paulo putent dolorem ea. Cum at offendit liberavisse, ex est deleniti iracundia. At facer aeterno habemus vix. Has sale porro mnesarchum ea. Vix in sumo veniam eripuit, sea no erat scripta. + + Lorem ipsum dolor sit amet, eam labores interpretaris id. Usu ut posse labore, et quem lobortis vim. Eu laudem euismod delicatissimi pri, nusquam torquatos eu mei, utamur commune deterruisset et vix. Sit mollis appareat salutatus eu. Vel eu facete repudiare honestatis, quo ut erant blandit. Oratio consectetuer id eam, ridens tamquam impedit no quo. + + Te qui eros melius inimicus, ex vel accusata electram salutatus, hinc prima brute te usu. Audiam prodesset cotidieque at eum, sale noster rationibus eu mei, quas invidunt usu id. Idque aperiri invenire no his, alia alterum vix in. Cum solum mundi ea, mea ut legere putent. Sit fugit maiorum eu, clita contentiones in eos, populo evertitur maiestatis ut ius. + + Ut quot petentium definiebas est, magna commune ex est, te magna voluptaria vis. Ne omnis probatus postulant ius, modus nemore suscipiantur cum eu. Et vocent discere recusabo eos, iudicabit deseruisse vix et. No sed discere voluptaria. Ad vis autem dicat delenit. Ut vim noluisse reprehendunt, mea velit veritus platonem ei, duo in legere contentiones. In alii sapientem contentiones vel. + + Te mea nibh eius philosophia, ubique tibique vel an, mei at error nullam aliquid. Bonorum delenit tibique ei sed. In partem convenire pro, ad summo appareat mediocrem cum. In ornatus accusam vel, nam veritus consectetuer id. + + Explicari voluptatum interpretaris et mea. Ex vix malorum blandit, nam elit animal ad, ne diam timeam probatus ius. Volumus lucilius sapientem pro ad. Pri ea sale possit. Blandit pertinax praesent per an, dolor saperet an vis. + + Duo possim luptatum interesset an. Quas omnes moderatius vis ad, cu dissentiet theophrastus ius. Quem doming eirmod nec id, quo quas democritum cu, duo no singulis delicata convenire. Vix eu perpetua honestatis, eos iuvaret scribentur an, in nisl alterum cum. Eu mandamus laboramus voluptatum usu. His ipsum invenire te, tation tamquam perfecto at ius, in elit clita iisque per. Sit conceptam adipiscing ex. + + Hinc utamur epicurei vis an, nec magna nostro ne. Vis ea viris legere interpretaris, eos regione laoreet eligendi id. Duo te partem vituperata disputando. Usu dicat verear an, pro ea inani legere dolorem. An cum assentior gloriatur honestatis. Eu nonumes repudiare mel, inani interesset sea at, ius cu fabellas convenire liberavisse. Delicata abhorreant ne quo, an cum case integre delicatissimi. + + Duo ea legimus blandit, duo ne persius insolens rationibus. Sed aeque putent maiorum ex. Appareat iracundia vis at, laoreet molestiae eu nam, eu docendi scriptorem efficiantur qui. Facer quaerendum ex eam. + + Ei debet bonorum sapientem mei, cu corpora qualisque similique his. Ex mel volumus argumentum, aeterno adversarium vim id. Vidit probo consetetur id ius, sit case copiosae ne. Per at antiopam forensibus, eu dicant offendit ius, sea ad liber graeco. + + Vitae nullam delenit vel in. Ne vim choro sadipscing, eos ad everti aliquando. Cu legere laoreet nec, wisi quaerendum has an. Sed ut agam eripuit delectus, eu integre fuisset reprehendunt vim. Cum quod viris appellantur at, ea ius virtute conceptam, sed esse aeque neglegentur in. Alienum verterem nam id, eu purto duis disputando est. + + Eros perfecto at est. Quas complectitur pri ad. Eam cu discere phaedrum, sit ut dicam dolore. Eu putant minimum postulant sit. Agam corpora aliquando nec ut, noluisse lobortis intellegebat sit id, cu omnis conceptam eum. + + Eius autem adolescens ius an, pro populo mandamus eu. Falli adipisci ea sed, laboramus signiferumque sea ea. Ex labores percipit qui, vidit scaevola evertitur sed eu, mutat mandamus explicari in mel. Patrioque instructior consequuntur ea sea, cu cum iudico graeco dissentias. + + Ea ancillae invidunt reprimique duo, cu quando euismod eum, eos cu simul causae pertinacia. Ea vix fierent hendrerit. Agam dolore volutpat id his, noster graeco praesent ea per. Purto tritani explicari mei id. An sed utroque consequat contentiones. An duo eros debet, ea quo veritus interpretaris. Ne harum pertinacia honestatis eum, mei no facer erant. + + Nullam numquam salutandi usu no, in omnesque expetendis efficiendi vix. Ius erat vivendum ea. Vis an ferri omittam scripserit, te his erat quaeque. Ne his doming indoctum maiestatis, vis id dicat nostrud placerat. Eu tempor appareat dissentias mei, eos novum ignota aperiri ea. + + Ex dicant tibique sapientem cum, id pro liber facilis aliquando. Mel no everti abhorreant, te utroque eleifend vel. Id harum suscipit suscipiantur eum. Cu sed tritani deleniti urbanitas, vim id saepe fabellas. Vel autem aperiam democritum id, nisl inciderint at his. Mea ubique argumentum ei. + + Malis semper usu ei. Simul phaedrum conceptam ad duo, id pro cibo doctus deleniti, erat persius quo ne. Cu quo novum partem blandit. Ad usu alterum euismod. Ex nec tamquam deserunt nominati, dicit option ut sed. + + Duo ei posse officiis, in fabulas nusquam usu. Vel impetus principes ad, mel ferri pertinax ex, ad vel nemore hendrerit repudiandae. Diam hinc eius vix ex, iisque percipit evertitur ea per. Summo minim discere an mea, vim dicam semper ne, cu vix virtute noluisse maiestatis. + + Facer possim mea id. An usu omnis noster laboramus. Graeco tritani eam an, cu sea ignota habemus recteque, an vis simul posidonium. Te omnis evertitur vim, pro ad equidem postulant. Eum soleat fuisset cu, an sit bonorum omnesque. Est an dicant omittantur, id pri mutat impedit partiendo, et eirmod corpora rationibus vix. + + Duo commune philosophia te. An vero sale tempor vis, odio similique gloriatur ex pri, quo id meis appareat. Ei vel wisi iracundia assentior, sed ex nostro invidunt elaboraret, te justo atomorum vis. Sed quaeque nonumes detraxit et, no dolores definitiones vix. + + Vide mutat facilisis ei sea. Ut ubique sanctus pri. Nonumy ubique ius id, vis paulo putent dolorem ea. Cum at offendit liberavisse, ex est deleniti iracundia. At facer aeterno habemus vix. Has sale porro mnesarchum ea. Vix in sumo veniam eripuit, sea no erat scripta. +

+ + + \ No newline at end of file diff --git a/Source/Demo/Common/TestSamples/35.Breaking pages 2 - Tables.htm b/Source/Demo/Common/TestSamples/35.Breaking pages 2 - Tables.htm new file mode 100644 index 000000000..375ab6b93 --- /dev/null +++ b/Source/Demo/Common/TestSamples/35.Breaking pages 2 - Tables.htm @@ -0,0 +1,205 @@ + + + + + +

Default page breaks

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ + +

Avoid breaking rows

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ + +

Avoid breaking words in cells

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. + + Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. Te nec veri legimus fuisset, nec quod tota instructior ne, bonorum pertinacia te eos. Liber nihil salutatus duo ex, eum ullum nostrud suscipit te. Eam inermis accumsan ex, pri cu quis deleniti. Nostrud veritus sadipscing no qui, mea odio mundi periculis ei, qui ubique civibus splendide ei. Eam denique postulant adipiscing ex, id sit zril legendos.Lorem ipsum dolor sit amet, tota sonet accusamus ea eum, ex virtute lobortis est, no sed delicata repudiare constituam. Solum facete ut his, posse iuvaret instructior his no, sed choro equidem comprehensam ex. Eum an decore impetus, illum singulis salutandi mea ea. Eu vix lorem altera hendrerit. Pri at utinam tamquam, usu id delicata deterruisset. Ipsum nonumy ex pro, sit et nihil assentior concludaturque. Cu sea zril mediocrem, sea mazim efficiendi id. Numquam disputando te per, ea bonorum sententiae vix, et vim liber putent. +
+ + + \ No newline at end of file diff --git a/Source/Demo/Directory.Build.props b/Source/Demo/Directory.Build.props new file mode 100644 index 000000000..a8225ce90 --- /dev/null +++ b/Source/Demo/Directory.Build.props @@ -0,0 +1,6 @@ + + + Arthur Teplitzki + 1.5.1 + + diff --git a/Source/Demo/WPF/App.xaml.cs b/Source/Demo/WPF/App.xaml.cs index 5a23c097f..93a7c452b 100644 --- a/Source/Demo/WPF/App.xaml.cs +++ b/Source/Demo/WPF/App.xaml.cs @@ -43,7 +43,7 @@ private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args) if (stream != null) { byte[] assemblyRawBytes = new byte[stream.Length]; - stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length); + stream.ReadExactly(assemblyRawBytes); return Assembly.Load(assemblyRawBytes); } return null; diff --git a/Source/Demo/WPF/HtmlRenderer.Demo.WPF.csproj b/Source/Demo/WPF/HtmlRenderer.Demo.WPF.csproj index 8c26cdcc4..1cb8cb67f 100644 --- a/Source/Demo/WPF/HtmlRenderer.Demo.WPF.csproj +++ b/Source/Demo/WPF/HtmlRenderer.Demo.WPF.csproj @@ -1,119 +1,23 @@ - - - + - Debug - AnyCPU - {F02E0216-4AE3-474F-9381-FCB93411CDB0} + net8.0-windows WinExe - Properties TheArtOfDev.HtmlRenderer.Demo.WPF HtmlRendererWpfDemo - v4.0 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - - ..\..\ - true - - - x86 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + true + true + true html.ico - - - - - - - - - ..\..\packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.DataGrid.dll - - - ..\..\packages\Extended.Wpf.Toolkit.2.2.1\lib\net40\Xceed.Wpf.Toolkit.dll - - - - - MSBuild:Compile - Designer - - - GenerateImageWindow.xaml - - - SampleWindow.xaml - - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - DemoWindow.xaml - Code - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - Designer - MSBuild:Compile - - - - - - MainControl.xaml - - - Code - - - {7e4e8db5-85ad-4388-bdcb-38c6f423b8b0} - HtmlRenderer.WPF - - - {fe611685-391f-4e3e-b27e-d3150e51e49b} - HtmlRenderer - - - {2390B71F-9400-47F4-B23A-7F2649C87D35} - HtmlRenderer.Demo.Common - + + + @@ -122,28 +26,6 @@ - + - - - - - %(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension) - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Source/Demo/WPF/HtmlRenderingHelper.cs b/Source/Demo/WPF/HtmlRenderingHelper.cs index 276737b1b..2fb88670e 100644 --- a/Source/Demo/WPF/HtmlRenderingHelper.cs +++ b/Source/Demo/WPF/HtmlRenderingHelper.cs @@ -65,7 +65,7 @@ public static BitmapEncoder GetBitmapEncoder(string ext) /// /// Handle stylesheet resolve. /// - public static void OnStylesheetLoad(object sender, RoutedEvenArgs args) + public static void OnStylesheetLoad(object sender, RoutedEventArgs args) { DemoUtils.OnStylesheetLoad(sender, args.Data); } @@ -105,7 +105,7 @@ public static BitmapImage ImageFromStream(Stream stream) /// /// On image load in renderer set the image by event async. /// - public static void OnImageLoad(object sender, RoutedEvenArgs args) + public static void OnImageLoad(object sender, RoutedEventArgs args) { ImageLoad(args.Data); } @@ -136,13 +136,13 @@ public static void ImageLoad(HtmlImageLoadEventArgs e) ThreadPool.QueueUserWorkItem(state => { Thread.Sleep(delay); - e.Callback("https://fbcdn-sphotos-a-a.akamaihd.net/hphotos-ak-snc7/c0.44.403.403/p403x403/318890_10151195988833836_1081776452_n.jpg"); + e.Callback("https://images.unsplash.com/photo-1608848461950-0fe51dfc41cb?w=500&q=80"); }); return; } else { - e.Callback("http://sphotos-a.xx.fbcdn.net/hphotos-ash4/c22.0.403.403/p403x403/263440_10152243591765596_773620816_n.jpg"); + e.Callback("https://images.unsplash.com/photo-1608848461950-0fe51dfc41cb?w=500&q=80"); return; } } diff --git a/Source/Demo/WPF/MainControl.xaml.cs b/Source/Demo/WPF/MainControl.xaml.cs index 215d3b13c..00fd7b5c5 100644 --- a/Source/Demo/WPF/MainControl.xaml.cs +++ b/Source/Demo/WPF/MainControl.xaml.cs @@ -326,7 +326,7 @@ private void OnColoredCheckbox_click(object sender, RoutedEventArgs e) /// /// Show error raised from html renderer. /// - private void OnRenderError(object sender, RoutedEvenArgs args) + private void OnRenderError(object sender, RoutedEventArgs args) { Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(args.Data.Message + (args.Data.Exception != null ? "\r\n" + args.Data.Exception : null), "Error in Html Renderer", MessageBoxButton.OK))); } @@ -334,7 +334,7 @@ private void OnRenderError(object sender, RoutedEvenArgs /// On specific link click handle it here. /// - private void OnLinkClicked(object sender, RoutedEvenArgs args) + private void OnLinkClicked(object sender, RoutedEventArgs args) { if (args.Data.Link == "SayHello") { diff --git a/Source/Demo/WPF/Properties/AssemblyInfo.cs b/Source/Demo/WPF/Properties/AssemblyInfo.cs deleted file mode 100644 index d5c8b4eb2..000000000 --- a/Source/Demo/WPF/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; -using System.Windows; - -// 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: AssemblyTitle("HTML Renderer WPF Demo")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("HTML Renderer WPF Demo")] -[assembly: AssemblyCopyright("Copyright © 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) - )] - - -// 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")] \ No newline at end of file diff --git a/Source/Demo/WinForms/DemoForm.cs b/Source/Demo/WinForms/DemoForm.cs index 3e7287b70..b408d3176 100644 --- a/Source/Demo/WinForms/DemoForm.cs +++ b/Source/Demo/WinForms/DemoForm.cs @@ -40,7 +40,7 @@ public partial class DemoForm : Form /// public DemoForm() { - SamplesLoader.Init(HtmlRenderingHelper.IsRunningOnMono() ? "Mono" : "WinForms", typeof(HtmlRender).Assembly.GetName().Version.ToString()); + SamplesLoader.Init("WinForms", typeof(HtmlRender).Assembly.GetName().Version.ToString()); InitializeComponent(); @@ -59,8 +59,8 @@ public DemoForm() LoadCustomFonts(); - _showIEViewTSSB.Enabled = !HtmlRenderingHelper.IsRunningOnMono(); - _generatePdfTSB.Enabled = !HtmlRenderingHelper.IsRunningOnMono(); + _showIEViewTSSB.Enabled = true; + _generatePdfTSB.Enabled = true; } /// @@ -145,10 +145,12 @@ private void OnGeneratePdf_Click(object sender, EventArgs e) config.SetMargins(20); var doc = PdfGenerator.GeneratePdf(_mainControl.GetHtml(), config, null, DemoUtils.OnStylesheetLoad, HtmlRenderingHelper.OnImageLoadPdfSharp); + var tmpFile = Path.GetTempFileName(); - tmpFile = Path.GetFileNameWithoutExtension(tmpFile) + ".pdf"; - doc.Save(tmpFile); - Process.Start(tmpFile); + var pdfFile = Path.ChangeExtension(tmpFile, ".pdf"); // Preserves the full path + doc.Save(pdfFile); + + Process.Start(new ProcessStartInfo(pdfFile) { UseShellExecute = true }); } /// diff --git a/Source/Demo/WinForms/GenerateImageForm.cs b/Source/Demo/WinForms/GenerateImageForm.cs index 5f966a8f2..f4e8a4577 100644 --- a/Source/Demo/WinForms/GenerateImageForm.cs +++ b/Source/Demo/WinForms/GenerateImageForm.cs @@ -51,8 +51,8 @@ public GenerateImageForm(string html) } _textRenderingHintTSCB.SelectedItem = TextRenderingHint.AntiAlias.ToString(); - _useGdiPlusTSB.Enabled = !HtmlRenderingHelper.IsRunningOnMono(); - _backgroundColorTSB.Enabled = !HtmlRenderingHelper.IsRunningOnMono(); + _useGdiPlusTSB.Enabled = true; + _backgroundColorTSB.Enabled = true; } private void OnSaveToFile_Click(object sender, EventArgs e) @@ -103,7 +103,7 @@ private void GenerateImage() TextRenderingHint textRenderingHint = (TextRenderingHint)Enum.Parse(typeof(TextRenderingHint), _textRenderingHintTSCB.SelectedItem.ToString()); Image img; - if (_useGdiPlusTSB.Checked || HtmlRenderingHelper.IsRunningOnMono()) + if (_useGdiPlusTSB.Checked) { img = HtmlRender.RenderToImageGdiPlus(_html, _pictureBox.ClientSize, textRenderingHint, null, DemoUtils.OnStylesheetLoad, HtmlRenderingHelper.OnImageLoad); } diff --git a/Source/Demo/WinForms/HtmlRenderer.Demo.WinForms.csproj b/Source/Demo/WinForms/HtmlRenderer.Demo.WinForms.csproj index 6d03ec0ca..e6b47dcc7 100644 --- a/Source/Demo/WinForms/HtmlRenderer.Demo.WinForms.csproj +++ b/Source/Demo/WinForms/HtmlRenderer.Demo.WinForms.csproj @@ -1,196 +1,28 @@ - - + - Debug - AnyCPU - 8.0.50727 - 2.0 - {8AD34FE8-8382-4A8A-B3AA-A0392ED42423} + net8.0-windows WinExe - Properties TheArtOfDev.HtmlRenderer.Demo.WinForms HtmlRendererWinFormsDemo - v2.0 - - - - - 2.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - ..\..\ - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - x86 - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - x86 - false + true + true + true html.ico - - ..\..\packages\PDFsharp.1.32.3057.0\lib\net20\PdfSharp.dll - - - ..\..\packages\PDFsharp.1.32.3057.0\lib\net20\PdfSharp.Charting.dll - - - - - - - - - - Form - - - GenerateImageForm.cs - - - + UserControl - - MainControl.cs - - - Form - - - PerfForm.cs - - - Form - - - DemoForm.cs - - - - - GenerateImageForm.cs - - - MainControl.cs - - - PerfForm.cs - Designer - - - Designer - DemoForm.cs - - - Form - - - SampleForm.cs - - - - - Designer - SampleForm.cs - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - - - - - {ca249f5d-9285-40a6-b217-5889ef79fd7e} - HtmlRenderer.PdfSharp - - - {1b058920-24b4-4140-8ae7-c8c6c38ca52d} - HtmlRenderer.WinForms - - - {fe611685-391f-4e3e-b27e-d3150e51e49b} - HtmlRenderer - - - {2390b71f-9400-47f4-b23a-7f2649c87d35} - HtmlRenderer.Demo.Common - + + + + - - - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - %(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension) - - - - \ No newline at end of file diff --git a/Source/Demo/WinForms/HtmlRenderingHelper.cs b/Source/Demo/WinForms/HtmlRenderingHelper.cs index d719f4ff5..33b6ae5e7 100644 --- a/Source/Demo/WinForms/HtmlRenderingHelper.cs +++ b/Source/Demo/WinForms/HtmlRenderingHelper.cs @@ -10,13 +10,14 @@ // - Sun Tsu, // "The Art of War" +using PdfSharp.Drawing; using System; using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Threading; using TheArtOfDev.HtmlRenderer.Core.Entities; using TheArtOfDev.HtmlRenderer.Demo.Common; -using PdfSharp.Drawing; namespace TheArtOfDev.HtmlRenderer.Demo.WinForms { @@ -31,15 +32,6 @@ internal static class HtmlRenderingHelper #endregion - - /// - /// Check if currently running in mono. - /// - public static bool IsRunningOnMono() - { - return Type.GetType("Mono.Runtime") != null; - } - /// /// Create image to be used to fill background so it will be clear that what's on top is transparent. /// @@ -79,7 +71,18 @@ public static Image TryLoadResourceImage(string src) public static XImage TryLoadResourceXImage(string src) { var img = TryLoadResourceImage(src); - return img != null ? XImage.FromGdiPlusImage(img) : null; + XImage xImg; + + if (img == null) + return null; + + using (var ms = new MemoryStream()) + { + img.Save(ms, img.RawFormat); + xImg = img != null ? XImage.FromStream(ms) : null; + } + + return xImg; } /// @@ -104,7 +107,17 @@ public static void OnImageLoadPdfSharp(object sender, HtmlImageLoadEventArgs e) public static void ImageLoad(HtmlImageLoadEventArgs e, bool pdfSharp) { var img = TryLoadResourceImage(e.Src); - var xImg = img != null ? XImage.FromGdiPlusImage(img) : null; + XImage xImg = null; + + if (img != null) + { + using (var ms = new MemoryStream()) + { + img.Save(ms, img.RawFormat); + xImg = img != null ? XImage.FromStream(ms) : null; + } + } + object imgObj; if (pdfSharp) imgObj = xImg; @@ -122,13 +135,13 @@ public static void ImageLoad(HtmlImageLoadEventArgs e, bool pdfSharp) ThreadPool.QueueUserWorkItem(state => { Thread.Sleep(delay); - e.Callback("https://fbcdn-sphotos-a-a.akamaihd.net/hphotos-ak-snc7/c0.44.403.403/p403x403/318890_10151195988833836_1081776452_n.jpg"); + e.Callback("https://images.unsplash.com/photo-1608848461950-0fe51dfc41cb?w=500&q=80"); }); return; } else { - e.Callback("http://sphotos-a.xx.fbcdn.net/hphotos-ash4/c22.0.403.403/p403x403/263440_10152243591765596_773620816_n.jpg"); + e.Callback("https://images.unsplash.com/photo-1608848461950-0fe51dfc41cb?w=500&q=80"); return; } } diff --git a/Source/Demo/WinForms/MainControl.cs b/Source/Demo/WinForms/MainControl.cs index 696fc032c..c683e99e2 100644 --- a/Source/Demo/WinForms/MainControl.cs +++ b/Source/Demo/WinForms/MainControl.cs @@ -11,6 +11,7 @@ // "The Art of War" using System; +using System.ComponentModel; using System.Drawing; using System.Drawing.Imaging; using System.IO; @@ -72,6 +73,8 @@ public MainControl() /// /// used ignore html editor updates when updating separately /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool UpdateLock { get { return _updateLock; } @@ -81,6 +84,8 @@ public bool UpdateLock /// /// In IE view if to show original html or the html generated from the html control /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool UseGeneratedHtml { get { return _useGeneratedHtml; } @@ -186,7 +191,7 @@ private void OnSamplesTreeViewAfterSelect(object sender, TreeViewEventArgs e) { _updateLock = true; - if (!HtmlRenderingHelper.IsRunningOnMono() && e.Node.Parent.Text != PerformanceSamplesTreeNodeName) + if (e.Node.Parent.Text != PerformanceSamplesTreeNodeName) SetColoredText(sample.Html); else _htmlEditor.Text = sample.Html; diff --git a/Source/Demo/WinForms/Program.cs b/Source/Demo/WinForms/Program.cs index f01eb6d0a..cba933ec4 100644 --- a/Source/Demo/WinForms/Program.cs +++ b/Source/Demo/WinForms/Program.cs @@ -14,6 +14,7 @@ using System.Globalization; using System.IO; using System.Reflection; +using System.Text; using System.Windows.Forms; namespace TheArtOfDev.HtmlRenderer.Demo.WinForms @@ -28,6 +29,8 @@ private static void Main() { AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly; + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new DemoForm()); @@ -52,7 +55,7 @@ private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args) if (stream != null) { byte[] assemblyRawBytes = new byte[stream.Length]; - stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length); + stream.ReadExactly(assemblyRawBytes); return Assembly.Load(assemblyRawBytes); } return null; diff --git a/Source/Demo/WinForms/Properties/AssemblyInfo.cs b/Source/Demo/WinForms/Properties/AssemblyInfo.cs deleted file mode 100644 index 2719715e7..000000000 --- a/Source/Demo/WinForms/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// 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: AssemblyTitle("HTML Renderer WinForms Demo")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("HTML Renderer WinForms Demo")] -[assembly: AssemblyCopyright("Copyright © 2008")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("3098581d-210a-4748-bcda-4b9a6b34a91a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Source/Demo/WinForms/packages.config b/Source/Demo/WinForms/packages.config index 0dec73c8f..2f092fd78 100644 --- a/Source/Demo/WinForms/packages.config +++ b/Source/Demo/WinForms/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/Source/Directory.Build.props b/Source/Directory.Build.props new file mode 100644 index 000000000..dfc83f317 --- /dev/null +++ b/Source/Directory.Build.props @@ -0,0 +1,22 @@ + + + HTML Renderer + Arthur Teplitzki + Arthur Teplitzki + Open source hosted on GitHub + Copyright © 2008-2025 + 1.6.0-dev + 1.6.0.0 + 1.6.0.0 + README.md + BSD-3-Clause + https://codeplexarchive.org/project/HtmlRenderer + html.png + false + See https://github.com/ArthurHub/HTML-Renderer/releases. + false + + + + + diff --git a/Source/HtmlRenderer.PdfSharp/Adapters/GraphicsAdapter.cs b/Source/HtmlRenderer.PdfSharp/Adapters/GraphicsAdapter.cs index 9af8a9790..c6d406c58 100644 --- a/Source/HtmlRenderer.PdfSharp/Adapters/GraphicsAdapter.cs +++ b/Source/HtmlRenderer.PdfSharp/Adapters/GraphicsAdapter.cs @@ -10,12 +10,12 @@ // - Sun Tsu, // "The Art of War" +using PdfSharp.Drawing; using System; using TheArtOfDev.HtmlRenderer.Adapters; using TheArtOfDev.HtmlRenderer.Adapters.Entities; using TheArtOfDev.HtmlRenderer.Core.Utils; using TheArtOfDev.HtmlRenderer.PdfSharp.Utilities; -using PdfSharp.Drawing; namespace TheArtOfDev.HtmlRenderer.PdfSharp.Adapters { @@ -49,7 +49,6 @@ static GraphicsAdapter() _stringFormat = new XStringFormat(); _stringFormat.Alignment = XStringAlignment.Near; _stringFormat.LineAlignment = XLineAlignment.Near; - _stringFormat.FormatFlags = XStringFormatFlags.MeasureTrailingSpaces; } /// diff --git a/Source/HtmlRenderer.PdfSharp/Adapters/PdfSharpAdapter.cs b/Source/HtmlRenderer.PdfSharp/Adapters/PdfSharpAdapter.cs index 564b2539b..e5fa309c0 100644 --- a/Source/HtmlRenderer.PdfSharp/Adapters/PdfSharpAdapter.cs +++ b/Source/HtmlRenderer.PdfSharp/Adapters/PdfSharpAdapter.cs @@ -10,13 +10,14 @@ // - Sun Tsu, // "The Art of War" +using PdfSharp.Drawing; +using PdfSharp.Pdf; using System.Drawing; +using System.Drawing.Text; using System.IO; using TheArtOfDev.HtmlRenderer.Adapters; using TheArtOfDev.HtmlRenderer.Adapters.Entities; using TheArtOfDev.HtmlRenderer.PdfSharp.Utilities; -using PdfSharp.Drawing; -using PdfSharp.Pdf; namespace TheArtOfDev.HtmlRenderer.PdfSharp.Adapters { @@ -43,9 +44,11 @@ private PdfSharpAdapter() AddFontFamilyMapping("monospace", "Courier New"); AddFontFamilyMapping("Helvetica", "Arial"); - foreach (var family in XFontFamily.Families) + var families = new InstalledFontCollection(); + + foreach (var family in families.Families) { - AddFontFamily(new FontFamilyAdapter(family)); + AddFontFamily(new FontFamilyAdapter(new XFontFamily(family.Name))); } } @@ -59,7 +62,15 @@ public static PdfSharpAdapter Instance protected override RColor GetColorInt(string colorName) { - return Utils.Convert(XColor.FromName(colorName)); + try + { + var color = Color.FromKnownColor((KnownColor)System.Enum.Parse(typeof(KnownColor), colorName, true)); + return Utils.Convert(color); + } + catch + { + return RColor.Empty; + } } protected override RPen CreatePen(RColor color) @@ -103,7 +114,7 @@ protected override RImage ConvertImageInt(object image) protected override RImage ImageFromStreamInt(Stream memoryStream) { - return new ImageAdapter(XImage.FromGdiPlusImage(Image.FromStream(memoryStream))); + return new ImageAdapter(XImage.FromStream(memoryStream)); } protected override RFont CreateFontInt(string family, double size, RFontStyle style) diff --git a/Source/HtmlRenderer.PdfSharp/HtmlContainer.cs b/Source/HtmlRenderer.PdfSharp/HtmlContainer.cs index a1825dee9..9339fd562 100644 --- a/Source/HtmlRenderer.PdfSharp/HtmlContainer.cs +++ b/Source/HtmlRenderer.PdfSharp/HtmlContainer.cs @@ -10,14 +10,15 @@ // - Sun Tsu, // "The Art of War" +using PdfSharp.Drawing; using System; using System.Collections.Generic; +using TheArtOfDev.HtmlRenderer.Adapters.Entities; using TheArtOfDev.HtmlRenderer.Core; using TheArtOfDev.HtmlRenderer.Core.Entities; using TheArtOfDev.HtmlRenderer.Core.Utils; using TheArtOfDev.HtmlRenderer.PdfSharp.Adapters; using TheArtOfDev.HtmlRenderer.PdfSharp.Utilities; -using PdfSharp.Drawing; namespace TheArtOfDev.HtmlRenderer.PdfSharp { @@ -161,6 +162,79 @@ public XSize ActualSize internal set { _htmlContainerInt.ActualSize = Utils.Convert(value); } } + public XSize PageSize { + get + { + return new XSize(_htmlContainerInt.PageSize.Width, _htmlContainerInt.PageSize.Height); + } + set + { + _htmlContainerInt.PageSize = new RSize(value.Width, value.Height); + } + } + + /// + /// the top margin between the page start and the text + /// + public int MarginTop + { + get { return _htmlContainerInt.MarginTop; } + set + { + if (value > -1) + _htmlContainerInt.MarginTop = value; + } + } + + /// + /// the bottom margin between the page end and the text + /// + public int MarginBottom + { + get { return _htmlContainerInt.MarginBottom; } + set + { + if (value > -1) + _htmlContainerInt.MarginBottom = value; + } + } + + /// + /// the left margin between the page start and the text + /// + public int MarginLeft + { + get { return _htmlContainerInt.MarginLeft; } + set + { + if (value > -1) + _htmlContainerInt.MarginLeft = value; + } + } + + /// + /// the right margin between the page end and the text + /// + public int MarginRight + { + get { return _htmlContainerInt.MarginRight; } + set + { + if (value > -1) + _htmlContainerInt.MarginRight = value; + } + } + + /// + /// Set all 4 margins to the given value. + /// + /// + public void SetMargins(int value) + { + if (value > -1) + _htmlContainerInt.SetMargins(value); + } + /// /// Get the currently selected text segment in the html. /// diff --git a/Source/HtmlRenderer.PdfSharp/HtmlRenderer.PdfSharp.csproj b/Source/HtmlRenderer.PdfSharp/HtmlRenderer.PdfSharp.csproj index c3a449718..2ff483a96 100644 --- a/Source/HtmlRenderer.PdfSharp/HtmlRenderer.PdfSharp.csproj +++ b/Source/HtmlRenderer.PdfSharp/HtmlRenderer.PdfSharp.csproj @@ -1,89 +1,38 @@ - - - + - Debug - AnyCPU - {CA249F5D-9285-40A6-B217-5889EF79FD7E} + net8.0-windows Library - Properties TheArtOfDev.HtmlRenderer.PdfSharp - HtmlRenderer.PdfSharp - v2.0 - 512 - ..\ - true + true + true + true - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + + + HtmlRenderer.PdfSharp + HTML Renderer for PDF using PdfSharp + html render renderer draw pdfsharp + PDF document generator from HTML snippet, 100% managed (C#), High performance library using PdfSharp. + +Features and Benefits: +--- +* 100% managed code depends only on PdfSharp library, no ActiveX, no MSHTML. +* Extensive HTML 4.01 and CSS level 2 specifications support. +* Support separating CSS from HTML by loading stylesheet code separately. +* Handles "real world" malformed HTML, it doesn't have to be XHTML. +* Lightweight, only two DLLs (~300K). +* High performance and low memory footprint. +* Extendable and configurable. + PDF document generator from HTML snippet, 100% managed (C#), High performance library using PdfSharp. - - ..\packages\PDFsharp.1.32.3057.0\lib\net20\PdfSharp.dll - - - ..\packages\PDFsharp.1.32.3057.0\lib\net20\PdfSharp.Charting.dll - - - - - - - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - - + - - {fe611685-391f-4e3e-b27e-d3150e51e49b} - HtmlRenderer - + - + + - - - - - - This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - \ No newline at end of file diff --git a/Source/HtmlRenderer.PdfSharp/PdfGenerator.cs b/Source/HtmlRenderer.PdfSharp/PdfGenerator.cs index c8c167e05..0f15c5a7a 100644 --- a/Source/HtmlRenderer.PdfSharp/PdfGenerator.cs +++ b/Source/HtmlRenderer.PdfSharp/PdfGenerator.cs @@ -10,14 +10,14 @@ // - Sun Tsu, // "The Art of War" +using PdfSharp; +using PdfSharp.Drawing; +using PdfSharp.Pdf; using System; using TheArtOfDev.HtmlRenderer.Core; using TheArtOfDev.HtmlRenderer.Core.Entities; using TheArtOfDev.HtmlRenderer.Core.Utils; using TheArtOfDev.HtmlRenderer.PdfSharp.Adapters; -using PdfSharp; -using PdfSharp.Drawing; -using PdfSharp.Pdf; namespace TheArtOfDev.HtmlRenderer.PdfSharp { @@ -154,6 +154,11 @@ public static void AddPdfPages(PdfDocument document, string html, PdfGenerateCon container.Location = new XPoint(config.MarginLeft, config.MarginTop); container.MaxSize = new XSize(pageSize.Width, 0); container.SetHtml(html, cssData); + container.PageSize = pageSize; + container.MarginBottom = config.MarginBottom; + container.MarginLeft = config.MarginLeft; + container.MarginRight = config.MarginRight; + container.MarginTop = config.MarginTop; // layout the HTML with the page width restriction to know how many pages are required using (var measure = XGraphics.CreateMeasureContext(pageSize, XGraphicsUnit.Point, XPageDirection.Downwards)) @@ -171,7 +176,8 @@ public static void AddPdfPages(PdfDocument document, string html, PdfGenerateCon using (var g = XGraphics.FromPdfPage(page)) { - g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height)); + //g.IntersectClip(new XRect(config.MarginLeft, config.MarginTop, pageSize.Width, pageSize.Height)); + g.IntersectClip(new XRect(0, 0, page.Width, page.Height)); container.ScrollOffset = new XPoint(0, scrollOffset); container.PerformPaint(g); @@ -212,6 +218,11 @@ private static void HandleLinks(PdfDocument document, HtmlContainer container, X { // document links to the same page as the link is not allowed int anchorPageIdx = (int)(anchorRect.Value.Top / pageSize.Height); + + // in case that not find the page index, set to the first page. + if (anchorPageIdx == 0) + anchorPageIdx = 1; + if (i != anchorPageIdx) document.Pages[i].AddDocumentLink(new PdfRectangle(xRect), anchorPageIdx); } @@ -227,4 +238,4 @@ private static void HandleLinks(PdfDocument document, HtmlContainer container, X #endregion } -} \ No newline at end of file +} diff --git a/Source/HtmlRenderer.PdfSharp/README.md b/Source/HtmlRenderer.PdfSharp/README.md new file mode 100644 index 000000000..f1af8def0 --- /dev/null +++ b/Source/HtmlRenderer.PdfSharp/README.md @@ -0,0 +1,35 @@ +# Welcome to the HTML Renderer PdfSharp library! + +This library provides the ability to generate PDF documents from HTML snippets using static rendering code. +For more info see HTML Renderer on GitHub: https://github.com/ArthurHub/HTML-Renderer + +## DEMO APPLICATION + +HTML Renderer Demo application showcases HTML Renderer capabilities, use it to explore and learn +on the library: https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Demo%20application + +## FEEDBACK / RELEASE NOTES + +If you have problems, wish to report a bug, or have a suggestion, please open an issue on the +HTML Renderer issue page: https://github.com/ArthurHub/HTML-Renderer/issues + +For full release notes and all versions see: https://github.com/ArthurHub/HTML-Renderer/releases + +## QUICK START + +For more Quick Start see: https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Documentation + +--- + +## Quick Start: Create PDF from HTML snippet using PdfSharp + +```csharp +class Program +{ + private static void Main(string[] args) + { + PdfDocument pdf = PdfGenerator.GeneratePdf("

Hello World

This is html rendered text

", PageSize.A4); + pdf.Save("document.pdf"); + } +} +``` diff --git a/Source/HtmlRenderer.PdfSharp/Utilities/Utils.cs b/Source/HtmlRenderer.PdfSharp/Utilities/Utils.cs index cf3a8e932..59ac2c4b5 100644 --- a/Source/HtmlRenderer.PdfSharp/Utilities/Utils.cs +++ b/Source/HtmlRenderer.PdfSharp/Utilities/Utils.cs @@ -10,9 +10,9 @@ // - Sun Tsu, // "The Art of War" +using PdfSharp.Drawing; using System.Drawing; using TheArtOfDev.HtmlRenderer.Adapters.Entities; -using PdfSharp.Drawing; namespace TheArtOfDev.HtmlRenderer.PdfSharp.Utilities { @@ -81,20 +81,20 @@ public static XRect Convert(RRect r) } /// - /// Convert from WinForms color to core color. + /// Convert from core color to WinForms color. /// - public static RColor Convert(XColor c) + public static XColor Convert(RColor c) { - var gc = c.ToGdiColor(); - return RColor.FromArgb(gc.A, gc.R, gc.G, gc.B); + return XColor.FromArgb(c.A, c.R, c.G, c.B); } /// - /// Convert from core color to WinForms color. + /// Convert from color to WinForms color. /// - public static XColor Convert(RColor c) + public static RColor Convert(Color c) { - return XColor.FromArgb(Color.FromArgb(c.A, c.R, c.G, c.B)); + return RColor.FromArgb(c.A, c.R, c.G, c.B); } + } } \ No newline at end of file diff --git a/Source/HtmlRenderer.PdfSharp/packages.config b/Source/HtmlRenderer.PdfSharp/packages.config deleted file mode 100644 index 4369cba8c..000000000 --- a/Source/HtmlRenderer.PdfSharp/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/Source/HtmlRenderer.WPF/Adapters/FontFamilyAdapter.cs b/Source/HtmlRenderer.WPF/Adapters/FontFamilyAdapter.cs index a3ec7734d..a517ad5ec 100644 --- a/Source/HtmlRenderer.WPF/Adapters/FontFamilyAdapter.cs +++ b/Source/HtmlRenderer.WPF/Adapters/FontFamilyAdapter.cs @@ -10,6 +10,8 @@ // - Sun Tsu, // "The Art of War" +using System.Globalization; +using System.Linq; using System.Windows.Markup; using System.Windows.Media; using TheArtOfDev.HtmlRenderer.Adapters; @@ -24,7 +26,7 @@ internal sealed class FontFamilyAdapter : RFontFamily /// /// Default language to get font family name by /// - private static readonly XmlLanguage _xmlLanguage = XmlLanguage.GetLanguage("en-us"); + private static readonly XmlLanguage _xmlLanguage = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag); /// /// the underline win-forms font. @@ -42,25 +44,8 @@ public FontFamilyAdapter(FontFamily fontFamily) /// /// the underline WPF font family. /// - public FontFamily FontFamily - { - get { return _fontFamily; } - } + public FontFamily FontFamily => _fontFamily; - public override string Name - { - get - { - string name = _fontFamily.FamilyNames[_xmlLanguage]; - if (string.IsNullOrEmpty(name)) - { - foreach (var familyName in _fontFamily.FamilyNames) - { - return familyName.Value; - } - } - return name; - } - } + public override string Name => _fontFamily.FamilyNames.TryGetValue(_xmlLanguage, out var name) ? name : _fontFamily.FamilyNames.FirstOrDefault().Value; } } \ No newline at end of file diff --git a/Source/HtmlRenderer.WPF/Adapters/GraphicsAdapter.cs b/Source/HtmlRenderer.WPF/Adapters/GraphicsAdapter.cs index d61bef4ca..b6685511d 100644 --- a/Source/HtmlRenderer.WPF/Adapters/GraphicsAdapter.cs +++ b/Source/HtmlRenderer.WPF/Adapters/GraphicsAdapter.cs @@ -122,7 +122,7 @@ public override RSize MeasureString(string str, RFont font) if (width <= 0) { - var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, Brushes.Red); + var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, Brushes.Red, 1.0); return new RSize(formattedText.WidthIncludingTrailingWhitespace, formattedText.Height); } @@ -164,7 +164,7 @@ public override void MeasureString(string str, RFont font, double maxWidth, out if (!handled) { - var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, Brushes.Red); + var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, Brushes.Red, 1.0); charFit = str.Length; charFitWidth = formattedText.WidthIncludingTrailingWhitespace; } @@ -200,14 +200,23 @@ public override void DrawString(string str, RFont font, RColor color, RPoint poi point.X += rtl ? 96d / 72d * font.Size * width : 0; glyphRendered = true; - var glyphRun = new GlyphRun(glyphTypeface, rtl ? 1 : 0, false, 96d / 72d * font.Size, glyphs, Utils.ConvertRound(point), widths, null, null, null, null, null, null); + var wpfPoint = Utils.ConvertRound(point); + var glyphRun = new GlyphRun(glyphTypeface, rtl ? 1 : 0, + false, 96d / 72d * font.Size, 1.0f, glyphs, + wpfPoint, widths, null, null, null, null, null, null); + + var guidelines = new GuidelineSet(); + guidelines.GuidelinesX.Add(wpfPoint.X); + guidelines.GuidelinesY.Add(wpfPoint.Y); + _g.PushGuidelineSet(guidelines); _g.DrawGlyphRun(colorConv, glyphRun); + _g.Pop(); } } if (!glyphRendered) { - var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, rtl ? FlowDirection.RightToLeft : FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, colorConv); + var formattedText = new FormattedText(str, CultureInfo.CurrentCulture, rtl ? FlowDirection.RightToLeft : FlowDirection.LeftToRight, ((FontAdapter)font).Font, 96d / 72d * font.Size, colorConv, 1.0); point.X += rtl ? formattedText.Width : 0; _g.DrawText(formattedText, Utils.ConvertRound(point)); } @@ -318,4 +327,4 @@ public override void DrawPolygon(RBrush brush, RPoint[] points) #endregion } -} \ No newline at end of file +} diff --git a/Source/HtmlRenderer.WPF/Adapters/WpfAdapter.cs b/Source/HtmlRenderer.WPF/Adapters/WpfAdapter.cs index 13f5eed55..3ea88d9c4 100644 --- a/Source/HtmlRenderer.WPF/Adapters/WpfAdapter.cs +++ b/Source/HtmlRenderer.WPF/Adapters/WpfAdapter.cs @@ -63,7 +63,13 @@ private WpfAdapter() foreach (var family in Fonts.SystemFontFamilies) { - AddFontFamily(new FontFamilyAdapter(family)); + try + { + AddFontFamily(new FontFamilyAdapter(family)); + } + catch + { + } } } @@ -201,13 +207,10 @@ private static Brush GetSolidColorBrush(RColor color) /// private static FontStyle GetFontStyle(RFontStyle style) { - switch (style) - { - case RFontStyle.Italic: - return FontStyles.Italic; - default: - return FontStyles.Normal; - } + if ((style & RFontStyle.Italic) == RFontStyle.Italic) + return FontStyles.Italic; + + return FontStyles.Normal; } /// @@ -215,13 +218,10 @@ private static FontStyle GetFontStyle(RFontStyle style) /// private static FontWeight GetFontWidth(RFontStyle style) { - switch (style) - { - case RFontStyle.Bold: - return FontWeights.Bold; - default: - return FontWeights.Normal; - } + if ((style & RFontStyle.Bold) == RFontStyle.Bold) + return FontWeights.Bold; + + return FontWeights.Normal; } #endregion diff --git a/Source/HtmlRenderer.WPF/HtmlContainer.cs b/Source/HtmlRenderer.WPF/HtmlContainer.cs index 13835c4ce..d7d37d5be 100644 --- a/Source/HtmlRenderer.WPF/HtmlContainer.cs +++ b/Source/HtmlRenderer.WPF/HtmlContainer.cs @@ -19,7 +19,6 @@ using TheArtOfDev.HtmlRenderer.Adapters.Entities; using TheArtOfDev.HtmlRenderer.Core; using TheArtOfDev.HtmlRenderer.Core.Entities; -using TheArtOfDev.HtmlRenderer.Core.Parse; using TheArtOfDev.HtmlRenderer.Core.Utils; using TheArtOfDev.HtmlRenderer.WPF.Adapters; using TheArtOfDev.HtmlRenderer.WPF.Utilities; @@ -49,6 +48,7 @@ public sealed class HtmlContainer : IDisposable public HtmlContainer() { _htmlContainerInt = new HtmlContainerInt(WpfAdapter.Instance); + _htmlContainerInt.PageSize = new RSize(99999, 99999); } /// diff --git a/Source/HtmlRenderer.WPF/HtmlControl.cs b/Source/HtmlRenderer.WPF/HtmlControl.cs index 752f5bd99..be4e241fd 100644 --- a/Source/HtmlRenderer.WPF/HtmlControl.cs +++ b/Source/HtmlRenderer.WPF/HtmlControl.cs @@ -388,7 +388,7 @@ protected override void OnKeyDown(KeyEventArgs e) /// protected virtual void OnLoadComplete(EventArgs e) { - RoutedEventArgs newEventArgs = new RoutedEvenArgs(LoadCompleteEvent, this, e); + RoutedEventArgs newEventArgs = new RoutedEventArgs(LoadCompleteEvent, this, e); RaiseEvent(newEventArgs); } @@ -397,7 +397,7 @@ protected virtual void OnLoadComplete(EventArgs e) ///
protected virtual void OnLinkClicked(HtmlLinkClickedEventArgs e) { - RoutedEventArgs newEventArgs = new RoutedEvenArgs(LinkClickedEvent, this, e); + RoutedEventArgs newEventArgs = new RoutedEventArgs(LinkClickedEvent, this, e); RaiseEvent(newEventArgs); } @@ -406,7 +406,7 @@ protected virtual void OnLinkClicked(HtmlLinkClickedEventArgs e) ///
protected virtual void OnRenderError(HtmlRenderErrorEventArgs e) { - RoutedEventArgs newEventArgs = new RoutedEvenArgs(RenderErrorEvent, this, e); + RoutedEventArgs newEventArgs = new RoutedEventArgs(RenderErrorEvent, this, e); RaiseEvent(newEventArgs); } @@ -415,7 +415,7 @@ protected virtual void OnRenderError(HtmlRenderErrorEventArgs e) ///
protected virtual void OnStylesheetLoad(HtmlStylesheetLoadEventArgs e) { - RoutedEventArgs newEventArgs = new RoutedEvenArgs(StylesheetLoadEvent, this, e); + RoutedEventArgs newEventArgs = new RoutedEventArgs(StylesheetLoadEvent, this, e); RaiseEvent(newEventArgs); } @@ -424,7 +424,7 @@ protected virtual void OnStylesheetLoad(HtmlStylesheetLoadEventArgs e) ///
protected virtual void OnImageLoad(HtmlImageLoadEventArgs e) { - RoutedEventArgs newEventArgs = new RoutedEvenArgs(ImageLoadEvent, this, e); + RoutedEventArgs newEventArgs = new RoutedEventArgs(ImageLoadEvent, this, e); RaiseEvent(newEventArgs); } diff --git a/Source/HtmlRenderer.WPF/HtmlRender.cs b/Source/HtmlRenderer.WPF/HtmlRender.cs index 77eb4a046..d9e6c65ad 100644 --- a/Source/HtmlRenderer.WPF/HtmlRender.cs +++ b/Source/HtmlRenderer.WPF/HtmlRender.cs @@ -31,7 +31,7 @@ namespace TheArtOfDev.HtmlRenderer.WPF /// /// Rendering to image
/// // TODO:a update! - /// See https://htmlrenderer.codeplex.com/wikipage?title=Image%20generation
+ /// See https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Image%20generation
/// Because of GDI text rendering issue with alpha channel clear type text rendering rendering to image requires special handling.
/// Solid color background - generate an image where the background is filled with solid color and all the html is rendered on top /// of the background color, GDI text rendering will be used. (RenderToImage method where the first argument is html string)
diff --git a/Source/HtmlRenderer.WPF/HtmlRenderer.WPF.csproj b/Source/HtmlRenderer.WPF/HtmlRenderer.WPF.csproj index 5c725a851..65d9f483f 100644 --- a/Source/HtmlRenderer.WPF/HtmlRenderer.WPF.csproj +++ b/Source/HtmlRenderer.WPF/HtmlRenderer.WPF.csproj @@ -1,85 +1,43 @@ - - - + - Debug - AnyCPU - {7E4E8DB5-85AD-4388-BDCB-38C6F423B8B0} - library - Properties + net8.0-windows + Library TheArtOfDev.HtmlRenderer.WPF - HtmlRenderer.WPF - v3.0 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - - + true + true + true - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release.WPF.Net35\ - TRACE - prompt - 4 + + + HtmlRenderer.WPF + HTML Renderer for WPF + html render renderer draw control WPF + Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WPF. + +HTML UI in .NET WPF applications using controls or static rendering. + +Features and Benefits: +--- +* Controls: HtmlPanel, HtmlLabel. +* Create images from HTML snippets. +* 100% managed code and no external dependencies, no ActiveX, no MSHTML. +* Extensive HTML 4.01 and CSS level 2 specifications support. +* Support separating CSS from HTML by loading stylesheet code separately. +* Support text selection, copy-paste and context menu. +* Handles "real world" malformed HTML, it doesn't have to be XHTML. +* Supports .NET 3.0 or higher including Client Profile. +* Lightweight, only two DLLs (~300K). +* High performance and low memory footprint. +* Extendable and configurable. + Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WPF. - - - - - - - - - - - {fe611685-391f-4e3e-b27e-d3150e51e49b} - HtmlRenderer - + - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - + - - \ No newline at end of file diff --git a/Source/HtmlRenderer.WPF/README.md b/Source/HtmlRenderer.WPF/README.md new file mode 100644 index 000000000..0c536f912 --- /dev/null +++ b/Source/HtmlRenderer.WPF/README.md @@ -0,0 +1,53 @@ +# Welcome to the HTML Renderer WPF library! + +This library provides the rich formatting power of HTML in your WPF .NET applications using +simple controls or static rendering code. +For more info see HTML Renderer on GitHub: https://github.com/ArthurHub/HTML-Renderer + +## DEMO APPLICATION + +HTML Renderer Demo application showcases HTML Renderer capabilities, use it to explore and learn +on the library: https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Demo%20application + +## FEEDBACK / RELEASE NOTES + +If you have problems, wish to report a bug, or have a suggestion, please open an issue on the +HTML Renderer issue page: https://github.com/ArthurHub/HTML-Renderer/issues + +For full release notes and all versions see: https://github.com/ArthurHub/HTML-Renderer/releases + +## QUICK START + +For more Quick Start see: https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Documentation + +--- + +## Quick Start: Use HTML panel control on WPF window + +```xaml + + + + + +``` + +## Quick Start: Create image from HTML snippet + +```csharp +class Program +{ + private static void Main(string[] args) + { + BitmapFrame image = HtmlRender.RenderToImage("

Hello World

This is html rendered text

"); + var encoder = new PngBitmapEncoder(); + encoder.Frames.Add(image); + using (FileStream stream = new FileStream("image.png", FileMode.OpenOrCreate)) + encoder.Save(stream); + } +} +``` \ No newline at end of file diff --git a/Source/HtmlRenderer.WPF/RoutedEvenArgs.cs b/Source/HtmlRenderer.WPF/RoutedEventArgs.cs similarity index 85% rename from Source/HtmlRenderer.WPF/RoutedEvenArgs.cs rename to Source/HtmlRenderer.WPF/RoutedEventArgs.cs index be5b60ed5..32dd0c65a 100644 --- a/Source/HtmlRenderer.WPF/RoutedEvenArgs.cs +++ b/Source/HtmlRenderer.WPF/RoutedEventArgs.cs @@ -20,26 +20,26 @@ namespace TheArtOfDev.HtmlRenderer.WPF /// /// the event arguments object /// the type of the routed events args data - public delegate void RoutedEventHandler(object sender, RoutedEvenArgs args) where T : class; + public delegate void RoutedEventHandler(object sender, RoutedEventArgs args) where T : class; /// /// HTML Renderer routed event arguments containing event data. /// - public sealed class RoutedEvenArgs : RoutedEventArgs where T : class + public sealed class RoutedEventArgs : RoutedEventArgs where T : class { /// /// the argument data of the routed event /// private readonly T _data; - public RoutedEvenArgs(RoutedEvent routedEvent, T data) + public RoutedEventArgs(RoutedEvent routedEvent, T data) : base(routedEvent) { ArgChecker.AssertArgNotNull(data, "args"); _data = data; } - public RoutedEvenArgs(RoutedEvent routedEvent, object source, T data) + public RoutedEventArgs(RoutedEvent routedEvent, object source, T data) : base(routedEvent, source) { ArgChecker.AssertArgNotNull(data, "args"); diff --git a/Source/HtmlRenderer.WPF/Utilities/ClipboardHelper.cs b/Source/HtmlRenderer.WPF/Utilities/ClipboardHelper.cs index aac84e249..df4f1b799 100644 --- a/Source/HtmlRenderer.WPF/Utilities/ClipboardHelper.cs +++ b/Source/HtmlRenderer.WPF/Utilities/ClipboardHelper.cs @@ -18,7 +18,7 @@ namespace TheArtOfDev.HtmlRenderer.WPF.Utilities { /// /// Helper to encode and set HTML fragment to clipboard.
- /// See http://theartofdev.com/2012/11/11/setting-html-and-plain-text-formatting-to-clipboard/.
+ /// See https://theartofdev.com/2012/11/11/setting-html-and-plain-text-formatting-to-clipboard/.
/// . ///
/// @@ -91,7 +91,7 @@ internal static class ClipboardHelper /// hello world /// ]]> /// - /// See format specification here: http://msdn.microsoft.com/library/default.asp?url=/workshop/networking/clipboard/htmlclipboard.asp + /// See format specification here: https://msdn.microsoft.com/library/default.asp?url=/workshop/networking/clipboard/htmlclipboard.asp ///
/// /// a html fragment diff --git a/Source/HtmlRenderer.WinForms/Adapters/GraphicsAdapter.cs b/Source/HtmlRenderer.WinForms/Adapters/GraphicsAdapter.cs index 523870c2b..6b55d50f2 100644 --- a/Source/HtmlRenderer.WinForms/Adapters/GraphicsAdapter.cs +++ b/Source/HtmlRenderer.WinForms/Adapters/GraphicsAdapter.cs @@ -62,12 +62,10 @@ internal sealed class GraphicsAdapter : RGraphics /// private readonly bool _useGdiPlusTextRendering; -#if !MONO /// /// the initialized HDC used /// private IntPtr _hdc; -#endif /// /// if to release the graphics object on dispose @@ -107,11 +105,7 @@ public GraphicsAdapter(Graphics g, bool useGdiPlusTextRendering, bool releaseGra _g = g; _releaseGraphics = releaseGraphics; -#if MONO - _useGdiPlusTextRendering = true; -#else _useGdiPlusTextRendering = useGdiPlusTextRendering; -#endif } public override void PopClip() @@ -167,19 +161,13 @@ public override RSize MeasureString(string str, RFont font) { var height = realFont.Height; var descent = realFont.Size * realFont.FontFamily.GetCellDescent(realFont.Style) / realFont.FontFamily.GetEmHeight(realFont.Style); -#if !MONO fontAdapter.SetMetrics(height, (int)Math.Round((height - descent + .5f))); -#else - fontAdapter.SetMetrics(height, (int)Math.Round((height - descent + 1f))); -#endif - } return Utils.Convert(size); } else { -#if !MONO SetFont(font); var size = new Size(); Win32Utils.GetTextExtentPoint32(_hdc, str, str.Length, ref size); @@ -192,9 +180,6 @@ public override RSize MeasureString(string str, RFont font) } return Utils.Convert(size); -#else - throw new InvalidProgramException("Invalid Mono code"); -#endif } } @@ -220,14 +205,12 @@ public override void MeasureString(string str, RFont font, double maxWidth, out } else { -#if !MONO SetFont(font); var size = new Size(); Win32Utils.GetTextExtentExPoint(_hdc, str, str.Length, (int)Math.Round(maxWidth), _charFit, _charFitWidth, ref size); charFit = _charFit[0]; charFitWidth = charFit > 0 ? _charFitWidth[charFit - 1] : 0; -#endif } } @@ -242,7 +225,6 @@ public override void DrawString(string str, RFont font, RColor color, RPoint poi } else { -#if !MONO var pointConv = Utils.ConvertRound(point); var colorConv = Utils.Convert(color); @@ -260,7 +242,6 @@ public override void DrawString(string str, RFont font, RColor color, RPoint poi SetRtlAlignGdi(rtl); DrawTransparentText(_hdc, str, font, pointConv, Utils.ConvertRound(size), colorConv); } -#endif } } @@ -349,17 +330,14 @@ public override void DrawPolygon(RBrush brush, RPoint[] points) /// private void ReleaseHdc() { -#if !MONO if (_hdc != IntPtr.Zero) { Win32Utils.SelectClipRgn(_hdc, IntPtr.Zero); _g.ReleaseHdc(_hdc); _hdc = IntPtr.Zero; } -#endif } -#if !MONO /// /// Init HDC for the current graphics object to be used to call GDI directly. /// @@ -448,7 +426,6 @@ private static void DrawTransparentText(IntPtr hdc, string str, RFont font, Poin Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } } -#endif /// /// Change text align to Left-to-Right or Right-to-Left if required. diff --git a/Source/HtmlRenderer.WinForms/HtmlContainer.cs b/Source/HtmlRenderer.WinForms/HtmlContainer.cs index 138cf8618..5bc7c5cd0 100644 --- a/Source/HtmlRenderer.WinForms/HtmlContainer.cs +++ b/Source/HtmlRenderer.WinForms/HtmlContainer.cs @@ -53,6 +53,8 @@ public sealed class HtmlContainer : IDisposable public HtmlContainer() { _htmlContainerInt = new HtmlContainerInt(WinFormsAdapter.Instance); + _htmlContainerInt.SetMargins(0); + _htmlContainerInt.PageSize = new RSize(99999, 99999); } /// diff --git a/Source/HtmlRenderer.WinForms/HtmlLabel.cs b/Source/HtmlRenderer.WinForms/HtmlLabel.cs index 8853490d2..283ef7360 100644 --- a/Source/HtmlRenderer.WinForms/HtmlLabel.cs +++ b/Source/HtmlRenderer.WinForms/HtmlLabel.cs @@ -295,6 +295,7 @@ public virtual bool IsContextMenuEnabled [Browsable(true)] [Description("Set base stylesheet to be used by html rendered in the control.")] [Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public virtual string BaseStylesheet { @@ -487,7 +488,7 @@ protected override void OnLayout(LayoutEventArgs levent) { if (_htmlContainer != null) { - Graphics g = Utils.CreateGraphics(this); + Graphics g = CreateGraphics(); if (g != null) { using (g) @@ -788,6 +789,7 @@ public override Cursor Cursor /// Not applicable. /// [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new bool UseWaitCursor { get { return base.UseWaitCursor; } diff --git a/Source/HtmlRenderer.WinForms/HtmlPanel.cs b/Source/HtmlRenderer.WinForms/HtmlPanel.cs index bbf1accf3..a2f061874 100644 --- a/Source/HtmlRenderer.WinForms/HtmlPanel.cs +++ b/Source/HtmlRenderer.WinForms/HtmlPanel.cs @@ -303,6 +303,7 @@ public virtual bool IsContextMenuEnabled [Browsable(true)] [Category("Appearance")] [Description("Set base stylesheet to be used by html rendered in the control.")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public virtual string BaseStylesheet { @@ -418,10 +419,8 @@ public void ClearSelection() _htmlContainer.ClearSelection(); } - #region Private methods -#if !MONO /// /// Override to support border for the control. /// @@ -445,7 +444,6 @@ protected override CreateParams CreateParams return createParams; } } -#endif /// /// Perform the layout of the html in the control. @@ -473,7 +471,7 @@ protected void PerformHtmlLayout() { _htmlContainer.MaxSize = new SizeF(ClientSize.Width - Padding.Horizontal, 0); - Graphics g = Utils.CreateGraphics(this); + Graphics g = CreateGraphics(); if (g != null) { using (g) @@ -482,7 +480,6 @@ protected void PerformHtmlLayout() } } - AutoScrollMinSize = Size.Round(new SizeF(_htmlContainer.ActualSize.Width + Padding.Horizontal, _htmlContainer.ActualSize.Height)); } } @@ -498,7 +495,6 @@ protected override void OnPaint(PaintEventArgs e) { e.Graphics.TextRenderingHint = _textRenderingHint; e.Graphics.SetClip(ClientRectangle); - _htmlContainer.Location = new PointF(Padding.Left, Padding.Top); _htmlContainer.ScrollOffset = AutoScrollPosition; _htmlContainer.PerformPaint(e.Graphics); @@ -709,15 +705,12 @@ protected virtual void InvokeMouseMove() { try { - // mono has issue throwing exception for no reason var mp = PointToClient(MousePosition); _htmlContainer.HandleMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, mp.X, mp.Y, 0)); } catch { -#if !MONO throw; -#endif } } @@ -742,7 +735,6 @@ protected override bool IsInputKey(Keys keyData) return base.IsInputKey(keyData); } -#if !MONO /// /// Override the proc processing method to set OS specific hand cursor. /// @@ -766,7 +758,6 @@ protected override void WndProc(ref Message m) } base.WndProc(ref m); } -#endif /// /// Release the html container resources. @@ -891,6 +882,7 @@ public override Cursor Cursor /// Not applicable. /// [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public new bool UseWaitCursor { get { return base.UseWaitCursor; } diff --git a/Source/HtmlRenderer.WinForms/HtmlRender.cs b/Source/HtmlRenderer.WinForms/HtmlRender.cs index 2d3f349ec..ca0f44532 100644 --- a/Source/HtmlRenderer.WinForms/HtmlRender.cs +++ b/Source/HtmlRenderer.WinForms/HtmlRender.cs @@ -39,7 +39,7 @@ namespace TheArtOfDev.HtmlRenderer.WinForms /// /// /// Rendering to image
- /// See https://htmlrenderer.codeplex.com/wikipage?title=Image%20generation
+ /// See https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Image%20generation
/// Because of GDI text rendering issue with alpha channel clear type text rendering rendering to image requires special handling.
/// Solid color background - generate an image where the background is filled with solid color and all the html is rendered on top /// of the background color, GDI text rendering will be used. (RenderToImage method where the first argument is html string)
@@ -134,7 +134,6 @@ public static CssData ParseStyleSheet(string stylesheet, bool combineWithDefault return CssData.Parse(WinFormsAdapter.Instance, stylesheet, combineWithDefault); } -#if !MONO /// /// Measure the size (width and height) required to draw the given html under given max width restriction.
/// If no max width restriction is given the layout will use the maximum possible width required by the content, @@ -154,7 +153,6 @@ public static SizeF Measure(Graphics g, string html, float maxWidth = 0, CssData ArgChecker.AssertArgNotNull(g, "g"); return Measure(g, html, maxWidth, cssData, false, stylesheetLoad, imageLoad); } -#endif /// /// Measure the size (width and height) required to draw the given html under given max width restriction.
@@ -176,7 +174,6 @@ public static SizeF MeasureGdiPlus(Graphics g, string html, float maxWidth = 0, return Measure(g, html, maxWidth, cssData, true, stylesheetLoad, imageLoad); } -#if !MONO /// /// Renders the specified HTML source on the specified location and max width restriction.
/// Use GDI text rendering, note has no effect.
@@ -223,7 +220,6 @@ public static SizeF Render(Graphics g, string html, PointF location, SizeF maxSi ArgChecker.AssertArgNotNull(g, "g"); return RenderClip(g, html, location, maxSize, cssData, false, stylesheetLoad, imageLoad); } -#endif /// /// Renders the specified HTML source on the specified location and max size restriction.
@@ -272,7 +268,28 @@ public static SizeF RenderGdiPlus(Graphics g, string html, PointF location, Size return RenderClip(g, html, location, maxSize, cssData, true, stylesheetLoad, imageLoad); } -#if !MONO + public static Metafile RenderToMetafile(string html, float left = 0, float top = 0, float maxWidth = 0, CssData cssData = null, + EventHandler stylesheetLoad = null, EventHandler imageLoad = null) + { + Metafile image; + IntPtr dib; + var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, 1, 1, out dib); + try + { + image = new Metafile(memoryHdc, EmfType.EmfPlusDual, ".."); + + using (var g = Graphics.FromImage(image)) + { + Render(g, html, left, top, maxWidth, cssData, stylesheetLoad, imageLoad); + } + } + finally + { + Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); + } + return image; + } + /// /// Renders the specified HTML on top of the given image.
/// will contain the rendered html in it on top of original content.
@@ -488,7 +505,6 @@ public static void RenderToImage(Image image, string html, PointF location, Size return image; } } -#endif /// /// Renders the specified HTML into a new image of the requested size.
@@ -741,7 +757,6 @@ private static SizeF RenderHtml(Graphics g, string html, PointF location, SizeF return actualSize; } -#if !MONO /// /// Copy all the bitmap bits from memory bitmap buffer to the given image. /// @@ -756,7 +771,6 @@ private static void CopyBufferToImage(IntPtr memoryHdc, Image image) imageGraphics.ReleaseHdc(imgHdc); } } -#endif #endregion } diff --git a/Source/HtmlRenderer.WinForms/HtmlRenderer.WinForms.csproj b/Source/HtmlRenderer.WinForms/HtmlRenderer.WinForms.csproj index 79b059d84..51aec7512 100644 --- a/Source/HtmlRenderer.WinForms/HtmlRenderer.WinForms.csproj +++ b/Source/HtmlRenderer.WinForms/HtmlRenderer.WinForms.csproj @@ -1,125 +1,48 @@ - - + - Debug - AnyCPU - 8.0.50727 - 2.0 - {1B058920-24B4-4140-8AE7-C8C6C38CA52D} + net8.0-windows Library - Properties TheArtOfDev.HtmlRenderer.WinForms - HtmlRenderer.WinForms - - - v2.0 - - - - - 2.0 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - + true + true + true - - true - full - false - bin\DebugNet20\ - DEBUG;TRACE - prompt - 4 - false - AllRules.ruleset - - - pdbonly - true - bin\ReleaseNet20\ - TRACE - prompt - 4 - AllRules.ruleset + + + HtmlRenderer.WinForms + HTML Renderer for WinForms + html render renderer draw control winforms + Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WinForms. + +HTML UI in .NET WinForms applications using controls or static rendering. + +Features and Benefits: +--- +* Controls: HtmlPanel, HtmlLabel, HtmlToolTip. +* Create images from HTML snippets. +* 100% managed code and no external dependencies, no ActiveX, no MSHTML. +* Extensive HTML 4.01 and CSS level 2 specifications support. +* Support separating CSS from HTML by loading stylesheet code separately. +* Support text selection, copy-paste and context menu. +* Handles "real world" malformed HTML, it doesn't have to be XHTML. +* Lightweight, only two DLLs (~300K). +* High performance and low memory footprint. +* Extendable and configurable. + Multipurpose (UI Controls / Image generation), 100% managed (C#), High performance HTML Rendering library for WinForms. - - - - - - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - + Component - + Component - - + Component - - - - - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - true - - - False - Windows Installer 3.1 - true - + - - {fe611685-391f-4e3e-b27e-d3150e51e49b} - HtmlRenderer - + - - \ No newline at end of file diff --git a/Source/HtmlRenderer.WinForms/HtmlToolTip.cs b/Source/HtmlRenderer.WinForms/HtmlToolTip.cs index 40d7ab6ca..2a82209bd 100644 --- a/Source/HtmlRenderer.WinForms/HtmlToolTip.cs +++ b/Source/HtmlRenderer.WinForms/HtmlToolTip.cs @@ -53,8 +53,6 @@ public class HtmlToolTip : ToolTip ///
private string _tooltipCssClass = "htmltooltip"; -#if !MONO - /// /// the control that the tooltip is currently showing on.
/// Used for link handling. @@ -79,7 +77,6 @@ public class HtmlToolTip : ToolTip /// if clicked the event will be raised although the tooltip will be closed. ///
private bool _allowLinksHandling = true; -#endif #endregion @@ -104,22 +101,18 @@ public HtmlToolTip() Draw += OnToolTipDraw; Disposed += OnToolTipDisposed; -#if !MONO _linkHandlingTimer = new Timer(); _linkHandlingTimer.Tick += OnLinkHandlingTimerTick; _linkHandlingTimer.Interval = 40; _htmlContainer.LinkClicked += OnLinkClicked; -#endif } -#if !MONO /// /// Raised when the user clicks on a link in the html.
/// Allows canceling the execution of the link. ///
public event EventHandler LinkClicked; -#endif /// /// Raised when an error occurred during html rendering.
@@ -181,6 +174,7 @@ public TextRenderingHint TextRenderingHint [Browsable(true)] [Description("Set base stylesheet to be used by html rendered in the tooltip.")] [Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [Editor("System.ComponentModel.Design.MultilineStringEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] public virtual string BaseStylesheet { @@ -200,13 +194,13 @@ public virtual string BaseStylesheet [Browsable(true)] [Description("The CSS class used for tooltip html root div.")] [Category("Appearance")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public virtual string TooltipCssClass { get { return _tooltipCssClass; } set { _tooltipCssClass = value; } } -#if !MONO /// /// If to handle links in the tooltip (default: false).
/// When set to true the mouse pointer will change to hand when hovering over a tooltip and @@ -221,7 +215,6 @@ public virtual bool AllowLinksHandling get { return _allowLinksHandling; } set { _allowLinksHandling = value; } } -#endif /// /// Gets or sets the max size the tooltip. @@ -230,6 +223,7 @@ public virtual bool AllowLinksHandling [Browsable(true)] [Category("Layout")] [Description("Restrict the max size of the shown tooltip (0 is not restricted)")] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public virtual Size MaximumSize { get { return Size.Round(_htmlContainer.MaxSize); } @@ -262,14 +256,12 @@ protected virtual void OnToolTipPopup(PopupEventArgs e) var desiredHeight = (int)Math.Ceiling(MaximumSize.Height > 0 ? Math.Min(_htmlContainer.ActualSize.Height, MaximumSize.Height) : _htmlContainer.ActualSize.Height); e.ToolTipSize = new Size(desiredWidth, desiredHeight); -#if !MONO // start mouse handle timer if (_allowLinksHandling) { _associatedControl = e.AssociatedControl; _linkHandlingTimer.Start(); } -#endif } /// @@ -277,7 +269,6 @@ protected virtual void OnToolTipPopup(PopupEventArgs e) /// protected virtual void OnToolTipDraw(DrawToolTipEventArgs e) { -#if !MONO if (_tooltipHandle == IntPtr.Zero) { // get the handle of the tooltip window using the graphics device context @@ -287,7 +278,6 @@ protected virtual void OnToolTipDraw(DrawToolTipEventArgs e) AdjustTooltipPosition(e.AssociatedControl, e.Bounds.Size); } -#endif e.Graphics.Clear(Color.White); e.Graphics.TextRenderingHint = _textRenderingHint; @@ -313,13 +303,10 @@ protected virtual void AdjustTooltipPosition(Control associatedControl, Size siz if (mousePos.Y + size.Height + yOffset > screenBounds.Bottom) mousePos.Y = Math.Max(screenBounds.Bottom - size.Height - yOffset - 3, screenBounds.Top + 2); -#if !MONO // move the tooltip window to new location Win32Utils.MoveWindow(_tooltipHandle, mousePos.X, mousePos.Y + yOffset, size.Width, size.Height, false); -#endif } -#if !MONO /// /// Propagate the LinkClicked event from root container. /// @@ -329,7 +316,6 @@ protected virtual void OnLinkClicked(HtmlLinkClickedEventArgs e) if (handler != null) handler(this, e); } -#endif /// /// Propagate the Render Error event from root container. @@ -361,7 +347,6 @@ protected virtual void OnImageLoad(HtmlImageLoadEventArgs e) handler(this, e); } -#if !MONO /// /// Raised on link handling timer tick, used for: /// 1. Know when the tooltip is hidden by checking the visibility of the tooltip window. @@ -407,7 +392,6 @@ protected virtual void OnLinkHandlingTimerTick(EventArgs e) OnRenderError(this, new HtmlRenderErrorEventArgs(HtmlRenderErrorType.General, "Error in link handling for tooltip", ex)); } } -#endif /// /// Unsubscribe from events and dispose of . @@ -427,7 +411,6 @@ protected virtual void OnToolTipDisposed(EventArgs e) _htmlContainer = null; } -#if !MONO if (_linkHandlingTimer != null) { _linkHandlingTimer.Dispose(); @@ -436,7 +419,6 @@ protected virtual void OnToolTipDisposed(EventArgs e) if (_htmlContainer != null) _htmlContainer.LinkClicked -= OnLinkClicked; } -#endif } @@ -466,7 +448,6 @@ private void OnImageLoad(object sender, HtmlImageLoadEventArgs e) OnImageLoad(e); } -#if !MONO private void OnLinkClicked(object sender, HtmlLinkClickedEventArgs e) { OnLinkClicked(e); @@ -475,7 +456,6 @@ private void OnLinkHandlingTimerTick(object sender, EventArgs e) { OnLinkHandlingTimerTick(e); } -#endif private void OnToolTipDisposed(object sender, EventArgs e) { diff --git a/Source/HtmlRenderer.WinForms/MetafileExtensions.cs b/Source/HtmlRenderer.WinForms/MetafileExtensions.cs new file mode 100644 index 000000000..7bc5fad25 --- /dev/null +++ b/Source/HtmlRenderer.WinForms/MetafileExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Drawing.Imaging; +using System.IO; +using System.Runtime.InteropServices; + +namespace TheArtOfDev.HtmlRenderer.WinForms +{ + public static class MetafileExtensions + { + public static void SaveAsEmf(Metafile me, string fileName) + { + /* https://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/12a1c749-b320-4ce9-aff7-9de0d7fd30ea + How to save or serialize a Metafile: Solution found + by : SWAT Team member _1 + Date : Friday, February 01, 2008 1:38 PM + */ + int enfMetafileHandle = me.GetHenhmetafile().ToInt32(); + int bufferSize = GetEnhMetaFileBits(enfMetafileHandle, 0, null); // Get required buffer size. + byte[] buffer = new byte[bufferSize]; // Allocate sufficient buffer + if (GetEnhMetaFileBits(enfMetafileHandle, bufferSize, buffer) <= 0) // Get raw metafile data. + throw new SystemException("Fail"); + + FileStream ms = File.Open(fileName, FileMode.Create); + ms.Write(buffer, 0, bufferSize); + ms.Close(); + ms.Dispose(); + if (!DeleteEnhMetaFile(enfMetafileHandle)) //free handle + throw new SystemException("Fail Free"); + } + + [DllImport("gdi32")] + public static extern int GetEnhMetaFileBits(int hemf, int cbBuffer, byte[] lpbBuffer); + + [DllImport("gdi32")] + public static extern bool DeleteEnhMetaFile(int hemfbitHandle); + } +} diff --git a/Source/HtmlRenderer.WinForms/README.md b/Source/HtmlRenderer.WinForms/README.md new file mode 100644 index 000000000..0d4f2d4d7 --- /dev/null +++ b/Source/HtmlRenderer.WinForms/README.md @@ -0,0 +1,53 @@ +# Welcome to the HTML Renderer WinForms library! + +This library provides the rich formatting power of HTML in your WinForms .NET applications using +simple controls or static rendering code. +For more info see HTML Renderer on GitHub: https://github.com/ArthurHub/HTML-Renderer + +## DEMO APPLICATION + +HTML Renderer Demo application showcases HTML Renderer capabilities, use it to explore and learn +on the library: https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Demo%20application + +## FEEDBACK / RELEASE NOTES + +If you have problems, wish to report a bug, or have a suggestion, please open an issue on the +HTML Renderer issue page: https://github.com/ArthurHub/HTML-Renderer/issues + +For full release notes and all versions see: https://github.com/ArthurHub/HTML-Renderer/releases + +## QUICK START + +For more Quick Start see: https://codeplexarchive.org/ProjectTab/Wiki/HtmlRenderer/Documentation/Documentation + +--- + +## Quick Start: Use HTML panel control on WinForms form + +```csharp +public partial class Form1 : Form +{ + public Form1() + { + InitializeComponent(); + + TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel htmlPanel = new TheArtOfDev.HtmlRenderer.WinForms.HtmlPanel(); + htmlPanel.Text = "

Hello World

This is html rendered text

"; + htmlPanel.Dock = DockStyle.Fill; + Controls.Add(htmlPanel); + } +} +``` + +## Quick Start: Create image from HTML snippet + +```csharp +class Program +{ + private static void Main(string[] args) + { + Image image = TheArtOfDev.HtmlRenderer.WinForms.HtmlRender.RenderToImage("

Hello World

This is html rendered text

"); + image.Save("image.png", ImageFormat.Png); + } +} +``` diff --git a/Source/HtmlRenderer.WinForms/Utilities/ClipboardHelper.cs b/Source/HtmlRenderer.WinForms/Utilities/ClipboardHelper.cs index dd5d3b7aa..8c34cab02 100644 --- a/Source/HtmlRenderer.WinForms/Utilities/ClipboardHelper.cs +++ b/Source/HtmlRenderer.WinForms/Utilities/ClipboardHelper.cs @@ -18,7 +18,7 @@ namespace TheArtOfDev.HtmlRenderer.WinForms.Utilities { /// /// Helper to encode and set HTML fragment to clipboard.
- /// See http://theartofdev.wordpress.com/2012/11/11/setting-html-and-plain-text-formatting-to-clipboard/.
+ /// See https://theartofdev.wordpress.com/2012/11/11/setting-html-and-plain-text-formatting-to-clipboard/.
/// . ///
/// @@ -91,7 +91,7 @@ internal static class ClipboardHelper /// hello world /// ]]> /// - /// See format specification here: http://msdn.microsoft.com/library/default.asp?url=/workshop/networking/clipboard/htmlclipboard.asp + /// See format specification here: https://msdn.microsoft.com/library/default.asp?url=/workshop/networking/clipboard/htmlclipboard.asp /// /// /// a html fragment diff --git a/Source/HtmlRenderer.WinForms/Utilities/Utils.cs b/Source/HtmlRenderer.WinForms/Utilities/Utils.cs index 9f25b6045..026102976 100644 --- a/Source/HtmlRenderer.WinForms/Utilities/Utils.cs +++ b/Source/HtmlRenderer.WinForms/Utilities/Utils.cs @@ -12,7 +12,6 @@ using System; using System.Drawing; -using System.Windows.Forms; using TheArtOfDev.HtmlRenderer.Adapters.Entities; namespace TheArtOfDev.HtmlRenderer.WinForms.Utilities @@ -120,26 +119,5 @@ public static Color Convert(RColor c) { return Color.FromArgb(c.A, c.R, c.G, c.B); } - - /// - /// mono has issue throwing exception for no reason. - /// - /// the control to create graphics object from - /// new graphics object or null in mono if failed - public static Graphics CreateGraphics(Control control) - { -#if MONO - try - { - return control.CreateGraphics(); - } - catch - { - return null; - } -#else - return control.CreateGraphics(); -#endif - } } } \ No newline at end of file diff --git a/Source/HtmlRenderer.WinForms/Utilities/Win32Utils.cs b/Source/HtmlRenderer.WinForms/Utilities/Win32Utils.cs index 33dddd53f..228e47658 100644 --- a/Source/HtmlRenderer.WinForms/Utilities/Win32Utils.cs +++ b/Source/HtmlRenderer.WinForms/Utilities/Win32Utils.cs @@ -10,7 +10,6 @@ // - Sun Tsu, // "The Art of War" -#if !MONO using System; using System.Drawing; using System.Runtime.InteropServices; @@ -248,5 +247,4 @@ internal struct TextMetric public byte tmPitchAndFamily; public byte tmCharSet; } -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/Source/HtmlRenderer.sln b/Source/HtmlRenderer.sln index cf7aaa634..c6594f4d7 100644 --- a/Source/HtmlRenderer.sln +++ b/Source/HtmlRenderer.sln @@ -1,30 +1,23 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 +# Visual Studio Version 18 +VisualStudioVersion = 18.1.11312.151 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Demo", "Demo", "{E263EA16-2E6A-4269-A319-AA2F97ADA8E1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlRenderer.Demo.Common", "Demo\Common\HtmlRenderer.Demo.Common.csproj", "{2390B71F-9400-47F4-B23A-7F2649C87D35}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlRenderer.Demo.Common", "Demo\Common\HtmlRenderer.Demo.Common.csproj", "{2390B71F-9400-47F4-B23A-7F2649C87D35}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlRenderer.Demo.WinForms", "Demo\WinForms\HtmlRenderer.Demo.WinForms.csproj", "{8AD34FE8-8382-4A8A-B3AA-A0392ED42423}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlRenderer.Demo.WinForms", "Demo\WinForms\HtmlRenderer.Demo.WinForms.csproj", "{8AD34FE8-8382-4A8A-B3AA-A0392ED42423}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlRenderer.Demo.WPF", "Demo\WPF\HtmlRenderer.Demo.WPF.csproj", "{F02E0216-4AE3-474F-9381-FCB93411CDB0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlRenderer.Demo.WPF", "Demo\WPF\HtmlRenderer.Demo.WPF.csproj", "{F02E0216-4AE3-474F-9381-FCB93411CDB0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlRenderer.WinForms", "HtmlRenderer.WinForms\HtmlRenderer.WinForms.csproj", "{1B058920-24B4-4140-8AE7-C8C6C38CA52D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlRenderer.WinForms", "HtmlRenderer.WinForms\HtmlRenderer.WinForms.csproj", "{1B058920-24B4-4140-8AE7-C8C6C38CA52D}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlRenderer.WPF", "HtmlRenderer.WPF\HtmlRenderer.WPF.csproj", "{7E4E8DB5-85AD-4388-BDCB-38C6F423B8B0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlRenderer.WPF", "HtmlRenderer.WPF\HtmlRenderer.WPF.csproj", "{7E4E8DB5-85AD-4388-BDCB-38C6F423B8B0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlRenderer", "HtmlRenderer\HtmlRenderer.csproj", "{FE611685-391F-4E3E-B27E-D3150E51E49B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlRenderer", "HtmlRenderer\HtmlRenderer.csproj", "{FE611685-391F-4E3E-B27E-D3150E51E49B}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HtmlRenderer.PdfSharp", "HtmlRenderer.PdfSharp\HtmlRenderer.PdfSharp.csproj", "{CA249F5D-9285-40A6-B217-5889EF79FD7E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{AA47D163-2ECF-45FB-8798-2432681396B5}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HtmlRenderer.PdfSharp", "HtmlRenderer.PdfSharp\HtmlRenderer.PdfSharp.csproj", "{CA249F5D-9285-40A6-B217-5889EF79FD7E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -115,4 +108,7 @@ Global {8AD34FE8-8382-4A8A-B3AA-A0392ED42423} = {E263EA16-2E6A-4269-A319-AA2F97ADA8E1} {F02E0216-4AE3-474F-9381-FCB93411CDB0} = {E263EA16-2E6A-4269-A319-AA2F97ADA8E1} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {902788D6-3165-491D-B860-DF2F74E66C1D} + EndGlobalSection EndGlobal diff --git a/Source/HtmlRenderer/Adapters/RGraphics.cs b/Source/HtmlRenderer/Adapters/RGraphics.cs index 040d14837..af54f2ae4 100644 --- a/Source/HtmlRenderer/Adapters/RGraphics.cs +++ b/Source/HtmlRenderer/Adapters/RGraphics.cs @@ -32,10 +32,15 @@ public abstract class RGraphics : IDisposable protected readonly RAdapter _adapter; /// - /// Te clipping bound stack as clips are pushed/poped to/from the graphics + /// The clipping bound stack as clips are pushed/poped to/from the graphics /// protected readonly Stack _clipStack = new Stack(); + /// + /// The suspended clips + /// + private Stack _suspendedClips = new Stack(); + #endregion @@ -109,6 +114,32 @@ public RRect GetClip() /// Rectangle to exclude clipping in. public abstract void PushClipExclude(RRect rect); + + /// + /// Restore the clipping region to the initial clip. + /// + public void SuspendClipping() + { + while (_clipStack.Count > 1) + { + var clip = GetClip(); + _suspendedClips.Push(clip); + PopClip(); + } + } + + /// + /// Resumes the suspended clips. + /// + public void ResumeClipping() + { + while (_suspendedClips.Count > 0) + { + var clip = _suspendedClips.Pop(); + PushClip(clip); + } + } + /// /// Set the graphics smooth mode to use anti-alias.
/// Use to return back the mode used. diff --git a/Source/HtmlRenderer/Core/Dom/CssBox.cs b/Source/HtmlRenderer/Core/Dom/CssBox.cs index edd9d6f0a..b2cd3d984 100644 --- a/Source/HtmlRenderer/Core/Dom/CssBox.cs +++ b/Source/HtmlRenderer/Core/Dom/CssBox.cs @@ -141,7 +141,9 @@ public List Boxes ///
public bool IsBrElement { - get { return _htmltag != null && _htmltag.Name.Equals("br", StringComparison.InvariantCultureIgnoreCase); } + get { + return _htmltag != null && _htmltag.Name.Equals("br", StringComparison.InvariantCultureIgnoreCase); + } } /// @@ -168,6 +170,36 @@ public virtual bool IsClickable get { return HtmlTag != null && HtmlTag.Name == HtmlConstants.A && !HtmlTag.HasAttribute("id"); } } + /// + /// Gets a value indicating whether this instance or one of its parents has Position = fixed. + /// + /// + /// true if this instance is fixed; otherwise, false. + /// + public virtual bool IsFixed + { + get + { + if (Position == CssConstants.Fixed) + return true; + + if (this.ParentBox == null) + return false; + + CssBox parent = this; + + while (!(parent.ParentBox == null || parent == parent.ParentBox)) + { + parent = parent.ParentBox; + + if (parent.Position == CssConstants.Fixed) + return true; + } + + return false; + } + } + /// /// Get the href link of the box (by default get "href" attribute) /// @@ -431,6 +463,12 @@ public void Paint(RGraphics g) { if (Display != CssConstants.None && Visibility == CssConstants.Visible) { + // use initial clip to draw blocks with Position = fixed. I.e. ignrore page margins + if (this.Position == CssConstants.Fixed) + { + g.SuspendClipping(); + } + // don't call paint if the rectangle of the box is not in visible rectangle bool visible = Rectangles.Count == 0; if (!visible) @@ -439,8 +477,11 @@ public void Paint(RGraphics g) var rect = ContainingBlock.ClientRectangle; rect.X -= 2; rect.Width += 2; - rect.Offset(new RPoint(-HtmlContainer.Location.X, -HtmlContainer.Location.Y)); - rect.Offset(HtmlContainer.ScrollOffset); + if (!IsFixed) + { + //rect.Offset(new RPoint(-HtmlContainer.Location.X, -HtmlContainer.Location.Y)); + rect.Offset(HtmlContainer.ScrollOffset); + } clip.Intersect(rect); if (clip != RRect.Empty) @@ -449,6 +490,13 @@ public void Paint(RGraphics g) if (visible) PaintImp(g); + + // Restore clips + if (this.Position == CssConstants.Fixed) + { + g.ResumeClipping(); + } + } } catch (Exception ex) @@ -593,10 +641,21 @@ protected virtual void PerformLayoutImp(RGraphics g) if (Display != CssConstants.TableCell) { var prevSibling = DomUtils.GetPreviousSibling(this); - double left = ContainingBlock.Location.X + ContainingBlock.ActualPaddingLeft + ActualMarginLeft + ContainingBlock.ActualBorderLeftWidth; - double top = (prevSibling == null && ParentBox != null ? ParentBox.ClientTop : ParentBox == null ? Location.Y : 0) + MarginTopCollapse(prevSibling) + (prevSibling != null ? prevSibling.ActualBottom + prevSibling.ActualBorderBottomWidth : 0); - Location = new RPoint(left, top); - ActualBottom = top; + double left; + double top; + + if (Position == CssConstants.Fixed) + { + left = 0; + top = 0; + } + else + { + left = ContainingBlock.Location.X + ContainingBlock.ActualPaddingLeft + ActualMarginLeft + ContainingBlock.ActualBorderLeftWidth; + top = (prevSibling == null && ParentBox != null ? ParentBox.ClientTop : ParentBox == null ? Location.Y : 0) + MarginTopCollapse(prevSibling) + (prevSibling != null ? prevSibling.ActualBottom + prevSibling.ActualBorderBottomWidth : 0); + Location = new RPoint(left, top); + ActualBottom = top; + } } //If we're talking about a table here.. @@ -637,8 +696,11 @@ protected virtual void PerformLayoutImp(RGraphics g) CreateListItemBox(g); - var actualWidth = Math.Max(GetMinimumWidth() + GetWidthMarginDeep(this), Size.Width < 90999 ? ActualRight - HtmlContainer.Root.Location.X : 0); - HtmlContainer.ActualSize = CommonUtils.Max(HtmlContainer.ActualSize, new RSize(actualWidth, ActualBottom - HtmlContainer.Root.Location.Y)); + if (!IsFixed) + { + var actualWidth = Math.Max(GetMinimumWidth() + GetWidthMarginDeep(this), Size.Width < 90999 ? ActualRight - HtmlContainer.Root.Location.X : 0); + HtmlContainer.ActualSize = CommonUtils.Max(HtmlContainer.ActualSize, new RSize(actualWidth, ActualBottom - HtmlContainer.Root.Location.Y)); + } } /// @@ -1056,6 +1118,26 @@ protected double MarginTopCollapse(CssBoxProperties prevSibling) return value; } + public bool BreakPage() + { + var container = this.HtmlContainer; + + if (this.Size.Height >= container.PageSize.Height) + return false; + + var remTop = (this.Location.Y - container.MarginTop) % container.PageSize.Height; + var remBottom = (this.ActualBottom - container.MarginTop) % container.PageSize.Height; + + if (remTop > remBottom) + { + var diff = container.PageSize.Height - remTop; + this.Location = new RPoint(this.Location.X, this.Location.Y + diff + 1); + return true; + } + + return false; + } + /// /// Calculate the actual right of the box by the actual right of the child boxes if this box actual right is not set. /// @@ -1135,17 +1217,24 @@ protected virtual void PaintImp(RGraphics g) var clipped = RenderUtils.ClipGraphicsByOverflow(g, this); var areas = Rectangles.Count == 0 ? new List(new[] { Bounds }) : new List(Rectangles.Values); - + var clip = g.GetClip(); RRect[] rects = areas.ToArray(); - RPoint offset = HtmlContainer.ScrollOffset; + RPoint offset = RPoint.Empty; + if (!IsFixed) + { + offset = HtmlContainer.ScrollOffset; + } for (int i = 0; i < rects.Length; i++) { var actualRect = rects[i]; actualRect.Offset(offset); - PaintBackground(g, actualRect, i == 0, i == rects.Length - 1); - BordersDrawHandler.DrawBoxBorders(g, this, actualRect, i == 0, i == rects.Length - 1); + if (IsRectVisible(actualRect, clip)) + { + PaintBackground(g, actualRect, i == 0, i == rects.Length - 1); + BordersDrawHandler.DrawBoxBorders(g, this, actualRect, i == 0, i == rects.Length - 1); + } } PaintWords(g, offset); @@ -1154,13 +1243,17 @@ protected virtual void PaintImp(RGraphics g) { var actualRect = rects[i]; actualRect.Offset(offset); - PaintDecoration(g, actualRect, i == 0, i == rects.Length - 1); + + if (IsRectVisible(actualRect, clip)) + { + PaintDecoration(g, actualRect, i == 0, i == rects.Length - 1); + } } // split paint to handle z-order foreach (CssBox b in Boxes) { - if (b.Position != CssConstants.Absolute) + if (b.Position != CssConstants.Absolute && !b.IsFixed) b.Paint(g); } foreach (CssBox b in Boxes) @@ -1168,6 +1261,11 @@ protected virtual void PaintImp(RGraphics g) if (b.Position == CssConstants.Absolute) b.Paint(g); } + foreach (CssBox b in Boxes) + { + if (b.IsFixed) + b.Paint(g); + } if (clipped) g.PopClip(); @@ -1179,6 +1277,18 @@ protected virtual void PaintImp(RGraphics g) } } + private bool IsRectVisible(RRect rect, RRect clip) + { + rect.X -= 2; + rect.Width += 2; + clip.Intersect(rect); + + if (clip != RRect.Empty) + return true; + + return false; + } + /// /// Paints the background of the box /// @@ -1256,37 +1366,45 @@ private void PaintWords(RGraphics g, RPoint offset) { if (!word.IsLineBreak) { - var wordPoint = new RPoint(word.Left + offset.X, word.Top + offset.Y); - if (word.Selected) - { - // handle paint selected word background and with partial word selection - var wordLine = DomUtils.GetCssLineBoxByWord(word); - var left = word.SelectedStartOffset > -1 ? word.SelectedStartOffset : (wordLine.Words[0] != word && word.HasSpaceBefore ? -ActualWordSpacing : 0); - var padWordRight = word.HasSpaceAfter && !wordLine.IsLastSelectedWord(word); - var width = word.SelectedEndOffset > -1 ? word.SelectedEndOffset : word.Width + (padWordRight ? ActualWordSpacing : 0); - var rect = new RRect(word.Left + offset.X + left, word.Top + offset.Y, width - left, wordLine.LineHeight); - - g.DrawRectangle(GetSelectionBackBrush(g, false), rect.X, rect.Y, rect.Width, rect.Height); + var clip = g.GetClip(); + var wordRect = word.Rectangle; + wordRect.Offset(offset); + clip.Intersect(wordRect); - if (HtmlContainer.SelectionForeColor != RColor.Empty && (word.SelectedStartOffset > 0 || word.SelectedEndIndexOffset > -1)) + if (clip != RRect.Empty) + { + var wordPoint = new RPoint(word.Left + offset.X, word.Top + offset.Y); + if (word.Selected) { - g.PushClipExclude(rect); - g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl); - g.PopClip(); - g.PushClip(rect); - g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl); - g.PopClip(); + // handle paint selected word background and with partial word selection + var wordLine = DomUtils.GetCssLineBoxByWord(word); + var left = word.SelectedStartOffset > -1 ? word.SelectedStartOffset : (wordLine.Words[0] != word && word.HasSpaceBefore ? -ActualWordSpacing : 0); + var padWordRight = word.HasSpaceAfter && !wordLine.IsLastSelectedWord(word); + var width = word.SelectedEndOffset > -1 ? word.SelectedEndOffset : word.Width + (padWordRight ? ActualWordSpacing : 0); + var rect = new RRect(word.Left + offset.X + left, word.Top + offset.Y, width - left, wordLine.LineHeight); + + g.DrawRectangle(GetSelectionBackBrush(g, false), rect.X, rect.Y, rect.Width, rect.Height); + + if (HtmlContainer.SelectionForeColor != RColor.Empty && (word.SelectedStartOffset > 0 || word.SelectedEndIndexOffset > -1)) + { + g.PushClipExclude(rect); + g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl); + g.PopClip(); + g.PushClip(rect); + g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl); + g.PopClip(); + } + else + { + g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl); + } } else { - g.DrawString(word.Text, ActualFont, GetSelectionForeBrush(), wordPoint, new RSize(word.Width, word.Height), isRtl); + // g.DrawRectangle(HtmlContainer.Adapter.GetPen(RColor.Black), wordPoint.X, wordPoint.Y, word.Width - 1, word.Height - 1); + g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl); } } - else - { - // g.DrawRectangle(HtmlContainer.Adapter.GetPen(RColor.Black), wordPoint.X, wordPoint.Y, word.Width - 1, word.Height - 1); - g.DrawString(word.Text, ActualFont, ActualColor, wordPoint, new RSize(word.Width, word.Height), isRtl); - } } } } @@ -1407,6 +1525,13 @@ protected override RColor GetActualColor(string colorStr) return HtmlContainer.CssParser.ParseColor(colorStr); } + protected override RPoint GetActualLocation(string X, string Y) + { + var left = CssValueParser.ParseLength(X, this.HtmlContainer.PageSize.Width, this, null); + var top = CssValueParser.ParseLength(Y, this.HtmlContainer.PageSize.Height, this, null); + return new RPoint(left, top); + } + /// /// ToString override. /// diff --git a/Source/HtmlRenderer/Core/Dom/CssBoxFrame.cs b/Source/HtmlRenderer/Core/Dom/CssBoxFrame.cs index ee73aee94..72104eef1 100644 --- a/Source/HtmlRenderer/Core/Dom/CssBoxFrame.cs +++ b/Source/HtmlRenderer/Core/Dom/CssBoxFrame.cs @@ -146,7 +146,7 @@ private void LoadYoutubeDataAsync(Uri uri) { try { - var apiUri = new Uri(string.Format("http://gdata.youtube.com/feeds/api/videos/{0}?v=2&alt=json", uri.Segments[2])); + var apiUri = new Uri(string.Format("https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v={0}&format=json", uri.Segments[2])); var client = new WebClient(); client.Encoding = Encoding.UTF8; @@ -172,89 +172,93 @@ private void OnDownloadYoutubeApiCompleted(object sender, DownloadStringComplete { if (e.Error == null) { - var idx = e.Result.IndexOf("\"media$title\"", StringComparison.Ordinal); + var idx = e.Result.IndexOf("\"title\"", StringComparison.Ordinal); if (idx > -1) { - idx = e.Result.IndexOf("\"$t\"", idx); + idx = e.Result.IndexOf('"', idx + 7); if (idx > -1) { - idx = e.Result.IndexOf('"', idx + 4); - if (idx > -1) + var endIdx = e.Result.IndexOf('"', idx + 1); + while (endIdx > 0 && e.Result[endIdx - 1] == '\\') + endIdx = e.Result.IndexOf('"', endIdx + 1); + if (endIdx > -1) { - var endIdx = e.Result.IndexOf('"', idx + 1); - while (e.Result[endIdx - 1] == '\\') - endIdx = e.Result.IndexOf('"', endIdx + 1); - if (endIdx > -1) - { - _videoTitle = e.Result.Substring(idx + 1, endIdx - idx - 1).Replace("\\\"", "\""); - } + _videoTitle = e.Result.Substring(idx + 1, endIdx - idx - 1).Replace("\\\"", "\""); } } } - idx = e.Result.IndexOf("\"media$thumbnail\"", StringComparison.Ordinal); + idx = e.Result.IndexOf("\"thumbnail_url\"", StringComparison.Ordinal); if (idx > -1) { - var iidx = e.Result.IndexOf("sddefault", idx); - if (iidx > -1) - { - if (string.IsNullOrEmpty(Width)) - Width = "640px"; - if (string.IsNullOrEmpty(Height)) - Height = "480px"; - } - else + idx = e.Result.IndexOf('"', idx + 15); + if (idx > -1) { - iidx = e.Result.IndexOf("hqdefault", idx); - if (iidx > -1) + var endIdx = e.Result.IndexOf('"', idx + 1); + while (endIdx > 0 && e.Result[endIdx - 1] == '\\') + endIdx = e.Result.IndexOf('"', endIdx + 1); + if (endIdx > -1) { - if (string.IsNullOrEmpty(Width)) - Width = "480px"; - if (string.IsNullOrEmpty(Height)) - Height = "360px"; + _videoImageUrl = e.Result.Substring(idx + 1, endIdx - idx - 1).Replace("\\\"", "\""); } - else + } + + idx = e.Result.IndexOf("\"thumbnail_width\"", StringComparison.Ordinal); + if (idx > -1) + { + idx = e.Result.IndexOf(':', idx); + if (idx > -1) { - iidx = e.Result.IndexOf("mqdefault", idx); - if (iidx > -1) - { - if (string.IsNullOrEmpty(Width)) - Width = "320px"; - if (string.IsNullOrEmpty(Height)) - Height = "180px"; - } - else + var endIdx = e.Result.IndexOf(',', idx); + if (endIdx > -1) { - iidx = e.Result.IndexOf("default", idx); - if (string.IsNullOrEmpty(Width)) - Width = "120px"; - if (string.IsNullOrEmpty(Height)) - Height = "90px"; + var widthStr = e.Result.Substring(idx + 1, endIdx - idx - 1).Trim(); + if (int.TryParse(widthStr, out int width)) + { + if (string.IsNullOrEmpty(Width)) + Width = width + "px"; + } } } } - iidx = e.Result.LastIndexOf("http:", iidx, StringComparison.Ordinal); - if (iidx > -1) + idx = e.Result.IndexOf("\"thumbnail_height\"", StringComparison.Ordinal); + if (idx > -1) { - var endIdx = e.Result.IndexOf('"', iidx); - if (endIdx > -1) + idx = e.Result.IndexOf(':', idx); + if (idx > -1) { - _videoImageUrl = e.Result.Substring(iidx, endIdx - iidx).Replace("\\\"", "\"").Replace("\\", ""); + var endIdx = e.Result.IndexOf(',', idx); + if (endIdx == -1) + endIdx = e.Result.IndexOf('}', idx); + if (endIdx > -1) + { + var heightStr = e.Result.Substring(idx + 1, endIdx - idx - 1).Trim(); + if (int.TryParse(heightStr, out int height)) + { + if (string.IsNullOrEmpty(Height)) + Height = height + "px"; + } + } } } } - idx = e.Result.IndexOf("\"link\"", StringComparison.Ordinal); + idx = e.Result.IndexOf("\"html\"", StringComparison.Ordinal); if (idx > -1) { - idx = e.Result.IndexOf("http:", idx); + idx = e.Result.IndexOf("src=", idx); if (idx > -1) { - var endIdx = e.Result.IndexOf('"', idx); - if (endIdx > -1) + idx = e.Result.IndexOf("embed/", idx); + if (idx > -1) { - _videoLinkUrl = e.Result.Substring(idx, endIdx - idx).Replace("\\\"", "\"").Replace("\\", ""); + var endIdx = e.Result.IndexOf('?', idx); + if (endIdx > -1) + { + var videoId = e.Result.Substring(idx + 6, endIdx - idx - 6); + _videoLinkUrl = "https://www.youtube.com/watch?v=" + videoId; + } } } } @@ -282,7 +286,7 @@ private void LoadVimeoDataAsync(Uri uri) { try { - var apiUri = new Uri(string.Format("http://vimeo.com/api/v2/video/{0}.json", uri.Segments[2])); + var apiUri = new Uri(string.Format("https://vimeo.com/api/v2/video/{0}.json", uri.Segments[2])); var client = new WebClient(); client.Encoding = Encoding.UTF8; @@ -317,7 +321,7 @@ private void OnDownloadVimeoApiCompleted(object sender, DownloadStringCompletedE if (idx > -1) { var endIdx = e.Result.IndexOf('"', idx + 1); - while (e.Result[endIdx - 1] == '\\') + while (endIdx > 0 && e.Result[endIdx - 1] == '\\') endIdx = e.Result.IndexOf('"', endIdx + 1); if (endIdx > -1) { @@ -333,49 +337,59 @@ private void OnDownloadVimeoApiCompleted(object sender, DownloadStringCompletedE Width = "640"; if (string.IsNullOrEmpty(Height)) Height = "360"; + var urlIdx = e.Result.IndexOf("\"https:\\/\\/", idx); + if (urlIdx != -1) + idx = urlIdx; } else { - idx = e.Result.IndexOf("thumbnail_medium", idx); + idx = e.Result.IndexOf("\"thumbnail_medium\"", StringComparison.Ordinal); if (idx > -1) { if (string.IsNullOrEmpty(Width)) Width = "200"; if (string.IsNullOrEmpty(Height)) Height = "150"; + var urlIdx = e.Result.IndexOf("\"https:\\/\\/", idx); + if (urlIdx != -1) + idx = urlIdx; } else { - idx = e.Result.IndexOf("thumbnail_small", idx); - if (string.IsNullOrEmpty(Width)) - Width = "100"; - if (string.IsNullOrEmpty(Height)) - Height = "75"; + idx = e.Result.IndexOf("\"thumbnail_small\"", StringComparison.Ordinal); + if (idx > -1) + { + if (string.IsNullOrEmpty(Width)) + Width = "100"; + if (string.IsNullOrEmpty(Height)) + Height = "75"; + var urlIdx = e.Result.IndexOf("\"https:\\/\\/", idx); + if (urlIdx != -1) + idx = urlIdx; + } } } if (idx > -1) { - idx = e.Result.IndexOf("http:", idx); - if (idx > -1) + idx = idx + 1; + var endIdx = e.Result.IndexOf('"', idx); + if (endIdx > -1) { - var endIdx = e.Result.IndexOf('"', idx); - if (endIdx > -1) - { - _videoImageUrl = e.Result.Substring(idx, endIdx - idx).Replace("\\\"", "\"").Replace("\\", ""); - } + _videoImageUrl = e.Result.Substring(idx, endIdx - idx).Replace("\\/", "/"); } } idx = e.Result.IndexOf("\"url\"", StringComparison.Ordinal); if (idx > -1) { - idx = e.Result.IndexOf("http:", idx); + idx = e.Result.IndexOf("\"https:\\/\\/", idx); if (idx > -1) { + idx = idx + 1; var endIdx = e.Result.IndexOf('"', idx); if (endIdx > -1) { - _videoLinkUrl = e.Result.Substring(idx, endIdx - idx).Replace("\\\"", "\"").Replace("\\", ""); + _videoLinkUrl = e.Result.Substring(idx, endIdx - idx).Replace("\\/", "/"); } } } @@ -451,7 +465,7 @@ protected override void PaintImp(RGraphics g) var rects = CommonUtils.GetFirstValueOrDefault(Rectangles); - RPoint offset = HtmlContainer != null ? HtmlContainer.ScrollOffset : RPoint.Empty; + RPoint offset = (HtmlContainer != null && !IsFixed) ? HtmlContainer.ScrollOffset : RPoint.Empty; rects.Offset(offset); var clipped = RenderUtils.ClipGraphicsByOverflow(g, this); diff --git a/Source/HtmlRenderer/Core/Dom/CssBoxHr.cs b/Source/HtmlRenderer/Core/Dom/CssBoxHr.cs index a73a5c3b3..8280f47c3 100644 --- a/Source/HtmlRenderer/Core/Dom/CssBoxHr.cs +++ b/Source/HtmlRenderer/Core/Dom/CssBoxHr.cs @@ -95,7 +95,7 @@ protected override void PerformLayoutImp(RGraphics g) /// the device to draw to protected override void PaintImp(RGraphics g) { - var offset = HtmlContainer != null ? HtmlContainer.ScrollOffset : RPoint.Empty; + var offset = (HtmlContainer != null && !IsFixed) ? HtmlContainer.ScrollOffset : RPoint.Empty; var rect = new RRect(Bounds.X + offset.X, Bounds.Y + offset.Y, Bounds.Width, Bounds.Height); if (rect.Height > 2 && RenderUtils.IsColorVisible(ActualBackgroundColor)) diff --git a/Source/HtmlRenderer/Core/Dom/CssBoxImage.cs b/Source/HtmlRenderer/Core/Dom/CssBoxImage.cs index 948a2721c..a33627c83 100644 --- a/Source/HtmlRenderer/Core/Dom/CssBoxImage.cs +++ b/Source/HtmlRenderer/Core/Dom/CssBoxImage.cs @@ -69,7 +69,7 @@ public RImage Image /// the device to draw to protected override void PaintImp(RGraphics g) { - // load image iff it is in visible rectangle + // load image if it is in visible rectangle if (_imageLoadHandler == null) { _imageLoadHandler = new ImageLoadHandler(HtmlContainer, OnLoadImageComplete); @@ -77,7 +77,11 @@ protected override void PaintImp(RGraphics g) } var rect = CommonUtils.GetFirstValueOrDefault(Rectangles); - RPoint offset = HtmlContainer.ScrollOffset; + RPoint offset = RPoint.Empty; + + if (!IsFixed) + offset = HtmlContainer.ScrollOffset; + rect.Offset(offset); var clipped = RenderUtils.ClipGraphicsByOverflow(g, this); @@ -138,7 +142,11 @@ internal override void MeasureWordsSize(RGraphics g) if (_imageLoadHandler == null && (HtmlContainer.AvoidAsyncImagesLoading || HtmlContainer.AvoidImagesLateLoading)) { _imageLoadHandler = new ImageLoadHandler(HtmlContainer, OnLoadImageComplete); - _imageLoadHandler.LoadImage(GetAttribute("src"), HtmlTag != null ? HtmlTag.Attributes : null); + + if (this.Content != null && this.Content != CssConstants.Normal) + _imageLoadHandler.LoadImage(this.Content, HtmlTag != null ? HtmlTag.Attributes : null); + else + _imageLoadHandler.LoadImage(GetAttribute("src"), HtmlTag != null ? HtmlTag.Attributes : null); } MeasureWordSpacing(g); diff --git a/Source/HtmlRenderer/Core/Dom/CssBoxProperties.cs b/Source/HtmlRenderer/Core/Dom/CssBoxProperties.cs index 3acc6ed41..e74671701 100644 --- a/Source/HtmlRenderer/Core/Dom/CssBoxProperties.cs +++ b/Source/HtmlRenderer/Core/Dom/CssBoxProperties.cs @@ -53,6 +53,7 @@ internal abstract class CssBoxProperties private string _borderCollapse = "separate"; private string _bottom; private string _color = "black"; + private string _content = "normal"; private string _cornerNwRadius = "0"; private string _cornerNeRadius = "0"; private string _cornerSeRadius = "0"; @@ -83,6 +84,7 @@ internal abstract class CssBoxProperties private string _paddingBottom = "0"; private string _paddingRight = "0"; private string _paddingTop = "0"; + private string _pageBreakInside = CssConstants.Auto; private string _right; private string _textAlign = string.Empty; private string _textDecoration = string.Empty; @@ -398,16 +400,41 @@ public string PaddingTop } } + public string PageBreakInside + { + get { return _pageBreakInside; } + set + { + _pageBreakInside = value; + } + } + public string Left { get { return _left; } - set { _left = value; } + set + { + _left = value; + + if (Position == CssConstants.Fixed) + { + _location = GetActualLocation(Left, Top); + } + } } public string Top { get { return _top; } - set { _top = value; } + set { + _top = value; + + if (Position == CssConstants.Fixed) + { + _location = GetActualLocation(Left, Top); + } + + } } public string Width @@ -474,6 +501,12 @@ public string Color } } + public string Content + { + get { return _content; } + set { _content = value; } + } + public string Display { get { return _display; } @@ -646,16 +679,26 @@ public string ListStyleType set { _listStyleType = value; } } - #endregion - + #endregion CSS Propertier /// /// Gets or sets the location of the box /// public RPoint Location { - get { return _location; } - set { _location = value; } + get { + if (_location.IsEmpty && Position == CssConstants.Fixed) + { + var left = Left; + var top = Top; + + _location = GetActualLocation(Left, Top); + } + return _location; + } + set { + _location = value; + } } /// @@ -1012,6 +1055,8 @@ public RColor ActualBorderTopColor } } + protected abstract RPoint GetActualLocation(string X, string Y); + protected abstract RColor GetActualColor(string colorStr); /// @@ -1454,7 +1499,6 @@ protected void InheritStyle(CssBox p, bool everything) _visibility = p._visibility; _textIndent = p._textIndent; _textAlign = p._textAlign; - _verticalAlign = p._verticalAlign; _fontFamily = p._fontFamily; _fontSize = p._fontSize; _fontStyle = p._fontStyle; @@ -1512,6 +1556,7 @@ protected void InheritStyle(CssBox p, bool everything) _textDecoration = p._textDecoration; _top = p._top; _position = p._position; + _verticalAlign = p._verticalAlign; _width = p._width; _maxWidth = p._maxWidth; _wordSpacing = p._wordSpacing; diff --git a/Source/HtmlRenderer/Core/Dom/CssLayoutEngine.cs b/Source/HtmlRenderer/Core/Dom/CssLayoutEngine.cs index 420717860..a24f9e708 100644 --- a/Source/HtmlRenderer/Core/Dom/CssLayoutEngine.cs +++ b/Source/HtmlRenderer/Core/Dom/CssLayoutEngine.cs @@ -250,8 +250,8 @@ private static void FlowBox(RGraphics g, CssBox blockbox, CssBox box, double lim foreach (CssBox b in box.Boxes) { - double leftspacing = b.Position != CssConstants.Absolute ? b.ActualMarginLeft + b.ActualBorderLeftWidth + b.ActualPaddingLeft : 0; - double rightspacing = b.Position != CssConstants.Absolute ? b.ActualMarginRight + b.ActualBorderRightWidth + b.ActualPaddingRight : 0; + double leftspacing = (b.Position != CssConstants.Absolute && b.Position != CssConstants.Fixed) ? b.ActualMarginLeft + b.ActualBorderLeftWidth + b.ActualPaddingLeft : 0; + double rightspacing = (b.Position != CssConstants.Absolute && b.Position != CssConstants.Fixed) ? b.ActualMarginRight + b.ActualBorderRightWidth + b.ActualPaddingRight : 0; b.RectanglesReset(); b.MeasureWordsSize(g); @@ -304,6 +304,11 @@ private static void FlowBox(RGraphics g, CssBox blockbox, CssBox box, double lim word.Left = curx; word.Top = cury; + if (!box.IsFixed) + { + word.BreakPage(); + } + curx = word.Left + word.FullWidth; maxRight = Math.Max(maxRight, word.Right); @@ -395,9 +400,11 @@ private static void BubbleRectangles(CssBox box, CssLineBox line) { // handle if line is wrapped for the first text element where parent has left margin\padding var left = word.Left; + if (box == box.ParentBox.Boxes[0] && word == box.Words[0] && word == line.Words[0] && line != line.OwnerBox.LineBoxes[0] && !word.IsLineBreak) left -= box.ParentBox.ActualMarginLeft + box.ParentBox.ActualBorderLeftWidth + box.ParentBox.ActualPaddingLeft; + x = Math.Min(x, left); r = Math.Max(r, word.Right); y = Math.Min(y, word.Top); diff --git a/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs b/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs index 7772a0d30..79627161a 100644 --- a/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs +++ b/Source/HtmlRenderer/Core/Dom/CssLayoutEngineTable.cs @@ -629,6 +629,7 @@ private void LayoutCells(RGraphics g) var row = _allRows[i]; double curx = startx; int curCol = 0; + bool breakPage = false; for (int j = 0; j < row.Boxes.Count; j++) { @@ -675,9 +676,32 @@ private void LayoutCells(RGraphics g) spacer.ExtendedBox.ActualBottom = maxBottom; CssLayoutEngine.ApplyCellVerticalAlignment(g, spacer.ExtendedBox); } + + // If one cell crosses page borders then don't need to check other cells in the row + if (_tableBox.PageBreakInside == CssConstants.Avoid) + { + breakPage = cell.BreakPage(); + if (breakPage) + { + cury = cell.Location.Y; + break; + } + } + } + + if (breakPage) // go back to move the whole row to the next page + { + if (i == 1) // do not leave single row in previous page + i = -1; // Start layout from the first row on new page + else + i--; + + maxBottom = 0; + continue; } cury = maxBottom + GetVerticalSpacing(); + currentrow++; } diff --git a/Source/HtmlRenderer/Core/Dom/CssRect.cs b/Source/HtmlRenderer/Core/Dom/CssRect.cs index e8bc9d3fa..d7ff14ac1 100644 --- a/Source/HtmlRenderer/Core/Dom/CssRect.cs +++ b/Source/HtmlRenderer/Core/Dom/CssRect.cs @@ -268,5 +268,24 @@ public override string ToString() { return string.Format("{0} ({1} char{2})", Text.Replace(' ', '-').Replace("\n", "\\n"), Text.Length, Text.Length != 1 ? "s" : string.Empty); } + + public bool BreakPage() + { + var container = this.OwnerBox.HtmlContainer; + + if (this.Height >= container.PageSize.Height) + return false; + + var remTop = (this.Top - container.MarginTop) % container.PageSize.Height; + var remBottom = (this.Bottom - container.MarginTop) % container.PageSize.Height; + + if (remTop > remBottom) + { + this.Top += container.PageSize.Height - remTop + 1; + return true; + } + + return false; + } } } \ No newline at end of file diff --git a/Source/HtmlRenderer/Core/Handlers/ImageDownloader.cs b/Source/HtmlRenderer/Core/Handlers/ImageDownloader.cs index 8ebdf009e..2f8b0f5e6 100644 --- a/Source/HtmlRenderer/Core/Handlers/ImageDownloader.cs +++ b/Source/HtmlRenderer/Core/Handlers/ImageDownloader.cs @@ -48,6 +48,11 @@ internal sealed class ImageDownloader : IDisposable /// private readonly Dictionary> _imageDownloadCallbacks = new Dictionary>(); + public ImageDownloader() + { + ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; + } + /// /// Makes a request to download the image from the server and raises the when it's down.
///
diff --git a/Source/HtmlRenderer/Core/HtmlContainerInt.cs b/Source/HtmlRenderer/Core/HtmlContainerInt.cs index e3f25cbef..1d71de9fb 100644 --- a/Source/HtmlRenderer/Core/HtmlContainerInt.cs +++ b/Source/HtmlRenderer/Core/HtmlContainerInt.cs @@ -179,6 +179,26 @@ public sealed class HtmlContainerInt : IDisposable ///
private RSize _actualSize; + /// + /// the top margin between the page start and the text + /// + private int _marginTop; + + /// + /// the bottom margin between the page end and the text + /// + private int _marginBottom; + + /// + /// the left margin between the page start and the text + /// + private int _marginLeft; + + /// + /// the right margin between the page end and the text + /// + private int _marginRight; + #endregion @@ -373,6 +393,70 @@ public RSize ActualSize set { _actualSize = value; } } + public RSize PageSize { get; set; } + + /// + /// the top margin between the page start and the text + /// + public int MarginTop + { + get { return _marginTop; } + set + { + if (value > -1) + _marginTop = value; + } + } + + /// + /// the bottom margin between the page end and the text + /// + public int MarginBottom + { + get { return _marginBottom; } + set + { + if (value > -1) + _marginBottom = value; + } + } + + /// + /// the left margin between the page start and the text + /// + public int MarginLeft + { + get { return _marginLeft; } + set + { + if (value > -1) + _marginLeft = value; + } + } + + /// + /// the right margin between the page end and the text + /// + public int MarginRight + { + get { return _marginRight; } + set + { + if (value > -1) + _marginRight = value; + } + } + + /// + /// Set all 4 margins to the given value. + /// + /// + public void SetMargins(int value) + { + if (value > -1) + _marginBottom = _marginLeft = _marginTop = _marginRight = value; + } + /// /// Get the currently selected text segment in the html. /// @@ -582,11 +666,13 @@ public void PerformPaint(RGraphics g) { ArgChecker.AssertArgNotNull(g, "g"); - bool pushedClip = false; if (MaxSize.Height > 0) { - pushedClip = true; - g.PushClip(new RRect(_location, _maxSize)); + g.PushClip(new RRect(_location.X, _location.Y, Math.Min(_maxSize.Width, PageSize.Width), Math.Min(_maxSize.Height, PageSize.Height))); + } + else + { + g.PushClip(new RRect(MarginLeft, MarginTop, PageSize.Width, PageSize.Height)); } if (_root != null) @@ -594,10 +680,7 @@ public void PerformPaint(RGraphics g) _root.Paint(g); } - if (pushedClip) - { - g.PopClip(); - } + g.PopClip(); } /// diff --git a/Source/HtmlRenderer/Core/Parse/CssParser.cs b/Source/HtmlRenderer/Core/Parse/CssParser.cs index 04839ad9a..cb6ef8975 100644 --- a/Source/HtmlRenderer/Core/Parse/CssParser.cs +++ b/Source/HtmlRenderer/Core/Parse/CssParser.cs @@ -395,6 +395,12 @@ private Dictionary ParseCssBlockProperties(string blockSource) while (startIdx < blockSource.Length) { int endIdx = blockSource.IndexOfAny(_cssBlockSplitters, startIdx); + + // If blockSource contains "data:image" then skip first semicolon since it is a part of image definition + // example: "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA......" + if (startIdx >= 0 && endIdx - startIdx >= 10 && blockSource.Length - startIdx >= 10 && blockSource.IndexOf("data:image", startIdx, endIdx - startIdx) >= 0) + endIdx = blockSource.IndexOfAny(_cssBlockSplitters, endIdx + 1); + if (endIdx < 0) endIdx = blockSource.Length - 1; @@ -485,7 +491,11 @@ private void AddProperty(string propName, string propValue, Dictionary prop /// /// the value of the property to parse /// parsed value - private static string ParseBackgroundImageProperty(string propValue) + private static string ParseImageProperty(string propValue) { int startIdx = propValue.IndexOf("url(", StringComparison.InvariantCultureIgnoreCase); if (startIdx > -1) @@ -615,9 +625,10 @@ private static string ParseBackgroundImageProperty(string propValue) private string ParseFontFamilyProperty(string propValue) { int start = 0; - while (start > -1 && start < propValue.Length) + + while (start < propValue.Length) { - while (char.IsWhiteSpace(propValue[start]) || propValue[start] == ',' || propValue[start] == '\'' || propValue[start] == '"') + while (start < propValue.Length && (char.IsWhiteSpace(propValue[start]) || propValue[start] == ',' || propValue[start] == '\'' || propValue[start] == '"')) start++; var end = propValue.IndexOf(',', start); if (end < 0) @@ -629,9 +640,7 @@ private string ParseFontFamilyProperty(string propValue) var font = propValue.Substring(start, adjEnd - start + 1); if (_adapter.IsFontExists(font)) - { return font; - } start = end; } diff --git a/Source/HtmlRenderer/Core/Parse/HtmlParser.cs b/Source/HtmlRenderer/Core/Parse/HtmlParser.cs index 286dee89c..49ee39051 100644 --- a/Source/HtmlRenderer/Core/Parse/HtmlParser.cs +++ b/Source/HtmlRenderer/Core/Parse/HtmlParser.cs @@ -222,27 +222,31 @@ private static void ExtractAttributes(string source, int idx, int length, out Di if (startIdx < idx + length) { var key = source.Substring(startIdx, endIdx - startIdx); + var value = ""; startIdx = endIdx + 1; while (startIdx < idx + length && (char.IsWhiteSpace(source, startIdx) || source[startIdx] == '=')) startIdx++; bool hasPChar = false; - char pChar = source[startIdx]; - if (pChar == '"' || pChar == '\'') + if (startIdx < idx + length) { - hasPChar = true; - startIdx++; - } + char pChar = source[startIdx]; + if (pChar == '"' || pChar == '\'') + { + hasPChar = true; + startIdx++; + } - endIdx = startIdx + (hasPChar ? 0 : 1); - while (endIdx < idx + length && (hasPChar ? source[endIdx] != pChar : !char.IsWhiteSpace(source, endIdx))) - endIdx++; + endIdx = startIdx + (hasPChar ? 0 : 1); + while (endIdx < idx + length && (hasPChar ? source[endIdx] != pChar : !char.IsWhiteSpace(source, endIdx))) + endIdx++; - var value = source.Substring(startIdx, endIdx - startIdx); - value = HtmlUtils.DecodeHtml(value); + value = source.Substring(startIdx, endIdx - startIdx); + value = HtmlUtils.DecodeHtml(value); + } - if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value)) + if (key.Length != 0) { if (attributes == null) attributes = new Dictionary(StringComparer.InvariantCultureIgnoreCase); diff --git a/Source/HtmlRenderer/Core/Parse/RegexParserUtils.cs b/Source/HtmlRenderer/Core/Parse/RegexParserUtils.cs index 806fca4cf..64e2891d9 100644 --- a/Source/HtmlRenderer/Core/Parse/RegexParserUtils.cs +++ b/Source/HtmlRenderer/Core/Parse/RegexParserUtils.cs @@ -107,9 +107,9 @@ public static string GetCssAtRules(string stylesheet, ref int startIdx) int endIdx = stylesheet.IndexOf('{', startIdx); if (endIdx > -1) { + endIdx++; // to prevent IndexOutOfRangeException at line 113. When '}' is last character in 'stylesheet' variable while (count > 0 && endIdx < stylesheet.Length) { - endIdx++; if (stylesheet[endIdx] == '{') { count++; @@ -118,6 +118,7 @@ public static string GetCssAtRules(string stylesheet, ref int startIdx) { count--; } + endIdx++; } if (endIdx < stylesheet.Length) { @@ -194,4 +195,4 @@ private static Regex GetRegex(string regex) return r; } } -} \ No newline at end of file +} diff --git a/Source/HtmlRenderer/Core/Utils/CssConstants.cs b/Source/HtmlRenderer/Core/Utils/CssConstants.cs index 352406244..655849256 100644 --- a/Source/HtmlRenderer/Core/Utils/CssConstants.cs +++ b/Source/HtmlRenderer/Core/Utils/CssConstants.cs @@ -19,6 +19,7 @@ internal static class CssConstants { public const string Absolute = "absolute"; public const string Auto = "auto"; + public const string Avoid = "avoid"; public const string Baseline = "baseline"; public const string Blink = "blink"; public const string Block = "block"; @@ -36,6 +37,7 @@ internal static class CssConstants public const string DecimalLeadingZero = "decimal-leading-zero"; public const string Disc = "disc"; public const string Fantasy = "fantasy"; + public const string Fixed = "fixed"; public const string Hide = "hide"; public const string Inherit = "inherit"; public const string Inline = "inline"; diff --git a/Source/HtmlRenderer/Core/Utils/CssUtils.cs b/Source/HtmlRenderer/Core/Utils/CssUtils.cs index 1f5c4da6a..69f949390 100644 --- a/Source/HtmlRenderer/Core/Utils/CssUtils.cs +++ b/Source/HtmlRenderer/Core/Utils/CssUtils.cs @@ -122,6 +122,8 @@ public static string GetPropertyValue(CssBox cssBox, string propName) return cssBox.PaddingRight; case "padding-top": return cssBox.PaddingTop; + case "page-break-inside": + return cssBox.PageBreakInside; case "left": return cssBox.Left; case "top": @@ -144,6 +146,8 @@ public static string GetPropertyValue(CssBox cssBox, string propName) return cssBox.BackgroundGradient; case "background-gradient-angle": return cssBox.BackgroundGradientAngle; + case "content": + return cssBox.Content; case "color": return cssBox.Color; case "display": @@ -290,6 +294,9 @@ public static void SetPropertyValue(CssBox cssBox, string propName, string value case "padding-top": cssBox.PaddingTop = value; break; + case "page-break-inside": + cssBox.PageBreakInside = value; + break; case "left": cssBox.Left = value; break; @@ -326,6 +333,9 @@ public static void SetPropertyValue(CssBox cssBox, string propName, string value case "color": cssBox.Color = value; break; + case "content": + cssBox.Content = value; + break; case "display": cssBox.Display = value; break; diff --git a/Source/HtmlRenderer/Core/Utils/DomUtils.cs b/Source/HtmlRenderer/Core/Utils/DomUtils.cs index 03a1d668c..6d00a4abc 100644 --- a/Source/HtmlRenderer/Core/Utils/DomUtils.cs +++ b/Source/HtmlRenderer/Core/Utils/DomUtils.cs @@ -101,12 +101,12 @@ public static CssBox GetPreviousSibling(CssBox b) int diff = 1; CssBox sib = b.ParentBox.Boxes[index - diff]; - while ((sib.Display == CssConstants.None || sib.Position == CssConstants.Absolute) && index - diff - 1 >= 0) + while ((sib.Display == CssConstants.None || sib.Position == CssConstants.Absolute || sib.Position == CssConstants.Fixed) && index - diff - 1 >= 0) { sib = b.ParentBox.Boxes[index - ++diff]; } - return sib.Display == CssConstants.None ? null : sib; + return (sib.Display == CssConstants.None || sib.Position == CssConstants.Fixed) ? null : sib; } } return null; @@ -131,7 +131,7 @@ public static CssBox GetPreviousContainingBlockSibling(CssBox b) int diff = 1; CssBox sib = conBlock.Boxes[index - diff]; - while ((sib.Display == CssConstants.None || sib.Position == CssConstants.Absolute) && index - diff - 1 >= 0) + while ((sib.Display == CssConstants.None || sib.Position == CssConstants.Absolute || sib.Position == CssConstants.Fixed) && index - diff - 1 >= 0) { sib = conBlock.Boxes[index - ++diff]; } @@ -169,7 +169,7 @@ public static CssBox GetNextSibling(CssBox b) while (index <= b.ParentBox.Boxes.Count - 1) { var pSib = b.ParentBox.Boxes[index]; - if (pSib.Display != CssConstants.None && pSib.Position != CssConstants.Absolute) + if (pSib.Display != CssConstants.None && pSib.Position != CssConstants.Absolute && pSib.Position != CssConstants.Fixed) { sib = pSib; break; diff --git a/Source/HtmlRenderer/Core/Utils/HtmlConstants.cs b/Source/HtmlRenderer/Core/Utils/HtmlConstants.cs index 6d2596218..834cbe540 100644 --- a/Source/HtmlRenderer/Core/Utils/HtmlConstants.cs +++ b/Source/HtmlRenderer/Core/Utils/HtmlConstants.cs @@ -128,7 +128,7 @@ internal static class HtmlConstants // public const string cols = "cols"; // public const string colspan = "colspan"; // public const string compact = "compact"; - // public const string content = "content"; + public const string content = "content"; // public const string coords = "coords"; // public const string data = "data"; // public const string datetime = "datetime"; diff --git a/Source/HtmlRenderer/Core/Utils/HtmlUtils.cs b/Source/HtmlRenderer/Core/Utils/HtmlUtils.cs index 09cc95a86..d0198d20c 100644 --- a/Source/HtmlRenderer/Core/Utils/HtmlUtils.cs +++ b/Source/HtmlRenderer/Core/Utils/HtmlUtils.cs @@ -46,6 +46,7 @@ internal static class HtmlUtils /// the html decode only pairs ///
private static readonly Dictionary _decodeOnly = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + private static readonly Dictionary _decodeOnlyCaseSensitive = new Dictionary(StringComparer.InvariantCulture); #endregion @@ -96,68 +97,68 @@ static HtmlUtils() _decodeOnly["divide"] = Convert.ToChar(247); // ISO 8859-1 Characters - _decodeOnly["Agrave"] = Convert.ToChar(192); - _decodeOnly["Aacute"] = Convert.ToChar(193); - _decodeOnly["Acirc"] = Convert.ToChar(194); - _decodeOnly["Atilde"] = Convert.ToChar(195); - _decodeOnly["Auml"] = Convert.ToChar(196); - _decodeOnly["Aring"] = Convert.ToChar(197); - _decodeOnly["AElig"] = Convert.ToChar(198); - _decodeOnly["Ccedil"] = Convert.ToChar(199); - _decodeOnly["Egrave"] = Convert.ToChar(200); - _decodeOnly["Eacute"] = Convert.ToChar(201); - _decodeOnly["Ecirc"] = Convert.ToChar(202); - _decodeOnly["Euml"] = Convert.ToChar(203); - _decodeOnly["Igrave"] = Convert.ToChar(204); - _decodeOnly["Iacute"] = Convert.ToChar(205); - _decodeOnly["Icirc"] = Convert.ToChar(206); - _decodeOnly["Iuml"] = Convert.ToChar(207); - _decodeOnly["ETH"] = Convert.ToChar(208); - _decodeOnly["Ntilde"] = Convert.ToChar(209); - _decodeOnly["Ograve"] = Convert.ToChar(210); - _decodeOnly["Oacute"] = Convert.ToChar(211); - _decodeOnly["Ocirc"] = Convert.ToChar(212); - _decodeOnly["Otilde"] = Convert.ToChar(213); - _decodeOnly["Ouml"] = Convert.ToChar(214); - _decodeOnly["Oslash"] = Convert.ToChar(216); - _decodeOnly["Ugrave"] = Convert.ToChar(217); - _decodeOnly["Uacute"] = Convert.ToChar(218); - _decodeOnly["Ucirc"] = Convert.ToChar(219); - _decodeOnly["Uuml"] = Convert.ToChar(220); - _decodeOnly["Yacute"] = Convert.ToChar(221); - _decodeOnly["THORN"] = Convert.ToChar(222); + _decodeOnlyCaseSensitive["Agrave"] = Convert.ToChar(192); + _decodeOnlyCaseSensitive["Aacute"] = Convert.ToChar(193); + _decodeOnlyCaseSensitive["Acirc"] = Convert.ToChar(194); + _decodeOnlyCaseSensitive["Atilde"] = Convert.ToChar(195); + _decodeOnlyCaseSensitive["Auml"] = Convert.ToChar(196); + _decodeOnlyCaseSensitive["Aring"] = Convert.ToChar(197); + _decodeOnlyCaseSensitive["AElig"] = Convert.ToChar(198); + _decodeOnlyCaseSensitive["Ccedil"] = Convert.ToChar(199); + _decodeOnlyCaseSensitive["Egrave"] = Convert.ToChar(200); + _decodeOnlyCaseSensitive["Eacute"] = Convert.ToChar(201); + _decodeOnlyCaseSensitive["Ecirc"] = Convert.ToChar(202); + _decodeOnlyCaseSensitive["Euml"] = Convert.ToChar(203); + _decodeOnlyCaseSensitive["Igrave"] = Convert.ToChar(204); + _decodeOnlyCaseSensitive["Iacute"] = Convert.ToChar(205); + _decodeOnlyCaseSensitive["Icirc"] = Convert.ToChar(206); + _decodeOnlyCaseSensitive["Iuml"] = Convert.ToChar(207); + _decodeOnlyCaseSensitive["ETH"] = Convert.ToChar(208); + _decodeOnlyCaseSensitive["Ntilde"] = Convert.ToChar(209); + _decodeOnlyCaseSensitive["Ograve"] = Convert.ToChar(210); + _decodeOnlyCaseSensitive["Oacute"] = Convert.ToChar(211); + _decodeOnlyCaseSensitive["Ocirc"] = Convert.ToChar(212); + _decodeOnlyCaseSensitive["Otilde"] = Convert.ToChar(213); + _decodeOnlyCaseSensitive["Ouml"] = Convert.ToChar(214); + _decodeOnlyCaseSensitive["Oslash"] = Convert.ToChar(216); + _decodeOnlyCaseSensitive["Ugrave"] = Convert.ToChar(217); + _decodeOnlyCaseSensitive["Uacute"] = Convert.ToChar(218); + _decodeOnlyCaseSensitive["Ucirc"] = Convert.ToChar(219); + _decodeOnlyCaseSensitive["Uuml"] = Convert.ToChar(220); + _decodeOnlyCaseSensitive["Yacute"] = Convert.ToChar(221); + _decodeOnlyCaseSensitive["THORN"] = Convert.ToChar(222); _decodeOnly["szlig"] = Convert.ToChar(223); - _decodeOnly["agrave"] = Convert.ToChar(224); - _decodeOnly["aacute"] = Convert.ToChar(225); - _decodeOnly["acirc"] = Convert.ToChar(226); - _decodeOnly["atilde"] = Convert.ToChar(227); - _decodeOnly["auml"] = Convert.ToChar(228); - _decodeOnly["aring"] = Convert.ToChar(229); - _decodeOnly["aelig"] = Convert.ToChar(230); - _decodeOnly["ccedil"] = Convert.ToChar(231); - _decodeOnly["egrave"] = Convert.ToChar(232); - _decodeOnly["eacute"] = Convert.ToChar(233); - _decodeOnly["ecirc"] = Convert.ToChar(234); - _decodeOnly["euml"] = Convert.ToChar(235); - _decodeOnly["igrave"] = Convert.ToChar(236); - _decodeOnly["iacute"] = Convert.ToChar(237); - _decodeOnly["icirc"] = Convert.ToChar(238); - _decodeOnly["iuml"] = Convert.ToChar(239); - _decodeOnly["eth"] = Convert.ToChar(240); - _decodeOnly["ntilde"] = Convert.ToChar(241); - _decodeOnly["ograve"] = Convert.ToChar(242); - _decodeOnly["oacute"] = Convert.ToChar(243); - _decodeOnly["ocirc"] = Convert.ToChar(244); - _decodeOnly["otilde"] = Convert.ToChar(245); - _decodeOnly["ouml"] = Convert.ToChar(246); - _decodeOnly["oslash"] = Convert.ToChar(248); - _decodeOnly["ugrave"] = Convert.ToChar(249); - _decodeOnly["uacute"] = Convert.ToChar(250); - _decodeOnly["ucirc"] = Convert.ToChar(251); - _decodeOnly["uuml"] = Convert.ToChar(252); - _decodeOnly["yacute"] = Convert.ToChar(253); - _decodeOnly["thorn"] = Convert.ToChar(254); - _decodeOnly["yuml"] = Convert.ToChar(255); + _decodeOnlyCaseSensitive["agrave"] = Convert.ToChar(224); + _decodeOnlyCaseSensitive["aacute"] = Convert.ToChar(225); + _decodeOnlyCaseSensitive["acirc"] = Convert.ToChar(226); + _decodeOnlyCaseSensitive["atilde"] = Convert.ToChar(227); + _decodeOnlyCaseSensitive["auml"] = Convert.ToChar(228); + _decodeOnlyCaseSensitive["aring"] = Convert.ToChar(229); + _decodeOnlyCaseSensitive["aelig"] = Convert.ToChar(230); + _decodeOnlyCaseSensitive["ccedil"] = Convert.ToChar(231); + _decodeOnlyCaseSensitive["egrave"] = Convert.ToChar(232); + _decodeOnlyCaseSensitive["eacute"] = Convert.ToChar(233); + _decodeOnlyCaseSensitive["ecirc"] = Convert.ToChar(234); + _decodeOnlyCaseSensitive["euml"] = Convert.ToChar(235); + _decodeOnlyCaseSensitive["igrave"] = Convert.ToChar(236); + _decodeOnlyCaseSensitive["iacute"] = Convert.ToChar(237); + _decodeOnlyCaseSensitive["icirc"] = Convert.ToChar(238); + _decodeOnlyCaseSensitive["iuml"] = Convert.ToChar(239); + _decodeOnlyCaseSensitive["eth"] = Convert.ToChar(240); + _decodeOnlyCaseSensitive["ntilde"] = Convert.ToChar(241); + _decodeOnlyCaseSensitive["ograve"] = Convert.ToChar(242); + _decodeOnlyCaseSensitive["oacute"] = Convert.ToChar(243); + _decodeOnlyCaseSensitive["ocirc"] = Convert.ToChar(244); + _decodeOnlyCaseSensitive["otilde"] = Convert.ToChar(245); + _decodeOnlyCaseSensitive["ouml"] = Convert.ToChar(246); + _decodeOnlyCaseSensitive["oslash"] = Convert.ToChar(248); + _decodeOnlyCaseSensitive["ugrave"] = Convert.ToChar(249); + _decodeOnlyCaseSensitive["uacute"] = Convert.ToChar(250); + _decodeOnlyCaseSensitive["ucirc"] = Convert.ToChar(251); + _decodeOnlyCaseSensitive["uuml"] = Convert.ToChar(252); + _decodeOnlyCaseSensitive["yacute"] = Convert.ToChar(253); + _decodeOnlyCaseSensitive["thorn"] = Convert.ToChar(254); + _decodeOnlyCaseSensitive["yuml"] = Convert.ToChar(255); // Math Symbols Supported by HTML _decodeOnly["forall"] = Convert.ToChar(8704); @@ -200,65 +201,65 @@ static HtmlUtils() _decodeOnly["sdot"] = Convert.ToChar(8901); // Greek Letters Supported by HTML - _decodeOnly["Alpha"] = Convert.ToChar(913); - _decodeOnly["Beta"] = Convert.ToChar(914); - _decodeOnly["Gamma"] = Convert.ToChar(915); - _decodeOnly["Delta"] = Convert.ToChar(916); - _decodeOnly["Epsilon"] = Convert.ToChar(917); - _decodeOnly["Zeta"] = Convert.ToChar(918); - _decodeOnly["Eta"] = Convert.ToChar(919); - _decodeOnly["Theta"] = Convert.ToChar(920); - _decodeOnly["Iota"] = Convert.ToChar(921); - _decodeOnly["Kappa"] = Convert.ToChar(922); - _decodeOnly["Lambda"] = Convert.ToChar(923); - _decodeOnly["Mu"] = Convert.ToChar(924); - _decodeOnly["Nu"] = Convert.ToChar(925); - _decodeOnly["Xi"] = Convert.ToChar(926); - _decodeOnly["Omicron"] = Convert.ToChar(927); - _decodeOnly["Pi"] = Convert.ToChar(928); - _decodeOnly["Rho"] = Convert.ToChar(929); - _decodeOnly["Sigma"] = Convert.ToChar(931); - _decodeOnly["Tau"] = Convert.ToChar(932); - _decodeOnly["Upsilon"] = Convert.ToChar(933); - _decodeOnly["Phi"] = Convert.ToChar(934); - _decodeOnly["Chi"] = Convert.ToChar(935); - _decodeOnly["Psi"] = Convert.ToChar(936); - _decodeOnly["Omega"] = Convert.ToChar(937); - _decodeOnly["alpha"] = Convert.ToChar(945); - _decodeOnly["beta"] = Convert.ToChar(946); - _decodeOnly["gamma"] = Convert.ToChar(947); - _decodeOnly["delta"] = Convert.ToChar(948); - _decodeOnly["epsilon"] = Convert.ToChar(949); - _decodeOnly["zeta"] = Convert.ToChar(950); - _decodeOnly["eta"] = Convert.ToChar(951); - _decodeOnly["theta"] = Convert.ToChar(952); - _decodeOnly["iota"] = Convert.ToChar(953); - _decodeOnly["kappa"] = Convert.ToChar(954); - _decodeOnly["lambda"] = Convert.ToChar(955); - _decodeOnly["mu"] = Convert.ToChar(956); - _decodeOnly["nu"] = Convert.ToChar(957); - _decodeOnly["xi"] = Convert.ToChar(958); - _decodeOnly["omicron"] = Convert.ToChar(959); - _decodeOnly["pi"] = Convert.ToChar(960); - _decodeOnly["rho"] = Convert.ToChar(961); - _decodeOnly["sigmaf"] = Convert.ToChar(962); - _decodeOnly["sigma"] = Convert.ToChar(963); - _decodeOnly["tau"] = Convert.ToChar(964); - _decodeOnly["upsilon"] = Convert.ToChar(965); - _decodeOnly["phi"] = Convert.ToChar(966); - _decodeOnly["chi"] = Convert.ToChar(967); - _decodeOnly["psi"] = Convert.ToChar(968); - _decodeOnly["omega"] = Convert.ToChar(969); + _decodeOnlyCaseSensitive["Alpha"] = Convert.ToChar(913); + _decodeOnlyCaseSensitive["Beta"] = Convert.ToChar(914); + _decodeOnlyCaseSensitive["Gamma"] = Convert.ToChar(915); + _decodeOnlyCaseSensitive["Delta"] = Convert.ToChar(916); + _decodeOnlyCaseSensitive["Epsilon"] = Convert.ToChar(917); + _decodeOnlyCaseSensitive["Zeta"] = Convert.ToChar(918); + _decodeOnlyCaseSensitive["Eta"] = Convert.ToChar(919); + _decodeOnlyCaseSensitive["Theta"] = Convert.ToChar(920); + _decodeOnlyCaseSensitive["Iota"] = Convert.ToChar(921); + _decodeOnlyCaseSensitive["Kappa"] = Convert.ToChar(922); + _decodeOnlyCaseSensitive["Lambda"] = Convert.ToChar(923); + _decodeOnlyCaseSensitive["Mu"] = Convert.ToChar(924); + _decodeOnlyCaseSensitive["Nu"] = Convert.ToChar(925); + _decodeOnlyCaseSensitive["Xi"] = Convert.ToChar(926); + _decodeOnlyCaseSensitive["Omicron"] = Convert.ToChar(927); + _decodeOnlyCaseSensitive["Pi"] = Convert.ToChar(928); + _decodeOnlyCaseSensitive["Rho"] = Convert.ToChar(929); + _decodeOnlyCaseSensitive["Sigma"] = Convert.ToChar(931); + _decodeOnlyCaseSensitive["Tau"] = Convert.ToChar(932); + _decodeOnlyCaseSensitive["Upsilon"] = Convert.ToChar(933); + _decodeOnlyCaseSensitive["Phi"] = Convert.ToChar(934); + _decodeOnlyCaseSensitive["Chi"] = Convert.ToChar(935); + _decodeOnlyCaseSensitive["Psi"] = Convert.ToChar(936); + _decodeOnlyCaseSensitive["Omega"] = Convert.ToChar(937); + _decodeOnlyCaseSensitive["alpha"] = Convert.ToChar(945); + _decodeOnlyCaseSensitive["beta"] = Convert.ToChar(946); + _decodeOnlyCaseSensitive["gamma"] = Convert.ToChar(947); + _decodeOnlyCaseSensitive["delta"] = Convert.ToChar(948); + _decodeOnlyCaseSensitive["epsilon"] = Convert.ToChar(949); + _decodeOnlyCaseSensitive["zeta"] = Convert.ToChar(950); + _decodeOnlyCaseSensitive["eta"] = Convert.ToChar(951); + _decodeOnlyCaseSensitive["theta"] = Convert.ToChar(952); + _decodeOnlyCaseSensitive["iota"] = Convert.ToChar(953); + _decodeOnlyCaseSensitive["kappa"] = Convert.ToChar(954); + _decodeOnlyCaseSensitive["lambda"] = Convert.ToChar(955); + _decodeOnlyCaseSensitive["mu"] = Convert.ToChar(956); + _decodeOnlyCaseSensitive["nu"] = Convert.ToChar(957); + _decodeOnlyCaseSensitive["xi"] = Convert.ToChar(958); + _decodeOnlyCaseSensitive["omicron"] = Convert.ToChar(959); + _decodeOnlyCaseSensitive["pi"] = Convert.ToChar(960); + _decodeOnlyCaseSensitive["rho"] = Convert.ToChar(961); + _decodeOnlyCaseSensitive["sigmaf"] = Convert.ToChar(962); + _decodeOnlyCaseSensitive["sigma"] = Convert.ToChar(963); + _decodeOnlyCaseSensitive["tau"] = Convert.ToChar(964); + _decodeOnlyCaseSensitive["upsilon"] = Convert.ToChar(965); + _decodeOnlyCaseSensitive["phi"] = Convert.ToChar(966); + _decodeOnlyCaseSensitive["chi"] = Convert.ToChar(967); + _decodeOnlyCaseSensitive["psi"] = Convert.ToChar(968); + _decodeOnlyCaseSensitive["omega"] = Convert.ToChar(969); _decodeOnly["thetasym"] = Convert.ToChar(977); _decodeOnly["upsih"] = Convert.ToChar(978); _decodeOnly["piv"] = Convert.ToChar(982); // Other Entities Supported by HTML - _decodeOnly["OElig"] = Convert.ToChar(338); - _decodeOnly["oelig"] = Convert.ToChar(339); - _decodeOnly["Scaron"] = Convert.ToChar(352); - _decodeOnly["scaron"] = Convert.ToChar(353); - _decodeOnly["Yuml"] = Convert.ToChar(376); + _decodeOnlyCaseSensitive["OElig"] = Convert.ToChar(338); + _decodeOnlyCaseSensitive["oelig"] = Convert.ToChar(339); + _decodeOnlyCaseSensitive["Scaron"] = Convert.ToChar(352); + _decodeOnlyCaseSensitive["scaron"] = Convert.ToChar(353); + _decodeOnlyCaseSensitive["Yuml"] = Convert.ToChar(376); _decodeOnly["fnof"] = Convert.ToChar(402); _decodeOnly["circ"] = Convert.ToChar(710); _decodeOnly["tilde"] = Convert.ToChar(732); @@ -270,13 +271,13 @@ static HtmlUtils() _decodeOnly["ldquo"] = Convert.ToChar(8220); _decodeOnly["rdquo"] = Convert.ToChar(8221); _decodeOnly["bdquo"] = Convert.ToChar(8222); - _decodeOnly["dagger"] = Convert.ToChar(8224); - _decodeOnly["Dagger"] = Convert.ToChar(8225); + _decodeOnlyCaseSensitive["dagger"] = Convert.ToChar(8224); + _decodeOnlyCaseSensitive["Dagger"] = Convert.ToChar(8225); _decodeOnly["bull"] = Convert.ToChar(8226); _decodeOnly["hellip"] = Convert.ToChar(8230); _decodeOnly["permil"] = Convert.ToChar(8240); - _decodeOnly["prime"] = Convert.ToChar(8242); - _decodeOnly["Prime"] = Convert.ToChar(8243); + _decodeOnlyCaseSensitive["prime"] = Convert.ToChar(8242); + _decodeOnlyCaseSensitive["Prime"] = Convert.ToChar(8243); _decodeOnly["lsaquo"] = Convert.ToChar(8249); _decodeOnly["rsaquo"] = Convert.ToChar(8250); _decodeOnly["oline"] = Convert.ToChar(8254); @@ -370,8 +371,12 @@ private static string DecodeHtmlCharByCode(string str) num = num * (hex ? 16 : 10) + CommonUtils.ToDigit(str[endIdx++], hex); endIdx += (endIdx < str.Length && str[endIdx] == ';') ? 1 : 0; + string repl = string.Empty; + if (num >= 0 && num <= 0x10ffff && !(num >= 0xd800 && num <= 0xdfff)) + repl = Char.ConvertFromUtf32((int)num); + str = str.Remove(idx, endIdx - idx); - str = str.Insert(idx, Convert.ToChar(num).ToString()); + str = str.Insert(idx, repl); idx = str.IndexOf("&#", idx + 1); } @@ -393,7 +398,12 @@ private static string DecodeHtmlCharByName(string str) { var key = str.Substring(idx + 1, endIdx - idx - 1); char c; - if (_decodeOnly.TryGetValue(key, out c)) + if (_decodeOnlyCaseSensitive.TryGetValue(key, out c)) + { + str = str.Remove(idx, endIdx - idx + 1); + str = str.Insert(idx, c.ToString()); + } + else if(_decodeOnly.TryGetValue(key, out c)) { str = str.Remove(idx, endIdx - idx + 1); str = str.Insert(idx, c.ToString()); diff --git a/Source/HtmlRenderer/Core/Utils/RenderUtils.cs b/Source/HtmlRenderer/Core/Utils/RenderUtils.cs index b5bfe4494..2726b5fb2 100644 --- a/Source/HtmlRenderer/Core/Utils/RenderUtils.cs +++ b/Source/HtmlRenderer/Core/Utils/RenderUtils.cs @@ -50,7 +50,10 @@ public static bool ClipGraphicsByOverflow(RGraphics g, CssBox box) var rect = box.ContainingBlock.ClientRectangle; rect.X -= 2; // TODO:a find better way to fix it rect.Width += 2; - rect.Offset(box.HtmlContainer.ScrollOffset); + + if (!box.IsFixed) + rect.Offset(box.HtmlContainer.ScrollOffset); + rect.Intersect(prevClip); g.PushClip(rect); return true; diff --git a/Source/HtmlRenderer/HtmlRenderer.csproj b/Source/HtmlRenderer/HtmlRenderer.csproj index 74549b41d..273dcccf8 100644 --- a/Source/HtmlRenderer/HtmlRenderer.csproj +++ b/Source/HtmlRenderer/HtmlRenderer.csproj @@ -1,129 +1,31 @@ - - - + - Debug - AnyCPU - {FE611685-391F-4E3E-B27E-D3150E51E49B} + netstandard2.0;net8.0 Library - Properties TheArtOfDev.HtmlRenderer - HtmlRenderer - v2.0 - 512 + true + true - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + + + HtmlRenderer.Core + HTML Renderer Core + html render renderer draw core + Cross framework (WinForms/WPF/PDF/Metro/etc.), Multipurpose (UI Controls / Image generation / PDF generation / etc.), 100% managed (C#), High performance HTML Rendering library. + +The Core assembly of HTML Renderer does not bound to any rendering framework (WinForms/WPF/PDF/etc.). +Can be used to create framework specific renderer using adapter extensibility object model. +For existing implementations see: HtmlRenderer.WinForms, HtmlRenderer.WPF and HtmlRenderer.PdfSharp. + Cross framework (WinForms/WPF/PDF/Metro/etc.), Multipurpose (UI Controls / Image generation / PDF generation / etc.), 100% managed (C#), High performance HTML Rendering library. - - - - - - - - Properties\SharedAssemblyInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - \ No newline at end of file diff --git a/Source/SharedAssemblyInfo.cs b/Source/SharedAssemblyInfo.cs deleted file mode 100644 index 175dafbe0..000000000 --- a/Source/SharedAssemblyInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// 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: AssemblyTitle("HTML Renderer")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Open source hosted on CodePlex")] -[assembly: AssemblyProduct("HTML Renderer")] -[assembly: AssemblyCopyright("Copyright © 2008")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. - -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM - -[assembly: Guid("ec8a9e7e-9a9d-43c3-aa97-f6f505b1d3ed")] - -// Version information for an assembly consists of the following four values: - -[assembly: AssemblyVersion("1.5.0.6")] \ No newline at end of file diff --git a/html.png b/html.png new file mode 100644 index 000000000..4e2eb38d5 Binary files /dev/null and b/html.png differ