Repository: typst/typst
File: crates/typst/src/visualize/color.rs (Rust)

Code before:
    /// This method is relative to the existing alpha value.
    ///
    /// ```example
    /// #block(fill: red)[opaque]
    /// #block(fill: red.transparentize(50%))[half red]
    /// #block(fill: red.transparentize(75%))[quarter red]
    /// ```
    #[func]
    pub fn transparentize(
        self,
        /// The factor to change the alpha value by.
        factor: Ratio,
    ) -> StrResult<Color> {
        #[inline]
        fn transform<C>(mut color: Alpha<C, f32>, factor: Ratio) -> Alpha<C, f32> {
            color.alpha = (color.alpha * (1.0 - factor.get() as f32)).clamp(0.0, 1.0);
            color
        }

        Ok(match self {
            Color::Luma(c) => Color::Luma(transform(c, factor)),
            Color::Oklab(c) => Color::Oklab(transform(c, factor)),
            Color::Oklch(c) => Color::Oklch(transform(c, factor)),
            Color::Rgb(c) => Color::Rgb(transform(c, factor)),
            Color::LinearRgb(c) => Color::LinearRgb(transform(c, factor)),
            Color::Cmyk(_) => bail!("CMYK does have an alpha component"),
            Color::Hsl(c) => Color::Hsl(transform(c, factor)),
            Color::Hsv(c) => Color::Hsv(transform(c, factor)),
        })
    }

    /// Make a color more opaque by a given factor.
    ///
    /// This method is relative to the existing alpha value.
    ///
    /// ```example
    /// #block(fill: red)[opaque]
    /// #block(fill: red.opacify(50%))[half red]
    /// #block(fill: red.opacify(75%))[quarter red]
    /// ```
    #[func]
    pub fn opacify(
        self,
        /// The factor to change the alpha value by.
        factor: Ratio,
    ) -> StrResult<Color> {
        #[inline]
        fn transform<C>(mut color: Alpha<C, f32>, factor: Ratio) -> Alpha<C, f32> {
            color.alpha = (color.alpha * (1.0 + factor.get() as f32)).clamp(0.0, 1.0);
            color
        }

Review comment (suggestion):
```suggestion
            Color::Cmyk(_) => bail!("CMYK does not have an alpha component"),
```

Code after:
    /// This method is relative to the existing alpha value.
    /// If the scale is positive, calculates `alpha - alpha * scale`.
    /// Negative scales behave like `color.opacify(-scale)`.
    ///
    /// ```example
    /// #block(fill: red)[opaque]
    /// #block(fill: red.transparentize(50%))[half red]
    /// #block(fill: red.transparentize(75%))[quarter red]
    /// ```
    #[func]
    pub fn transparentize(
        self,
        /// The factor to change the alpha value by.
        scale: Ratio,
    ) -> StrResult<Color> {
        self.scale_alpha(-scale)
    }

    /// Makes a color more opaque by a given scale.
    ///
    /// This method is relative to the existing alpha value.
    /// If the scale is positive, calculates `alpha + scale - alpha * scale`.
    /// Negative scales behave like `color.transparentize(-scale)`.
    ///
    /// ```example
    /// #let half-red = red.transparentize(50%)
    /// #block(fill: half-red.opacify(100%))[opaque]
    /// #block(fill: half-red.opacify(50%))[three quarters red]
    /// #block(fill: half-red.opacify(-50%))[one quarter red]
    /// ```
    #[func]
    pub fn opacify(
        self,
        /// The scale to change the alpha value by.
        scale: Ratio,
    ) -> StrResult<Color> {
        self.scale_alpha(scale)
    }
}

impl Color {
    /// Same as [`Color::mix`], but takes an iterator instead of a vector.
    pub fn mix_iter(
        colors: impl IntoIterator<
            Item = WeightedColor,
            IntoIter = impl ExactSizeIterator<Item = WeightedColor>,
        >,
        space: ColorSpace,
    ) -> StrResult<Color> {
        let mut colors = colors.into_iter();
        if space.hue_index().is_some() && colors.len() > 2 {