mirror of
https://github.com/gnustep/libs-back.git
synced 2025-04-22 15:31:14 +00:00
2005-01-11 20:27 Alexander Malmberg <alexander@malmberg.org>
* Source/art/ARTGState.h: Add strokeadjust ivar. * Source/art/ARTContext.m (-DPScurrentstrokeadjust) (-DPSsetstrokeadjust): Use the strokeadjust ivar. * Source/art/path.m (-DPSrectclip::::): Don't use the optimized path if the clipping path is complex. (-_stroke::): Remove second argument, rename to ... (-_stroke:): ... this. If strokeadjust is active, adjust the path to make it clearer. (-DPSrectstroke::::): Update _stroke::: call. Remove dash adjustment code. (-DPSstroke): Update _stroke:: call. * Source/art/composite.m: Fix comment typo. Remove some old debugging code. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/trunk@20536 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
621e1fc4ef
commit
6582a61927
5 changed files with 202 additions and 40 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2005-01-11 20:27 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
* Source/art/ARTGState.h: Add strokeadjust ivar.
|
||||
* Source/art/ARTContext.m (-DPScurrentstrokeadjust)
|
||||
(-DPSsetstrokeadjust): Use the strokeadjust ivar.
|
||||
* Source/art/path.m (-DPSrectclip::::): Don't use the optimized
|
||||
path if the clipping path is complex.
|
||||
(-_stroke::): Remove second argument, rename to ...
|
||||
(-_stroke:): ... this. If strokeadjust is active, adjust the path
|
||||
to make it clearer.
|
||||
(-DPSrectstroke::::): Update _stroke::: call. Remove dash adjustment
|
||||
code.
|
||||
(-DPSstroke): Update _stroke:: call.
|
||||
* Source/art/composite.m: Fix comment typo. Remove some old
|
||||
debugging code.
|
||||
|
||||
2005-01-11 16:15 Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
* Source/art/blit.m: Remove #warning:s.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
Author: Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
|
@ -420,12 +420,6 @@ very expensive
|
|||
*limit=miter_limit;
|
||||
}
|
||||
|
||||
- (void) DPScurrentstrokeadjust: (int*)b
|
||||
{
|
||||
/* TODO We never stroke-adjust, see DPSsetstrokeadjust. */
|
||||
*b=0;
|
||||
}
|
||||
|
||||
- (void) DPSsetdash: (const float*)pat : (int)size : (float)offs
|
||||
{
|
||||
int i;
|
||||
|
@ -505,13 +499,15 @@ very expensive
|
|||
miter_limit=limit;
|
||||
}
|
||||
|
||||
|
||||
- (void) DPScurrentstrokeadjust: (int*)b
|
||||
{
|
||||
*b = strokeadjust;
|
||||
}
|
||||
|
||||
- (void) DPSsetstrokeadjust: (int)b
|
||||
{
|
||||
/* Since we anti-alias stroke-adjustment isn't really applicable.
|
||||
TODO:
|
||||
However, it might be useful to handle stroke-adjusting by snapping
|
||||
to whole pixels when rendering to avoid anti-aliasing of rectangles
|
||||
and straight lines. */
|
||||
strokeadjust = b;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
|
||||
Author: Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
|
@ -53,6 +53,7 @@
|
|||
float line_width;
|
||||
int linecapstyle,linejoinstyle;
|
||||
float miter_limit;
|
||||
BOOL strokeadjust;
|
||||
|
||||
struct _ArtVpathDash dash;
|
||||
int do_dash;
|
||||
|
|
|
@ -454,12 +454,6 @@ static BOOL _rect_advance(rect_trace_t *t, int *x0, int *x1)
|
|||
if (all_clipped) return;
|
||||
|
||||
|
||||
/* NSLog(@"composite op=%i (%g %g)+(%g %g)->(%g %g)",op,
|
||||
aRect.origin.x,aRect.origin.y,
|
||||
aRect.size.width,aRect.size.height,
|
||||
aPoint.x,aPoint.y);*/
|
||||
|
||||
|
||||
{
|
||||
BOOL dst_needs_alpha;
|
||||
op = [self _composite_func: !ags->wi->has_alpha : NO
|
||||
|
@ -870,7 +864,6 @@ static BOOL _rect_advance(rect_trace_t *t, int *x0, int *x1)
|
|||
if (!wi || !wi->data || !ags->wi || !ags->wi->data) return;
|
||||
if (all_clipped) return;
|
||||
|
||||
|
||||
/* Set up all the pointers and clip things */
|
||||
|
||||
dbpl = wi->bytes_per_line;
|
||||
|
@ -1031,7 +1024,7 @@ static BOOL _rect_advance(rect_trace_t *t, int *x0, int *x1)
|
|||
}
|
||||
}
|
||||
|
||||
/* this breaks the alpha pointer in some, but that's ok since in
|
||||
/* this breaks the alpha pointer in some cases, but that's ok since in
|
||||
all those cases, the alpha pointer isn't used (inline alpha or
|
||||
no alpha) */
|
||||
if (order == 2)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
|
||||
Author: Alexander Malmberg <alexander@malmberg.org>
|
||||
|
||||
|
@ -43,6 +43,29 @@ Path handling.
|
|||
|
||||
#if 0
|
||||
/* useful when debugging */
|
||||
static void dump_vpath(ArtVpath *vp)
|
||||
{
|
||||
int i;
|
||||
printf("** dumping %p **\n", vp);
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
if (vp[i].code == ART_MOVETO_OPEN)
|
||||
printf(" moveto_open");
|
||||
else if (vp[i].code == ART_MOVETO)
|
||||
printf(" moveto");
|
||||
else if (vp[i].code == ART_LINETO)
|
||||
printf(" lineto");
|
||||
else if (vp[i].code == ART_END)
|
||||
printf(" end");
|
||||
else
|
||||
printf(" unknown %i", vp[i].code);
|
||||
|
||||
printf(" (%g %g)\n",
|
||||
vp[i].x, vp[i].y);
|
||||
if (vp[i].code == ART_END)
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void dump_bpath(ArtBpath *vp)
|
||||
{
|
||||
int i;
|
||||
|
@ -823,7 +846,7 @@ static void clip_svp_callback(void *data, int y, int start,
|
|||
axis: &x0 : &y0 : &x1 : &y1
|
||||
pixel: NO];
|
||||
|
||||
if (!axis_aligned)
|
||||
if (!axis_aligned || clip_span)
|
||||
{
|
||||
svp = art_svp_from_vpath(vp);
|
||||
[self _clip_add_svp: svp];
|
||||
|
@ -1035,12 +1058,14 @@ static void clip_svp_callback(void *data, int y, int start,
|
|||
/** Stroking **/
|
||||
|
||||
/* will free the passed in vpath */
|
||||
-(void) _stroke: (ArtVpath *)vp : (BOOL)adjust_dash_ofs
|
||||
-(void) _stroke: (ArtVpath *)vp
|
||||
{
|
||||
double temp_scale;
|
||||
ArtVpath *vp2;
|
||||
ArtSVP *svp;
|
||||
|
||||
float dash_adjust;
|
||||
|
||||
|
||||
/* TODO: this is a hack, but it's better than nothing */
|
||||
/* since we flip vertically, the signs here should really be
|
||||
inverted, but the fabs() means that it doesn't matter */
|
||||
|
@ -1048,14 +1073,155 @@ static void clip_svp_callback(void *data, int y, int start,
|
|||
ctm->matrix.m12 * ctm->matrix.m21));
|
||||
if (temp_scale <= 0) temp_scale = 1;
|
||||
|
||||
|
||||
/*
|
||||
If stroke-adjusting (or something equivalent) is active, we want to adjust
|
||||
the path so it will turn out nice and sharp.
|
||||
|
||||
To do this, we round the line width to the closest integer width. To get
|
||||
sharp lines, we then want each pixel to be at an integer coordinate, or
|
||||
an integer plus 0.5, depending on the width and a bunch of other things.
|
||||
*/
|
||||
if (strokeadjust
|
||||
|
||||
/* No point trying to adjust width 0 lines. (if they were implemented
|
||||
properly) */
|
||||
&& line_width > 0
|
||||
|
||||
/* Nor if the path is empty. */
|
||||
&& vp[0].code != ART_END)
|
||||
{
|
||||
int i;
|
||||
|
||||
int effective_width = rint(temp_scale * line_width);
|
||||
float ofs;
|
||||
|
||||
int last_move;
|
||||
|
||||
/* Paths with more elements than this won't be adjusted. */
|
||||
#define MAX_LEN 1024
|
||||
unsigned char flags[MAX_LEN];
|
||||
/*
|
||||
1 start of vertical line
|
||||
2 start of horizontal line
|
||||
4 end-point on vertical line
|
||||
8 end-point on horizontal line
|
||||
*/
|
||||
|
||||
temp_scale = effective_width / line_width;
|
||||
|
||||
if (effective_width & 1)
|
||||
ofs = 0.5;
|
||||
else
|
||||
ofs = 0.0;
|
||||
|
||||
last_move = 0;
|
||||
/* TODO: use epsilons instead of exact comparisons? makes rounding
|
||||
a huge mess. */
|
||||
flags[0] = 0;
|
||||
for (i = 1; i < MAX_LEN; i++)
|
||||
{
|
||||
flags[i] = 0;
|
||||
/* If this is a closed sub-path, consider the line from the last
|
||||
element to the moveto. */
|
||||
if (vp[i].code != ART_LINETO)
|
||||
{
|
||||
if (vp[last_move].code == ART_MOVETO)
|
||||
{
|
||||
if (vp[i - 1].x == vp[last_move].x)
|
||||
{
|
||||
flags[i - 1] |= 1;
|
||||
flags[last_move] |= 1;
|
||||
}
|
||||
if (vp[i - 1].y == vp[last_move].y)
|
||||
{
|
||||
flags[i - 1] |= 2;
|
||||
flags[last_move] |= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags[last_move] & 1)
|
||||
flags[last_move] |= 4;
|
||||
if (flags[last_move] & 2)
|
||||
flags[last_move] |= 8;
|
||||
|
||||
if (flags[i - 1] & 1)
|
||||
flags[i - 1] |= 4;
|
||||
if (flags[i - 1] & 2)
|
||||
flags[i - 1] |= 8;
|
||||
}
|
||||
}
|
||||
|
||||
if (vp[i].code == ART_END)
|
||||
break;
|
||||
|
||||
if (vp[i].code == ART_MOVETO
|
||||
|| vp[i].code == ART_MOVETO_OPEN)
|
||||
{
|
||||
last_move = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vp[i - 1].x == vp[i].x)
|
||||
{
|
||||
flags[i - 1] |= 1;
|
||||
flags[i] |= 1;
|
||||
}
|
||||
if (vp[i - 1].y == vp[i].y)
|
||||
{
|
||||
flags[i - 1] |= 2;
|
||||
flags[i] |= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i < MAX_LEN)
|
||||
{
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
if (vp[i].code == ART_END)
|
||||
break;
|
||||
if (flags[i] & 1)
|
||||
vp[i].x = floorf(vp[i].x) + ofs;
|
||||
else if (flags[i] & 8)
|
||||
vp[i].x = floorf(vp[i].x + 0.5);
|
||||
if (flags[i] & 2)
|
||||
vp[i].y = floorf(vp[i].y) + ofs;
|
||||
else if (flags[i] & 4)
|
||||
vp[i].y = floorf(vp[i].y + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to line an integer dash offset up on a pixel boundary near
|
||||
the first point. (Safe because we know the path isn't empty
|
||||
at this point.) */
|
||||
dash_adjust = 0.0;
|
||||
if (vp[1].code == ART_LINETO)
|
||||
{
|
||||
if (fabs(vp[0].x - vp[1].x) < 0.1)
|
||||
dash_adjust = rint(vp[0].y) - vp[0].y;
|
||||
else if (fabs(vp[0].y - vp[1].y) < 0.1)
|
||||
dash_adjust = rint(vp[0].x) - vp[0].x;
|
||||
}
|
||||
#undef MAX_LEN
|
||||
}
|
||||
else
|
||||
{
|
||||
dash_adjust = 0.0;
|
||||
}
|
||||
|
||||
|
||||
if (do_dash)
|
||||
{
|
||||
/* try to adjust the offset so dashes appear on pixel boundaries
|
||||
(otherwise it turns into an antialiased blur) */
|
||||
int i;
|
||||
float old_offset = dash.offset;
|
||||
ArtVpath *vp2;
|
||||
|
||||
if (adjust_dash_ofs)
|
||||
dash.offset += (((int)line_width) & 1) / 2.0;
|
||||
if (!dash.offset)
|
||||
dash.offset += dash_adjust;
|
||||
|
||||
for (i = 0; i < dash.n_dash; i++)
|
||||
dash.dash[i] *= temp_scale;
|
||||
|
@ -1067,8 +1233,7 @@ static void clip_svp_callback(void *data, int y, int start,
|
|||
art_free(vp);
|
||||
vp = vp2;
|
||||
|
||||
if (adjust_dash_ofs)
|
||||
dash.offset -= (((int)line_width) & 1) / 2.0;
|
||||
dash.offset = old_offset;
|
||||
}
|
||||
|
||||
svp = art_svp_vpath_stroke(vp, linejoinstyle, linecapstyle,
|
||||
|
@ -1097,15 +1262,6 @@ static void clip_svp_callback(void *data, int y, int start,
|
|||
|
||||
vp = art_new(ArtVpath, 6);
|
||||
|
||||
if (line_width == (int)line_width && ((int)line_width) & 1)
|
||||
{ /* TODO: only do this if stroke-adjust is on? */
|
||||
/* TODO: check coordinates to see how much we should adjust */
|
||||
x += 0.5;
|
||||
y += 0.5;
|
||||
w -= 1;
|
||||
h -= 1;
|
||||
}
|
||||
|
||||
vp[0].code = ART_MOVETO;
|
||||
vp[0].x = x; vp[0].y = y;
|
||||
|
||||
|
@ -1135,7 +1291,7 @@ static void clip_svp_callback(void *data, int y, int start,
|
|||
art_free(vp);
|
||||
vp = vp2;
|
||||
|
||||
[self _stroke: vp : YES];
|
||||
[self _stroke: vp];
|
||||
}
|
||||
|
||||
- (void) DPSstroke
|
||||
|
@ -1177,7 +1333,7 @@ will give correct results as long as both axises are scaled the same.
|
|||
if (!vp)
|
||||
return;
|
||||
|
||||
[self _stroke: vp : NO];
|
||||
[self _stroke: vp];
|
||||
|
||||
[path removeAllPoints];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue