An issue occured when using subpixel antialiasing with user-fonts and
XRender - the glyphs were transparent, as demonstrated by the font-view
example.
The problem lies in that enabling subpixel antialiasing triggers use of an
ARGB32 image surface for rendering the glyph, but the default colour is
black (so the only information is in the alpha-channel). Given an ARGB32
glyph XRender treats it as a per-channel mask, but since the R,G,B
channels were uniformly zero, the glyph is rendered as transparent.
Fix this by setting the initial colour to white before rendering the image
surface for a user-font glyph, which generates the appropiate gray-level
mask by default.
The PDF surface now keeps track of all the patterns it is embedding in
a hash table keyed by the unique_id returned by the
_cairo_surface_get_unique_id().
This patch adds more implementation of the snapshot method. For
surface types where acquire_source_image is already making a copy
of the bits, doing another one as is the case for the fallback
implementation is a waste.
Provide a mechanism for backends to attach and remove snapshots. This can
be used by backends to provide a cache for _cairo_surface_clone_similar(),
or by the meta-surfaces to only emit a single pattern for each unique
snapshot.
In order to prevent stale data being returned upon a snapshot operation,
if the surface is modified (via the 5 high level operations, and on
notification of external modification) we break the association with any
current snapshot of the surface and thus preserve the current data for
their use.
Allow the caller to choose whether or not various conversions take place.
The first flag is used to disable the expansion of reflected patterns into a
repeating surface.
We can defer taking the cairo_scaled_font_map_lock until we drop the
last reference to the scaled font so long as we double check the reference
count after waiting for the lock and not making assumptions about
unreferenced fonts during construction. This is significant as even
acquiring the uncontended cairo_scaled_font_map_lock during
cairo_scaled_font_destroy() was showing up as a couple of percent on text
heavy profiles (e.g. gnome-terminal).
When observing applications two patterns emerge. The first is due to
Pango, which wraps each glyph run within a context save/restore. This
causes the scaled font to be evicted after every run and reloaded on the
next. This is caught by the MRU slot on the cairo_scaled_font_map and
prevents a relatively costly traversal of the hash table and holdovers.
The second pattern is by applications that directly manage the rendering
of their own glyphs. The prime example of this is gnome-terminal/vte. Here
the application frequently alternates between a few scaled fonts - which
requires a hash table retrieval every time.
By introducing a MRU slot on the gstate we are able to directly recover
the scaled font around 90% of the time.
Of 110,000 set-scaled-fonts:
4,000 were setting the current font
96,000 were setting to the previous font
2,500 were recovered from the MRU on the cairo_scaled_font_map
7,500 needed a hash retrieval
which compares to ~106,000 hash lookups without the additional MRU slot on
the gstate.
This translates to an elapsed time saving of ~5% when replaying a
gnome-terminal trace using the drm backend.
The structure is already exposed, so just expose the
constructors/destructors in order to enable caches to be embedded and
remove a superfluous malloc.
By simply iterating over the array cairo_trapezoid_t, converting each one
separately to a pixman_trapezoid_t and rasterizing each one individually
we can avoid the common heap allocation. pixman performs exactly the same
iteration internally so there is no efficiency loss.
Make the treatment of replacing the NULL source pattern with WHITE
consistent. As it is a solid pattern, we can skip _cairo_pattern_fini()
and so make the code more readable, and consistent along the error paths.
The number of mime-types attached to a surface is usually small,
typically zero. Therefore it is quicker to do a strcmp() against
each key in the private mime-data array than it is to intern the
string (i.e. compute a hash, search the hash table, and do a final
strcmp).
Some backends are quite constrained with surface sizes and so trigger
fallbacks when asked to clone large images. To avoid this we attempt
to trim ROIs (as these are often limited to the destination image, and
so can be accommodated by the hardware). This patch allows trimming
REPEAT sources both horizontally and vertically independently.
Jeff Muizelaar noted that the treatment of edges differed with firefox's
canvas definition, which considers a point on any edge as inside. The
current implementation has a similar definition to that of flash, for
which the top and right edges are outside. Arguably, firefox has the more
intuitive definition here...
If the backend cannot create a similar surface to hold the image, then
report back the failure before embarking upon an infinite recursion.
The UNSUPPORTED return should percolate up through the call stack and
trigger a fallback.
Bug 19251: --enable-win32=yes and --enable-win32-font=no causes
compilation failure
[https://bugs.freedesktop.org/show_bug.cgi?id=19251]
Wrap use of the win32 font backend within win32-printing-surface within
CAIRO_HAS_WIN32_FONT ifdefs to prevent compilation failure if the user
explicitly disables the win32 font backend.
As an aide to tracking down the source of uninitialised reads, run
VALGRIND_CHECK_MEM_IS_DEFINED() over the contents of image surfaces at the
boundary between backends, e.g. upon setting a glyph image or acquiring
a source image.
Damian Frank noted
[http://lists.cairographics.org/archives/cairo/2009-May/017095.html]
a performance problem with an older XServer with an
unaccelerated composite - similar problems will be seen with non-XRender
servers which will trigger extraneous fallbacks. The problem he found was
that painting an ARGB32 image onto an RGB24 destination window (using
SOURCE) was going via the RENDER protocol and not core. He was able to
demonstrate that this could be worked around by declaring the pixel data as
an RGB24 image. The issue is that the image is uploaded into a temporary
pixmap of matching depth (i.e. 32 bit for ARGB32 and 24 bit for RGB23
data), however the core protocol can only blit between Drawables of
matching depth - so without the work-around the Drawables are mismatched
and we either need to use RENDER or fallback.
This patch adds a content mask to _cairo_surface_clone_similar() to
provide the extra bit of information to the backends for when it is
possible for them to drop channels from the clone. This is used by the
xlib backend to only create a 24 bit source when blitting to a Window.
Bug 21706 -- zombie ft_font_face / ft_unscaled_font mutual
referencing problems
[http://bugs.freedesktop.org/show_bug.cgi?id=21706]
There can be more than one zombie font_face belonging to an unscaled_font,
but only the first is destroyed. This leaks the client's FT_Face
(and associated font data) as release of the FT_Face depends on release
of the font_face.
(The reason why Firefox ends up with two different font_faces for one
unscaled_font is that load_flags for faces with artificial oblique have
FT_LOAD_NO_BITMAP set.
https://bugzilla.mozilla.org/show_bug.cgi?id=486974)
Also it's possible for _cairo_ft_font_face_create to pull out a zombie
font_face from the unscaled_font, which would crash
_cairo_ft_font_face_scaled_font_create, as that expects non-null
font_face->unscaled (if !font-face->pattern).
I broke the ability for the ft font backend to resolve patterns whilst
fixing the font creation to propagate the error status from fontconfig
(be27e8). By adjusting the sequence of error checks we do not confuse
the absence of a match with a fatal error and thereby restoring the
lazy pattern resolution whilst ensuring error propagation.
Simply request a surface with a similar content to the source image when
uploading pixel data. Failing to do so prevents using a 16-bit (or
otherwise non-standard pixman image format) window as a source - in fact
it will trigger an infinite recursion.
Currently the surface snapshotting attempts to clone the source using a
new surface of identical format. This will raise an error if the source is
an unusual xserver, for example one operating at 16bpp. The solution to
this is to create the surface using the content type rather than the
format (as elsewhere within the code base). However, we also wish to
preserve FORMAT_A1 (which is lost if we only choose the format based on
_cairo_format_from_content) as the various backends may be able to
trivially special case such bitmaps.
It is possible for cairo_surface_write_to_png() to acquire a non-standard
image surface when, for example, we try to dump a low bit-depth XServer.
Handle this scenario by coercing the unknown image format to a standard
type via pixman.