Logo Search packages:      
Sourcecode: vflib3 version File versions  Download package

drv_jg.c

/* CAUTION! NEVER EDIT THIS FILE */
/*
 * drv_jg.c - A font driver for JG format fonts 
 *
 * by Hirotsugu Kakugawa
 *
 *  3 Dec 1996  First version.
 * 10 Dec 1996  Changed for VFlib version 3.1
 * 12 Dec 1996  Eliminated "do" capability.
 * 26 Feb 1997  Added 'query_font_type'.
 *  7 Aug 1997  VFlib 3.3  Changed API.
 * 28 Jan 1998  VFlib 3.4  Changed API.
 * 24 Nov 1998  Added get_fontbbx1() and get_fontbbx2().
 * 18 Oct 2001    Fixed memory leaks.
 *
 */
/*
 * Copyright (C) 1993-2001 Hirotsugu Kakugawa. 
 * All rights reserved.
 *
 * This file is part of the VFlib Library.  This library is free
 * software; you can redistribute it and/or modify it under the terms of
 * the GNU Library General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  This library 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 Library General Public License for more details.
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

/* debug flag in vflibcap (debug capability):
 *    f - print font file path
 *    i - print info on character index 
 *    o - print contents of outline data
 *    * - everything
 */

#include  "config.h"
#include  <stdio.h>
#include  <stdlib.h>
#ifdef HAVE_UNISTD_H
#  include <unistd.h>
#endif
#include  <ctype.h>
#include  <math.h>
#include  <sys/param.h>
#include  "VFlib-3_6.h"
#include  "VFsys.h"
#include  "vflibcap.h"
#include  "bitmap.h"
#include  "cache.h"
#include  "fsearch.h"
#include  "str.h"
#include  "sexp.h"


#include  "jg.h"

#define DIRECTION_HORIZONTAL  0
#define DIRECTION_VERTICAL    1

#define   POINTS_PER_INCH      72.27  /* 1 inch = 72.27 point */

#define   DEFAULT_DPI          72.27
#define   DEFAULT_POINT_SIZE   32.0
#define   DEFAULT_PIXEL_SIZE   32
#define   DEFAULT_DIRECTION    DIRECTION_HORIZONTAL  


Private SEXP_LIST    default_fontdirs;
Private SEXP_LIST    default_extensions;
Private SEXP_STRING  default_point_size;
Private double       v_default_point_size;
Private SEXP_STRING  default_pixel_size;
Private double       v_default_pixel_size;
Private SEXP_STRING  default_dpi, default_dpi_x, default_dpi_y;
Private double       v_default_dpi_x, v_default_dpi_y;
Private SEXP_STRING  default_aspect;
Private double       v_default_aspect;
Private SEXP_STRING  default_direction;
Private char         v_default_direction;
Private SEXP_LIST    default_vec_bbxul;
Private double       v_default_vec_bbxul_x, v_default_vec_bbxul_y;
Private SEXP_LIST    default_vec_next;
Private double       v_default_vec_next_x, v_default_vec_next_y;
Private SEXP_ALIST   default_properties;
Private SEXP_ALIST   default_variables;
Private SEXP_STRING  default_debug_mode;

struct s_font_jg {
  int       jg_id;
  char     *font_name;
  double    point_size;
  int       pixel_size;
  double    dpi_x, dpi_y;
  double    aspect;
  double    mag;
  double    slant;
  double    vec_bbxul_x, vec_bbxul_y;
  double    vec_next_x, vec_next_y;
  char      direction;
  SEXP      props;
};
typedef struct s_font_jg  *FONT_JG;

Private int        jg_create(VF_FONT font, char *font_class,
                         char *font_name, int implicit, SEXP entry);
Private int        jg_close(VF_FONT);
Private int        jg_get_metric1(VF_FONT,long,VF_METRIC1,double,double);
Private int        jg_get_metric2(VF_FONT,long,VF_METRIC2,double,double);
Private int        jg_get_fontbbx1(VF_FONT,double,double,
                             double*,double*,double*,double*);
Private int        jg_get_fontbbx2(VF_FONT,double,double, 
                             int*,int*,int*,int*);
Private VF_BITMAP  jg_get_bitmap1(VF_FONT,long,double,double);
Private VF_BITMAP  jg_get_bitmap2(VF_FONT,long,double,double);
Private VF_OUTLINE jg_get_outline1(VF_FONT,long,double,double);
Private char*      jg_get_font_prop(VF_FONT,char*);
Private VF_OUTLINE   get_outline2(VF_FONT,FONT_JG,long,int,double,double);

Private JG       JG_GetJG(int jg_id);
Private void       JG_SetJG(int jg_id, JG jg);
Private int        debug_on(char type);



Public int
VF_Init_Driver_JG(void)
{
  char   *p;
  SEXP   s1, s2;
  struct s_capability_table  ct[20];
  int  z;

  z = 0;
  /* VF_CAPE_FONT_DIRECTORIES */
  ct[z].cap = VF_CAPE_FONT_DIRECTORIES;   ct[z].type = CAPABILITY_LIST;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_fontdirs;
  /* VF_CAPE_EXTENSIONS */
  ct[z].cap = VF_CAPE_EXTENSIONS;         ct[z].type = CAPABILITY_LIST;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_extensions;
  /* VF_CAPE_POINT_SIZE */
  ct[z].cap = VF_CAPE_POINT_SIZE;         ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_point_size;
  /* VF_CAPE_PIXEL_SIZE */
  ct[z].cap = VF_CAPE_PIXEL_SIZE;         ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_pixel_size;
  /* VF_CAPE_DPI */
  ct[z].cap = VF_CAPE_DPI;                ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_dpi;
  /* VF_CAPE_DPI_X */
  ct[z].cap = VF_CAPE_DPI_X;              ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_dpi_x;
  /* VF_CAPE_DPI_Y */
  ct[z].cap = VF_CAPE_DPI_Y;              ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_dpi_y;
  /* VF_CAPE_ASPECT_RATIO */
  ct[z].cap = VF_CAPE_ASPECT_RATIO;       ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_aspect;
  /* VF_CAPE_DIRECTION */
  ct[z].cap = VF_CAPE_DIRECTION;          ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_direction;
  /* VF_CAPE_VECTOR_TO_BBX_UL */
  ct[z].cap = VF_CAPE_VECTOR_TO_BBX_UL;   ct[z].type = CAPABILITY_VECTOR;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_vec_bbxul;
  /* VF_CAPE_VECTOR_TO_NEXT */
  ct[z].cap = VF_CAPE_VECTOR_TO_NEXT;     ct[z].type = CAPABILITY_VECTOR;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_vec_next;
  /* VF_CAPE_PROPERTIES */
  ct[z].cap = VF_CAPE_PROPERTIES;         ct[z].type = CAPABILITY_ALIST;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_properties;
  /* VF_CAPE_VARIABLE_VALUES */
  ct[z].cap = VF_CAPE_VARIABLE_VALUES;    ct[z].type = CAPABILITY_ALIST;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_variables;
  /* VF_CAPE_DEBUG */ 
  ct[z].cap = VF_CAPE_DEBUG;              ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;        ct[z++].val = &default_debug_mode;
  /* end */
  ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;


  if (vf_cap_GetParsedClassDefault(FONTCLASS_NAME, ct, NULL, NULL) 
      == VFLIBCAP_PARSED_ERROR)
    return -1;

  if (default_extensions == NULL)
    default_extensions = vf_sexp_cstring2list(DEFAULT_EXTENSIONS);

  v_default_point_size = DEFAULT_POINT_SIZE;
  if (default_point_size != NULL)
    v_default_point_size = atof(vf_sexp_get_cstring(default_point_size));
  if (v_default_point_size < 0)
    v_default_point_size = DEFAULT_POINT_SIZE;

  v_default_pixel_size = DEFAULT_PIXEL_SIZE;
  if (default_pixel_size != NULL)
    v_default_pixel_size = atof(vf_sexp_get_cstring(default_pixel_size));
  if (v_default_pixel_size < 0)
    v_default_pixel_size  = DEFAULT_PIXEL_SIZE;

  v_default_dpi_x  = DEFAULT_DPI;
  v_default_dpi_y  = DEFAULT_DPI;
  if (default_dpi != NULL)
    v_default_dpi_x = v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi));
  if (default_dpi_x != NULL)
    v_default_dpi_x = atof(vf_sexp_get_cstring(default_dpi_x));
  if (default_dpi_y != NULL)
    v_default_dpi_y = atof(vf_sexp_get_cstring(default_dpi_y));
  if (v_default_dpi_x < 0)
    v_default_dpi_x = DEFAULT_DPI;
  if (v_default_dpi_y < 0)
    v_default_dpi_y = DEFAULT_DPI;

  v_default_aspect = 1.0;
  if (default_aspect != NULL)
    v_default_aspect = atof(vf_sexp_get_cstring(default_aspect));
  if (v_default_aspect < 0)
    v_default_aspect = 1.0;

  v_default_direction = DEFAULT_DIRECTION;
  if (default_direction != NULL){
    p = vf_sexp_get_cstring(default_direction);
    switch (*p){
    case 'h': case 'H':
      v_default_direction = DIRECTION_HORIZONTAL;
      break;
    case 'v': case 'V':
      v_default_direction = DIRECTION_VERTICAL;
      break;
    default:
      fprintf(stderr, "VFlib warning: Unknown writing direction: %s\n", p);
      break;
    }
  }

  switch(v_default_direction){
  case DIRECTION_HORIZONTAL: default:
    v_default_vec_bbxul_x = 0;
    v_default_vec_bbxul_y = DEFAULT_TO_REF_PT_H;
    v_default_vec_next_x  = 1.0;
    v_default_vec_next_y  = 0.0;
    break;
  case DIRECTION_VERTICAL:
    v_default_vec_bbxul_x = DEFAULT_TO_REF_PT_V;
    v_default_vec_bbxul_y = 0;
    v_default_vec_next_x  = 0.0;
    v_default_vec_next_y  = -1.0;
    break;
  }

  if (default_vec_bbxul != NULL){
    s1 = vf_sexp_car(default_vec_bbxul);
    s2 = vf_sexp_cadr(default_vec_bbxul);
    v_default_vec_bbxul_x = atof(vf_sexp_get_cstring(s1));
    v_default_vec_bbxul_y = atof(vf_sexp_get_cstring(s2));
  }

  if (default_vec_next != NULL){
    s1 = vf_sexp_car(default_vec_next);
    s2 = vf_sexp_cadr(default_vec_next);
    v_default_vec_next_x = atof(vf_sexp_get_cstring(s1));
    v_default_vec_next_y = atof(vf_sexp_get_cstring(s2));
  }

  if (JG_Init() < 0)
    return -1;

  VF_InstallFontDriver(FONTCLASS_NAME, (DRIVER_FUNC_TYPE)jg_create);

  return 0;
}
  

Private int
jg_create(VF_FONT font, char *font_class,
          char *font_name, int implicit, SEXP entry)
{
  FONT_JG  font_jg;
  JG       jg;
  char      *font_file, *p;
  int        jg_id, val;
  SEXP       s1, s2;
  SEXP       cap_font, cap_point, cap_pixel;
  SEXP       cap_dpi, cap_dpi_x, cap_dpi_y, cap_mag, cap_aspect;
  SEXP       cap_direction, cap_vec_bbxul, cap_vec_next, cap_props;
  struct s_capability_table  ct[20];
  int  z;

  z = 0;
  /* VF_CAPE_FONT_CLASS */
  ct[z].cap = VF_CAPE_FONT_CLASS;       ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_ESSENTIAL;     ct[z++].val = NULL;
  /* VF_CAPE_FONT_FILE */
  ct[z].cap = VF_CAPE_FONT_FILE;        ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_font;
  /* VF_CAPE_POINT_SIZE */
  ct[z].cap = VF_CAPE_POINT_SIZE;       ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_point;
  /* VF_CAPE_PIXEL_SIZE */
  ct[z].cap = VF_CAPE_PIXEL_SIZE;       ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_pixel;
  /* VF_CAPE_DPI */
  ct[z].cap = VF_CAPE_DPI;              ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi;
  /* VF_CAPE_DPI_X */
  ct[z].cap = VF_CAPE_DPI_X;            ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi_x;
  /* VF_CAPE_DPI_Y */
  ct[z].cap = VF_CAPE_DPI_Y;            ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_dpi_y;
  /* VF_CAPE_MAG */
  ct[z].cap = VF_CAPE_MAG;              ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_mag;
  /* VF_CAPE_ASPECT_RATIO */
  ct[z].cap = VF_CAPE_ASPECT_RATIO;     ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_aspect;
  /* VF_CAPE_DIRECTION */
  ct[z].cap = VF_CAPE_DIRECTION;        ct[z].type = CAPABILITY_STRING;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_direction;
  /* VF_CAPE_VECTOR_TO_BBX_UL */
  ct[z].cap = VF_CAPE_VECTOR_TO_BBX_UL; ct[z].type = CAPABILITY_VECTOR;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_vec_bbxul;
  /* VF_CAPE_VECTOR_TO_NEXT */
  ct[z].cap = VF_CAPE_VECTOR_TO_NEXT;   ct[z].type = CAPABILITY_VECTOR;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_vec_next;
  /* VF_CAPE_PROPERTIES */
  ct[z].cap = VF_CAPE_PROPERTIES;       ct[z].type = CAPABILITY_ALIST;
  ct[z].ess = CAPABILITY_OPTIONAL;      ct[z++].val = &cap_props;
  /* end */
  ct[z].cap = NULL; ct[z].type = 0; ct[z].ess = 0; ct[z++].val = NULL;


  if (implicit == 1){   /* implicit font */
    font_file = font_name;
  } else {              /* explicit font */
    if (vf_cap_GetParsedFontEntry(entry, font_name, ct,
                          default_variables, NULL) < 0)
      return -1;
    if (cap_font == NULL){
      /* Use font name as font file name if font file name is not given. */
      font_file = font_name;
    } else {
      font_file = vf_sexp_get_cstring(cap_font);
    }
  }

  val = -1;
  font_jg = NULL;

  if ((jg_id = JG_Open(font_file)) < 0)
      goto End;

  font->font_type       = VF_FONT_TYPE_OUTLINE;
  font->get_metric1     = jg_get_metric1;
  font->get_metric2     = jg_get_metric2;
  font->get_fontbbx1    = jg_get_fontbbx1;
  font->get_fontbbx2    = jg_get_fontbbx2;
  font->get_bitmap1     = jg_get_bitmap1;
  font->get_bitmap2     = jg_get_bitmap2;
  font->get_outline     = jg_get_outline1;
  font->get_font_prop   = jg_get_font_prop;
  font->query_font_type = NULL;  /* Use font->font_type value. */
  font->close           = jg_close;

  ALLOC_IF_ERR(font_jg, struct s_font_jg){
    vf_error = VF_ERR_NO_MEMORY;
    goto End;
  }

  font_jg->jg_id     = jg_id;
  font_jg->font_name   = NULL;
  font_jg->point_size  = v_default_point_size;
  font_jg->pixel_size  = v_default_pixel_size;
  font_jg->mag         = 1.0;
  font_jg->dpi_x       = v_default_dpi_x;
  font_jg->dpi_y       = v_default_dpi_y;
  font_jg->aspect      = v_default_aspect;
  font_jg->direction   = v_default_direction;
  font_jg->slant       = 0;
  font_jg->vec_bbxul_x = v_default_vec_bbxul_x;
  font_jg->vec_bbxul_y = v_default_vec_bbxul_y;
  font_jg->vec_next_x  = v_default_vec_next_x;
  font_jg->vec_next_y  = v_default_vec_next_y;

  if (implicit == 0){
    if (cap_point != NULL)
      font_jg->point_size = atof(vf_sexp_get_cstring(cap_point));
    if (cap_pixel != NULL)
      font_jg->pixel_size = atof(vf_sexp_get_cstring(cap_pixel));
    if (cap_dpi != NULL)
      font_jg->dpi_x = font_jg->dpi_y = atof(vf_sexp_get_cstring(cap_dpi));
    if (cap_dpi_x != NULL)
      font_jg->dpi_x = atof(vf_sexp_get_cstring(cap_dpi_x));
    if (cap_dpi_y != NULL)
      font_jg->dpi_y = atof(vf_sexp_get_cstring(cap_dpi_y));
    if (cap_mag != NULL)
      font_jg->mag = atof(vf_sexp_get_cstring(cap_mag));
    if (cap_aspect != NULL)
      font_jg->aspect = atof(vf_sexp_get_cstring(cap_aspect));
    if (cap_direction != NULL){
      p = vf_sexp_get_cstring(cap_direction);
      switch (*p){
      case 'h': case 'H':
      font_jg->direction = DIRECTION_HORIZONTAL;  break;
      case 'v': case 'V':
      font_jg->direction = DIRECTION_VERTICAL;    break;
      default:
      fprintf(stderr, "VFlib warning: Unknown writing direction: %s\n", p);
      break;
      }
    }
    switch(font_jg->direction){
    case DIRECTION_HORIZONTAL: default:
      font_jg->vec_bbxul_x = v_default_vec_bbxul_x;
      font_jg->vec_bbxul_y = v_default_vec_bbxul_y;
      font_jg->vec_next_x  = v_default_vec_next_x;
      font_jg->vec_next_y  = v_default_vec_next_y;
      break;
    case DIRECTION_VERTICAL:
      font_jg->vec_bbxul_x = v_default_vec_bbxul_x;
      font_jg->vec_bbxul_y = v_default_vec_bbxul_y;
      font_jg->vec_next_x  = v_default_vec_next_x;
      font_jg->vec_next_y  = v_default_vec_next_y;
      break;
    }
    if (cap_vec_bbxul != NULL){
      s1 = vf_sexp_car(cap_vec_bbxul);
      s2 = vf_sexp_cadr(cap_vec_bbxul);
      font_jg->vec_bbxul_x = atof(vf_sexp_get_cstring(s1));
      font_jg->vec_bbxul_y = atof(vf_sexp_get_cstring(s2));
    }
    if (cap_vec_next != NULL){
      s1 = vf_sexp_car(cap_vec_next);
      s2 = vf_sexp_cadr(cap_vec_next);
      font_jg->vec_next_x = atof(vf_sexp_get_cstring(s1));
      font_jg->vec_next_y = atof(vf_sexp_get_cstring(s2));
    }
    if (cap_props != NULL)
      font_jg->props = cap_props;
  }

  if ((font_jg->font_name = vf_strdup(font_name)) == NULL){
    vf_error = VF_ERR_NO_MEMORY;
    goto End;
  }

  if ((jg = JG_GetJG(font_jg->jg_id)) == NULL){
    fprintf(stderr, "VFlib: internal error in jg_create()\n");
    vf_error = VF_ERR_INTERNAL;
    goto End;
  }

  font->private = font_jg;
  val = 0;

End:
  if (implicit == 0){
    vf_sexp_free3(&cap_font, &cap_point, &cap_pixel);
    vf_sexp_free3(&cap_dpi, &cap_dpi_x, &cap_dpi_y);
    vf_sexp_free3(&cap_direction, &cap_vec_bbxul, &cap_vec_next);
  }
  if (val < 0)
    jg_close(font);

  return val;
}


Private int
jg_close(VF_FONT font)
{
  FONT_JG  font_jg;

  font_jg = (FONT_JG)font->private;

  if (font_jg != NULL){
    if (font_jg->jg_id >= 0)
      JG_Close(font_jg->jg_id);
    vf_free(font_jg->font_name); 
    vf_sexp_free1(&font_jg->props);
    vf_free(font_jg);
  }

  return 0; 
}



Private void
mag_mode_1(FONT_JG font_jg, VF_FONT font, 
         double mag_x, double mag_y,
         double *ret_point_size,
         double *ret_bbx_w, double *ret_bbx_h, 
         double *ret_mag_x, double *ret_mag_y, 
         double *ret_dpix, double *ret_dpiy)
{
  double  mx, my, dpix, dpiy, ps, asp;

  if ((ps = font->point_size) < 0)
    if ((ps = font_jg->point_size) < 0)
      ps = v_default_point_size;

  if (ret_point_size != NULL)
    *ret_point_size = ps;

  asp = (v_default_aspect * font_jg->aspect);

  mx = mag_x * font_jg->mag * font->mag_x * asp;
  my = mag_y * font_jg->mag * font->mag_y;

  if (ret_mag_x != NULL)
    *ret_mag_x = mx;
  if (ret_mag_y != NULL)
    *ret_mag_y = my;

  if ((font->dpi_x > 0) && (font->dpi_y > 0)){
    dpix = font->dpi_x;
    dpiy = font->dpi_y;
  } else if ((font_jg->dpi_x > 0) && (font_jg->dpi_y > 0)){
    dpix = font_jg->dpi_x;
    dpiy = font_jg->dpi_y;
  } else {
    dpix = v_default_dpi_x;
    dpiy = v_default_dpi_y;
  }

  if (ret_dpix != NULL)
    *ret_dpix = dpix;
  if (ret_dpiy != NULL)
    *ret_dpiy = dpiy;

  if (ret_bbx_w != NULL)
    *ret_bbx_w = dpix * mx * (ps / POINTS_PER_INCH);
  if (ret_bbx_h != NULL)
    *ret_bbx_h = dpiy * my * (ps / POINTS_PER_INCH);

#if 0
  printf("*** %.3f %.3f %.3f\n", mag_x, font_jg->mag, font->mag_x);
  printf("    %.3f %.3f %.3f\n", mag_y, font_jg->mag, font->mag_y);
  printf("    dpix=%.3f  font_dpi_x=%.3f\n", dpix, font_dpi_x);
  printf("    dpiy=%.3f  font_dpi_y=%.3f\n", dpiy, font_dpi_y);
  printf("    asp=%.3f\n", asp);
  printf("    mx=%.3f, my=%.3f\n", mx, my);
  if (ret_bbx_w != NULL)
    printf("    W=%.3f  H=%.3f\n", *ret_bbx_w, *ret_bbx_h);
#endif

}


Private int
jg_get_metric1(VF_FONT font, long code, VF_METRIC1 metric, 
             double mag_x, double mag_y)
{
  FONT_JG  font_jg;
  double     bbx_w, bbx_h;
  double     dpix, dpiy;

  if (   ((font_jg = (FONT_JG)font->private) == NULL)
      || (metric == NULL)){
    fprintf(stderr, "VFlib internal error: in jg_get_metric1()\n");
    abort();
  }

  mag_mode_1(font_jg, font, mag_x, mag_y, 
           NULL, &bbx_w, &bbx_h, NULL, NULL, &dpix, &dpiy);

  metric->bbx_width  = bbx_w;
  metric->bbx_height = bbx_h;
  metric->off_x = bbx_w * font_jg->vec_bbxul_x;
  metric->off_y = bbx_h * font_jg->vec_bbxul_y;
  metric->mv_x  = bbx_w * font_jg->vec_next_x;
  metric->mv_y  = bbx_h * font_jg->vec_next_y;

  return 0;
}

Private int
jg_get_fontbbx1(VF_FONT font, double mag_x, double mag_y,
              double *w_p, double *h_p, double *xoff_p, double *yoff_p)
{
  FONT_JG  font_jg;
  double     bbx_w, bbx_h;
  double     dpix, dpiy;

  if ((font_jg = (FONT_JG)font->private) == NULL){
    fprintf(stderr, "VFlib internal error: in jg_get_fontbbx1()\n");
    abort();
  }

  mag_mode_1(font_jg, font, mag_x, mag_y, 
           NULL, &bbx_w, &bbx_h, NULL, NULL, &dpix, &dpiy);

  *w_p = bbx_w;
  *h_p = bbx_h;
  *xoff_p = bbx_w * font_jg->vec_bbxul_x;
  *yoff_p = bbx_h * (1.0 - font_jg->vec_bbxul_y);

  return 0;
}

Private VF_BITMAP
jg_get_bitmap1(VF_FONT font, long code_point,
             double mag_x, double mag_y)
{
  VF_OUTLINE   outline;
  VF_BITMAP    bm;

  if ((outline = jg_get_outline1(font, code_point, mag_x, mag_y)) == NULL)
    return NULL;

  bm = vf_outline_to_bitmap(outline, -1, -1, -1, 1, 1);
  VF_FreeOutline(outline);

  return  bm;
}

Private VF_OUTLINE
jg_get_outline1(VF_FONT font, long code_point,
              double mag_x, double mag_y)
{
  FONT_JG   font_jg;
  VF_OUTLINE  outline;
  double      ps, mx, my, bbx_w, bbx_h, dpix, dpiy, em_mag;

  if ((font_jg = (FONT_JG)font->private) == NULL){
    fprintf(stderr, "VFlib: internal error in jg_get_outline1()\n");
    abort();
  }

  mag_mode_1(font_jg, font, mag_x, mag_y, 
           &ps, &bbx_w, &bbx_h, &mx, &my, &dpix, &dpiy);

  em_mag = 1.0;
  if (mx > 1){
    em_mag /= mx;
    my = my/mx;
    mx = 1.0;
  }
  if (my > 1){
    em_mag /= my;
    mx = mx/my;
    my = 1.0;
  }

  outline = JG_ReadOutline(font_jg->jg_id, (int)code_point, mx, my);
  if (outline == NULL)
    return NULL;

  outline[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
  outline[VF_OL_HEADER_INDEX_DPI_X]       = VF_OL_HEADER_ENCODE(dpix);
  outline[VF_OL_HEADER_INDEX_DPI_Y]       = VF_OL_HEADER_ENCODE(dpiy);
  outline[VF_OL_HEADER_INDEX_POINT_SIZE]  = VF_OL_HEADER_ENCODE(ps);
  outline[VF_OL_HEADER_INDEX_EM]          = VF_OL_COORD_RANGE * em_mag;
  outline[VF_OL_HEADER_INDEX_MAX_X]       = VF_OL_COORD_RANGE * mx;
  outline[VF_OL_HEADER_INDEX_MAX_Y]       = VF_OL_COORD_RANGE * my;
  outline[VF_OL_HEADER_INDEX_REF_X] 
    = VF_OL_COORD_RANGE * (0 -  font_jg->vec_bbxul_x) * mx;
  outline[VF_OL_HEADER_INDEX_REF_Y] 
    = VF_OL_COORD_RANGE * font_jg->vec_bbxul_y * my;
  outline[VF_OL_HEADER_INDEX_MV_X] 
    = VF_OL_COORD_RANGE * font_jg->vec_next_x * mx;
  outline[VF_OL_HEADER_INDEX_MV_Y]
    = VF_OL_COORD_RANGE * font_jg->vec_next_y * my;

  return outline;
}


Private void
mag_mode_2(FONT_JG font_jg, VF_FONT font, 
         double mag_x, double mag_y,
         double *ret_pixel_size,
         double *ret_magx, double *ret_magy,
         double *ret_bbx_w, double *ret_bbx_h)
{
  int     ps;
  double  mx, my, asp;

  if ((ps = font->pixel_size) < 0)
    if ((ps = font_jg->pixel_size) < 0)
      ps = v_default_pixel_size;

  asp = (v_default_aspect * font_jg->aspect);

  mx = mag_x * font_jg->mag * font->mag_x * asp;
  my = mag_y * font_jg->mag * font->mag_y;

  if (ret_pixel_size != NULL)
    *ret_pixel_size = ps;

  if (ret_magx != NULL)
    *ret_magx = mx;
  if (ret_magy != NULL)
    *ret_magy = my;

  if (ret_bbx_w != NULL)
    *ret_bbx_w = mx * ps;
  if (ret_bbx_h != NULL)
    *ret_bbx_h = my * ps;
}


Private int
jg_get_metric2(VF_FONT font, long code_point, VF_METRIC2 metric, 
             double mag_x, double mag_y)
{
  FONT_JG  font_jg;
  double     bbx_w, bbx_h;

  if (   ((font_jg = (FONT_JG)font->private) == NULL)
      || (metric == NULL)){
    fprintf(stderr, "VFlib internal error: in jg_get_metric2()\n");
    abort();
  }

  mag_mode_2(font_jg, font, mag_x, mag_y, NULL, NULL, NULL, &bbx_w, &bbx_h);

  metric->bbx_width  = (int)ceil(bbx_w);
  metric->bbx_height = (int)ceil(bbx_h);
  metric->off_x = toint(bbx_w * font_jg->vec_bbxul_x);
  metric->off_y = toint(bbx_h * font_jg->vec_bbxul_y);
  metric->mv_x  = toint(bbx_w * font_jg->vec_next_x);
  metric->mv_y  = toint(bbx_h * font_jg->vec_next_y);

  return 0;
}

Private int
jg_get_fontbbx2(VF_FONT font, double mag_x, double mag_y,
              int *w_p, int *h_p, int *xoff_p, int *yoff_p)
{
  FONT_JG  font_jg;
  double     bbx_w, bbx_h;

  if ((font_jg = (FONT_JG)font->private) == NULL){
    fprintf(stderr, "VFlib internal error: in jg_get_fontbbx2()\n");
    abort();
  }

  mag_mode_2(font_jg, font, mag_x, mag_y, NULL, NULL, NULL, &bbx_w, &bbx_h);

  *w_p  = toint(bbx_w);
  *h_p  = toint(bbx_h);
  *xoff_p = toint(bbx_w * font_jg->vec_bbxul_x);
  *yoff_p = toint(bbx_w * (font_jg->vec_bbxul_y - 1.0));

  return 0;
}

Private VF_BITMAP
jg_get_bitmap2(VF_FONT font, long code_point, 
             double mag_x, double mag_y)
{
  FONT_JG   font_jg;
  VF_OUTLINE  outline; 
  VF_BITMAP   bm;
  double      ps, mx, my, bbx_w, bbx_h;
  int         bbx_width, bbx_height;

  if ((font_jg = (FONT_JG)font->private) == NULL){
    fprintf(stderr, "VFlib internal error: in jg_get_bitmap2()\n");
    abort();
  }

  mag_mode_2(font_jg, font, mag_x, mag_y, &ps, &mx, &my, &bbx_w, &bbx_h);

  bbx_width  = (int)ceil(bbx_w);
  bbx_height = (int)ceil(bbx_h);

  if ((bm = vf_alloc_bitmap(bbx_width, bbx_height)) == NULL){
    vf_error = VF_ERR_NO_MEMORY;
    return NULL;
  }

  outline = get_outline2(font, font_jg, code_point, ps, mx, my);
  if (outline == NULL)
    return NULL;

  if (vf_draw_outline(bm, outline) < 0){
    VF_FreeOutline(outline);
    VF_FreeBitmap(bm);
    return NULL;
  }
  VF_FreeOutline(outline);

  bm->off_x = toint(bbx_w * font_jg->vec_bbxul_x);
  bm->off_y = toint(bbx_h * font_jg->vec_bbxul_y);
  bm->mv_x  = toint(bbx_w * font_jg->vec_next_x);
  bm->mv_y  = toint(bbx_h * font_jg->vec_next_y);

  return bm;
}


Private VF_OUTLINE
get_outline2(VF_FONT font, FONT_JG font_jg, long code_point,
           int pixel_size, double mx, double my)
{
  VF_OUTLINE   outline;
  double       em_mag;
  
  em_mag = 1.0; 
  if (mx > 1){
    em_mag /= mx; 
    my = my/mx;
    mx = 1.0;
  }
  if (my > 1){
    em_mag /= my; 
    mx = mx/my;
    my = 1.0;
  }
  
  outline = JG_ReadOutline(font_jg->jg_id, (int)code_point, mx, my);
  if (outline == NULL)
    return NULL;

  outline[VF_OL_HEADER_INDEX_HEADER_TYPE] = VF_OL_OUTLINE_HEADER_TYPE0;
  outline[VF_OL_HEADER_INDEX_DPI_X] = VF_OL_HEADER_ENCODE(POINTS_PER_INCH);
  outline[VF_OL_HEADER_INDEX_DPI_Y] = VF_OL_HEADER_ENCODE(POINTS_PER_INCH);
  outline[VF_OL_HEADER_INDEX_POINT_SIZE] = VF_OL_HEADER_ENCODE(pixel_size);
  outline[VF_OL_HEADER_INDEX_EM]    = VF_OL_COORD_RANGE * my;
  outline[VF_OL_HEADER_INDEX_MAX_X] = VF_OL_COORD_RANGE * mx;
  outline[VF_OL_HEADER_INDEX_MAX_Y] = VF_OL_COORD_RANGE * my;
  outline[VF_OL_HEADER_INDEX_REF_X] 
    = VF_OL_COORD_RANGE * (0 -  font_jg->vec_bbxul_x) * mx;
  outline[VF_OL_HEADER_INDEX_REF_Y]
    = VF_OL_COORD_RANGE * font_jg->vec_bbxul_y * my;
  outline[VF_OL_HEADER_INDEX_MV_X] 
    = VF_OL_COORD_RANGE * font_jg->vec_next_x * mx;
  outline[VF_OL_HEADER_INDEX_MV_Y]
    = VF_OL_COORD_RANGE * font_jg->vec_next_y * my;

  return outline;
}


Private char*
jg_get_font_prop(VF_FONT font, char *prop_name)
     /* CALLER MUST RELEASE RETURNED STRING */
{
  FONT_JG   font_jg;
  char        str[512];
  double      ps, dpix, dpiy;
  SEXP        v;

  if ((font_jg = (FONT_JG)font->private) == NULL){
    fprintf(stderr, "VFlib: internal error in jg_get_font_prop()\n");
    abort();
  }
  
  if ((v = vf_sexp_assoc(prop_name, font_jg->props)) != NULL){
    return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
  } else if ((v = vf_sexp_assoc(prop_name, default_properties)) != NULL){
    return vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)));
  }

  if (font->mode == 1){
    mag_mode_1(font_jg, font, 1.0, 1.0,
             &ps, NULL, NULL, NULL, NULL, &dpix, &dpiy);
    /**printf("** Mode1 %.3f %.3f %.3f\n", ps, dpix, dpiy);**/
    if (strcmp(prop_name, "POINT_SIZE") == 0){
      sprintf(str, "%d", toint(10.0 * ps)); 
      return vf_strdup(str);
    } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
      sprintf(str, "%d", toint(ps * dpiy / POINTS_PER_INCH));
      return vf_strdup(str);
    } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
      sprintf(str, "%d", toint(dpix)); 
      return vf_strdup(str);
    } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
      sprintf(str, "%d", toint(dpiy)); 
      return vf_strdup(str);
    } 
  } else if (font->mode == 2){
    mag_mode_2(font_jg, font, 1.0, 1.0, &ps, NULL, NULL, NULL, NULL);
    /**printf("** Mode2 %.3f\n", ps);**/
    if (strcmp(prop_name, "POINT_SIZE") == 0){
      sprintf(str, "%d", toint(10.0 * ps * POINTS_PER_INCH / DEFAULT_DPI)); 
      return vf_strdup(str);
    } else if (strcmp(prop_name, "PIXEL_SIZE") == 0){
      sprintf(str, "%d", toint(ps)); 
      return vf_strdup(str);
    } else if (strcmp(prop_name, "RESOLUTION_X") == 0){
      sprintf(str, "%d", toint(DEFAULT_DPI)); 
      return vf_strdup(str);
    } else if (strcmp(prop_name, "RESOLUTION_Y") == 0){
      sprintf(str, "%d", toint(DEFAULT_DPI)); 
      return vf_strdup(str);
    } 
  }

  return NULL; 
}


/* 
 * Include Low-Level Font Interface Routine. 
 */ 

#include "jg.c"


static int    jg_last_jg_id = -1;
static JG   jg_last_jg   = NULL;

Private void
JG_SetJG(int jg_id, JG jg)
{
  jg_last_jg_id  = jg_id;
  jg_last_jg     = jg;
}

Private JG
JG_GetJG(int jg_id)
{
  JG   jg;

  if (jg_id == -1){
    jg_last_jg_id  = -1;
    jg_last_jg     = NULL;
    return NULL;
  }

  if (   (jg_last_jg_id == jg_id) 
      && (jg_last_jg != NULL) 
      && (jg_last_jg_id != -1))
    return jg_last_jg;
  
  jg = (jg_table->get_obj_by_id)(jg_table, jg_id);
  jg_last_jg_id = jg_id;
  jg_last_jg    = jg;  

  return jg;
}


Private int
debug_on(char type)
{
  char  *p, *p0;

  if (default_debug_mode == NULL)
    return FALSE;
  if ((p0 = vf_sexp_get_cstring(default_debug_mode)) == NULL)
    return FALSE;
  
  for (p = p0; *p != '\0'; p++){
    if (*p == type)
      return TRUE;
  }
  for (p = p0; *p != '\0'; p++){
    if (*p == '*')
      return TRUE;
  }
  return FALSE;
}

/*EOF*/

Generated by  Doxygen 1.6.0   Back to index