ecere/gfx/Surface: Fixed PaletteGradient() ignoring alpha
[sdk] / ecere / src / gfx / Surface.ec
index 5a6bb1c..bc13065 100644 (file)
@@ -19,7 +19,7 @@ public void PaletteGradient(ColorAlpha * palette, int numColors, ColorKey * keys
    float inc = 1.0f/(numColors-1);
    float percent = 0;
    int start;
-   ColorAlpha color;
+   ColorAlpha color = 0;
    int c;
 
    for(c = start = 0; c<numColors; c++)
@@ -28,12 +28,12 @@ public void PaletteGradient(ColorAlpha * palette, int numColors, ColorKey * keys
 
       while(nextKey && percent > nextKey->percent)
       {
-         key = nextKey; keyNum = nextKeyNum; 
-      
-         if(keyNum < numKeys - 1) 
-         { 
+         key = nextKey; keyNum = nextKeyNum;
+
+         if(keyNum < numKeys - 1)
+         {
             nextKey = key + 1;
-            nextKeyNum = keyNum + 1; 
+            nextKeyNum = keyNum + 1;
          }
          else
             break;
@@ -41,23 +41,27 @@ public void PaletteGradient(ColorAlpha * palette, int numColors, ColorKey * keys
 
       if(nextKey && nextKey->percent != key->percent)
       {
-         float scale = ease((percent - key->percent) / (nextKey->percent - key->percent), 
+         float scale = ease((percent - key->percent) / (nextKey->percent - key->percent),
             smoothness, smoothness);
+         int ca = key->color.a;
          int cr = key->color.color.r;
          int cg = key->color.color.g;
          int cb = key->color.color.b;
+         int na = nextKey->color.color.r;
          int nr = nextKey->color.color.r;
          int ng = nextKey->color.color.g;
          int nb = nextKey->color.color.b;
+         int a = (int)(ca + (na - ca) * scale);
          int r = (int)(cr + (nr - cr) * scale);
          int g = (int)(cg + (ng - cg) * scale);
          int b = (int)(cb + (nb - cb) * scale);
 
+         a = Max(Min(r, 255),0);
          r = Max(Min(r, 255),0);
          g = Max(Min(g, 255),0);
          b = Max(Min(b, 255),0);
 
-         newColor = Color { (byte)r, (byte)g, (byte)b };
+         newColor = ColorAlpha { (byte)a, { (byte)r, (byte)g, (byte)b } };
       }
       else if(key)
          newColor = key ? key->color : 0;
@@ -84,13 +88,13 @@ public void PaletteGradient(ColorAlpha * palette, int numColors, ColorKey * keys
    }
 }
 
-float ease(float t, float a, float b) 
+float ease(float t, float a, float b)
 {
    float k;
    float s = a + b;
 
    if (s == 0.0f) return t;
-   if (s > 1.0f) 
+   if (s > 1.0f)
    {
       a /= s;
       b /= s;
@@ -111,30 +115,34 @@ public enum AlphaWriteMode
 
 public class Surface
 {
-   public int width, height;
+public:
+   int width, height;
+   Point offset;
+   Box box, unclippedBox;
+   void * driverData;
 
+private:
    subclass(DisplayDriver) driver;
    DisplaySystem displaySystem;
    Display display;
 
-   public Point offset;
-   public Box box, unclippedBox;
 
    // States
    Font font;
    ColorAlpha foreground, background;
    bool textOpacity;
-   public void * driverData;
    AlphaWriteMode alphaWrite;
    bool blend;
    bool writeColor;
    ColorAlpha blitTint;
+   ColorAlpha outlineColor;
 
    blitTint = white;
 
    blend = true;
    writeColor = true;
    alphaWrite = blend;
+   outlineColor = black;
 
    ~Surface()
    {
@@ -158,7 +166,12 @@ public:
       get
       {
          return ((LFBSurface)driverData).bitmap;
-      }     
+      }
+   }
+   property ColorAlpha outlineColor
+   {
+      set { outlineColor = value; }
+      get { return outlineColor; }
    }
 
    ColorAlpha GetPixel(int x, int y)
@@ -276,50 +289,67 @@ public:
       }
    }
 
-   void WriteText(int x, int y, char * text, int len)
+   void WriteText(int x, int y, const char * text, int len)
+   {
+      if(text)
+         driver.WriteText(display, this, x,y, text, len, 0, null); //, null);
+   }
+
+   void WriteText2(int x, int y, const char * text, int len, int prevGlyph, int * rPrevGlyph)
    {
       if(text)
-         driver.WriteText(display, this, x,y, text, len);
+         driver.WriteText(display, this, x,y, text, len, prevGlyph, rPrevGlyph);
+   }
+
+   void TextExtent(const char * text, int len, int * width, int * height)
+   {
+      int advance = 0;
+      driver.TextExtent(display, this, text, len, width, height, 0, null, &advance);
+      if(width)
+         *width += advance;
    }
 
-   void TextExtent(char * text, int len, int * width, int * height)
+   void TextExtent2(const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * overHang)
    {
-      driver.TextExtent(display, this, text, len, width, height);
+      driver.TextExtent(display, this, text, len, width, height, prevGlyph, rPrevGlyph, overHang);
    }
 
-   void WriteTextf(int x, int y, char * format, ...)
+   void WriteTextf(int x, int y, const char * format, ...)
    {
       if(format)
       {
          char text[MAX_F_STRING];
          va_list args;
          va_start(args, format);
-         vsprintf(text, format, args);
-         driver.WriteText(display, this, x,y, text, strlen(text));
+         vsnprintf(text, sizeof(text), format, args);
+         text[sizeof(text)-1] = 0;
+         if(driver)
+            driver.WriteText(display, this, x,y, text, strlen(text), 0, null);
          va_end(args);
       }
    }
 
-   void CenterTextf(int x, int y, char * format, ...)
+   void CenterTextf(int x, int y, const char * format, ...)
    {
       if(format)
       {
          char text[MAX_F_STRING];
          va_list args;
          int len;
-         int w, h;
-
+         int w, h, oh;
          va_start(args, format);
-         vsprintf(text, format, args);
+         vsnprintf(text, sizeof(text), format, args);
+         text[sizeof(text)-1] = 0;
          len = strlen(text);
 
-         driver.TextExtent(display, this, text, len, &w, &h);
-         driver.WriteText(display, this, x - w/2, y, text, len);
+         driver.TextExtent(display, this, text, len, &w, &h, 0, null, &oh);
+         w += oh;
+         driver.WriteText(display, this, x - w/2, y, text, len, 0, null);
          va_end(args);
       }
    }
 
-   void WriteTextDots(Alignment alignment, int x, int y, int width, char * text, int len)
+   void WriteTextDots(Alignment alignment, int x, int y, int width, const char * text, int len)
    {
       int w, h;
 
@@ -360,19 +390,20 @@ public:
       }
    }
 
-   void WriteTextDotsf(Alignment alignment, int x, int y, int width, char * format, ...)
+   void WriteTextDotsf(Alignment alignment, int x, int y, int width, const char * format, ...)
    {
       if(format)
       {
          char text[MAX_F_STRING];
          va_list args;
          va_start(args, format);
-         vsprintf(text, format, args);
+         vsnprintf(text, sizeof(text), format, args);
+         text[sizeof(text)-1] = 0;
          WriteTextDots(alignment, x,y, width, text, strlen(text));
          va_end(args);
       }
    }
-   
+
    void Bevel(bool inner, int x, int y, int w, int h)
    {
       ColorAlpha foreground = this.foreground;
@@ -416,7 +447,7 @@ public:
          float inc = 1.0f/(height-1);
          float percent = 0;
          int start;
-         ColorAlpha color;
+         ColorAlpha color = 0;
          int firstPixel = (direction == horizontal) ? x1 : y1;
          int lastPixel = (direction == horizontal) ? x2 : y2;
          int boxLeft = (direction == horizontal) ? box.left : box.top;
@@ -427,7 +458,7 @@ public:
          if(boxLeft > firstPixel)
          {
             percent = (boxLeft - firstPixel) * inc;
-            firstPixel = boxLeft;            
+            firstPixel = boxLeft;
          }
          if(boxRight < lastPixel)
             lastPixel = boxRight;
@@ -438,12 +469,12 @@ public:
 
             while(nextKey && percent > nextKey->percent)
             {
-               key = nextKey; keyNum = nextKeyNum; 
-            
-               if(keyNum < numKeys - 1) 
-               { 
+               key = nextKey; keyNum = nextKeyNum;
+
+               if(keyNum < numKeys - 1)
+               {
                   nextKey = key + 1;
-                  nextKeyNum = keyNum + 1; 
+                  nextKeyNum = keyNum + 1;
                }
                else
                   break;
@@ -451,7 +482,7 @@ public:
 
             if(nextKey && nextKey->percent != key->percent)
             {
-               float scale = ease((percent - key->percent) / (nextKey->percent - key->percent), 
+               float scale = ease((percent - key->percent) / (nextKey->percent - key->percent),
                   smoothness, smoothness);
                int cr = key->color.color.r;
                int cg = key->color.color.g;