PDA

View Full Version : Font Studio 4



Nitrogen
16-03-2007, 08:29 PM
(PS. I couldnt reply to the end of the last Font Studio topic, kept saying my session ID is invalid and randomly logging me out...)

Ok, after a LONG while, I've finally done summore on Font Studio...

Here's what it's looking like:

http://www.nitrogen.za.org/gallery/FontStudio2.jpg

Firstly I've managed to override the windows font smoothing effect, so it defaults to nice AA!
And the main difference is that I've implemented the Outline effect.. Looks neat no? :)
I had a bit of fun with this one. At first I tried the StrokePath() API call on the text paths, but this didnt work because it doesnt AA the result. Then I tried a simple average blur on the outline, and that looked very crappy so I ended up using this technique:

Draw the text onto the background, then grow all the edges of the text using the following algorithm:


For each pixel:
ThisPixelValue = Add up and average all neighbors which have a higher value than ThisPixelValue


Then draw original text onto the result.

And it works pretty well, but it does give blurry edges with large Outline Widths. I tried to counteract this a bit by cube-rooting the colour value to give it a bit of a sharper image and that's given the results you see above.
Anyone got a better idea of getting a sharp (but AA'ed) edge?

jdarling
16-03-2007, 08:44 PM
So, how long till we see a download ready to go?

Traveler
16-03-2007, 08:47 PM
This sure is looking better and better with each update!

Nitrogen
16-03-2007, 09:45 PM
So, how long till we see a download ready to go?

Weeeeell, all of a sudden I've got 4-5 projects/assignments/contracts all clamoring for my time, so I cant say any time soon...

I havent even got the alpha channel working yet or the file saving routines. Those are the two major barriers in the way at the moment.

JernejL
17-03-2007, 07:39 AM
You should implement non-grid placement of characters into maximum optimal space usage (more characters - smaller texture), something that angelcode font bitmap generator does:

http://www.angelcode.com/products/bmfont

chronozphere
17-03-2007, 09:14 AM
Looks great... keep it up :thumbup:

Nitrogen
17-03-2007, 09:25 AM
You should implement non-grid placement of characters into maximum optimal space usage (more characters - smaller texture), something that angelcode font bitmap generator does:

Way ahead of you there. It already does that using a 2d binary partitioning tree. And you can choose from which corner of the texture to pack the characters.

Chebmaster
18-03-2007, 09:07 AM
Alas, for download there's stil v.3 that crashes when you press "Characters..." button.
At least, in Wine.

http://host-17-99.imsys.net/_share/_001/fontstudiooops.png

Note: the console has no any output, i.e. Wine doesn't detect any problems or missing WinAPI functions.

[unhappy] Anyway, the win32 programs do not "see" the native Linux fonts like "Nimbus Sans L Condensed". So I have to draw 'em using GIMP and implement the splitter by myself [pulls out a bunch of 20x6000-sized PNGs] :x Damn.

'Seems there's yet a price for ditching Micro$oft completely... :?

paul_nicholls
18-03-2007, 11:16 PM
You should implement non-grid placement of characters into maximum optimal space usage (more characters - smaller texture), something that angelcode font bitmap generator does:

Way ahead of you there. It already does that using a 2d binary partitioning tree. And you can choose from which corner of the texture to pack the characters.

Hi Nitrogen :-)
I don't suppose you could share the 2d binary partitioning tree algorithm for packing the characters?

I would like to be able to pack 2d rectangles into a texture for my own uses :-)

I am making a sprite packing program that will store smaller bitmaps and their 'hotspot' origin into the larger texture, and this feature would be very handy...

cheers,
Paul.

Sly
19-03-2007, 03:24 AM
Do a search on "packing lightmaps". They often use more or less the same techniques to pack many smaller images onto a single larger image.

Example: Packing Lightmaps (http://www.blackpawn.com/texts/lightmaps/default.html)

paul_nicholls
19-03-2007, 03:32 AM
Do a search on "packing lightmaps". They often use more or less the same techniques to pack many smaller images onto a single larger image.

Example: Packing Lightmaps (http://www.blackpawn.com/texts/lightmaps/default.html)

thanks,
I will see if I can make some pascal code to do the same :-)
cheers,
Paul

JernejL
19-03-2007, 12:28 PM
Do a search on "packing lightmaps". They often use more or less the same techniques to pack many smaller images onto a single larger image.

Example: Packing Lightmaps (http://www.blackpawn.com/texts/lightmaps/default.html)

Excellent tutorial, i just made a small pascal demo to do this in my free time, since i suspect i'm going to need it in the future:

http://www.gtatools.com/temp/texpartition.jpg

]http://www.gtatools.com/temp/texture_partitioning.rar[/url]

Legolas
19-03-2007, 01:32 PM
Maybe this (http://www.delphiforfun.org/Programs/tilefit.htm) example could be useful too. It is made by a brilliant 68 years old boy :D

JernejL
19-03-2007, 02:33 PM
Maybe this (http://www.delphiforfun.org/Programs/tilefit.htm) example could be useful too. It is made by a brilliant 68 years old boy :D

That algorythm groups similar width and height objects together, something i'd like to use in my algorythm as well. Also: that algorythm also allows himself to rotate specific tiles, which would be undesirable in a graphics tiling program.

paul_nicholls
19-03-2007, 10:15 PM
Do a search on "packing lightmaps". They often use more or less the same techniques to pack many smaller images onto a single larger image.

Example: Packing Lightmaps (http://www.blackpawn.com/texts/lightmaps/default.html)

Excellent tutorial, i just made a small pascal demo to do this in my free time, since i suspect i'm going to need it in the future:

http://www.gtatools.com/temp/texpartition.jpg

]http://www.gtatools.com/temp/texture_partitioning.rar[/url]

Thanks Delfi! This should save me quite a bit of time working it out myself :)

You are a champion!
cheers,
Paul.

Nitrogen
07-04-2007, 12:22 AM
Well, I'm still busy with it!

This time I've got dropshadows working and finally written the preview code. Now I just have to get the save functionality and we're on the home stretch...

http://www.nitrogen.za.org/gallery/FontStudio3.jpg

Yea, I can share my code if you still need it, I dont think it's any better than what you've already got there.. I did, however, implement a QuickSort which sorts the characters by size first which helps quite a bit when packing them.

JernejL
07-04-2007, 09:45 AM
Yea, I can share my code if you still need it, I dont think it's any better than what you've already got there.. I did, however, implement a QuickSort which sorts the characters by size first which helps quite a bit when packing them.

my code does sorting as well, but i use listview to do custom sort on the data for which i return the surface area of a rectangle to sort by and the listview sorts the items properly.

paul_nicholls
08-04-2007, 03:40 AM
Yea, I can share my code if you still need it, I dont think it's any better than what you've already got there.. I did, however, implement a QuickSort which sorts the characters by size first which helps quite a bit when packing them.

I would be interested in looking at your packing code as well :-)
Thanks!
cheers,
Paul.

paul_nicholls
08-04-2007, 03:43 AM
my code does sorting as well, but i use listview to do custom sort on the data for which i return the surface area of a rectangle to sort by and the listview sorts the items properly.

Hi Delfi :-)
I was trying to alter your code to use a stand-alone class and not a VCL component to make it more portable, but I am having difficulty for some reason...I don't suppose you could alter the code to do this?

cheers,
Paul

Nitrogen
08-04-2007, 09:16 AM
unit Partitions;

interface

Uses Windows, Graphics;

const
NW = 0;
NE = 1;
SE = 2;
SW = 3;


Type TPartition = class
X,Y,X2,Y2,Wid,Hgt,Corner: integer;
Used: boolean;
A,B: TPartition;
Function Insert(Width, Height: integer): TRect;
Procedure Draw(can: TCanvas);
constructor Create(xx,yy,xx2,yy2, Corn: integer);
destructor Destroy;
end;

implementation


{ TPartition }

//Corn is to specify from which corner to pack the rectangles.
//Use NW,NE, SW or SE.
constructor TPartition.Create(xx, yy, xx2, yy2, Corn: integer);
var I: integer;
begin
inherited Create;

X := xx;
Y := Yy;
X2 := Xx2;
Y2 := YY2;
Wid := X2-X;
Hgt := Y2-Y;
Corner := Corn;
A := nil;
B := nil;
Used := false;

end;

destructor TPartition.Destroy;
var I: integer;
begin

if Assigned(A) then A.Free;
if Assigned(B) then B.Free;

inherited Destroy;
end;

//For Debugging purposes.
procedure TPartition.Draw(can: TCanvas);
begin

if Used then
begin
can.Pen.Color := clRed;
can.Rectangle(X,Y,X2,Y2);
if Assigned(A) then A.Draw(can);
if Assigned(B) then B.Draw(can);
end
else
begin
//can.Pen.Color := clGreen;
//can.Rectangle(X,Y,X2,Y2);
end;
end;


//Inserts a rectangle into the package, returns a TRect
//If the rect could not fit, the Rect.Left = -123456.
function TPartition.Insert(Width, Height: integer): TRect;
Var R: TRect;
begin
Result.Left := -123456;
if Used then
begin
if Assigned(A) then
R := A.Insert(Width, HEight);
if (R.Left = -123456) and Assigned(B) then
R := B.Insert(Width, HEight);
result := R;
end
else
begin
if (Width <= Wid) and (Height <= Hgt) then
begin
Used := true;
case Corner of
NW: begin
result.Left := X;
Result.Top := Y;
Result.Right := X+Width;
Result.Bottom := Y+Height;

if (Wid-Width) >= (Hgt-Height) then
begin
A := TPartition.Create(X,(Y+height),(X+Width), Y2, Corner);
B := TPartition.Create((X+Width),Y, X2, Y2, Corner);

end
else
begin
A := TPartition.Create((X+Width),Y,X2, (Y+Height), Corner);
B := TPartition.Create(X,(Y+Height), X2, Y2, Corner);
end;
end;
NE: begin
result.Left := X2-Width;
Result.Top := Y;
Result.Right := X2;
Result.Bottom := Y+Height;

if (Wid-Width) >= (Hgt-Height) then
begin
A := TPartition.Create(X2-Width,(Y+height),X2, Y2, Corner);
B := TPartition.Create(X,Y, X2-Width, Y2, Corner);

end
else
begin
A := TPartition.Create(X,Y,X2-Width, (Y+Height), Corner);
B := TPartition.Create(X,(Y+Height), X2, Y2, Corner);
end;
end;
SW: begin
result.Left := X;
Result.Top := Y2-Height;
Result.Right := X+Width;
Result.Bottom := Y2;

if (Wid-Width) >= (Hgt-Height) then
begin
A := TPartition.Create(X,Y,(X+Width), Y2-Height, Corner);
B := TPartition.Create((X+Width),Y, X2, Y2, Corner);

end
else
begin
A := TPartition.Create((X+Width),Y2-Height,X2, Y2, Corner);
B := TPartition.Create(X,Y, X2, Y2-Height, Corner);
end;
end;
SE: begin
result.Left := X2-Width;
Result.Top := Y2-Height;
Result.Right := X2;
Result.Bottom := Y2;

if (Wid-Width) >= (Hgt-Height) then
begin
A := TPartition.Create(X2-Width,Y,X2, Y2-Height, Corner);
B := TPartition.Create(X,Y, X2-Width, Y2, Corner);

end
else
begin
A := TPartition.Create(X,Y2-Height,X2-Width, Y2, Corner);
B := TPartition.Create(X,Y, X2, Y2-Height, Corner);
end;
end;
end;

end;
end;
end;

end.

JernejL
08-04-2007, 11:03 AM
my code does sorting as well, but i use listview to do custom sort on the data for which i return the surface area of a rectangle to sort by and the listview sorts the items properly.

Hi Delfi :-)
I was trying to alter your code to use a stand-alone class and not a VCL component to make it more portable, but I am having difficulty for some reason...I don't suppose you could alter the code to do this?

cheers,
Paul

Yeah sorry about that, you'll have to store the rectangles in custom structures and do the sorting manually, if you need a quick sorting algorythm, the openal audio library wrapper in my sig has a simple quicksort algorythm implemented.

paul_nicholls
11-04-2007, 01:38 AM
unit Partitions;

interface

Uses Windows, Graphics;

<SNIP>

Thanks for the code! I will give it a go :)
Keep up the great work on your font editor :-)
cheers,
Paul.

paul_nicholls
11-04-2007, 01:39 AM
my code does sorting as well, but i use listview to do custom sort on the data for which i return the surface area of a rectangle to sort by and the listview sorts the items properly.

Hi Delfi :-)
I was trying to alter your code to use a stand-alone class and not a VCL component to make it more portable, but I am having difficulty for some reason...I don't suppose you could alter the code to do this?

cheers,
Paul

Yeah sorry about that, you'll have to store the rectangles in custom structures and do the sorting manually, if you need a quick sorting algorythm, the openal audio library wrapper in my sig has a simple quicksort algorythm implemented.

Thanks for the help :-)
cheers,
Paul.