[Ffmpeg-devel] [PATCH] drawtext.c: 09 fix draw_glyph
Michael Niedermayer
michaelni
Wed Sep 13 11:56:53 CEST 2006
Hi
On Sun, Sep 10, 2006 at 04:29:56PM -0300, Gustavo Sverzut Barbieri wrote:
> This fix the other major remaining bug with drawtext.c: drawing glyphs.
>
> The previous code was flawed due over-complicated outline detection,
> this is much more simple: while visiting a glyph pixel, check if
> neighbours are not pixels, in this case they're border and should be
> draw as outline if this is the case.
>
> I believe this is the last patch to fix bugs and improve code. If
> they're all ok then I'll post a "code cleanup" series of patches.
[...]
> @@ -317,65 +305,55 @@
> }
>
>
> +static inline int bitmap_is_set(const FT_Bitmap *bitmap, const int x, const int y)
> +{
> + const int idx = bitmap->pitch * y + x / 8;
> + const int is_pixel = bitmap->buffer[idx] & (0x80 >> (x % 8));
/8 and %8 of signed integers is slow, you should use >>3 and &7
> +
> + return is_pixel;
> +}
> +
> +static inline int bitmap_is_border(const FT_Bitmap *bitmap, const int x, const int y, const int dx, const int dy)
> +{
> + if (x == 0 || x >= bitmap->width || y == 0 || y >= bitmap->rows)
> + return 1;
> + return !bitmap_is_set(bitmap, x + dx, y + dy);
> +}
>
>
> static inline void draw_glyph(AVPicture *picture, FT_Bitmap *bitmap, unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned char yuv_fgcolor[3], unsigned char yuv_bgcolor[3], int outline)
> {
> int r, c;
> - int spixel, dpixel[3], in_glyph=0;
>
> if (bitmap->pixel_mode == ft_pixel_mode_mono)
> {
> - in_glyph = 0;
> - for (r=0; (r < bitmap->rows) && (r+y < height); r++)
> + for (r=0; r < bitmap->rows; r++)
> {
> - for (c=0; (c < bitmap->width) && (c+x < width); c++)
> + for (c=0; c < bitmap->width; c++)
> {
> - /* pixel in the picture (destination) */
> - GET_PIXEL(picture, dpixel, (c+x), (y+r));
> -
> - /* pixel in the glyph bitmap (source) */
> - spixel = bitmap->buffer[r*bitmap->pitch +c/8] & (0x80>>(c%8));
> -
> - if (spixel)
> - COPY_3(dpixel, yuv_fgcolor);
> -
> - if (outline)
> + if (bitmap_is_set(bitmap, c, r))
> {
> - /* border detection: */
> - if ( (!in_glyph) && (spixel) )
> - /* left border detected */
> - {
> - in_glyph = 1;
> - /* draw left pixel border */
> - if (c-1 >= 0)
> - SET_PIXEL(picture, yuv_bgcolor, (c+x-1), (y+r));
> - }
> - else if ( (in_glyph) && (!spixel) )
> - /* right border detected */
> + if (outline)
> {
> - in_glyph = 0;
> - /* 'draw' right pixel border */
> - COPY_3(dpixel, yuv_bgcolor);
> + if (bitmap_is_border(bitmap, c, r, -1, 0) &&
> + c - 1 + x >= 0)
> + SET_PIXEL(picture, yuv_bgcolor, c - 1 + x, r + y);
> +
> + if (bitmap_is_border(bitmap, c, r, +1, 0) &&
> + c + 1 + x < width)
> + SET_PIXEL(picture, yuv_bgcolor, c + 1 + x, r + y);
> +
> + if (bitmap_is_border(bitmap, c, r, 0, -1) &&
> + r - 1 + y >= 0)
> + SET_PIXEL(picture, yuv_bgcolor, c + x, r - 1 + y);
> +
> + if (bitmap_is_border(bitmap, c, r, 0, +1) &&
> + r + 1 + y < height)
> + SET_PIXEL(picture, yuv_bgcolor, c + x, r + 1 + y);
> }
the outline should be precalculated, instead of redoing the calculation for
every pixel, also the code should be split into a inner optimized part and
one for the areas close to the borders of the image to avoid the
0/width/height checks
>
> - if (in_glyph)
> - /* see if we have a top/bottom border */
> - {
> - /* top */
> - if ( (r-1 >= 0) && (! bitmap->buffer[(r-1)*bitmap->pitch +c/8] & (0x80>>(c%8))) )
> - /* we have a top border */
> - SET_PIXEL(picture, yuv_bgcolor, (c+x), (y+r-1));
> -
> - /* bottom */
> - if ( (r+1 < height) && (! bitmap->buffer[(r+1)*bitmap->pitch +c/8] & (0x80>>(c%8))) )
> - /* we have a bottom border */
> - SET_PIXEL(picture, yuv_bgcolor, (c+x), (y+r+1));
> -
> - }
> + SET_PIXEL(picture, yuv_fgcolor, c + x, r + y);
arent the chroma values totally wrong here? they are subsampled and just
setting them to the color of the font if any of the 4 luma samples is part
of the text isnt correct
and actually the whole should be "antialiased" instead of the binary
transparent vs. opaque
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
In the past you could go to a library and read, borrow or copy any book
Today you'd get arrested for mere telling someone where the library is
More information about the ffmpeg-devel
mailing list