Re: [Fwd: Re: (partial patch) Fixing some issues with fontconfig]
Petri Hintukainen <[email protected]> Fri, 19 Oct 2018 13:05:56 +0300
| Newsgroups | gmane.comp.video.xine.devel |
|---|---|
| Message-ID | <[email protected]> |
la, 2018-10-13 kello 09:31 +1100, Dale Magee kirjoitti: > Hi Petri, > > I had an issue subscribing and had to send my message twice. I > suspect > that's why your response didn't go through. Looks like sourceforge doesn't allow posts from my sourceforge alias anymore. Messages just disappear. Maybe they've activated some kind of new spam filter... > Like I said, I'm no C coder. In fact this will be my very > first patch to a C program! :) > > Here is another attempt that isn't horribly broken (as far as I can > tell) The second iteration looks good. You must have experience with some other language(s) :) > As suggested, I've split this into 2 patches, attached. > > * 001-fontconfig_support_filenames.patch makes it possible to use > filenames in subtitles.separate.font_freetype when fontconfig is > enabled. This is pretty trivial and just involves moving that > functionality from osd_lookup_xdg into osd_set_font_freetype2 so that > it > is attempted before trying osd_lookup_fontconfig. I did a bunch of > tests > with just this patch applied (you make a good point, splitting it > into 2 > patches makes testing easier) and can confirm that you can now use > filenames and also freetype font names. However if you put in 'cetus' > you'll get the system default font from fontconfig, same as if you > type > something invalid. > > * 002-fontconfig_prefer_native.patch makes xine prefer to use a > native > font over a freetype font if it can find one with the provided name, > making it possible to use native fonts when fontconfig is enabled and > fixing the OSD play/pause icons. > > - i went with osd_lookup_native rather than osd_find_native_font to > be > more consistent with the others (osd_lookup_xdg and > osd_lookup_fontconfig) > > - I looked through the code a bit more closely and it looks it's OK > to > just set osd->font in osd_lookup_native, so that's what I've done. If > it > sets osd->font during the first call (the test to see if there is a > native font) then it means that it's going to return 1 and it will > just > drop back out to osd_set_font - the freetype/fontconfig code will > never > be called, and osd_lookup_native will be called again and set osd- > >font > again - no big deal. setting osd->font in the function makes the > whole > thing simpler. I don't particularly like doing that because to my > mind a > function to lookup the font shouldn't also load it - the pedant in me > thinks these should be named osd_load_font_x rather than > osd_lookup_x. > But to be fair it is consistent with the behaviour of osd_lookup_xdg > and > osd_lookup_fontconfig, which both load the font rather than just > looking > it up. > > - this caused another issue in a few places (osd_render_text, > osd_get_text_size) where the code was assuming that if osd->ft2 was > set > then a freetype font has been loaded, and tries to access the > uninitialised osd->ft2->face. I added checks to ensure that > osd->ft2->face is initialised. The easier alternative was to call > osd_free_ft2 in osd_set_font if osd_lookup_native returns 1, but that > would mean creating and destroying osd->ft2 repeatedly - inefficient. > This is probably almost a separate issue again, but it's caused by > the > changes made in this patch, so I didn't separate it out. Both patches look fine. Pushed, thanks! > - I also fixed inconsistent indenting in osd_set_font (inside the if > (ret) block) > > - you mention font size being an issue for e.g UHD screens. This is a > good point and this patch will cause that issue because e.g native > xine's sans will be shown rather than the freetype sans font. > > My preference would be to make bigger native fonts since they tend to > look nicer anyway (e.g the freetype fonts don't have a border for > me). I > haven't looked but I would expect that it shouldn't be too hard to do > this by modifying xine-fontconv. Yes, it seems easy to do. Generated font sizes are hardcoded in the conversion program. > Another approach which may be the best overall would be to integrate > xine-fontconv's functionality into xine and render native fonts from > truetype on the fly when fonts are first loaded. With that approach, > all > font rendering would be 'native', and all fonts would get the nice > border added by xine-fontconv, and be scaleable to any size. I was also thinking about this. We could simply improve rendering code and install cetus.ttf. Maybe native fonts could still be used as fallback when truetype is disabled. > Also to support bigger fonts for arbitrarily large screens it may be > necessary to allow users to set the font size as an integer rather > than > the current 'small|large|etc' options. > > But you're right, that's a separate issue (and a bit of a can of > worms). I tried adding few new size options. It worked as expected, but I wasn't still happy with it. When playing in smaller window text was far too large :) Maybe subtitle font size should be relative to output size. We could scale those "huge"/"tiny" sizes to match output resolution, or add an option to set font size in % of output size. > - One issue that occurs to me is that it's now mostly redundant to > have > the two config variables subtitles.separate.font and > subtitles.separate.font_freetype, because now either can be used to > specify either a freetype or native font (as long as ft2 and > fontconfig > are compiled in). > > This also sort of makes the subtitles.separate.font_use_freetype > config > item redundant/inaccurate because it'll now prefer to use a native > font > and use freetype if that doesn't work. But I haven't done any testing > or > investigation at all as to how this works if freetype or fontconfig > are > not compiled in. Perhaps in these cases it makes sense to keep these > config vars. I haven't looked those config items, but if there are useless / redundant items, we could deprecate those. Having less config options is always a good thing. Maybe use_freetype was meant to allow selecting between built-in and freetype fonts. With that, different options for freetype and non- freetype make sense. But, still, having only single entry (font) seems simpler ... > Still, I think this is an improvement overall :) > > > Thanks for looking into this and sending the patch. It is nice to > > see xine is still used > > I've been using xine for over 15 years and it's played tens > (hundreds?) > of thousands of hours of video for me (my PC is my primary means of > watching movies). It's still my preferred player by a big margin, and > I'll keep using it for as long as I can get it to run. It's about > time I gave something back :) BTW, what GUI are you using ? Both xine-ui and gxine are pretty much the same those were over 10 years ago. > Dale Magee > > > On 13/10/18 02:14, Petri Hintukainen wrote: > > Hello, > > > > Looks like my reply never got to the mailing list ... > > > > ------- Välitetty viesti --------- > > Lähettäjä: Petri Hintukainen <[email protected]> > > Vastaanottaja: [email protected] > > Aihe: Re: [xine-devel] (partial patch) Fixing some issues with > > fontconfig > > Päiväys: Thu, 11 Oct 2018 12:16:07 +0300 > > > > ma, 2018-10-08 kello 15:04 +1100, Dale Magee kirjoitti: > > > Hi > > > > > > I've just been messing around with tracking down the cause and > > > trying > > > to > > > fix a couple of issues I've found WRT the way fontconfig works in > > > xine-lib. > > > > > > The attached patch is what I think it should be doing, but I'm no > > > C > > > coder and this code causes a segfault at the moment. I've tried a > > > bunch > > > of different things to fix it but I obviously don't understand > > > what's > > > going on and I've run out of time and patience today (it's now > > > 2am). > > > If > > > somebody could explain why it causes a segfault and how to fix > > > that > > > I'd > > > be very grateful as this might help me understand C better > > > (particularly > > > memory allocation and freeing) :) > > > > Hello, > > > > I think the problem is with splitting osd_find_native_font(). Looks > > like the new function is missing functionality of one line from the > > original code: > > osd->font = font; > > So, it does not remember nor return the best font. > > > > > > The crash itself is caused by variable > > osd_font_t *font = NULL; > > This is never changed to point to the actual font, leading to crash > > at > > line > > ret = osd_renderer_load_font(osd->renderer, osd- > > >font>filename); > > where NULL osd->font is dereferenced. > > > > > > There are multiple ways to fix this. Probably simplest would be > > returning pointer to found font. Returning integer "found"/"not > > found" > > is redundant if we return the actual "font" or "no font" (=NULL). > > > > > > Looking at the code I think you're trying to return the font to > > caller > > in the variable given as last argument. > > > > C pointers can be tricky. If you pass a pointer to a function, > > you're > > passing the address that is stored in the pointer variable. Just as > > if > > it was "normal" integer. > > osd_font_t *font = NULL; > > func(font); > > Now func() is given the address stored in variable font (NULL in > > this > > case). It can't change the value of variable font, it sees only the > > address that was stored in font. To modify the actual variable > > "font" > > in the above code, you need to take a pointer to it (= pointer to > > pointer). something like: > > osd_font_t *font = NULL; > > func(&font); > > Now func() knows the address of "font" and can modify the value of > > variable "font". Something like: > > func(osd_font_t **pfont) { > > osd_font_t *f = find_font(); > > /* store pointer "f" to the variable > > where "pfont" points to */ > > *pfont = f; > > } > > > > This could be easier to understand if osd_font_t was not a pointer: > > int font; > > /* font passed by value -> func() can't change local variable > > font */ > > func(font); > > and > > void func(int i) { > > /* only the local variable i is changed - > > caller does not see this change in variable font */ > > i = 10; > > } > > With pointers: > > int font; > > func(&font); > > and > > func (int *p) { > > /* modify caller variable "font" where p points to */ > > *p = 111; > > } > > > > > > This would change the implementation to something like: > > > > static int osd_find_native_font(osd_object_t *osd, > > const char *fontname, > > int size, > > - osd_font_t *font) { > > + osd_font_t **pfont) { > > { > > int best = 0; > > int found = 0; > > + osd_font_t *font; > > > > font = osd->renderer->fonts; > > while( font ) { > > > > if( !strcasecmp(font->name, fontname) && (size>=font->size > > && (best<font->size)) { > > found = 1; > > best = font->size; > > lprintf ("best: font->name=%s, size=%d\n", > > font->name, font->size); > > + /* "return" the font to caller */ > > + if (pfont) > > + *pfont = font; > > } > > font = font->next; > > } > > return found; > > } > > > > and you would invoke it like this: > > > > /* just look if the font is available */ > > if (osd_find_native_font(osd, fontname, size, NULL)) > > return 0; > > > > and > > > > /* get the actual font too */ > > ret = osd_find_native_font(osd, fontname, size, &font); > > > > > > An alternative would be storing the font directly to osd->font like > > in > > the original code (well, I didn't look to the code to see if that > > would > > cause some side effects in the first use case). > > > > > > If you don't want or can't modify osd->font directly, simpler could > > be > > returning the best font (or NULL if none was found). Something > > like: > > > > static osd_font_t *int osd_find_native_font(osd_object_t *osd, > > const char *fontname, int size) { > > osd_font_t *best = NULL, *font; > > > > font = osd->renderer->fonts; > > while( font ) { > > if( !strcasecmp(font->name, fontname) && (size >= font->size) > > && (best == NULL || best->size < font->size)) { > > best = font; > > lprintf ("best: font->name=%s, size=%d\n", > > font->name, font->size); > > } > > font = font->next; > > } > > return best; > > } > > > > Now, the first use case would work just as-is (check if the > > function > > returns non-NULL): > > > > if (osd_find_native_font(osd, fontname, size)) > > return 0; > > > > and the second one would be something like: > > > > font = osd_find_native_font(osd, fontname, size); > > > > > > > This patch addresses 2 issues that I've discovered when compiling > > > with > > > fontconfig enabled: > > > > > > 1. When using fontconfig it's not possible for xine to use the > > > cetus font for OSD, because osd_set_font tries to load a font > > > using > > > freetype (and hence fontconfig) first. When > > > osd_set_font_freetype2 > > > passes 'cetus' as the font name to osd_lookup_fontconfig, > > > fontconfig > > > loads a system default font because it can't find a font named > > > cetus. > > > This means that play/pause icons in the OSD are replaced with the > > > corresponding characters (">" and "<"). > > > > > > 2. When compiled with fontconfig you can not use a filename in > > > subtitles.separate.font_freetype, because when this filename is > > > passed > > > to fontconfig it looks by font name rather than filename and > > > returns > > > the > > > system default font. > > > > > > Here's what my patch is trying to do: > > > > > > 0. abstract out the bit of osd_set_font which searches for a > > > matching > > > native font into a new function osd_find_native_font (to be DRY). > > > > > > 1. osd_set_font_freetype2 first tries to use fontname as a > > > filename > > > and > > > load it (to support filenames in > > > subtitles.separate.font_freetype). > > > > > > 2. osd_set_font_freetype2 then looks for a native xine font with > > > the > > > provided name. If it finds it, it immediately returns 0 so that > > > osd_set_font can load the native xine font (i.e xine fonts are > > > now > > > used > > > as preference over freetype fonts. This should be fine because > > > according > > > to the FAQ the native fonts are better. e.g for subtitles they > > > have > > > borders). > > > > > > 3. if the 2 above steps fail, osd_set_font_freetype2 passes the > > > font > > > name to fontconfig, which may find the font or return the system > > > default > > > font (i.e previous behaviour). > > > > > > I'd love to hear any thoughts and feedback. > > > > Looks OK. I think 1 and 2 should be separate patches (those fix > > unrelated issues). > > > > With 2, the only issue I have in mind is if the internal fonts > > support > > large enough sizes. With UHD resolutions even the largest subtitle > > size > > is _very_ small. Maybe we should generate larger fonts or make font > > selection also based on available sizes (= prefer freetype when ex. > > 100+ pixel font is requested, but internal font is only 64 pixels). > > > > But that doesn't matter yet (even subtitle size selection doesn't > > support larger sizes). And, as you said, lookup order still needs > > to be > > reversed. > > > > > Thanks for your time :) > > > > Thanks for looking into this and sending the patch. It is nice to > > see > > xine is still used :) > > > > > Dale Magee > > > > > > _______________________________________________ > > > xine-devel mailing list > > > [email protected] > > > https://lists.sourceforge.net/lists/listinfo/xine-devel _______________________________________________ xine-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/xine-devel