Module: duim-dcs-internals Synopsis: DUIM display device contexts Author: Scott McKay, Andy Armstrong Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND /// Images define protocol <> () getter image-width (image :: ) => (width :: ); getter image-height (image :: ) => (height :: ); getter image-depth (image :: ) => (depth :: ); // Reading and writing images function read-image (locator, #key image-type, #all-keys) => (image :: false-or()); function read-image-as (class :: , locator, image-type, #key, #all-keys) => (image :: false-or()); function write-image (image :: , locator) => (); // Image conversion function convert-image (image :: , image-type) => (image :: ); function image-convertible? (image :: , image-type) => (true? :: ); end protocol <>; /// Stencils define constant $stencil-colors :: = vector($background, $foreground); // A stencil is just a bitmap of the foreground and background colors define sealed class () sealed constant slot %array :: , required-init-keyword: array:; sealed slot %transform = #f, init-keyword: transform:; end class ; define sealed domain make (singleton()); define sealed domain initialize (); define protocol-predicate stencil; define method make-stencil (array :: ) => (stencil :: ) make(, array: array) end method make-stencil; define method make-stencil (sequence :: ) => (stencil :: ) let array = make-array-from-contents(sequence); make(, array: array) end method make-stencil; define macro stencil-definer { define stencil ?:name ?array:* end } => { define constant ?name :: = make-stencil(list(?array)) } array: { } => { } { ?row:*; ... } => { list(?row), ... } row: { } => { } { ?cell:*, ... } => { ?cell, ... } end macro stencil-definer; define method box-edges (stencil :: ) => (left :: , top :: , right :: , bottom :: ) values(0, 0, dimension(stencil.%array, 1), dimension(stencil.%array, 0)) end method box-edges; define method image-width (stencil :: ) => (width :: ) dimension(stencil.%array, 1) end method image-width; define method image-height (stencil :: ) => (width :: ) dimension(stencil.%array, 0) end method image-height; define method decode-pattern (stencil :: ) => (array, colors, transform) values(stencil.%array, $stencil-colors, stencil.%transform) end method decode-pattern; define method transform-image (transform :: , stencil :: ) => (stencil :: ) if (identity-transform?(transform)) stencil else make(, array: stencil.%array, transform: transform) end end method transform-image; /// Patterns // A pattern is a portable bitmap of arbitrary colors define sealed class () sealed constant slot %colors :: , required-init-keyword: colors:; end class ; define sealed domain make (singleton()); define sealed domain initialize (); define protocol-predicate pattern; define method make-pattern (array :: , colors) => (pattern :: ) make(, array: array, colors: as(, colors)) end method make-pattern; define method make-pattern (sequence :: , colors) => (pattern :: ) let array = make-array-from-contents(sequence); make(, array: array, colors: as(, colors)) end method make-pattern; define macro pattern-definer { define pattern ?:name (?colors:expression) ?array:* end } => { define constant ?name :: = make-pattern(list(?array), ?colors) } array: { } => { } { ?row:*; ... } => { list(?row), ... } row: { } => { } { ?cell:*, ... } => { ?cell, ... } end macro pattern-definer; define method decode-pattern (pattern :: ) => (array, colors, transform) values(pattern.%array, pattern.%colors, pattern.%transform) end method decode-pattern; define method transform-image (transform :: , pattern :: ) => (pattern :: ) if (identity-transform?(transform)) pattern else make(, array: pattern.%array, colors: pattern.%colors, transform: transform) end end method transform-image; /// Images define method read-image (locator, #rest keys, #key image-type, #all-keys) => (image :: false-or()) dynamic-extent(keys); // The idea is that back ends have methods that '==' specialize // on the image type, and create various subclasses of with-keywords-removed (keys = keys, #[image-type:]) apply(read-image-as, , locator, image-type, keys) end end method read-image;