@@ -40,7 +40,7 @@ use std::collections::HashMap;
4040use pdf_writer:: types:: ProcSet ;
4141use pdf_writer:: writers:: { ColorSpace , ExponentialFunction , FormXObject , Resources } ;
4242use pdf_writer:: { Content , Finish , Name , PdfWriter , Rect , Ref , TextStr , Writer } ;
43- use usvg:: { NodeExt , NodeKind , Stop , Tree } ;
43+ use usvg:: { NodeExt , NodeKind , Opacity , Stop , Tree } ;
4444
4545mod defer;
4646mod render;
@@ -234,6 +234,11 @@ impl<'a> Context<'a> {
234234
235235/// Convert an SVG source string to a standalone PDF buffer.
236236///
237+ /// Does not load any fonts and consequently cannot convert `text` elements. To
238+ /// convert text, you should convert your source string to a usvg [`Tree`]
239+ /// manually (providing a [font database](usvg::Options::fontdb)) and then use
240+ /// [`convert_tree`].
241+ ///
237242/// Returns an error if the SVG string is malformed.
238243pub fn convert_str ( src : & str , options : Options ) -> Result < Vec < u8 > , usvg:: Error > {
239244 let mut usvg_opts = usvg:: Options :: default ( ) ;
@@ -545,31 +550,24 @@ fn apply_mask(
545550
546551/// A color helper function that stores colors with values between 0.0 and 1.0.
547552#[ derive( Debug , Clone , Copy ) ]
548- struct RgbaColor {
553+ struct RgbColor {
549554 /// Red.
550555 r : f32 ,
551556 /// Green.
552557 g : f32 ,
553558 /// Blue.
554559 b : f32 ,
555- /// Alpha.
556- a : f32 ,
557560}
558561
559- impl RgbaColor {
562+ impl RgbColor {
560563 /// Create a new color.
561- fn new ( r : f32 , g : f32 , b : f32 , a : f32 ) -> RgbaColor {
562- RgbaColor { r, g, b, a }
564+ fn new ( r : f32 , g : f32 , b : f32 ) -> RgbColor {
565+ RgbColor { r, g, b }
563566 }
564567
565568 /// Create a new color from u8 color components between 0.0 and 255.0.
566- fn from_u8 ( r : u8 , g : u8 , b : u8 , a : u8 ) -> RgbaColor {
567- RgbaColor :: new (
568- r as f32 / 255.0 ,
569- g as f32 / 255.0 ,
570- b as f32 / 255.0 ,
571- a as f32 / 255.0 ,
572- )
569+ fn from_u8 ( r : u8 , g : u8 , b : u8 ) -> RgbColor {
570+ RgbColor :: new ( r as f32 / 255.0 , g as f32 / 255.0 , b as f32 / 255.0 )
573571 }
574572
575573 /// Create a RGB array for use in PDF.
@@ -578,9 +576,9 @@ impl RgbaColor {
578576 }
579577}
580578
581- impl From < usvg:: Color > for RgbaColor {
579+ impl From < usvg:: Color > for RgbColor {
582580 fn from ( color : usvg:: Color ) -> Self {
583- Self :: from_u8 ( color. red , color. green , color. blue , color . alpha )
581+ Self :: from_u8 ( color. red , color. green , color. blue )
584582 }
585583}
586584
@@ -595,22 +593,9 @@ fn register_functions(
595593 let func_ref = ctx. alloc_ref ( ) ;
596594 stops_to_function ( writer, func_ref, stops, false ) ;
597595
598- let alpha_ref = if stops
599- . iter ( )
600- . any ( |stop| stop. opacity . value ( ) < 1.0 || stop. color . alpha < 255 )
601- {
602- let stops = stops
603- . iter ( )
604- . cloned ( )
605- . map ( |mut stop| {
606- stop. color . alpha = ( stop. color . alpha as f64 * stop. opacity . value ( ) ) as u8 ;
607- stop
608- } )
609- . collect :: < Vec < _ > > ( ) ;
610-
596+ let alpha_ref = if stops. iter ( ) . any ( |stop| stop. opacity . value ( ) < 1.0 ) {
611597 let alpha_ref = ctx. alloc_ref ( ) ;
612598 stops_to_function ( writer, alpha_ref, & stops, true ) ;
613-
614599 Some ( alpha_ref)
615600 } else {
616601 None
@@ -626,32 +611,34 @@ fn stops_to_function(
626611 stops : & [ Stop ] ,
627612 alpha : bool ,
628613) -> bool {
629- let range =
630- IntoIterator :: into_iter ( [ 0.0f32 , 1.0f32 ] )
631- . cycle ( )
632- . take ( if alpha { 2 } else { 6 } ) ;
633-
634- let set_colors =
635- |exp : & mut ExponentialFunction , a_color : RgbaColor , b_color : RgbaColor | {
636- if alpha {
637- exp. c0 ( [ a_color. a ] ) ;
638- exp. c1 ( [ b_color. a ] ) ;
639- } else {
640- exp. c0 ( a_color. to_array ( ) ) ;
641- exp. c1 ( b_color. to_array ( ) ) ;
642- }
614+ let range = [ 0.0f32 , 1.0f32 ] . into_iter ( ) . cycle ( ) . take ( if alpha { 2 } else { 6 } ) ;
615+
616+ let set_alphas =
617+ |exp : & mut ExponentialFunction , a_alpha : Opacity , b_alpha : Opacity | {
618+ exp. c0 ( [ a_alpha. value ( ) as f32 ] ) ;
619+ exp. c1 ( [ b_alpha. value ( ) as f32 ] ) ;
620+ } ;
621+
622+ let set_rgbs =
623+ |exp : & mut ExponentialFunction , a_color : RgbColor , b_color : RgbColor | {
624+ exp. c0 ( a_color. to_array ( ) ) ;
625+ exp. c1 ( b_color. to_array ( ) ) ;
643626 } ;
644627
645628 if stops. is_empty ( ) {
646629 return false ;
647630 } else if stops. len ( ) == 1 {
648631 let mut exp = writer. exponential_function ( id) ;
649632 let stop = stops[ 0 ] ;
650- let color = RgbaColor :: from ( stop. color ) ;
633+ let color = RgbColor :: from ( stop. color ) ;
651634
652635 exp. domain ( [ 0.0 , 1.0 ] ) ;
653636 exp. range ( range) ;
654- set_colors ( & mut exp, color, color) ;
637+ if alpha {
638+ set_alphas ( & mut exp, stop. opacity , stop. opacity )
639+ } else {
640+ set_rgbs ( & mut exp, color, color) ;
641+ }
655642
656643 exp. n ( 1.0 ) ;
657644 return true ;
@@ -678,12 +665,16 @@ fn stops_to_function(
678665
679666 for window in stops. windows ( 2 ) {
680667 let ( a, b) = ( window[ 0 ] , window[ 1 ] ) ;
681- let ( a_color, b_color) = ( RgbaColor :: from ( a. color ) , RgbaColor :: from ( b. color ) ) ;
668+ let ( a_color, b_color) = ( RgbColor :: from ( a. color ) , RgbColor :: from ( b. color ) ) ;
682669 bounds. push ( b. offset . value ( ) as f32 ) ;
683670 let mut exp = ExponentialFunction :: start ( func_array. push ( ) ) ;
684671 exp. domain ( [ 0.0 , 1.0 ] ) ;
685672 exp. range ( range. clone ( ) ) ;
686- set_colors ( & mut exp, a_color, b_color) ;
673+ if alpha {
674+ set_alphas ( & mut exp, a. opacity , b. opacity ) ;
675+ } else {
676+ set_rgbs ( & mut exp, a_color, b_color) ;
677+ }
687678
688679 exp. n ( 1.0 ) ;
689680
0 commit comments