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

doodle.algebra.generic.GenericText.scala Maven / Gradle / Ivy

The newest version!
/*
 * 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 algebra
package generic

import cats.data.State
import doodle.core.BoundingBox
import doodle.core.Transform as Tx
import doodle.core.font.Font

trait GenericText[G[_]] extends Text {
  self: Algebra { type Drawing[A] = Finalized[G, A] } =>

  trait TextApi {

    /** The type of additional information that is useful for laying out text.
      *
      * Text layout is complicated. Doodle's layout only cares about the
      * bounding box, with the usual assumption that the origin is the center of
      * the bounding box. However, when we come to actually render the text we
      * usually want additional information. In particular we usually specify
      * the origin where we start rendering as the left-most point on the
      * baseline of the text (and text may descend below the baseline). This is
      * difficult to calculate just from the Doodle bounding box, so we allow
      * methods to return an additional piece of information that can be used to
      * layout the text.
      */
    type Bounds

    def text(
        tx: Tx,
        fill: Option[Fill],
        stroke: Option[Stroke],
        font: Font,
        text: String,
        bounds: Bounds
    ): G[Unit]

    def textBoundingBox(text: String, font: Font): (BoundingBox, Bounds)
  }

  def TextApi: TextApi

  def font[A](image: Finalized[G, A], font: Font): Finalized[G, A] =
    Finalized.contextTransform(_.font(font))(image)

  def text(text: String): Finalized[G, Unit] = {
    val api = TextApi

    Finalized.leaf { dc =>
      val (bb, bounds) = api.textBoundingBox(text, dc.font)
      (
        bb,
        State.inspect(tx =>
          api.text(tx, dc.fill, dc.stroke, dc.font, text, bounds)
        )
      )
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy