diff --git a/components/ctx/ctx.h b/components/ctx/ctx.h
index adcf3433f75f6fe7dfb2624098f3e0db540bf202..156bb5c2f86191205ecccf7f40701ec61598d9b3 100644
--- a/components/ctx/ctx.h
+++ b/components/ctx/ctx.h
@@ -115,10 +115,9 @@ enum _CtxPixelFormat
   CTX_FORMAT_CMYKA8, // 15 
   CTX_FORMAT_GRAY2,  // 16 // matching flags
   CTX_FORMAT_YUV420, // 17
-  CTX_FORMAT_BGR8,   // 
-  CTX_FORMAT_RGBA8_SEPARATE_ALPHA, //
   CTX_FORMAT_GRAY4 =32, // to match flags
   CTX_FORMAT_BGRA8Z,    // 
+  CTX_FORMAT_RGBA8_SEPARATE_ALPHA, //
 };
 typedef enum   _CtxPixelFormat CtxPixelFormat;
 
@@ -3972,7 +3971,6 @@ int       ctx_get_render_threads   (Ctx *ctx);
 #define CTX_ENABLE_RGB8                 1
 #define CTX_ENABLE_RGBA8                1
 #define CTX_ENABLE_BGRA8                1
-#define CTX_ENABLE_BGR8                 1
 #define CTX_ENABLE_RGB332               1
 #define CTX_ENABLE_RGB565               1
 #define CTX_ENABLE_RGB565_BYTESWAPPED   1
@@ -12337,8 +12335,8 @@ struct _CtxGradientStop
 
 enum _CtxSourceType
 {
+  CTX_SOURCE_NONE = 0,
   CTX_SOURCE_COLOR,
-  CTX_SOURCE_NONE = 1,
   CTX_SOURCE_TEXTURE,
   CTX_SOURCE_LINEAR_GRADIENT,
   CTX_SOURCE_RADIAL_GRADIENT,
@@ -13527,31 +13525,19 @@ struct _EvSource
   /* if this returns non-0 select can be used for non-blocking.. */
 };
 
-typedef struct CtxCbJob
-{
-  int      x0;
-  int      y0;
-  int      width;
-  int      height;
-  uint32_t bitmask;
-  int      renderer;      // 0 - no render
-} CtxCbJob;
-
-#define CTX_CB_MAX_JOBS 8
-#define CTX_JOB_PENDING (-1)
-
-
 typedef struct CtxCbBackend
 {
   CtxBackend     backend;
 
   Ctx           *drawlist_copy;
-  Ctx           *rctx; 
+  Ctx           *rctx; // only used by FULL_FB
   int            rendering;
   int            re_render;
   int            frame_no;
 
   CtxCbConfig    config;
+  //int            flags;
+  //int            memory_budget;
   int            min_col; // hasher cols and rows
   int            min_row; // hasher cols and rows
   int            max_col; // hasher cols and rows
@@ -13560,15 +13546,19 @@ typedef struct CtxCbBackend
   int            allocated_fb;
   Ctx           *ctx;
 
-  int n_jobs;
-  CtxCbJob  jobs[CTX_CB_MAX_JOBS];
-
+#if 0
+  void (*set_pixels) (Ctx *ctx, void *user_data, 
+                      int x, int y, int w, int h, void *buf);
+  void   *set_pixels_user_data;
+  int  (*update_fb) (Ctx *ctx, void *user_data);
+  void   *update_fb_user_data;
+#endif
    EvSource    *evsource[4];
    int          evsource_count;
 
   uint32_t hashes[CTX_HASH_ROWS * CTX_HASH_COLS];
 
-  CtxHasher     hasher;
+  CtxHasher     rasterizer;
   uint8_t res[CTX_HASH_ROWS * CTX_HASH_COLS]; // when non-0 we have non-full res rendered
                                            
   mtx_t mtx;
@@ -14190,8 +14180,7 @@ _ctx_fragment_gradient_1d_RGBA8 (CtxRasterizer *rasterizer, float x, float y, ui
 {
   float v = x;
   uint8_t global_alpha_u8 = rasterizer->state->gstate.global_alpha_u8;
-  CtxState *state = rasterizer->state;
-  CtxGradient *g = &state->gradient;
+  CtxGradient *g = &rasterizer->state->gradient;
   v *= (v>0);
   if (v > 1) { v = 1; }
 
@@ -14226,8 +14215,8 @@ _ctx_fragment_gradient_1d_RGBA8 (CtxRasterizer *rasterizer, float x, float y, ui
     {
       uint8_t stop_rgba[4];
       uint8_t next_rgba[4];
-      ctx_color_get_rgba8 (state, & (stop->color), stop_rgba);
-      ctx_color_get_rgba8 (state, & (next_stop->color), next_rgba);
+      ctx_color_get_rgba8 (rasterizer->state, & (stop->color), stop_rgba);
+      ctx_color_get_rgba8 (rasterizer->state, & (next_stop->color), next_rgba);
       int dx = (int)((v - stop->pos) * 255 / (next_stop->pos - stop->pos));
       ((uint32_t*)rgba)[0] = ctx_lerp_RGBA8 (((uint32_t*)stop_rgba)[0],
                                              ((uint32_t*)next_rgba)[0], dx);
@@ -14245,7 +14234,7 @@ _ctx_fragment_gradient_1d_RGBA8 (CtxRasterizer *rasterizer, float x, float y, ui
     {
       color = & (g->stops[g->n_stops-1].color);
     }
-  ctx_color_get_rgba8 (state, color, rgba);
+  ctx_color_get_rgba8 (rasterizer->state, color, rgba);
   if (rasterizer->swap_red_green)
   {
     uint8_t tmp = rgba[0];
@@ -14330,8 +14319,7 @@ CTX_INLINE static void
 ctx_fragment_gradient_1d_GRAYA8 (CtxRasterizer *rasterizer, float x, float y, uint8_t *rgba)
 {
   float v = x;
-  CtxState *state = rasterizer->state;
-  CtxGradient *g = &state->gradient;
+  CtxGradient *g = &rasterizer->state->gradient;
   if (v < 0) { v = 0; }
   if (v > 1) { v = 1; }
   if (g->n_stops == 0)
@@ -14365,8 +14353,8 @@ ctx_fragment_gradient_1d_GRAYA8 (CtxRasterizer *rasterizer, float x, float y, ui
     {
       uint8_t stop_rgba[4];
       uint8_t next_rgba[4];
-      ctx_color_get_graya_u8 (state, & (stop->color), stop_rgba);
-      ctx_color_get_graya_u8 (state, & (next_stop->color), next_rgba);
+      ctx_color_get_graya_u8 (rasterizer->state, & (stop->color), stop_rgba);
+      ctx_color_get_graya_u8 (rasterizer->state, & (next_stop->color), next_rgba);
       int dx = (int)((v - stop->pos) * 255 / (next_stop->pos - stop->pos));
       for (int c = 0; c < 2; c++)
         { rgba[c] = ctx_lerp_u8 (stop_rgba[c], next_rgba[c], dx); }
@@ -14376,15 +14364,14 @@ ctx_fragment_gradient_1d_GRAYA8 (CtxRasterizer *rasterizer, float x, float y, ui
     {
       color = & (g->stops[g->n_stops-1].color);
     }
-  ctx_color_get_graya_u8 (state, color, rgba);
+  ctx_color_get_graya_u8 (rasterizer->state, color, rgba);
 }
 
 CTX_INLINE static void
 ctx_fragment_gradient_1d_RGBAF (CtxRasterizer *rasterizer, float v, float y, float *rgba)
 {
   float global_alpha = rasterizer->state->gstate.global_alpha_f;
-  CtxState *state = rasterizer->state;
-  CtxGradient *g = &state->gradient;
+  CtxGradient *g = &rasterizer->state->gradient;
   v *= (v>0);
   if (v > 1) { v = 1; }
   if (g->n_stops == 0)
@@ -14418,8 +14405,8 @@ ctx_fragment_gradient_1d_RGBAF (CtxRasterizer *rasterizer, float v, float y, flo
     {
       float stop_rgba[4];
       float next_rgba[4];
-      ctx_color_get_rgba (state, & (stop->color), stop_rgba);
-      ctx_color_get_rgba (state, & (next_stop->color), next_rgba);
+      ctx_color_get_rgba (rasterizer->state, & (stop->color), stop_rgba);
+      ctx_color_get_rgba (rasterizer->state, & (next_stop->color), next_rgba);
       float dx = (v - stop->pos) / (next_stop->pos - stop->pos);
       for (int c = 0; c < 4; c++)
         { rgba[c] = ctx_lerpf (stop_rgba[c], next_rgba[c], dx); }
@@ -14433,7 +14420,7 @@ ctx_fragment_gradient_1d_RGBAF (CtxRasterizer *rasterizer, float v, float y, flo
     {
       color = & (g->stops[g->n_stops-1].color);
     }
-  ctx_color_get_rgba (state, color, rgba);
+  ctx_color_get_rgba (rasterizer->state, color, rgba);
   rgba[3] *= global_alpha;
   for (int c = 0; c < 3; c++)
     rgba[c] *= rgba[3];
@@ -15987,19 +15974,18 @@ ctx_fragment_image_rgba8_RGBA8_bi_affine_with_alpha (CtxRasterizer *rasterizer,
                                           void *out, int scount,
                                           float dx, float dy, float dz)
 {
-  CtxState *state = rasterizer->state;
-  uint8_t global_alpha_u8 = state->gstate.global_alpha_u8;
+  uint8_t global_alpha_u8 = rasterizer->state->gstate.global_alpha_u8;
         x-=0.5f;
         y-=0.5f;
   uint32_t count = scount;
   uint8_t *rgba = (uint8_t *) out;
-  CtxSource *g = &state->gstate.source_fill;
+  CtxSource *g = &rasterizer->state->gstate.source_fill;
 #if CTX_ENABLE_CM
   CtxBuffer *buffer = g->texture.buffer->color_managed?g->texture.buffer->color_managed:g->texture.buffer;
 #else
   CtxBuffer *buffer = g->texture.buffer;
 #endif
-  CtxExtend extend = state->gstate.extend;
+  CtxExtend extend = rasterizer->state->gstate.extend;
   const int bwidth = buffer->width;
   const int bheight = buffer->height;
   unsigned int i = 0;
@@ -19866,97 +19852,20 @@ ctx_composite_CMYK8 (CTX_COMPOSITE_ARGUMENTS)
 }
 #endif
 
-
-#if CTX_ENABLE_BGR8
-
-inline static void
-ctx_BGR8_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *rgba, int count)
-{
-  const uint8_t *pixel = (const uint8_t *) buf;
-  uint32_t *dst = (uint32_t*)rgba;
-  while (count--)
-    {
-      *dst = pixel[1] +  (pixel[0] << 8) + (pixel[2] << 16) + (((unsigned)0xff) << 24);
-      pixel+=3;
-      dst++;
-    }
-}
-
-inline static void
-ctx_RGBA8_to_BGR8 (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count)
-{
-  uint8_t *pixel = (uint8_t *) buf;
-  const uint32_t *src = (const uint32_t*)rgba;
-  while (count--)
-    {
-      uint32_t s = *src;
-      uint8_t r = s & 0xff;
-      uint8_t g = (s>>8) & 0xff;
-      uint8_t b = (s>>16) & 0xff;
-      pixel[0] = g;
-      pixel[1] = r;
-      pixel[2] = b;
-      pixel+=3;
-      src++;
-    }
-}
-
-static void
-ctx_composite_BGR8 (CTX_COMPOSITE_ARGUMENTS)
-{
-#if 1 // code is OK - but less code is better
-  if (rasterizer->comp_op == ctx_RGBA8_source_over_normal_color)
-  {
-    uint8_t *src = ((uint8_t*)rasterizer->color);
-    uint8_t *dst_u8 = (uint8_t*)dst;
-    while (count--)
-    {
-        uint32_t cov = ((*coverage++) * src[3] + 255) >> 8;
-        dst_u8[0] = ctx_lerp_u8 (dst_u8[0], src[1], cov);
-        dst_u8[1] = ctx_lerp_u8 (dst_u8[1], src[0], cov);
-        dst_u8[2] = ctx_lerp_u8 (dst_u8[2], src[2], cov);
-        dst_u8+=3;
-    }
-    return;
-  }
-#endif
-#if 1
-  if (rasterizer->comp_op == ctx_RGBA8_source_copy_normal_color)
-  {
-    uint8_t *src = ((uint8_t*)rasterizer->color);
-    uint8_t *dst_u8 = (uint8_t*)dst;
-    while (count--)
-    {
-        uint32_t cov = *coverage++;
-        dst_u8[0] = ctx_lerp_u8 (dst_u8[0], src[1], cov);
-        dst_u8[1] = ctx_lerp_u8 (dst_u8[1], src[0], cov);
-        dst_u8[2] = ctx_lerp_u8 (dst_u8[2], src[2], cov);
-        dst_u8+=3;
-    }
-    return;
-  }
-#endif
-
-  uint8_t pixels[count * 4];
-  ctx_BGR8_to_RGBA8 (rasterizer, x0, dst, &pixels[0], count);
-  rasterizer->comp_op (count, &pixels[0], rasterizer->color, coverage, rasterizer, x0);
-  ctx_RGBA8_to_BGR8 (rasterizer, x0, &pixels[0], dst, count);
-}
-
-#endif
-
 #if CTX_ENABLE_RGB8
 
 inline static void
 ctx_RGB8_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *rgba, int count)
 {
   const uint8_t *pixel = (const uint8_t *) buf;
-  uint32_t *dst = (uint32_t*)rgba;
   while (count--)
     {
-      *dst = pixel[0] +  (pixel[1] << 8) + (pixel[2] << 16) + (((unsigned)0xff) << 24);
+      rgba[0] = pixel[0];
+      rgba[1] = pixel[1];
+      rgba[2] = pixel[2];
+      rgba[3] = 255;
       pixel+=3;
-      dst++;
+      rgba +=4;
     }
 }
 
@@ -19964,62 +19873,14 @@ inline static void
 ctx_RGBA8_to_RGB8 (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count)
 {
   uint8_t *pixel = (uint8_t *) buf;
-  const uint32_t *src = (const uint32_t*)rgba;
   while (count--)
     {
-      uint32_t s = *src;
-      uint8_t r = s & 0xff;
-      uint8_t g = (s>>8) & 0xff;
-      uint8_t b = (s>>16) & 0xff;
-      pixel[0] = r;
-      pixel[1] = g;
-      pixel[2] = b;
+      pixel[0] = rgba[0];
+      pixel[1] = rgba[1];
+      pixel[2] = rgba[2];
       pixel+=3;
-      src++;
-    }
-}
-
-static void
-ctx_composite_RGB8 (CTX_COMPOSITE_ARGUMENTS)
-{
-#if 1 // code is OK - but less code is better
-  if (rasterizer->comp_op == ctx_RGBA8_source_over_normal_color)
-  {
-    uint8_t *src = ((uint8_t*)rasterizer->color);
-    uint8_t *dst_u8 = (uint8_t*)dst;
-    while (count--)
-    {
-        uint32_t cov = ((*coverage++) * src[3] + 255) >> 8;
-        dst_u8[0] = ctx_lerp_u8 (dst_u8[0], src[0], cov);
-        dst_u8[1] = ctx_lerp_u8 (dst_u8[1], src[1], cov);
-        dst_u8[2] = ctx_lerp_u8 (dst_u8[2], src[2], cov);
-        dst_u8+=3;
-    }
-    return;
-  }
-#endif
-#if 1
-  if (rasterizer->comp_op == ctx_RGBA8_source_copy_normal_color)
-  {
-    uint8_t *src = ((uint8_t*)rasterizer->color);
-    uint8_t *dst_u8 = (uint8_t*)dst;
-    while (count--)
-    {
-        //uint32_t cov = ((*coverage++) * src[3] + 255) >> 8;
-        uint32_t cov = *coverage++;
-        dst_u8[0] = ctx_lerp_u8 (dst_u8[0], src[0], cov);
-        dst_u8[1] = ctx_lerp_u8 (dst_u8[1], src[1], cov);
-        dst_u8[2] = ctx_lerp_u8 (dst_u8[2], src[2], cov);
-        dst_u8+=3;
+      rgba +=4;
     }
-    return;
-  }
-#endif
-
-  uint8_t pixels[count * 4];
-  ctx_RGB8_to_RGBA8 (rasterizer, x0, dst, &pixels[0], count);
-  rasterizer->comp_op (count, &pixels[0], rasterizer->color, coverage, rasterizer, x0);
-  ctx_RGBA8_to_RGB8 (rasterizer, x0, &pixels[0], dst, count);
 }
 
 #endif
@@ -20089,11 +19950,11 @@ ctx_GRAY1_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *
   while (count--)
     {
       int bitno = x&7;
-      uint8_t pval = *pixel;
+
       if ((bitno == 0) & (count >=7))
       {
         /* special case some bit patterns when decoding */
-        if (pval == 0)
+        if (*pixel == 0)
         {
           *dst++ = 0xff000000;
           *dst++ = 0xff000000;
@@ -20106,7 +19967,7 @@ ctx_GRAY1_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *
           x+=8; count-=7; pixel++;
           continue;
         }
-        else if (pval == 0xff)
+        else if (*pixel == 0xff)
         {
           *dst++ = 0xffffffff;
           *dst++ = 0xffffffff;
@@ -20119,7 +19980,7 @@ ctx_GRAY1_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *
           x+=8; count-=7; pixel++;
           continue;
         }
-        else if (pval == 0x0f)
+        else if (*pixel == 0x0f)
         {
           *dst++ = 0xff000000;
           *dst++ = 0xff000000;
@@ -20132,7 +19993,7 @@ ctx_GRAY1_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *
           x+=8; count-=7; pixel++;
           continue;
         }
-        else if (pval == 0xfc)
+        else if (*pixel == 0xfc)
         {
           *dst++ = 0xffffffff;
           *dst++ = 0xffffffff;
@@ -20145,7 +20006,7 @@ ctx_GRAY1_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *
           x+=8; count-=7; pixel++;
           continue;
         }
-        else if (pval == 0x3f)
+        else if (*pixel == 0x3f)
         {
           *dst++ = 0xff000000;
           *dst++ = 0xff000000;
@@ -20159,7 +20020,7 @@ ctx_GRAY1_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *
           continue;
         }
       }
-      *dst++=0xff000000 + 0x00ffffff * ((pval & (1<< bitno ) )!=0);
+      *dst++=0xff000000 + 0x00ffffff * ((*pixel & (1<< bitno ) )!=0);
       pixel += (bitno ==7);
       x++;
     }
@@ -20313,10 +20174,9 @@ inline static void
 ctx_RGBA8_to_GRAY2 (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count)
 {
   uint8_t *pixel = (uint8_t *) buf;
-  CtxState *state = rasterizer->state;
   while (count--)
     {
-      int val = ctx_u8_color_rgb_to_gray (state, rgba);
+      int val = ctx_u8_color_rgb_to_gray (rasterizer->state, rgba);
       val >>= 6;
       *pixel = (*pixel & (~ (3 << ((x&3) <<1) ) ))
                       | ( (val << ((x&3) <<1) ) );
@@ -20389,10 +20249,9 @@ inline static void
 ctx_RGBA8_to_GRAY4 (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count)
 {
   uint8_t *pixel = (uint8_t *) buf;
-  CtxState *state = rasterizer->state;
   while (count--)
     {
-      int val = ctx_u8_color_rgb_to_gray (state, rgba);
+      int val = ctx_u8_color_rgb_to_gray (rasterizer->state, rgba);
       val >>= 4;
       *pixel = *pixel & (~ (15 << ( (x&1) <<2) ) );
       *pixel = *pixel | ( (val << ( (x&1) <<2) ) );
@@ -20452,10 +20311,9 @@ inline static void
 ctx_RGBA8_to_GRAY8 (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count)
 {
   uint8_t *pixel = (uint8_t *) buf;
-  CtxState *state = rasterizer->state;
   for (int i = 0; i < count; i ++)
     {
-      pixel[i] = ctx_u8_color_rgb_to_gray (state, rgba + i * 4);
+      pixel[i] = ctx_u8_color_rgb_to_gray (rasterizer->state, rgba + i * 4);
     }
 }
 #endif
@@ -20482,10 +20340,9 @@ inline static void
 ctx_RGBA8_to_GRAYA8 (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count)
 {
   uint8_t *pixel = (uint8_t *) buf;
-  CtxState *state = rasterizer->state;
   while (count--)
     {
-      pixel[0] = ctx_u8_color_rgb_to_gray (state, rgba);
+      pixel[0] = ctx_u8_color_rgb_to_gray (rasterizer->state, rgba);
       pixel[1] = rgba[3];
       pixel+=2;
       rgba +=4;
@@ -20895,7 +20752,7 @@ ctx_RGBA8_to_RGB332 (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void
 static void
 ctx_composite_RGB332 (CTX_COMPOSITE_ARGUMENTS)
 {
-#if 0 // it is slower
+#if 1
   if (CTX_LIKELY(rasterizer->comp_op == ctx_RGBA8_source_over_normal_color))
   {
     uint32_t si_ga = ((uint32_t*)rasterizer->color)[1];
@@ -21065,6 +20922,47 @@ ctx_RGBA8_source_copy_normal_color (CTX_COMPOSITE_ARGUMENTS);
 static void
 ctx_composite_RGB565 (CTX_COMPOSITE_ARGUMENTS)
 {
+#if 0 // code is OK - but less code is better
+  if (rasterizer->comp_op == ctx_RGBA8_source_over_normal_color)
+  {
+    uint32_t si_ga = ((uint32_t*)rasterizer->color)[1];
+    uint32_t si_rb = ((uint32_t*)rasterizer->color)[2];
+    uint32_t si_a  = si_ga >> 16;
+    while (count--)
+    {
+        uint32_t cov   = *coverage++;
+        uint32_t rcov  = (((255+si_a * cov)>>8))^255;
+        uint32_t di    = ctx_565_to_888 (*((uint16_t*)dst), 0);
+        uint32_t di_ga = ((di & 0xff00ff00) >> 8);
+        uint32_t di_rb = (di & 0x00ff00ff);
+        *((uint16_t*)(dst)) =
+        ctx_888_to_565((((si_rb * cov + 0xff00ff + di_rb * rcov) & 0xff00ff00) >> 8)  |
+         ((si_ga * cov + 0xff00ff + di_ga * rcov) & 0xff00ff00), 0);
+         dst+=2;
+    }
+    return;
+  }
+  if (rasterizer->comp_op == ctx_RGBA8_source_copy_normal_color)
+  {
+    uint32_t si_ga = ((uint32_t*)rasterizer->color)[1];
+    uint32_t si_rb = ((uint32_t*)rasterizer->color)[2];
+    uint32_t si_a  = si_ga >> 16;
+    while (count--)
+    {
+        uint32_t cov   = *coverage++;
+        uint32_t rcov  = cov^255;
+        uint32_t di    = ctx_565_to_888 (*((uint16_t*)dst), 0);
+        uint32_t di_ga = ((di & 0xff00ff00) >> 8);
+        uint32_t di_rb = (di & 0x00ff00ff);
+        *((uint16_t*)(dst)) =
+        ctx_888_to_565((((si_rb * cov + 0xff00ff + di_rb * rcov) & 0xff00ff00) >> 8)  |
+         ((si_ga * cov + 0xff00ff + di_ga * rcov) & 0xff00ff00), 0);
+         dst+=2;
+    }
+    return;
+  }
+#endif
+
   uint8_t pixels[count * 4];
   ctx_RGB565_to_RGBA8 (rasterizer, x0, dst, &pixels[0], count);
   rasterizer->comp_op (count, &pixels[0], rasterizer->color, coverage, rasterizer, x0);
@@ -21073,14 +20971,57 @@ ctx_composite_RGB565 (CTX_COMPOSITE_ARGUMENTS)
 #endif
 #if CTX_ENABLE_RGB565_BYTESWAPPED
 
-static void
+void
 ctx_RGB565_BS_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *rgba, int count);
-static void
+void
 ctx_RGBA8_to_RGB565_BS (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count);
 
 static void
 ctx_composite_RGB565_BS (CTX_COMPOSITE_ARGUMENTS)
 {
+#if 0 // code is OK - but not faster - at least no on risc-V
+  if ((rasterizer->comp_op == ctx_RGBA8_source_over_normal_color)
+      ||(rasterizer->comp_op == ctx_RGBA8_source_copy_normal_color))
+  {
+    uint32_t si_ga = ((uint32_t*)rasterizer->color)[1];
+    uint32_t si_rb = ((uint32_t*)rasterizer->color)[2];
+    uint32_t si_a  = si_ga >> 16;
+    while (count--)
+    {
+      uint32_t cov   = *coverage++;
+      uint32_t rcov  = (((255+si_a * cov)>>8))^255;
+      uint32_t di    = ctx_565_to_888 (*((uint16_t*)dst), 1);
+      uint32_t di_ga = ((di & 0xff00ff00) >> 8);
+      uint32_t di_rb = (di & 0x00ff00ff);
+      *((uint16_t*)(dst)) =
+      ctx_888_to_565((((si_rb * cov + 0xff00ff + di_rb * rcov) & 0xff00ff00) >> 8)  |
+       ((si_ga * cov + 0xff00ff + di_ga * rcov) & 0xff00ff00), 1);
+       dst+=2;
+    }
+    return;
+  }
+#endif
+#if 1
+  if (rasterizer->comp_op == ctx_RGBA8_source_copy_normal_color)
+  {
+    uint32_t si_ga = ((uint32_t*)rasterizer->color)[1];
+    uint32_t si_rb = ((uint32_t*)rasterizer->color)[2];
+    while (count--)
+    {
+        uint8_t cov   = *coverage++;
+        uint8_t rcov  = cov^255;
+        uint32_t di    = ctx_565_to_888 (*((uint16_t*)dst), 1);
+        uint32_t di_ga = ((di & 0xff00ff00) >> 8);
+        uint32_t di_rb = (di & 0x00ff00ff);
+        *((uint16_t*)(dst)) =
+        ctx_888_to_565((((si_rb * cov + 0xff00ff + di_rb * rcov) & 0xff00ff00) >> 8)  |
+         ((si_ga * cov + 0xff00ff + di_ga * rcov) & 0xff00ff00), 1);
+         dst+=2;
+    }
+    return;
+  }
+#endif
+
   uint8_t pixels[count * 4];
   ctx_RGB565_BS_to_RGBA8 (rasterizer, x0, dst, &pixels[0], count);
   rasterizer->comp_op (count, &pixels[0], rasterizer->color, coverage, rasterizer, x0);
@@ -21656,12 +21597,20 @@ CTX_SIMD_SUFFIX (ctx_composite_fill_rect) (CtxRasterizer *rasterizer,
 
   y1 += 1.0f;
   x1 += 7.0f/8.0f;
+  x0 = ctx_maxi (x0, blit_x);
+  x1 = ctx_mini (x1, blit_x + blit_width - 1);
+  y0 = ctx_maxi (y0, blit_y);
+  y1 = ctx_mini (y1, blit_y + blit_height - 1);
 
   uint8_t left = (int)(255-x0_fm * 255);
   uint8_t top  = (int)(255-y0_fm * 255);
   uint8_t right  = (int)(x1_fm * 255);
   uint8_t bottom = (int)(y1_fm * 255);
 
+  x0 = ctx_floorf (x0);
+  y0 = ctx_floorf (y0);
+  x1 = ctx_floorf (x1);
+  y1 = ctx_floorf (y1);
 
   int has_top    = (top < 255);
   int has_bottom = (bottom < 255);
@@ -21671,15 +21620,6 @@ CTX_SIMD_SUFFIX (ctx_composite_fill_rect) (CtxRasterizer *rasterizer,
   has_right *= !(x1 >= blit_x + blit_width);
   has_bottom *= !(y1 >= blit_y + blit_height);
 
-  x0 = ctx_maxi (x0, blit_x);
-  x1 = ctx_mini (x1, blit_x + blit_width);
-  y0 = ctx_maxi (y0, blit_y);
-  y1 = ctx_mini (y1, blit_y + blit_height);
-  x0 = ctx_floorf (x0);
-  y0 = ctx_floorf (y0);
-  x1 = ctx_floorf (x1);
-  y1 = ctx_floorf (y1);
-
   int width = (int)(x1 - x0);
   int height = (int)(y1 - y0);
 
@@ -21923,6 +21863,12 @@ const CtxPixelFormatInfo CTX_SIMD_SUFFIX(ctx_pixel_formats)[]=
     NULL, NULL, NULL, ctx_setup_RGBAF,
   },
 #endif
+#if CTX_ENABLE_RGB8
+  {
+    CTX_FORMAT_RGB8, 3, 24, 4, 0, 0, CTX_FORMAT_RGBA8,
+    ctx_RGB8_to_RGBA8, ctx_RGBA8_to_RGB8, ctx_composite_convert, ctx_setup_RGB8,
+  },
+#endif
 #if CTX_ENABLE_GRAY1
   {
 #if CTX_NATIVE_GRAYA8
@@ -21992,20 +21938,6 @@ const CtxPixelFormatInfo CTX_SIMD_SUFFIX(ctx_pixel_formats)[]=
     ctx_composite_RGB565, ctx_setup_RGB565,
   },
 #endif
-#if CTX_ENABLE_RGB8
-  {
-    CTX_FORMAT_RGB8, 3, 24, 4, 0, 0, CTX_FORMAT_RGBA8,
-    ctx_RGB8_to_RGBA8, ctx_RGBA8_to_RGB8,
-    ctx_composite_RGB8, ctx_setup_RGB8,
-  },
-#endif
-#if CTX_ENABLE_BGR8
-  {
-    CTX_FORMAT_BGR8, 3, 24, 4, 0, 0, CTX_FORMAT_RGBA8,
-    ctx_RGB8_to_RGBA8, ctx_RGBA8_to_RGB8,
-    ctx_composite_BGR8, ctx_setup_RGB8,
-  },
-#endif
 #if CTX_ENABLE_RGB565_BYTESWAPPED
   {
     CTX_FORMAT_RGB565_BYTESWAPPED, 3, 16, 4, 16, 32, CTX_FORMAT_RGBA8,
@@ -23059,7 +22991,7 @@ ctx_rasterizer_apply_grads_copy_normal_color (CtxRasterizer *rasterizer,
        ctx_span_set_color_x4 ((uint32_t*)dst_i, (uint32_t*)color, width);
        break;
     case 4:
-      ctx_span_set_color ((uint32_t*)dst_i, ((uint32_t*)color)[0], width);
+      ctx_span_set_color ((uint32_t*)(&dst[(first+pre) *4]), ((uint32_t*)color)[0], width);
       break;
     case 2:
     {
@@ -23071,28 +23003,6 @@ ctx_rasterizer_apply_grads_copy_normal_color (CtxRasterizer *rasterizer,
       }
     }
       break;
-    case 3:
-    {
-       uint8_t r = color[0];
-       uint8_t g = color[1];
-       uint8_t b = color[2];
-       while (width--)
-       {
-         *dst_i++ = r;
-         *dst_i++ = g;
-         *dst_i++ = b;
-       }
-     }
-     break;
-    case 1:
-    {
-       uint8_t val = color[0];
-       while (width--)
-       {
-         *dst_i++ = val;
-       }
-     }
-     break;
    default:
    while (width--)
    {
@@ -23797,7 +23707,7 @@ void CTX_SIMD_SUFFIX(ctx_simd_setup)(void)
 
 #if CTX_ENABLE_RGB565
 
-static void
+void
 ctx_RGBA8_to_RGB565_BS (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, void *buf, int count)
 {
   uint16_t *pixel = (uint16_t *) buf;
@@ -23814,7 +23724,7 @@ ctx_RGBA8_to_RGB565_BS (CtxRasterizer *rasterizer, int x, const uint8_t *rgba, v
     }
 }
 
-static void
+void
 ctx_RGB565_BS_to_RGBA8 (CtxRasterizer *rasterizer, int x, const void *buf, uint8_t *rgba, int count)
 {
   const uint16_t *pixel = (uint16_t *) buf;
@@ -26462,11 +26372,6 @@ ctx_rasterizer_init (CtxRasterizer *rasterizer, Ctx *ctx, Ctx *texture_source, C
     pixel_format = CTX_FORMAT_RGBA8;
     rasterizer->swap_red_green = 1;
   }
-  else if (pixel_format == CTX_FORMAT_BGR8)
-  {
-    pixel_format = CTX_FORMAT_RGB8;
-    rasterizer->swap_red_green = 1;
-  }
 
   rasterizer->format = ctx_pixel_format_info (pixel_format);
 
@@ -26524,11 +26429,6 @@ ctx_rasterizer_reinit (Ctx *ctx,
     pixel_format = CTX_FORMAT_RGBA8;
     rasterizer->swap_red_green = 1;
   }
-  else if (pixel_format == CTX_FORMAT_BGR8)
-  {
-    pixel_format = CTX_FORMAT_RGB8;
-    rasterizer->swap_red_green = 1;
-  }
 
   rasterizer->format = ctx_pixel_format_info (pixel_format);
 #endif
@@ -43418,7 +43318,7 @@ static const CtxRawKey raw_key_map[]=
 static char *evsource_kb_raw_get_event (void)
 {
   struct input_event ev;
-  Ctx *ctx = (void*)ctx_ev_src_kb_raw.priv;
+  Ctx *ctx = (void*)ctx_ev_src_mice.priv;
 
   memset (&ev, 0, sizeof (ev));
   if (-1==read(kb_fd, &ev, sizeof(ev)))
@@ -48905,58 +48805,6 @@ Ctx *ctx_new_ctx (int width, int height, int flags)
 
 #if CTX_RASTERIZER
 
-
-CtxCbJob *cb_get_job (Ctx *ctx, int renderer)
-{
-  CtxCbBackend *cb = (CtxCbBackend*)ctx->backend;
-  for (int i = 0; i < cb->n_jobs; i++)
-  {
-    if (cb->jobs[i].renderer == CTX_JOB_PENDING)
-    {
-      cb->jobs[i].renderer = renderer;
-      return &cb->jobs[i];
-    }
-  }
-  return NULL;
-}
-
-void cb_job_done (CtxCbJob *job)
-{
-  job->renderer = 0;
-}
-
-int cb_jobs_pending (Ctx *ctx)
-{
-  CtxCbBackend *cb = (CtxCbBackend*)ctx->backend;
-  int sum = 0;
-  for (int i = 0; i < cb->n_jobs; i++)
-    sum += (cb->jobs[i].renderer != 0);
-  return sum;
-}
-
-void cb_clear_jobs (Ctx *ctx)
-{
-  CtxCbBackend *cb = (CtxCbBackend*)ctx->backend;
-  for (int i = 0; i < cb->n_jobs; i++)
-    cb->jobs[i].renderer = 0;
-  cb->n_jobs = 0;
-}
-
-void cb_add_job (Ctx *ctx, int x0, int y0, int width, int height, int bitmask)
-{
-  CtxCbBackend *cb = (CtxCbBackend*)ctx->backend;
-  if (cb->n_jobs >= CTX_CB_MAX_JOBS)
-    return;
-  CtxCbJob *job = &cb->jobs[cb->n_jobs++];;
-  job->renderer = CTX_JOB_PENDING;
-  job->x0 = x0;
-  job->y0 = y0;
-  job->width = width;
-  job->height = height;
-  job->bitmask = bitmask;
-}
-
-
 static int ctx_cb_kill = 0;
 
 void ctx_cb_set_flags (Ctx *ctx, int flags)
@@ -49084,12 +48932,12 @@ static int ctx_render_cb (CtxCbBackend *backend_cb,
 {
   Ctx *ctx           = backend_cb->ctx;
   int flags          = backend_cb->config.flags;
-  Ctx *rctx          = flags&CTX_FLAG_RENDER_THREAD?backend_cb->drawlist_copy:ctx;
   int buffer_size    = backend_cb->config.buffer_size;
   uint16_t *scratch;
   CtxPixelFormat format = backend_cb->config.format;
   int bpp            = ctx_pixel_format_bits_per_pixel (format) / 8;
   int abort          = 0;
+  Ctx *rctx = flags&CTX_FLAG_RENDER_THREAD?backend_cb->drawlist_copy:ctx;
   
   int width          = x1 - x0 + 1;
   int height         = y1 - y0 + 1;
@@ -49161,16 +49009,20 @@ static int ctx_render_cb (CtxCbBackend *backend_cb,
     uint16_t *scaled = (uint16_t*)&fb_u8[small_height*small_stride];
 
     memset(scratch, 0, small_stride * small_height);
-    ctx_rasterizer_reinit(backend_cb->rctx, scratch, 0, 0, small_width, small_height, small_stride, format);
-
-    ctx_set_texture_source (backend_cb->rctx, ctx);
-
-    ctx_scale (backend_cb->rctx, 1.0f/scale_factor, 1.0f/scale_factor);
-    ctx_translate (backend_cb->rctx, -1.0f * x0, -1.0f * y0);
+    CtxRasterizer *r = ctx_rasterizer_init ((CtxRasterizer*)&backend_cb->rasterizer,
+                rctx, NULL, &rctx->state, scratch, 0, 0, small_width, small_height,
+                small_stride, tformat, CTX_ANTIALIAS_DEFAULT);
+    ((CtxBackend*)r)->destroy = (CtxDestroyNotify)ctx_rasterizer_deinit;
+    ctx_push_backend (rctx, r);
+    ctx_set_texture_source (rctx, ctx);
+
+    ctx_scale (rctx, 1.0f/scale_factor, 1.0f/scale_factor);
+    ctx_translate (rctx, -1.0f * x0, -1.0f * y0);
     if (active_mask)
-      ctx_render_ctx_masked (rctx, backend_cb->rctx, active_mask);
+      ctx_render_ctx_masked (rctx, rctx, active_mask);
     else
-      ctx_render_ctx (rctx, backend_cb->rctx);
+      ctx_render_ctx (rctx, rctx);
+    ctx_pop_backend (rctx);
 
     if (backend_cb->config.update_fb && (flags & CTX_FLAG_INTRA_UPDATE))
        backend_cb->config.update_fb (ctx, backend_cb->config.update_fb_user_data?
@@ -49348,6 +49200,11 @@ static int ctx_render_cb (CtxCbBackend *backend_cb,
     {
        render_height = buffer_size / width / bpp;
     }
+    CtxRasterizer *r = ctx_rasterizer_init((CtxRasterizer*)&backend_cb->rasterizer,
+                         rctx, NULL, &rctx->state, scratch, 0, 0, width, height,
+                         width * bpp, format, CTX_ANTIALIAS_DEFAULT);
+    ((CtxBackend*)r)->destroy = (CtxDestroyNotify)ctx_rasterizer_deinit;
+    ctx_push_backend (rctx, r);
 
     int do_intra = (((flags & CTX_FLAG_INTRA_UPDATE) != 0) && backend_cb->config.update_fb);
     int keep_data = ((flags & CTX_FLAG_KEEP_DATA) != 0);
@@ -49357,30 +49214,32 @@ static int ctx_render_cb (CtxCbBackend *backend_cb,
     do
     {
       render_height = ctx_mini (render_height, y1-y0+1);
-      ctx_rasterizer_reinit(backend_cb->rctx, scratch, 0, 0, width, render_height, width * bpp, format);
+      ctx_rasterizer_init (r, rctx, NULL, &rctx->state, scratch, 0, 0, width,
+                   render_height, width * bpp, format, CTX_ANTIALIAS_DEFAULT);
+      ((CtxBackend*)r)->destroy = (CtxDestroyNotify)ctx_rasterizer_deinit;
 
       if (!keep_data)
         memset (scratch, 0, width * bpp * render_height);
 
-      ctx_translate (backend_cb->rctx, -1.0f * x0, -1.0f * y0);
+      ctx_translate (rctx, -1.0f * x0, -1.0f * y0);
       if (active_mask)
-        ctx_render_ctx_masked (rctx, backend_cb->rctx, active_mask);
+        ctx_render_ctx_masked (rctx, rctx, active_mask);
       else
-        ctx_render_ctx (rctx, backend_cb->rctx);
+        ctx_render_ctx (rctx, rctx);
 
       if (flags & CTX_FLAG_DAMAGE_CONTROL)
         ctx_cb_mark_damage (width, height, bpp, scratch);
-
       set_pixels (ctx, set_pixels_user_data, 
                   x0, y0, width, render_height, (uint16_t*)scratch);
 
-      // TODO : make this be a separate cb, more flexible
       if (do_intra)
         abort = backend_cb->config.update_fb (ctx, backend_cb->config.update_fb_user_data?
                                                    backend_cb->config.update_fb_user_data:
                                                    backend_cb->config.user_data);
+
       y0 += render_height;
     } while (y0 < y1 && !abort);
+    ctx_pop_backend (rctx);    
   }
   return abort;
 }
@@ -49471,7 +49330,7 @@ ctx_cb_render_frame (Ctx *ctx)
     int bpp               = ctx_pixel_format_bits_per_pixel (format) / 8;
     int tile_dim          = tile_width * tile_height * bpp;
 
-    CtxRasterizer *rasterizer = (CtxRasterizer*)&cb_backend->hasher;
+    CtxRasterizer *rasterizer = (CtxRasterizer*)&cb_backend->rasterizer;
     ctx_hasher_init (rasterizer, rctx, state, width, height, CTX_HASH_COLS, CTX_HASH_ROWS, &rctx->drawlist);
     ((CtxBackend*)rasterizer)->destroy = (CtxDestroyNotify)ctx_rasterizer_deinit;
 
@@ -49552,7 +49411,7 @@ ctx_cb_render_frame (Ctx *ctx)
         {
             int memory = (cb_backend->max_col-cb_backend->min_col+1)*
                           (cb_backend->max_row-cb_backend->min_row+1)*tile_dim;
-            if (memory < cb_backend->config.buffer_size && 0) // straight to hifi
+            if (memory < cb_backend->config.buffer_size && 0)
             {
               in_low_res = 0;
               if ((cb_backend->config.flags & CTX_FLAG_STAY_LOW) == 0)
@@ -49606,12 +49465,9 @@ ctx_cb_render_frame (Ctx *ctx)
            tile_no = 0;
            cb_backend->re_render = 0;
 
-           if (width * height * bpp <= cb_backend->config.buffer_size &&
-               dirty_tiles * (tile_width * tile_height) >= (width * height) * 3 / 4
-               )
+           if (width * height * bpp <= cb_backend->config.buffer_size)
            {
-             // we have enough memory to render all in one go -
-             // and we do not add more than 25% of pixel re-render overhead
+             // we have enough memory to render all in one go
              active_mask = 0;
              for (int row = cb_backend->min_row; row <= cb_backend->max_row; row++)
                for (int col = cb_backend->min_col; col <= cb_backend->max_col; col++)
@@ -50004,9 +49860,6 @@ ctx_cb_end_frame (Ctx *ctx)
       {
         ctx_cb_render_frame (ctx);
       }
-#if CTX_EVENTS
-      ctx_handle_events (ctx);
-#endif
   }
 
 #if 0//CTX_EVENTS
@@ -50111,7 +49964,7 @@ static char *ctx_cb_get_clipboard (Ctx *ctx)
 static void ctx_cb_full_set_pixels (Ctx *ctx, void *user_data, int x, int y, int w, int h, void *buf)
 {
   CtxCbBackend *cb_backend = (CtxCbBackend*)user_data;
-  uint8_t *out = (uint8_t*)cb_backend->config.fb;
+  uint8_t *out = cb_backend->config.fb;
   int bpp  = ctx_pixel_format_bits_per_pixel (cb_backend->config.format) / 8;
   uint8_t *src = (uint8_t*)buf;
   for (int scan = y; scan < y + h; scan++)
@@ -50300,12 +50153,12 @@ Ctx *ctx_new_cb (int width, int height, CtxCbConfig *config)
   }
 
 
-  //if (config->flags & CTX_FLAG_FULL_FB)
-  //{
+  if (config->flags & CTX_FLAG_FULL_FB)
+  {
     cb_backend->rctx = ctx_new_for_framebuffer (cb_backend->config.fb, ctx->width, ctx->height, ctx_pixel_format_get_stride (cb_backend->config.format, ctx->width),
                                                 cb_backend->config.format);
     ctx_set_texture_source (cb_backend->rctx, ctx);
-  //}
+  }
 
   return ctx;
 }
@@ -51370,7 +51223,7 @@ Ctx *ctx_new_sdl_cb (int width, int height, int flags)
     .format         = CTX_FORMAT_RGBA8,
     .flags          = flags
                     | CTX_FLAG_HASH_CACHE 
-                    | CTX_FLAG_LOWFI
+                 // | CTX_FLAG_LOWFI
                     | CTX_FLAG_RENDER_THREAD
                  // | CTX_FLAG_DAMAGE_CONTROL
                  // | CTX_FLAG_POINTER
@@ -74244,7 +74097,7 @@ const char * html_css =
 ".cursor{color:white;background: black;} \n"
 "br{display:block;}\n"
 "html{font-weight:normal;background-color:white;}\n"
-"body{background-color:transparent;color:#000;}\n"
+"body{background-color:transparent;color:black;}\n"
 "a{color:blue;text-decoration: underline;}\n"
 "a:hover{background:black;color:white;text-decoration:underline; }\n"
 "head{display:none;}\n"
@@ -74258,7 +74111,8 @@ const char * html_css =
 
 " .children{ border:1px solid green;padding-left:3em; }\n"
 " .selection{background:white; color: red; }\n"
-" :focused {color: green; }\n"
+" :focused {color: yellow; }\n"
+" .fnord { color: green; }\n"
 "   .item { border: 1px solid transparent; color: white; }"
 "   .item:focused { color: yellow; border: 1px solid blue;}"
  /*  .item>.text::before { content:"-";display:block;position:absolute;margin-left:-1.2em; } */
@@ -74271,19 +74125,18 @@ const char * html_css =
 //"html{font-size:10.0px;color:white;}\n" // from ACID1 - not parsed right
 
 //// itk defaults stylesheet
-"toggle        {border: 1px solid green;border: 1px solid red;color:white;display:block;}\n"
-"button        {border: 1px solid green;display:block; height: 1em;background:#000;color:#f00;}\n"
-"button:focused{color:#f0f;border: 1px solid purple;background:blue;}\n"
-
+"toggle        {border: 1px solid green;border: 1px solid red;color:yellow;display:block;}\n"
+"button        {border: 1px solid green;}\n"
 "choice        {border: 1px solid brown;display:inline-block;}\n"
 ".choice_menu_wrap  {border: 1px solid red;display:block;position:relative;top:-1.2em;left:4em;height:0;width:0;}\n"
 ".choice_menu  {border: 1px solid red;display:block;position:absolute;width:7em;}\n"
 ".choice       {border: 1px solid brown;display:block;background:black}\n"
 ".choice:chosen{border: 1px solid brown;display:block;background:red;}\n"
+"button:focused{color:yellow;border: 1px solid yellow;background:blue;}\n"
 "label         {display:inline; color:white;}\n"
-"slider        {display:block; color:white;}\n"
-"propline      {display:block;margin-top:0.25em;margin-bottom:0.25em;border:2 px solid cyan;}\n"
-"propline:focused {border:2px solid red;background:#444;}\n"
+"slider        {display:inline-block; color:white;}\n"
+"propline      {display:block;margin-top:0.25em;margin-bottom:0.25em;border:1 px solid transparent;}\n"
+"propline:focused {border:1px solid red;background:#faf}\n"
 ;
 
 
@@ -74489,11 +74342,8 @@ enum
 };
 
 
-static void _ctx_stylesheet_add (CtxCssParseState *ps,
-                                 Css *mrg,
-                                 const char *css,
-                                 const char *uri_base,
-                                 int priority, char **error)
+static void _ctx_stylesheet_add (CtxCssParseState *ps, Css *mrg, const char *css, const char *uri_base,
+                         int priority, char **error)
 {
   const char *p;
   if (!ps)
@@ -74788,7 +74638,7 @@ void css_css_default (Css *mrg)
   }
 }
 
-void ctx_stylesheet_clear (Css *mrg)
+void css_stylesheet_clear (Css *mrg)
 {
   if (mrg->stylesheet)
     ctx_list_free (&mrg->stylesheet);
@@ -75094,7 +74944,7 @@ void ctx_css_add (Css *mrg, const char *css)
   ctx_string_append_str (mrg->style, css);
 }
 
-void ctx_stylesheet_clear (Css *mrg);
+void css_stylesheet_clear (Css *mrg);
 void ctx_stylesheet_add (Css *mrg, const char *css, const char *uri,
                          int priority,
                          char **error);
@@ -75756,8 +75606,6 @@ static void ctx_css_handle_property_pass1 (Css *mrg, uint32_t key,
     case SQZ_font_family:
       {
         SET_PROPS(font_family, value);
-        if (!strcmp (value, "monospace"))
-          value = "Mono";
         ctx_font (mrg_ctx (mrg), value);
       }
       break;
@@ -76256,7 +76104,7 @@ void ctx_style_defaults (Css *mrg)
     ctx_color_free (color);
   }
 
-  ctx_stylesheet_clear (mrg);
+  css_stylesheet_clear (mrg);
   _ctx_initial_style (mrg);
 
   if (mrg->style_global->length)
@@ -76468,7 +76316,9 @@ void _mrg_layout_pre (Css *mrg)
   }
   else if (style->display == CTX_DISPLAY_INLINE_BLOCK)
   {
-    float left_margin_pad_and_border  = padding_left + margin_left + border_left_width;
+
+
+    float left_margin_pad_and_border = padding_left + margin_left + border_left_width;
     float right_margin_pad_and_border = padding_right + margin_right + border_right_width;
 
     if (mrg_x (mrg) + width + left_margin_pad_and_border + right_margin_pad_and_border
@@ -76784,7 +76634,7 @@ void css_end (Css *mrg, CtxFloatRectangle *ret_rect)
   if (mrg->state_no == 0)
   {
     ctx_list_reverse (&mrg->absolutes);
-    ctx_list_sort (&mrg->absolutes, compare_zindex, NULL); // oh - wow, we do get some z-index with the drawlist use!
+    ctx_list_sort (&mrg->absolutes, compare_zindex, NULL);
 
     /* TODO: handle negative z-index */
     /* TODO: also copy/paste registered interaction points */
@@ -77487,15 +77337,13 @@ float mrg_draw_string (Css *mrg, CtxStyle *style,
                        const char *string,
                        int utf8_len)
 {
-  float y;
+  //float x = mrg->x;
+  float y = mrg->y;
   float new_x, old_x;
   char *temp_string = NULL;
   Ctx *cr = mrg_ctx (mrg);
 
-  //css_set_xy (mrg, new_x, y);
-  old_x = mrg->x;
-  y = mrg->y;
-  ctx_move_to (cr, old_x, y + style->font_size);
+  ctx_current_point (cr, &old_x, NULL);
 
   if (utf8_len < 0)
     utf8_len = ctx_utf8_strlen (string);
@@ -77513,6 +77361,46 @@ float mrg_draw_string (Css *mrg, CtxStyle *style,
     *(char *)t = 0;
     string = temp_string;
   }
+#if 0
+  if (mrg_is_terminal (mrg) && mrg_em (mrg) <= CPX * 4 / mrg->ddpx)
+  {
+    const char *t;
+    int i;
+
+    /* XXX: include transforms */
+    int offset;
+    double u = x , v = y;
+    cairo_matrix_t matrix;
+    cairo_get_matrix (mrg_ctx (mrg), &matrix);
+    cairo_matrix_transform_point (&matrix, &u, &v);
+
+    //u = ctx_floorf(u);
+    //v = ctx_floorf(v);
+    
+    offset = (int)(v/CPX) * ((int)(mrg->width/CPX) * 4) + (int)(u/CPX) * 4;
+
+    old_x = x;
+    for (i = 0, t = string; *t; i++)
+    {
+      if ( v >= 0 && u >= 0 &&
+          (int)u/CPX < (int)(mrg->width/CPX) &&
+          (int)v/CPX < (int)(mrg->height/CPX))
+      {
+        int styleno = offset/4;
+        memcpy (&mrg->glyphs[offset], t, ctx_utf8_len (*t));
+        mrg->styles[styleno] = mrg->state->fg +
+                               mrg->state->bg * 8 +
+                               (mrg->state->style.text_decoration & 
+                                (CTX_TEXT_DECORATION_BOLD|CTX_TEXT_DECORATION_DIM|CTX_TEXT_DECORATION_UNDERLINE|CTX_TEXT_DECORATION_REVERSE)) * 64;;
+      }
+      t += ctx_utf8_len (*t);
+      offset += 4;
+      x += CPX / mrg->ddpx;
+    }
+    new_x = x;
+  }
+  else 
+#endif
   //if (mrg->in_paint)
   {
     ctx_font_size (cr, style->font_size);
@@ -77539,6 +77427,7 @@ float mrg_draw_string (Css *mrg, CtxStyle *style,
     ctx_color_free (color);
     }
     //ctx_move_to   (cr, x, y - _mrg_text_shift (mrg));
+    ctx_current_point (cr, &old_x, NULL);
 
     /* when syntax highlighting,.. should do it as a coloring
      * directly here..
@@ -77547,8 +77436,6 @@ float mrg_draw_string (Css *mrg, CtxStyle *style,
     const char *syntax_highlight = PROPS(syntax_highlight);
     if (!syntax_highlight) syntax_highlight = "";
 
-//  ctx_current_point (cr, &old_x, NULL);
-    //ctx_move_to (cr, old_x, y);// - style->font_size);
     if (syntax_highlight[0] == 0)
       ctx_text (cr, string);
     else if (!strcmp (syntax_highlight, "C"))
@@ -77560,10 +77447,8 @@ float mrg_draw_string (Css *mrg, CtxStyle *style,
 
     if (style->text_decoration & CTX_TEXT_DECORATION_UNDERLINE)
       {
-        //ctx_rel_move_to (cr, -(new_x-old_x), 0);
-        //ctx_rel_line_to (cr, new_x-old_x, 0);
-        ctx_move_to (cr, old_x, y + style->font_size * 1.1f);
-        ctx_line_to (cr, new_x, y + style->font_size * 1.1f);
+        ctx_rel_move_to (cr, -(new_x-old_x), 0);
+        ctx_rel_line_to (cr, new_x-old_x, 0);
         ctx_stroke (cr);
       }
     if (style->text_decoration & CTX_TEXT_DECORATION_LINETHROUGH)
@@ -77578,8 +77463,7 @@ float mrg_draw_string (Css *mrg, CtxStyle *style,
         ctx_line_to (cr, new_x, y - style->font_size);
         ctx_stroke (cr);
       }
-    //css_set_xy (mrg, new_x, y);
-    //ctx_move_to (cr, new_x, y + style->font_size * style->line_height);
+    //ctx_move_to (cr, new_x, y);
   }
 #if 0
   else
@@ -77594,20 +77478,20 @@ float mrg_draw_string (Css *mrg, CtxStyle *style,
     float em = mrg_em (mrg);
     int no = mrg->text_listen_count-1;
     float x, y;
-    x = mrg->x; y=mrg->y;
+
+    ctx_current_point (cr, &x, &y);
+
     ctx_reset_path (cr);
     ctx_rectangle (cr,
-        old_x, y, new_x - old_x + 1, em * mrg->state->style.line_height);
+        old_x, y - em, new_x - old_x + 1, em * mrg->state->style.line_height);
     ctx_listen (cr,
                 mrg->text_listen_types[no],
                 mrg->text_listen_cb[no],
                 mrg->text_listen_data1[no],
                 mrg->text_listen_data2[no]);
     ctx_reset_path (cr);
-    css_set_xy (mrg, x, y);
+    ctx_move_to (cr, x, y);
   }
-  //css_set_xy (mrg, new_x, y);
-  //ctx_move_to (cr, new_x, y + style->font_size);
 
   if (temp_string)
     free (temp_string);
@@ -78910,6 +78794,12 @@ void _mrg_layout_post (Css *mrg, CtxFloatRectangle *ret_rect)
   {
     if (style->display == CTX_DISPLAY_INLINE_BLOCK)
     {
+      if (height == 0)
+        height = mrg_y (mrg) - (mrg->state->block_start_y);
+      
+      mrg->line_max_height[mrg->line_level-1] =
+        ctx_maxf (mrg->line_max_height[mrg->line_level-1],
+                  height);
       
     }
     else
@@ -78955,13 +78845,6 @@ void _mrg_layout_post (Css *mrg, CtxFloatRectangle *ret_rect)
 
   if (style->display == CTX_DISPLAY_INLINE_BLOCK)
   {
-     if (height == 0)
-       height = mrg_y (mrg) - (mrg->state->block_start_y);
-      
-     mrg->line_max_height[mrg->line_level-1] =
-        ctx_maxf (mrg->line_max_height[mrg->line_level-1],
-                  height);
-
     CtxFloatRectangle _geo;
     CtxFloatRectangle *geo = &_geo;
     memset (geo, 0, sizeof (_geo));
@@ -78971,6 +78854,9 @@ void _mrg_layout_post (Css *mrg, CtxFloatRectangle *ret_rect)
       width = mrg_x (mrg) - (mrg->state->block_start_x) + padding_right;
     }
     geo->width = width;
+
+    if (height == 0)
+      height = mrg_y (mrg) - (mrg->state->block_start_y);
     geo->height = height;
 
     char name[10]="ele_";
@@ -81134,8 +81020,6 @@ void css_xml_render (Css *mrg,
           }
 #endif
         }
-        else
-          should_be_empty = 0;
         break;
     }
   }
@@ -81840,7 +81724,7 @@ Css *css_new (Ctx *ctx)
   css_init (mrg, ctx, ctx_width(ctx), ctx_height(ctx));
 
 
-  //ctx_stylesheet_clear (mrg);
+  //css_stylesheet_clear (mrg);
   ctx_style_defaults (mrg);
 
   //printf ("%f %i %i\n", mrg->state->style.font_size, mrg_width(mrg), mrg_height(mrg));
@@ -81967,7 +81851,7 @@ void css_reset (Css *itk)
   //mrg_clear (itk);
   ctx_clear_bindings (itk->ctx);
 #if 0
-  ctx_stylesheet_clear ((Css*)itk);
+  css_stylesheet_clear ((Css*)itk);
   ctx_style_defaults ((Css*)itk);
 #endif
 }
@@ -82968,8 +82852,8 @@ int css_button (Css *itk, const char *label)
 //  css_label (itk, label);
   css_print (mrg, label);
 
-  css_end (mrg, &extent);
 
+  css_end (mrg, &extent);
   CtxControl *control = css_add_control (itk, UI_BUTTON, label,
                   extent.x, extent.y, extent.width, extent.height);
                              //itk->x, itk->y, width, em * itk->rel_ver_advance);
@@ -82978,6 +82862,8 @@ int css_button (Css *itk, const char *label)
   control->type = UI_BUTTON;
   ctx_rectangle (ctx, extent.x, extent.y, extent.width, extent.height);
   ctx_listen_with_finalize (ctx, CTX_CLICK, button_clicked, control, itk, control_finalize, NULL);
+  ctx_rgb (ctx, 1,1,0);
+  ctx_fill (ctx);
   ctx_reset_path (ctx);
 
   //css_newline (itk);