Open GoogleCodeExporter opened 9 years ago
Hi,
Are we talking about the white lines in pattern and small white patterns in
gradients? I see the issue and I'd like to catch it.
Thank you!
Original comment by kobalicek.petr
on 24 Nov 2010 at 9:01
Yes, I am talking about those white lines.
In AGG 2.4 had this same problem but then AGG 2.5 was released, the image fill
was fixed.
In AGG, I was able to create span generators which was useful for creating
shading patterns that were truely smooth filled (no color stops). See attached
example below: Is this possible with FOG-GRAPHICS?
//==========================================================span_gradient
template<class ColorT,
class Interpolator,
class Allocator = span_allocator<ColorT> >
class span_radial_shading : public agg::span_generator<ColorT, Allocator>
{
public:
typedef Interpolator interpolator_type;
typedef Allocator alloc_type;
typedef ColorT color_type;
typedef agg::span_generator<color_type, alloc_type> base_type;
GfxState *m_gfxstate ;
GfxRadialShading *m_shading ;
AggClip *m_pClip ;
double xMin, yMin, xMax, yMax ;
double x0, y0, r0, x1, y1, r1 ;
double t0, t1 ;
double tMin, tMax ;
double dx, dy, dr ;
double C ;
double c0_c1 ;
double r1_2 ;
int aligned_circles ;
bool bExtend0 ;
bool bExtend1 ;
//--------------------------------------------------------------------
span_radial_shading(alloc_type& alloc) : base_type(alloc) {}
//--------------------------------------------------------------------
span_radial_shading(alloc_type& alloc,
interpolator_type& inter,
AggClip *pClip,
GfxState *gfxstate,
GfxRadialShading *shading ) :
base_type(alloc),
m_interpolator(&inter)
{
m_pClip = pClip ;
m_gfxstate = gfxstate ;
m_shading = shading ;
// get the clip region bbox
gfxstate->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
// compute min and max t values, based on the four corners of the
// clip region bbox
m_shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1 );
dx = x1 - x0;
dy = y1 - y0;
dr = r1 - r0 ;
C = dx*dx + dy*dy - dr*dr ;
// get the function domain
t0 = shading->getDomain0();
t1 = shading->getDomain1();
x1 = x0 ;
if (x0 != x1 || y0 != y1) {
aligned_circles = 0;
dx = x1 - x0;
dy = y1 - y0;
c0_c1 = sqrt (dx * dx + dy * dy);
r1_2 = r1 * r1;
} else {
aligned_circles = 1;
r1 = 1.0 / (r1 - r0);
r1_2 = c0_c1 = 0.0; /* shut up compiler */
}
bExtend0 = shading->getExtend0() != gFalse ;
bExtend1 = shading->getExtend1() != gFalse ;
}
//--------------------------------------------------------------------
interpolator_type& interpolator() { return *m_interpolator; }
//--------------------------------------------------------------------
void interpolator(interpolator_type& i) { m_interpolator = &i; }
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
color_type* span = base_type::allocator().span();
m_interpolator->begin(x+0.5, y+0.5, len);
do
{
// Compute the color at x and y for this shading function!!
m_interpolator->coordinates(&x, &y); // Map x and y between x0,y0 and x1,y1
double posx = x / 256.0 ;
double posy = y / 256.0;
double px = posx;
double py = posy ;
/* transform fragment into pattern space!! */
// double ex = a * px + c * py + tx;
// double ey = b * px + d * py + ty;
double ex = px;
double ey = py;
double factor ;
// Rotate ex, ey so that circles are aligned!!
// the calculate factor
if ( ! aligned_circles ) {
//x1 = x0 and y1 = y0
agg::trans_affine mtx ;
mtx *= agg::trans_affine_translation( -x0, -y0 ) ;
// mtx *= agg::trans_affine_rotation( ) ;
mtx *= agg::trans_affine_translation( x0, y0 ) ;
}
// this works only if c0 is inside c1 !!!
if (aligned_circles) {
ex = ex - x1;
ey = ey - y1;
factor = (sqrt (ex * ex + ey * ey) - r0) * r1;
} else {
/*
y (ex, ey)
c0 -------------------+---------- x
\ | __--
\ | __--
\ | __--
\ | __-- r1
\ | __--
c1 --
We need to calulate distance c0->x; the distance from
the inner circle center c0, through fragment position
(ex, ey) to point x where it crosses the outer circle.
From points c0, c1 and (ex, ey) we get angle C0. With
angle C0 we calculate distance c1->y and c0->y and by
knowing c1->y and r1, we also know y->x. Adding y->x to
c0->y gives us c0->x. The gradient offset can then be
calculated as:
offset = (c0->e - r0) / (c0->x - r0)
*/
double c0_e_x, c0_e_y, c0_e, c1_e_x, c1_e_y, c1_e ;
double angle_c0 ;
double c1_y, y_x, c0_y, c0_x ;
double denumerator ;
double fraction ;
c0_e_x = ex - x0;
c0_e_y = ey - y0;
c0_e = sqrt (c0_e_x * c0_e_x + c0_e_y * c0_e_y);
c1_e_x = ex - x1;
c1_e_y = ey - y1;
c1_e = sqrt (c1_e_x * c1_e_x + c1_e_y * c1_e_y);
denumerator = -2.0 * c0_e * c0_c1;
if (denumerator != 0.0) {
fraction = (c1_e * c1_e - c0_e * c0_e - c0_c1 * c0_c1) / denumerator;
if (fraction > 1.0)
fraction = 1.0;
else if (fraction < -1.0)
fraction = -1.0;
angle_c0 = acos (fraction);
c0_y = cos (angle_c0) * c0_c1 ;
c1_y = sin (angle_c0) * c0_c1 ;
y_x = sqrt (r1_2 - c1_y * c1_y);
c0_x = y_x + c0_y;
if ( c0_y > 0 )
factor = (c0_e - r0) / (c0_x - r0);
else
factor = 0 ;
} else {
factor = -r0;
}
}
double t = t0 + factor * (t1 - t0) ;
if ( t < t0 ) {
if ( ! bExtend0 )
t = -1 ;
else
t = t0 ;
} else if ( t > t1 ) {
if ( ! bExtend1 )
t = -1 ;
else
t = t1 ;
}
if ( t < 0 ) {
// Not colored - set to white with no alpha?
*span++ = (color_type)(agg::rgba8(0, 255, 0 ,255 )) ;
// *span++ = (color_type)(agg::rgba8(255, 255, 255 ,0 )) ;
} else {
GfxColor color0 ;
m_shading->getColor( t, &color0 ) ;
m_gfxstate->setFillColor(&color0);
GfxRGB rgb;
m_gfxstate->getFillRGB(&rgb);
*span++ = (color_type)(agg::rgba8(colToByte(rgb.r),
colToByte(rgb.g),
colToByte(rgb.b), 255 )) ;
}
++(*m_interpolator);
}
while(--len);
return base_type::allocator().span();
}
private:
interpolator_type* m_interpolator;
};
Original comment by marietta...@peernet.com
on 24 Nov 2010 at 10:11
Hi Marietta,
This issue is not related to the AGG, because span fillers were written from
the scratch. I think that it's only minor issue, I will catch it.
And about your code, I don't know what it does, do you have some example of it?
(I mean image rendered through it).
Thanks!
Petr
Original comment by kobalicek.petr
on 24 Nov 2010 at 10:42
Code above show a sample of radial shading operator for PDF and Postscript.
I have similar code for axial shading operator for PDF and Postscript.
The result it true smooth shading and any resolution.
This is not to say color stop based gradients can not simulate smooth shading
so I have to expriement with this style of fill to get a better understanding
of them and how they related to PDF and Postscript smooth fill operators.
Original comment by marietta...@peernet.com
on 25 Nov 2010 at 12:50
Attachments:
Hi Marietta,
this type of gradient can be rendered using two color stops at [0.0 and 1.0].
The only thing that is not supported at this time is radius of inner circle
(starting at focal point) and selecting background color (when SPREAD_NONE is
used).
I don't know if I add support for inner circle radius, but the background color
will be implemented in future versions of Fog-Framework (for all patterns).
Maybe the inner circle radius will be added too, but at this time I have not
done mathematics for this.
Original comment by kobalicek.petr
on 26 Nov 2010 at 7:45
It's not that simple for the color as the shading dictionary in PDF is a
function returns color values based on the value of t. You need to read the
attached technical note to understand what I am saming.
Also, it is in the PDF Reference guide.
To further mess us all up they also allow patterns to be one size but move in a
specified step so pattern fills are not steps are not always one to one with
the pattern size. This is also a feature the tends never to be part of any
graphics library and has to be emmulated using other techniques.
By the way I am Robert Massart, just we use only one Google account.
Petr, thanks for your looking at this.
Original comment by marietta...@peernet.com
on 26 Nov 2010 at 2:06
Attachments:
I optimized the shaded fill to use linear gradient fill with color stops but if
you skew the transform as shown in upper left you get all blue and not the red
to blue fill as expected.
Original comment by marietta...@peernet.com
on 26 Nov 2010 at 9:02
Attachments:
If may understanding is correct about radial, you do not have an equivalent for:
cairo_pattern_t *
cairo_pattern_create_radial (double cx0, double cy0, double radius0,
double cx1, double cy1, double radius1)
Original comment by marietta...@peernet.com
on 26 Nov 2010 at 9:34
Hi Robert,
Sorry for delay.
I can confirm that there is no equivalent to cairo_pattern_create_radial in
Fog, but that version would be useful in the future (I'd like to make my best
for compatibility with other libs).
I can also confirm that when affine transform is used and it's skew then
gradient rendering is not correct, this will be fixed of course by new painter
architecture. Maybe this is your problem at this time.
BTW: Currently Fog doesn't allow to create color interpolator based on
function, but when shaders will be complete I think that it will be possible
(but this is long-time feature).
Accepting as "gradient transform issue". Thank You!
Original comment by kobalicek.petr
on 9 Dec 2010 at 5:49
Any update on when the new painter update will be available?
I know it's tricky business but I am trying to plan whether to proceed with fog
or go another route
Original comment by marietta...@peernet.com
on 8 Jan 2011 at 2:25
Hi Robert,
I'm still working on it, the only thing that remains is the raster-painter
engine, everything else is refactorized/compilable. I know that my work is
slow, but please be patient;)
Original comment by kobalicek.petr
on 12 Jan 2011 at 1:08
Any idea at this point when you might be ready for us to start testing your
changes?
Original comment by marietta...@peernet.com
on 1 Feb 2011 at 1:56
Hi Robert,
7 days? I'm getting closer! Thanks for your patience;)
Original comment by kobalicek.petr
on 5 Feb 2011 at 1:57
Any Luck?
Original comment by marietta...@peernet.com
on 18 Feb 2011 at 1:51
I'm making my best, really
Original comment by kobalicek.petr
on 22 Feb 2011 at 11:25
I know, but is there nothing I can do to help?
Original comment by marietta...@peernet.com
on 24 Feb 2011 at 1:15
Original issue reported on code.google.com by
marietta...@peernet.com
on 23 Nov 2010 at 5:45Attachments: