From a7d154259160d72a5d6430305def60ee271f1f08 Mon Sep 17 00:00:00 2001
From: scuri <scuri>
Date: Sat, 13 Jun 2009 20:40:10 +0000
Subject: *** empty log message ***

---
 src/cd_freetype.mak      |  4 ++++
 src/drv/cdirgb.c         |  8 +++----
 src/gdiplus/cdwdbufp.cpp | 28 +++++++++++++++-------
 src/sim/cd_truetype.h    |  2 +-
 src/sim/sim_text.c       | 61 +++++++++++++++++++++++++++++++++++++++++-------
 src/win32/cdwdbuf.c      | 18 +++++++++++---
 src/x11/cdxdbuf.c        | 18 +++++++++++---
 7 files changed, 111 insertions(+), 28 deletions(-)

(limited to 'src')

diff --git a/src/cd_freetype.mak b/src/cd_freetype.mak
index 857c5b2..9d67e8a 100644
--- a/src/cd_freetype.mak
+++ b/src/cd_freetype.mak
@@ -30,6 +30,10 @@ ifneq ($(findstring Win, $(TEC_SYSNAME)), )
   LIBNAME = freetype6
 endif
 
+ifneq ($(findstring gcc, $(TEC_UNAME)), )
+  LIBNAME = freetype
+endif
+
 ifneq ($(findstring bc5, $(TEC_UNAME)), )
   FLAGS = -w-8004
 endif
diff --git a/src/drv/cdirgb.c b/src/drv/cdirgb.c
index 9fbb540..c590dcf 100644
--- a/src/drv/cdirgb.c
+++ b/src/drv/cdirgb.c
@@ -56,7 +56,7 @@ struct _cdCtxCanvas
 #define _sNormX(_ctxcanvas, _x) (_x < 0? 0: _x < _ctxcanvas->canvas->w? _x: _ctxcanvas->canvas->w-1)
 #define _sNormY(_ctxcanvas, _y) (_y < 0? 0: _y < _ctxcanvas->canvas->h? _y: _ctxcanvas->canvas->h-1)
 
-#define RGBA_COMPOSE(_SRC, _SRC_ALPHA, _DST, _TMP_MULTI, _TMP_ALPHA) (unsigned char)(((_SRC_ALPHA)*(_SRC) + (_TMP_MULTI)*(_DST)) / (_TMP_ALPHA))
+#define RGB_COMPOSE(_SRC, _SRC_ALPHA, _DST, _TMP_MULTI, _TMP_ALPHA) (unsigned char)(((_SRC_ALPHA)*(_SRC) + (_TMP_MULTI)*(_DST)) / (_TMP_ALPHA))
 
 #define RGBA_COLOR_COMBINE(_ctxcanvas, _pdst_red, _pdst_green, _pdst_blue, _pdst_alpha, _src_red, _src_green, _src_blue, _src_alpha) \
 {                                                                                                                        \
@@ -87,9 +87,9 @@ struct _cdCtxCanvas
           /* Closed Compositing Formulas for SRC over DST, Colors Not Premultiplied by Alpha:  */                        \
           int _tmp_multi = *_pdst_alpha * (255 - _src_alpha);                                                            \
           int _tmp_alpha = _src_alpha + _tmp_multi;                                                                      \
-          _tmp_red = RGBA_COMPOSE(_src_red, _src_alpha, *_pdst_red, _tmp_multi, _tmp_alpha);                             \
-          _tmp_green = RGBA_COMPOSE(_src_green, _src_alpha, *_pdst_green, _tmp_multi, _tmp_alpha);                       \
-          _tmp_blue = RGBA_COMPOSE(_src_blue, _src_alpha, *_pdst_blue, _tmp_multi, _tmp_alpha);                          \
+          _tmp_red = RGB_COMPOSE(_src_red, _src_alpha, *_pdst_red, _tmp_multi, _tmp_alpha);                             \
+          _tmp_green = RGB_COMPOSE(_src_green, _src_alpha, *_pdst_green, _tmp_multi, _tmp_alpha);                       \
+          _tmp_blue = RGB_COMPOSE(_src_blue, _src_alpha, *_pdst_blue, _tmp_multi, _tmp_alpha);                          \
           *_pdst_alpha = (unsigned char)(_tmp_alpha / 255);                                                              \
         }                                                                                                                \
       }                                                                                                                  \
diff --git a/src/gdiplus/cdwdbufp.cpp b/src/gdiplus/cdwdbufp.cpp
index 6d968b2..95cfe2e 100644
--- a/src/gdiplus/cdwdbufp.cpp
+++ b/src/gdiplus/cdwdbufp.cpp
@@ -62,29 +62,34 @@ static void cdflush(cdCtxCanvas* ctxcanvas)
 
 static int cdactivate(cdCtxCanvas* ctxcanvas)
 {
+  int w, h;
   cdCanvas* canvas_dbuffer = ctxcanvas->canvas_dbuffer;
 
   /* this is done in the canvas_dbuffer context */
   /* this will update canvas size */
   cdCanvasActivate(canvas_dbuffer);
+  w = canvas_dbuffer->w;
+  h = canvas_dbuffer->h;
+  if (w==0) w=1;
+  if (h==0) h=1;
 
   /* check if the size changed */
-  if (canvas_dbuffer->w != ctxcanvas->canvas->w ||
-      canvas_dbuffer->h != ctxcanvas->canvas->h)
+  if (w != ctxcanvas->canvas->w ||
+      h != ctxcanvas->canvas->h)
   {
     delete ctxcanvas->graphics;
     delete ctxcanvas->bitmap;
     if (ctxcanvas->bitmap_dbuffer) delete ctxcanvas->bitmap_dbuffer;
     ctxcanvas->bitmap_dbuffer = NULL;
 
-    Bitmap* bitmap = new Bitmap(canvas_dbuffer->w, canvas_dbuffer->h, PixelFormat24bppRGB);
+    Bitmap* bitmap = new Bitmap(w, h, PixelFormat24bppRGB);
     bitmap->SetResolution((REAL)(canvas_dbuffer->xres*25.4), (REAL)(canvas_dbuffer->yres*25.4));
 
     ctxcanvas->bitmap = bitmap;
     ctxcanvas->graphics = new Graphics(bitmap);
 
-    ctxcanvas->canvas->w = canvas_dbuffer->w;
-    ctxcanvas->canvas->h = canvas_dbuffer->h;
+    ctxcanvas->canvas->w = w;
+    ctxcanvas->canvas->h = h;
 
     ctxcanvas->dirty = 1;
 
@@ -100,11 +105,18 @@ O DC 
 */
 static void cdcreatecanvas(cdCanvas* canvas, void *data)
 {
+  int w, h;
   cdCanvas* canvas_dbuffer = (cdCanvas*)data;
   if (!canvas_dbuffer)
     return;
 
-  Bitmap* bitmap = new Bitmap(canvas_dbuffer->w, canvas_dbuffer->h, PixelFormat24bppRGB);
+  cdCanvasActivate(canvas_dbuffer); /* Update size */
+  w = canvas_dbuffer->w;
+  h = canvas_dbuffer->h;
+  if (w==0) w=1;
+  if (h==0) h=1;
+
+  Bitmap* bitmap = new Bitmap(w, h, PixelFormat24bppRGB);
   bitmap->SetResolution((REAL)(canvas_dbuffer->xres*25.4), (REAL)(canvas_dbuffer->yres*25.4));
 
   Graphics imggraphics(bitmap);
@@ -112,8 +124,8 @@ static void cdcreatecanvas(cdCanvas* canvas, void *data)
 
   Graphics* graphics = new Graphics(bitmap);
 
-  canvas->w = canvas_dbuffer->w;
-  canvas->h = canvas_dbuffer->h;
+  canvas->w = w;
+  canvas->h = h;
   canvas->bpp = 24;
 
   /* Initialize base driver */
diff --git a/src/sim/cd_truetype.h b/src/sim/cd_truetype.h
index 5675998..f29fb82 100644
--- a/src/sim/cd_truetype.h
+++ b/src/sim/cd_truetype.h
@@ -24,7 +24,7 @@ typedef struct _cdTT_Text
   FT_Library library;
   FT_Face face;          
 
-  unsigned char* rgba_data;
+  unsigned char* rgba_data;   /* the image where one character is drawn with the foreground color during text output */
   int rgba_data_size;
 
   int max_height;
diff --git a/src/sim/sim_text.c b/src/sim/sim_text.c
index 3ea7aef..7172e16 100644
--- a/src/sim/sim_text.c
+++ b/src/sim/sim_text.c
@@ -198,7 +198,11 @@ static void simDrawTextBitmap(cdSimulation* simulation, FT_Bitmap* bitmap, int x
   /* disable image transformation */
   simulation->canvas->use_matrix = 0;
 
+  /* this is the char bitmap, contains an alpha map of the char 
+     to be combined with the foreground color */
   bitmap_data = bitmap->buffer + (height-1)*width;  /* bitmap is top down. */
+
+  /* this is the image used to draw the char with the foreground color */ 
   red   = simulation->tt_text->rgba_data;
   green = red   + size;
   blue  = green + size;
@@ -207,8 +211,12 @@ static void simDrawTextBitmap(cdSimulation* simulation, FT_Bitmap* bitmap, int x
   if (!simulation->canvas->cxPutImageRectRGBA && !simulation->canvas->cxGetImageRGB)
   {
     int i, j;
-    unsigned char bg_red, bg_green, bg_blue, fg_red, fg_green, fg_blue;
+    unsigned char bg_red, bg_green, bg_blue, 
+                  fg_red, fg_green, fg_blue, fg_alpha, calpha;
     long int c;
+
+    /* must manually combine using only the background color, ignore canvas contents */
+
     c = simulation->canvas->background;
     bg_red   = cdRed(c);
     bg_green = cdGreen(c);
@@ -217,39 +225,74 @@ static void simDrawTextBitmap(cdSimulation* simulation, FT_Bitmap* bitmap, int x
     fg_red   = cdRed(c);
     fg_green = cdGreen(c);
     fg_blue  = cdBlue(c);
+    fg_alpha = cdAlpha(c);
 
     for (i = 0; i < height; i++)
     {
       for (j = 0; j < width; j++)
       {
-        *red++ = (fg_red*bitmap_data[j] + bg_red*(255-bitmap_data[j]))/255;
-        *green++ = (fg_green*bitmap_data[j] + bg_green*(255-bitmap_data[j]))/255;
-        *blue++ = (fg_blue*bitmap_data[j] + bg_blue*(255-bitmap_data[j]))/255;
+        if (fg_alpha == 255)
+          calpha = bitmap_data[j];
+        else
+          calpha = (fg_alpha*bitmap_data[j])/255;
+
+        *red++ = CD_ALPHA_BLEND(fg_red, bg_red, calpha);
+        *green++ = CD_ALPHA_BLEND(fg_green, bg_green, calpha);
+        *blue++ = CD_ALPHA_BLEND(fg_blue, bg_blue, calpha);
       }
 
       bitmap_data -= width;
     }
 
+    /* reset pointers */
     red   = simulation->tt_text->rgba_data;
     green = red   + size;
     blue  = green + size;
+
+    /* draw the char */
     simulation->canvas->cxPutImageRectRGB(simulation->canvas->ctxcanvas, width,height,red,green,blue,x,y,width,height,0,width-1,0,height-1);
   }
   else
   {
-    int i;
+    int i, j;
     long int fg = simulation->canvas->foreground;
+    unsigned char fg_alpha = cdAlpha(fg);
     memset(red,   cdRed(fg), size);
     memset(green, cdGreen(fg), size);
     memset(blue,  cdBlue(fg), size);
-    for (i = 0; i < height; i++)
+
+    if (fg_alpha == 255)
     {
-      memcpy(alpha,  bitmap_data, width);
-      alpha += width;
-      bitmap_data -= width;
+      /* alpha is the bitmap_data itself 
+         if the foreground color does not contains alpha.
+         Also must invert since it is top-down. */
+      for (i = 0; i < height; i++)
+      {
+        memcpy(alpha,  bitmap_data, width);
+        alpha += width;
+        bitmap_data -= width;
+      }
+    }
+    else
+    {
+      /* alpha is the bitmap_data itself 
+         if the foreground color does not contains alpha.
+         Also must invert since it is top-down. */
+      for (i = 0; i < height; i++)
+      {
+        for (j = 0; j < width; j++)
+        {
+          *alpha++ = (fg_alpha*bitmap_data[j])/255;
+        }
+
+        bitmap_data -= width;
+      }
     }
 
+    /* reset alpha pointer */
     alpha = blue + size;
+
+    /* draw the char */
     simulation->canvas->cxPutImageRectRGBA(simulation->canvas->ctxcanvas, width,height,red,green,blue,alpha,x,y,width,height,0,width-1,0,height-1);
   }
 
diff --git a/src/win32/cdwdbuf.c b/src/win32/cdwdbuf.c
index 035e29e..85af87c 100644
--- a/src/win32/cdwdbuf.c
+++ b/src/win32/cdwdbuf.c
@@ -44,12 +44,19 @@ static void cdflush(cdCtxCanvas *ctxcanvas)
 
 static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)
 {
+  int w, h;
   cdCtxCanvas* ctxcanvas;
   cdImage* image_dbuffer;
   cdCtxImage* ctximage;
 
+  cdCanvasActivate(canvas_dbuffer);
+  w = canvas_dbuffer->w;
+  h = canvas_dbuffer->h;
+  if (w==0) w=1;
+  if (h==0) h=1;
+
   /* this is done in the canvas_dbuffer context */
-  image_dbuffer = cdCanvasCreateImage(canvas_dbuffer, canvas_dbuffer->w, canvas_dbuffer->h);
+  image_dbuffer = cdCanvasCreateImage(canvas_dbuffer, w, h);
   if (!image_dbuffer) 
     return;
 
@@ -74,15 +81,20 @@ static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)
 
 static int cdactivate(cdCtxCanvas *ctxcanvas)
 {
+  int w, h;
   cdCanvas* canvas_dbuffer = ctxcanvas->canvas_dbuffer;
 
   /* this is done in the canvas_dbuffer context */
   /* this will update canvas size */
   cdCanvasActivate(canvas_dbuffer);
+  w = canvas_dbuffer->w;
+  h = canvas_dbuffer->h;
+  if (w==0) w=1;
+  if (h==0) h=1;
 
   /* check if the size changed */
-  if (canvas_dbuffer->w != ctxcanvas->image_dbuffer->w ||
-      canvas_dbuffer->h != ctxcanvas->image_dbuffer->h)
+  if (w != ctxcanvas->image_dbuffer->w ||
+      h != ctxcanvas->image_dbuffer->h)
   {
     cdCanvas* canvas = ctxcanvas->canvas;
     /* save the current, if the rebuild fail */
diff --git a/src/x11/cdxdbuf.c b/src/x11/cdxdbuf.c
index 1c92da5..835687c 100644
--- a/src/x11/cdxdbuf.c
+++ b/src/x11/cdxdbuf.c
@@ -41,12 +41,19 @@ static void cdflush(cdCtxCanvas* ctxcanvas)
 
 static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)
 {
+  int w, h;
   cdCtxCanvas* ctxcanvas;
   cdImage* image_dbuffer;
   cdCtxImage* ctximage;
 
+  cdCanvasActivate(canvas_dbuffer);
+  w = canvas_dbuffer->w;
+  h = canvas_dbuffer->h;
+  if (w==0) w=1;
+  if (h==0) h=1;
+
   /* this is done in the canvas_dbuffer context */
-  image_dbuffer = cdCanvasCreateImage(canvas_dbuffer, canvas_dbuffer->w, canvas_dbuffer->h);
+  image_dbuffer = cdCanvasCreateImage(canvas_dbuffer, w, h);
   if (!image_dbuffer) 
     return;
 
@@ -63,15 +70,20 @@ static void cdcreatecanvas(cdCanvas* canvas, cdCanvas* canvas_dbuffer)
 
 static int cdactivate(cdCtxCanvas* ctxcanvas)
 {
+  int w, h;
   cdCanvas* canvas_dbuffer = ctxcanvas->canvas_dbuffer;
 
   /* this is done in the canvas_dbuffer context */
   /* this will update canvas size */
   cdCanvasActivate(canvas_dbuffer);
+  w = canvas_dbuffer->w;
+  h = canvas_dbuffer->h;
+  if (w==0) w=1;
+  if (h==0) h=1;
 
   /* check if the size changed */
-  if (canvas_dbuffer->w != ctxcanvas->image_dbuffer->w ||
-      canvas_dbuffer->h != ctxcanvas->image_dbuffer->h)
+  if (w != ctxcanvas->image_dbuffer->w ||
+      h != ctxcanvas->image_dbuffer->h)
   {
     cdCanvas* canvas = ctxcanvas->canvas;
     /* save the current, if the rebuild fail */
-- 
cgit v1.2.3