mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Back out bbd7b1da5d36:b0d1c4456b73 (bug 974575) and 6e8140ae4961 (bug 969814) for ASan bustage
This commit is contained in:
parent
3a0e99a68b
commit
e17aa09c58
@ -952,7 +952,7 @@ MOZ_JPEG_CFLAGS=
|
||||
MOZ_JPEG_LIBS='$(call EXPAND_LIBNAME_PATH,mozjpeg,$(DEPTH)/media/libjpeg)'
|
||||
MOZ_BZ2_CFLAGS=
|
||||
MOZ_BZ2_LIBS='$(call EXPAND_LIBNAME_PATH,bz2,$(DEPTH)/modules/libbz2/src)'
|
||||
MOZ_PNG_CFLAGS="-I$_objdir/dist/include" # needed for freetype compilation
|
||||
MOZ_PNG_CFLAGS=
|
||||
MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/media/libpng)'
|
||||
|
||||
MOZ_JS_STATIC_LIBS='$(call EXPAND_LIBNAME_PATH,js_static,$(LIBXUL_DIST)/lib)'
|
||||
@ -8927,10 +8927,8 @@ if test "$MOZ_TREE_FREETYPE"; then
|
||||
export CPPFLAGS="$CPPFLAGS $MOZ_DEBUG_FLAGS"
|
||||
export CXXFLAGS="$CXXFLAGS $MOZ_DEBUG_FLAGS"
|
||||
export LDFLAGS="$LDFLAGS $MOZ_DEBUG_LDFLAGS"
|
||||
export LIBPNG_CFLAGS="$MOZ_PNG_CFLAGS"
|
||||
export LIBPNG_LDFLAGS="$MOZ_PNG_LIBS"
|
||||
export CONFIG_FILES="unix-cc.mk:unix-cc.in unix-def.mk:unix-def.in freetype-config freetype2.pc:freetype2.in"
|
||||
ac_configure_args="$ac_configure_args --host=$target --disable-shared --with-pic=yes"
|
||||
ac_configure_args="$ac_configure_args --host=$target --disable-shared --with-pic=yes --without-png"
|
||||
|
||||
if ! test -e modules; then
|
||||
mkdir modules
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
#include FT_IMAGE_H
|
||||
#include FT_BITMAP_H
|
||||
#include FT_TRUETYPE_TABLES_H
|
||||
#if HAVE_FT_GLYPHSLOT_EMBOLDEN
|
||||
#include FT_SYNTHESIS_H
|
||||
@ -703,8 +702,7 @@ _cairo_ft_unscaled_font_unlock_face (cairo_ft_unscaled_font_t *unscaled)
|
||||
|
||||
static cairo_status_t
|
||||
_compute_transform (cairo_ft_font_transform_t *sf,
|
||||
cairo_matrix_t *scale,
|
||||
cairo_ft_unscaled_font_t *unscaled)
|
||||
cairo_matrix_t *scale)
|
||||
{
|
||||
cairo_status_t status;
|
||||
double x_scale, y_scale;
|
||||
@ -732,39 +730,6 @@ _compute_transform (cairo_ft_font_transform_t *sf,
|
||||
if (y_scale < 1.0)
|
||||
y_scale = 1.0;
|
||||
|
||||
if (unscaled && (unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) == 0) {
|
||||
double min_distance = DBL_MAX;
|
||||
cairo_bool_t magnify = TRUE;
|
||||
int i;
|
||||
int best_i = 0;
|
||||
double best_x_size = 0;
|
||||
double best_y_size = 0;
|
||||
|
||||
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
|
||||
double x_size = unscaled->face->available_sizes[i].y_ppem / 64.;
|
||||
double y_size = unscaled->face->available_sizes[i].y_ppem / 64.;
|
||||
double distance = y_size - y_scale;
|
||||
|
||||
/*
|
||||
* distance is positive if current strike is larger than desired
|
||||
* size, and negative if smaller.
|
||||
*
|
||||
* We like to prefer down-scaling to upscaling.
|
||||
*/
|
||||
|
||||
if ((magnify && distance >= 0) || fabs (distance) <= min_distance) {
|
||||
magnify = distance < 0;
|
||||
min_distance = fabs (distance);
|
||||
best_i = i;
|
||||
best_x_size = x_size;
|
||||
best_y_size = y_size;
|
||||
}
|
||||
}
|
||||
|
||||
x_scale = best_x_size;
|
||||
y_scale = best_y_size;
|
||||
}
|
||||
|
||||
sf->x_scale = x_scale;
|
||||
sf->y_scale = y_scale;
|
||||
|
||||
@ -802,7 +767,7 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
||||
unscaled->have_scale = TRUE;
|
||||
unscaled->current_scale = *scale;
|
||||
|
||||
status = _compute_transform (&sf, scale, unscaled);
|
||||
status = _compute_transform (&sf, scale);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -827,12 +792,46 @@ _cairo_ft_unscaled_font_set_scale (cairo_ft_unscaled_font_t *unscaled,
|
||||
|
||||
FT_Set_Transform(unscaled->face, &mat, NULL);
|
||||
|
||||
error = FT_Set_Char_Size (unscaled->face,
|
||||
sf.x_scale * 64.0 + .5,
|
||||
sf.y_scale * 64.0 + .5,
|
||||
0, 0);
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
if ((unscaled->face->face_flags & FT_FACE_FLAG_SCALABLE) != 0) {
|
||||
double x_scale = MIN(sf.x_scale, MAX_FONT_SIZE);
|
||||
double y_scale = MIN(sf.y_scale, MAX_FONT_SIZE);
|
||||
error = FT_Set_Char_Size (unscaled->face,
|
||||
x_scale * 64.0 + .5,
|
||||
y_scale * 64.0 + .5,
|
||||
0, 0);
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
} else {
|
||||
double min_distance = DBL_MAX;
|
||||
int i;
|
||||
int best_i = 0;
|
||||
|
||||
for (i = 0; i < unscaled->face->num_fixed_sizes; i++) {
|
||||
#if HAVE_FT_BITMAP_SIZE_Y_PPEM
|
||||
double size = unscaled->face->available_sizes[i].y_ppem / 64.;
|
||||
#else
|
||||
double size = unscaled->face->available_sizes[i].height;
|
||||
#endif
|
||||
double distance = fabs (size - sf.y_scale);
|
||||
|
||||
if (distance <= min_distance) {
|
||||
min_distance = distance;
|
||||
best_i = i;
|
||||
}
|
||||
}
|
||||
#if HAVE_FT_BITMAP_SIZE_Y_PPEM
|
||||
error = FT_Set_Char_Size (unscaled->face,
|
||||
unscaled->face->available_sizes[best_i].x_ppem,
|
||||
unscaled->face->available_sizes[best_i].y_ppem,
|
||||
0, 0);
|
||||
if (error)
|
||||
#endif
|
||||
error = FT_Set_Pixel_Sizes (unscaled->face,
|
||||
unscaled->face->available_sizes[best_i].width,
|
||||
unscaled->face->available_sizes[best_i].height);
|
||||
if (error)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
}
|
||||
|
||||
return CAIRO_STATUS_SUCCESS;
|
||||
}
|
||||
@ -1115,7 +1114,6 @@ _fill_xrender_bitmap(FT_Bitmap *target,
|
||||
*/
|
||||
static cairo_status_t
|
||||
_get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
FT_Library library,
|
||||
cairo_bool_t own_buffer,
|
||||
cairo_font_options_t *font_options,
|
||||
cairo_image_surface_t **surface)
|
||||
@ -1124,7 +1122,6 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
unsigned char *data;
|
||||
int format = CAIRO_FORMAT_A8;
|
||||
cairo_image_surface_t *image;
|
||||
cairo_bool_t component_alpha = FALSE;
|
||||
|
||||
width = bitmap->width;
|
||||
height = bitmap->rows;
|
||||
@ -1155,7 +1152,9 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
source = bitmap->buffer;
|
||||
dest = data;
|
||||
for (i = height; i; i--) {
|
||||
memcpy (dest, source, stride);
|
||||
memcpy (dest, source, bitmap->pitch);
|
||||
memset (dest + bitmap->pitch, '\0', stride - bitmap->pitch);
|
||||
|
||||
source += bitmap->pitch;
|
||||
dest += stride;
|
||||
}
|
||||
@ -1179,18 +1178,8 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
case FT_PIXEL_MODE_LCD:
|
||||
case FT_PIXEL_MODE_LCD_V:
|
||||
case FT_PIXEL_MODE_GRAY:
|
||||
if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL ||
|
||||
bitmap->pixel_mode == FT_PIXEL_MODE_GRAY)
|
||||
{
|
||||
if (font_options->antialias != CAIRO_ANTIALIAS_SUBPIXEL) {
|
||||
stride = bitmap->pitch;
|
||||
|
||||
/* We don't support stride not multiple of 4. */
|
||||
if (stride & 3)
|
||||
{
|
||||
assert (!own_buffer);
|
||||
goto convert;
|
||||
}
|
||||
|
||||
if (own_buffer) {
|
||||
data = bitmap->buffer;
|
||||
} else {
|
||||
@ -1201,72 +1190,21 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
}
|
||||
|
||||
format = CAIRO_FORMAT_A8;
|
||||
format = CAIRO_FORMAT_A8;
|
||||
} else {
|
||||
data = bitmap->buffer;
|
||||
stride = bitmap->pitch;
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
component_alpha = TRUE;
|
||||
}
|
||||
break;
|
||||
#ifdef FT_LOAD_COLOR
|
||||
case FT_PIXEL_MODE_BGRA:
|
||||
stride = width * 4;
|
||||
if (own_buffer) {
|
||||
data = bitmap->buffer;
|
||||
} else {
|
||||
data = _cairo_malloc_ab (height, stride);
|
||||
if (!data)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
/* if we get there, the data from the source bitmap
|
||||
* really comes from _fill_xrender_bitmap, and is
|
||||
* made of 32-bit ARGB or ABGR values */
|
||||
assert (own_buffer != 0);
|
||||
assert (bitmap->pixel_mode != FT_PIXEL_MODE_GRAY);
|
||||
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
data = bitmap->buffer;
|
||||
stride = bitmap->pitch;
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
}
|
||||
format = CAIRO_FORMAT_ARGB32;
|
||||
break;
|
||||
#endif
|
||||
case FT_PIXEL_MODE_GRAY2:
|
||||
case FT_PIXEL_MODE_GRAY4:
|
||||
convert:
|
||||
if (!own_buffer && library)
|
||||
{
|
||||
/* This is pretty much the only case that we can get in here. */
|
||||
/* Convert to 8bit grayscale. */
|
||||
|
||||
FT_Bitmap tmp;
|
||||
FT_Int align;
|
||||
|
||||
format = CAIRO_FORMAT_A8;
|
||||
|
||||
align = cairo_format_stride_for_width (format, bitmap->width);
|
||||
|
||||
FT_Bitmap_New( &tmp );
|
||||
|
||||
if (FT_Bitmap_Convert( library, bitmap, &tmp, align ))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
FT_Bitmap_Done( library, bitmap );
|
||||
*bitmap = tmp;
|
||||
|
||||
stride = bitmap->pitch;
|
||||
data = _cairo_malloc_ab (height, stride);
|
||||
if (!data)
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
if (bitmap->num_grays != 256)
|
||||
{
|
||||
unsigned int x, y;
|
||||
unsigned int mul = 255 / (bitmap->num_grays - 1);
|
||||
FT_Byte *p = bitmap->buffer;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
p[x] *= mul;
|
||||
p += bitmap->pitch;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (data, bitmap->buffer, stride * height);
|
||||
break;
|
||||
}
|
||||
/* These could be triggered by very rare types of TrueType fonts */
|
||||
default:
|
||||
if (own_buffer)
|
||||
@ -1284,7 +1222,7 @@ _get_bitmap_surface (FT_Bitmap *bitmap,
|
||||
return (*surface)->base.status;
|
||||
}
|
||||
|
||||
if (component_alpha)
|
||||
if (format == CAIRO_FORMAT_ARGB32)
|
||||
pixman_image_set_component_alpha (image->pixman_image, TRUE);
|
||||
|
||||
_cairo_image_surface_assume_ownership_of_data (image);
|
||||
@ -1465,7 +1403,7 @@ _render_glyph_outline (FT_Face face,
|
||||
/* Note:
|
||||
* _get_bitmap_surface will free bitmap.buffer if there is an error
|
||||
*/
|
||||
status = _get_bitmap_surface (&bitmap, NULL, TRUE, font_options, surface);
|
||||
status = _get_bitmap_surface (&bitmap, TRUE, font_options, surface);
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
@ -1506,7 +1444,6 @@ _render_glyph_bitmap (FT_Face face,
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
status = _get_bitmap_surface (&glyphslot->bitmap,
|
||||
glyphslot->library,
|
||||
FALSE, font_options,
|
||||
surface);
|
||||
if (unlikely (status))
|
||||
@ -1548,7 +1485,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||
* the "shape" portion of the font transform
|
||||
*/
|
||||
original_to_transformed = *shape;
|
||||
|
||||
|
||||
cairo_surface_get_device_offset (&(*surface)->base, &origin_x, &origin_y);
|
||||
orig_width = (*surface)->width;
|
||||
orig_height = (*surface)->height;
|
||||
@ -1598,11 +1535,7 @@ _transform_glyph_bitmap (cairo_matrix_t * shape,
|
||||
if (unlikely (status))
|
||||
return status;
|
||||
|
||||
if (cairo_image_surface_get_format (*surface) == CAIRO_FORMAT_ARGB32 &&
|
||||
!pixman_image_get_component_alpha ((*surface)->pixman_image))
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
|
||||
else
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
|
||||
image = cairo_image_surface_create (CAIRO_FORMAT_A8, width, height);
|
||||
if (unlikely (image->status))
|
||||
return image->status;
|
||||
|
||||
@ -2236,18 +2169,6 @@ _cairo_ft_scaled_glyph_init (void *abstract_font,
|
||||
vertical_layout = TRUE;
|
||||
}
|
||||
|
||||
#ifdef FT_LOAD_COLOR
|
||||
/* Color-glyph support:
|
||||
*
|
||||
* This flags needs plumbing through fontconfig (does it?), and
|
||||
* maybe we should cache color and grayscale bitmaps separately
|
||||
* such that users of the font (ie. the surface) can choose which
|
||||
* version to use based on target content type.
|
||||
*/
|
||||
|
||||
load_flags |= FT_LOAD_COLOR;
|
||||
#endif
|
||||
|
||||
error = FT_Load_Glyph (scaled_font->unscaled->face,
|
||||
_cairo_scaled_glyph_index(scaled_glyph),
|
||||
load_flags);
|
||||
@ -3005,7 +2926,7 @@ _cairo_ft_resolve_pattern (FcPattern *pattern,
|
||||
font_matrix,
|
||||
&scale);
|
||||
|
||||
status = _compute_transform (&sf, &scale, NULL);
|
||||
status = _compute_transform (&sf, &scale);
|
||||
if (unlikely (status))
|
||||
return (cairo_font_face_t *)&_cairo_font_face_nil;
|
||||
|
||||
|
@ -3958,6 +3958,16 @@ _composite_glyphs (void *closure,
|
||||
cairo_status_t status;
|
||||
int i;
|
||||
|
||||
if (pattern != NULL) {
|
||||
src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
|
||||
src_x -= dst_x;
|
||||
src_y -= dst_y;
|
||||
} else {
|
||||
src = _pixman_white_image ();
|
||||
}
|
||||
if (unlikely (src == NULL))
|
||||
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
|
||||
memset (glyph_cache, 0, sizeof (glyph_cache));
|
||||
status = CAIRO_STATUS_SUCCESS;
|
||||
|
||||
@ -4008,43 +4018,17 @@ _composite_glyphs (void *closure,
|
||||
if (y2 > extents->y + extents->height)
|
||||
y2 = extents->y + extents->height;
|
||||
|
||||
if (glyph_surface->format == CAIRO_FORMAT_A8 ||
|
||||
glyph_surface->format == CAIRO_FORMAT_A1)
|
||||
{
|
||||
if (unlikely (src == NULL)) {
|
||||
if (pattern != NULL) {
|
||||
src = _pixman_image_for_pattern (pattern, FALSE, extents, &src_x, &src_y);
|
||||
src_x -= dst_x;
|
||||
src_y -= dst_y;
|
||||
} else {
|
||||
src = _pixman_white_image ();
|
||||
}
|
||||
if (unlikely (src == NULL)) {
|
||||
status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pixman_image_composite32 (pixman_op,
|
||||
src, glyph_surface->pixman_image, dst,
|
||||
x1 + src_x, y1 + src_y,
|
||||
x1 - x, y1 - y,
|
||||
x1 - dst_x, y1 - dst_y,
|
||||
x2 - x1, y2 - y1);
|
||||
} else {
|
||||
pixman_image_composite32 (pixman_op,
|
||||
glyph_surface->pixman_image, NULL, dst,
|
||||
x1 - x, y1 - y,
|
||||
0, 0,
|
||||
x1 - dst_x, y1 - dst_y,
|
||||
x2 - x1, y2 - y1);
|
||||
}
|
||||
pixman_image_composite32 (pixman_op,
|
||||
src, glyph_surface->pixman_image, dst,
|
||||
x1 + src_x, y1 + src_y,
|
||||
x1 - x, y1 - y,
|
||||
x1 - dst_x, y1 - dst_y,
|
||||
x2 - x1, y2 - y1);
|
||||
}
|
||||
}
|
||||
_cairo_scaled_font_thaw_cache (info->font);
|
||||
|
||||
if (src != NULL)
|
||||
pixman_image_unref (src);
|
||||
pixman_image_unref (src);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -66,25 +66,19 @@
|
||||
#define PNG_READ_SCALE_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_TRANSFORMS_SUPPORTED
|
||||
|
||||
/* necessary for freetype color bitmap support (Android & B2G)
|
||||
and boot animation code (Gonk) */
|
||||
#if defined(ANDROID) || defined(FT_CONFIG_OPTION_USE_PNG)
|
||||
#define PNG_READ_PACK_SUPPORTED
|
||||
#define PNG_READ_FILLER_SUPPORTED
|
||||
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_SEQUENTIAL_READ_SUPPORTED
|
||||
#endif
|
||||
|
||||
/* necessary for boot animation code (Gonk) */
|
||||
/* necessary for boot animation code */
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#define PNG_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED
|
||||
#define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
|
||||
#define PNG_EASY_ACCESS_SUPPORTED
|
||||
#define PNG_READ_BGR_SUPPORTED
|
||||
#define PNG_READ_FILLER_SUPPORTED
|
||||
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
|
||||
#define PNG_READ_STRIP_16_TO_8_SUPPORTED
|
||||
#define PNG_READ_STRIP_ALPHA_SUPPORTED
|
||||
#define PNG_READ_USER_TRANSFORM_SUPPORTED
|
||||
#define PNG_SEQUENTIAL_READ_SUPPORTED
|
||||
#endif
|
||||
|
||||
#define PNG_WRITE_SUPPORTED
|
||||
@ -115,8 +109,11 @@
|
||||
#define PNG_SETJMP_SUPPORTED
|
||||
#define PNG_STDIO_SUPPORTED
|
||||
#define PNG_TEXT_SUPPORTED
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
#define PNG_ERROR_TEXT_SUPPORTED
|
||||
#define PNG_WARNINGS_SUPPORTED
|
||||
#endif
|
||||
|
||||
/* Mangle names of exported libpng functions so different libpng versions
|
||||
can coexist. It is recommended that if you do this, you give your
|
||||
@ -647,11 +644,9 @@
|
||||
#define png_realloc_array MOZ_PNG_realloc_array
|
||||
#define png_zstream_error MOZ_PNG_zstream_error
|
||||
|
||||
/* needed by FreeType's PNG support */
|
||||
#define png_error MOZ_PNG_error
|
||||
|
||||
#if defined(PR_LOGGING) && defined(PNG_WARNINGS_SUPPORTED)
|
||||
#define png_warning MOZ_PNG_warning
|
||||
#define png_error MOZ_PNG_error
|
||||
#define png_chunk_error MOZ_PNG_chunk_err
|
||||
#define png_fixed_error MOZ_PNG_fixed_err
|
||||
#define png_formatted_warning MOZ_PNG_formatted_warning
|
||||
@ -661,8 +656,4 @@
|
||||
#define png_warning_parameter_unsigned MOZ_PNG_warn_param_unsigned
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
|
||||
#define png_set_packing MOZ_PNG_set_packing
|
||||
#endif
|
||||
|
||||
#endif /* MOZPNGCONF_H */
|
||||
|
@ -267,7 +267,7 @@ RawReader(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
RawReadState *state = (RawReadState *)png_get_io_ptr(png_ptr);
|
||||
if (length > (state->length - state->offset))
|
||||
png_error(png_ptr, "PNG read overrun");
|
||||
png_err(png_ptr);
|
||||
|
||||
memcpy(data, state->start + state->offset, length);
|
||||
state->offset += length;
|
||||
|
Loading…
Reference in New Issue
Block a user