Recent

Author Topic: Draw Curved Text  (Read 23687 times)

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Draw Curved Text
« Reply #30 on: April 19, 2015, 05:08:05 pm »
that looks nasty. I need to look closer because I don't think a tolerance reduction to 1/1000 should create only 4 points.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Draw Curved Text
« Reply #31 on: April 19, 2015, 06:17:09 pm »
When I add the code below just at the end of BezierTexOut procedure, I have not this issue anymore.

Code: [Select]
   //reset font orientation
    ACanvas.Font.Orientation := 0;  <<<<<<<<  add this line

    //debug only - draw the path from the points ...
    //with flatPts[0] do ACanvas.moveto(X,Y);
    //for i := 1 to ptCnt -1 do with flatPts[i] do ACanvas.lineto(X,Y);

This seems to solve it. Thank you!

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Draw Curved Text
« Reply #32 on: April 20, 2015, 12:44:37 am »
Curiously, this procedure allows to draw a circle too.

Code: [Select]
BezierTextOut(Canvas,
    [Point(200, 50), Point(400, 50), Point(400, 350), Point(200, 350),
    Point(0, 350), Point(0, 50), Point(200, 50)],
    S);

Carver413

  • Full Member
  • ***
  • Posts: 119
Re: Draw Curved Text
« Reply #33 on: April 20, 2015, 04:17:03 am »
There is not reason this routine can't be made to work any line. all that is needed is the abillity to interpolate the line based on character width + a little extra so they don’t collide from being rotated. this would also produce a better fit.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Draw Curved Text
« Reply #34 on: April 20, 2015, 06:54:09 am »
Find attached the project with some benchmark added to it. The following enhancements where made
1) all drawing takes place on to a bitmap no one draws directly to the form canvas any more.
2) changed the agg version removing the font manager creation and management and attaching it directly to the output bitmap to avoid triple buffering.

even with this changes agg version seems to be about 2 times slower than the native one on windows as the screen shot shows.

One more think I observed. If I execute the timing loop for agg multiple times I get wildly different results. What that means I'm unclear at the moment
« Last Edit: April 20, 2015, 06:56:04 am by taazz »
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

finalpatch

  • New Member
  • *
  • Posts: 12
Re: Draw Curved Text
« Reply #35 on: April 20, 2015, 08:41:05 am »
Find attached the project with some benchmark added to it. The following enhancements where made
1) all drawing takes place on to a bitmap no one draws directly to the form canvas any more.
2) changed the agg version removing the font manager creation and management and attaching it directly to the output bitmap to avoid triple buffering.

even with this changes agg version seems to be about 2 times slower than the native one on windows as the screen shot shows.

One more think I observed. If I execute the timing loop for agg multiple times I get wildly different results. What that means I'm unclear at the moment

Hi Taazz,

The AGG version is slower because it does a lot more work.  This is how it works:

1. extract the glyph outlines from the font
2. convert the outlines from curves to line segments
3. cut the line segments to smaller line segments so they can be distorted by a curve
4. use the caller supplied bezier curve to warp the vertices of the glyph
5. rasterize the glyph's polygon into scanlines
6. fill the scanlines with the specified color

This gives more accurate result when the font is large and curve has sharp turns.

The speed variation you observed is probably due to font caching.

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Draw Curved Text
« Reply #36 on: April 20, 2015, 09:14:35 am »
Find attached the project with some benchmark added to it. The following enhancements where made
1) all drawing takes place on to a bitmap no one draws directly to the form canvas any more.
2) changed the agg version removing the font manager creation and management and attaching it directly to the output bitmap to avoid triple buffering.

even with this changes agg version seems to be about 2 times slower than the native one on windows as the screen shot shows.

One more think I observed. If I execute the timing loop for agg multiple times I get wildly different results. What that means I'm unclear at the moment

Hi Taazz,

The AGG version is slower because it does a lot more work.  This is how it works:

1. extract the glyph outlines from the font
2. convert the outlines from curves to line segments
3. cut the line segments to smaller line segments so they can be distorted by a curve
4. use the caller supplied bezier curve to warp the vertices of the glyph
5. rasterize the glyph's polygon into scanlines
6. fill the scanlines with the specified color

This gives more accurate result when the font is large and curve has sharp turns.

The speed variation you observed is probably due to font caching.
I'm guessing that steps 5. 6. are done in the native api as well at some point so lets say they are on both.
As you can see on the measuring procedure isn't the font cached the first time on the agg drawing as well? Or I'm missing something vital? when I say I'm seeing wild differences I mean if I execute the 1.000.000 iteration test on your procedure 3 consecutive times I got the results of 1)436,1215 2)427,8211 3)445,1853 (measurement in seconds (ticks/freq)) while thenative routine gives (1)209,2781 (2) 211,0545 (3) 210,3242 respectively. As you can see the time fluctuation is a bit too much on agg (it should be less as the iterations rise I think). In 10.000 iterations things are pretty unstable I got readings from 1.2 times slower up to 2.5 times slower that is why I jumped in to 1M iteration for my tests.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

finalpatch

  • New Member
  • *
  • Posts: 12
Re: Draw Curved Text
« Reply #37 on: April 20, 2015, 09:57:33 am »
Find attached the project with some benchmark added to it. The following enhancements where made
1) all drawing takes place on to a bitmap no one draws directly to the form canvas any more.
2) changed the agg version removing the font manager creation and management and attaching it directly to the output bitmap to avoid triple buffering.

even with this changes agg version seems to be about 2 times slower than the native one on windows as the screen shot shows.

One more think I observed. If I execute the timing loop for agg multiple times I get wildly different results. What that means I'm unclear at the moment

Hi Taazz,

The AGG version is slower because it does a lot more work.  This is how it works:

1. extract the glyph outlines from the font
2. convert the outlines from curves to line segments
3. cut the line segments to smaller line segments so they can be distorted by a curve
4. use the caller supplied bezier curve to warp the vertices of the glyph
5. rasterize the glyph's polygon into scanlines
6. fill the scanlines with the specified color

This gives more accurate result when the font is large and curve has sharp turns.

The speed variation you observed is probably due to font caching.
I'm guessing that steps 5. 6. are done in the native api as well at some point so lets say they are on both.
As you can see on the measuring procedure isn't the font cached the first time on the agg drawing as well? Or I'm missing something vital? when I say I'm seeing wild differences I mean if I execute the 1.000.000 iteration test on your procedure 3 consecutive times I got the results of 1)436,1215 2)427,8211 3)445,1853 (measurement in seconds (ticks/freq)) while thenative routine gives (1)209,2781 (2) 211,0545 (3) 210,3242 respectively. As you can see the time fluctuation is a bit too much on agg (it should be less as the iterations rise I think). In 10.000 iterations things are pretty unstable I got readings from 1.2 times slower up to 2.5 times slower that is why I jumped in to 1M iteration for my tests.

Hi Taazz,

I just had a quick look at your modifications and the way you measure it looks good to me.  You numbers also look very convincing.   I think a 2x speed penalty is not bad at all considering how much more vertices it has to compute.  Also the Win32 TextOut function is often accelerated by video drivers.

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Draw Curved Text
« Reply #38 on: April 20, 2015, 05:39:58 pm »
Code: [Select]
procedure CircleTextOut(ACanvas :TCanvas; Center :TPoint; Radius :integer; S :string);
var
  Points :array[0..6] of TPoint;
  dx, dy :integer;
begin
  // horizontal
  dx := Center.X - Radius;
  dy := Center.Y;
  Points[0] := Point(dx, dy);
  Points[1] := Point(dx + Round(0.05*dx), dy - 4*Radius div 3);
  Points[2] := Point(dx + 2*Radius - Round(0.05*dx), dy - 4*Radius div 3);
  Points[3] := Point(dx + 2*Radius,  dy);
  Points[4] := Point(dx + 2*Radius - Round(0.05*dx), dy + 4*Radius div 3);
  Points[5] := Point(dx + Round(0.05*dx), dy + 4*Radius div 3);
  Points[6] := Point(dx, dy);
  BezierTextOut(ACanvas, Points, S);
end; 
« Last Edit: April 20, 2015, 06:24:32 pm by typo »

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: Draw Curved Text
« Reply #39 on: April 20, 2015, 11:12:30 pm »
here this should solve all round cases (circle,ellipse, arch) http://www.angusj.com/delphitips/ellipses.php
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Draw Curved Text
« Reply #40 on: April 20, 2015, 11:19:08 pm »
Screenshot attached (CircleTextOut).

typo

  • Hero Member
  • *****
  • Posts: 3051
Re: Draw Curved Text
« Reply #41 on: April 21, 2015, 02:50:52 pm »

typo

  • Hero Member
  • *****
  • Posts: 3051

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Draw Curved Text
« Reply #43 on: April 24, 2015, 12:21:06 am »
download aggpas from their website, the zip archive contains the full source code to all examples.
Don't use the original AggPas from  aggpas.org website, as it is old, not 64-bit enabled and has some bugs. Instead us AggPas included in fpGUI's repository (See <fpgui>/src/corelib/render/software/agg-demos/) or try the AggPas included with Lazarus (which contains fewer bug-fixes than the fpGUI one - but still better than the original aggpas.org release).

Full source code is included. There is also a TAgg2D class you can use, if the AggPas API is not what you want. Attached is a screenshot of curved and flipped text using the trans_curve2_ft demo. The AggPas included with fpGUI is tested against Windows, Linux, FreeBSD, OpenSolaris, ReactOS and RaspberryPi systems.
« Last Edit: November 07, 2016, 11:19:08 am by Graeme »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

Graeme

  • Hero Member
  • *****
  • Posts: 1428
    • Graeme on the web
Re: Draw Curved Text
« Reply #44 on: April 24, 2015, 01:39:42 pm »
Attached is a modification to the original Bench.curvedtext.zip, which was not cross-platform. With the new version you can also, under Windows, switch AggPas to use FreeType or Native GDI rendering. I've also replaced the timing which was Windows specific with EpikTimer [https://github.com/graemeg/epiktimer]to make it cross-platform. The timing results are now posted in seconds and milliseconds in the status bar. Timing results are now consistent between runs.

The results (tested under Win2000):
  • Using AggPas+FreeType the results are near identical. The Native results was only 20ms faster for a 1000 iterations.
  • Using AggPas+Native GDI the results are vastly different. The AggPas rendering was magnitudes faster. 1.124 seconds vs 0.107 seconds.
See attached screenshots for the actual output and results. I've also attached the updated text curve demo project.

note:
When using AggPas+FreeType you get a whole lot of extra font features, and improved font rendering. So even under Windows this would be my preferred option, but that means shipping a freetype.dll (though small) with your application.

The speed test project doesn't show improved font rendering, because it renders the same text over and over on the same place in the canvas (without clearing it between text output), so the anti-aliasing starts to look jaggy.

The 32-bit freetype.dll can be downloaded from this URL
[https://github.com/graemeg/fpGUI/blob/master/extras/freetype_windows/freetype.zip] 300KB size.
« Last Edit: April 24, 2015, 02:24:48 pm by Graeme Geldenhuys »
--
fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal
http://fpgui.sourceforge.net/

 

TinyPortal © 2005-2018