mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 23:42:16 +00:00
Implement text rendering to buffers with destination alpha. Change the subpixel rendering to override the glyph operator.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@16288 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
23a3ed2d56
commit
9abc0be347
7 changed files with 118 additions and 77 deletions
|
@ -1,3 +1,11 @@
|
|||
2003-03-29 19:13 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
* Source/art/ARTContext.m, Source/art/blit.h, Source/art/blit.m,
|
||||
Source/art/ftfont.h, Source/art/ftfont.m: Implement rendering of
|
||||
text to buffers with destination alpha. Change the subpixel
|
||||
font rendering to override the glyph operator since it's the one
|
||||
actually being used.
|
||||
|
||||
2003-03-25 Adam Fedor <fedor@gnu.org>
|
||||
|
||||
* Source/xlib/GSXftFontInfo.m: Protect 'id' when including
|
||||
|
|
|
@ -229,6 +229,7 @@ very expensive
|
|||
drawString: s
|
||||
at: x:y
|
||||
to: clip_x0:clip_y0:clip_x1:clip_y1 : CLIP_DATA : wi->bytes_per_line
|
||||
: (wi->has_alpha? wi->alpha + clip_x0 + clip_y0 * wi->sx : NULL) : wi->sx
|
||||
color: fill_color[0]:fill_color[1]:fill_color[2]:fill_color[3]
|
||||
transform: ctm
|
||||
drawinfo: &DI];
|
||||
|
|
|
@ -90,6 +90,14 @@ typedef struct draw_info_s
|
|||
unsigned char r, unsigned char g, unsigned char b,
|
||||
unsigned char alpha, int num);
|
||||
|
||||
void (*render_blit_alpha_a)(unsigned char *dst, unsigned char *dsta, const unsigned char *src,
|
||||
unsigned char r, unsigned char g, unsigned char b,
|
||||
unsigned char alpha, int num);
|
||||
void (*render_blit_mono_a)(unsigned char *dst, unsigned char *dsta,
|
||||
const unsigned char *src, int src_ofs,
|
||||
unsigned char r, unsigned char g, unsigned char b,
|
||||
unsigned char alpha, int num);
|
||||
|
||||
void (*render_blit_subpixel)(unsigned char *dst, const unsigned char *src,
|
||||
unsigned char r, unsigned char g, unsigned char b, unsigned char a,
|
||||
int num);
|
||||
|
@ -142,6 +150,8 @@ typedef struct draw_info_s
|
|||
#define RENDER_BLIT_MONO_OPAQUE DI.render_blit_mono_opaque
|
||||
#define RENDER_BLIT_ALPHA DI.render_blit_alpha
|
||||
#define RENDER_BLIT_MONO DI.render_blit_mono
|
||||
#define RENDER_BLIT_ALPHA_A DI.render_blit_alpha_a
|
||||
#define RENDER_BLIT_MONO_A DI.render_blit_mono_a
|
||||
|
||||
void artcontext_setup_draw_info(draw_info_t *di,
|
||||
unsigned int red_mask, unsigned int green_mask, unsigned int blue_mask,
|
||||
|
|
|
@ -81,8 +81,6 @@ some cases).
|
|||
#define MPRE(r) M2PRE(r, FORMAT_INSTANCE)
|
||||
|
||||
|
||||
/* TODO: these need versions for destination alpha */
|
||||
|
||||
static void MPRE(blit_alpha_opaque) (unsigned char *adst,
|
||||
const unsigned char *asrc,
|
||||
unsigned char r, unsigned char g, unsigned char b, int num)
|
||||
|
@ -221,6 +219,81 @@ static void MPRE(blit_mono) (unsigned char *adst,
|
|||
}
|
||||
|
||||
|
||||
static void MPRE(blit_alpha_a) (unsigned char *adst, unsigned char *dsta,
|
||||
const unsigned char *asrc,
|
||||
unsigned char r, unsigned char g, unsigned char b, unsigned char a_alpha,
|
||||
int num)
|
||||
{
|
||||
const unsigned char *src = asrc;
|
||||
BLEND_TYPE *dst = (BLEND_TYPE *)adst;
|
||||
int a, nr, ng, nb, na;
|
||||
int alpha = a_alpha;
|
||||
|
||||
if (alpha>127) alpha++;
|
||||
|
||||
for (; num; num--, src++)
|
||||
{
|
||||
a = *src;
|
||||
if (!a)
|
||||
{
|
||||
ALPHA_INC(dst, dsta)
|
||||
continue;
|
||||
}
|
||||
a *= alpha;
|
||||
BLEND_READ_ALPHA(dst, dsta, nr, ng, nb, na)
|
||||
nr = (r * a + nr * (65280 - a) + 0xff00) >> 16;
|
||||
ng = (g * a + ng * (65280 - a) + 0xff00) >> 16;
|
||||
nb = (b * a + nb * (65280 - a) + 0xff00) >> 16;
|
||||
na = ((a << 8) + na * (65280 - a) + 0xff00) >> 16;
|
||||
BLEND_WRITE_ALPHA(dst, dsta, nr, ng, nb, na)
|
||||
ALPHA_INC(dst, dsta)
|
||||
}
|
||||
}
|
||||
|
||||
static void MPRE(blit_mono_a) (unsigned char *adst, unsigned char *dsta,
|
||||
const unsigned char *src, int src_ofs,
|
||||
unsigned char r, unsigned char g, unsigned char b, unsigned char alpha,
|
||||
int num)
|
||||
{
|
||||
BLEND_TYPE *dst = (BLEND_TYPE *)adst;
|
||||
int i, nr, ng, nb;
|
||||
unsigned char s;
|
||||
int a;
|
||||
|
||||
a = alpha;
|
||||
if (a>127) a++;
|
||||
|
||||
s = *src++;
|
||||
i = src_ofs;
|
||||
while (src_ofs--) s <<= 1;
|
||||
|
||||
for (; num; num--)
|
||||
{
|
||||
if (s&0x80)
|
||||
{
|
||||
BLEND_READ(dst, nr, ng, nb)
|
||||
nr = (r * a + nr * (255 - a) + 0xff) >> 8;
|
||||
ng = (g * a + ng * (255 - a) + 0xff) >> 8;
|
||||
nb = (b * a + nb * (255 - a) + 0xff) >> 8;
|
||||
BLEND_WRITE(dst, nr, ng, nb)
|
||||
BLEND_INC(dst)
|
||||
}
|
||||
else
|
||||
{
|
||||
BLEND_INC(dst)
|
||||
}
|
||||
i++;
|
||||
if (i == 8)
|
||||
{
|
||||
s = *src++;
|
||||
i = 0;
|
||||
}
|
||||
else
|
||||
s <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void MPRE(blit_subpixel) (unsigned char *adst, const unsigned char *asrc,
|
||||
unsigned char r, unsigned char g, unsigned char b, unsigned char a,
|
||||
int num)
|
||||
|
@ -1548,6 +1621,8 @@ static draw_info_t draw_infos[DI_NUM] = {
|
|||
NPRE(blit_mono_opaque,x), \
|
||||
NPRE(blit_alpha,x), \
|
||||
NPRE(blit_mono,x), \
|
||||
NPRE(blit_alpha_a,x), \
|
||||
NPRE(blit_mono_a,x), \
|
||||
\
|
||||
NPRE(blit_subpixel,x), \
|
||||
\
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
at: (int)x : (int)y
|
||||
to: (int)x0 : (int)y0 : (int)x1 : (int)y1
|
||||
: (unsigned char *)buf : (int)bpl
|
||||
: (unsigned char *)abuf : (int)abpl
|
||||
color: (unsigned char)r : (unsigned char)g : (unsigned char)b
|
||||
: (unsigned char)alpha
|
||||
transform: (NSAffineTransform *)transform
|
||||
|
|
|
@ -725,7 +725,9 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
|
||||
-(void) drawString: (const char *)s
|
||||
at: (int)x : (int)y
|
||||
to: (int)x0 : (int)y0 : (int)x1 : (int)y1 : (unsigned char *)buf : (int)bpl
|
||||
to: (int)x0 : (int)y0 : (int)x1 : (int)y1
|
||||
: (unsigned char *)buf : (int)bpl
|
||||
: (unsigned char *)abuf : (int)abpl
|
||||
color:(unsigned char)r : (unsigned char)g : (unsigned char)b : (unsigned char)alpha
|
||||
transform: (NSAffineTransform *)transform
|
||||
drawinfo: (draw_info_t *)di
|
||||
|
@ -1061,6 +1063,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
int sx = gb->bitmap.width, sy = gb->bitmap.rows;
|
||||
const unsigned char *src = gb->bitmap.buffer;
|
||||
unsigned char *dst = buf;
|
||||
unsigned char *dsta = abuf;
|
||||
|
||||
if (gy < 0)
|
||||
{
|
||||
|
@ -1071,6 +1074,8 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
else if (gy > 0)
|
||||
{
|
||||
dst += bpl * gy;
|
||||
if (dsta)
|
||||
dsta += abpl * gy;
|
||||
}
|
||||
|
||||
sy += gy;
|
||||
|
@ -1086,6 +1091,8 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
else if (gx > 0)
|
||||
{
|
||||
dst += DI.bytes_per_pixel * gx;
|
||||
if (dsta)
|
||||
dsta += gx;
|
||||
}
|
||||
|
||||
sx += gx;
|
||||
|
@ -1095,7 +1102,10 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib, FT_Pointer data, FT_
|
|||
|
||||
if (sx > 0)
|
||||
{
|
||||
if (alpha >= 255)
|
||||
if (dsta)
|
||||
for (; gy < sy; gy++, src += sbpl, dst += bpl, dsta += abpl)
|
||||
RENDER_BLIT_ALPHA_A(dst, dsta, src, r, g, b, alpha, sx);
|
||||
else if (alpha >= 255)
|
||||
for (; gy < sy; gy++, src += sbpl, dst += bpl)
|
||||
RENDER_BLIT_ALPHA_OPAQUE(dst, src, r, g, b, sx);
|
||||
else
|
||||
|
@ -1992,17 +2002,15 @@ static int filters[3][7]=
|
|||
/* TODO: this whole thing needs cleaning up */
|
||||
@implementation FTFontInfo_subpixel
|
||||
|
||||
-(void) drawString: (const char *)s
|
||||
-(void) drawGlyphs: (const NSGlyph *)glyphs : (int)length
|
||||
at: (int)x : (int)y
|
||||
to: (int)x0 : (int)y0 : (int)x1 : (int)y1 : (unsigned char *)buf : (int)bpl
|
||||
color:(unsigned char)r : (unsigned char)g : (unsigned char)b : (unsigned char)alpha
|
||||
to: (int)x0 : (int)y0 : (int)x1 : (int)y1
|
||||
: (unsigned char *)buf : (int)bpl
|
||||
color: (unsigned char)r : (unsigned char)g : (unsigned char)b
|
||||
: (unsigned char)alpha
|
||||
transform: (NSAffineTransform *)transform
|
||||
drawinfo: (draw_info_t *)di
|
||||
drawinfo: (struct draw_info_s *)di
|
||||
{
|
||||
const unsigned char *c;
|
||||
unsigned char ch;
|
||||
unsigned int uch;
|
||||
|
||||
FTC_CMapDescRec cmap;
|
||||
unsigned int glyph;
|
||||
|
||||
|
@ -2016,7 +2024,6 @@ static int filters[3][7]=
|
|||
|
||||
BOOL subpixel = NO;
|
||||
|
||||
|
||||
if (!alpha)
|
||||
return;
|
||||
|
||||
|
@ -2091,70 +2098,9 @@ static int filters[3][7]=
|
|||
cmap.u.encoding = ft_encoding_unicode;
|
||||
cmap.type = FTC_CMAP_BY_ENCODING;
|
||||
|
||||
for (c = s; *c; c++)
|
||||
for (; length; length--, glyphs++)
|
||||
{
|
||||
/* TODO: do the same thing in outlineString:... */
|
||||
ch = *c;
|
||||
if (ch < 0x80)
|
||||
{
|
||||
uch = ch;
|
||||
}
|
||||
else if (ch < 0xc0)
|
||||
{
|
||||
uch = 0xfffd;
|
||||
}
|
||||
else if (ch < 0xe0)
|
||||
{
|
||||
#define ADD_UTF_BYTE(shift, internal) \
|
||||
ch = *++c; \
|
||||
if (ch >= 0x80 && ch < 0xc0) \
|
||||
{ \
|
||||
uch |= (ch & 0x3f) << shift; \
|
||||
internal \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
uch = 0xfffd; \
|
||||
c--; \
|
||||
}
|
||||
|
||||
uch = (ch & 0x1f) << 6;
|
||||
ADD_UTF_BYTE(0, )
|
||||
}
|
||||
else if (ch < 0xf0)
|
||||
{
|
||||
uch = (ch & 0x0f) << 12;
|
||||
ADD_UTF_BYTE(6, ADD_UTF_BYTE(0, ))
|
||||
}
|
||||
else if (ch < 0xf8)
|
||||
{
|
||||
uch = (ch & 0x07) << 18;
|
||||
ADD_UTF_BYTE(12, ADD_UTF_BYTE(6, ADD_UTF_BYTE(0, )))
|
||||
}
|
||||
else if (ch < 0xfc)
|
||||
{
|
||||
uch = (ch & 0x03) << 24;
|
||||
ADD_UTF_BYTE(18, ADD_UTF_BYTE(12, ADD_UTF_BYTE(6, ADD_UTF_BYTE(0, ))))
|
||||
}
|
||||
else if (ch < 0xfe)
|
||||
{
|
||||
uch = (ch & 0x01) << 30;
|
||||
ADD_UTF_BYTE(24, ADD_UTF_BYTE(18, ADD_UTF_BYTE(12, ADD_UTF_BYTE(6, ADD_UTF_BYTE(0, )))))
|
||||
}
|
||||
else
|
||||
uch = 0xfffd;
|
||||
#undef ADD_UTF_BYTE
|
||||
|
||||
glyph = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, uch);
|
||||
cur.font.face_id = imgd.font.face_id;
|
||||
if (!glyph)
|
||||
{
|
||||
cmap.face_id = fallback.font.face_id;
|
||||
glyph = FTC_CMapCache_Lookup(ftc_cmapcache, &cmap, uch);
|
||||
if (glyph)
|
||||
cur.font.face_id = fallback.font.face_id;
|
||||
cmap.face_id = imgd.font.face_id;
|
||||
}
|
||||
glyph = *glyphs - 1;
|
||||
|
||||
if (use_sbit)
|
||||
{
|
||||
|
|
|
@ -560,7 +560,7 @@ seem to cause edges to be off by a pixel
|
|||
|
||||
ox = [matrix transformPoint: NSMakePoint(0, 0)].x;
|
||||
oy = wi->sy - [matrix transformPoint: NSMakePoint(0, 0)].y - pixelsHigh;
|
||||
|
||||
|
||||
for (y = 0; y < pixelsHigh; y++)
|
||||
{
|
||||
for (x = 0; x < pixelsWide; x++)
|
||||
|
|
Loading…
Reference in a new issue