The ctype(3) character classification and mapping functions have a
peculiarly limited definition (C11, Sec. 7.4 `Character handling
<ctype.h>', p. 200):
`The header <ctype.h> declares several functions useful for
classifying and mapping characters. In all cases the
argument is an int, the value of which shall be
representable as an unsigned char or shall equal the value
of the macro EOF. If the argument has any other value, the
behavior is undefined.'
In other words, in the most common case of 8-bit char and EOF = -1,
the domain of the 257 allowed arguments is:
-1, 0, 1, 2, ..., 254, 255
The ctype(3) functions are designed for use with stdio functions like
getchar and fgetc which return int values in the same domain.
In an ABI where char is signed (e.g., x86 SysV ABI used by most
Unixish operating systems), passing an argument of type char as is
can go wrong in two ways:
1. The value of a non-EOF input octet interpreted as `char' may
coincide, as an integer, with the value of EOF, leading to wrong
answers for some non-EOF inputs.
E.g., if EOF = 1, and an input octet has all bits set, i.e., 255
as an unsigned char, then as a char the value is -1, which will be
confused with EOF. In the ISO-8859-1 locale, the code point 255
is (in Unicode terminology) LATIN SMALL LETTER Y WITH DIAERESIS,
for which isprint, isalpha, &c., are true. But isprint, isalpha,
&c., are false for EOF. So if char *s points to a string with
that character, isprint(*s) will return false when it should
return true.
2. Passing a negative char whose value does not coincide with EOF is
undefined behaviour.
This isn't purely theoretical: often the functions are implemented
by an array lookup, #define isprint(c) (ctypetab[c] & ISPRINT).
If c is out of range (e.g., 192, ISO-8859-1 for LATIN CAPITAL
LETTER A WITH GRAVE, which convers to (signed) char as -64), then
you can get garbage answers by reading uninitialized memory or
application crashes with SIGSEGV if the page preceding the table
is unmapped.
If what you have is an arbitrary char (e.g., from a char * string
pointing at user input), then the only correct way to use the
ctype(3) functions is by converting to unsigned char first -- e.g.,
isprint((unsigned char)*s). (If the functions were defined as macros
that convert to unsigned char first, they would then spuriously
interpret EOF as a non-EOF, so they can't do that themselves.)
It is possible, in some cases, to prove that the input always
actually lies in {0, 1, 2, ..., 127}, so the conversion to unsigned
char is not necessary. I didn't check whether this was the case --
it's safer to just adopt the habit of always casting char to unsigned
char first before using the ctype(3) macros, which satisfies a
compiler warning on some systems designed to detect this class of
application errors at compile-time.
cairo_win32_font_face_create_for_hfont is reusing the HFONT object
passed by an argument if possible to create a scaled font. However,
the condition was wrong. It checked the font matrix scale factor is
`-lfHeight`. But it should be `-lfHeight * WIN32_FONT_LOGICAL_SCALE`.
Fixescairo/cairo#3
As we do already in _cairo_recording_surface_finish. Otherwise, the
cleanup path of _cairo_recording_surface_create_bbtree() could call
free() on surface->bbtree which is not dynamically allocated.
Closes: https://gitlab.freedesktop.org/cairo/cairo/-/issues/645
The following clipping text tests of win32/rgb24 target were visibly
failing because clipping didn't work.
* clip-text
* partial-clip-text-bottom
* partial-clip-text-left
* partial-clip-text-right
* partial-clip-text-top
_cairo_win32_gdi_compositor_glyphs sets the clip. However,
_cairo_dwrite_show_glyphs_on_surface unset it.
Fixescairo/cairo#641
The DWRITE_COLOR_GLYPH_RUN1 struct definition of the old MinGW
dwrite_3.h was invalid. To work around the problem, dw-extra.h defined
the correct struct definition and all necessary API from dwrite_3.h.
This approach needed to redefine all necessary API.
This change added DWRITE_COLOR_GLYPH_RUN1_WORKAROUND struct and use it
for IDWriteColorGlyphRunEnumerator1::GetCurrentRun.
The most top and bottom lines of glyphs were clipped in some fonts and
conditions. The glyph bounds were inflated 1px horizontally. It should
inflate vertically too.
Fixescairo/cairo#569
* Use dx and dy instead of dx1 and dy1 to match with the arguments
* Use dx_new and dy_new instead of dx2 and dy2 to match with other parts of the documentation
* Use xx, yx, xy, yy instead of a, b, c, d to match with other parts of the documentation
* Remove the last two sentences that doesn't make sense
The default RGB colorspace must be converted to the GPU's colorspace
using CGColorTransformConvertUsingCMSConverter. Profiling has shown this
function to consume as much as 48% of a redraw cycle in gdk-quartz.
There seems to be no named colorspace that matches the one stored on the
display, so we use the one associated with the main display. This has
some risks for users with multiple monitors but in testing with my own
two-monitor setup, one of which is HDR and the other not, the colorspace
was the same for both.
This is applied to quartz surfaces created with
cairo_quartz_surface_create(); surfaces created with
cairo_quartz_surface_create_for_cg_context will inherit the colorspace
from the context.
In order to generate PNGs that look right I've converted the
existing debugging functions for writing a quartz surface to png
into private functions and wired cairo-boilerplate-quartz to use
them. Using the generic cairo routine produced washed-out PNGs.
Fixes https://gitlab.freedesktop.org/cairo/cairo/-/issues/330
Use a CGBitmapContext mapping the underlying image surface's data instead
of maintaining a CGImage. Generalize the quartz surface snapshot mechanism
to work with both cairo_quartz_surface_t and cairo_quartz_image_surface_t
and to use the latter to get a CGContext around non-quartz surfaces.
Use this snapshot machanism to get a CGImageRef when needed from a
cairo_quartz_image_surface_t.
The win32 compositor is using _cairo_dwrite_show_glyphs_on_surface for
DWrite. It was assuming that a glyph was painted inside 3x3 of the em
square. It should take the actual glyph bounding box by using
GetAlphaTextureBounds.
Fixescairo/cairo#641
Now that FreeType 2.13.0 has been released with a stable COLRv1 API,
the meson configuration can be updated to enable COLRv1 when this
version is available.
Reuse the win32 font code to create a glyph mask for a dwrite font.
Renamed a function _compute_mask in cairo-win32-font.c to
_cairo_compute_glyph_mask.
Applying a transformation matrix to a glyph path after converting
floats to fixed point numbers caused caluculation errors. Apply the
transform before the conversion.
Fixescairo/cairo#611
The code is doing "if (!double_buf_equal () != 0)" which seems to be a
convoluted way to do "if (!double_buf_equal ())". Fixes:
../test/pattern-getters.c:153:6: warning: logical not is only applied to the left hand side of this comparison [-Wlogical-not-parentheses]
if (!double_buf_equal (ctx, new_buf, expected_values,
^
../test/pattern-getters.c:153:6: note: add parentheses after the '!' to evaluate the comparison first
if (!double_buf_equal (ctx, new_buf, expected_values,
^
(
../test/pattern-getters.c:153:6: note: add parentheses around left hand side expression to silence this warning
if (!double_buf_equal (ctx, new_buf, expected_values,
^
(