File: graphics.lisp

package info (click to toggle)
cl-typesetting 117-3
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 808 kB
  • ctags: 508
  • sloc: lisp: 4,073; makefile: 33; sh: 22
file content (115 lines) | stat: -rw-r--r-- 4,427 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
;;; cl-typesetting copyright 2002 Marc Battyani see license.txt for details of the license
;;; You can reach me at marc.battyani@fractalconcept.com or marc@battyani.net

(in-package typeset)

(defclass hrule (soft-box v-mode-mixin)
  ((color :accessor color :initarg :color :initform *color*)
   (stroke-fn :accessor stroke-fn :initarg :stroke-fn :initform nil)))

(defmethod adjust-box-dx ((box hrule) dx baseline)
  (setf (dx box) dx (baseline box) baseline))

(defmethod stroke ((box hrule) x y)
  (if (stroke-fn box)
      (funcall (stroke-fn box) box x y)
      (unless (zerop (dy box))
	(pdf:with-saved-state
	    (pdf:set-color-fill (color box))
	  (decf x (baseline box))
	  (pdf:basic-rect x y (dx box)(- (dy box)))
	  (pdf:fill-path)))))

(defun hrule (&rest args)
  (add-box (apply 'make-instance 'hrule args)))

(defclass jpeg-box (soft-box)
  ((file :accessor file :initform nil :initarg :file)
   (pdf-jpeg-obj :accessor pdf-jpeg-obj :initform nil :initarg :pdf-jpeg-obj)))

(defun image (&rest args &key inline &allow-other-keys)
  (if inline
      (add-box (apply 'make-instance 'jpeg-box :allow-other-keys t args))
      (let ((hbox (make-instance 'hbox :boxes (list (make-hfill-glue)
						    (apply 'make-instance 'jpeg-box :allow-other-keys t args)
						    (make-hfill-glue))
				 :adjustable-p t)))
	(compute-natural-box-size hbox)
	(add-box hbox))))

(defmethod stroke ((box jpeg-box) x y)
  (unless (pdf-jpeg-obj box)
    (setf (pdf-jpeg-obj box) (pdf:make-jpeg-image (pdf:read-jpeg-file (file box)))))
  (pdf:add-images-to-page (pdf-jpeg-obj box))
  (pdf:draw-image (pdf-jpeg-obj box) x (+ (- y (dy box))(offset box))(dx box)(dy box) 0 t))

(defclass background-jpeg-box (jpeg-box)
  ((x0 :accessor x0 :initarg :x0)
   (y0 :accessor y0 :initarg :y0)
   (fill-dx :accessor fill-dx :initform nil :initarg :fill-dx)
   (fill-dy :accessor fill-dy :initform nil :initarg :fill-dy)))

#+nil
(defmacro background-image (&rest args &key inline &allow-other-keys)
  `(add-box (make-instance 'background-jpeg-box ,@args :allow-other-keys t)))

(defclass user-drawn-box (soft-box)
  ((stroke-fn :accessor stroke-fn :initform nil :initarg :stroke-fn)))

(defun user-drawn-box (&rest args &key inline &allow-other-keys)
  (if inline
      (add-box (apply 'make-instance 'user-drawn-box :allow-other-keys t args))
      (let ((hbox (make-instance 'hbox :boxes
				 (list (make-hfill-glue)
				       (apply 'make-instance 'user-drawn-box  :allow-other-keys t args)
				       (make-hfill-glue))
				 :adjustable-p t)))
	(compute-natural-box-size hbox)
	(add-box hbox))))

(defmethod stroke ((box user-drawn-box) x y)
  (if (stroke-fn box)
      (funcall (stroke-fn box) box x y)
      (unless (zerop (dy box))
	(pdf:with-saved-state
	    (pdf:set-color-fill '(0.5 0.5 0.5))
	  (pdf:basic-rect x y (dx box)(- (dy box)))
	  (pdf:fill-path)))))

(defun stroke-colored-box (box x y color border-width border-color)
  (pdf:with-saved-state
      (pdf:set-color-fill color)
      (when border-width
	(pdf:set-color-stroke border-color)
	(pdf:set-line-width border-width))
      (pdf:basic-rect x (+ y (offset box)) (dx box)(- (dy box)))
      (pdf:fill-and-stroke)))

(defun colored-box (&rest args &key dy (offset dy) color border-width (border-color '(0 0 0))
			  &allow-other-keys)
  (add-box (apply 'make-instance 'user-drawn-box
		  :stroke-fn
		  #'(lambda(box x y)
		      (stroke-colored-box box x y color border-width border-color))
		  :allow-other-keys t :offset offset args)))

(defclass dotted-spacing (soft-box h-mode-mixin)
  ((char-pattern :accessor char-pattern :initarg :char-pattern :initform ".")
   (pattern-spacing :accessor pattern-spacing :initarg :pattern-spacing :initform 0.3)))

(defmethod stroke ((box dotted-spacing) x y)
  (let* ((pattern-width (pdf::text-width (char-pattern box) *font* *font-size*))
	 (spacing-width (* *font-size* (pattern-spacing box)))
	 (total-width (+ pattern-width spacing-width))
	 (last-x (- (+ x (dx box)(delta-size box)) pattern-width)))
    (incf y (offset box))
    (loop for x from (* total-width (ceiling x total-width)) by total-width
	  while (< x last-x)
	  do (pdf:in-text-mode
	      (pdf:move-text x y)
	      (pdf:set-font *font* *font-size*)
	      (pdf:show-text (char-pattern box))))))

(defun dotted-hfill (&rest args)
  (add-box (apply 'make-instance 'dotted-spacing
		  :dx 0 :max-expansion +huge-number+ :expansibility +huge-number+ args)))