// #define DEBUG
/*
	ARTemis (Graphic Editor for FM-TOWNS)
	(c) MATSUUCHI Ryosuke 1992,1993

	pen.c

(*) int		pen_init(void)
(*) void	pen_end(void)

	pen_t	*pen_new(void)
	void	pen_delete(pen_t *pp)
	int		pen_setpattern(pen_t *pp, penpat_t patp)
	void	pen_getpattern(pen_t *pp, penpat_t outpat)
	void	pen_settype(pen_t *pp, pentype_t type)
	pentype_t pen_gettype(pen_t *pp)
	void	pen_setoriginalpen(pen_t *pp, pen_t *inp)
	pen_t	*pen_getoriginalpen(pen_t *pp)
	void	pen_clearoriginalpen(pen_t *pp)
	void	pen_setsize(pen_t *pp, int size)
	int		pen_getsize(pen_t *pp)
	void	pen_setrotate(pen_t *pp, int rot)
	int		pen_getrotate(pen_t *pp)
	void	pen_setzoom(pen_t *pp, int zoom)
	int		pen_getzoom(pen_t *pp)
	void	pen_setcenterflag(pen_t *pp, bool flag)
	bool	pen_getcenterflag(pen_t *pp)
	void	pen_setgray(pen_t *pp, int gray)
	int		pen_getgray(pen_t *pp)
	void	pen_makeup(pen_t *pp)
 (*)void	pen_display(pen_t *pp, int x, int y)
 (*)bool	pen_isdottype(pen_t *p)
 (*)void	pen_fill(const pen_t *p,
				  void func(int x0,int y0,int dx,int xlen,int dy,
				  			short *graymap)!,
				  const int x, const int y, const bool clip)


	void	penlist_init(penlist_t *lp)
	void	penlist_delete(penlist_t *lp)
	int 	penlist_addpen(penlist_t *lp, pen_t *pp)
	void	penlist_deletepen(penlist_t *lp, pen_t *pp)
	pen_t	*penlist_getfirstpen(penlist_t *lp)
	pen_t	*penlist_getnextpen(penlist_t *lp)
	int		penlist_getpennum(penlist_t *lp)
	pen_t	*penlist_getnpen(penlist_t *lp, int n)
*/

#define	MODULE_pen

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>

#include "ge.h"
#include "dispman.h"
#include "imageman.h"

/*--------------------------------------------------------*/
/*                          定数                          */
/*--------------------------------------------------------*/

#define	DOTXLEN	8
#define	DOTYLEN	8

/*--------------------------------------------------------*/
/*                        内部変数                        */
/*--------------------------------------------------------*/

typedef struct {
	pen_t	*listtop;
	pen_t	*curptr;
} penlist_t;

typedef	short int penpat_t[32][32];
static	penlist_t	penlist;
static	penlist_t	kouholist;
static	int			kouho_num = 0;	// ペン先候補の番号
// [3*8];
// static	pen_t	nowpen_mixed;
// static	pen_t	*nowpenp = &penlist[0]; // 現在のペン先の元となっているペン先
static	pen_t	*nowpen = NULL;			// NULL or &nowpen_mixed

/*--------------------------------------------------------*/
/*            (local) モジュール内部の補助関数            */
/*--------------------------------------------------------*/

static int __curpenx = 0, __curpeny = 0;

static void getcurpenxy(int *x, int *y)
{
	*x = __curpenx;
	*y = __curpeny;
}


static void setcurpenxy(int x, int y)
{
	__curpenx = x;
	__curpeny = y;
	// nowpenp = penlist + y * 3 + x;
}

static void grayPset(int x,int y,int gray256)
{
	int scale;
	if      (gray256 < 0)	gray256 = 0;
	else if (gray256 > 256)	gray256 = 256;
	scale = (gray256+5)/29;	// 階調を 0,1,2,3,4,5,6,7,8,9 で表す
	gpset(x,y,menu_plt(Black+(9-scale)),DrawNORMAL);
}

/*--------------------------------------------------------*/
/*                      ペン先の管理                      */
/*--------------------------------------------------------*/

static void makeup_penpat(penpat_t out, penpat_t in, int gray, bool centergray)
{
	int x,y,r;
	r=0;
	if (centergray)
	{
		for(y=0; y<32; y++)
			for(x=0; x<32; x++)
				if (in[y][x] > 0)
					r = _max(r, abs(x-15), abs(y-15));
	}
	for(y=0; y<32; y++)
	{
		for(x=0; x<32; x++)
		{
			int g,dx,dy;
			dx = x-15, dy = y-15;
			if(centergray && r>0)
				g = _max(0, gray - (gray * (dx*dx+dy*dy) + r*r/2) / (r*r));
			else
				g = gray;
			out[y][x] = (in[y][x] * g + 128 ) / 256;
			if(in[y][x] > 0)
				out[y][x] = _max(1, out[y][x]);
		}
	}
}

static pen_t *pen_new(void)
{
	pen_t *p = malloc(sizeof(pen_t));
	if (p == NULL)
		return NULL;
	p->next = NULL;
	p->pattern = NULL;
	p->type = PENTYPE_ANY;
	p->originalpen = NULL;
	p->gray = 256;
	p->centergray = NO;
	return p;
}

static void pen_delete(pen_t *p)
{
	if (p->pattern != NULL)
		free(p->pattern);
	free(p);
}

static int pen_setpattern(pen_t *pp, penpat_t pat)
{
	if (pp->pattern != NULL)
		free(pp->pattern);
	pp->pattern = malloc(sizeof(penpat_t));
	if (pp->pattern == NULL)
		return -1;
	memcpy(pp->pattern, pat, sizeof(penpat_t));
	return 0;
}

static void pen_getpattern(pen_t *pp, penpat_t outpat)
{
	memset(outpat, 0, sizeof(penpat_t));
	if (pp->pattern == NULL)
		return;
	memcpy(outpat, pp->pattern, sizeof(penpat_t));
}

static void pen_settype(pen_t *pp, pentype_t type)
{
	pp->type = type;
}

static pentype_t pen_gettype(pen_t *pp)
{
	return pp->type;
}

static void pen_setoriginalpen(pen_t *pp, pen_t *inp)
{
	penpat_t pat, pat2;
	if (inp != NULL)
	{
		pen_settype(pp, pen_gettype(inp));
		if (inp->pattern != NULL)
		{
			pen_getpattern(inp,pat);
			makeup_penpat(pat2, pat, pp->gray, pp->centergray);
			pen_setpattern(pp, pat2);
		}
		else
		{
			if (pp->pattern != NULL)
				free(pp->pattern);
			pp->pattern = NULL;
		}
	}
	pp->originalpen = inp;
}

static pen_t *pen_getoriginalpen(pen_t *pp)
{
	return pp->originalpen;
}

static void pen_clearoriginalpen(pen_t *pp)
{
}

#if 0
static void pen_setsize(pen_t *pp, int size)
// 丸ペン／四角ペンの場合の大きさ
{
}

static int pen_getsize(pen_t *pp)
// 丸ペン／四角ペンの場合の大きさ
{
	return 1;
}

static void pen_setrotate(pen_t *pp, int rot)
{
}

static int pen_getrotate(pen_t *pp)
{
	return 0;
}

static void pen_setzoom(pen_t *pp, int zoom)
{
}

static int pen_getzoom(pen_t *pp)
{
	return 100;
}
#endif

static void pen_setcenterflag(pen_t *pp, bool flag)
{
	pp->centergray = YES;
	if (pp->originalpen != NULL)
	{
		penpat_t pat1,pat2;
		pen_getpattern(pp->originalpen, pat1);
		makeup_penpat(pat2, pat1, pp->gray, pp->centergray);
		pen_setpattern(pp, pat2);
	}
}

static bool pen_getcenterflag(pen_t *pp)
{
	return pp->centergray;
}

static void pen_setgray(pen_t *pp, int gray)
{
	pp->gray = gray;
	if (pp->originalpen != NULL)
	{
		penpat_t pat1,pat2;
		pen_getpattern(pp->originalpen, pat1);
		makeup_penpat(pat2, pat1, pp->gray, pp->centergray);
		pen_setpattern(pp, pat2);
	}
}

static int pen_getgray(pen_t *pp)
{
	return pp->gray;
}

static void pen_makeup(pen_t *pp)
{
	if (pp==NULL)
		return;
	if (pp->originalpen != NULL)
	{
		pen_settype(pp, pen_gettype(pp->originalpen));
		if ((pp->originalpen)->pattern != NULL)
		{
			penpat_t pat,pat2;
			pen_getpattern(pp->originalpen,pat);
			makeup_penpat(pat2,pat,pp->gray,pp->centergray);
			pen_setpattern(pp, pat2);
		}
		else
		{
			if (pp->pattern != NULL)
				free(pp->pattern);
			pp->pattern = NULL;
		}
	}
}

void pen_display(pen_t *pp, int x, int y)
{
	grboxfill(x,y,32,32,menu_plt(White),DrawNORMAL);
	if (pp==NULL || pp->pattern == NULL)
		return;
	penpat_t pat;
	pen_getpattern(pp, pat);
	int i,j;
	for (i=0; i<32; i++)
		for (j=0; j<32; j++)
		{
			short int g = pat[i][j];
			if (g > 0)
				grayPset(x+j,y+i,pat[i][j]);
		}
}

bool pen_isdottype(pen_t *p)
{
	if (p==NULL)
		return YES;
	if (p->type == PENTYPE_DOT)
		return YES;
	else
		return NO;
}

void pen_fill(pen_t *p,
			  void func(int x0,int y0,int dx,int xlen,int dy,
			  			short *graymap)!,
			  const int x, const int y, const bool clip)
/*
	機能：ペン先内の各水平ラインについて、何かを行う関数を呼び出す。
	　　　ペン先の形にそって描画などを行うときに用いる。
	
	p    : ペン先
	func : 呼び出す関数(x0,y0=ペンの中心の座標 dx,dy=ペンの中心からの相対座標
					    xlen=水平ラインの長さ  graymap=濃淡リストへのポインタ)
	x,y  : ペンの中心の、編集画面内での座標
	clip : 画面の端でクリッピングするかどうか
*/
{
	int ixlen = EIMgetxsize(), iylen = EIMgetysize();
#if 0
	static short dummy_graymap[] = {256};
	if (0<=x && x<ixlen && 0<=y && y<iylen)
		func(x,y,0,1,0,dummy_graymap);
	return;
#else
	if (p == NULL || pen_isdottype(p) || p->pattern == NULL)
	{
		static short dummy_graymap[] = {256};
		if (0<=x && x<ixlen && 0<=y && y<iylen)
			func(x,y,0,1,0,dummy_graymap);
		return;
	}
	int penxl,penyl;
	penxl=penyl=32;
	int x0,y0, x1,y1,x2,y2;
	x0 = x - ((penxl>>1)-1);
	y0 = y - ((penyl>>1)-1);
	if (clip)
		x1=_max(0,x0), y1=_max(0,y0),
		x2=_min(ixlen-1,x0+penxl-1), y2=_min(iylen-1,y0+penyl-1);
	else
		x1=x0, y1=y0, x2=x0+penxl-1, y2=y0+penyl-1;
	int xlen = x2-x1+1;
	short *p0 = (short*)p->pattern + (y1-y0)*32 + (x1-x0);
	int i;
	for (i=y1; i<=y2; i++, p0+=penxl)
	{
		int ix=0;
		while (ix<xlen)
		{
			int l=(_skip_char(p0+ix,xlen*2,0))>>1;
			ix+=l;
			if(ix>=xlen)  break;
			for(l=0;ix+l<xlen;l++)
				if(p0[ix+l]==0) break;
			if(l>0)
				func(x,y, x1+ix-x,l, i-y, p0+ix);
			ix+=l;
		}
	}
#endif
}

/*--------------------------------------------------------*/
/*                    ペンリストの管理                    */
/*--------------------------------------------------------*/

static void penlist_init(penlist_t *lp)
{
	lp->listtop = NULL;
	lp->curptr = NULL;
}

static void penlist_delete(penlist_t *lp)
{
	pen_t *p,*pp;
	for(p=lp->listtop,pp=NULL; p!=NULL; pp=p,p=p->next)
	{
		if(pp!=NULL) { pen_delete(pp); pp=NULL; }
	}
	if(pp!=NULL) { pen_delete(pp); pp=NULL; }
	lp->listtop = NULL;
	lp->curptr = NULL;
}

static int penlist_addpen(penlist_t *lp, pen_t *pp)
{
	if (lp->listtop == NULL)
		lp->listtop = pp;
	else
	{
		pen_t *p;
		for (p=lp->listtop; p->next!=NULL; p=p->next)
			;
		p->next = pp;
	}
	pp->next = NULL;
	return 0;
}

static void penlist_deletepen(penlist_t *lp, pen_t *pp)
{
}

static pen_t *penlist_getfirstpen(penlist_t *lp)
{
	lp->curptr = lp->listtop;
	return lp->curptr;
}

static pen_t *penlist_getnextpen(penlist_t *lp)
{
	if (lp->curptr != NULL)
		lp->curptr = (lp->curptr)->next;
	return lp->curptr;
}

static int penlist_getpennum(penlist_t *lp)	// リストに登録されているペンの数
{
	pen_t *p; int i;
	for (p=penlist_getfirstpen(lp), i=0; p!=NULL;
		 p=penlist_getnextpen(lp), i++)
		;
	return i;
}

static pen_t *penlist_getnpen(penlist_t *lp, int n)	// リストの n 番目のペン
{
	pen_t *p; int i;
	for (p=penlist_getfirstpen(lp), i=0;
		 i<n && p!=NULL;
		 p=penlist_getnextpen(lp), i++)
		;
	return p;
}

static int penlist_getpenidx(penlist_t *lp, pen_t *pp) // リストの何番目のペンか
{
	pen_t *p; int i;
	for (p=penlist_getfirstpen(lp), i=0; p!=NULL;
		 p=penlist_getnextpen(lp), i++)
		if (p == pp)
			return i;
	return -1;
}

/*--------------------------------------------------------*/
/*                     メニューの定義                     */
/*--------------------------------------------------------*/

// ●ペン設定メニュー

/*
enum {
	itemPenList=13,
	itemPenEdit,
	itemPens,
	itemZoom,
	itemGraySample,
	itemICONS,
	itemSave,
	itemLoad,
};

enum {
	barPenList=4
};
*/


#define	ANYPENXNUM	3
#define	ANYPENYNUM	4
#define	ANYPENXLEN	36
#define	ANYPENYLEN	36

#define	BTN(n)	(penmenu.buttonlist[n])
#define	BAR(n)		menu_scrollbar(&penmenu,n)
#define	BARVAR(n)	menu_scrollbar_getvar(menu_scrollbar(&penmenu,n))

static void putpenlist();
static void zoomupPenData();
static void _putGraySample(int x,int y);
static void drawPenMenu(),erasePenMenu();
static void putGraySample(int gray256);
static void putMix();
static void disp_anypenlist();
static void setpengray();

// ●任意ペン編集メニュー

/*
enum {
	barSetGray=0
};
*/

#define	EBTN(n)	(peneditmenu.buttonlist[n])
#define	EBAR(n)	menu_scrollbar(&peneditmenu,n)

static void disp_peneditmenu();
static void erase_peneditmenu();

#include "pen.md"

/*--------------------------------------------------------*/
/*                  (global) 状態取得関数                 */
/*--------------------------------------------------------*/

pen_t *getcurpen(void)
{
	return nowpen;
}

#if 0
pen_t *getcurpen_0(void)	// 現在のペン先の元データのペン先へのポインタを返す
{
	// return nowpenp;
	return nowpen;
}
#endif

int	 getmixrate(void)
{
	return mixrate;
}

/*--------------------------------------------------------*/
/*            (local) モジュール内部の補助関数            */
/*--------------------------------------------------------*/

// ● ペン先候補カーソルの描画／消去

static bool __kcsr_disp = NO;
static int  __kcsr_pos = 0;
static int ki[] =
  { itemPenKouho0, itemPenKouho1, itemPenKouho2, itemPenKouho3,
    itemPenKouho4 };

static void kcsr_erase(void)
{
	if (!__kcsr_disp)
		return;
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,ki[__kcsr_pos],&ix,&iy,&ixlen,&iylen);
	grboxline(ix,iy,ixlen,iylen,menu_plt(White),DrawNORMAL);
	grboxline(ix+1,iy+1,ixlen-2,iylen-2,menu_plt(White),DrawNORMAL);
	__kcsr_disp = NO;
}

static void kcsr_disp(int n)
{
	if (__kcsr_disp)
		kcsr_erase();
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,ki[n],&ix,&iy,&ixlen,&iylen);
	grboxline(ix,iy,ixlen,iylen,menu_plt(Black),DrawNORMAL);
	grboxline(ix+1,iy+1,ixlen-2,iylen-2,menu_plt(Black),DrawNORMAL);
	__kcsr_disp = YES;
	__kcsr_pos = n;
}

// ●任意ペン選択カーソルの描画／消去

static bool __acsr_disp = NO;
static int	__acsr_x, __acsr_y;

static void acsr_erase(void)
{
	if (!__acsr_disp)
		return;
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,itemPenList,&ix,&iy,&ixlen,&iylen);
	grboxline(ix+__acsr_x+1,iy+__acsr_y+1,ANYPENXLEN-2,ANYPENYLEN-2,
			  menu_plt(White),DrawNORMAL);
	__acsr_disp = NO;
}

static void acsr_disp(void)
{
	if (__acsr_disp)
		acsr_erase();
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,itemPenList,&ix,&iy,&ixlen,&iylen);
	#define	B	BARVAR(barPenList)
	pen_t *kp = penlist_getnpen(&kouholist, kouho_num), *origp;
	int an = -1;
	if (kp != NULL && (origp = pen_getoriginalpen(kp)) != NULL)
		an = penlist_getpenidx(&penlist, origp) - B*ANYPENXNUM;
	if (an>=0 && 0 <= an && an < ANYPENYNUM*ANYPENXNUM)
	{
		int tx = (an % ANYPENXNUM) * ANYPENXLEN;
		int ty = (an / ANYPENXNUM) * ANYPENYLEN;
		grboxline(ix+tx+1,iy+ty+1,ANYPENXLEN-2,ANYPENYLEN-2,
		          menu_plt(Black),DrawNORMAL);
		__acsr_disp = YES;
		__acsr_x = tx;
		__acsr_y = ty;
	}
	#undef B
}

// ●

static void grayBoxfill(int x,int y,int xlen,int ylen,int gray256)
{
	int scale1,scale2;
	gray256=_lim(gray256,0,256);
	if(gray256==0)
		{ grboxfill(x,y,xlen,ylen,menu_plt(White),DrawNORMAL);return; }
	else if(gray256==256)
		{ grboxfill(x,y,xlen,ylen,menu_plt(Black),DrawNORMAL);return; }
	scale1 = (gray256+5)/29;	// 階調を 0,1,2,3,4,5,6,7,8,9 で表す
	scale2 = (gray256+5)%29;
	grboxfill(x,y,xlen,ylen,menu_plt(Black+(9-scale1)),DrawNORMAL);
	if (scale2 > 14)		// 中間調だったら網かけ
		mist(x,y,xlen,ylen,menu_plt(Black+(9-(scale1+1))));
}

void putPenSample(int x,int y, pen_t *pen)
{
	int i,j,gray;
	grboxfill(x,y,16,16,menu_plt(White),DrawNORMAL);
	#if 1
		gpset(x+7,y+7,menu_plt(Black),DrawNORMAL);
	#else
		if (pen == NULL)
		{
			gpset(x+7,y+7,menu_plt(Black),DrawNORMAL);
		}
		else
		{
			for (i=0; i<16; i++)
			{
				for (j=0; j<16; j++)
				{
					if ((gray = pen->pat[i*16+j]) != 0)
						grayPset(x+j,y+i,gray);
				}
			}
		}
	#endif
}

static void drawPenCsr(void)
{
#if 0
	BUTTON *ip;
	ip = &penmenu.buttonlist[itemPens];
	int x,y;
	getcurpenxy(&x,&y);
	grboxline(menuX+ip->x+8+x*24-2,menuY+ip->y+8+y*24-2,20,20,menu_plt(Black),DrawNORMAL);
#endif
}

static void erasePenCsr(void)
{
#if 0
	BUTTON *ip;
	ip = &penmenu.buttonlist[itemPens];
	int x,y;
	getcurpenxy(&x,&y);
	grboxline(menuX+ip->x+8+x*24-2,menuY+ip->y+8+y*24-2,20,20,menu_plt(White),DrawNORMAL);
#endif
}

static void putpenlist(void)
{
#if 0
	BUTTON *ip;
	ip = &penmenu.buttonlist[itemPens];
	grboxfill(menuX+ip->x,menuY+ip->y,ip->xlen,ip->ylen,menu_plt(White),DrawNORMAL);
	int i,j;  pen_t *pen;
	pen = penlist;
	for (i=0; i<8; i++)
	{
		for (j=0; j<3; j++,pen++)
		{
			putPenSample(menuX+ip->x+8+j*24,menuY+ip->y+8+i*24,pen);
		}
	}
#endif
}

static void zoomupPenData(void)
{
#if 0
	pen_t *penp;
	penp = getcurpen_0();
	BUTTON *ip;
	ip = &penmenu.buttonlist[itemZoom];
	int x,y;
	x = menuX+ip->x;		y = menuY+ip->y;
	grboxfill(x,y,128-1,128-1,menu_plt(White),DrawNORMAL);
	int i,j;
	for (i=0; i<=16; i++)
	{
		gvline(x-1+i*8,y-1,y+128-1,menu_plt(Black),DrawNORMAL);
		ghline(x-1,x+128-1,y-1+i*8,menu_plt(Black),DrawNORMAL);
	}
	if (penp != NULL)
	{
		for (i=0; i<16; i++)
			for (j=0; j<16; j++)
			{
				int gray256;
				if ((gray256 = penp->pat[i*16+j]) != 0)
					grayBoxfill(x+j*8,y+i*8,7,7,gray256);
			}
	}
	else
	{
		grayBoxfill(x+7*8,y+7*8,7,7, 256);
	}
#endif
}

static void _putGraySample(int x,int y)
{
#if 0
	SCROLLBAR *bp;
	bp = &penmenu.sbarlist[0];
	grayBoxfill(x,y,20,20,bp->dsppos);
#endif
}

static void putGraySample(int gray256)
{
#if 0
	BUTTON *ip;
	// 濃度のグレイスケール表示
	ip = &penmenu.buttonlist[itemGraySample];
	grayBoxfill(menuX+ip->x,menuY+ip->y,ip->xlen,ip->ylen,gray256);
#if 0
	// 濃度の表示
	ip = &penmenu.buttonlist[itemGrayNumber];
	grboxfill(menuX+ip->x,menuY+ip->y,8*4,16,menu_plt(COL_menu),DrawNORMAL); // 消去
	char strbuf[6];
	sprintf(strbuf,"%3d",gray256);
	grp_putstr(menuX+ip->x,menuY+ip->y,strbuf,menu_plt(COL_menuString));
#endif
#endif
}

static void putMix(int mix256)
{
	BUTTON *ip;
#if 0
	// 描画濃度の数値表示
	ip = &penmenu.buttonlist[itemMix];
	grboxfill(menuX+ip->x,menuY+ip->y,8*3,16,menu_plt(COL_menu),DrawNORMAL); // 消去
	char strbuf[6];
	sprintf(strbuf,"%3d",mix256);
	grp_putstr(menuX+ip->x,menuY+ip->y,strbuf,menu_plt(COL_menuString));
#endif
}

static void alterPenData(int px,int py, int gray256)
{
#if 0
	pen_t *penp = getcurpen_0();
	int penx,peny;
	getcurpenxy(&penx,&peny);
	// データの更新
	penp->pat[px+py*16] = gray256;
	// 拡大表示の更新
	BUTTON *ip;
	ip = &penmenu.buttonlist[itemZoom];
	int x,y;
	x = menuX+ip->x;		y = menuY+ip->y;
	grayBoxfill(x+px*8,y+py*8,7,7,gray256);
	// サンプル表示の更新
	ip = &penmenu.buttonlist[itemPens];
	x = menuX + ip->x + 8 + penx*24;
	y = menuY + ip->y + 8 + peny*24;
	grayPset(x+px,y+py,gray256);
#endif
}

static int getPenGray(pen_t *penp, int px,int py)
{
#if 0
	return penp->pat[px+py*16];
#endif
	return 0;
}

static void makeupPenData(pen_t *pp)
{
#if 0
	bool normal;
	int i,j;
	normal = YES;
	for (i=0; i<16; i++)
	{
		for (j=0; j<16; j++)
		{
			if (i==7 && j==7)
			{
				if (pp->pat[i*16+j]!=256)	normal = NO;
			}
			else
			{
				if (pp->pat[i*16+j]!=0)	normal = NO;
			}
		}
	}
	pp->x1 = pp->y1 = 0;
	pp->xlen = pp->ylen = 16;
	pp->normal = normal;
#endif
}

// ●任意ペンリストの描画

static void disp_anypenlist(void)
{
	#define	B	BARVAR(barPenList)
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,itemPenList,&ix,&iy,&ixlen,&iylen);
	int i,j;
	int s = (ANYPENXLEN-32)/2;
	for (i=0; i<ANYPENYNUM; i++)
		for (j=0; j<ANYPENXNUM; j++)
		{
			pen_t *p = penlist_getnpen(&penlist,ANYPENXNUM*(i+B)+j);
			pen_display(p, ix+j*ANYPENXLEN+s, iy+i*ANYPENYLEN+s);
		}
	#undef B
	acsr_erase();
	acsr_disp();
}

// ●ペン先候補リストの描画

static void disp_kouho(int n)
{
	int ix,iy,ixlen,iylen;
	int s;
	menu_getbuttonxy(NULL,itemPenKouho0+n,&ix,&iy,&ixlen,&iylen);
	s = (ixlen-32)/2;
	pen_t *p = penlist_getnpen(&kouholist,n);
	pen_display(p, ix+s, iy+s);
}

static void disp_kouholist(void)
{
	int i;
	for (i=0; i<5; i++)
		disp_kouho(i);
}

// ●ペン濃度の設定（スクロールバー関数）

static void setpengray(void)
{
	SCROLLBAR *sp = menu_scrollbar(&penmenu, barPenGray);
	if(sp==NULL) return;
	pen_t *kp = penlist_getnpen(&kouholist,kouho_num);
	if(kp==NULL) return;
	pen_setgray(kp, menu_scrollbar_getvar(sp));
	disp_kouho(kouho_num);
}

// ●メニューの描画／消去

static void drawPenMenu()
{
	disp_kouholist();
	kcsr_disp(kouho_num);
	acsr_disp();
}

static void erasePenMenu()
{
	kcsr_erase();
	acsr_erase();
}

/*--------------------------------------------------------*/
/*              モジュールの初期化／終了処理              */
/*--------------------------------------------------------*/

int		pen_init(void)
{
	penlist_init(&penlist);
	penlist_init(&kouholist);
	int i;
	penpat_t pat;
	memset(&pat,0,sizeof(penpat_t));
	pat[15][15] = 256;
	for (i=0; i<5; i++)
	{
		pen_t *pp = pen_new();
		pen_t *kp = pen_new();
		if (pp==NULL||kp==NULL) goto ERR;
		if (pen_setpattern(pp, pat)!=0) goto ERR;
		if (pen_setpattern(kp, pat)!=0) goto ERR;
		pen_settype(pp, PENTYPE_ANY);
		pen_settype(kp, PENTYPE_ANY);
		if (penlist_addpen(&kouholist, kp) != 0) goto ERR;
		if (penlist_addpen(&penlist, pp) != 0) goto ERR;
		pen_setoriginalpen(kp, pp);
	}
	int an = ANYPENXNUM*ANYPENYNUM-1;
	do {
		pen_t *pp;
		if ((pp = pen_new()) == NULL) goto ERR;
		pen_settype(pp, PENTYPE_ANY);
		if (pen_setpattern(pp, pat) != 0)
			goto ERR;
		if (penlist_addpen(&penlist, pp) != 0)
			goto ERR;
	} while (penlist_getnpen(&penlist, an) == NULL);
	kouho_num = 0;
	nowpen = penlist_getnpen(&kouholist, 0);

	int pn = penlist_getpennum(&penlist);
	menu_scrollbar_setallsize(BAR(barPenList),(pn+ANYPENXNUM-1)/ANYPENXNUM+1);
	menu_scrollbar_setdispsize(BAR(barPenList), ANYPENYNUM);
	return 0;
ERR:
	return -1;
}


void	pen_end(void)
{
	return;
}

/*--------------------------------------------------------*/
/*                         副処理                         */
/*--------------------------------------------------------*/

// ●ペンデータのロード・セーブ

typedef struct {
	int			pat[256];
	int			x1,y1,xlen,ylen;
	bool		normal;
} oldpen_t;


#define	PENDATAFILE		"artemis.pen"
static char pendata_fname[128] = {0};


static void savePenData()
{
	if (pendata_fname[0] == 0)
		strcpy(pendata_fname, PENDATAFILE);
	if (fexist(pendata_fname))
	{
		if (resetfattr(pendata_fname) != 0)
		{
			dispAttentionMsg("ペン先データファイルが"
							 "書き込み禁止になっています");
			return;
		}
	}
	FILE *fp;
	if ((fp = fopen(pendata_fname,"wb")) == NULL)
		return;
	char buf[128];
	memset(buf,0,64);
	strcpy(buf, "ARTemis PenDATA r1.00");
	fwrite(buf,1,64,fp);
	int ibuf[20];
	ibuf[0] = penlist_getpennum(&penlist);
	ibuf[1] = sizeof(penpat_t);
	ibuf[2] = penlist_getpennum(&kouholist);
	ibuf[3] = sizeof(pen_t);
	fwrite(ibuf,4,4,fp);
	int i;
	for (i=0; i<ibuf[0]; i++)
	{
		pen_t *ap = penlist_getnpen(&penlist,i);
		if(ap==NULL) goto SVERR;
		penpat_t pat;
		pen_getpattern(ap,pat);
		fwrite(pat,sizeof(pat),1,fp);
	}
	for (i=0; i<ibuf[2]; i++)
	{
		pen_t *kp = penlist_getnpen(&kouholist,i);
		if(kp==NULL) goto SVERR;
		pen_t p;
		p = *kp;
		if (kp->originalpen == NULL)
			p.originalpen = (pen_t *)0;
		else
			p.originalpen =
				(pen_t*) penlist_getpenidx(&penlist, kp->originalpen);
		fwrite(&p, sizeof(pen_t),1,fp);
	}
	SVERR:
	fclose(fp);
}


void loadPenData(void)
{
	int i;
	_searchenv(PENDATAFILE,"PATH",pendata_fname);
	if (pendata_fname[0] == 0)
	{
		_searchenv(PENDATAFILE,"PATH386",pendata_fname);
		if (pendata_fname[0] == 0)
			return;   // ファイルが存在しない
	}
	int size;
	if ((size = getfsize(pendata_fname)) < 0)
		return;
	FILE *fp;
	if ((fp = fopen(pendata_fname,"rb")) == NULL)
		return;
	penlist_delete(&penlist);
	if (size == 24984)
	{
		for (i=0; i<3*8; i++)
		{
			pen_t *pp = pen_new();
			if (pp == NULL) break;
			oldpen_t pbuf;
			fread(&pbuf,sizeof(oldpen_t),1,fp);
			penpat_t penpat;
			memset(penpat, 0, sizeof(penpat_t));
			int j,k;
			for (j=0; j<15; j++)
				for (k=0; k<15; k++)
					penpat[8+j][8+k] = pbuf.pat[j*16+k];
			#if 0
				if (pbuf.normal)
					pen_settype(pp, PENTYPE_DOT);
				else
			#endif
			pen_settype(pp, PENTYPE_ANY);
			pen_setpattern(pp, penpat);
			penlist_addpen(&penlist, pp);
		}
		for (i=0; i<5; i++)
		{
			pen_t *pp = penlist_getnpen(&kouholist, i);
			pen_t *ap = penlist_getnpen(&penlist,i);
			if (pp!=NULL && ap!=NULL)
			{
				pen_settype(pp, pen_gettype(ap));
				pen_setoriginalpen(pp, ap);
			}
		}
	}
	else
	{
		char buf[128];
		fread(buf,1,64,fp);
		if (strcmp(buf, "ARTemis PenDATA r1.00") == 0)
		{
			int an;
			fread(buf,4,1,fp);	// 任意ペンリストの要素数
			an = *(int*)buf;
			fread(buf,4,1,fp);	// 任意ペンリストの１要素のバイト数
								//  (sizeof(penpat_t))
			fread(buf,4,1,fp);	// 候補リストの要素数 (5 ?)
			fread(buf,4,1,fp);	// 候補リストの１要素のバイト数 (sizeof(pen_t))
			/* 任意ペンリストの読み込み */
			for (i=0; i<an; i++)
			{
				penpat_t pat;
				pen_t *pp = pen_new();
				if (pp==NULL) goto LDERR;
				fread(pat,sizeof(penpat_t),1,fp);
				pen_settype(pp, PENTYPE_ANY);
				if (pen_setpattern(pp, pat) != 0)
					goto LDERR;
				if (penlist_addpen(&penlist, pp) != 0)
					goto LDERR;
			}
			/* 候補リストの読み込み */
			for (i=0; i<5; i++)
			{
				pen_t p;
				fread(&p,sizeof(pen_t),1,fp);
				pen_t *kp = penlist_getnpen(&kouholist, i);
				pen_t *ap = penlist_getnpen(&penlist,(int)p.originalpen);
				if(kp==NULL||ap==NULL) goto LDERR;
				kp->type = p.type;
				kp->gray = p.gray;
				kp->centergray = p.centergray;
				pen_setoriginalpen(kp, ap);
			}
			LDERR:
			;
		}
	}
	fclose(fp);
	#define	B	BAR(barPenList)
	int pn = penlist_getpennum(&penlist);
	menu_scrollbar_setallsize(BAR(barPenList),(pn+ANYPENXNUM-1)/ANYPENXNUM+1);
	menu_scrollbar_setdispsize(BAR(barPenList), ANYPENYNUM);
	#undef B
}


static void _loadPenData(void)
{
	kcsr_erase();
	acsr_erase();
	loadPenData();
	int pn = penlist_getpennum(&penlist);
	menu_scrollbar_setallsize(BAR(barPenList),(pn+ANYPENXNUM-1)/ANYPENXNUM+1);
	menu_scrollbar_setdispsize(BAR(barPenList), ANYPENYNUM);
	disp_anypenlist();
	disp_kouholist();
	kcsr_disp(kouho_num);
	acsr_disp();
	{
		pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
		if (kp!=NULL) {
			menu_scrollbar_setvar(menu_scrollbar(
				&penmenu,barPenGray),kp->gray);
			SEL *s = menu_selector(&penmenu,selCenterGray);
			menu_selector_setvar(s, (kp->centergray?0:1));
			menu_selector_makeup(s);
		}
	}
}


/*--------------------------------------------------------*/
/*                   任意ペン編集・補助                   */
/*--------------------------------------------------------*/

typedef struct {
	penpat_t	pat;
	int			selcmd;
} penedit_data;

// ●任意ペン編集メニュー上のコマンド選択カーソルの描画／消去

static bool __ccsr_disp = NO;
static int  __ccsr_cmd;

static void ccsr_erase(void)
{
	if (!__ccsr_disp)
		return;
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,__ccsr_cmd,&ix,&iy,&ixlen,&iylen);
	inverse(ix,iy,ixlen,iylen);
	__ccsr_disp = NO;
}

static void ccsr_disp(int cmd)
{
	if (__ccsr_disp)
		ccsr_erase();
	if (cmd<0)
		return;
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,cmd,&ix,&iy,&ixlen,&iylen);
	inverse(ix,iy,ixlen,iylen);
	__ccsr_disp = YES;
	__ccsr_cmd = cmd;
}

// ●任意ペン編集メニューの描画・消去

static void disp_peneditmenu(void)
{
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,&ixlen,&iylen);
	grboxfill(ix,iy,ixlen,iylen,menu_plt(White),DrawNORMAL);
	penedit_data *d;
	d = menu_getdata(NULL);
	if (d == NULL) goto NODATA;
	int i,j;
	for (i=0; i<32; i++)
	 for (j=0; j<32; j++)
	 {
	  if ((i==15||j==15)&&d->pat[i][j]==0)
	    grboxfill(ix+DOTXLEN*j,iy+DOTYLEN*i,DOTXLEN,DOTYLEN,
	    		  menu_plt(Yellow),DrawNORMAL);
	  else
	    grayBoxfill(ix+DOTXLEN*j,iy+DOTYLEN*i,DOTXLEN,DOTYLEN,d->pat[i][j]);
	 }
	NODATA:
	for (i=0; i<=32; i++)
	{
		ghline(ix-1,ix+ixlen-1,iy-1+DOTYLEN*i,menu_plt(Black),DrawNORMAL);
		gvline(ix-1+DOTXLEN*i,iy-1,iy+iylen-1,menu_plt(Black),DrawNORMAL);
	}
	if (d->selcmd >= 0)
		ccsr_disp(d->selcmd);
}

static void erase_peneditmenu(void)
{
	ccsr_erase();
}

/*--------------------------------------------------------*/
/*                     任意ペンの編集                     */
/*--------------------------------------------------------*/


static void pen_setdot(penpat_t pat, int x, int y, int gray)
{
	int ix,iy,ixlen,iylen;
	menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,&ixlen,&iylen);
	gray = _lim(gray,0,256);
	pat[y][x] = gray;
	if ((x==15||y==15)&&gray==0)
	    grboxfill(ix+DOTXLEN*x,iy+DOTYLEN*y,DOTXLEN-1,DOTYLEN-1,
	    		  menu_plt(Yellow),DrawNORMAL);
	else
		grayBoxfill(ix+DOTXLEN*x,iy+DOTYLEN*y,DOTXLEN-1,DOTYLEN-1,gray);
}

static void pen_editanypen(penpat_t pat)
{
	penedit_data d;
	int i;
	bool docmd = NO;
	int cmdstep;
	int cx,cy;	// ellipse 用
	memcpy(d.pat, pat, sizeof(penpat_t));
	d.selcmd = -1;
	menu_setdata(&peneditmenu, &d);
	menu_disp(&peneditmenu);
	void rubber_ellipse(bool draw)
	{
		int ix,iy;
		menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,NULL,NULL);
		static int tx,ty;
		if (draw)
			tx=(ms.x-ix)/DOTXLEN,ty=(ms.y-iy)/DOTYLEN;
		void pset(int x,int y)
		{
			if (0<=x&&x<32&&0<=y&&y<32)
				pen_setdot(d.pat, x,y,256-d.pat[y][x]);
		}
		do_ellipse(cx,cy,abs(tx-cx),abs(ty-cy),pset);
	}
	void rubber_line(bool draw)
	{
		int ix,iy;
		menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,NULL,NULL);
		static int tx,ty;
		if (draw) tx=(ms.x-ix)/DOTXLEN,ty=(ms.y-iy)/DOTYLEN;
		void pset(int x,int y)
		 { if (0<=x&&x<32&&0<=y&&y<32)
				pen_setdot(d.pat, x,y,256-d.pat[y][x]); }
		do_line(cx,cy,tx,ty,pset);
	}
	void rubber_boxline(bool draw)
	{
		int ix,iy;
		menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,NULL,NULL);
		static int tx,ty;
		if (draw) tx=(ms.x-ix)/DOTXLEN,ty=(ms.y-iy)/DOTYLEN;
		void pset(int x,int y)
		 { if (0<=x&&x<32&&0<=y&&y<32)
				pen_setdot(d.pat, x,y,256-d.pat[y][x]); }
		do_boxline(cx,cy,tx,ty,pset);
	}
	for (;;)
	{
		if (docmd)
		{
			switch(d.selcmd)
			{
			case itemLine:
				rubber_line(YES); break;
			case itemBox: case itemBoxFill:
				rubber_boxline(YES); break;
			case itemEllipseFill: case itemEllipse:
				rubber_ellipse(YES); break;
			}
		}
		DMdispcsr(ms.x,ms.y);
		do
		{
			ms_get(&ms);
		} while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
				 key_chk() == 0);
		DMerasecsr();
		if (docmd)
		{
			switch(d.selcmd)
			{
			case itemLine:
				rubber_line(NO); break;
			case itemBox: case itemBoxFill:
				rubber_boxline(NO); break;
			case itemEllipseFill: case itemEllipse:
				rubber_ellipse(NO); break;
			}
		}
		scrollForCsr(1,1);
		if (ms.btn2==OFFON)
		{
			if (docmd)
				docmd = NO;
			else if (d.selcmd >= 0)
			{
				ccsr_erase();
				d.selcmd = -1;
			}
			else
			{
				int tx,ty;
				int a; int ax,ay;
				a = menu_where(ms.x,ms.y,&peneditmenu, &ax,&ay,NULL);
				switch(a)
				{
				case itemPenZoom:
					tx = ax/DOTXLEN; ty = ay/DOTYLEN;
					menu_scrollbar_setvar(EBAR(barSetGray),d.pat[ty][tx]);
					break;
				default:
					goto ENDLOOP;
				}
			}
		}
		else if (ms.btn1==OFFON)
		{
			int tx,ty;
			int a;  int ax,ay; SCROLLBAR *sbarp;
			a = menu_where(ms.x,ms.y,&peneditmenu, &ax,&ay,&sbarp);
			int gray = menu_scrollbar_getvar(EBAR(barSetGray));
			switch(a)
			{
			case itemMoveMenu:
				menu_move();
				break;
			case itemScrollBar:
				menu_touchscrollbar(sbarp, ax,ay);
				break;
			case itemSelector:
				menu_touchselector(&peneditmenu);
				break;
			case itemPenZoom:
				tx = ax/DOTXLEN; ty = ay/DOTYLEN;
				if (!docmd)
				{
					if (d.selcmd >= 0)
					{
						switch(d.selcmd)
						{
						case itemLine: case itemBox: case itemBoxFill:
						case itemEllipse: case itemEllipseFill:
							docmd=YES;
							cmdstep=0;
							cx=tx,cy=ty;
							break;
						}
					}
					else
						pen_setdot(d.pat, tx,ty,gray);
				}
				else
				{
					void pset(int x,int y)
					{
						if (0<=x&&x<32&&0<=y&&y<32)
							pen_setdot(d.pat, x,y,gray);
					}
					void hline(int x1,int x2,int y)
					{
						int i;
						for (i=x1; i<=x2; i++)
							if (0<=i&&i<32&&0<=y&&y<32)
								pen_setdot(d.pat, i,y,gray);
					}
					switch(d.selcmd)
					{
					case itemLine:
						do_line(cx,cy,tx,ty,pset); cx=tx,cy=ty;
						break;
					case itemBox:
						do_boxline(cx,cy,tx,ty,pset); docmd=NO;
						break;
					case itemBoxFill:
						do_boxfill(cx,cy,tx,ty,hline); docmd=NO;
						break;
					case itemEllipse:
						do_ellipse(cx,cy,abs(tx-cx),abs(ty-cy),pset); docmd=NO;
						break;
					case itemEllipseFill:
						do_ellipsefill(cx,cy,abs(tx-cx),abs(ty-cy),hline);
						docmd = NO;
						break;
					}
				}
				break;
			/* case itemFpset: case itemFline: */
			case itemLine:
			case itemBox: case itemBoxFill:
			case itemEllipse: case itemEllipseFill:
			/* case itemPaint: */
				if (!docmd)
				{
					if (d.selcmd == a)
						d.selcmd = -1;
					else
						d.selcmd = a;
					ccsr_disp(d.selcmd);
				}
				break;
			}
		}
		else if (ms.btn1 == ON)
		{
			int tx,ty;
			int a;  int ax,ay; SCROLLBAR *sbarp;
			a = menu_where(ms.x,ms.y,&peneditmenu, &ax,&ay,&sbarp);
			int gray = menu_scrollbar_getvar(EBAR(barSetGray));
			switch(a)
			{
			case itemPenZoom:
				tx = ax/DOTXLEN; ty = ay/DOTYLEN;
				if (!docmd && d.selcmd < 0)
					pen_setdot(d.pat, tx,ty,gray);
				break;
#if 0
			case itemPenZoom:
				{
					int ix,iy,ixlen,iylen;
					menu_getbuttonxy(NULL,itemPenZoom,&ix,&iy,&ixlen,&iylen);
					int tx,ty;
					tx = ax/DOTXLEN; ty = ay/DOTYLEN;
					d.pat[ty][tx] = 256-d.pat[ty][tx];
					grayBoxfill(ix+DOTXLEN*tx,iy+DOTYLEN*ty,
								DOTXLEN-1,DOTYLEN-1,d.pat[ty][tx]);
				}
#endif
			}
		}
	}
	ENDLOOP:
	menu_erase();
	memcpy(pat, d.pat, sizeof(penpat_t));
	menu_cleardata(&peneditmenu);
}


/*--------------------------------------------------------*/
/*                         主処理                         */
/*--------------------------------------------------------*/


void setPen()
{
	int i;
	{
		pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
		if (kp!=NULL) {
			menu_scrollbar_setvar(menu_scrollbar(&penmenu,barPenGray),
								  kp->gray);
			menu_selector_setvar(menu_selector(&penmenu,selCenterGray),
								 (kp->centergray ? 0 : 1));
		}
	}
	menu_disp(&penmenu);
	for (;;)
	{
		DMdispcsr(ms.x,ms.y);
		do
		{
			ms_get(&ms);
		} while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
				 key_chk() == 0);
		DMerasecsr();
		scrollForCsr(1,1);
		if (ms.btn2==OFFON)
		{
#if 0
			int ax,ay;
			int a = menu_where(ms.x,ms.y,&penmenu, &ax,&ay,NULL);
			if (a == itemPenEdit)
			{
				SCROLLBAR *sp = menu_scrollbar(&penmenu, &penmenu.sbarlist[0];
				sp->dsppos = getPenGray(getcurpen_0(),ax/8,ay/8);
				menu_makeupscrollbar(sp);
				putGraySample(sp->dsppos);
			}
			else
#endif
				break;
		}
		else if (ms.btn1==OFFON)
		{
			int a;  int ax,ay; SCROLLBAR *sbarp;
			a = menu_where(ms.x,ms.y,&penmenu, &ax,&ay,&sbarp);
#if 0
			if (a == itemPens)
			{
				if (ax < 8)		ax = 8;
				if (ay < 8)		ay = 8;
				makeupPenData(getcurpen_0()); // ペンデータの補完
				erasePenCsr();
				setcurpenxy((ax-8)/24, (ay-8)/24);
				zoomupPenData(); // ペン先の拡大表示
				drawPenCsr();
			}
			else if (a == itemZoom)
			{
				int gray256;
				gray256 = penmenu.sbarlist[0].dsppos;
				alterPenData(ax/8,ay/8,gray256);
			}
			else if (a == itemSave)
			{
				savePenData();
			}
			else if (a == itemLoad)
			{
				_loadPenData();
			}
#endif
			switch(a)
			{
			case itemMoveMenu:
				menu_move();
				break;
			case itemScrollBar:
				menu_touchscrollbar(sbarp, ax,ay);
				break;
			case itemSelector:
				menu_touchselector(&penmenu);
				{
					pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
					SEL *s = menu_selector(&penmenu, selCenterGray);
					if(s==NULL||kp==NULL) goto HATENA;
					if (menu_selector_getvar(s)==0)
						kp->centergray = YES;
					else
						kp->centergray = NO;
					pen_makeup(kp);
					disp_kouho(kouho_num);
					HATENA: ;
				}
				break;
			case itemPenKouho0..itemPenKouho4:
				kouho_num = a - itemPenKouho0;
				kcsr_disp(kouho_num);
				acsr_erase();
				acsr_disp();
				{
					pen_t *kp = penlist_getnpen(&kouholist, kouho_num);
					if (kp!=NULL) {
						menu_scrollbar_setvar(menu_scrollbar(
							&penmenu,barPenGray),kp->gray);
						SEL *s = menu_selector(&penmenu,selCenterGray);
						menu_selector_setvar(s, (kp->centergray?0:1));
						menu_selector_makeup(s);
					}
				}
				break;
			case itemPenList:
				{
					#define	B	BARVAR(barPenList)
					int an=(B+ay/ANYPENYLEN)*ANYPENXNUM+ax/ANYPENXLEN;
					pen_t *kp,*ap;
					kp = penlist_getnpen(&kouholist, kouho_num);
					ap = penlist_getnpen(&penlist, an);
					if (kp != NULL && ap!=NULL)
						pen_setoriginalpen(kp, ap);
					else if (ap == NULL)
					{
						pen_t *pp;
						penpat_t penpat;
						memset(penpat,0,sizeof(penpat_t));
						do {
							if ((pp = pen_new()) == NULL)
								goto PLERR;
							pen_settype(pp, PENTYPE_ANY);
							if (pen_setpattern(pp, penpat) != 0)
								goto PLERR;
							if (penlist_addpen(&penlist, pp) != 0)
								goto PLERR;
						} while (penlist_getnpen(&penlist, an) == NULL);
						pen_setoriginalpen(kp, pp);
					}
					PLERR:
					acsr_erase();
					acsr_disp();
					disp_kouholist();
					int pn = penlist_getpennum(&penlist);
					menu_scrollbar_setallsize(BAR(barPenList),
						(pn+ANYPENXNUM-1)/ANYPENXNUM+1);
					#undef B
				}
				break;
			case itemPenEdit:
				{
					menu_erase();
					pen_t *kp,*ap;
					kp = penlist_getnpen(&kouholist, kouho_num);
					if (kp==NULL) break;
					ap = pen_getoriginalpen(kp);
					if (ap==NULL) break;
					penpat_t pat;
					pen_getpattern(ap,pat);
					pen_editanypen(pat);
					pen_setpattern(ap,pat);
					int i;
					for (i=0; i<5; i++)
					{
						kp=penlist_getnpen(&kouholist, i);
						if (kp!=NULL) pen_makeup(kp);
					}
					menu_disp(&penmenu);
				}
				break;
			case btnSave:
				savePenData();
				break;
			case btnLoad:
				_loadPenData();
				break;
			}
		}
		else if (ms.btn1 == ON)
		{
#if 0
			int a;  int ax,ay;
			a = menu_where(ms.x,ms.y,&penmenu, &ax,&ay,NULL);
			if (a == itemZoom)
			{
				int gray256;
				gray256 = penmenu.sbarlist[0].dsppos;
				alterPenData(ax/8,ay/8,gray256);
			}
#endif
		}
	}
	menu_erase();
#if 0
	{
		int i;  pen_t *pp;
		pp = getcurpen_0();
		for (i=0; i<16*16; i++)
		{
			int s,d;
			s = pp->pat[i];
			/* d = (s * mix + 128) / 256;  if (d == 0 && s > 0)  d = 1; */
			d = s;
			nowpen_mixed.pat[i] = d;
		}
	}
	makeupPenData(&nowpen_mixed);
#endif
	nowpen = penlist_getnpen(&kouholist, kouho_num);
}

// end of pen.c
