Skip to content

Commit

Permalink
Merge pull request #40 from SixLabors/text-bounding-boxes
Browse files Browse the repository at this point in the history
Refactor text measure to measure actual bounding box
  • Loading branch information
tocsoft authored Jul 16, 2017
2 parents 527ae44 + f1b5885 commit e8ebdcb
Show file tree
Hide file tree
Showing 115 changed files with 655 additions and 648 deletions.
11 changes: 6 additions & 5 deletions SixLabors.Fonts.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.9
VisualStudioVersion = 15.0.26430.15
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{C317F1B1-D75E-4C6D-83EB-80367343E0D7}"
ProjectSection(SolutionItems) = preProject
Expand All @@ -15,17 +15,18 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{9E574A07-F879-4811-9C41-5CBDC6BAFDB7}"
ProjectSection(SolutionItems) = preProject
src\Shared\AssemblyInfo.Common.cs = src\Shared\AssemblyInfo.Common.cs
stylecop.json = stylecop.json
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SixLabors.Fonts", "src\SixLabors.Fonts\SixLabors.Fonts.csproj", "{09E744EC-4852-4FC7-BE78-C1B399F17967}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SixLabors.Fonts", "src\SixLabors.Fonts\SixLabors.Fonts.csproj", "{09E744EC-4852-4FC7-BE78-C1B399F17967}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SixLabors.Fonts.Tests", "tests\SixLabors.Fonts.Tests\SixLabors.Fonts.Tests.csproj", "{F836E8E6-B4D9-4208-8346-140C74678B91}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SixLabors.Fonts.Tests", "tests\SixLabors.Fonts.Tests\SixLabors.Fonts.Tests.csproj", "{F836E8E6-B4D9-4208-8346-140C74678B91}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{71A3911C-D6B9-4EBE-9691-2FE28BDF462E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DrawWithImageSharp", "samples\DrawWithImageSharp\DrawWithImageSharp.csproj", "{999EDFB3-9FE4-4E09-B669-CB02E597EC20}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DrawWithImageSharp", "samples\DrawWithImageSharp\DrawWithImageSharp.csproj", "{999EDFB3-9FE4-4E09-B669-CB02E597EC20}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ListFonts", "samples\ListFonts\ListFonts.csproj", "{6DF4C474-1FDF-4DE0-9CB2-9674D2CCE1BA}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ListFonts", "samples\ListFonts\ListFonts.csproj", "{6DF4C474-1FDF-4DE0-9CB2-9674D2CCE1BA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down
28 changes: 28 additions & 0 deletions samples/DrawWithImageSharp/BoundingBoxes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using ImageSharp;
using SixLabors.Fonts;
using SixLabors.Shapes.Temp;

namespace DrawWithImageSharp
{
public static class BoundingBoxes
{
public static void Generate(string text, Font font)
{
using (var img = new Image<Rgba32>(1000, 1000))
{
img.Fill(Rgba32.White);

var box = TextMeasurer.MeasureBounds(text, new RendererOptions(font));
var data = TextBuilder.GenerateGlyphsWithBox(text, new RendererOptions(font));

var f = Rgba32.Fuchsia;
f.A = 128;
img.Fill(Rgba32.Black, data.paths);
img.Draw(f, 1, data.boxes);
img.Draw(Rgba32.Lime, 1, new SixLabors.Shapes.RectangularePolygon(box));

img.Save("Output/Boxed.png");
}
}
}
}
5 changes: 3 additions & 2 deletions samples/DrawWithImageSharp/DrawWithImageSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="ImageSharp" Version="1.0.0-alpha9-00139" />
<PackageReference Include="ImageSharp.Drawing" Version="1.0.0-alpha9-00134" />
<PackageReference Include="ImageSharp" Version="1.0.0-alpha9-00152" />
<PackageReference Include="ImageSharp.Drawing" Version="1.0.0-alpha9-00147" />
<PackageReference Include="System.ValueTuple" Version="4.4.0-preview2-25405-01" />
</ItemGroup>

</Project>
10 changes: 7 additions & 3 deletions samples/DrawWithImageSharp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using ImageSharp;
using System;
using System.IO;

namespace SixLabors.Fonts.DrawWithImageSharp
Expand Down Expand Up @@ -57,7 +56,11 @@ public static void Main(string[] args)
RenderText(new Font(SystemFonts.Find("Arial"), 20f, FontStyle.Regular), "á é í ó ú ç ã õ", 200, 50);
RenderText(new Font(SystemFonts.Find("Arial"), 10f, FontStyle.Regular), "PGEP0JK867", 200, 50);

TextAlignment.Generate(new Font(font2, 50));
RenderText(new RendererOptions(SystemFonts.CreateFont("consolas", 72)) { TabWidth = 4 }, "xxxxxxxxxxxxxxxx\n\txxxx\txxxx\n\t\txxxxxxxx\n\t\t\txxxx");

BoundingBoxes.Generate("a b c y q G H T", SystemFonts.CreateFont("arial", 40f));

TextAlignment.Generate(SystemFonts.CreateFont("arial", 50f));

StringBuilder sb = new StringBuilder();
for (char c = 'a'; c <= 'z'; c++)
Expand Down Expand Up @@ -101,6 +104,7 @@ public static void RenderText(Font font, string text, int width, int height)
}
}
}

public static void RenderText(RendererOptions font, string text)
{
GlyphBuilder builder = new GlyphBuilder();
Expand Down Expand Up @@ -149,7 +153,7 @@ public static void SaveImage(this IEnumerable<IPath> shapes, params string[] pat
.Translate(new Vector2(10)); // move in from top left

StringBuilder sb = new StringBuilder();
System.Collections.Immutable.ImmutableArray<ISimplePath> converted = shape.Flatten();
var converted = shape.Flatten();
converted.Aggregate(sb, (s, p) =>
{
foreach (Vector2 point in p.Points)
Expand Down
22 changes: 11 additions & 11 deletions samples/DrawWithImageSharp/TextAlignment.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
using ImageSharp;
using ImageSharp.Drawing;
using SixLabors.Fonts;
using SixLabors.Fonts.DrawWithImageSharp;
using SixLabors.Shapes.Temp;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;

namespace DrawWithImageSharp
{
Expand Down Expand Up @@ -64,11 +60,11 @@ public static void Draw(Image<Rgba32> img, Font font, VerticalAlignment vert, Ho
break;
}

GlyphBuilder glyphBuilder = new GlyphBuilder(location);
GlyphBuilder glyphBuilder = new GlyphBuilder();

TextRenderer renderer = new TextRenderer(glyphBuilder);

RendererOptions style = new RendererOptions(font, 72)
RendererOptions style = new RendererOptions(font, 72, location)
{
ApplyKerning = true,
TabWidth = 4,
Expand All @@ -77,14 +73,18 @@ public static void Draw(Image<Rgba32> img, Font font, VerticalAlignment vert, Ho
VerticalAlignment = vert
};

string text = $"{horiz}\n{vert}";
string text = $"{horiz} x y z\n{vert} x y z";
renderer.RenderText(text, style);

System.Collections.Generic.IEnumerable<SixLabors.Shapes.IPath> shapesToDraw = glyphBuilder.Paths;
foreach (SixLabors.Shapes.IPath s in shapesToDraw)
{
img.Fill(Rgba32.Black, s);
}
img.Fill(Rgba32.Black, glyphBuilder.Paths);

var f = Rgba32.Fuchsia;
f.A = 128;
img.Fill(Rgba32.Black, glyphBuilder.Paths);
img.Draw(f, 1, glyphBuilder.Boxes);

img.Draw(Rgba32.Lime, 1, glyphBuilder.TextBox);
}
}
}
18 changes: 15 additions & 3 deletions samples/DrawWithImageSharp/TextBuilder/BaseGlyphBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Numerics;

using SixLabors.Fonts;
using SixLabors.Shapes;
using SixLabors.Primitives;
using System.Linq;

namespace SixLabors.Shapes.Temp
{
Expand All @@ -14,6 +13,7 @@ namespace SixLabors.Shapes.Temp
internal class BaseGlyphBuilder : IGlyphRenderer
{
protected readonly PathBuilder builder = new PathBuilder();
private readonly List<RectangleF> glyphBounds = new List<RectangleF>();
private readonly List<IPath> paths = new List<IPath>();
private Vector2 currentPoint = default(Vector2);

Expand All @@ -31,12 +31,23 @@ public BaseGlyphBuilder()
/// </summary>
public IPathCollection Paths => new PathCollection(this.paths);

/// <summary>
/// Gets the paths that have been rendered by this.
/// </summary>
public IPathCollection Boxes => new PathCollection(this.glyphBounds.Select(x => new SixLabors.Shapes.RectangularePolygon(x)));

/// <summary>
/// Gets the paths that have been rendered by this.
/// </summary>
public IPath TextBox { get; private set; }

void IGlyphRenderer.EndText()
{
}

void IGlyphRenderer.BeginText(RectangleF rect)
{
this.TextBox = new SixLabors.Shapes.RectangularePolygon(rect);
BeginText(rect);
}

Expand All @@ -52,6 +63,7 @@ protected virtual void BeginText(RectangleF rect)
bool IGlyphRenderer.BeginGlyph(RectangleF rect, int cachKey)
{
this.builder.Clear();
this.glyphBounds.Add(rect);
return BeginGlyph(rect, cachKey);
}

Expand Down
7 changes: 1 addition & 6 deletions samples/DrawWithImageSharp/TextBuilder/GlyphBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.Numerics;

using SixLabors.Fonts;
using SixLabors.Shapes;
using System.Numerics;

namespace SixLabors.Shapes.Temp
{
Expand Down
8 changes: 2 additions & 6 deletions samples/DrawWithImageSharp/TextBuilder/PathGlyphBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Numerics;

using SixLabors.Fonts;
using SixLabors.Shapes;
using SixLabors.Primitives;

namespace SixLabors.Shapes.Temp
Expand Down Expand Up @@ -39,11 +35,11 @@ protected override void BeginGlyph(RectangleF rect)
{
var point = this.path.PointAlongPath(rect.X);

var targetPoint = point.Point + new Vector2(0, rect.Y - this.offsetY);
var targetPoint = point.Point + new PointF(0, rect.Y - this.offsetY);

// due to how matrix combining works you have to combine thins in the revers order of operation
// this one rotates the glype then moves it.
var matrix = Matrix3x2.CreateTranslation(targetPoint - (Vector2)rect.Location) * Matrix3x2.CreateRotation(point.Angle - Pi, point.Point);
var matrix = Matrix3x2.CreateTranslation(targetPoint - rect.Location) * Matrix3x2.CreateRotation(point.Angle - Pi, point.Point);
this.builder.SetTransform(matrix);
}
}
Expand Down
32 changes: 25 additions & 7 deletions samples/DrawWithImageSharp/TextBuilder/TextBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
using SixLabors.Fonts;
using SixLabors.Primitives;
using SixLabors.Shapes.Temp;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Text;

namespace SixLabors.Shapes.Temp
{
Expand All @@ -20,15 +15,27 @@ public static class TextBuilder
/// <param name="location">The location</param>
/// <param name="style">The style and settings to use while rendering the glyphs</param>
/// <returns></returns>
public static IPathCollection GenerateGlyphs(string text, PointF location, RendererOptions style)
public static (IPathCollection paths, IPathCollection boxes, IPath textBox) GenerateGlyphsWithBox(string text, PointF location, RendererOptions style)
{
var glyphBuilder = new GlyphBuilder(location);

TextRenderer renderer = new TextRenderer(glyphBuilder);

renderer.RenderText(text, style);

return glyphBuilder.Paths;
return (glyphBuilder.Paths, glyphBuilder.Boxes, glyphBuilder.TextBox);
}

/// <summary>
/// Generates the shapes corresponding the glyphs described by the font and with the setting ing withing the FontSpan
/// </summary>
/// <param name="text">The text to generate glyphs for</param>
/// <param name="location">The location</param>
/// <param name="style">The style and settings to use while rendering the glyphs</param>
/// <returns></returns>
public static IPathCollection GenerateGlyphs(string text, PointF location, RendererOptions style)
{
return GenerateGlyphsWithBox(text, location, style).paths;
}

/// <summary>
Expand All @@ -42,6 +49,17 @@ public static IPathCollection GenerateGlyphs(string text, RendererOptions style)
return GenerateGlyphs(text, PointF.Empty, style);
}

/// <summary>
/// Generates the shapes corresponding the glyphs described by the font and with the setting ing withing the FontSpan
/// </summary>
/// <param name="text">The text to generate glyphs for</param>
/// <param name="style">The style and settings to use while rendering the glyphs</param>
/// <returns></returns>
public static (IPathCollection paths, IPathCollection boxes, IPath textBox) GenerateGlyphsWithBox(string text, RendererOptions style)
{
return GenerateGlyphsWithBox(text, PointF.Empty, style);
}

/// <summary>
/// Generates the shapes corresponding the glyphs described by the font and with the setting in within the FontSpan along the described path.
/// </summary>
Expand Down
9 changes: 4 additions & 5 deletions src/Shared/AssemblyInfo.Common.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// <copyright file="AssemblyInfo.Common.cs" company="Scott Williams">
// Copyright (c) Scott Williams and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>

using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
Expand All @@ -11,9 +10,9 @@
// associated with an assembly.
[assembly: AssemblyDescription("A cross-platform library for loading and laying out for processing and measuring; written in C#")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Scott Williams")]
[assembly: AssemblyCompany("Six Labors")]
[assembly: AssemblyProduct("SixLabors.Fonts")]
[assembly: AssemblyCopyright("Copyright (c) Scott Williams and contributors.")]
[assembly: AssemblyCopyright("Copyright (c) Six Labors and contributors.")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
Expand Down
8 changes: 4 additions & 4 deletions src/SixLabors.Fonts/BigEndianBitConverter.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.

using SixLabors.Fonts.Tables;
using System;
using System.Runtime.InteropServices;

namespace SixLabors.Fonts
{
Expand Down
Loading

0 comments on commit e8ebdcb

Please sign in to comment.