Skip to content

Commit 5eb3292

Browse files
author
ArthurHub
committed
Merge branch 'master'
2 parents ce31cb5 + eb8ae7a commit 5eb3292

12 files changed

Lines changed: 134 additions & 87 deletions

File tree

Build/HtmlRenderer.WinForms.nuspec

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,23 +28,7 @@ Features and Benefits
2828
* Extendable and configurable.
2929
* Powerful Demo application to explore and learn the library.</description>
3030
<summary>The rich formatting power of HTML in your .NET applications using simple controls or static rendering code with 100% managed C# code.</summary>
31-
<releaseNotes>* Add GDI+ text rendering support
32-
* Add GDI+ static rendering methods in HtmlRender
33-
* Add RenderToImage on existing image to act as background
34-
* Add support for synchronous image loading, used by HtmlRender.
35-
* Add SelectedText, SelectedHtml to get selected text/html.
36-
* Improve HtmlRender documentation
37-
* Handle relative URLs in downloaded stylesheet.
38-
* Fix html attributes case sensitivity
39-
* Fix element height not respected
40-
* Fix index out of range exception in table layout (thx Kublia)
41-
* Fix error with empty lines and RTL
42-
* Fix floating point values handling
43-
* Fix mm and cm units factor
44-
* Fix table width not respected and incorrect unit handling
45-
* Fix table columns width incorrect unit handling
46-
* Handle when all table cells width is provided but smaller than set table width
47-
</releaseNotes>
31+
<releaseNotes>See http://htmlrenderer.codeplex.com/releases.</releaseNotes>
4832
<tags>html, renderer, control</tags>
4933
<frameworkAssemblies>
5034
<frameworkAssembly assemblyName="System.Windows.Forms" targetFramework="" />
@@ -60,5 +44,6 @@ Features and Benefits
6044
<file src="Release\Bins\net40\HtmlRenderer.pdb" target="lib\net40-client\HtmlRenderer.pdb" />
6145
<file src="Release\Bins\net45\HtmlRenderer.dll" target="lib\net45\HtmlRenderer.dll" />
6246
<file src="Release\Bins\net45\HtmlRenderer.pdb" target="lib\net45\HtmlRenderer.pdb" />
47+
<file src="readme.txt" target="" />
6348
</files>
6449
</package>

Build/ILMerge.exe

671 KB
Binary file not shown.

Build/build.xml

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<!--Execute all steps of the build-->
2222
<Target Name="Run">
2323

24+
2425
<Message Importance="high" Text="====================== Clean build output..."/>
2526
<RemoveDir Directories="$(OutputRoot)" ContinueOnError="true"/>
2627
<RemoveDir Directories="$(OutputRoot)" ContinueOnError="true"/>
@@ -29,17 +30,17 @@
2930

3031
<Message Importance="high" Text="====================== Build demo..."/>
3132
<CallTarget Targets="BuildDemo"/>
32-
33+
3334
<Message Importance="high" Text="====================== Build libraries..."/>
3435
<CallTarget Targets="BuildLibrary"/>
35-
36+
3637
<Message Importance="high" Text="====================== Get current version..."/>
3738
<GetAssemblyIdentity AssemblyFiles="$(OutputBinRoot)\NET20\HtmlRenderer.dll">
3839
<Output TaskParameter="Assemblies" ItemName="AsmInfo" />
3940
</GetAssemblyIdentity>
40-
41+
4142
<Message Importance="high" Text="====================== Build demo..."/>
42-
<CallTarget Targets="BuildDemo"/>
43+
<CallTarget Targets="BuildDemo" />
4344

4445
<Message Importance="high" Text="====================== Copy source..."/>
4546
<CallTarget Targets="CopySource"/>
@@ -56,9 +57,7 @@
5657
<Error Condition="!Exists('$(OutputBinRoot)\NET40\HtmlRenderer.dll')" Text="Validation failed (.NET 4.0)!" />
5758
<Error Condition="!Exists('$(OutputBinRoot)\NET45\HtmlRenderer.dll')" Text="Validation failed (.NET 4.5)!" />
5859
<Error Condition="!Exists('$(OutputSourceRoot)\HtmlRenderer.sln')" Text="Validation failed (Source)!" />
59-
<Error Condition="!Exists('$(OutputRoot)\HtmlRendererDemo.exe')" Text="Validation failed (Demo)!" />
60-
<Error Condition="!Exists('$(OutputRoot)\HtmlRenderer.dll')" Text="Validation failed (Demo)!" />
61-
<Error Condition="!Exists('$(OutputRoot)\HtmlRenderer.dll')" Text="Validation failed (Demo)!" />
60+
<Error Condition="!Exists('$(OutputRoot)\HtmlRendererDemo.WinForms.exe')" Text="Validation failed (Demo)!" />
6261
<Error Condition="!Exists('$(OutputRoot)\HtmlRenderer %(AsmInfo.Version).zip')" Text="Validation failed (zip)!" />
6362

6463
<Message Importance="high" Text="====================== SUCCESS!"/>
@@ -90,13 +89,21 @@
9089
</CreateProperty>
9190
</Target>
9291

93-
<!--Build the demo application and delete the pdbs-->
92+
<!--Build the demo application, merge to single exe and delete the rest of the files-->
9493
<Target Name="BuildDemo">
9594
<MSBuild Properties="$(BuildProperties);$(DemoBuildOutputPath);$(BuildWarn)" UseResultsCache="true" Targets="Rebuild" Projects="$(DemoRoot)\HtmlRenderer.Demo.csproj" />
95+
96+
<GetAssemblyIdentity AssemblyFiles="$(OutputRoot)\HtmlRenderer.dll">
97+
<Output TaskParameter="Assemblies" ItemName="AsmInfo" />
98+
</GetAssemblyIdentity>
99+
100+
<Exec Command="ILMerge.exe $(OutputRoot)\HtmlRendererDemo.exe $(OutputRoot)\HtmlRenderer.dll /out:$(OutputRoot)\HtmlRendererDemo.WinForms.exe /ver:%(AsmInfo.Version)" />
101+
96102
<ItemGroup>
97-
<files Include="$(OutputRoot)\*.*" Exclude="$(OutputRoot)\*.exe;$(OutputRoot)\*.dll;"/>
103+
<files Include="$(OutputRoot)\*.*" Exclude="$(OutputRoot)\HtmlRendererDemo.WinForms.exe"/>
98104
</ItemGroup>
99105
<Delete Files="@(files)"/>
106+
100107
</Target>
101108

102109
<!--Copy all the source and remove the bin and obj folders-->
@@ -115,6 +122,7 @@
115122

116123
<!--Create NuGet package-->
117124
<Target Name="CreatePackage">
125+
<Copy SourceFiles="readme.txt" DestinationFolder="$(OutputRoot)"/>
118126
<Exec Command="nuget.exe pack HtmlRenderer.WinForms.nuspec -Version $(Version) -OutputDirectory $(OutputRoot)" />
119127
</Target>
120128

Source/Demo/WinForms/DemoForm.Designer.cs

Lines changed: 0 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Source/Demo/WinForms/DemoForm.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -510,9 +510,10 @@ private void OnRunTestButtonClick(object sender, EventArgs e)
510510
Application.DoEvents();
511511

512512
GC.Collect();
513+
#if NET_40
513514
AppDomain.MonitoringIsEnabled = true;
514515
var startMemory = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
515-
516+
#endif
516517
var sw = Stopwatch.StartNew();
517518

518519
const int iterations = 20;
@@ -527,10 +528,12 @@ private void OnRunTestButtonClick(object sender, EventArgs e)
527528

528529
sw.Stop();
529530

530-
531-
var endMemory = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
532-
var totalMem = (endMemory - startMemory)/1024f;
533-
531+
long endMemory = 0;
532+
float totalMem = 0;
533+
#if NET_40
534+
endMemory = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
535+
totalMem = (endMemory - startMemory)/1024f;
536+
#endif
534537
float htmlSize = 0;
535538
foreach (var sample in _perfTestSamples)
536539
htmlSize += sample.Length*2;

Source/Demo/WinForms/PerfForm.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,10 @@ private void OnRunTestButtonClick(object sender, EventArgs e)
208208
var html = _samples[(string)_samplesTreeView.SelectedNode.Tag];
209209

210210
GC.Collect();
211+
#if NET_40
211212
AppDomain.MonitoringIsEnabled = true;
212213
var startMemory = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
213-
214+
#endif
214215
var sw = Stopwatch.StartNew();
215216

216217
for (int i = 0; i < _iterations.Value; i++)
@@ -221,10 +222,13 @@ private void OnRunTestButtonClick(object sender, EventArgs e)
221222

222223
sw.Stop();
223224

224-
225-
var endMemory = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
226-
var totalMem = (endMemory - startMemory) / 1024f;
227-
float htmlSize = html.Length*2/1024f;
225+
long endMemory = 0;
226+
float totalMem = 0;
227+
#if NET_40
228+
endMemory = AppDomain.CurrentDomain.MonitoringTotalAllocatedMemorySize;
229+
totalMem = (endMemory - startMemory) / 1024f;
230+
#endif
231+
float htmlSize = html.Length * 2 / 1024f;
228232

229233
var msg = string.Format("1 HTML ({0:N0} KB)\r\n{1} Iterations", htmlSize, _iterations.Value);
230234
msg += "\r\n\r\n";

Source/HtmlRenderer/Core/HtmlContainerBase.cs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public abstract class HtmlContainerBase : IDisposable
136136
/// Gets or sets a value indicating if image loading only when visible should be avoided (default - false).<br/>
137137
/// </summary>
138138
private bool _avoidImagesLateLoading;
139-
139+
140140
/// <summary>
141141
/// the top-left most location of the rendered html
142142
/// </summary>
@@ -368,7 +368,7 @@ internal Color SelectionBackColor
368368
/// <param name="baseCssData">optional: the stylesheet to init with, init default if not given</param>
369369
public void SetHtml(string htmlSource, CssData baseCssData = null)
370370
{
371-
371+
372372
if( _root != null )
373373
{
374374
_root.Dispose();
@@ -399,7 +399,7 @@ public string GetHtml(HtmlGenerationStyle styleGen = HtmlGenerationStyle.Inline)
399399
{
400400
return DomUtils.GenerateHtml(_root, styleGen);
401401
}
402-
402+
403403
/// <summary>
404404
/// Get attribute value of element at the given x,y location by given key.<br/>
405405
/// If more than one element exist with the attribute at the location the inner most is returned.
@@ -408,12 +408,12 @@ public string GetHtml(HtmlGenerationStyle styleGen = HtmlGenerationStyle.Inline)
408408
/// <param name="attribute">the attribute key to get value by</param>
409409
/// <returns>found attribute value or null if not found</returns>
410410
public string GetAttributeAt(Point location, string attribute)
411-
{
411+
{
412412
ArgChecker.AssertArgNotNullOrEmpty(attribute, "attribute");
413413

414-
var cssBox = DomUtils.GetCssBox(_root, OffsetByScroll(location));
415-
return cssBox != null ? DomUtils.GetAttribute(cssBox, attribute) : null;
416-
}
414+
var cssBox = DomUtils.GetCssBox(_root, OffsetByScroll(location));
415+
return cssBox != null ? DomUtils.GetAttribute(cssBox, attribute) : null;
416+
}
417417

418418
/// <summary>
419419
/// Get css link href at the given x,y location.
@@ -426,6 +426,21 @@ public string GetLinkAt(Point location)
426426
return link != null ? link.HrefLink : null;
427427
}
428428

429+
/// <summary>
430+
/// Get the rectangle of html element as calculated by html layout.<br/>
431+
/// Element if found by id (id attribute on the html element).<br/>
432+
/// Note: to get the screen rectangle you need to adjust by the hosting control.<br/>
433+
/// </summary>
434+
/// <param name="elementId">the id of the element to get its rectangle</param>
435+
/// <returns>the rectangle of the element or null if not found</returns>
436+
public RectangleF? GetElementRectangle(string elementId)
437+
{
438+
ArgChecker.AssertArgNotNullOrEmpty(elementId, "elementId");
439+
440+
var box = DomUtils.GetBoxById(_root, elementId.ToLower());
441+
return box != null ? CommonUtils.GetFirstValueOrDefault(box.Rectangles, box.Bounds) : (RectangleF?)null;
442+
}
443+
429444
/// <summary>
430445
/// Measures the bounds of box and children, recursively.
431446
/// </summary>
@@ -745,22 +760,19 @@ internal void HandleLinkClicked(IControl parent, Point location, CssBox link)
745760
throw new HtmlLinkClickedException("Error in link clicked intercept", ex);
746761
}
747762
if( args.Handled )
748-
{
749763
return;
750764
}
751-
}
752765

753766
if( !string.IsNullOrEmpty(link.HrefLink) )
754767
{
755-
if( link.HrefLink.StartsWith("#") )
768+
if( link.HrefLink.StartsWith("#") && link.HrefLink.Length > 1 )
756769
{
757770
if( ScrollChange != null )
758771
{
759-
var box = DomUtils.GetBoxById(_root, link.HrefLink.Substring(1));
760-
if( box != null )
772+
var rect = GetElementRectangle(link.HrefLink.Substring(1));
773+
if( rect.HasValue )
761774
{
762-
var rect = CommonUtils.GetFirstValueOrDefault(box.Rectangles, box.Bounds);
763-
ScrollChange(this, new HtmlScrollEventArgs(Point.Round(rect.Location)));
775+
ScrollChange(this, new HtmlScrollEventArgs(Point.Round(rect.Value.Location)));
764776
HandleMouseMove(parent, location);
765777
}
766778
}

Source/HtmlRenderer/Core/Utils/CommonUtils.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@
2020
using HtmlRenderer.Entities;
2121

2222
namespace HtmlRenderer.Utils
23-
{
24-
internal delegate void ActionInt<in T>(T obj);
25-
26-
internal delegate void ActionInt<in T1, in T2>(T1 arg1, T2 arg2);
27-
23+
{
24+
internal delegate void ActionInt<in T>(T obj);
25+
26+
internal delegate void ActionInt<in T1, in T2>(T1 arg1, T2 arg2);
27+
2828
internal delegate void ActionInt<in T1, in T2, in T3>(T1 arg1, T2 arg2, T3 arg3);
2929

3030
/// <summary>

Source/HtmlRenderer/Core/Utils/DomUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public static CssBox GetCssBox(CssBox box, Point location, bool visible = true)
194194
{
195195
foreach(var childBox in box.Boxes)
196196
{
197-
if( childBox.Bounds.Contains(location) )
197+
if( CommonUtils.GetFirstValueOrDefault(box.Rectangles, box.Bounds).Contains(location) )
198198
{
199199
return GetCssBox(childBox, location) ?? childBox;
200200
}

Source/HtmlRenderer/WinForm/HtmlPanel.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Windows.Forms;
1717
using HtmlRenderer.Entities;
1818
using HtmlRenderer.Parse;
19+
using HtmlRenderer.Utils;
1920

2021
namespace HtmlRenderer
2122
{
@@ -256,6 +257,26 @@ public string GetHtml()
256257
return _htmlContainer != null ? _htmlContainer.GetHtml() : null;
257258
}
258259

260+
/// <summary>
261+
/// Adjust the scrollbar of the panel on html element by the given id.<br/>
262+
/// The top of the html element rectangle will be at the top of the panel, if there
263+
/// is not enough height to scroll to the top the scroll will be at maximum.<br/>
264+
/// </summary>
265+
/// <param name="elementId">the id of the element to scroll to</param>
266+
public void ScrollToElement(string elementId)
267+
{
268+
ArgChecker.AssertArgNotNullOrEmpty(elementId, "elementId");
269+
270+
if( _htmlContainer != null )
271+
{
272+
var rect = _htmlContainer.GetElementRectangle(elementId);
273+
if (rect.HasValue)
274+
{
275+
UpdateScroll(Point.Round(rect.Value.Location));
276+
_htmlContainer.HandleMouseMove(this, new MouseEventArgs(MouseButtons, 0, MousePosition.X, MousePosition.Y, 0));
277+
}
278+
}
279+
}
259280

260281
#region Private methods
261282

@@ -481,7 +502,16 @@ private void OnRefresh(object sender, HtmlRefreshEventArgs e)
481502
/// </summary>
482503
private void OnScrollChange(object sender, HtmlScrollEventArgs e)
483504
{
484-
AutoScrollPosition = e.Location;
505+
UpdateScroll(e.Location);
506+
}
507+
508+
/// <summary>
509+
/// Adjust the scrolling of the panel to the requested location.
510+
/// </summary>
511+
/// <param name="location">the location to adjust the scroll to</param>
512+
private void UpdateScroll(Point location)
513+
{
514+
AutoScrollPosition = location;
485515
_htmlContainer.ScrollOffset = AutoScrollPosition;
486516
}
487517

0 commit comments

Comments
 (0)