Merge pull request #10 from scymtym/fix-post20-reading-again
[zpb-ttf.git] / font-loader.lisp
blob44df2b7d98fd7f8f3b4c0c798d579349550507c0
1 ;;; Copyright (c) 2006 Zachary Beane, All Rights Reserved
2 ;;;
3 ;;; Redistribution and use in source and binary forms, with or without
4 ;;; modification, are permitted provided that the following conditions
5 ;;; are met:
6 ;;;
7 ;;; * Redistributions of source code must retain the above copyright
8 ;;; notice, this list of conditions and the following disclaimer.
9 ;;;
10 ;;; * Redistributions in binary form must reproduce the above
11 ;;; copyright notice, this list of conditions and the following
12 ;;; disclaimer in the documentation and/or other materials
13 ;;; provided with the distribution.
14 ;;;
15 ;;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESSED
16 ;;; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 ;;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 ;;; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19 ;;; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 ;;; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 ;;; GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 ;;; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 ;;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 ;;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 ;;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 ;;;
27 ;;; The font-loader object, which is the primary interface for
28 ;;; getting glyph and metrics info.
29 ;;;
30 ;;; $Id: font-loader.lisp,v 1.26 2006/03/23 22:21:40 xach Exp $
32 (in-package #:zpb-ttf)
34 (defclass font-loader ()
35 ((tables :initform (make-hash-table) :reader tables)
36 (input-stream :initarg :input-stream :accessor input-stream
37 :documentation "The stream from which things are loaded.")
38 (table-count :initarg :table-count :reader table-count)
39 ;; from the 'head' table
40 (units/em :accessor units/em)
41 (bounding-box :accessor bounding-box)
42 (loca-offset-format :accessor loca-offset-format)
43 ;; from the 'loca' table
44 (glyph-locations :accessor glyph-locations)
45 ;; from the 'cmap' table
46 (character-map :accessor character-map)
47 (inverse-character-map :accessor inverse-character-map)
48 ;; from the 'maxp' table
49 (glyph-count :accessor glyph-count)
50 ;; from the 'hhea' table
51 (ascender :accessor ascender)
52 (descender :accessor descender)
53 (line-gap :accessor line-gap)
54 ;; from the 'hmtx' table
55 (advance-widths :accessor advance-widths)
56 (left-side-bearings :accessor left-side-bearings)
57 ;; from the 'kern' table
58 (kerning-table :initform (make-hash-table) :accessor kerning-table)
59 ;; from the 'name' table
60 (name-entries :initform nil :accessor name-entries)
61 ;; from the 'post' table
62 (italic-angle :accessor italic-angle :initform 0)
63 (fixed-pitch-p :accessor fixed-pitch-p :initform nil)
64 (underline-position :accessor underline-position :initform 0)
65 (underline-thickness :accessor underline-thickness :initform 0)
66 (postscript-glyph-names :accessor postscript-glyph-names)
67 ;; misc
68 (glyph-cache :accessor glyph-cache)
69 ;; # of fonts in collection, if loaded from a ttc file
70 (collection-font-count :reader collection-font-count :initform nil
71 :initarg :collection-font-cont)
72 ;; index of font in collection, if loaded from a ttc file
73 (collection-font-index :reader collection-font-index :initform nil
74 :initarg :collection-font-index)))
76 (defclass table-info ()
77 ((name :initarg :name :reader name)
78 (offset :initarg :offset :reader offset)
79 (size :initarg :size :reader size)))
81 (defmethod print-object ((object table-info) stream)
82 (print-unreadable-object (object stream :type t)
83 (format stream "\"~A\"" (name object))))
86 ;;; tag integers to strings and back
88 (defun number->tag (number)
89 "Convert the 32-bit NUMBER to a string of four characters based on
90 the CODE-CHAR of each octet in the number."
91 (let ((tag (make-string 4)))
92 (loop for i below 4
93 for offset from 24 downto 0 by 8
94 do (setf (schar tag i)
95 (code-char (ldb (byte 8 offset) number))))
96 tag))
98 (defun tag->number (tag)
99 "Convert the four-character string TAG to a 32-bit number based on
100 the CHAR-CODE of each character."
101 (declare (simple-string tag))
102 (loop for char across tag
103 for offset from 24 downto 0 by 8
104 summing (ash (char-code char) offset)))
107 ;;; Getting table info out of the loader
109 (defmethod table-info ((tag string) (font-loader font-loader))
110 (gethash (tag->number tag) (tables font-loader)))
112 (defmethod table-exists-p (tag font-loader)
113 (nth-value 1 (table-info tag font-loader)))
115 (defmethod table-position ((tag string) (font-loader font-loader))
116 "Return the byte position in the font-loader's stream for the table
117 named by TAG."
118 (let ((table-info (table-info tag font-loader)))
119 (if table-info
120 (offset table-info)
121 (error "No such table -- ~A" tag))))
123 (defmethod table-size ((tag string) (font-loader font-loader))
124 (let ((table-info (table-info tag font-loader)))
125 (if table-info
126 (size table-info)
127 (error "No such table -- ~A" tag))))
129 (defmethod seek-to-table ((tag string) (font-loader font-loader))
130 "Move FONT-LOADER's input stream to the start of the table named by TAG."
131 (let ((table-info (table-info tag font-loader)))
132 (if table-info
133 (seek-to-table table-info font-loader)
134 (error "No such table -- ~A" tag))))
136 (defmethod seek-to-table ((table table-info) (font-loader font-loader))
137 "Move FONT-LOADER's input stream to the start of TABLE."
138 (file-position (input-stream font-loader) (offset table)))