Oleg Oshmyan [Wed, 4 Nov 2015 13:25:47 +0000 (15:25 +0200)]
fontselect: replace is_postscript flag with check_postscript function
DirectWrite does not provide fast access to the is_postscript flag,
requiring each font to be loaded before its format can be determined.
Eagerly doing this for every installed font can be quite slow,
on the order of seconds.
To improve performance, ask the font provider for this information
only when it is actually needed, i.e. when one of the font's full
names or its PostScript name matches a requested font name and we
need to know whether to accept this match.
The return value of check_postscript is not cached in this commit.
This makes repeated calls slower than accessing is_postscript was.
This should not be a problem, but if it is, the value can be cached
(or precomputed) by font providers in their font private data.
This commit also potentially increases the memory usage of some
font providers by retaining data structures needed to implement
check_postscript in their font private data. This should not be
a problem either, but if it is, the value of check_postscript
can be precomputed by all providers other than DirectWrite.
Oleg Oshmyan [Thu, 29 Oct 2015 23:33:30 +0000 (01:33 +0200)]
directwrite: improve error handling
* Check malloc and calloc return values.
* Abort if a name can't be fetched, rather than supply a NULL
string to fontselect causing it to crash.
* Make sure to free all allocated memory.
* Always check FAILED(hr) before using the value of any output
argument returned by DirectWrite, because it is not clear whether
they are guaranteed to have correct values in case of error.
Oleg Oshmyan [Thu, 29 Oct 2015 23:33:30 +0000 (01:33 +0200)]
directwrite: slightly clean up the code
* Metrics are not used, so don't fetch them.
* All variables except meta are always explicitly set before use,
so don't initialize them.
* Declare variables where they are used.
* Use int loop variables when the loop bound is int.
* Prefer post-increment to pre-increment.
Oleg Oshmyan [Thu, 29 Oct 2015 23:13:59 +0000 (01:13 +0200)]
directwrite: split out the inner loop of scan_fonts as a separate function
This has the side effect that the ASS_FontProviderMetaData instance is now
cleared for every font rather than only once at the start of the search,
which fixes some use-after-free scenarios and prevents the creation of
chimeric fonts using names left over from other fonts processed earlier.
This lays the groundwork for further code simplification and error handling
improvements within this function, which will come in a separate commit.
This commit is transparent to `git blame -w` except for return statements.
Oleg Oshmyan [Wed, 28 Oct 2015 22:19:20 +0000 (00:19 +0200)]
fontselect: silence warnings about discarding const
Fixing this properly involves constifying ASS_FontProviderMetaData
and refactoring code that allocates and frees strings stored in it.
This seems easy on the surface but turns out to be nontrivial when
you actually try to do it. This may still be done at a later date,
but for now, just add explicit casts.
Oleg Oshmyan [Thu, 22 Oct 2015 23:20:19 +0000 (02:20 +0300)]
fontselect: don't trim font names
This matches the behavior of GDI and hence VSFilter.
Note that \fn arguments are trimmed during parsing.
However, none of the names inside fonts should be trimmed,
and @-prefixed fonts should keep whitespace following the @,
both of which this commit addresses.
Remove strdup_trimmed because it is no longer used. Also remove
the declaration of a function that was deleted a few months ago.
Oleg Oshmyan [Thu, 22 Oct 2015 22:55:06 +0000 (01:55 +0300)]
fontselect: don't find fonts with PostScript outlines by full name
Related to commit e00691e8096cc69e5651480155ebc61d9e079290:
it turns out that GDI (and hence VSFilter) does not check full names of
fonts that have PostScript outlines when searching for a font by name.
To summarize the resulting behavior:
* Fonts with PostScript outlines can be found by family name
and by PostScript name.
* Fonts without PostScript outlines can be found by family name
and by full name.
Oleg Oshmyan [Mon, 19 Oct 2015 13:28:33 +0000 (16:28 +0300)]
fontselect: read PostScript names for memory fonts
Currently this affects only the verbose output in
ass_font_select, but it will become more useful when we
start matching against PostScript names in the future.
Oleg Oshmyan [Wed, 14 Oct 2015 18:45:31 +0000 (21:45 +0300)]
configure: don't add unnecessary libraries to PKG_LIBS_PRIVATE
Library checks can succeed if the needed functions exist in libc
and don't need any extra linker flags. Avoid adding unnecessary
flags (which break static linking against libass) in this case.
wm4 [Mon, 12 Oct 2015 19:56:44 +0000 (21:56 +0200)]
ass: use a bitmap for checking duplicate events
The loop in check_duplicate_event() essentially makes event processing
with ass_process_chunk() O(n^2). Using a bitmap instead of a loop brings
it back to O(n).
This could be interpreted as an API change: since the event list is
freely modifieable by the API user through ASS_Track public fields,
libass can't know if the internal bitmap went out of sync with the
public event list. We just redefine it so that calling
ass_process_chunk() means the API user agrees not to manipulate the
event list otherwise.
Grigori Goronzy [Wed, 23 Sep 2015 08:34:55 +0000 (10:34 +0200)]
Remove ENCA support
There is no real value in it. ENCA only works in some cases and I
can't find any information about software that integrates libass
which relies on it or users that rely on ENCA support in case the
interface is exposed directly (e.g. in MPlayer).
If there is still a wish to have charset detection integrated into
libass (it is out of scope, IMHO), a better library like uchardet
should be used for that.
As before, this does not add any build system support:
a config.h file and a project must still be manually created
(or the compiler can be run manually instead of using a project).
Signed-off-by: Grigori Goronzy <greg@kinoho.net> Signed-off-by: Oleg Oshmyan <chortos@inbox.lv>
Include config.h in all source files and in no headers
This way, #include "config.h" is consistently the very
first thing the compiler sees when compiling any file.
Some source files currently don't use anything defined in config.h,
but it's easier and less error-prone to include it now to anticipate
possible future changes in those files, config.h or other headers.
Grigori Goronzy [Tue, 15 Sep 2015 01:00:05 +0000 (03:00 +0200)]
font: ignore bearing for strikes
This is more robust and simpler. The bearing calculations initially
were bugged, but getting rid of them completely seems better. It is
consistent with other text renderers as well. To simplify things, also
move striking before the additional scale is applied and get rid of the
half-pixel overlapping thing; it is not needed with additive blending.
Grigori Goronzy [Mon, 7 Sep 2015 21:44:41 +0000 (23:44 +0200)]
NIH: add locale-independent string functions
OS or platform-specific locale independent functions are painful to
use and/or not available, so roll our own. Not great but the least
painful and least intrusive.
Passing NULL as argument to %s format specifiers when using the printf
fasmily of functions is not allowed. While some libcs handle it, other
libcs will simply crash.
Another consequence of the trickiness in this code. This codepath for
opaque_box=1 assumes both bm_o and bm_g are set, but if memory
allocation fails somewhere, bm_o could be non-NULL, but bm_g NULL, which
then would result in a crash when accessing bm_g.
Possibly this code could be cleaned up to look much nicer (and not have
dozens of hidden, obscure bugs), but for now this fixes the potential
crash found by Coverity.
The logic here is pretty complicated. The caller of this function guards
it with "if(info->bm || info->bm_o){", and generally indeed only one of
them is set. But in some cases, both are needed. fix_outline()
definitely dereferences both. This is not necessarily guaranteed, e.g.
on out of memory errors. Add the missing checks.
Grigori Goronzy [Sun, 6 Sep 2015 23:29:27 +0000 (01:29 +0200)]
fontconfig: handle fallback corner cases
If no particular codepoint is requested (codepoint == 0), just return
the first font family. Additionally, handle fontconfig errors, albeit
they're unlikely to happen.
Grigori Goronzy [Wed, 2 Sep 2015 22:04:59 +0000 (00:04 +0200)]
fontselect: fix match_fonts semantics
We don't want to add fonts multiple times, so call match_fonts lazily,
i.e. only after selecting a font with a certain name failed. Since
font matching interacts with glyph coverage checks, add a simple
mechanism to determine whether matching failed because of name or
glyph coverage. Additionally make sure to handle substitutions before
any calls to match_fonts; this only correctly deals with single-name
substitutions, though.
CFRelease(NULL) can crash. While we're still not sure which CoreText API
calls can fail etc. (thanks Apple), this should fix a couple of
theoretically possible crashes.
ass_set_fonts_dir() is supposed to enable all fonts in a specific
directory. The implementation for it was dropped with the commit
introducing the new fontselect code. Some users were relying on it, so
we need it back.
It used to be implemented using a single fontconfig call. But since this
has to work even if fontconfig support is not even compiled, a new
implementation is needed.
This commit adds very simple and low-effort support for it. It loads all
files into memory, and then lets the memory font code do the rest. A
more efficient implementation would be possible, for example by
implementing a new font provider, which serves get_data requests from
open file handles. Anyone who wants to do this is welcome to try, and
this commit is just the minimum to restore the lost feature.
wm4 [Fri, 28 Aug 2015 16:34:36 +0000 (18:34 +0200)]
render_api: fix crash when calling ass_set_fonts() after rendering
The caches may reference data which belongs to the font provider. If the
font selector and the font provider are destroyed, it can leave dangling
pointers in the renderer cache. (At least that's what it looks like.)
For some reason, this didn't even trigger valgrind warnings with the
fontconfig font provider. Possibly the dangling pointers were FT_Face
pointers, and fontconfig might cache these process-wide.
wm4 [Fri, 28 Aug 2015 15:39:08 +0000 (17:39 +0200)]
font: fix broken charmap fallback handling
An earlier commit added this code to avoid adding font faces multiple
times. In this form, it breaks the "Trying all charmaps" fallback case,
which can lead to text being rendered as boxes.
Return the font that is going to contain the missing glyph instead. The
calling code will check again, and run the fallback if necessary.
wm4 [Fri, 28 Aug 2015 12:51:09 +0000 (14:51 +0200)]
ass: make font_provider API private
We were discussing whether this should be public or private. It could be
public, because the API is potentially useful, and is relatively simple.
On the other hand, the API is not necessarily final, and making it
public would prevent us from improving/fixing it.
Make it private for now - making it public later is much easier than
having to break the public API later.