/*
 * VF_Null.c
 *
 *  Programmmed by Hirotsugu Kakugawa, Hiroshima University
 *  E-Mail:  h.kakugawa@computer.org
 *
 *  Edition History
 *   18 Nov 1995  
 */


/* This file is part of VFlib
 *
 * Copyright (C) 1995-1998 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.
 */


/*
  Capabilities interpretable by Null font objects::
  "ty"  (str)  --  Glyph type:
                   white - writes nothing (default)
                   black - writes a black box
                   frame - writes a frame box
 */

#include  <stdio.h> 
#include  <stdlib.h> 
#include  <string.h> 
#include  "config.h"
#include  "defs.h"
#include  "_VF.h"
#include  "VF.h"
#include  "VFcap.h"

#define TYPE_DEFAULT 0
#define TYPE_WHITE   0
#define TYPE_BLACK   1
#define TYPE_FRAME   2
#define VFCE_TYPE    "ty"
#define WD           20

struct s_font {
  int     type; 
};
typedef struct s_font  Font;


Private int    OpenFont();
Private int    CloseFont();
Private int    GetBitmap();
Private long*  GetOutline();
Private long*  GetOutline2();
Private int    DrawOutline();
Private int    FreeOutline();
Private int    Link();
Private int    Unlink();

Private int    ReadCapa();

int            VF_Draw();



Public FontObj*
CreateFont_Null(ent)
  char *ent;
{
  Font    *font;
  FontObj *fobj;

  if ((font = (Font*) malloc(sizeof(Font))) == NULL)
    return NULL;  /* ERR: malloc err */
  font->type = TYPE_DEFAULT;
  if (ReadCapa(font, ent) < 0)
    return NULL;

  fobj = (FontObj*) malloc(sizeof(FontObj));
  fobj->ClassID     = VF_FONT_NULLFONT;
  fobj->Self        = fobj;
  fobj->LinkCount   = 0;
  fobj->OpenFont    = OpenFont;
  fobj->CloseFont   = CloseFont;
  fobj->GetBitmap   = GetBitmap;
  fobj->GetOutline  = GetOutline;
  fobj->GetOutline2 = GetOutline2;
  fobj->DrawOutline = DrawOutline;
  fobj->FreeOutline = FreeOutline;
  fobj->GetCharSet  = NULL;
  fobj->GetEnc      = NULL;
  fobj->Link        = Link;
  fobj->Unlink      = Unlink;
  fobj->Locals      = (long) font;
  return fobj;
}
       

Private int
OpenFont(obj)
  FontObj* obj;
{
  return 0;
}


Private int
CloseFont(obj, fid)
  FontObj  *obj;
  int      fid;
{
  return 0;
}

Private int
GetBitmap(obj, jiscode, w, h, bw, bo, bm_buf)
  FontObj  *obj;
  int   jiscode;
  int   w;
  int   h;
  int   bw;
  int   bo;
  char  *bm_buf;
{
  int  val;
  long *vfdata;

  if ((vfdata = GetOutline(obj, jiscode)) == NULL)
    return -1;
  val = DrawOutline(obj, vfdata, w, h, bw, bo, bm_buf);
  FreeOutline(obj, vfdata);
  return val;
}


Private long*
GetOutline(obj, jiscode)
  FontObj  *obj;
  int      jiscode;
{
  long  *outline;
  Font  *font;
  
  font = (Font*) obj->Locals;
  outline = NULL;
  switch (font->type){
  default:
  case TYPE_WHITE:
    if ((outline = (long*)malloc((int)(3)*sizeof(long))) == NULL)
      return NULL;
    outline[0] = jiscode;
    outline[1] = VF_SONY_COORDINATES;
    outline[2] = 0L;
    break;
  case TYPE_BLACK:
    if ((outline = (long*)malloc((int)(8)*sizeof(long))) == NULL)
      return NULL;
    outline[0] = jiscode;
    outline[1] = VF_SONY_COORDINATES;
    outline[2] = VFD_TOKEN|VFD_CHAR|VFD_CWCURV|VFD_LINE;
    outline[3] = VFD_MAKE_XY(12288, 12288);
    outline[4] = VFD_MAKE_XY(12288, 20479);
    outline[5] = VFD_MAKE_XY(20479, 20479);
    outline[6] = VFD_MAKE_XY(20479, 12288);
    outline[7] = 0L;
    break;
  case TYPE_FRAME:
    if ((outline = (long*)malloc((int)(13)*sizeof(long))) == NULL)
      return NULL;
    outline[0] = jiscode;
    outline[1] = VF_SONY_COORDINATES;
    outline[2] = VFD_TOKEN|VFD_CHAR|VFD_CWCURV|VFD_LINE;
    outline[3] = VFD_MAKE_XY(12288, 12288);
    outline[4] = VFD_MAKE_XY(20479, 12288);
    outline[5] = VFD_MAKE_XY(20479, 20479);
    outline[6] = VFD_MAKE_XY(12288, 20479);
    outline[7] = VFD_TOKEN|VFD_CHAR|VFD_CWCURV|VFD_LINE;
    outline[8] = VFD_MAKE_XY(12288+WD, 12288+WD);
    outline[9] = VFD_MAKE_XY(20479-WD, 12288+WD);
    outline[10]= VFD_MAKE_XY(20479-WD, 20479-WD);
    outline[11]= VFD_MAKE_XY(12288+WD, 20479-WD);
    outline[12]= 0L;
    break;
  }
  return outline;
}


Private long*
GetOutline2(obj, jiscode)
  FontObj  *obj;
  int      jiscode;
{
  return GetOutline2(obj, jiscode);
}


Private int
DrawOutline(obj, vfdata, w, h, bw, bo, bm_buf) 
  FontObj  *obj;
  long     *vfdata;
  int   w;
  int   h;
  int   bw;
  int   bo;
  char  *bm_buf;
{
  unsigned char *buff, d;
  int           rast, x, y, yy1, yy2, val;
  
  rast = (w+7)/8;
  if ((buff = (unsigned char*) malloc(h*rast)) == NULL)
    return -1;   /* ERR: malloc err */ 
  bzero(buff, rast*h);
  if ((val = VF_Draw(vfdata, w, h, rast, buff, 0, 0)) < 0){
    free(buff);
    return -1;
  }    
  yy1 = 0;  yy2 = 0;
  for (y = 0; y < h; y++){
    for (x = 0; x < rast; x++){
      d = buff[yy2 + x];
      bm_buf[yy1 + x]   |= d >> bo;
      bm_buf[yy1 + x+1] |= d << (8-bo);
    }
    yy1 += bw;
    yy2 += rast;
  }
  free(buff);
  return val;
}


Private int
FreeOutline(obj, vfdata)
  FontObj  *obj;
  long*    vfdata;
{
  Font  *font;

  font = (Font*) obj->Locals;
  if (vfdata != NULL)
    free(vfdata);
  return 0;
}



Private int
Link(obj)
  FontObj  *obj;
{
  obj->LinkCount = obj->LinkCount + 1;
  return obj->LinkCount;
}

Private int
Unlink(obj)
  FontObj  *obj;
{
  obj->LinkCount = obj->LinkCount - 1;
  return obj->LinkCount;
}


static int
ReadCapa(font, ent)
  Font *font;
  char *ent;
{
  char *p;

  VFC_GetEntry(ent);
  if ((p = VFC_GetString(VFCE_TYPE)) == NULL)
    font->type = TYPE_DEFAULT;
  else {
    if (strcmp(p, "black") == 0){
      font->type = TYPE_BLACK;
    } else if (strcmp(p, "white") == 0){
      font->type = TYPE_WHITE;
    } else if (strcmp(p, "frame") == 0){
      font->type = TYPE_FRAME;
    } else {
      fprintf(stderr, "VFlib VF_Null: unknown type %s (%s)... Use default.\n",
	      p, ent);
    }
  }
  return 0;
}
