Created
November 8, 2012 11:31
-
-
Save v6ak/4038281 to your computer and use it in GitHub Desktop.
Skript na přidání ořezových značek v SVG. Hodí se v původním obrázku přesáhnout okraje. Omlouvám se za magické konstanty, někde jsem to kdyi vyčetl a nejsem tiskař (a bohužel jsem si to nepoznamenal).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import xml._ | |
| trait Rect[+T]{ | |
| def x: T | |
| def y: T | |
| def fun(name: String) = name+"("+x+","+y+")" | |
| } | |
| final case class OrientedRect[+T](vertical: T, horizontal: T) extends Rect[T]{ | |
| def width = horizontal | |
| def height = vertical | |
| def x = horizontal | |
| def y = vertical | |
| def map[U](f: (T=>U)) = OrientedRect.fromXY(x = f(x), y = f(y)) | |
| def unorient(d: Direction): UnorientedRect[T] = UnorientedRect[T](x=d.primary(this), y=d.secondary(this)) | |
| def combine[U >: T, V](that: OrientedRect[U], pf: (T, U) =>V) = OrientedRect( | |
| vertical = pf(this.vertical, that.vertical), | |
| horizontal = pf(this.horizontal, that.horizontal) | |
| ) | |
| } | |
| object OrientedRect{ | |
| def fromXY[T](x: T, y: T): OrientedRect[T] = apply(vertical = y, horizontal = x) | |
| def fromSizes[T](width: T, height: T): OrientedRect[T] = apply(vertical = height, horizontal = width) | |
| def fromAttrs[F, T](f: (String) => T, xName: String, yName: String) = fromXY(f(xName), f(yName)) | |
| def fromSizeAttrs[F, T](f: (String) => T) = fromAttrs(f, "width", "height") | |
| def fromXYAttrs[F, T](f: (String) => T) = fromAttrs(f, "x", "y") | |
| } | |
| final case class UnorientedRect[+T](x: T, y: T) extends Rect[T]{ | |
| def toOriented(d: Direction): OrientedRect[T] = d.createOrientedRect(this) | |
| } | |
| implicit def toUnorientedRectIntOnlyOperations(left: UnorientedRect[Int]) = new AnyRef{ | |
| def onlyPrimary = UnorientedRect(x=left.x, y=0) | |
| def onlySecondary = UnorientedRect(x=0, y=left.y) | |
| } | |
| implicit def toUnorientedRectStringOnlyOperations(left: UnorientedRect[String]) = new AnyRef{ | |
| def onlyPrimary = UnorientedRect(x=left.x, y="0") | |
| def onlySecondary = UnorientedRect(x="0", y=left.y) | |
| } | |
| implicit def toOrientedRectIntOnlyOperations(that: OrientedRect[Int]) = new AnyRef{ | |
| def onlyPrimary(direction: Direction): OrientedRect[Int] = that.unorient(direction).onlyPrimary.toOriented(direction) | |
| def onlySecondary(direction: Direction) = that.unorient(direction).onlySecondary.toOriented(direction) | |
| } | |
| implicit def toOrientedRectStringOnlyOperations(that: OrientedRect[String]) = new AnyRef{ | |
| def onlyPrimary(direction: Direction) = that.unorient(direction).onlyPrimary.toOriented(direction) | |
| def onlySecondary(direction: Direction) = that.unorient(direction).onlySecondary.toOriented(direction) | |
| } | |
| sealed abstract class Direction{ | |
| def primary[T](r: OrientedRect[T]): T | |
| def secondary[T](r: OrientedRect[T]): T | |
| def createOrientedRect[T](r: UnorientedRect[T]): OrientedRect[T] // x=primary | |
| def rotate: Direction | |
| } | |
| object Vertical extends Direction{ | |
| override def primary[T](r: OrientedRect[T]) = r.vertical | |
| override def secondary[T](r: OrientedRect[T]) = r.horizontal | |
| override def createOrientedRect[T](r: UnorientedRect[T]) = OrientedRect(vertical = r.x, horizontal = r.y) | |
| override def rotate = Horizontal | |
| } | |
| object Horizontal extends Direction{ | |
| override def primary[T](r: OrientedRect[T]) = r.horizontal | |
| override def secondary[T](r: OrientedRect[T]) = r.vertical | |
| override def createOrientedRect[T](r: UnorientedRect[T]) = OrientedRect(horizontal = r.x, vertical = r.y) | |
| override def rotate = Vertical | |
| } | |
| implicit def toOrientedRectIntOperations(left: OrientedRect[Int]) = new AnyRef{ | |
| def +(right: OrientedRect[Int]): OrientedRect[Int] = left.combine(right, (a: Int, b: Int) => a+b) | |
| def *(right: Int) = left.map(_*right) | |
| } | |
| implicit def toOrientedRectDoubleOperations(left: OrientedRect[Double]) = new AnyRef{ | |
| def +(right: OrientedRect[Double]): OrientedRect[Double] = left.combine(right, (a: Double, b: Double) => a+b) | |
| def *(right: Double) = left.map(_*right) | |
| def *(right: OrientedRect[Double]): OrientedRect[Double] = left.combine(right, (a: Double, b: Double) => a*b) | |
| } | |
| val CropmarkerSize = UnorientedRect(50, 3) | |
| val CropmarkerMovement = UnorientedRect(50, 0) | |
| val MarginInternal = OrientedRect(350, 700) | |
| val Space = OrientedRect(240, 240) | |
| val Array(source) = args | |
| val img = XML.load(source) | |
| val orig = OrientedRect.fromSizeAttrs(img.attributes(_).toString) | |
| val dpi = OrientedRect.fromXYAttrs(d => (img \ ("@{http://www.inkscape.org/namespaces/inkscape}export-"+d+"dpi")).toString.toDouble)// ="24.190001" | |
| def calcScale(dpi: Double) = dpi/25.4/10 | |
| val color = "black" //"#000000" | |
| val scale = dpi.map(calcScale) | |
| val margin = MarginInternal.map(_.toDouble) * scale | |
| def cm(direction: Direction, moveBefore: OrientedRect[Any], moveAfter: OrientedRect[Any]) = { | |
| val cmr = CropmarkerSize.toOriented(direction) | |
| val cmm = orig.onlyPrimary(direction) //val cmm = CropmarkerMovement.toOriented(direction) | |
| <rect | |
| style={"fill:"+color} | |
| width={cmr.width.toString} | |
| height={cmr.height.toString} | |
| x="0" | |
| y="0" | |
| transform={List(moveBefore fun "translate", scale fun "scale", moveAfter fun "translate") mkString " "} /> | |
| } | |
| def genCM(direction: Direction, offset: OrientedRect[String]) = { | |
| val cmr = CropmarkerSize.toOriented(direction) | |
| val cmm = orig.onlyPrimary(direction)// | |
| val sp = Space.onlyPrimary(direction) | |
| <g transform={offset.onlyPrimary(direction.rotate) fun "translate"}> | |
| {cm(direction, OrientedRect(0, 0), (cmr+sp) * -1)} | |
| {cm(direction, cmm, sp)} | |
| </g> | |
| } | |
| val generatedCM = <g>{ | |
| for( | |
| cmType <- List(Vertical, Horizontal); | |
| offset <- List(OrientedRect("0", "0"), orig) | |
| ) yield genCM(cmType, offset) | |
| }</g> | |
| val newSize = orig.map(_.toDouble) + margin*2 | |
| val newImg = img match { | |
| case Elem(prefix, label, attrs, metadata, scope, children @ _*) => | |
| Elem( | |
| prefix, label, attrs, metadata, scope, | |
| <g transform={margin fun "translate"}>{children}{generatedCM}</g> | |
| ) % | |
| new UnprefixedAttribute("width", newSize.width toString, Null) % | |
| new UnprefixedAttribute("height", newSize.height toString, Null) | |
| } | |
| println(newImg) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment