+(defbinding %surface-write-to-jpeg-stream (surface stream param) status-signal
+ (surface surface)
+ (jpeg-stream-write-func callback)
+ (stream pointer-data)
+ (param jpeg-parameter))
+
+(defmethod surface-write-to-jpeg (surface (stream stream) &key
+ (quality 75) (interlace t))
+ (let ((stream-id (register-user-data stream))
+ (param (make-instance 'jpeg-parameter
+ :quality quality :interlace interlace)))
+ (unwind-protect
+ (%surface-write-to-jpeg-stream (%surface-acquire-image surface) stream-id param)
+ (destroy-user-data stream-id))))
+
+
+;;; Virtual size surface (abstract class)
+
+(defmethod initialize-instance :after ((surface vector-surface) &key
+ width height)
+ (setf (user-data surface 'width) width)
+ (setf (user-data surface 'height) height))
+
+(defmethod surface-width ((surface vector-surface))
+ (user-data surface 'width))
+
+(defmethod surface-height ((surface vector-surface))
+ (user-data surface 'height))
+
+
+(defun allocate-vector-surface (surface-create surface-create-for-stream
+ &key output filename stream width height)
+ (let ((location
+ (cond
+ ((/= (count-if #'identity (list output filename stream)) 1)
+ (error "One and only one of the arguments :OUTPUT, :FILENAME and :STREAM shoud be specified"))
+ (filename (funcall surface-create filename width height))
+ ((typep output '(or string pathname))
+ (%svg-surface-create output width height))
+ (t
+ (let* ((stream-id (register-user-data (or stream output)))
+ (location (funcall surface-create-for-stream
+ stream-id width height)))
+ (%surface-set-user-data location 'stream stream-id)
+ location)))))
+ location))
+
+
+;;; PDF Surface
+
+(defmethod allocate-foreign ((surface pdf-surface) &rest args)
+ (apply #'allocate-vector-surface
+ #'%pdf-surface-create #'%pdf-surface-create-for-stream args))