Improve transparency handling while plotting.
Only SVG can actually handle transparency, but we should at least mimic the color value of other transparent fills by blending with a (presumed) white paper. Fixes https://gitlab.com/kicad/code/kicad/issues/11304
This commit is contained in:
parent
702623ef87
commit
079d4a603a
|
@ -159,9 +159,19 @@ void PDF_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
|
|||
}
|
||||
|
||||
|
||||
void PDF_PLOTTER::emitSetRGBColor( double r, double g, double b )
|
||||
void PDF_PLOTTER::emitSetRGBColor( double r, double g, double b, double a )
|
||||
{
|
||||
wxASSERT( workFile );
|
||||
|
||||
// PDF treats all colors as opaque, so the best we can do with alpha is generate an
|
||||
// appropriate blended color assuming white paper.
|
||||
if( a < 1.0 )
|
||||
{
|
||||
r = ( r * a ) + ( 1 - a );
|
||||
g = ( g * a ) + ( 1 - a );
|
||||
b = ( b * a ) + ( 1 - a );
|
||||
}
|
||||
|
||||
fprintf( workFile, "%g %g %g rg %g %g %g RG\n", r, g, b, r, g, b );
|
||||
}
|
||||
|
||||
|
|
|
@ -64,9 +64,9 @@ void PSLIKE_PLOTTER::SetColor( const COLOR4D& color )
|
|||
if( m_colorMode )
|
||||
{
|
||||
if( m_negativeMode )
|
||||
emitSetRGBColor( 1 - color.r, 1 - color.g, 1 - color.b );
|
||||
emitSetRGBColor( 1 - color.r, 1 - color.g, 1 - color.b, color.a );
|
||||
else
|
||||
emitSetRGBColor( color.r, color.g, color.b );
|
||||
emitSetRGBColor( color.r, color.g, color.b, color.a );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -80,9 +80,9 @@ void PSLIKE_PLOTTER::SetColor( const COLOR4D& color )
|
|||
k = 0;
|
||||
|
||||
if( m_negativeMode )
|
||||
emitSetRGBColor( 1 - k, 1 - k, 1 - k );
|
||||
emitSetRGBColor( 1 - k, 1 - k, 1 - k, 1.0 );
|
||||
else
|
||||
emitSetRGBColor( k, k, k );
|
||||
emitSetRGBColor( k, k, k, 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,10 +527,21 @@ void PS_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
|
|||
}
|
||||
|
||||
|
||||
void PS_PLOTTER::emitSetRGBColor( double r, double g, double b )
|
||||
void PS_PLOTTER::emitSetRGBColor( double r, double g, double b, double a )
|
||||
{
|
||||
wxASSERT( m_outputFile );
|
||||
|
||||
// Postscript treats all colors as opaque, so the best we can do with alpha is generate
|
||||
// an appropriate blended color assuming white paper. (It's possible that a halftone would
|
||||
// work better on *some* drivers, but most drivers are known to still treat halftones as
|
||||
// opaque and remove any colors underneath them.)
|
||||
if( a < 1.0 )
|
||||
{
|
||||
r = ( r * a ) + ( 1 - a );
|
||||
g = ( g * a ) + ( 1 - a );
|
||||
b = ( b * a ) + ( 1 - a );
|
||||
}
|
||||
|
||||
// XXX why %.3g ? shouldn't %g suffice? who cares...
|
||||
fprintf( m_outputFile, "%.3g %.3g %.3g setrgbcolor\n", r, g, b );
|
||||
}
|
||||
|
|
|
@ -168,6 +168,7 @@ SVG_PLOTTER::SVG_PLOTTER()
|
|||
m_fillMode = FILL_T::NO_FILL; // or FILLED_SHAPE or FILLED_WITH_BG_BODYCOLOR
|
||||
m_pen_rgb_color = 0; // current color value (black)
|
||||
m_brush_rgb_color = 0; // current color value (black)
|
||||
m_brush_alpha = 1.0;
|
||||
m_dashed = PLOT_DASH_TYPE::SOLID;
|
||||
m_useInch = false; // millimeters are always the svg unit
|
||||
m_precision = 4; // default: 4 digits in mantissa.
|
||||
|
@ -233,10 +234,14 @@ void SVG_PLOTTER::setSVGPlotStyle( bool aIsGroup, const std::string& aExtraStyle
|
|||
|
||||
switch( m_fillMode )
|
||||
{
|
||||
case FILL_T::NO_FILL: fputs( "fill-opacity:0.0; ", m_outputFile ); break;
|
||||
case FILL_T::FILLED_SHAPE: fputs( "fill-opacity:1.0; ", m_outputFile ); break;
|
||||
case FILL_T::NO_FILL:
|
||||
fputs( "fill-opacity:0.0; ", m_outputFile );
|
||||
break;
|
||||
case FILL_T::FILLED_SHAPE:
|
||||
case FILL_T::FILLED_WITH_BG_BODYCOLOR:
|
||||
case FILL_T::FILLED_WITH_COLOR: fputs( "fill-opacity:0.6; ", m_outputFile ); break;
|
||||
case FILL_T::FILLED_WITH_COLOR:
|
||||
fprintf( m_outputFile, "fill-opacity:%.*f; ", m_precision, m_brush_alpha );
|
||||
break;
|
||||
}
|
||||
|
||||
double pen_w = userToDeviceSize( GetCurrentLineWidth() );
|
||||
|
@ -342,7 +347,7 @@ void SVG_PLOTTER::EndBlock( void* aData )
|
|||
}
|
||||
|
||||
|
||||
void SVG_PLOTTER::emitSetRGBColor( double r, double g, double b )
|
||||
void SVG_PLOTTER::emitSetRGBColor( double r, double g, double b, double a )
|
||||
{
|
||||
int red = (int) ( 255.0 * r );
|
||||
int green = (int) ( 255.0 * g );
|
||||
|
@ -356,6 +361,7 @@ void SVG_PLOTTER::emitSetRGBColor( double r, double g, double b )
|
|||
|
||||
// Currently, use the same color for brush and pen (i.e. to draw and fill a contour).
|
||||
m_brush_rgb_color = rgb_color;
|
||||
m_brush_alpha = a;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -746,7 +752,7 @@ bool SVG_PLOTTER::StartPlot()
|
|||
double opacity = 1.0; // 0.0 (transparent to 1.0 (solid)
|
||||
fprintf( m_outputFile,
|
||||
"<g style=\"fill:#%6.6lX; fill-opacity:%.*f;stroke:#%6.6lX; stroke-opacity:%.*f;\n",
|
||||
m_brush_rgb_color, m_precision, opacity, m_pen_rgb_color, m_precision, opacity );
|
||||
m_brush_rgb_color, m_precision, m_brush_alpha, m_pen_rgb_color, m_precision, opacity );
|
||||
|
||||
// output the pen cap and line joint
|
||||
fputs( "stroke-linecap:round; stroke-linejoin:round;\"\n", m_outputFile );
|
||||
|
|
|
@ -131,7 +131,7 @@ protected:
|
|||
virtual std::string encodeStringForPlotter( const wxString& aUnicode );
|
||||
|
||||
/// Virtual primitive for emitting the setrgbcolor operator
|
||||
virtual void emitSetRGBColor( double r, double g, double b ) = 0;
|
||||
virtual void emitSetRGBColor( double r, double g, double b, double a ) = 0;
|
||||
|
||||
/// Height of the postscript font (from the AFM)
|
||||
static const double postscriptTextAscent; // = 0.718;
|
||||
|
@ -232,7 +232,7 @@ public:
|
|||
void* aData = nullptr ) override;
|
||||
|
||||
protected:
|
||||
virtual void emitSetRGBColor( double r, double g, double b ) override;
|
||||
virtual void emitSetRGBColor( double r, double g, double b, double a ) override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -373,7 +373,7 @@ protected:
|
|||
* engines. Also arcs are filled as pies but only the arc is stroked so
|
||||
* it would be difficult to handle anyway.
|
||||
*/
|
||||
virtual void emitSetRGBColor( double r, double g, double b ) override;
|
||||
virtual void emitSetRGBColor( double r, double g, double b, double a ) override;
|
||||
|
||||
/**
|
||||
* Allocate a new handle in the table of the PDF object. The
|
||||
|
@ -521,7 +521,7 @@ protected:
|
|||
* Initialize m_pen_rgb_color from reduced values r, g ,b
|
||||
* ( reduced values are 0.0 to 1.0 )
|
||||
*/
|
||||
virtual void emitSetRGBColor( double r, double g, double b ) override;
|
||||
virtual void emitSetRGBColor( double r, double g, double b, double a ) override;
|
||||
|
||||
/**
|
||||
* Output the string which define pen and brush color, shape, transparency
|
||||
|
@ -544,6 +544,7 @@ protected:
|
|||
// (written in hex to svg files)
|
||||
long m_brush_rgb_color; // same as m_pen_rgb_color, used to fill
|
||||
// some contours.
|
||||
double m_brush_alpha;
|
||||
bool m_graphics_changed; // true if a pen/brush parameter is modified
|
||||
// color, pen size, fill mode ...
|
||||
// the new SVG stype must be output on file
|
||||
|
|
Loading…
Reference in New Issue