src/bm2ol.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- VF_BitmapToOutline
- VF_FreeOutline
- vf_bitmap_to_outline
- vf_bitmap_to_outline2
1 /*
2 * bm2ol.c - a module for generating an outline from a bitmap
3 * by Hirotsugu Kakugawa
4 *
5 */
6 /*
7 * Copyright (C) 1996, 1997 Hirotsugu Kakugawa.
8 * All rights reserved.
9 *
10 * This file is part of the VFlib Library. This library is free
11 * software; you can redistribute it and/or modify it under the terms of
12 * the GNU Library General Public License as published by the Free
13 * Software Foundation; either version 2 of the License, or (at your
14 * option) any later version. This library is distributed in the hope
15 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
16 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
17 * PURPOSE. See the GNU Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22 #include <stdio.h>
23 #include <stdlib.h>
24 #ifdef HAVE_UNISTD_H
25 # include <unistd.h>
26 #endif
27 #include <math.h>
28 #include "config.h"
29 #include "VFlib-3_6.h"
30 #include "VFsys.h"
31 #include "consts.h"
32
33 #define DEFAULT_POINT_SIZE 10.0
34
35
36 /**
37 ** VF_Bitmap2Outline
38 **/
39 Public VF_OUTLINE
40 VF_BitmapToOutline(VF_BITMAP bm)
/* [<][>][^][v][top][bottom][index][help] */
41 {
42 return vf_bitmap_to_outline(bm, bm->bbx_width, bm->bbx_height,
43 VF_DEFAULT_DPI, VF_DEFAULT_DPI,
44 DEFAULT_POINT_SIZE, 1, 1);
45 }
46
47 /**
48 ** VF_FreeOutline
49 **/
50 Public void
51 VF_FreeOutline(VF_OUTLINE outline_data)
/* [<][>][^][v][top][bottom][index][help] */
52 {
53 vf_free(outline_data);
54 }
55
56
57 Glocal VF_OUTLINE
58 vf_bitmap_to_outline(VF_BITMAP bm, int font_bbx_width, int font_bbx_height,
/* [<][>][^][v][top][bottom][index][help] */
59 double dpi_x, double dpi_y,
60 double point_size, double mag_x, double mag_y)
61 {
62 return vf_bitmap_to_outline2(bm,
63 BM2OL_DOT_SHAPE_SQUARE, BM2OL_DEFAULT_DOT_SIZE,
64 font_bbx_width, font_bbx_height,
65 dpi_x, dpi_y,
66 point_size, mag_x, mag_y);
67 }
68
69 Glocal VF_OUTLINE
70 vf_bitmap_to_outline2(VF_BITMAP bm, int dot_shape, double dot_mag,
/* [<][>][^][v][top][bottom][index][help] */
71 int font_bbx_width, int font_bbx_height,
72 double dpi_x, double dpi_y,
73 double point_size,
74 double mag_x, double mag_y)
75 {
76 int x, y, xx, nbits, size, index;
77 int xl, xr, yu, yl, xc, yc;
78 int xl2, xr2, yu2, yl2;
79 double bbx, fx, fy;
80 unsigned char *p, *p0;
81 VF_OUTLINE outline;
82 static unsigned char bit_tbl[] = {
83 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
84 static int nbits_tbl[] = {
85 0, 1, 1, 2, 1, 2, 2, 3, /* 0, 1, 2, 3, 4, 5, 6, 7 */
86 1, 2, 2, 3, 2, 3, 3, 4}; /* 8, 9, A, B, C, D, E, F */
87
88 if ((bm == NULL) || (bm->bitmap == NULL))
89 return NULL;
90
91 if ((bm->bbx_width <= 0) || (bm->bbx_height <= 0)
92 || (mag_x <= 0) || (mag_y <= 0)){
93 vf_error = VF_ERR_BITMAP2OUTLINE;
94 return NULL;
95 }
96
97 if ((dpi_x < 0) || (dpi_y < 0)){
98 dpi_x = VF_DEFAULT_DPI;
99 dpi_y = VF_DEFAULT_DPI;
100 }
101
102 if (dot_mag < 0)
103 dot_mag = 1.0;
104
105 #if 0
106 printf("* BM->OL: BBX: %d,%d\n", bm->bbx_width, bm->bbx_height);
107 printf(" FBBX: %d,%d Pt: %.4fpt DPI: (%.2f,%.2f)\n",
108 font_bbx_width, font_bbx_height,
109 point_size, dpi_x, dpi_y);
110 #endif
111
112 /* scaling */
113 if (font_bbx_width > font_bbx_height){
114 bbx = font_bbx_width;
115 } else {
116 bbx = font_bbx_height;
117 }
118 fx = (double)VF_OL_COORD_RANGE / bbx;
119 fy = (double)VF_OL_COORD_RANGE / bbx;
120
121 /* count # of single bits */
122 nbits = 0;
123 p0 = bm->bitmap;
124 for (y = 0; y < bm->bbx_height; y++){
125 for (x = 0, p = p0; x < bm->raster; x++, p++){
126 nbits += nbits_tbl[*p/0x10];
127 nbits += nbits_tbl[*p%0x10];
128 }
129 p0 = p0 + bm->raster;
130 }
131
132 /* count outline data size */
133 if (dot_shape < 0)
134 dot_shape = BM2OL_DOT_SHAPE_SQUARE;
135 switch (dot_shape){
136 default:
137 case BM2OL_DOT_SHAPE_SQUARE:
138 case BM2OL_DOT_SHAPE_DIAMOND:
139 size = VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + 5*nbits + 1;
140 break;
141 }
142
143 /* allocate outline data area */
144 if ((outline = (VF_OUTLINE)calloc(size, sizeof(VF_OUTLINE_ELEM))) == NULL){
145 vf_error = VF_ERR_NO_MEMORY;
146 return NULL;
147 }
148
149 /* make a header of outline data */
150 outline[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
151 outline[VF_OL_HEADER_INDEX_DATA_SIZE] = size;
152 outline[VF_OL_HEADER_INDEX_DPI_X] = VF_OL_HEADER_ENCODE(dpi_x);
153 outline[VF_OL_HEADER_INDEX_DPI_Y] = VF_OL_HEADER_ENCODE(dpi_y);
154 outline[VF_OL_HEADER_INDEX_POINT_SIZE] = VF_OL_HEADER_ENCODE(point_size);
155 outline[VF_OL_HEADER_INDEX_EM] = (double)bbx * fy;
156 outline[VF_OL_HEADER_INDEX_MAX_X] = (double)bm->bbx_width * fx;
157 outline[VF_OL_HEADER_INDEX_MAX_Y] = (double)bm->bbx_height * fy;
158 outline[VF_OL_HEADER_INDEX_REF_X] = (0 - bm->off_x) * fx;
159 outline[VF_OL_HEADER_INDEX_REF_Y] = bm->off_y * fy;
160 outline[VF_OL_HEADER_INDEX_MV_X] = bm->mv_x * fx;
161 outline[VF_OL_HEADER_INDEX_MV_Y] = bm->mv_y * fy;
162
163 /* make outline data from bitmap */
164 index = VF_OL_OUTLINE_HEADER_SIZE_TYPE0;
165 for (y = 0, p0 = bm->bitmap; y < bm->bbx_height; y++, p0 += bm->raster){
166 yu = (y+0) * fy;
167 yl = (y+1) * fy;
168 yu2 = VF_OL_COORD_OFFSET + (yu+yl)/2 - dot_mag * (yl-yu)/2;
169 yl2 = VF_OL_COORD_OFFSET + (yu+yl)/2 + dot_mag * (yl-yu)/2 - 1;
170 yc = VF_OL_COORD_OFFSET + (yu+yl)/2;
171 for (x = 0, p = p0; x < bm->raster; x++, p++){
172 if (*p == 0)
173 continue;
174 for (xx = 0; xx <= 7; xx++){
175 if ((bit_tbl[xx] & *p) == 0)
176 continue;
177 xl = (8*x+xx+0) * fx;
178 xr = (8*x+xx+1) * fx;
179 xl2 = VF_OL_COORD_OFFSET + (xl+xr)/2 - dot_mag * (xr-xl)/2;
180 xr2 = VF_OL_COORD_OFFSET + (xl+xr)/2 + dot_mag * (xr-xl)/2 - 1;
181 xc = VF_OL_COORD_OFFSET + (xl+xr)/2;
182 if (dot_shape == BM2OL_DOT_SHAPE_SQUARE){
183 outline[index++]
184 = (VF_OUTLINE_ELEM)(VF_OL_INSTR_TOKEN
185 | VF_OL_INSTR_CWCURV | VF_OL_INSTR_LINE);
186 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xl2, yu2);
187 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xl2, yl2);
188 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xr2, yl2);
189 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xr2, yu2);
190 } else { /* dot_shape == DOT_SHAPE_DIAMOND */
191 outline[index++]
192 = (VF_OUTLINE_ELEM)(VF_OL_INSTR_TOKEN
193 | VF_OL_INSTR_CWCURV | VF_OL_INSTR_LINE);
194 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xl2, yc);
195 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xc, yl2);
196 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xr2, yc);
197 outline[index++] = (VF_OUTLINE_ELEM)VF_OL_MAKE_XY(xc, yu2);
198 }
199 }
200 }
201 }
202 if (index != VF_OL_OUTLINE_HEADER_SIZE_TYPE0)
203 outline[VF_OL_OUTLINE_HEADER_SIZE_TYPE0] |= VF_OL_INSTR_CHAR;
204
205 /* end of outline */
206 outline[index] = (VF_OUTLINE_ELEM)0L;
207
208 return outline;
209 }
210
211 /*EOF*/