All Downloads are FREE. Search and download functionalities are using the official Maven repository.

doodle.java2d.algebra.Algebra.scala Maven / Gradle / Ivy

/*
 * Copyright 2015 Creative Scala
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package doodle
package java2d
package algebra

import cats.*
import cats.data.WriterT
import cats.implicits.*
import doodle.algebra.generic.*
import doodle.core.BoundingBox
import doodle.java2d.algebra.reified.*
import doodle.language.Basic

import java.awt.Graphics2D

final case class Algebra(
    gc: Graphics2D,
    applyDrawing: Apply[Reification] = Apply.apply[Reification],
    functorDrawing: Functor[Reification] = Apply.apply[Reification]
) extends Basic
    with Java2dFromBufferedImage
    with Java2dFromBase64
    with ReifiedBitmap
    with ReifiedPath
    with ReifiedShape
    with ReifiedText
    with GenericDebug[Reification]
    with GenericLayout[Reification]
    with GenericSize[Reification]
    with GenericStyle[Reification]
    with GenericTransform[Reification]
    with GivenApply[Reification]
    with GivenFunctor[Reification]
    with doodle.algebra.Algebra {
  type Drawing[A] = doodle.java2d.Drawing[A]
  implicit val drawingInstance: Monad[Drawing] =
    new Monad[Drawing] {
      def pure[A](x: A): Drawing[A] =
        Finalized.leaf(_ =>
          (
            BoundingBox.empty,
            Renderable.apply(_ =>
              Eval.now(WriterT.liftF[Eval, List[Reified], A](Eval.now(x)))
            )
          )
        )

      def flatMap[A, B](fa: Drawing[A])(f: A => Drawing[B]): Drawing[B] =
        fa.flatMap { (bb, rdr) =>
          val reified = rdr.runA(doodle.core.Transform.identity).value
          val (_, a) = reified.run.value
          f(a)
        }

      def tailRecM[A, B](a: A)(f: A => Drawing[Either[A, B]]): Drawing[B] = {
        // TODO: This implementation is not tail recursive but I don't think we need it for what we use in Doodle
        val dAB = f(a)
        flatMap(dAB)(either =>
          either match {
            case Left(a)  => tailRecM(a)(f)
            case Right(b) => dAB.asInstanceOf[Drawing[B]]
          }
        )
      }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy