src/bm2ol.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. VF_BitmapToOutline
  2. VF_FreeOutline
  3. vf_bitmap_to_outline
  4. 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*/

/* [<][>][^][v][top][bottom][index][help] */