diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/draw/5x7.bdf | 3190 | ||||
| -rw-r--r-- | src/draw/Makefile | 4 | ||||
| -rw-r--r-- | src/draw/ao_blt.c | 294 | ||||
| -rw-r--r-- | src/draw/ao_copy.c | 75 | ||||
| -rw-r--r-- | src/draw/ao_draw.h | 119 | ||||
| -rw-r--r-- | src/draw/ao_draw_int.h | 136 | ||||
| -rw-r--r-- | src/draw/ao_font.h | 139 | ||||
| -rw-r--r-- | src/draw/ao_line.c | 314 | ||||
| -rw-r--r-- | src/draw/ao_pattern.c | 80 | ||||
| -rw-r--r-- | src/draw/ao_rect.c | 46 | ||||
| -rw-r--r-- | src/draw/ao_text.c | 65 | ||||
| -rwxr-xr-x | src/draw/font-convert | 150 | ||||
| -rw-r--r-- | src/draw/line.5c | 389 | 
13 files changed, 5001 insertions, 0 deletions
| diff --git a/src/draw/5x7.bdf b/src/draw/5x7.bdf new file mode 100644 index 00000000..b511f289 --- /dev/null +++ b/src/draw/5x7.bdf @@ -0,0 +1,3190 @@ +STARTFONT 2.1 +COMMENT  Copyright 1991 Massachusetts Institute of Technology +COMMENT   +COMMENT  Permission to use, copy, modify, and distribute this software +COMMENT  and its documentation for any purpose and without fee is +COMMENT  hereby granted, provided that the above copyright notice +COMMENT  appear in all copies and that both that copyright notice and +COMMENT  this permission notice appear in supporting documentation, +COMMENT  and that the name of M.I.T. not be used in advertising or +COMMENT  publicity pertaining to distribution of the software without +COMMENT  specific, written prior permission.  M.I.T. makes no +COMMENT  representations about the suitability of this software for +COMMENT  any purpose.  It is provided "as is" without express or +COMMENT  implied warranty. +COMMENT   +COMMENT  M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +COMMENT  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +COMMENT  FITNESS, IN NO EVENT SHALL M.I.T.  BE LIABLE FOR ANY SPECIAL, +COMMENT  INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER +COMMENT  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +COMMENT  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +COMMENT  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +COMMENT  OF THIS SOFTWARE. +COMMENT   +COMMENT  Author:  Stephen Gildea, MIT X Consortium, June 1991 +COMMENT   +FONT -Misc-Fixed-Medium-R-Normal--7-70-75-75-C-50-ISO8859-1 +SIZE 7 75 75 +FONTBOUNDINGBOX 5 7 0 -1 +STARTPROPERTIES 21 +FONTNAME_REGISTRY "" +FOUNDRY "Misc" +FAMILY_NAME "Fixed" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 7 +POINT_SIZE 70 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 50 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "1" +FONT_ASCENT 6 +FONT_DESCENT 1 +UNDERLINE_POSITION 0 +DESTINATION 1 +DEFAULT_CHAR 0 +COPYRIGHT "Copyright 1991 Massachusetts Institute of Technology" +ENDPROPERTIES +CHARS 224 +STARTCHAR C000 +ENCODING 0 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +f0 +f0 +f0 +f0 +f0 +00 +ENDCHAR +STARTCHAR C001 +ENCODING 1 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +70 +f8 +70 +20 +00 +ENDCHAR +STARTCHAR C002 +ENCODING 2 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +50 +a0 +50 +a0 +00 +ENDCHAR +STARTCHAR C003 +ENCODING 3 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +e0 +a0 +a0 +70 +20 +20 +ENDCHAR +STARTCHAR C004 +ENCODING 4 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +80 +c0 +b0 +20 +30 +20 +ENDCHAR +STARTCHAR C005 +ENCODING 5 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +80 +c0 +60 +50 +60 +50 +ENDCHAR +STARTCHAR C006 +ENCODING 6 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +c0 +30 +20 +30 +20 +ENDCHAR +STARTCHAR C007 +ENCODING 7 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C010 +ENCODING 8 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +70 +20 +00 +70 +00 +00 +ENDCHAR +STARTCHAR C011 +ENCODING 9 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +d0 +b0 +90 +20 +20 +30 +ENDCHAR +STARTCHAR C012 +ENCODING 10 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +a0 +40 +70 +20 +20 +ENDCHAR +STARTCHAR C013 +ENCODING 11 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +e0 +00 +00 +00 +ENDCHAR +STARTCHAR C014 +ENCODING 12 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +e0 +20 +20 +20 +ENDCHAR +STARTCHAR C015 +ENCODING 13 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +38 +20 +20 +20 +ENDCHAR +STARTCHAR C016 +ENCODING 14 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +38 +00 +00 +00 +ENDCHAR +STARTCHAR C017 +ENCODING 15 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +f8 +20 +20 +20 +ENDCHAR +STARTCHAR C020 +ENCODING 16 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +f8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C021 +ENCODING 17 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +00 +00 +f8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C022 +ENCODING 18 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f8 +00 +00 +00 +ENDCHAR +STARTCHAR C023 +ENCODING 19 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +f8 +00 +00 +ENDCHAR +STARTCHAR C024 +ENCODING 20 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +f8 +00 +ENDCHAR +STARTCHAR C025 +ENCODING 21 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +38 +20 +20 +20 +ENDCHAR +STARTCHAR C026 +ENCODING 22 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +e0 +20 +20 +20 +ENDCHAR +STARTCHAR C027 +ENCODING 23 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +20 +20 +20 +f8 +00 +00 +00 +ENDCHAR +STARTCHAR C030 +ENCODING 24 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f8 +20 +20 +20 +ENDCHAR +STARTCHAR C031 +ENCODING 25 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR C032 +ENCODING 26 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +10 +20 +40 +20 +10 +70 +00 +ENDCHAR +STARTCHAR C033 +ENCODING 27 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +10 +20 +40 +70 +00 +ENDCHAR +STARTCHAR C034 +ENCODING 28 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +50 +50 +50 +00 +ENDCHAR +STARTCHAR C035 +ENCODING 29 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +10 +70 +20 +70 +40 +00 +ENDCHAR +STARTCHAR C036 +ENCODING 30 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +30 +40 +e0 +40 +b0 +00 +ENDCHAR +STARTCHAR C037 +ENCODING 31 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR C040 +ENCODING 32 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ! +ENCODING 33 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +20 +20 +00 +20 +00 +ENDCHAR +STARTCHAR " +ENCODING 34 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +50 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR # +ENCODING 35 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +50 +f8 +50 +f8 +50 +00 +ENDCHAR +STARTCHAR $ +ENCODING 36 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +70 +a0 +70 +28 +70 +00 +ENDCHAR +STARTCHAR % +ENCODING 37 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +90 +20 +40 +90 +10 +00 +ENDCHAR +STARTCHAR & +ENCODING 38 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +40 +a0 +40 +a0 +50 +00 +ENDCHAR +STARTCHAR ' +ENCODING 39 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +40 +80 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ( +ENCODING 40 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +40 +40 +40 +20 +00 +ENDCHAR +STARTCHAR ) +ENCODING 41 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +20 +20 +20 +40 +00 +ENDCHAR +STARTCHAR * +ENCODING 42 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +a0 +40 +e0 +40 +a0 +00 +ENDCHAR +STARTCHAR + +ENCODING 43 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +20 +f8 +20 +20 +00 +ENDCHAR +STARTCHAR , +ENCODING 44 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +60 +40 +80 +ENDCHAR +STARTCHAR - +ENCODING 45 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f0 +00 +00 +00 +ENDCHAR +STARTCHAR . +ENCODING 46 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +60 +60 +00 +ENDCHAR +STARTCHAR / +ENCODING 47 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +10 +20 +40 +80 +00 +00 +ENDCHAR +STARTCHAR 0 +ENCODING 48 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +a0 +a0 +a0 +40 +00 +ENDCHAR +STARTCHAR 1 +ENCODING 49 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +c0 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR 2 +ENCODING 50 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +10 +20 +40 +f0 +00 +ENDCHAR +STARTCHAR 3 +ENCODING 51 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +10 +60 +10 +90 +60 +00 +ENDCHAR +STARTCHAR 4 +ENCODING 52 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +60 +a0 +f0 +20 +20 +00 +ENDCHAR +STARTCHAR 5 +ENCODING 53 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +10 +90 +60 +00 +ENDCHAR +STARTCHAR 6 +ENCODING 54 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +80 +e0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR 7 +ENCODING 55 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +10 +20 +20 +40 +40 +00 +ENDCHAR +STARTCHAR 8 +ENCODING 56 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR 9 +ENCODING 57 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +70 +10 +60 +00 +ENDCHAR +STARTCHAR : +ENCODING 58 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +60 +00 +60 +60 +00 +ENDCHAR +STARTCHAR ; +ENCODING 59 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +60 +00 +60 +40 +80 +ENDCHAR +STARTCHAR < +ENCODING 60 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +40 +80 +40 +20 +00 +ENDCHAR +STARTCHAR = +ENCODING 61 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +f0 +00 +f0 +00 +00 +ENDCHAR +STARTCHAR > +ENCODING 62 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +80 +40 +20 +40 +80 +00 +ENDCHAR +STARTCHAR ? +ENCODING 63 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +20 +40 +00 +40 +00 +ENDCHAR +STARTCHAR @ +ENCODING 64 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +b0 +b0 +80 +60 +00 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +e0 +90 +90 +e0 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +80 +80 +90 +60 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +90 +90 +90 +e0 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +80 +b0 +90 +70 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +f0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +10 +10 +10 +10 +90 +60 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +a0 +c0 +c0 +a0 +90 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +80 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +f0 +f0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +d0 +d0 +b0 +b0 +90 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +90 +e0 +80 +80 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +d0 +60 +10 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +90 +90 +e0 +a0 +90 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +40 +20 +90 +60 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +40 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +60 +60 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +f0 +f0 +90 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +a0 +40 +40 +40 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +10 +20 +40 +80 +f0 +00 +ENDCHAR +STARTCHAR [ +ENCODING 91 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +80 +80 +80 +80 +e0 +00 +ENDCHAR +STARTCHAR \ +ENCODING 92 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +80 +40 +20 +10 +00 +00 +ENDCHAR +STARTCHAR ] +ENCODING 93 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +20 +20 +20 +20 +e0 +00 +ENDCHAR +STARTCHAR ^ +ENCODING 94 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR _ +ENCODING 95 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +f0 +00 +ENDCHAR +STARTCHAR ` +ENCODING 96 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +40 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +e0 +90 +90 +e0 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +80 +80 +60 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +10 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +40 +e0 +40 +40 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +90 +60 +80 +70 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +e0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +00 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +00 +20 +20 +20 +a0 +40 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +a0 +c0 +a0 +90 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +a0 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +e0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +e0 +90 +90 +e0 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +90 +90 +70 +10 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +e0 +90 +80 +80 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +00 +00 +70 +c0 +30 +e0 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +40 +e0 +40 +40 +30 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +a0 +a0 +a0 +40 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +f0 +f0 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +50 +20 +40 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +f0 +20 +40 +f0 +00 +ENDCHAR +STARTCHAR { +ENCODING 123 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +c0 +40 +40 +20 +00 +ENDCHAR +STARTCHAR | +ENCODING 124 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +40 +40 +40 +40 +40 +00 +ENDCHAR +STARTCHAR } +ENCODING 125 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 6 7 0 -1 +BITMAP +80 +40 +60 +40 +40 +80 +00 +ENDCHAR +STARTCHAR ~ +ENCODING 126 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Blank +ENCODING 127 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C160 +ENCODING 160 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C161 +ENCODING 161 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +00 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR C162 +ENCODING 162 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +70 +a0 +a0 +70 +20 +ENDCHAR +STARTCHAR C163 +ENCODING 163 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +30 +40 +e0 +40 +b0 +00 +ENDCHAR +STARTCHAR C164 +ENCODING 164 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +88 +70 +50 +70 +88 +00 +ENDCHAR +STARTCHAR C165 +ENCODING 165 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +40 +e0 +40 +40 +00 +ENDCHAR +STARTCHAR C166 +ENCODING 166 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +20 +20 +00 +20 +20 +00 +ENDCHAR +STARTCHAR C167 +ENCODING 167 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +30 +40 +60 +50 +30 +10 +60 +ENDCHAR +STARTCHAR C168 +ENCODING 168 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C169 +ENCODING 169 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +88 +a8 +c8 +a8 +88 +70 +ENDCHAR +STARTCHAR C170 +ENCODING 170 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +a0 +60 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C171 +ENCODING 171 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +48 +90 +48 +00 +00 +ENDCHAR +STARTCHAR C172 +ENCODING 172 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +f0 +10 +00 +00 +00 +ENDCHAR +STARTCHAR C173 +ENCODING 173 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +f0 +00 +00 +00 +ENDCHAR +STARTCHAR C174 +ENCODING 174 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +88 +e8 +c8 +c8 +88 +70 +ENDCHAR +STARTCHAR C175 +ENCODING 175 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C176 +ENCODING 176 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C177 +ENCODING 177 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +20 +f8 +20 +20 +f8 +00 +ENDCHAR +STARTCHAR C178 +ENCODING 178 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +20 +40 +60 +00 +00 +00 +ENDCHAR +STARTCHAR C179 +ENCODING 179 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +60 +20 +60 +00 +00 +00 +ENDCHAR +STARTCHAR C180 +ENCODING 180 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C181 +ENCODING 181 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +90 +90 +e0 +80 +ENDCHAR +STARTCHAR C182 +ENCODING 182 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +d0 +d0 +50 +50 +50 +00 +ENDCHAR +STARTCHAR C183 +ENCODING 183 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +60 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C184 +ENCODING 184 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +00 +00 +00 +20 +40 +ENDCHAR +STARTCHAR C185 +ENCODING 185 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +60 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR C186 +ENCODING 186 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR C187 +ENCODING 187 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +48 +90 +00 +00 +ENDCHAR +STARTCHAR C188 +ENCODING 188 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +80 +90 +30 +70 +10 +ENDCHAR +STARTCHAR C189 +ENCODING 189 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +80 +80 +b0 +10 +20 +30 +ENDCHAR +STARTCHAR C190 +ENCODING 190 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +c0 +c0 +40 +d0 +30 +70 +10 +ENDCHAR +STARTCHAR C191 +ENCODING 191 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +00 +40 +80 +a0 +40 +00 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C193 +ENCODING 193 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C194 +ENCODING 194 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C195 +ENCODING 195 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C196 +ENCODING 196 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C197 +ENCODING 197 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +f0 +90 +90 +00 +ENDCHAR +STARTCHAR C198 +ENCODING 198 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +a0 +b0 +e0 +a0 +b0 +00 +ENDCHAR +STARTCHAR C199 +ENCODING 199 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +80 +80 +90 +60 +40 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C201 +ENCODING 201 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C202 +ENCODING 202 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C203 +ENCODING 203 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +f0 +80 +e0 +80 +80 +f0 +00 +ENDCHAR +STARTCHAR C204 +ENCODING 204 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C205 +ENCODING 205 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C206 +ENCODING 206 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C207 +ENCODING 207 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +40 +40 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C208 +ENCODING 208 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +e0 +50 +d0 +50 +50 +e0 +00 +ENDCHAR +STARTCHAR C209 +ENCODING 209 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +b0 +90 +d0 +b0 +b0 +90 +00 +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C211 +ENCODING 211 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C212 +ENCODING 212 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C213 +ENCODING 213 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C214 +ENCODING 214 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C215 +ENCODING 215 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR C216 +ENCODING 216 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +70 +b0 +b0 +d0 +d0 +e0 +00 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C218 +ENCODING 218 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C219 +ENCODING 219 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C220 +ENCODING 220 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C221 +ENCODING 221 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +a0 +a0 +40 +40 +40 +00 +ENDCHAR +STARTCHAR C222 +ENCODING 222 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +e0 +90 +e0 +80 +80 +00 +ENDCHAR +STARTCHAR C223 +ENCODING 223 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +90 +e0 +90 +d0 +a0 +80 +ENDCHAR +STARTCHAR a-grave +ENCODING 224 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C225 +ENCODING 225 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C226 +ENCODING 226 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +50 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C227 +ENCODING 227 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C228 +ENCODING 228 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C229 +ENCODING 229 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +60 +70 +90 +b0 +50 +00 +ENDCHAR +STARTCHAR C230 +ENCODING 230 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +b0 +a0 +70 +00 +ENDCHAR +STARTCHAR C231 +ENCODING 231 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +60 +80 +80 +60 +40 +ENDCHAR +STARTCHAR e-grave +ENCODING 232 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C233 +ENCODING 233 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C234 +ENCODING 234 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C235 +ENCODING 235 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +00 +60 +b0 +c0 +60 +00 +ENDCHAR +STARTCHAR C236 +ENCODING 236 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +80 +40 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C237 +ENCODING 237 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +80 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C238 +ENCODING 238 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +a0 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C239 +ENCODING 239 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +00 +c0 +40 +40 +e0 +00 +ENDCHAR +STARTCHAR C240 +ENCODING 240 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +30 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C241 +ENCODING 241 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +e0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR C242 +ENCODING 242 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C243 +ENCODING 243 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C244 +ENCODING 244 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C245 +ENCODING 245 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +a0 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C246 +ENCODING 246 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +a0 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR C247 +ENCODING 247 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +60 +00 +f0 +00 +60 +00 +ENDCHAR +STARTCHAR C248 +ENCODING 248 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +00 +70 +b0 +d0 +e0 +00 +ENDCHAR +STARTCHAR C249 +ENCODING 249 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +40 +20 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C250 +ENCODING 250 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C251 +ENCODING 251 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +60 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C252 +ENCODING 252 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR C253 +ENCODING 253 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +20 +40 +90 +90 +50 +20 +40 +ENDCHAR +STARTCHAR C254 +ENCODING 254 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +00 +80 +e0 +90 +90 +e0 +80 +ENDCHAR +STARTCHAR C255 +ENCODING 255 +SWIDTH 686 0 +DWIDTH 5 0 +BBX 5 7 0 -1 +BITMAP +50 +00 +90 +90 +50 +20 +40 +ENDCHAR +ENDFONT diff --git a/src/draw/Makefile b/src/draw/Makefile new file mode 100644 index 00000000..0a542a1f --- /dev/null +++ b/src/draw/Makefile @@ -0,0 +1,4 @@ +BDF=5x7.bdf + +ao_font.h: font-convert $(BDF) +	nickle font-convert $(BDF) > $@ diff --git a/src/draw/ao_blt.c b/src/draw/ao_blt.c new file mode 100644 index 00000000..e3f45221 --- /dev/null +++ b/src/draw/ao_blt.c @@ -0,0 +1,294 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" + +#define O 0 +#define I AO_ALLONES + +struct ao_merge_rop { +	uint32_t	ca1, cx1, ca2, cx2; +}; + +const struct ao_merge_rop ao_merge_rop[16] = { +    {O, O, O, O},               /* clear         0x0         0 */ +    {I, O, O, O},               /* and           0x1         src AND dst */ +    {I, O, I, O},               /* andReverse    0x2         src AND NOT dst */ +    {O, O, I, O},               /* copy          0x3         src */ +    {I, I, O, O},               /* andInverted   0x4         NOT src AND dst */ +    {O, I, O, O},               /* noop          0x5         dst */ +    {O, I, I, O},               /* xor           0x6         src XOR dst */ +    {I, I, I, O},               /* or            0x7         src OR dst */ +    {I, I, I, I},               /* nor           0x8         NOT src AND NOT dst */ +    {O, I, I, I},               /* equiv         0x9         NOT src XOR dst */ +    {O, I, O, I},               /* invert        0xa         NOT dst */ +    {I, I, O, I},               /* orReverse     0xb         src OR NOT dst */ +    {O, O, I, I},               /* copyInverted  0xc         NOT src */ +    {I, O, I, I},               /* orInverted    0xd         NOT src OR dst */ +    {I, O, O, I},               /* nand          0xe         NOT src OR NOT dst */ +    {O, O, O, I},               /* set           0xf         1 */ +}; + +#define ao_do_merge_rop(src, dst) \ +    (((dst) & (((src) & _ca1) ^ _cx1)) ^ (((src) & _ca2) ^ _cx2)) + +#define ao_do_dst_invarient_merge_rop(src)	(((src) & _ca2) ^ _cx2) + +#define ao_do_mask_merge_rop(src, dst, mask) \ +    (((dst) & ((((src) & _ca1) ^ _cx1) | ~(mask))) ^ ((((src) & _ca2) ^ _cx2) & (mask))) + +#define ao_dst_invarient_merge_rop()   (_ca1 == 0 && _cx1 == 0) + +void +ao_blt(uint32_t		*src_line, +       int16_t		src_stride, +       int16_t		src_x, +       uint32_t		*dst_line, +       int16_t		dst_stride, +       int16_t		dst_x, +       int16_t		width, +       int16_t		height, +       uint8_t		rop, +       uint8_t		reverse, +       uint8_t		upsidedown) +{ +	uint32_t	*src, *dst; +	uint32_t	_ca1, _cx1, _ca2, _cx2; +	uint8_t		dst_invarient; +	uint32_t	startmask, endmask; +	int16_t		nmiddle, n; +	uint32_t	bits1, bits; +	int16_t		left_shift, right_shift; + +	_ca1 = ao_merge_rop[rop].ca1; +	_cx1 = ao_merge_rop[rop].cx1; +	_ca2 = ao_merge_rop[rop].ca2; +	_cx2 = ao_merge_rop[rop].cx2; +	dst_invarient = ao_dst_invarient_merge_rop(); + +	if (upsidedown) { +		src_line += (height - 1) * src_stride; +		dst_line += (height - 1) * dst_stride; +		src_stride = -src_stride; +		dst_stride = -dst_stride; +	} + +	ao_mask_bits(dst_x, width, startmask, nmiddle, endmask); +	if (reverse) { +		src_line += ((src_x + width - 1) >> AO_SHIFT) + 1; +		dst_line += ((dst_x + width - 1) >> AO_SHIFT) + 1; +		src_x = (src_x + width - 1) & AO_MASK; +		dst_x = (dst_x + width - 1) & AO_MASK; +	} else { +		src_line += src_x >> AO_SHIFT; +		dst_line += dst_x >> AO_SHIFT; +		src_x &= AO_MASK; +		dst_x &= AO_MASK; +	} +	if (src_x == dst_x) { +		while (height--) { +			src = src_line; +			src_line += src_stride; +			dst = dst_line; +			dst_line += dst_stride; +			if (reverse) { +				if (endmask) { +					bits = *--src; +					--dst; +					*dst = ao_do_mask_merge_rop(bits, *dst, endmask); +				} +				n = nmiddle; +				if (dst_invarient) { +					while (n--) +						*--dst = ao_do_dst_invarient_merge_rop(*--src); +				} +				else { +					while (n--) { +						bits = *--src; +						--dst; +						*dst = ao_do_merge_rop(bits, *dst); +					} +				} +				if (startmask) { +					bits = *--src; +					--dst; +					*dst = ao_do_mask_merge_rop(bits, *dst, startmask); +				} +			} +			else { +				if (startmask) { +					bits = *src++; +					*dst = ao_do_mask_merge_rop(bits, *dst, startmask); +					dst++; +				} +				n = nmiddle; +				if (dst_invarient) { +					while (n--) +						*dst++ = ao_do_dst_invarient_merge_rop(*src++); +				} +				else { +					while (n--) { +						bits = *src++; +						*dst = ao_do_merge_rop(bits, *dst); +						dst++; +					} +				} +				if (endmask) { +					bits = *src; +					*dst = ao_do_mask_merge_rop(bits, *dst, endmask); +				} +			} +		} +	} else { +		if (src_x > dst_x) { +			left_shift = src_x - dst_x; +			right_shift = AO_UNIT - left_shift; +		} else { +			right_shift = dst_x - src_x; +			left_shift = AO_UNIT - right_shift; +		} +		while (height--) { +			src = src_line; +			src_line += src_stride; +			dst = dst_line; +			dst_line += dst_stride; + +			bits1 = 0; +			if (reverse) { +				if (src_x < dst_x) +					bits1 = *--src; +				if (endmask) { +					bits = ao_right(bits1, right_shift); +					if (ao_right(endmask, left_shift)) { +						bits1 = *--src; +						bits |= ao_left(bits1, left_shift); +					} +					--dst; +					*dst = ao_do_mask_merge_rop(bits, *dst, endmask); +				} +				n = nmiddle; +				if (dst_invarient) { +					while (n--) { +						bits = ao_right(bits1, right_shift); +						bits1 = *--src; +						bits |= ao_left(bits1, left_shift); +						--dst; +						*dst = ao_do_dst_invarient_merge_rop(bits); +					} +				} else { +					while (n--) { +						bits = ao_right(bits1, right_shift); +						bits1 = *--src; +						bits |= ao_left(bits1, left_shift); +						--dst; +						*dst = ao_do_merge_rop(bits, *dst); +					} +				} +				if (startmask) { +					bits = ao_right(bits1, right_shift); +					if (ao_right(startmask, left_shift)) { +						bits1 = *--src; +						bits |= ao_left(bits1, left_shift); +					} +					--dst; +					*dst = ao_do_mask_merge_rop(bits, *dst, startmask); +				} +			} +			else { +				if (src_x > dst_x) +					bits1 = *src++; +				if (startmask) { +					bits = ao_left(bits1, left_shift); +					if (ao_left(startmask, right_shift)) { +						bits1 = *src++; +						bits |= ao_right(bits1, right_shift); +					} +					*dst = ao_do_mask_merge_rop(bits, *dst, startmask); +					dst++; +				} +				n = nmiddle; +				if (dst_invarient) { +					while (n--) { +						bits = ao_left(bits1, left_shift); +						bits1 = *src++; +						bits |= ao_right(bits1, right_shift); +						*dst = ao_do_dst_invarient_merge_rop(bits); +						dst++; +					} +				} +				else { +					while (n--) { +						bits = ao_left(bits1, left_shift); +						bits1 = *src++; +						bits |= ao_right(bits1, right_shift); +						*dst = ao_do_merge_rop(bits, *dst); +						dst++; +					} +				} +				if (endmask) { +					bits = ao_left(bits1, left_shift); +					if (ao_left(endmask, right_shift)) { +						bits1 = *src; +						bits |= ao_right(bits1, right_shift); +					} +					*dst = ao_do_mask_merge_rop(bits, *dst, endmask); +				} +			} +		} +	} +} + +void +ao_solid(uint32_t	and, +	 uint32_t	xor, +	 uint32_t	*dst, +	 int16_t	dst_stride, +	 int16_t	dst_x, +	 int16_t	width, +	 int16_t	height) +{ +	uint32_t	startmask, endmask; +	int16_t		nmiddle; +	int16_t		n; + +	dst += dst_x >> AO_SHIFT; +	dst_x &= AO_MASK; + +	ao_mask_bits(dst_x, width, startmask, nmiddle, endmask); + +	if (startmask) +		dst_stride--; + +	dst_stride -= nmiddle; +	while (height--) { +		if (startmask) { +			*dst = ao_do_mask_rrop(*dst, and, xor, startmask); +			dst++; +		} +		n = nmiddle; +		if (!and) +			while (n--) +				*dst++ = xor; +		else +			while (n--) { +				*dst = ao_do_rrop(*dst, and, xor); +				dst++; +			} +		if (endmask) +			*dst = ao_do_mask_rrop(*dst, and, xor, endmask); +		dst += dst_stride; +	} +} diff --git a/src/draw/ao_copy.c b/src/draw/ao_copy.c new file mode 100644 index 00000000..47067bb8 --- /dev/null +++ b/src/draw/ao_copy.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" + +#define bound(val,max,other) do {		\ +		if (val < 0) {			\ +			other -= val;		\ +			val = 0;		\ +		}				\ +		if (val > max) {		\ +			other -= (val - max);	\ +			val = max;		\ +		}				\ +	} while (0) + +#define bound2(a, max_a, b, max_b) do {		\ +		bound(a, max_a, b);		\ +		bound(b, max_b, a);		\ +	} while (0) + +void +ao_copy(const struct ao_bitmap	*dst, +	int16_t			dst_x, +	int16_t			dst_y, +	int16_t			width, +	int16_t			height, +	const struct ao_bitmap	*src, +	int16_t			src_x, +	int16_t			src_y, +	uint8_t			rop) +{ +	int16_t		dst_x2 = dst_x + width, dst_y2 = dst_y + height; +	int16_t		src_x2 = src_x + width, src_y2 = src_y + height; +	uint8_t		reverse = 0; +	uint8_t		upsidedown = 0; + +	bound2(dst_x, dst->width, src_x, src->width); +	bound2(dst_x2, dst->width, src_x2, src->width); +	bound2(dst_y, dst->height, src_y, src->height); +	bound2(dst_y2, dst->height, src_y2, src->height); + +	if (dst == src) { +		reverse = (dst_x > src_x); +		upsidedown = (dst_y > src_y); +	} + +	if (dst_x < dst_x2 && dst_y < dst_y2) { +		ao_blt(src->base + src_y * src->stride, +		       src->stride, +		       src_x, +		       dst->base + dst_y * dst->stride, +		       dst->stride, +		       dst_x, +		       dst_x2 - dst_x, +		       dst_y2 - dst_y, +		       rop, +		       reverse, +		       upsidedown); +	} +} + diff --git a/src/draw/ao_draw.h b/src/draw/ao_draw.h new file mode 100644 index 00000000..92150fc1 --- /dev/null +++ b/src/draw/ao_draw.h @@ -0,0 +1,119 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#ifndef _AO_DRAW_H_ +#define _AO_DRAW_H_ + +struct ao_bitmap { +	uint32_t	*base; +	int16_t		stride;	/* in units */ +	int16_t		width;	/* in pixels */ +	int16_t		height;	/* in pixels */ +}; + +struct ao_pattern { +	uint8_t		pattern[8]; +}; + +void +ao_copy(const struct ao_bitmap	*dst, +	int16_t			dst_x, +	int16_t			dst_y, +	int16_t			width, +	int16_t			height, +	const struct ao_bitmap	*src, +	int16_t			src_x, +	int16_t			src_y, +	uint8_t			rop); + +void +ao_rect(const struct ao_bitmap	*dst, +	int16_t			x, +	int16_t			y, +	int16_t			width, +	int16_t			height, +	uint32_t		fill, +	uint8_t			rop); + +void +ao_pattern(const struct ao_bitmap	*dst, +	   int16_t			x, +	   int16_t			y, +	   int16_t			width, +	   int16_t			height, +	   const struct ao_pattern	*pattern, +	   int16_t			pat_x, +	   int16_t			pat_y, +	   uint8_t			rop); + +void +ao_line(const struct ao_bitmap	*dst, +	int16_t			x1, +	int16_t			y1, +	int16_t			x2, +	int16_t			y2, +	uint32_t		fill, +	uint8_t			rop); + +void +ao_text(const struct ao_bitmap	*dst, +	int16_t			x, +	int16_t			y, +	char			*string, +	uint32_t		fill, +	uint8_t			rop); + +struct ao_font { +	int	width; +	int	height; +	int	ascent; +	int	descent; +}; + +extern const struct ao_font ao_font; + +#define AO_SHIFT	5 +#define AO_UNIT		(1 << AO_SHIFT) +#define AO_MASK		(AO_UNIT - 1) +#define AO_ALLONES	((uint32_t) -1) + +/* + *	    dst + *	   0   1 + * + *	0  a   b + *  src + *	1  c   d + * + *	ROP = abcd + */ + +#define AO_CLEAR         0x0	/* 0 */ +#define AO_AND           0x1	/* src AND dst */ +#define AO_AND_REVERSE   0x2	/* src AND NOT dst */ +#define AO_COPY          0x3	/* src */ +#define AO_AND_INVERTED  0x4	/* NOT src AND dst */ +#define AO_NOOP          0x5	/* dst */ +#define AO_XOR           0x6	/* src XOR dst */ +#define AO_OR            0x7	/* src OR dst */ +#define AO_NOR           0x8	/* NOT src AND NOT dst */ +#define AO_EQUIV         0x9	/* NOT src XOR dst */ +#define AO_INVERT        0xa	/* NOT dst */ +#define AO_OR_REVERSE    0xb	/* src OR NOT dst */ +#define AO_COPY_INVERTED 0xc	/* NOT src */ +#define AO_OR_INVERTED   0xd	/* NOT src OR dst */ +#define AO_NAND          0xe	/* NOT src OR NOT dst */ +#define AO_SET           0xf	/* 1 */ + +#endif /* _AO_DRAW_H_ */ diff --git a/src/draw/ao_draw_int.h b/src/draw/ao_draw_int.h new file mode 100644 index 00000000..433aa409 --- /dev/null +++ b/src/draw/ao_draw_int.h @@ -0,0 +1,136 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#ifndef _AO_DRAW_INT_H_ +#define _AO_DRAW_INT_H_ + +static inline uint32_t +ao_expand(uint32_t bits) +{ +	return ~((bits & 1)-1); +} + +static inline uint32_t +ao_xor(uint8_t rop, uint32_t fg) +{ +	fg = ao_expand(fg); + +	return (fg & ao_expand(rop >> 1)) | +		(~fg & ao_expand(rop >> 3)); +} + +static inline uint32_t +ao_and(uint8_t rop, uint32_t fg) +{ +	fg = ao_expand(fg); + +	return (fg & ao_expand(rop ^ (rop >> 1))) | +		(~fg & ao_expand((rop>>2) ^ (rop>>3))); +} + +static inline uint32_t +ao_left(uint32_t bits, int16_t shift) { +	return bits >> shift; +} + +static inline uint32_t +ao_right(uint32_t bits, int16_t shift) { +	return bits << shift; +} + +static inline uint32_t +ao_right_mask(int16_t x) { +	if ((AO_UNIT - x) & AO_MASK) +		return ao_left(AO_ALLONES,(AO_UNIT - x) & AO_MASK); +	else +		return 0; +} + +static inline uint32_t +ao_left_mask(int16_t x) { +	if (x & AO_MASK) +		return ao_right(AO_ALLONES, x & AO_MASK); +	else +		return 0; +} + +static inline uint32_t +ao_bits_mask(int16_t x, int16_t w) { +	return ao_right(AO_ALLONES, x & AO_MASK) & +		ao_left(AO_ALLONES,(AO_UNIT - (x + w)) & AO_MASK); +} + +#define ao_mask_bits(x,w,l,n,r) { \ +    n = (w); \ +    r = ao_right_mask((x)+n); \ +    l = ao_left_mask(x); \ +    if (l) { \ +	n -= AO_UNIT - ((x) & AO_MASK); \ +	if (n < 0) { \ +	    n = 0; \ +	    l &= r; \ +	    r = 0; \ +	} \ +    } \ +    n >>= AO_SHIFT; \ +} + +#define ao_clip(val,min,max) do {		\ +		if (val < min) {		\ +			val = min;		\ +		} else if (val > max) {		\ +			val = max;		\ +		}				\ +	} while (0) + +static inline uint32_t +ao_do_mask_rrop(uint32_t dst, uint32_t and, uint32_t xor, uint32_t mask) { +	return (dst & (and | ~mask)) ^ (xor & mask); +} + +static inline uint32_t +ao_do_rrop(uint32_t dst, uint32_t and, uint32_t xor) { +	return (dst & and) ^ xor; +} + +void +ao_blt(uint32_t		*src_line, +       int16_t		src_stride, +       int16_t		src_x, +       uint32_t		*dst_line, +       int16_t		dst_stride, +       int16_t		dst_x, +       int16_t		width, +       int16_t		height, +       uint8_t		rop, +       uint8_t		reverse, +       uint8_t		upsidedown); + +void +ao_solid(uint32_t	and, +	 uint32_t	xor, +	 uint32_t	*dst, +	 int16_t	dst_stride, +	 int16_t	dst_x, +	 int16_t	width, +	 int16_t	height); + +int16_t +ao_glyph(const struct ao_bitmap	*dst, +	 int16_t		x, +	 int16_t		y, +	 uint8_t		c, +	 uint8_t		rop); + +#endif /* _AO_DRAW_INT_H_ */ diff --git a/src/draw/ao_font.h b/src/draw/ao_font.h new file mode 100644 index 00000000..5e31dd11 --- /dev/null +++ b/src/draw/ao_font.h @@ -0,0 +1,139 @@ +static const uint8_t glyph_bytes[1568] = { +	0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x04, 0x0e, 0x1f, 0x0e, 0x04, 0x00, 0x0a, 0x05,  +	0x0a, 0x05, 0x0a, 0x05, 0x00, 0x05, 0x07, 0x05, 0x05, 0x0e, 0x04, 0x04, 0x03, 0x01, 0x03, 0x0d,  +	0x04, 0x0c, 0x04, 0x03, 0x01, 0x03, 0x06, 0x0a, 0x06, 0x0a, 0x01, 0x01, 0x03, 0x0c, 0x04, 0x0c,  +	0x04, 0x04, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x0e, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x09,  +	0x0b, 0x0d, 0x09, 0x04, 0x04, 0x0c, 0x05, 0x05, 0x05, 0x02, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04,  +	0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x1c, 0x04,  +	0x04, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x04,  +	0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x1f, 0x00, 0x04, 0x04, 0x04, 0x1c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x04,  +	0x04, 0x04, 0x04, 0x04, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04,  +	0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x04, 0x02, 0x04, 0x08, 0x0e, 0x00, 0x02, 0x04, 0x08,  +	0x04, 0x02, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x0a, 0x0a, 0x0a, 0x00, 0x00, 0x08, 0x0e, 0x04, 0x0e,  +	0x02, 0x00, 0x00, 0x0c, 0x02, 0x07, 0x02, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x00, 0x0a, 0x0a,  +	0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x1f, 0x0a, 0x1f, 0x0a, 0x00, 0x00, 0x0e, 0x05, 0x0e,  +	0x14, 0x0e, 0x00, 0x01, 0x09, 0x04, 0x02, 0x09, 0x08, 0x00, 0x00, 0x02, 0x05, 0x02, 0x05, 0x0a,  +	0x00, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x02,  +	0x04, 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, 0x05, 0x02, 0x07, 0x02, 0x05, 0x00, 0x00, 0x04, 0x04,  +	0x1f, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00,  +	0x02, 0x05, 0x05, 0x05, 0x05, 0x02, 0x00, 0x02, 0x03, 0x02, 0x02, 0x02, 0x07, 0x00, 0x06, 0x09,  +	0x08, 0x04, 0x02, 0x0f, 0x00, 0x0f, 0x08, 0x06, 0x08, 0x09, 0x06, 0x00, 0x04, 0x06, 0x05, 0x0f,  +	0x04, 0x04, 0x00, 0x0f, 0x01, 0x07, 0x08, 0x09, 0x06, 0x00, 0x06, 0x01, 0x07, 0x09, 0x09, 0x06,  +	0x00, 0x0f, 0x08, 0x04, 0x04, 0x02, 0x02, 0x00, 0x06, 0x09, 0x06, 0x09, 0x09, 0x06, 0x00, 0x06,  +	0x09, 0x09, 0x0e, 0x08, 0x06, 0x00, 0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x06,  +	0x00, 0x06, 0x02, 0x01, 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0f,  +	0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x02, 0x01, 0x00, 0x02, 0x05, 0x04, 0x02, 0x00, 0x02, 0x00,  +	0x06, 0x09, 0x0d, 0x0d, 0x01, 0x06, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x07, 0x09,  +	0x07, 0x09, 0x09, 0x07, 0x00, 0x06, 0x09, 0x01, 0x01, 0x09, 0x06, 0x00, 0x07, 0x09, 0x09, 0x09,  +	0x09, 0x07, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x01,  +	0x00, 0x06, 0x09, 0x01, 0x0d, 0x09, 0x0e, 0x00, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x09, 0x00, 0x07,  +	0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x08, 0x08, 0x08, 0x08, 0x09, 0x06, 0x00, 0x09, 0x05, 0x03,  +	0x03, 0x05, 0x09, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x0f, 0x00, 0x09, 0x0f, 0x0f, 0x09, 0x09,  +	0x09, 0x00, 0x09, 0x0b, 0x0b, 0x0d, 0x0d, 0x09, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00,  +	0x07, 0x09, 0x09, 0x07, 0x01, 0x01, 0x00, 0x06, 0x09, 0x09, 0x09, 0x0b, 0x06, 0x08, 0x07, 0x09,  +	0x09, 0x07, 0x05, 0x09, 0x00, 0x06, 0x09, 0x02, 0x04, 0x09, 0x06, 0x00, 0x07, 0x02, 0x02, 0x02,  +	0x02, 0x02, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x06, 0x06,  +	0x00, 0x09, 0x09, 0x09, 0x0f, 0x0f, 0x09, 0x00, 0x09, 0x09, 0x06, 0x06, 0x09, 0x09, 0x00, 0x05,  +	0x05, 0x05, 0x02, 0x02, 0x02, 0x00, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x00, 0x07, 0x01, 0x01,  +	0x01, 0x01, 0x07, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00, 0x07, 0x04, 0x04, 0x04, 0x04,  +	0x07, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,  +	0x03, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x01, 0x01,  +	0x07, 0x09, 0x09, 0x07, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x00, 0x08, 0x08, 0x0e, 0x09,  +	0x09, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x04, 0x0a, 0x02, 0x07, 0x02, 0x02,  +	0x00, 0x00, 0x00, 0x0e, 0x09, 0x06, 0x01, 0x0e, 0x01, 0x01, 0x07, 0x09, 0x09, 0x09, 0x00, 0x02,  +	0x00, 0x03, 0x02, 0x02, 0x07, 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x05, 0x02, 0x01, 0x01, 0x05,  +	0x03, 0x05, 0x09, 0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x00, 0x00, 0x05, 0x0f, 0x09,  +	0x09, 0x00, 0x00, 0x00, 0x07, 0x09, 0x09, 0x09, 0x00, 0x00, 0x00, 0x06, 0x09, 0x09, 0x06, 0x00,  +	0x00, 0x00, 0x07, 0x09, 0x09, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x09, 0x09, 0x0e, 0x08, 0x00, 0x00,  +	0x07, 0x09, 0x01, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x03, 0x0c, 0x07, 0x00, 0x02, 0x02, 0x07, 0x02,  +	0x02, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x05, 0x05, 0x02,  +	0x00, 0x00, 0x00, 0x09, 0x09, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x06, 0x06, 0x09, 0x00, 0x00,  +	0x00, 0x09, 0x09, 0x0a, 0x04, 0x02, 0x00, 0x00, 0x0f, 0x04, 0x02, 0x0f, 0x00, 0x04, 0x02, 0x03,  +	0x02, 0x02, 0x04, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x01, 0x02, 0x06, 0x02, 0x02,  +	0x01, 0x00, 0x0a, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x04,  +	0x0e, 0x05, 0x05, 0x0e, 0x04, 0x00, 0x0c, 0x02, 0x07, 0x02, 0x0d, 0x00, 0x00, 0x11, 0x0e, 0x0a,  +	0x0e, 0x11, 0x00, 0x05, 0x05, 0x02, 0x07, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x04, 0x04,  +	0x00, 0x0c, 0x02, 0x06, 0x0a, 0x0c, 0x08, 0x06, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,  +	0x11, 0x15, 0x13, 0x15, 0x11, 0x0e, 0x06, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,  +	0x09, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00,  +	0x00, 0x00, 0x0e, 0x11, 0x17, 0x13, 0x13, 0x11, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  +	0x04, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x1f, 0x04, 0x04, 0x1f, 0x00, 0x06, 0x04,  +	0x02, 0x06, 0x00, 0x00, 0x00, 0x06, 0x06, 0x04, 0x06, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00,  +	0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x07, 0x01, 0x0e, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a,  +	0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x04,  +	0x06, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,  +	0x12, 0x09, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x0c, 0x0e, 0x08, 0x01, 0x01, 0x01, 0x0d, 0x08,  +	0x04, 0x0c, 0x03, 0x03, 0x02, 0x0b, 0x0c, 0x0e, 0x08, 0x02, 0x00, 0x02, 0x01, 0x05, 0x02, 0x00,  +	0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09,  +	0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f,  +	0x09, 0x09, 0x00, 0x06, 0x09, 0x09, 0x0f, 0x09, 0x09, 0x00, 0x0e, 0x05, 0x0d, 0x07, 0x05, 0x0d,  +	0x00, 0x06, 0x09, 0x01, 0x01, 0x09, 0x06, 0x02, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f,  +	0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07, 0x01, 0x01, 0x0f, 0x00, 0x0f, 0x01, 0x07,  +	0x01, 0x01, 0x0f, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02,  +	0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x00,  +	0x07, 0x0a, 0x0b, 0x0a, 0x0a, 0x07, 0x00, 0x0d, 0x09, 0x0b, 0x0d, 0x0d, 0x09, 0x00, 0x06, 0x09,  +	0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09,  +	0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x06, 0x09, 0x09, 0x09, 0x09, 0x06,  +	0x00, 0x00, 0x00, 0x09, 0x06, 0x06, 0x09, 0x00, 0x0e, 0x0d, 0x0d, 0x0b, 0x0b, 0x07, 0x00, 0x09,  +	0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09,  +	0x09, 0x09, 0x06, 0x00, 0x09, 0x09, 0x09, 0x09, 0x09, 0x06, 0x00, 0x05, 0x05, 0x05, 0x02, 0x02,  +	0x02, 0x00, 0x01, 0x07, 0x09, 0x07, 0x01, 0x01, 0x00, 0x06, 0x09, 0x07, 0x09, 0x0b, 0x05, 0x01,  +	0x02, 0x04, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x04, 0x02, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x04, 0x0a,  +	0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x0a, 0x05, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x0a, 0x00, 0x0e, 0x09,  +	0x0d, 0x0a, 0x00, 0x06, 0x06, 0x0e, 0x09, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x05, 0x0e,  +	0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x06, 0x02, 0x02, 0x04, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x04,  +	0x02, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x02, 0x05, 0x06, 0x0d, 0x03, 0x06, 0x00, 0x05, 0x00, 0x06,  +	0x0d, 0x03, 0x06, 0x00, 0x01, 0x02, 0x03, 0x02, 0x02, 0x07, 0x00, 0x02, 0x01, 0x03, 0x02, 0x02,  +	0x07, 0x00, 0x02, 0x05, 0x03, 0x02, 0x02, 0x07, 0x00, 0x05, 0x00, 0x03, 0x02, 0x02, 0x07, 0x00,  +	0x02, 0x0c, 0x06, 0x09, 0x09, 0x06, 0x00, 0x0a, 0x05, 0x07, 0x09, 0x09, 0x09, 0x00, 0x02, 0x04,  +	0x06, 0x09, 0x09, 0x06, 0x00, 0x04, 0x02, 0x06, 0x09, 0x09, 0x06, 0x00, 0x06, 0x00, 0x06, 0x09,  +	0x09, 0x06, 0x00, 0x0a, 0x05, 0x06, 0x09, 0x09, 0x06, 0x00, 0x05, 0x00, 0x06, 0x09, 0x09, 0x06,  +	0x00, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0e, 0x0d, 0x0b, 0x07, 0x00, 0x02,  +	0x04, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x04, 0x02, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x06, 0x00, 0x09,  +	0x09, 0x09, 0x0e, 0x00, 0x0a, 0x00, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x04, 0x02, 0x09, 0x09, 0x0a,  +	0x04, 0x02, 0x00, 0x01, 0x07, 0x09, 0x09, 0x07, 0x01, 0x0a, 0x00, 0x09, 0x09, 0x0a, 0x04, 0x02,  +}; + +static const uint16_t glyph_pos[256] = { +	   0,    7,   14,   21,   28,   35,   42,   49,  +	  56,   63,   70,   77,   84,   91,   98,  105,  +	 112,  119,  126,  133,  140,  147,  154,  161,  +	 168,  175,  182,  189,  196,  203,  210,  217,  +	 224,  231,  238,  245,  252,  259,  266,  273,  +	 280,  287,  294,  301,  308,  315,  322,  329,  +	 336,  343,  350,  357,  364,  371,  378,  385,  +	 392,  399,  406,  413,  420,  427,  434,  441,  +	 448,  455,  462,  469,  476,  483,  490,  497,  +	 504,  511,  518,  525,  532,  539,  546,  553,  +	 560,  567,  574,  581,  588,  595,  602,  609,  +	 616,  623,  630,  637,  644,  651,  658,  665,  +	 672,  679,  686,  693,  700,  707,  714,  721,  +	 728,  735,  742,  749,  756,  763,  770,  777,  +	 784,  791,  798,  805,  812,  819,  826,  833,  +	 840,  847,  854,  861,  868,  875,  882,  889,  +	   0,    0,    0,    0,    0,    0,    0,    0,  +	   0,    0,    0,    0,    0,    0,    0,    0,  +	   0,    0,    0,    0,    0,    0,    0,    0,  +	   0,    0,    0,    0,    0,    0,    0,    0,  +	 896,  903,  910,  917,  924,  931,  938,  945,  +	 952,  959,  966,  973,  980,  987,  994, 1001,  +	1008, 1015, 1022, 1029, 1036, 1043, 1050, 1057,  +	1064, 1071, 1078, 1085, 1092, 1099, 1106, 1113,  +	1120, 1127, 1134, 1141, 1148, 1155, 1162, 1169,  +	1176, 1183, 1190, 1197, 1204, 1211, 1218, 1225,  +	1232, 1239, 1246, 1253, 1260, 1267, 1274, 1281,  +	1288, 1295, 1302, 1309, 1316, 1323, 1330, 1337,  +	1344, 1351, 1358, 1365, 1372, 1379, 1386, 1393,  +	1400, 1407, 1414, 1421, 1428, 1435, 1442, 1449,  +	1456, 1463, 1470, 1477, 1484, 1491, 1498, 1505,  +	1512, 1519, 1526, 1533, 1540, 1547, 1554, 1561,  +}; + +#define GLYPH_WIDTH 5 +#define GLYPH_HEIGHT 7 +#define GLYPH_ASCENT 6 diff --git a/src/draw/ao_line.c b/src/draw/ao_line.c new file mode 100644 index 00000000..ed1fc21c --- /dev/null +++ b/src/draw/ao_line.c @@ -0,0 +1,314 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" + +#define ao_mask(x,w)	(ao_right(AO_ALLONES,(x) & AO_MASK) & \ +			 ao_left(AO_ALLONES,(FB_UNIT - ((x)+(w))) & AO_MASK)) + + +/* out of clip region codes */ +#define OUT_LEFT 0x08 +#define OUT_RIGHT 0x04 +#define OUT_ABOVE 0x02 +#define OUT_BELOW 0x01 + +/* major axis for bresenham's line */ +#define X_AXIS	0 +#define Y_AXIS	1 + +/* + * Line clipping. Clip to the box, bringing the coordinates forward while + * preserving the actual slope and error + * + * + *	X major line, clip X: + * + *	adjust_x = -x; + * + *	e += adjust_x * e1; + * + *	adjust_y = (e + -e3-1) / -e3; + * + *	e -= adjust_y / -e3; + * + *	X major line, clip Y: + * + *	adjust_y = -y; + + * + *	e -= adjust_y / -e3; + * + *	adjust_x = e / e1; + */ + + + + +static void +ao_bres(const struct ao_bitmap	*dst_bitmap, +	int16_t		signdx, +	int16_t		signdy, +	int16_t		axis, +	int16_t		x1, +	int16_t		y1, +	int16_t		e, +	int16_t		e1, +	int16_t		e3, +	int16_t		len, +	uint32_t	and, +	uint32_t	xor) +{ +	int16_t		stride = dst_bitmap->stride; +	uint32_t	*dst = dst_bitmap->base; +	uint32_t	mask0, mask; + +	mask0 = 1; +	if (signdx < 0) +		mask0 = ao_right(1, AO_UNIT - 1); + +	if (signdy < 0) +		stride = -stride; + +	dst = dst + y1 * stride + (x1 >> AO_SHIFT); +	mask = ao_right(1, x1 & AO_MASK); + +	while (len--) { +		/* clip each point */ + +		*dst = ao_do_mask_rrop(*dst, and, xor, mask); + +		if (axis == X_AXIS) { +			if (signdx < 0) +				mask = ao_left(mask, 1); +			else +				mask = ao_right(mask, 1); +			if (!mask) { +				dst += signdx; +				mask = mask0; +			} +			e += e1; +			if (e >= 0) { +				dst += stride; +				e += e3; +			} +		} else { +			dst += stride; +			e += e1; +			if (e >= 0) { +				if (signdx < 0) +					mask = ao_left(mask, 1); +				else +					mask = ao_right(mask, 1); +				if (!mask) { +					dst += signdx; +					mask = mask0; +				} +				e += e3; +			} +		} +	} +} + +struct ao_cc { +	int16_t	major; +	int16_t	minor; +	int16_t	sign_major; +	int16_t	sign_minor; +	int16_t	e; +	int16_t	e1; +	int16_t	e3; +	int8_t	first; +}; + +/* line clipping box */ +struct ao_cbox { +	int16_t	maj1, min1; +	int16_t	maj2, min2; +}; + +/* -b <= a, so we need to make a bigger */ +static int16_t +div_ceil(int32_t a, int16_t b) { +	return (a + b + b - 1) / b - 1; +} + +static int16_t +div_floor_plus_one(int32_t a, int16_t b) { +	return (a + b) / b; +} + +static int8_t +ao_clip_line(struct ao_cc *c, struct ao_cbox *b) +{ +	int32_t	adjust_major = 0, adjust_minor = 0; + +	/* Clip major axis */ +	if (c->major < b->maj1) { +		if (c->sign_major <= 0) +			return FALSE; +		adjust_major = b->maj1 - c->major; +	} else if (c->major >= b->maj2) { +		if (c->sign_major >= 0) +			return FALSE; +		adjust_major = c->major - (b->maj2-1); +	} + +	/* Clip minor axis */ +	if (c->minor < b->min1) { +		if (c->sign_minor <= 0) +			return FALSE; +		adjust_minor = b->min1 - c->minor; +	} else if (c->minor >= b->min2) { +		if (c->sign_minor >= 0) +			return FALSE; +		adjust_minor = c->minor - (b->min2-1); +	} + +	/* If unclipped, we're done */ +	if (adjust_major == 0 && adjust_minor == 0) +		return TRUE; + +	/* See how much minor adjustment would happen during +	 * a major clip. This is a bit tricky because line drawing +	 * isn't symmetrical when the line passes exactly between +	 * two pixels, we have to pick which one gets drawn +	 */ +	int32_t	adj_min; + +	if (!c->first) +		adj_min = div_ceil(c->e + adjust_major * c->e1, -c->e3); +	else +		adj_min = div_floor_plus_one(c->e + adjust_major * c->e1, -c->e3); + +	if (adj_min < adjust_minor) { +		if (c->first) +			adjust_major = div_ceil(c->e - adjust_minor * c->e3, c->e1); +		else +			adjust_major = div_floor_plus_one(c->e - adjust_minor * c->e3, c->e1); +	} else { +		adjust_minor = adj_min; +	} + +	c->e += adjust_major * c->e1 + adjust_minor * c->e3; + +	c->major += c->sign_major * adjust_major; +	c->minor += c->sign_minor * adjust_minor; + +	return TRUE; +} + +void +ao_line(const struct ao_bitmap	*dst, +	int16_t			x1, +	int16_t			y1, +	int16_t			x2, +	int16_t			y2, +	uint32_t		fill, +	uint8_t			rop) +{ +	int16_t	adx, ady; +	int16_t	e, e1, e2, e3; +	int16_t	signdx = 1, signdy = 1; +	int16_t axis; +	int16_t len; +	struct ao_cc	clip_1, clip_2; +	struct ao_cbox	cbox; + +	if ((adx = x2 - x1) < 0) { +		adx = -adx; +		signdx = -1; +	} +	if ((ady = y2 - y1) < 0) { +		ady = -ady; +		signdy = -1; +	} + +	if (adx > ady) { +		axis = X_AXIS; +		e1 = ady << 1; +		e2 = e1 - (adx << 1); +		e = e1 - adx; + +		clip_1.major = x1; +		clip_1.minor = y1; +		clip_2.major = x2; +		clip_2.minor = y2; +		clip_1.sign_major = signdx; +		clip_1.sign_minor = signdy; + +		cbox.maj1 = 0; +		cbox.maj2 = dst->width; +		cbox.min1 = 0; +		cbox.min2 = dst->height; +	} else { +		axis = Y_AXIS; +		e1 = adx << 1; +		e2 = e1 - (ady << 1); +		e = e1 - ady; + +		clip_1.major = y1; +		clip_1.minor = x1; +		clip_2.major = y2; +		clip_2.minor = x2; +		clip_1.sign_major = signdy; +		clip_1.sign_minor = signdx; + +		cbox.maj1 = 0; +		cbox.maj2 = dst->height; +		cbox.min1 = 0; +		cbox.min2 = dst->width; +	} + +	e3 = e2 - e1; +	e = e - e1; + +	clip_1.first = TRUE; +	clip_2.first = FALSE; +	clip_2.e = clip_1.e = e; +	clip_2.e1 = clip_1.e1 = e1; +	clip_2.e3 = clip_1.e3 = e3; +	clip_2.sign_major = -clip_1.sign_major; +	clip_2.sign_minor = -clip_1.sign_minor; + +	if (!ao_clip_line(&clip_1, &cbox)) +		return; + +	if (!ao_clip_line(&clip_2, &cbox)) +		return; + +	len = clip_1.sign_major * (clip_2.major - clip_1.major) + clip_2.first; + +	if (len <= 0) +		return; + +	if (adx > ady) { +		x1 = clip_1.major; +		y1 = clip_1.minor; +	} else { +		x1 = clip_1.minor; +		y1 = clip_1.major; +	} +	ao_bres(dst, +		signdx, +		signdy, +		axis, +		x1, +		y1, +		clip_1.e, e1, e3, len, +		ao_and(rop, fill), +		ao_xor(rop, fill)); +} diff --git a/src/draw/ao_pattern.c b/src/draw/ao_pattern.c new file mode 100644 index 00000000..0d1dc765 --- /dev/null +++ b/src/draw/ao_pattern.c @@ -0,0 +1,80 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" + +static inline uint32_t +ao_pattern_expand(uint8_t v, uint8_t rot) +{ +	uint32_t	r; + +	if (rot) +		v = ao_left(v, 8-rot) | ao_right(v, rot); +	r = v; +	return (r << 24) | (r << 16) | (r << 8) | (r); +} + +static inline int +min(int a, int b) { +	return a < b ? a : b; +} + +void +ao_pattern(const struct ao_bitmap	*dst, +	   int16_t			x, +	   int16_t			y, +	   int16_t			width, +	   int16_t			height, +	   const struct ao_pattern	*pattern, +	   int16_t			pat_x, +	   int16_t			pat_y, +	   uint8_t			rop) +{ +	uint32_t	pat[8]; + +	int16_t	x2 = x + width; +	int16_t y2 = y + height; + +	ao_clip(x, 0, dst->width); +	ao_clip(x2, 0, dst->width); +	ao_clip(y, 0, dst->height); +	ao_clip(y2, 0, dst->height); + +	if (x < x2 && y < y2) { +		int	xrot = (x - pat_x) & 7; +		int	yrot = (y - pat_y) & 7; +		int	i; +		int16_t	dst_x, dst_y; + +		for (i = 0; i < 8; i++) +			pat[(i + yrot) & 7] = ao_pattern_expand(pattern->pattern[i], xrot); +		for (dst_y = y; dst_y < y2; dst_y += 8) { +			int	h = min(y2 - dst_y, 8); +			for (dst_x = x; dst_x < x2; dst_x += 8) { +				int	w = min(x2 - dst_x, 8); + +				ao_blt(pat, 1, 0, +				       dst->base + dst_y * dst->stride, +				       dst->stride, +				       dst_x, +				       w, h, +				       rop, +				       0, 0); +			} +		} +	} +} + diff --git a/src/draw/ao_rect.c b/src/draw/ao_rect.c new file mode 100644 index 00000000..71fa4aea --- /dev/null +++ b/src/draw/ao_rect.c @@ -0,0 +1,46 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" + +void +ao_rect(const struct ao_bitmap	*dst, +	int16_t			x, +	int16_t			y, +	int16_t			width, +	int16_t			height, +	uint32_t		fill, +	uint8_t			rop) +{ +	int16_t	x2 = x + width; +	int16_t y2 = y + height; + +	ao_clip(x, 0, dst->width); +	ao_clip(x2, 0, dst->width); +	ao_clip(y, 0, dst->height); +	ao_clip(y2, 0, dst->height); + +	if (x < x2 && y < y2) { +		ao_solid(ao_and(rop, fill), +			 ao_xor(rop, fill), +			 dst->base + y * dst->stride, +			 dst->stride, +			 x, +			 x2 - x, +			 y2 - y); +	} +} + diff --git a/src/draw/ao_text.c b/src/draw/ao_text.c new file mode 100644 index 00000000..7ce2a623 --- /dev/null +++ b/src/draw/ao_text.c @@ -0,0 +1,65 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + */ + +#include "ao.h" +#include "ao_draw.h" +#include "ao_draw_int.h" +#include "ao_font.h" + +const struct ao_font ao_font = { +	.width = GLYPH_WIDTH, +	.height = GLYPH_HEIGHT, +	.ascent = GLYPH_ASCENT, +	.descent = GLYPH_HEIGHT - GLYPH_ASCENT, +}; + +void +ao_text(const struct ao_bitmap	*dst, +	int16_t			x, +	int16_t			y, +	char			*string, +	uint32_t		fill, +	uint8_t			rop) +{ +	uint32_t	src[GLYPH_HEIGHT]; +	char		c; +	int		h; + +	struct ao_bitmap	src_bitmap = { +		.base = src, +		.stride = 1, +		.width = GLYPH_WIDTH, +		.height = GLYPH_HEIGHT +	}; + +	y -= GLYPH_ASCENT; + +	rop = (rop & 3) | 0x4; + +	if ((fill&1) == 0) +		rop ^= 3; + +	while ((c = *string++)) { +		const uint8_t	*bytes = &glyph_bytes[glyph_pos[(uint8_t) c]]; + +		for (h = 0; h < GLYPH_HEIGHT; h++) +			src[h] = bytes[h]; + +		ao_copy(dst, +			x, y, GLYPH_WIDTH, GLYPH_HEIGHT, +			&src_bitmap, +			0, 0, rop); +		x += GLYPH_WIDTH; +	} +} diff --git a/src/draw/font-convert b/src/draw/font-convert new file mode 100755 index 00000000..1985e418 --- /dev/null +++ b/src/draw/font-convert @@ -0,0 +1,150 @@ +#!/usr/bin/nickle + +typedef struct { +	int[]	bytes; +	int	width; +	int	height; +	int	encoding; +	int	location; +} glyph_t; + +typedef struct { +	glyph_t[...]	glyphs; +	int		default_char; +	int		ascent; +} font_t; + +glyph_t +read_glyph(file f) +{ +	glyph_t	glyph = { .encoding = -1, .bytes = (int[...]){}, .width = 0 }; + +	while (!File::end(f)) { +		string	l = fgets(f); + +		string[*] tokens = String::split(l, " "); +		if (dim(tokens) == 0) +			continue; + +		switch (tokens[0]) { +		case "ENCODING": +			glyph.encoding = atoi(tokens[1]); +			break; +		case "DWIDTH": +			glyph.width = atoi(tokens[1]); +			break; +		case "BBX": +			glyph.height = atoi(tokens[2]); +			break; +		case "ENDCHAR": +			return glyph; +		case "BITMAP": +			while (!File::end(f)) { +				string l = fgets(f); +				if (l == "ENDCHAR") +					return glyph; +				glyph.bytes[dim(glyph.bytes)] = atoi(l, 16); +			} +			break; +		} +	} +	return glyph; +} + +font_t read_font(file f) { +	font_t	font = { .glyphs = {}, .default_char = -1 }; +	bool in_head = true; + +	while (in_head && !File::end(f)) { +		string l = File::fgets(f); + +		string[*] tokens = String::split(l, " "); +		switch (tokens[0]) { +		case "DEFAULT_CHAR": +			font.default_char = atoi(tokens[1]); +			break; +		case "FONT_ASCENT": +			font.ascent = atoi(tokens[1]); +			break; +		case "CHARS": +			in_head = false; +			break; +		} +	} +	while (!File::end(f)) { +		glyph_t	glyph = read_glyph(f); +		if (glyph.encoding == -1) +			break; +		font.glyphs[dim(font.glyphs)] = glyph; +	} +	return font; +} + +int +flip_byte(int x) +{ +	int	dest = 0; + +	for (int i = 0; i < 8; i++) +		dest |= ((x >> (7 - i)) & 1) << i; +	return dest; +} + +void print_font(font_t font) { +	int	width = font.glyphs[0].width; +	int	height = font.glyphs[0].height; +	int[256] pos = { -1 ... }; +	int[...] bytes; + +	if (false) { +	for (int i = 1; i < dim(font.glyphs); i++) { +		if (font.glyphs[i].width != width || +		   font.glyphs[i].height != height) +		{ +			File::fprintf(stderr, "font not constant size, glyph %d is %dx%d\n", +				      font.glyphs[i].encoding, font.glyphs[i].width, font.glyphs[i].height); +			exit(1); +		} +	} +	} + +	if (font.default_char == -1) +		font.default_char = font.glyphs[0].encoding; + +	/* build byte array */ +	for (int i = 0; i < dim(font.glyphs); i++) { +		pos[font.glyphs[i].encoding] = dim(bytes); +		for (int b = 0; b < dim(font.glyphs[i].bytes); b++) +			bytes[dim(bytes)] = font.glyphs[i].bytes[b]; +	} + +	/* Fill in default glyph */ +	for (int i = 0; i < dim(pos); i++) +		if (pos[i] == -1) +			pos[i] = pos[font.default_char]; + +	printf("static const uint8_t glyph_bytes[%d] = {", dim(bytes)); +	for (int b = 0; b < dim(bytes); b++) { +		if ((b & 15) == 0) +			printf("\n\t"); +		printf("0x%02x, ", flip_byte(bytes[b])); +	} +	printf("\n};\n\n"); + +	printf("static const uint16_t glyph_pos[%d] = {", dim(pos)); +	for (int i = 0; i < dim(pos); i++) { +		if ((i & 7) == 0) +			printf("\n\t"); +		printf("%4d, ", pos[i]); +	} +	printf("\n};\n\n"); + +	printf("#define GLYPH_WIDTH %d\n", width); +	printf("#define GLYPH_HEIGHT %d\n", height); +	printf("#define GLYPH_ASCENT %d\n", font.ascent); +} + +twixt (file f = File::open(argv[1], "r"); File::close(f)) { +       font_t font = read_font(f); +       print_font(font); +} diff --git a/src/draw/line.5c b/src/draw/line.5c new file mode 100644 index 00000000..747768b0 --- /dev/null +++ b/src/draw/line.5c @@ -0,0 +1,389 @@ +#!/usr/bin/nickle + +autoimport Cairo; +autoload PRNG; + +int +sign(int x) +{ +	return x == 0 ? 0 : x < 0 ? -1 : 1; +} + +int X_AXIS = 0; +int Y_AXIS = 1; + +typedef struct { +	int	major; +	int	minor; +	int	sign_major; +	int	sign_minor; +	int	e; +	int	e1; +	int	e3; +	bool	first; +} clip_context; + +typedef struct { +	int	maj1, min1, maj2, min2; +} clip_box; + +typedef struct { +	int	x1, y1, x2, y2; +} box; + +typedef struct { +	int	x, y; +} point; + +typedef struct { +	int	x1, y1, x2, y2; +	box	b; +	point[]	clipped; +	point[]	run; +} test; + +box	bounds = { .x1 = 10, .x2 = 30, .y1 = 10, .y2 = 30 }; + +int +div_ceil(a, b) { +	a += b; +	assert(a >= 0 && b > 0, "bad divide args %d %d\n", a, b); +	return (a + b - 1) // b - 1; +} + +int +div_floor_plus_one(a, b) { +	a += b; +	assert(a >= 0 && b > 0, "bad divide args %d %d\n", a, b); +	return a // b; +} + +bool +clip(*clip_context c, *clip_box b) +{ +	int	adjust_major = 0, adjust_minor = 0; + +	/* Clip major axis */ +	if (c->major < b->maj1) { +		if (c->sign_major <= 0) +			return false; +		adjust_major = b->maj1 - c->major; +	} else if (c->major >= b->maj2) { +		if (c->sign_major >= 0) +			return false; +		adjust_major = c->major - (b->maj2-1); +	} + +	/* Clip minor axis */ +	if (c->minor < b->min1) { +		if (c->sign_minor <= 0) +			return false; +		adjust_minor = b->min1 - c->minor; +	} else if (c->minor >= b->min2) { +		if (c->sign_minor >= 0) +			return false; +		adjust_minor = c->minor - (b->min2-1); +	} + +	/* If unclipped, we're done */ +	if (adjust_major == 0 && adjust_minor == 0) +		return true; + +	/* See how much minor adjustment would happen during +	 * a major clip. This is a bit tricky because line drawing +	 * isn't symmetrical when the line passes exactly between +	 * two pixels, we have to pick which one gets drawn +	 */ +	int	adj_min; + +	if (!c->first) +		adj_min = div_ceil(c->e + adjust_major * c->e1, -c->e3); +	else +		adj_min = div_floor_plus_one(c->e + adjust_major * c->e1, -c->e3); + +	/* Compare that to the minor clip and pick +	 * the larger amount. +	 */ +	printf ("\tinitial major %d minor %d error %d e1 %d e3 %d\n", c->major, c->minor, c->e, c->e1, c->e3); + +	if (adj_min < adjust_minor) { +		printf("\tminor clip dominates %d < %d. adjust major %d -> ", +		       adj_min, adjust_minor, adjust_major); +		if (c->first) +			adjust_major = div_ceil(c->e - adjust_minor * c->e3, c->e1); +		else +			adjust_major = div_floor_plus_one(c->e - adjust_minor * c->e3, c->e1); +		printf("%d\n", adjust_major); +	} else { +		printf("\tminor clip dominates %d > %d. adjust minor %d -> ", +		       adj_min, adjust_minor, adjust_minor); +		adjust_minor = adj_min; +		printf("%d\n", adjust_minor); +	} + +	c->e += adjust_major * c->e1 + adjust_minor * c->e3; + +	c->major += c->sign_major * adjust_major; +	c->minor += c->sign_minor * adjust_minor; + +	printf ("\tadjust major %d adjust minor %d e %d e1 %d e3 %e\n", +		adjust_major, adjust_minor, c->e, c->e1, c->e3); + +	if (c->e >= 0) +		printf ("error positive e %d e1 %d e3 %d\n", +			c->e, c->e1, c->e3); +	if (c->e < c->e3) +		printf ("error magnitude too large e %d e1 %d e3 %d\n", c->e, c->e1, c->e3); + +	return true; +} + +test +line(int x1, int y1, int x2, int y2, *box b) { + +	int	dx = x2 - x1; +	int	dy = y2 - y1; +	int	signdx = sign(dx); +	int	signdy = sign(dy); +	int	adx = abs(dx); +	int	ady = abs(dy); +	int	axis; +	int	e, e1, e2, e3; +	int	len; +	clip_context	clip_1, clip_2; +	clip_box	c; +	bool		clipped = false; +	test		t = { +		.x1 = x1, +		.y1 = y1, +		.x2 = x2, +		.y2 = y2, +		.b = *b, +		.clipped = (point[...]) {}, +		.run = (point[...]) {} +	}; + +	if (adx >= ady) { +		axis = X_AXIS; +		e1 = ady << 1; +		e2 = e1 - (adx << 1); +		e = e1 - adx; +		len = adx; + +		clip_1.major = x1; +		clip_1.minor = y1; +		clip_2.major = x2; +		clip_2.minor = y2; +		clip_1.sign_major = signdx; +		clip_1.sign_minor = signdy; + +		c.maj1 = b->x1; +		c.maj2 = b->x2; +		c.min1 = b->y1; +		c.min2 = b->y2; +	} else { +		axis = Y_AXIS; +		e1 = adx << 1; +		e2 = e1 - (ady << 1); +		e = e1 - ady; +		len = ady; + +		clip_1.major = y1; +		clip_1.minor = x1; +		clip_2.major = y2; +		clip_2.minor = x2; +		clip_1.sign_major = signdy; +		clip_1.sign_minor = signdx; +		c.maj1 = b->y1; +		c.maj2 = b->y2; +		c.min1 = b->x1; +		c.min2 = b->x2; +	} + +	e3 = e2 - e1; +	e = e - e1; + +	clip_1.first = true; +	clip_2.first = false; +	clip_2.e = clip_1.e = e; +	clip_2.e1 = clip_1.e1 = e1; +	clip_2.e3 = clip_1.e3 = e3; +	clip_2.sign_major = -clip_1.sign_major; +	clip_2.sign_minor = -clip_1.sign_minor; + +	printf ("clip start:\n"); +	if (!clip(&clip_1, &c)) +		clipped = true; + +	printf("clip end:\n"); +	if (!clip(&clip_2, &c)) +		clipped = true; + +	int	clip_len; +	int	clip_x, clip_y; +	int	clip_e; +	int	x_major, x_minor; +	int	y_major, y_minor; + +	clip_len = clip_1.sign_major * (clip_2.major - clip_1.major); +	if (clip_len < 0) +		clipped = true; + +	int x, y; + +	if (axis == X_AXIS) { +		x = clip_1.major; +		y = clip_1.minor; +		x_major = clip_1.sign_major; +		x_minor = 0; +		y_major = 0; +		y_minor = clip_1.sign_minor; +	} else { +		x = clip_1.minor; +		y = clip_1.major; +		x_major = 0; +		x_minor = clip_1.sign_minor; +		y_major = clip_1.sign_major; +		y_minor = 0; +	} + +	clip_e = clip_1.e; + +	if (clipped) +		clip_len = -1; + +	while (clip_len-- >= 0) { +		t.clipped[dim(t.clipped)] = (point) { .x = x, .y = y }; +		x += x_major; +		y += y_major; +		clip_e += e1; +		if (clip_e >= 0) { +			x += x_minor; +			y += y_minor; +			clip_e += e3; +		} +	} + +	x = x1; +	y = y1; + +	while (len-- >= 0) { +		if (bounds.x1 <= x && x < bounds.x2 && +		    bounds.y1 <= y && y < bounds.y2) { +			t.run[dim(t.run)] = (point) { .x = x, .y = y }; +		} +		x += x_major; +		y += y_major; +		e += e1; +		if (e >= 0) { +			x += x_minor; +			y += y_minor; +			e += e3; +		} +	} +	return t; +} + +void read_events (Cairo::cairo_t cr) +{ +	file	event = Cairo::open_event(cr); + +	while (!File::end(event)) { +		string	event_line = File::fgets(event); +		if (String::index(event_line, "delete") >= 0) +			exit(0); +	} +} + +#for (int y = 0; y < 20; y++) + +void +show(cairo_t cr, test t) +{ +	rectangle(cr, 0, 0, 40, 40); +	set_source_rgba(cr, 1, 1, 1, 1); +	fill(cr); + +	set_source_rgba(cr, 0, 1, 0, .2); +	set_line_width(cr, 0.1); +	for (int x = 0; x < 40; x++) { +		move_to(cr, 0, x); +		line_to(cr, 40, x); +		move_to(cr, x, 0); +		line_to(cr, x, 40); +	} +	stroke(cr); + +	rectangle(cr, t.b.x1, t.b.y1, t.b.x2 - t.b.x1, t.b.y2 - t.b.y1); +	set_line_width(cr, 0.1); +	set_source_rgba(cr, 0, 0, 0, 1); +	stroke(cr); + +	move_to(cr, t.x1+.5, t.y1+.5); +	line_to(cr, t.x2+.5, t.y2+.5); +	move_to(cr, t.x2, t.y2); +	line_to(cr, t.x2+1, t.y2+1); +	move_to(cr, t.x2+1, t.y2); +	line_to(cr, t.x2, t.y2+1); +	stroke(cr); + +	void pixels(point[] pt) { +		for (int i = 0; i < dim(pt); i++) { +			rectangle(cr, pt[i].x, pt[i].y, 1, 1); +		} +		fill(cr); +	} + +	set_source_rgba(cr, 1, 0, 0, .5); +	pixels(t.clipped); + +	set_source_rgba(cr, 0, 0, 1, .5); +	pixels(t.run); +} + +bool +compare(test t) +{ +	if (dim(t.clipped) != dim(t.run)) +		return false; + +	for (int i = 0; i < dim(t.clipped); i++) +		if (t.clipped[i] != t.run[i]) +			return false; +	return true; +} + +void +doit(int i) +{ +	int	n; +	*box	b = &bounds; + +	cairo_t cr = new(800, 800); + +	scale(cr, 20, 20); + +	for (;;) { +		PRNG::srandom(i); +		int	x1 = PRNG::randint(40); +		int	x2 = PRNG::randint(40); +		int	y1 = PRNG::randint(40); +		int	y2 = PRNG::randint(40); + +		test t = line (x1, y1, x2, y2, &bounds); +		show(cr, t); +		if (!compare(t)) { +			printf("line %d -- %d x %d - %d x %d\n", i, x1, y1, x2, y2); +			gets(); +		} +		i++; +	} + +	read_events(cr); +} + +int i = 0; +if (dim(argv) > 1) +	i = atoi(argv[1]); + +doit(i); | 
