13 public enum GradientDirection { vertical, horizontal };
15 public void PaletteGradient(ColorAlpha * palette, int numColors, ColorKey * keys, int numKeys, float smoothness)
17 ColorKey * key = keys, * nextKey = keys;
18 int keyNum = 0, nextKeyNum = 0;
19 float inc = 1.0f/(numColors-1);
25 for(c = start = 0; c<numColors; c++)
27 ColorAlpha newColor = 0;
29 while(nextKey && percent > nextKey->percent)
31 key = nextKey; keyNum = nextKeyNum;
33 if(keyNum < numKeys - 1)
36 nextKeyNum = keyNum + 1;
42 if(nextKey && nextKey->percent != key->percent)
44 float scale = ease((percent - key->percent) / (nextKey->percent - key->percent),
45 smoothness, smoothness);
46 int cr = key->color.color.r;
47 int cg = key->color.color.g;
48 int cb = key->color.color.b;
49 int nr = nextKey->color.color.r;
50 int ng = nextKey->color.color.g;
51 int nb = nextKey->color.color.b;
52 int r = (int)(cr + (nr - cr) * scale);
53 int g = (int)(cg + (ng - cg) * scale);
54 int b = (int)(cb + (nb - cb) * scale);
56 r = Max(Min(r, 255),0);
57 g = Max(Min(g, 255),0);
58 b = Max(Min(b, 255),0);
60 newColor = Color { (byte)r, (byte)g, (byte)b };
63 newColor = key ? key->color : 0;
65 if(c == 0 || newColor != color)
70 for(i = start; i<c; i++)
82 for(i = start; i<c; i++)
87 float ease(float t, float a, float b)
92 if (s == 0.0f) return t;
99 if (t < a) return (k/a)*t*t;
100 if (t < 1.0f - b) return k*(2.0f * t - a);
102 return 1.0f - (k/b)*t*t;
105 public enum AlphaWriteMode
114 public int width, height;
116 subclass(DisplayDriver) driver;
117 DisplaySystem displaySystem;
121 public Box box, unclippedBox;
125 ColorAlpha foreground, background;
127 public void * driverData;
128 AlphaWriteMode alphaWrite;
142 driver.ReleaseSurface(display, this);
146 property AlphaWriteMode alphaWrite
148 set { alphaWrite = value; }
149 get { return alphaWrite; }
153 set { blend = value; }
154 get { return blend; }
156 property Bitmap bitmap
160 return ((LFBSurface)driverData).bitmap;
164 ColorAlpha GetPixel(int x, int y)
166 return driver.GetPixel(display, this, x,y);
169 void PutPixel(int x, int y)
171 driver.PutPixel(display, this, x,y);
174 void DrawLine(int x1, int y1, int x2, int y2)
176 driver.DrawLine(display, this, x1,y1,x2,y2);
179 void VLine(int y1, int y2, int x)
181 driver.DrawLine(display, this, x,y1,x,y2);
184 void HLine(int x1, int x2, int y)
186 driver.DrawLine(display, this, x1,y,x2,y);
189 void Rectangle(int x1, int y1, int x2, int y2)
191 driver.Rectangle(display, this, x1,y1,x2,y2);
194 void Area(int x1, int y1, int x2, int y2)
196 driver.Area(display, this, x1,y1,x2,y2);
199 void Clear(ClearType type)
201 driver.Clear(display, this, type);
204 void Blit(Bitmap src, int dx, int dy, int sx, int sy, int w, int h)
206 if(src.driver == driver)
207 driver.Blit(display, this, src, dx,dy, sx, sy,w,h);
208 else if(!src.driver || src.driver == class(LFBDisplayDriver))
209 driver.BlitDI(display, this, src, dx,dy, sx, sy,w,h);
212 void Stretch(Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
214 if(src.driver == driver)
215 driver.Stretch(display, this, src, dx,dy, sx,sy, w,h, sw, sh);
216 else if(!src.driver || src.driver == class(LFBDisplayDriver))
217 driver.StretchDI(display, this, src, dx,dy, sx,sy, w,h, sw, sh);
220 void Filter(Bitmap src, int dx, int dy, int sx, int sy, int w, int h, int sw, int sh)
222 if(src.driver == driver)
223 driver.Filter(display, this, src, dx,dy, sx,sy, w,h, sw, sh);
224 else if(!src.driver || src.driver == class(LFBDisplayDriver))
225 driver.FilterDI(display, this, src, dx,dy, sx,sy, w,h, sw, sh);
228 void Tile(Bitmap src, int dx, int dy, int w, int h)
230 if(src && src.width && src.height)
233 for(x = 0,sx = dx; x < w; x += src.width, sx += src.width)
234 for(y = 0, sy = dy; y < h; y += src.height,sy += src.height)
235 Blit(src, sx, sy, 0,0, Min(src.width, w - x), Min(src.height, h - y));
239 void HTile(Bitmap src, int dx, int dy, int w, int h)
241 if(src && src.width && src.height)
244 for(x = 0, sx = dx; x < w; x += src.width, sx += src.width)
245 Stretch(src, sx, dy, 0, 0, Min(src.width, w - x), h, Min(src.width, w - x), src.height);
249 void VTile(Bitmap src, int dx, int dy, int w, int h)
251 if(src && src.width && src.height)
254 for(y = 0, sy = dy; y < h; y += src.height, sy += src.height)
255 Stretch(src, dx, sy, 0,0, w, Min(src.height, h - y), src.width, Min(src.height, h - y));
259 void FilterHTile(Bitmap src, int dx, int dy, int w, int h)
261 if(src && src.width && src.height)
264 for(x = 0, sx = dx; x < w; x += src.width, sx += src.width)
265 Filter(src, sx, dy, 0, 0, Min(src.width, w - x), h, Min(src.width, w - x), src.height);
269 void FilterVTile(Bitmap src, int dx, int dy, int w, int h)
271 if(src && src.width && src.height)
274 for(y = 0, sy = dy; y < h; y += src.height, sy += src.height)
275 Filter(src, dx, sy, 0,0, w, Min(src.height, h - y), src.width, Min(src.height, h - y));
279 void WriteText(int x, int y, char * text, int len)
282 driver.WriteText(display, this, x,y, text, len);
285 void TextExtent(char * text, int len, int * width, int * height)
287 driver.TextExtent(display, this, text, len, width, height);
290 void WriteTextf(int x, int y, char * format, ...)
294 char text[MAX_F_STRING];
296 va_start(args, format);
297 vsnprintf(text, sizeof(text), format, args);
298 text[sizeof(text)-1] = 0;
299 driver.WriteText(display, this, x,y, text, strlen(text));
304 void CenterTextf(int x, int y, char * format, ...)
308 char text[MAX_F_STRING];
312 va_start(args, format);
313 vsnprintf(text, sizeof(text), format, args);
314 text[sizeof(text)-1] = 0;
317 driver.TextExtent(display, this, text, len, &w, &h);
318 driver.WriteText(display, this, x - w/2, y, text, len);
323 void WriteTextDots(Alignment alignment, int x, int y, int width, char * text, int len)
327 TextExtent(text, len, &w, &h);
330 if(alignment == right)
332 else if(alignment == center)
333 x += (width - w) / 2;
334 WriteText(x, y, text, len);
345 TextExtent(".", 1, &dw, &dh);
347 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
348 for(c = 0; (ch = text[c]); c += nb)
350 nb = UTF8_NUM_BYTES(ch);
351 TextExtent(text+c, nb, &w, &h);
357 WriteText(x, y, text, c);
358 //TextExtent(text, c, &totalW, &h);
360 WriteText(x, y, "...", 3);
364 void WriteTextDotsf(Alignment alignment, int x, int y, int width, char * format, ...)
368 char text[MAX_F_STRING];
370 va_start(args, format);
371 vsnprintf(text, sizeof(text), format, args);
372 text[sizeof(text)-1] = 0;
373 WriteTextDots(alignment, x,y, width, text, strlen(text));
378 void Bevel(bool inner, int x, int y, int w, int h)
380 ColorAlpha foreground = this.foreground;
382 SetForeground(inner ? Color { 128,128,128 } : formColor);
383 HLine(x, x+w - 2, y);
384 VLine(y+1, y+h - 2, x);
386 SetForeground(inner ? Color { 64,64,64 } : white);
387 HLine(x+1, x+w-3, y+1);
388 VLine(y+2, y+h-3, x+1);
390 SetForeground(inner ? formColor : Color { 128,128,128 } );
391 HLine(x+1, x+w-2, y + h -2);
392 VLine(y+1, y+h-3, x + w - 2);
394 SetForeground(inner ? white : Color { 64,64,64 });
395 HLine(x, x+w-1, y + h - 1);
396 VLine(y, y+h-2, x + w - 1);
398 SetForeground(foreground);
401 void ThinBevel(bool inner, int x, int y, int w, int h)
403 SetForeground(inner ? Color { 128,128,128 } : white);
404 HLine(x, x+w - 2, y);
405 VLine(y+1, y+h - 2, x);
406 SetForeground(inner ? white : Color { 128,128,128 });
407 HLine(x, x+w-1, y + h - 1);
408 VLine(y, y+h-2, x + w - 1);
411 void Gradient(ColorKey * keys, int numKeys, float smoothness, GradientDirection direction, int x1, int y1, int x2, int y2)
413 if(x2 >= box.left && x1 <= box.right && y2 >= box.top && y1 <= box.bottom)
415 ColorKey * key = keys, * nextKey = keys;
416 int keyNum = 0, nextKeyNum = 0;
417 int height = (direction == horizontal) ? ((x2 - x1) + 1) : ((y2 - y1) + 1);
418 float inc = 1.0f/(height-1);
421 ColorAlpha color = 0;
422 int firstPixel = (direction == horizontal) ? x1 : y1;
423 int lastPixel = (direction == horizontal) ? x2 : y2;
424 int boxLeft = (direction == horizontal) ? box.left : box.top;
425 int boxRight = (direction == horizontal) ? box.right : box.bottom;
429 if(boxLeft > firstPixel)
431 percent = (boxLeft - firstPixel) * inc;
432 firstPixel = boxLeft;
434 if(boxRight < lastPixel)
435 lastPixel = boxRight;
437 for(c = start = firstPixel; c<=lastPixel; c++)
441 while(nextKey && percent > nextKey->percent)
443 key = nextKey; keyNum = nextKeyNum;
445 if(keyNum < numKeys - 1)
448 nextKeyNum = keyNum + 1;
454 if(nextKey && nextKey->percent != key->percent)
456 float scale = ease((percent - key->percent) / (nextKey->percent - key->percent),
457 smoothness, smoothness);
458 int cr = key->color.color.r;
459 int cg = key->color.color.g;
460 int cb = key->color.color.b;
461 int nr = nextKey->color.color.r;
462 int ng = nextKey->color.color.g;
463 int nb = nextKey->color.color.b;
464 int r = (int)(cr + (nr - cr) * scale);
465 int g = (int)(cg + (ng - cg) * scale);
466 int b = (int)(cb + (nb - cb) * scale);
468 r = Max(Min(r, 255),0);
469 g = Max(Min(g, 255),0);
470 b = Max(Min(b, 255),0);
472 newColor = Color { (byte)r, (byte)g, (byte)b };
475 newColor = key ? key->color : 0;
477 if(c == firstPixel || newColor != color)
481 SetBackground(color);
483 if(direction == horizontal)
484 Area(start,y1,c-1,y2);
486 Area(x1, start,x2, c-1);
494 SetBackground(color);
495 if(direction == horizontal)
496 Area(start,y1,c-1,y2);
498 Area(x1, start,x2, c-1);
503 property ColorAlpha foreground
508 driver.SetForeground(display, this, value);
510 get { return foreground; }
513 property ColorAlpha background
518 driver.SetBackground(display, this, value);
520 get { return background; }
523 property ColorAlpha blitTint
528 driver.SetBlitTint(display, this, value);
530 get { return blitTint; }
533 property uint lineStipple
537 driver.LineStipple(display, this, value);
543 get { value = { width, height }; }
551 if(display && display.flags.text)
553 value.left *= textCellW;
554 value.top *= textCellH;
555 value.right *= textCellW;
556 value.bottom *= textCellH;
561 property Display display
563 get { return display; }
570 if(value && font != value)
572 driver.TextFont(display, this, value);
580 property bool textOpacity
585 driver.TextOpacity(display, this, value);
588 get { return textOpacity; }
591 property byte drawingChar
593 set { driver.DrawingChar(display, this, value); }
596 property Box clipping
598 set { driver.Clip(display, this, value); }
601 // TODO: Make these functions obsolete
602 void SetForeground(ColorAlpha value)
605 driver.SetForeground(display, this, value);
608 void SetBackground(ColorAlpha value)
611 driver.SetBackground(display, this, value);
614 Color GetForeground(void)
619 Color GetBackground(void)
624 void LineStipple(uint value)
626 driver.LineStipple(display, this, value);
629 void GetSize(int * w, int * h)
635 void GetBox(Box value)
638 if(display.flags.text)
640 box.left *= textCellW;
641 box.top *= textCellH;
642 box.right *= textCellW;
643 box.bottom *= textCellH;
647 Display GetDisplay(void)
652 void TextFont(Font value)
654 if(value && font != value)
656 driver.TextFont(display, this, value);
666 bool GetTextOpacity(void)
671 void TextOpacity(bool value)
674 driver.TextOpacity(display, this, value);
677 void DrawingChar(unsigned char value)
679 driver.DrawingChar(display, this, value);
684 driver.Clip(display, this, box);