// Module PI : Peida Interactive     PIGraphicX
// Trace graphiques- Implementation X11  R. Ansari  97
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#include <stdio.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>

#include "pigraphx.h"


/*  Variables globales pour modifier les GC  */
#define NMAXFONTSZ  7
static XFontStruct * fntst[NMAXFONTSZ][3];
static int fntsz[NMAXFONTSZ] = {8,10,12,14,18,24,36};
static int SmallFontIndex = 1; 
static int NormalFontIndex = 3;
static int BigFontIndex = 5;
static int HugeFontIndex = 6;
static  PIFontAtt fntatt[3] = { PI_RomanFont, PI_BoldFont, PI_ItalicFont }; 
#define NMAXCOL  16
static  PIXColor colpix[NMAXCOL];

/*  GC pour DrawPixmap   */
static GC dpxgc;

// #define DEBUG_PIBWDGX     Flag pour impression de debug etc ...

/* --Methode-- */
PIGraphicX::PIGraphicX(PIWdg* wdg)
: PIGraphicGen(wdg)
{

GlInit();

if (MyWdg()) {
  mDisp = XtDisplay(MyWdg());       // Structure Display X associe
  mWId = XtWindow(MyWdg());   // Le drawable X
  }
else mDisp = PIXDisplay();       // Structure Display X associe

XGCValues  xgv;
xgv.function = GXcopy;
xgv.plane_mask = ~0;
mDefGC = XCreateGC (PIXDisplay(), XtWindow(PIXtTopWdg()), GCFunction | GCPlaneMask, &xgv);

Init();
}

/* --Methode-- */
PIGraphicX::PIGraphicX(PIScreenBuffer* grb)
: PIGraphicGen(grb)
{
GlInit();

mDisp = PIXDisplay();       // Structure Display X associe
mWId = grb->XScrBuffer();

XGCValues  xgv;
xgv.function = GXcopy;
xgv.plane_mask = ~0;
mDefGC = XCreateGC (mDisp, mWId, GCFunction | GCPlaneMask, &xgv);
Init();
}


/* --Methode-- */
void PIGraphicX::Init()
{
mGOm = PI_GOCopy;
mFCol = mBCol = PI_Grey;
SelForeground(PI_Black);
SelBackground(PI_White);
mLAtt = PI_ThinLine;
SelLine();
mFAtt = PI_BoldFont;  mFSize = 0;
SelFont();
SelMarker(1, PI_DotMarker);  
mFCfMap = colpix[PI_Black];  mBCfMap = colpix[PI_White];
}

/* --Methode-- */
PIGraphicX::~PIGraphicX()
{
XFreeGC(mDisp, mDefGC);
}

/* --Methode-- */
int PIGraphicX::kind()
{
if (myWdg != NULL) return (PI_ScrWindowGraphics);
else if (myGrb != NULL) return (PI_ScrBufferGraphics);
else return(PI_UnknownGraphics);
}

/* --Methode-- */
void PIGraphicX::TerminateInit()
{
if (MyWdg() == NULL)  { fprintf(stderr, "BUG/PIGraphicX::TerminateInit() for NULL Wdg \n"); return; }
mDisp = XtDisplay(MyWdg());       // Structure Display X associe
mWId = XtWindow(MyWdg());   // Le drawable X
}

/* --Methode-- */
void PIGraphicX::Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
XClearArea (mDisp,mWId, (int)x0, (int)y0, (int)dx, (int)dy, False );
return;
}

/* --Methode-- */
void PIGraphicX::DrawString(PIGrCoord x, PIGrCoord y, const char* s, int /*pos*/)
{
XDrawString (XtDisplay (MyWdg()),mWId, 
                  DefGC(), (int)x, (int)y, s, strlen(s));
return;
}

/* --Methode-- */
void PIGraphicX::DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, int /*pos*/)
{
XDrawImageString (XtDisplay (MyWdg()),mWId, 
                  DefGC(), (int)x, (int)y, s, strlen(s));
return;
}

 
/* --Methode-- */
void PIGraphicX::DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)
{
XDrawLine(XtDisplay (MyWdg()), mWId, DefGC(), (int)x1, (int)y1, (int)x2, (int)y2);
return;
}


/* --Methode-- */
void PIGraphicX::DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
int ix0 = x0;
int iy0 = y0;
int idx = dx;
int idy = dy;
if (idx < 0)  { ix0 += idx;  idx = -idx; }
if (idy < 0)  { iy0 += idy;  idy = -idy; }
XDrawRectangle(XtDisplay (MyWdg()), mWId, 
               DefGC(), ix0, iy0, idx, idy);
return;
}

/* --Methode-- */
void PIGraphicX::DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
int ix0 = x0;
int iy0 = y0;
int idx = dx;
int idy = dy;
if (idx < 0)  { ix0 += idx;  idx = -idx; }
if (idy < 0)  { iy0 += idy;  idy = -idy; }
XFillRectangle(XtDisplay (MyWdg()), mWId, 
               DefGC(), ix0, iy0, idx, idy);
return;
}

/* --Methode-- */
void PIGraphicX::DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
{
XDrawArc(XtDisplay (MyWdg()), mWId, DefGC(),
         (int)x0-(int)r, (int)y0-(int)r, 2*(int)r, 2*(int)r, 0, 360*64);
return;
}

/* --Methode-- */
void PIGraphicX::DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
{
XFillArc(XtDisplay (MyWdg()), mWId, DefGC(),
         (int)x0-(int)r, (int)y0-(int)r, 2*(int)r, 2*(int)r, 0, 360*64);
return;
}

/* --Methode-- */
void PIGraphicX::DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
XDrawArc(XtDisplay (MyWdg()), mWId, DefGC(),
         (int)x0, (int)y0, (int)dx, (int)dy, 0, 360*64);
return;
}

/* --Methode-- */
void PIGraphicX::DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
XFillArc(XtDisplay (MyWdg()), mWId, DefGC(),
         (int)x0, (int)y0, (int)dx, (int)dy, 0, 360*64);
return;
}

// Pour les fonctions de trace avec un plusieurs coordonnees
#define NMXXPOINTS  30 

/* --Methode-- */
void PIGraphicX::DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
{
XPoint multipoint[NMXXPOINTS];
XPoint *pxp;
int i;

if (n <= 0)  return;
if (n > NMXXPOINTS)  pxp = new XPoint[n];
else pxp = multipoint;
for(i=0; i<n; i++)  { pxp[i].x = x[i];  pxp[i].y = y[i]; } 
int mode = CoordModeOrigin;
if (cinc) mode =  CoordModePrevious;
XDrawLines(mDisp, mWId, DefGC(), pxp, n, mode);
if (n > NMXXPOINTS)  delete[] pxp;

return;
}


/* --Methode-- */
void PIGraphicX::DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
{
XPoint multipoint[NMXXPOINTS];
XPoint *pxp;
int i;

if (n <= 0)  return;
if (n > NMXXPOINTS)  pxp = new XPoint[n];
else pxp = multipoint;
for(i=0; i<n; i++)  { pxp[i].x = x[i];  pxp[i].y = y[i]; } 
int mode = CoordModeOrigin;
if (cinc) mode =  CoordModePrevious;
XFillPolygon(XtDisplay (MyWdg()), mWId, DefGC(), pxp, n, 
                        Complex, mode);
if (n > NMXXPOINTS)  delete[] pxp;

return;
}

/* --Methode-- */
void PIGraphicX::DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
                         double degdeb, double degfin)
{
XDrawArc(XtDisplay (MyWdg()), mWId, DefGC(),
         (int)x0, (int)y0, (int)dx, (int)dy, (int)(degdeb*64.), (int)(degfin*64.));
return;
}

/* --Methode-- */
void PIGraphicX::DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
                         double degdeb, double degfin)
{
XFillArc(XtDisplay (MyWdg()), mWId, DefGC(),
         (int)x0, (int)y0, (int)dx, (int)dy, (int)(degdeb*64.), (int)(degfin*64.));
return;
}

/* --Methode-- */
void PIGraphicX::DrawMarker(PIGrCoord x0, PIGrCoord y0)
{
float hmsz = mMrkSz/2;
float dmsz = mMrkSz-hmsz;
PIGrCoord x[4],y[4];
PILineAtt clatt;

if (mMrk == PI_DotMarker)
  XDrawPoint(mDisp, mWId, DefGC(), (int)x0, (int)y0);

else  {
  clatt = mLAtt;
  SelLine(PI_ThinLine);
  switch (mMrk) {
    case  PI_PlusMarker :
      DrawLine((float)x0-hmsz, y0, (float)x0+dmsz, y0);
      DrawLine(x0, (float)y0-hmsz, x0, (float)y0+dmsz);
      break;
    case  PI_CrossMarker :
      DrawLine((float)x0-hmsz, (float)y0-hmsz, (float)x0+dmsz, (float)y0+dmsz);
      DrawLine((float)x0-hmsz, (float)y0+dmsz, (float)x0+dmsz, (float)y0-hmsz);
      break;  
    case PI_CircleMarker :
      DrawCircle(x0, y0, hmsz);
      break;
    case PI_FCircleMarker :
      DrawFCircle(x0, y0, hmsz);
      break;
    case PI_BoxMarker :
      DrawBox((float)x0-hmsz, (float)y0-hmsz, mMrkSz, mMrkSz);
      break;
    case PI_FBoxMarker :
      DrawFBox((float)x0-hmsz, (float)y0-hmsz, mMrkSz, mMrkSz);
      break;
    case  PI_TriangleMarker :
      x[1] = mMrkSz; y[1] = 0; x[2] = -hmsz; y[2] = -mMrkSz; 
      x[3] = -dmsz; y[3] = +mMrkSz; x[0] = (float)x0-hmsz; y[0] = (float)y0+hmsz;  
      DrawPolygon(x, y, 4);
      break;
    case  PI_FTriangleMarker :
      x[1] = mMrkSz; y[1] = 0; x[2] = -hmsz; y[2] = -mMrkSz; 
      x[3] = -dmsz; y[3] = +mMrkSz; x[0] = (float)x0-hmsz; y[0] = (float)y0+hmsz;  
      DrawFPolygon(x, y, 4);
      break;
    default :
      XDrawPoint(mDisp, mWId, DefGC(), x0, y0);
      break;
    }
  SelLine(clatt);
  }

return;
}

/* --Methode-- */
void PIGraphicX::DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)
{
int i;
if (n <= 0)  return;
if (mMrk == PI_DotMarker)
  {
  XPoint multipoint[NMXXPOINTS];
  XPoint *pxp;
  if (n > NMXXPOINTS)  pxp = new XPoint[n];
  else pxp = multipoint;
  for(i=0; i<n; i++)  { pxp[i].x = x[i];  pxp[i].y = y[i]; } 
  XDrawPoints(mDisp, mWId, DefGC(), pxp, n, CoordModeOrigin);
  if (n > NMXXPOINTS)  delete[] pxp;  
  }
else for(i=0; i<n; i++) DrawMarker(x[i], y[i]);

return;
}


/* --Methode-- */
void PIGraphicX::DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
                            int sx, int sy, PIColorMap* cmap)
{
Window xw;
Display * mdsp;
int scr;
int depth;
int pad;
int i,j;
XImage * ximg;

if ( (sx < 1) || (sy < 1) )  return;
if ((pix == NULL) || (cmap == NULL)) return; 

  
xw = mWId;
mdsp = PIXDisplay();
scr = PIXScreen();

depth = DefaultDepth(mdsp,scr);
pad = (depth > 8) ? 32 : 8;
ximg = XCreateImage (mdsp,DefaultVisual(mdsp,scr),
                     depth,ZPixmap,0,NULL, sx, sy, pad,0);
if (ximg == NULL)  return;
ximg->data = new char [sy*ximg->bytes_per_line];
if (ximg->data == NULL)  
  { XFree(ximg); return; }

for(j=0; j<sy; j++)
  for(i=0; i<sx; i++)
    { XPutPixel(ximg, i, j, cmap->Color(*pix) );  pix++; }

XPutImage(mdsp, xw, dpxgc, ximg, 0, 0, (int)x, (int)y, sx, sy);

delete[] ximg->data;
XFree(ximg); 
return;
}



/* --Methode-- */
void PIGraphicX::SelForeground(PIColors col)
{
if (col == mFCol)  return;
if ( (col < 0) || (col >= NMAXCOL))  return;
XSetForeground(mDisp, DefGC(), colpix[col]); 
mFCol = col;  
return;
}

/* --Methode-- */
void PIGraphicX::SelBackground(PIColors col)
{
if (col == mBCol)  return;
if ( (col < 0) || (col >= NMAXCOL))  return;
XSetBackground(mDisp, DefGC(), colpix[col]); 
mBCol = col;  
return;
}

/* --Methode-- */
void PIGraphicX::SelForeground(PIColorMap& cmap, int cid)
{
SelectFCol(cmap.Color(cid));
}

/* --Methode-- */
void PIGraphicX::SelBackground(PIColorMap& cmap, int cid)
{
SelectBCol(cmap.Color(cid));
}

/* --Methode-- */
void PIGraphicX::SelGOMode(PIGOMode mod)
{
if (mod == mGOm)  return;
switch (mod)
  {
  case PI_GOCopy :
    XSetFunction(mDisp, DefGC(), GXcopy);
    mGOm = mod;
    break;
  case PI_GOXOR :
    XSetFunction(mDisp, DefGC(), GXxor);
    mGOm = mod;
    break;
  }
return;
}


/* --Methode-- */
void PIGraphicX::SelFontSzPt(int npt, PIFontAtt att)
{
int dsz,i,isel, j;

if ((npt == mFSize) && (att == mFAtt))  return;
isel = 0;
dsz = 9999;
for(i=0; i<NMAXFONTSZ; i++)
  {
  j = npt - fntsz[i];   if (j < 0)  j = -j;
  if (j < dsz)  {  isel = i; dsz = j; }
  }

j = 0;
if (att & PI_RomanFont) j = 0;
if (att & PI_BoldFont) j = 1;
if (att & PI_ItalicFont) j = 2;
SelectFont(isel, j);

}

/* --Methode-- */
void PIGraphicX::SelFont(PIFontSize sz, PIFontAtt att)
{
int i,j;
switch (sz)
  {
  case PI_SmallSizeFont:
    i = SmallFontIndex;
    break;
  case PI_NormalSizeFont:
    i = NormalFontIndex;
    break;
  case PI_BigSizeFont:
    i = BigFontIndex;
    break;
  case PI_HugeSizeFont:
    i = HugeFontIndex;
    break;
  default:
    i = NormalFontIndex;
    break;
  }

j = 0;
if (att & PI_RomanFont) j = 0;
if (att & PI_BoldFont) j = 1;
if (att & PI_ItalicFont) j = 2;

SelectFont(i, j);
}



/* --Methode-- */
void PIGraphicX::SelLine(PILineAtt att)
{
unsigned int lt=0;
int lstyle=LineSolid;
char dash[2]= {3,3};   

if (att == mLAtt)  return;

switch (att)
  {
  case PI_NormalLine :
    lt = 2;
    lstyle = LineSolid;
    break;
  case PI_ThickLine :
    lt = 4;
    lstyle = LineSolid;
    break;
  case  PI_ThinLine :
    lt = 0;
    lstyle = LineSolid;
    break;

  case PI_DashedLine :
    lt = 2;
    lstyle = LineOnOffDash;
    dash[0] = dash[1] = 6;  
    break;
  case PI_ThickDashedLine :
    lt = 4;
    lstyle = LineOnOffDash;
    dash[0] = dash[1] = 6;  
    break;
  case  PI_ThinDashedLine :
    lt = 0;
    lstyle = LineOnOffDash;
    dash[0] = dash[1] = 6;  
    break;

  case PI_DottedLine :
    lt = 2;
    lstyle = LineOnOffDash;
    dash[0] = 2; dash[1] = 6;  
    break;
  case PI_ThickDottedLine :
    lt = 4;
    lstyle = LineOnOffDash;
    dash[0] = 2; dash[1] = 6;  
    break;
  case  PI_ThinDottedLine :
    lt = 0;
    lstyle = LineOnOffDash;
    dash[0] = 2; dash[1] = 6;  
    break;

  default:
    lt = 0;
    lstyle=LineSolid;
    break;
  }

if (lstyle != LineSolid) 
  XSetDashes( mDisp, DefGC(), 0, dash, 2);
  
XSetLineAttributes(mDisp, DefGC(), lt, lstyle, CapButt, JoinMiter);
mLAtt = att;
return;
}


/* --Methode-- */
void PIGraphicX::SelMarker(int msz, PIMarker mrk)
{
if (msz > 1)  { mMrk = mrk;  mMrkSz = msz; }
else  { mMrk = PI_DotMarker;  mMrkSz = 1; }
return;
}


/* --Methode-- */
void PIGraphicX::SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
XRectangle xr;
xr.x = x0;  xr.y = y0;
xr.width = dx;  xr.height = dy;
XSetClipRectangles(mDisp, DefGC(), 0, 0, &xr, 1, Unsorted);
XSetClipRectangles(mDisp, dpxgc, 0, 0, &xr, 1, Unsorted);
return;
}

/* --Methode-- */
void PIGraphicX::ClearClipRectangle()
{ 
XSetClipMask(mDisp, DefGC(), None);
XSetClipMask(mDisp, dpxgc, None);
return;
}

/* --Methode-- */
PIColors  PIGraphicX::GetForeground() 
{
return (mFCol);
}

/* --Methode-- */
PIColors  PIGraphicX::GetBackground() 
{
return (mBCol);
}


/* --Methode-- */
PIGOMode   PIGraphicX::GetGOMode()
{
return (mGOm);
}

/* --Methode-- */
PIFontAtt  PIGraphicX::GetFontAtt()
{
return (mFAtt);
}

/* --Methode-- */
int        PIGraphicX::GetFontSize()
{
return (mFSize);
}

/* --Methode-- */
PILineAtt  PIGraphicX::GetLineAtt()
{
return (mLAtt);
}

/* --Methode-- */
PIMarker   PIGraphicX::GetMarker()
{
return (mMrk);
}

/* --Methode-- */
int        PIGraphicX::GetMarkerSize()
{
return (mMrkSz);
}

/* --Methode-- */
int        PIGraphicX::GetFontHeight(int& asc, int& desc)   
{
char a[2];
XCharStruct  ovr;
int hd, fa, fd;
XTextExtents(mFSt, a, 0, &hd, &fa, &fd, &ovr);
asc = fa; desc = fd; 
return(fa+fd);
}

/* --Methode-- */
PIGrCoord PIGraphicX::CalcStringWidth(char const* s)
{
return(XTextWidth(mFSt, s, strlen(s)));
}

/* --Methode-- */
void PIGraphicX::SaveGraphicAtt()
{  
// Pour optimier l'implementation de PIBaseWdgGen
sFCol = mFCol;    sBCol = mBCol;
sGOm = mGOm;
sFAtt = mFAtt;   sFSize = mFSize;
sMrk = mMrk;   sMrkSz = mMrkSz;
sFCfMap = mFCfMap; sBCfMap = mBCfMap; 
return;
}

/* --Methode-- */
void PIGraphicX::RestoreGraphicAtt()
{
  if (sFCol != PI_ColorFromMap) SelForeground(sFCol);
  else SelectFCol(sFCfMap);
  if (sBCol != PI_ColorFromMap) SelBackground(sBCol);
  else SelectBCol(sBCfMap);
  SelGOMode(sGOm);
  SelFontSzPt(sFSize, sFAtt);
  SelLine(sLAtt);
  SelMarker(sMrkSz, sMrk);
  return;
}


/* --Methode-- */
unsigned long PIGraphicX::GetPixelValueforColor(PIColors col)
{
if ( (col < 0) || (col >= NMAXCOL))  return(0);
return(colpix[col]); 
}


static bool fggrcx = false ;

// Le bazar pour recuperer des resources de .Xdefault et autres 
typedef struct 
  {
  String fntFam;
  } myAppData;
static myAppData  apd;

static XtResource resources[] = {
  { "fontFamilyName", "FontFamilyName", XtRString, sizeof(String),
    /*XtOffset(apdp, fntFam)*/ 0, XtRString, "*-courier" }
};
 
static char * fnbi_b[4] = { "medium-r-normal", "bold-r-normal", 
                          "medium-o-normal", "medium-i-normal" };

static XFontStruct * defnt = NULL;
static char * fnbi[3];


/* --Methode-- */
void PIGraphicX::GlInit()
{
char buff[256];
int i,j,count;
char **list;

if (fggrcx)  return;
fggrcx = true;

Display *mdsp;
int scr;
XColor exact,mycol;
Colormap  cmap;

mdsp = PIXDisplay();
scr = XDefaultScreen(mdsp);

XtGetApplicationResources(PIXtTopWdg(), &apd, resources, 
                          XtNumber(resources), NULL, 0);
sprintf(buff,"-%s-*-*-*-*-*-*-*-*-*-*-*-*", apd.fntFam);
list = XListFonts(mdsp, buff, 15, &count);
XFreeFontNames(list);
if (count < 5)
  { 
  printf("PIGraphicX::Init %d fonts found for %s , switching to courier\n",
         count, apd.fntFam);
  apd.fntFam = "*-courier";
  }
sprintf(buff,"-%s-%s-*-*-*-*-*-*-*-*-*", apd.fntFam, fnbi_b[0]);
list = XListFonts(mdsp, buff, 10, &count);
XFreeFontNames(list);
if (count < 2) fnbi[0] = "*-*-*";
else  fnbi[0] = fnbi_b[0];
sprintf(buff,"-%s-%s-*-*-*-*-*-*-*-*-*", apd.fntFam, fnbi_b[1]);
list = XListFonts(mdsp, buff, 10, &count);
XFreeFontNames(list);
if (count < 2) fnbi[1] = "*-*-*";
else  fnbi[1] = fnbi_b[1];
sprintf(buff,"-%s-%s-*-*-*-*-*-*-*-*-*", apd.fntFam, fnbi_b[2]);
list = XListFonts(mdsp, buff, 10, &count);
XFreeFontNames(list);
fnbi[2] = fnbi_b[2];
if (count < 2) 
  {
  sprintf(buff,"-%s-%s-*-*-*-*-*-*-*-*-*", apd.fntFam, fnbi_b[3]);
  list = XListFonts(mdsp, buff, 10, &count);
  XFreeFontNames(list);
  fnbi[2] = fnbi_b[3];
  }
if (count < 2) fnbi[2] = "*-*-*";

sprintf(buff,"-*-fixed-*-*-*-*-14-*-*-*-*-*-*-*");
list = XListFonts(mdsp, buff, 10, &count);
XFreeFontNames(list);
if (count < 1) 
  {  
  sprintf(buff,"fixed");
  list = XListFonts(mdsp, buff, 10, &count);
  XFreeFontNames(list);
  }
if (count < 1) 
  {  
  strcpy(buff,"");
  list = XListFonts(mdsp, buff, 10, &count);
  XFreeFontNames(list);
  printf("PIGraphicX::Init/ Erreur, no font found ... \n");
  defnt = NULL;
  }
else defnt = XLoadQueryFont(mdsp, buff);

for (i=0; i<NMAXFONTSZ; i++)
  for (j=0; j<3; j++)  fntst[i][j] = NULL;

// Choix des trois tailles de fontes standard en fonction de 
// la taille de fonte par defaut des composantes standard
int szx, szy, szf;
PIXtAppCtx(szx, szy, szf);
int kkk, kkj, kksel, kkdsz = 9999;  
kksel = NMAXFONTSZ/2;
for(kkk=NMAXFONTSZ-1; kkk>=0; kkk--) {
  kkj = szf - fntsz[kkk];   if (kkj < 0)  kkj = -kkj;
  if (kkj < kkdsz)  {  kksel = kkk;  kkdsz = kkj; }
  }
if (kksel == NMAXFONTSZ-1)  kksel = NMAXFONTSZ-2;
NormalFontIndex = kksel;
SmallFontIndex = (kksel > 1) ? kksel-2 : 0 ;
BigFontIndex =  NMAXFONTSZ-2 ;
if (BigFontIndex < NormalFontIndex)  BigFontIndex = NormalFontIndex;
HugeFontIndex = NMAXFONTSZ-1;

//printf("PIGraphicX::Init()-DBG- FontIndex= %d %d %d (%d) \n", 
//       SmallFontIndex, NormalFontIndex, BigFontIndex, szf);

/*  Les couleurs  */
cmap = XDefaultColormap (mdsp, scr);

for(i=0; i<NMAXCOL; i++)  colpix[i] = XWhitePixel(mdsp, scr);
colpix[PI_Black] = XBlackPixel(mdsp, scr);
colpix[PI_White] = XWhitePixel(mdsp, scr);
if ( XAllocNamedColor (mdsp, cmap, "LightGray", &mycol, &exact) )
  colpix[PI_Grey] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "red", &mycol, &exact) )
  colpix[PI_Red] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "blue", &mycol, &exact) )
  colpix[PI_Blue] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "green", &mycol, &exact) )
  colpix[PI_Green] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "yellow", &mycol, &exact) )
  colpix[PI_Yellow] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "magenta", &mycol, &exact) )
  colpix[PI_Magenta] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "cyan", &mycol, &exact) )
  colpix[PI_Cyan] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "turquoise", &mycol, &exact) )
  colpix[PI_Turquoise] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "NavyBlue", &mycol, &exact) )
  colpix[PI_NavyBlue] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "orange", &mycol, &exact) )
  colpix[PI_Orange] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "sienna", &mycol, &exact) )
  colpix[PI_SiennaRed] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "purple", &mycol, &exact) )
  colpix[PI_Purple] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "LimeGreen", &mycol, &exact) )
  colpix[PI_LimeGreen] = mycol.pixel;
if ( XAllocNamedColor (mdsp, cmap, "gold", &mycol, &exact) )
  colpix[PI_Gold] = mycol.pixel;


/*  le GC pour DrawPixmap  */
XGCValues  xgv;
xgv.function = GXcopy;
xgv.plane_mask = ~0;
dpxgc = XCreateGC(mdsp, DefaultRootWindow(mdsp), GCFunction | GCPlaneMask, &xgv);

return;
}


/* --Methode-- */
void PIGraphicX::SelectFont(int isz, int jat)
{

if (!fntst[isz][jat])  // Il faut charger la fonte
  {
  char buff[256];
  int count,k;
  Display * mdsp = PIXDisplay();
  char **list;

  for (k=0; k<5; k++)    // Recherche de la fonte pour tailles croissantes
    {
    sprintf(buff,"-%s-%s-*-%d-*-*-*-*-*-*-*", apd.fntFam, fnbi[jat], fntsz[isz]+k);
    list = XListFonts(mdsp, buff, 10, &count);
    XFreeFontNames(list);
    if (count > 0)  break;
    }
  if (count > 0) 
    fntst[isz][jat] = XLoadQueryFont(mdsp, buff);
  else
    { printf("PIGraphicX::SelectFont/ Pb font %s - Using default \n", buff);    
    fntst[isz][jat] = defnt; }
  }

mFAtt = fntatt[jat];
mFSize = fntsz[isz];
mFSt = fntst[isz][jat];
XSetFont(mDisp, DefGC(), fntst[isz][jat]->fid);
return;
}


