Recent

Author Topic: [LazFreeType] Resource Font  (Read 19495 times)

Vladimyr

  • New member
  • *
  • Posts: 7
[LazFreeType] Resource Font
« on: January 07, 2013, 05:37:47 pm »
hi, using FreeType in my app I'd like to load custom font from resource.
Failed to substitute resource stream instead of the file stream in FreeType
because of lots of file related code, I wrote my own function to load font
face from resource. 

Could anybody help me to insert loaded face into FreeType instance?
I have not enough experience to do it myself, but don't mind to share
my work with community.

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: [LazFreeType] Resource Font
« Reply #1 on: January 30, 2013, 10:06:32 pm »
Hello, can you explain the modifications you propose to apply ?
Conscience is the debugger of the mind

Vladimyr

  • New member
  • *
  • Posts: 7
Re: [LazFreeType] Resource Font
« Reply #2 on: January 31, 2013, 03:41:08 pm »
hello circular,

i'd like to add
Code: [Select]
LoadFromResource (const ResourceName: String)method into TFreeTypeFont type.

actually, this one is 90% ready (see attach on the 1st post),
still can't insert loaded object into existing TFreeTypeFont
data scructure.

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: [LazFreeType] Resource Font
« Reply #3 on: January 31, 2013, 08:39:39 pm »
I think I get it, well, the code you propose comes from deeper FreeType units, so I suppose it should not be put directly TFreeTypeFont type.

More over, I suppose you are writing twice the loading code, which must be in some deeper FreeType units, right?
Conscience is the debugger of the mind

Vladimyr

  • New member
  • *
  • Posts: 7
Re: [LazFreeType] Resource Font
« Reply #4 on: February 01, 2013, 03:38:48 pm »
you are correct, my code is similar to the existing code,
but that one is based onto file operations too tight, and
also separated into many small hierarchical functions.

it seems 'canonical' approach will be very time-consuming:
since i can't override functions enclosed into very depth,
i need to rewrite entire module 'from scratch'!
(i.e. EazyLazFreeType, LazFreeType and TTCache)

bypass the existing code is a 'tricky' way, but probably
is the shortest path to the goal.  :-[

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: [LazFreeType] Resource Font
« Reply #5 on: February 01, 2013, 03:44:25 pm »
You may be right. Can you tell me where you've taken the parts that you've put together in your function ? From which files ?
Conscience is the debugger of the mind

Vladimyr

  • New member
  • *
  • Posts: 7
Re: [LazFreeType] Resource Font
« Reply #6 on: February 01, 2013, 06:27:17 pm »
well, that's everything i learned.
when an instance of TFreeTypeFont is initializing,
the following procedures are being called
(I put module names in curved brackets):

_SetName {EazyLazFreeType.pas}
  \________UpdateFace {EazyLazFreeType.pas}
     \______TT_Open_Face {LazFreeType.pas}
        \____TT_Open_Stream {TTFile.pas}
           \__Stream_New {TTFile.pas}
            |_Stream_Activate (here are the file access operations!) {TTFile.pas}
           /__Cache_New {TTCache.pas}
           \__cache.clazz^.init {TTCache.pas}
            \_Face_Create (called indirectly, via "cache.clazz^.init") {TTObjs.pas}
             \_Cache_Create {TTCache.pas}
             |_Load_TrueType_Header * {TTLoad.pas}
             |_Load_TrueType_MaxProfile * {TTLoad.pas}
             |_Load_TrueType_Locations * {TTLoad.pas}
             |_Load_TrueType_CMap * {TTLoad.pas}
             |_Load_TrueType_CVT * {TTLoad.pas}
             |_Load_TrueType_Metrics_Header * {TTLoad.pas}
             |_Load_TrueType_Programs * {TTLoad.pas}
             |_Load_TrueType_Gasp * {TTLoad.pas}
             |_Load_TrueType_Names * {TTLoad.pas}
             |_Load_TrueType_OS2 * {TTLoad.pas}
             |_Load_TrueType_Hdmx * {TTLoad.pas}
             |_Load_TrueType_Postscript * {TTLoad}
             |_Load_TrueType_Metrics_Header * {TTLoad.pas}

* - these are the procedures I joined into LoadFromRecource function.
Each of these ones contain "TT_Seek_File", "TT_Access_Frame", etc. {TTFile.pas}

I'm shocked as tangled are these procedures!
Looks like it was ported from C, its limbs stick out of everywhere.  %)

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: [LazFreeType] Resource Font
« Reply #7 on: February 01, 2013, 08:26:11 pm »
Yes it's a mess. I totally agree. I tried to put some it into classes, but there is still much to do.

I understand. In fact, I would like to rewrite completely the file access. I don't like those calls TT_Seek etc. outside of an object. So we could both add loading from resources, and also improve the way the library is written.

Thanks a lot for this description. It will be useful for this purpose.
Conscience is the debugger of the mind

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: [LazFreeType] Resource Font
« Reply #8 on: February 02, 2013, 01:30:50 am »
Quote
I would like to rewrite completely the file access.
If you do that, please also try to reduce the amount of range check errors --
that code is written in true C style, with buffer overruns everywhere :)

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: [LazFreeType] Resource Font
« Reply #9 on: February 06, 2013, 06:07:57 pm »
Here is a patch for file access. It goes now through a TFreeTypeStream class, and TFreeTypeFont has a AccessFromStream function to load the font from any stream. There is a AStreamOwner parameter to specify that the stream must be freed by the font.

So for example, to load from a file, you can do that if you want :
Code: [Select]
    stream:= TFileStream.Create('arial.ttf',fmOpenRead);
    ftFont := TFreeTypeFont.Create;
    ftFont.AccessFromStream(stream,True{will be freed});

Instead of doing this :
Code: [Select]
ftFont := TFreeTypeFont.Create;
    ftFont.Name := 'arial.ttf';  [/quote]

About range check errors, I do not know what you're talking about Ask.
Conscience is the debugger of the mind

Vladimyr

  • New member
  • *
  • Posts: 7
Re: [LazFreeType] Resource Font
« Reply #10 on: February 06, 2013, 07:59:42 pm »
unbelievable! within a week, you did that would take for me a month or even more!
(i'm coding in my free time only, but nevertheless...)
how can i thank you?!  O:-)

(i will try this patch on the upcoming weekend.)

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: [LazFreeType] Resource Font
« Reply #11 on: February 06, 2013, 09:12:14 pm »
Cool. Give me some news when you do.  ;)
Conscience is the debugger of the mind

Ask

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 687
Re: [LazFreeType] Resource Font
« Reply #12 on: February 08, 2013, 02:21:00 pm »
Committed in r40207. This have taken me some time to review -- but hey, it is a 2000-line patch :)
In general, I agree with the change and I have not found serious errors, so it seems to be ok.

Some notes:
1) The most important -- is there any tests besides the example? I would like to make sure nothing breaks.
2) You have removed comments related to thread-safety. Do you consider new code to be thread-safe?
3) Is TT_Stream type still needed?
4) The error handling is now quite convoluted, since it is a mix of exceptions and error coder.

Quote
About range check errors, I do not know what you're talking about Ask.
To see them, remove {$R-} from the beginning of the lazfreetype units and rebuild Lazarus with range check on.

circular

  • Hero Member
  • *****
  • Posts: 2982
    • Personal webpage
Re: [LazFreeType] Resource Font
« Reply #13 on: February 08, 2013, 04:21:12 pm »
Ok.

1) Well I tested it with some files. That's all I can say.
2) Those comments were just misplaced, because I removed some procedures and functions. It is not thread safe. For example, I suppose it will not work if the font is loaded twice and is access by two streams at the same time. But I'm not sure about it. Otherwise, if the same font is used by two threads at the same time, it will not work at all, see point 3.
3) TT_Stream is used as an untyped global variable and a gate to access the stream. Basically, TT_Use_Stream gives you a typed class that you can use, but it will not work if it is already in use. To make it completely thread safe, it would be necessary to do that test in a critical section or something like that.
4) Sure. On one side there are LCL units that use exceptions, and on the other LazFreeType returns error codes. There is something to improve however, it is about the constructor, which can cause an exception, because FName <> '' is used as a hint that a file should be opened. Adding a boolean would allow to avoid this exception here.

Quote
Quote
About range check errors, I do not know what you're talking about Ask.
To see them, remove {$R-} from the beginning of the lazfreetype units and rebuild Lazarus with range check on.
I don't get any range error. Where for example ?

To go towards multi-threading, there would be two things to do :
- to ensure that the same file can be accessed by the different font objects.
- to provide a mutex instance, when TT_Use_Stream is called, which is released when TT_Done_Stream is called
« Last Edit: February 08, 2013, 04:47:33 pm by circular »
Conscience is the debugger of the mind

Vladimyr

  • New member
  • *
  • Posts: 7
Re: [LazFreeType] Resource Font
« Reply #14 on: February 08, 2013, 05:50:18 pm »
Cool. Give me some news when you do.  ;)
some hunks failed, but nothing serious.
compiled and it works!  :D

excuse me, but one question is left: can it work with BGRATextFX?

i've read the tutorial here, but didn't find how to select the font face.
it seems still using old 'Font.Name' approach, and also 'SetDefaultFreeTypeFontCollection'.

but even if i set font collection, how to select one font between the other ones?
or the font from resource stream still can be used somehow?

Committed in r40207.
very strange commit.... the patch uploaded here does not contain 'A Count'  %)