Age | Commit message (Collapse) | Author | Files | Lines |
|
num_glyphs and num_clusters are explicitly checked to be non-NULL at the
beginning of this routine, and by this point in the code both have been
deref'd multiple times, so checking them for NULL here again is
superfluous.
It looks like the intent here is to verify the glyphs and clusters
arrays are non-NULL unless their counts are zero, so change the tests
accordingly.
Coverity ID: #983386
Signed-off-by: Bryce Harrington <bryce@bryceharrington.org>
|
|
_cairo_malloc(0) always returns NULL, but has not been used
consistently. This patch replaces many calls to malloc() with
_cairo_malloc().
Fixes: fdo# 101547
CVE: CVE-2017-9814 Heap buffer overflow at cairo-truetype-subset.c:1299
Reviewed-by: Bryce Harrington <bryce@osg.samsung.com>
|
|
This happens when _cairo_ft_scaled_glyph_init() returns
CAIRO_INT_STATUS_UNSUPPORTED when called from
_cairo_scaled_glyph_lookup(). In those cases
_cairo_scaled_font_free_last_glyph() is called to release the glyph that
has just been allocated. If there aren't more glyphs,
_cairo_scaled_glyph_page_destroy() is called. The problem is that
_cairo_scaled_glyph_lookup() should always be called with the cache
frozen, and _cairo_scaled_glyph_page_destroy() without the cache
frozen. We can simply thaw/freeze the font before calling
_cairo_scaled_glyph_page_destroy().
https://bugs.freedesktop.org/show_bug.cgi?id=103335
|
|
|
|
This information will be used in subsequent commits to quickly
decide that we won't try to handle glpyhs as masks. Implementing
the new has_color_glyphs vfunc is optional - only backends that
support color glyphs need to implement it.
|
|
With this, glyphs can have either a surface that is expected
to be used as mask, or a color_surface that should be used
as source, or both.
This will be used to support colored emoji glyphs that are
stored as PNG images in OpenType fonts.
|
|
"can be get" is incorrect grammar; "can be gotten" would be better, but
active voice is best.
Signed-off-by: Bryce Harrington <bryce@bryceharrington.org>
|
|
The destruction of a scaled font could indirectly trigger the destruction
of a second scaled font, causing the global cache to be locked twice in
the same thread.
This is solved by unlinking the font's glyph pages while holding the global
lock, then releasing the lock before destruction takes place.
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=93891
|
|
|
|
If we fail to create a glyph, and it is the only one in the glyph page,
we then pluck that page out of the global glyph cache. The cache destroy
callback tries to take the scaled_font lock again, causing a lockup.
Rework the error path to avoid taking that lock in this case - still a
potential lock ordering issue remains.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Stop trying to workaround the destroy-callback requiring the font mutex
as we already hold the mutex whilst cleaning up the font caches.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Sadly we cannot check ahead of acquiring the lock whether we hold the
lock. Just have to rely on lockdep.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
If we need to reap the global cache, this will call back into the scaled
font to free the glyph page. We therefore need to be careful not to run
concurrently with a user adding to the glyph page, ergo we need locking.
To complicate matters we need to be wary of a lock-inversion as we hold
the scaled_font lock whilst thawing the global cache. We prevent the
deadlock by careful ordering of the thaw-unlock and by inspecting the
current frozen state of the scaled-font before releasing the glyph
page.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
In the case of a recording surface we may recurse into the global glyph
cache so we need to be careful and stage the ordering of how we free the
glyphs. So first we finish any information and surfaces from the scaled
font glyph cache (and so triggering recursion into other scaled fonts)
and then take the global cache and remove our pages.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=54950
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
The freeze/thaw routines have a side-effect of managing the global glyph
cache in addition to taking the mutex on the font. If we don't call
them, we may end up indefinitely keeping the global glyph cache frozen
(effectively leaking glyphs to the maximum of all open fonts) and
triggering asserts.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
As suggested by Simon Sapin.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
This new pixman API allows glyphs to be cached and composited in one
go, which reduces overhead compared to individual calls to
pixman_image_composite_region32().
Notes:
- There is an explicit call to _cairo_image_scaled_glyph_fini(). This
could instead be done with a private, but I chose not to do that
since we don't need to store any actual data; we only need
notification when the glyph dies.
- The slowdown in poppler-reseau is real and stable across runs. I'm
not too concerned about it because this benchmark is only one run
and so it is dominated by glyph cache setup costs and FreeType
rasterizing.
Performance results, image backend:
Speedups
firefox-talos-gfx 5571.55 -> 4265.57: 1.31x speedup
gnome-terminal-vim 1875.82 -> 1715.14: 1.09x speedup
evolution 1128.24 -> 1047.68: 1.08x speedup
xfce4-terminal-a1 1364.38 -> 1277.48: 1.07x speedup
Slowdowns
poppler-reseau 374.42 -> 394.29: 1.05x slowdown
Performance results, image16 backend:
Speedups
firefox-talos-gfx 5387.25 -> 4065.39: 1.33x speedup
gnome-terminal-vim 2116.66 -> 1962.79: 1.08x speedup
evolution 987.50 -> 924.27: 1.07x speedup
xfce4-terminal-a1 1856.85 -> 1748.25: 1.06x speedup
gvim 1484.07 -> 1398.75: 1.06x speedup
Slowdowns
poppler-reseau 371.37 -> 393.99: 1.06x slowdown
Also bump pixman requirement to 0.27.1.
|
|
Spotted by code inspection whilst looking at #50705
References: https://bugs.freedesktop.org/show_bug.cgi?id=50705
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
If the font metrics appear broken, i.e. key values are being reported as
zero, skip approximating the bbox of the glyph string.
References: https://bugs.freedesktop.org/show_bug.cgi?id=50688
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
This was pushed accidentally - apologies.
This reverts commit 752c3b69e008b7d219da8cc5c657cf995732d3b8.
|
|
|
|
References: https://bugs.freedesktop.org/show_bug.cgi?id=48577
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
The following Python script was used to compute "Since: 1.X" tags,
based on the first version where a symbol became officially supported.
This script requires a concatenation of the the cairo public headers
for the officially supported beckends to be available as
"../../includes/1.X.0.h".
from sys import argv
import re
syms = {}
def stripcomments(text):
def replacer(match):
s = match.group(0)
if s.startswith('/'):
return ""
else:
return s
pattern = re.compile(
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
re.DOTALL | re.MULTILINE
)
return re.sub(pattern, replacer, text)
for minor in range(12,-2,-2):
version = "1.%d" % minor
names = re.split('([A-Za-z0-9_]+)', stripcomments(open("../../includes/%s.0.h" % version).read()))
for s in names: syms[s] = version
for filename in argv[1:]:
is_public = False
lines = open(filename, "r").read().split("\n")
newlines = []
for i in range(len(lines)):
if lines[i] == "/**":
last_sym = lines[i+1][2:].strip().replace(":", "")
is_public = last_sym.lower().startswith("cairo")
elif is_public and lines[i] == " **/":
if last_sym in syms:
v = syms[last_sym]
if re.search("Since", newlines[-1]): newlines = newlines[:-1]
if newlines[-1].strip() != "*": newlines.append(" *")
newlines.append(" * Since: %s" % v)
else:
print "%s (%d): Cannot determine the version in which '%s' was introduced" % (filename, i, last_sym)
newlines.append(lines[i])
out = open(filename, "w")
out.write("\n".join(newlines))
out.close()
|
|
Documentation comments should always start with "/**" and end with
"**/". This is not required by gtk-doc, but it makes the
documentations formatting more consistent and simplifies the checking
of documentation comments.
The following Python script tries to enforce this.
from sys import argv
from sre import search
for filename in argv[1:]:
in_doc = False
lines = open(filename, "r").read().split("\n")
for i in range(len(lines)):
ls = lines[i].strip()
if ls == "/**":
in_doc = True
elif in_doc and ls == "*/":
lines[i] = " **/"
if ls.endswith("*/"):
in_doc = False
out = open(filename, "w")
out.write("\n".join(lines))
out.close()
This fixes most 'documentation comment not closed with **/' warnings
by check-doc-syntax.awk.
|
|
A zero-sized box contains no pixels and so cannot overlap, but it does
still need to contribute to the extents.
|
|
Fixes [large-]twin-antialias-mixed.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Remove the cut'n'paste duplication and replace the hash computation with
a proper function.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Complete the task started in cd4b2d843b2a8c06ba78c15ff65763b5bdf54dc6 by
remembering to compute the insertion hash on the original font face as
well as the lookup hashes. Also take advantage by deferring resolution
of the implementation for the font face until after we fail to find an
already constructed scaled font.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Having spent the last dev cycle looking at how we could specialize the
compositors for various backends, we once again look for the
commonalities in order to reduce the duplication. In part this is
motivated by the idea that spans is a good interface for both the
existent GL backend and pixman, and so they deserve a dedicated
compositor. xcb/xlib target an identical rendering system and so they
should be using the same compositor, and it should be possible to run
that same compositor locally against pixman to generate reference tests.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
P.S. This brings massive upheaval (read breakage) I've tried delaying in
order to fix as many things as possible but now this one patch does far,
far, far too much. Apologies in advance for breaking your favourite
backend, but trust me in that the end result will be much better. :)
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
If the hash value is different, the keys cannot be equal. Testing this
beforehand can avoid a few function calls and shares this optimization
across all cairo-hash uses.
|
|
This patch has been generated by the following Coccinelle semantic patch:
// Remove useless checks for NULL before freeing
//
// free (NULL) is a no-op, so there is no need to avoid it
@@
expression E;
@@
+ free (E);
+ E = NULL;
- if (unlikely (E != NULL)) {
- free(E);
(
- E = NULL;
|
- E = 0;
)
...
- }
@@
expression E;
@@
+ free (E);
- if (unlikely (E != NULL)) {
- free (E);
- }
|
|
Computing the exact bbox of the glyphs and whether they are overlapped
is expensive. However, we can often check whether they are visible just
by looking at the maximal extents of the fonts along with the bbox of
the positions; much cheaper.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
But easy to optimise.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Step 1, fix the failings sighted recently by tracking clip-boxes as an
explicit property of the clipping and of composition.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
In order for custom context to automatically track when a pattern is
modify after being set on the context (and before it is used in an
operator), we need for there to be a callback when the pattern is
modified.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
We check the incoming scaled font using the original font fce, so we
need to also store it in the cache using the same face, and not the
resolved font_face (which will remain the same unless the fontconfig
configuration is updated).
Hides the quadratic behaviour of font retrieval in recent cairo-traces.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
|
|
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
With the toy font API, it is possible that cairo_scaled_font_get_font_face()
doesn't return the font face which was passed to cairo_scaled_font_create()
despite the docs saying otherwise.
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
Holding the mutex over glyph lookup not only prevents multi-threaded
races between insertion and deletion that spell disaster for memory
integrity, but also implies that the glyph cache is frozen.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
|
|
Path are always interpreted in forward direction, so the ability of
interpreting in the opposite direction (which is very unlikely to be
useful at all) can be removed.
|
|
The previous commit only added this option and made sure it gets set, but it
didn't actually have any effect. This commit now implements this option.
Signed-off-by: Uli Schlachter <psychon@znc.in>
|
|
I did this manually so I could review the docs at the same time.
If anyone finds typos or other mistakes I did, please complain to me (or
better: fix them).
|
|
Text with size 0 has a singular scale matrix, thus requires special
handling to avoid invalidating the context where it is used.
Fixes pthread-show-text and text-zero-len (they failed with assertion
when ran using the user font backend).
|
|
This patch implements the ideas outlined by Behdad Esfahbod in the following
mailing list message:
http://lists.cairographics.org/archives/cairo/2010-June/020065.html
Specifically, two things have been adjusted. First, the size of the look-up
table was reduced to 64. Second, cache codepath is now bypassed for strings
that are shorter than 16, not only for one-character strings. This allowed
us to reduce the LUT initialization overhead while still retaining the
advantage of caching for common-case string sizes.
We have experimented with different LUT sizes, and it came out that the size
of 64 is the best one in view of speed, at least for our language-neutral
benchmark, which generated random strings of printable ASCII characters.
Below is a table presenting benchmark results for different values of LUT
size:
===============================================================================
Benchmark | [1] | [2] | [3] | [4] | [5] | [6] | [7]
===============================================================================
8px text, 1 chars | 0.41 | 0.41 | 0 | 0.41 | 0 | 0.41 | 0
8px text, 10 chars | 2.13 | 2.21 | 3.76 | 2.19 | 2.82 | 2.09 | -1.88
8px text, 20 chars | 2.97 | 3.04 | 2.36 | 3.01 | 1.35 | 2.98 | 0.34
12px text, 1 chars | 0.94 | 0.94 | 0 | 0.95 | 1.06 | 0.94 | 0
12px text, 10 chars | 4.73 | 4.89 | 3.38 | 4.9 | 3.59 | 4.82 | 1.9
12px text, 20 chars | 6.32 | 6.42 | 1.58 | 6.46 | 2.22 | 6.32 | 0
16px text, 1 chars | 1.75 | 1.76 | 0.57 | 1.77 | 1.14 | 1.76 | 0.57
16px text, 10 chars | 8.13 | 8.45 | 3.94 | 8.43 | 3.69 | 8.44 | 3.81
16px text, 20 chars | 10.41 | 10.69 | 2.69 | 10.64 | 2.21 | 10.65 | 2.31
24px text, 1 chars | 3.3 | 3.3 | 0 | 3.32 | 0.61 | 3.3 | 0
24px text, 10 chars | 14.68 | 14.97 | 1.98 | 14.97 | 1.98 | 14.87 | 1.29
24px text, 20 chars | 17.93 | 18.01 | 0.45 | 18.06 | 0.73 | 17.81 | -0.67
96px text, 1 chars | 23.65 | 23.38 | -1.14 | 23.74 | 0.38 | 23.65 | 0
96px text, 5 chars | 50.52 | 51.34 | 1.62 | 51.48 | 1.9 | 51.41 | 1.76
96px text, 10 chars | 57.5 | 58.11 | 1.06 | 58.27 | 1.34 | 58.04 | 0.94
===============================================================================
[1]: Git head, Mpix/s
[2]: {GLYPH_LUT_SIZE = 32, CACHING_THRESHOLD = 16}
[3]: Gain of {32, 16} w.r.t. Git head
[4]: {GLYPH_LUT_SIZE = 64, CACHING_THRESHOLD = 16}
[5]: Gain of {64, 16} w.r.t. Git head
[6]: {GLYPH_LUT_SIZE = 128, CACHING_THRESHOLD = 16}
[7]: Gain of {128, 16} w.r.t. Git head
The benchmark itself can be found from this mailing list message:
http://lists.cairographics.org/archives/cairo/2010-June/020064.html
|