Blame graph.c

452870
452870
#include "app.h"
452870
452870
452870
452870
int graphInit(Graph *g, App *app) {
452870
  LOGDBG("graph: init");
452870
  
dbe1a1
  CLEARFROM(g, app);
452870
  g->app = app;
452870
  
dbe1a1
  enum {
dbe1a1
    F = 65535u,   // full
dbe1a1
    H = 32768u,   // half
dbe1a1
    Q = 16384u }; // quart
dbe1a1
  static const XRenderColor renderColors[GC_COUNT] = {
dbe1a1
    { 0, 0, Q, F },   // window
dbe1a1
    { 0, 0, H, F },   // inactive button
dbe1a1
    { 0, 0, F, F },   // active button
dbe1a1
    { H, 0, F, F },   // active button 2
dbe1a1
    { F, F, 0, F },   // inactive text
dbe1a1
    { F, F, 0, F },   // active text
dbe1a1
    { F, F, 0, F } }; // active text 2
dbe1a1
dbe1a1
  static const char *fonts[] = FONTS;
dbe1a1
  static const int sizes[FONT_MAX_SIZES] = FONT_SIZES;
452870
  
dbe1a1
  LOGDBG("graph: init: create XftDraw");
dbe1a1
  g->draw = XftDrawCreate(
dbe1a1
    g->app->dpy,
dbe1a1
    g->app->win,
dbe1a1
    DefaultVisual(g->app->dpy, g->app->screen),
dbe1a1
    DefaultColormap(g->app->dpy, g->app->screen) );
dbe1a1
  if (!g->draw)
dbe1a1
    return LOGERR("graph: init: cannot create XftDraw");
dbe1a1
dbe1a1
  LOGDBG("graph: init: open fonts");
dbe1a1
  char buf[1024] = {};
dbe1a1
  for(int i = 0; i < FONT_MAX_SIZES; ++i) {
dbe1a1
    if (!sizes[i]) break;
dbe1a1
    for(int j = 0; j < COUNTOF(fonts); ++j) {
dbe1a1
      snprintf(buf, sizeof(buf), "%s:size=%d", fonts[j], sizes[i]);
dbe1a1
      LOGDBG("graph: init: try open font [%s]", buf);
dbe1a1
      g->fonts[g->fontsCnt] = XftFontOpenName(g->app->dpy, g->app->screen, buf);
dbe1a1
      if (g->fonts[g->fontsCnt]) {
dbe1a1
        ++g->fontsCnt;
dbe1a1
        break;
dbe1a1
      } else {
dbe1a1
        LOGDBG("graph: init: cannot open font [%s]", buf);
061fcf
      }
061fcf
    }
061fcf
  }
061fcf
  
dbe1a1
  if (!g->fontsCnt) {
dbe1a1
    LOGERR("graph: init: cannot open any font");
dbe1a1
    XftDrawDestroy(g->draw);
dbe1a1
    CLEARFROM(g, app);
061fcf
    return 0;
061fcf
  }
dbe1a1
 
dbe1a1
  LOGDBG("graph: init: allocate colors");
dbe1a1
  for(int i = 0; i < GC_COUNT; ++i) {
dbe1a1
    XftColorAllocValue(
dbe1a1
      g->app->dpy,
dbe1a1
      DefaultVisual(g->app->dpy, g->app->screen),
dbe1a1
      DefaultColormap(g->app->dpy, g->app->screen),
dbe1a1
      &renderColors[i],
dbe1a1
      &g->colors[i] );
452870
  }
452870
  
452870
  return 1;
452870
}
452870
452870
452870
void graphDeinit(Graph *g) {
452870
  LOGDBG("graph: deinit");
dbe1a1
  for(int i = 0; i < GC_COUNT; ++i)
dbe1a1
    XftColorFree(
dbe1a1
      g->app->dpy,
dbe1a1
      DefaultVisual(g->app->dpy, g->app->screen),
dbe1a1
      DefaultColormap(g->app->dpy, g->app->screen),
dbe1a1
      &g->colors[i] );
dbe1a1
  for(int i = 0; i < g->fontsCnt; ++i)
dbe1a1
    XftFontClose(g->app->dpy, g->fonts[i]);
dbe1a1
  XftDrawDestroy(g->draw);
452870
}
452870
452870
452870
void graphResize(Graph *g)
452870
  { }
452870
452870
452870
void graphDrawBackgound(Graph *g, int x, int y, int w, int h) {
dbe1a1
  XftDrawRect(g->draw, &g->colors[GC_WINDOW], x, y, w, h);
452870
}
452870
452870
452870
void graphDrawButton(Graph *g, int x, int y, int w, int h, int active) {
dbe1a1
  GraphStyle s = active == 1 ? GC_BUTTON_ACTIVE
dbe1a1
               : active == 2 ? GC_BUTTON_ACTIVE2
dbe1a1
               :               GC_BUTTON_INACTIVE;
dbe1a1
  XftDrawRect(g->draw, &g->colors[s], x, y, w, h);
452870
}
452870
452870
452870
843e7a
void textLayoutInit(TextLayout *tl, Graph *g, const char *text) {
dbe1a1
  CLEARFROM(tl, g);
452870
  tl->g = g;
dbe1a1
  tl->len = text ? strlen(text) : 0;
dbe1a1
  tl->text = text;
061fcf
  if (!tl->len)
061fcf
    return;
061fcf
  
dbe1a1
  for(int i = 0; i < tl->g->fontsCnt; ++i) {
dbe1a1
    XGlyphInfo e = {};
dbe1a1
    XftTextExtentsUtf8(g->app->dpy, g->fonts[i], (const FcChar8*)tl->text, tl->len, &e);
dbe1a1
    int w = e.width;
dbe1a1
    int h = tl->g->fonts[i]->ascent;
dbe1a1
    int minw = h + h/3;
dbe1a1
    tl->sizes[i].x = -e.x - w/2;
dbe1a1
    tl->sizes[i].y = h/2;
dbe1a1
    tl->sizes[i].w = w < minw ? minw : w;
dbe1a1
    tl->sizes[i].h = h;
061fcf
  }
452870
}
452870
061fcf
452870
void textLayoutDeinit(TextLayout *tl)
dbe1a1
  { CLEARFROM(tl, g); }
452870
061fcf
dbe1a1
void textLayoutDraw(TextLayout *tl, int x, int y, int w, int h, int active) {
061fcf
  if (!tl->len) return;
dbe1a1
  GraphStyle s = active == 1 ? GC_TEXT_ACTIVE
dbe1a1
               : active == 2 ? GC_TEXT_ACTIVE2
dbe1a1
               :               GC_TEXT_INACTIVE;
dbe1a1
  
dbe1a1
  // find font size
dbe1a1
  int i;
dbe1a1
  for(i = tl->g->fontsCnt - 1; i > 0; --i)
dbe1a1
    if (tl->sizes[i].w <= w && tl->sizes[i].h <= h) break;
dbe1a1
  
dbe1a1
  XftDrawStringUtf8(
dbe1a1
    tl->g->draw,
dbe1a1
    &tl->g->colors[s],
dbe1a1
    tl->g->fonts[i],
dbe1a1
    x + tl->sizes[i].x,
dbe1a1
    y + tl->sizes[i].y,
dbe1a1
    (const FcChar8*)tl->text,
dbe1a1
    tl->len );
061fcf
}
061fcf