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 {
37122c
    F = 0xffffu,   // full
37122c
    B = 0x9000u,   // bright
37122c
    D = 0x7000u,   // dark
37122c
    Q = 0x4000u }; // quart
dbe1a1
  static const XRenderColor renderColors[GC_COUNT] = {
dbe1a1
    { 0, 0, Q, F },   // window
37122c
    { 0, 0, D, F },   // inactive button
37122c
    { 0, 0, B, F },   // highlighted button
dbe1a1
    { 0, 0, F, F },   // active button
37122c
    { B, 0, F, F },   // active button 2
dbe1a1
    { F, F, 0, F },   // inactive text
37122c
    { F, F, 0, F },   // highlighted 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
37122c
void graphDrawButton(Graph *g, int x, int y, int w, int h, int active, int highlight) {
dbe1a1
  GraphStyle s = active == 1 ? GC_BUTTON_ACTIVE
dbe1a1
               : active == 2 ? GC_BUTTON_ACTIVE2
37122c
               : highlight   ? GC_BUTTON_HIGHTLIGHT
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;
8864eb
  
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);
8864eb
    
8864eb
    int asc  = tl->g->fonts[i]->ascent;
8864eb
    int desc = tl->g->fonts[i]->descent;
dbe1a1
    int w = e.width;
8864eb
    int minw = asc + asc/3;
db2d04
    int h = asc + desc; // proper value is: asc + 2*desc
8864eb
    
8864eb
    tl->sizes[i].x = e.x - w/2;
8864eb
    tl->sizes[i].y = asc/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
37122c
void textLayoutDraw(TextLayout *tl, int x, int y, int w, int h, int active, int highlight) {
061fcf
  if (!tl->len) return;
dbe1a1
  GraphStyle s = active == 1 ? GC_TEXT_ACTIVE
dbe1a1
               : active == 2 ? GC_TEXT_ACTIVE2
37122c
               : highlight   ? GC_TEXT_HIGHTLIGHT
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