Merge pull request #110 from tesselode/fixes
[wdl/wdl-ol.git] / WDL / swell / swell-gdi-generic.cpp
blob0c9b73b48d20ff9aa39b3ec8b07703dd4ebc8551
1 /* Cockos SWELL (Simple/Small Win32 Emulation Layer for Linux/OSX)
2 Copyright (C) 2006 and later, Cockos, Inc.
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
21 This file provides basic win32 GDI--> null translation.
25 #ifndef SWELL_PROVIDED_BY_APP
27 #include "swell.h"
28 #include "swell-internal.h"
29 #include "../wdlcstring.h"
31 const char *g_swell_deffont_face = "Arial";
33 swell_colortheme g_swell_ctheme = {
34 #define __def_theme_ent(x,c) (c),
35 #define __def_theme_ent_fb(x,c,fb) (c),
36 SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
37 #undef __def_theme_ent
38 #undef __def_theme_ent_fb
41 int GetSysColor(int idx)
43 switch (idx)
45 case COLOR_WINDOW:
46 case COLOR_3DFACE:
47 case COLOR_BTNFACE: return g_swell_ctheme._3dface;
48 case COLOR_3DSHADOW: return g_swell_ctheme._3dshadow;
49 case COLOR_3DHILIGHT: return g_swell_ctheme._3dhilight;
50 case COLOR_3DDKSHADOW: return g_swell_ctheme._3ddkshadow;
51 case COLOR_BTNTEXT: return g_swell_ctheme.button_text;
52 case COLOR_INFOBK: return g_swell_ctheme.info_bk;
53 case COLOR_INFOTEXT: return g_swell_ctheme.info_text;
54 case COLOR_SCROLLBAR: return g_swell_ctheme.scrollbar;
56 return 0;
59 int g_swell_ui_scale = 256;
61 int SWELL_GetScaling256(void)
63 return g_swell_ui_scale;
66 #ifndef SWELL_LICE_GDI
68 #include "../mutex.h"
69 #include "../ptrlist.h"
71 #include "swell-gdi-internalpool.h"
73 HDC SWELL_CreateGfxContext(void *c)
75 HDC__ *ctx=SWELL_GDP_CTX_NEW();
78 return ctx;
81 HDC SWELL_CreateMemContext(HDC hdc, int w, int h)
83 // we could use CGLayer here, but it's 10.4+ and seems to be slower than this
84 // if (w&1) w++;
85 void *buf=calloc(w*4,h);
86 if (!buf) return 0;
88 HDC__ *ctx=SWELL_GDP_CTX_NEW();
89 ctx->ownedData=buf;
91 SetTextColor(ctx,0);
92 return ctx;
96 void SWELL_DeleteGfxContext(HDC ctx)
98 HDC__ *ct=(HDC__ *)ctx;
99 if (HDC_VALID(ct))
101 if (ct->ownedData)
103 free(ct->ownedData);
105 SWELL_GDP_CTX_DELETE(ct);
108 HPEN CreatePen(int attr, int wid, int col)
110 return CreatePenAlpha(attr,wid,col,1.0f);
113 HBRUSH CreateSolidBrush(int col)
115 return CreateSolidBrushAlpha(col,1.0f);
118 HPEN CreatePenAlpha(int attr, int wid, int col, float alpha)
120 HGDIOBJ__ *pen=GDP_OBJECT_NEW();
121 pen->type=TYPE_PEN;
122 pen->wid=wid<0?0:wid;
123 // pen->color=CreateColor(col,alpha);
124 return pen;
126 HBRUSH CreateSolidBrushAlpha(int col, float alpha)
128 HGDIOBJ__ *brush=GDP_OBJECT_NEW();
129 brush->type=TYPE_BRUSH;
130 // brush->color=CreateColor(col,alpha);
131 brush->wid=0;
132 return brush;
135 #define FONTSCALE 0.9
136 HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic,
137 char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision,
138 char lfQuality, char lfPitchAndFamily, const char *lfFaceName)
140 HGDIOBJ__ *font=GDP_OBJECT_NEW();
141 font->type=TYPE_FONT;
142 float fontwid=lfHeight;
145 if (!fontwid) fontwid=lfWidth;
146 if (fontwid<0)fontwid=-fontwid;
148 if (fontwid < 2 || fontwid > 8192) fontwid=10;
150 return font;
154 HFONT CreateFontIndirect(LOGFONT *lf)
156 return CreateFont(lf->lfHeight, lf->lfWidth,lf->lfEscapement, lf->lfOrientation, lf->lfWeight, lf->lfItalic,
157 lf->lfUnderline, lf->lfStrikeOut, lf->lfCharSet, lf->lfOutPrecision,lf->lfClipPrecision,
158 lf->lfQuality, lf->lfPitchAndFamily, lf->lfFaceName);
161 int GetTextFace(HDC ctx, int nCount, LPTSTR lpFaceName)
163 if (lpFaceName) lpFaceName[0]=0;
164 return 0;
167 void DeleteObject(HGDIOBJ pen)
169 if (HGDIOBJ_VALID(pen))
171 HGDIOBJ__ *p=(HGDIOBJ__ *)pen;
172 if (--p->additional_refcnt < 0)
174 if (p->type == TYPE_PEN || p->type == TYPE_BRUSH || p->type == TYPE_FONT || p->type == TYPE_BITMAP)
176 if (p->type == TYPE_PEN || p->type == TYPE_BRUSH)
177 if (p->wid<0) return;
179 GDP_OBJECT_DELETE(p);
181 // JF> don't free unknown objects, this should never happen anyway: else free(p);
187 HGDIOBJ SelectObject(HDC ctx, HGDIOBJ pen)
189 HDC__ *c=(HDC__ *)ctx;
190 HGDIOBJ__ *p=(HGDIOBJ__ *) pen;
191 HGDIOBJ__ **mod=0;
192 if (!HDC_VALID(c)||!p) return 0;
194 if (p == (HGDIOBJ__ *)TYPE_PEN) mod=&c->curpen;
195 else if (p == (HGDIOBJ__ *)TYPE_BRUSH) mod=&c->curbrush;
196 else if (p == (HGDIOBJ__ *)TYPE_FONT) mod=&c->curfont;
198 if (mod)
200 HGDIOBJ__ *np=*mod;
201 *mod=0;
202 return np?np:p;
205 if (!HGDIOBJ_VALID(p)) return 0;
207 if (p->type == TYPE_PEN) mod=&c->curpen;
208 else if (p->type == TYPE_BRUSH) mod=&c->curbrush;
209 else if (p->type == TYPE_FONT) mod=&c->curfont;
210 else return 0;
212 HGDIOBJ__ *op=*mod;
213 if (!op) op=(HGDIOBJ__ *)(INT_PTR)p->type;
214 if (op != p)
216 *mod=p;
218 if (p->type == TYPE_FONT)
222 return op;
227 void SWELL_FillRect(HDC ctx, const RECT *r, HBRUSH br)
229 HDC__ *c=(HDC__ *)ctx;
230 HGDIOBJ__ *b=(HGDIOBJ__ *) br;
231 if (!HDC_VALID(c) || !HGDIOBJ_VALID(b,TYPE_BRUSH)) return;
233 if (b->wid<0) return;
238 void RoundRect(HDC ctx, int x, int y, int x2, int y2, int xrnd, int yrnd)
240 xrnd/=3;
241 yrnd/=3;
242 POINT pts[10]={ // todo: curves between edges
243 {x,y+yrnd},
244 {x+xrnd,y},
245 {x2-xrnd,y},
246 {x2,y+yrnd},
247 {x2,y2-yrnd},
248 {x2-xrnd,y2},
249 {x+xrnd,y2},
250 {x,y2-yrnd},
251 {x,y+yrnd},
252 {x+xrnd,y},
255 WDL_GDP_Polygon(ctx,pts,sizeof(pts)/sizeof(pts[0]));
258 void Ellipse(HDC ctx, int l, int t, int r, int b)
260 HDC__ *c=(HDC__ *)ctx;
261 if (!HDC_VALID(c)) return;
263 //CGRect rect=CGRectMake(l,t,r-l,b-t);
265 if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >=0)
268 if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0)
273 void Rectangle(HDC ctx, int l, int t, int r, int b)
275 HDC__ *c=(HDC__ *)ctx;
276 if (!HDC_VALID(c)) return;
278 if (HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH) && c->curbrush->wid >= 0)
281 if (HGDIOBJ_VALID(c->curpen,TYPE_PEN) && c->curpen->wid >= 0)
286 HGDIOBJ GetStockObject(int wh)
288 switch (wh)
290 case NULL_BRUSH:
292 static HGDIOBJ__ br={0,};
293 br.type=TYPE_BRUSH;
294 br.wid=-1;
295 return &br;
297 case NULL_PEN:
299 static HGDIOBJ__ pen={0,};
300 pen.type=TYPE_PEN;
301 pen.wid=-1;
302 return &pen;
305 return 0;
308 void Polygon(HDC ctx, POINT *pts, int npts)
310 HDC__ *c=(HDC__ *)ctx;
311 if (!HDC_VALID(c)) return;
312 if (((!HGDIOBJ_VALID(c->curbrush,TYPE_BRUSH)||c->curbrush->wid<0) &&
313 (!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0)) || npts<2) return;
317 void MoveToEx(HDC ctx, int x, int y, POINT *op)
319 HDC__ *c=(HDC__ *)ctx;
320 if (!HDC_VALID(c)) return;
321 if (op)
323 op->x = (int) (c->lastpos_x);
324 op->y = (int) (c->lastpos_y);
326 c->lastpos_x=(float)x;
327 c->lastpos_y=(float)y;
330 void PolyBezierTo(HDC ctx, POINT *pts, int np)
332 HDC__ *c=(HDC__ *)ctx;
333 if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||np<3) return;
335 int x;
336 float xp,yp;
337 for (x = 0; x < np-2; x += 3)
339 xp=(float)pts[x+2].x;
340 yp=(float)pts[x+2].y;
342 c->lastpos_x=(float)xp;
343 c->lastpos_y=(float)yp;
347 void SWELL_LineTo(HDC ctx, int x, int y)
349 HDC__ *c=(HDC__ *)ctx;
350 if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0) return;
352 float fx=(float)x,fy=(float)y;
354 c->lastpos_x=fx;
355 c->lastpos_y=fy;
358 void PolyPolyline(HDC ctx, POINT *pts, DWORD *cnts, int nseg)
360 HDC__ *c=(HDC__ *)ctx;
361 if (!HDC_VALID(c)||!HGDIOBJ_VALID(c->curpen,TYPE_PEN)||c->curpen->wid<0||nseg<1) return;
363 while (nseg-->0)
365 DWORD cnt=*cnts++;
366 if (!cnt) continue;
367 if (!--cnt) { pts++; continue; }
369 pts++;
371 while (cnt--)
373 pts++;
377 void *SWELL_GetCtxGC(HDC ctx)
379 HDC__ *ct=(HDC__ *)ctx;
380 if (!HDC_VALID(ct)) return 0;
381 return NULL;
385 void SWELL_SetPixel(HDC ctx, int x, int y, int c)
387 HDC__ *ct=(HDC__ *)ctx;
388 if (!HDC_VALID(ct)) return;
392 BOOL GetTextMetrics(HDC ctx, TEXTMETRIC *tm)
394 HDC__ *ct=(HDC__ *)ctx;
395 if (tm) // give some sane defaults
397 tm->tmInternalLeading=3;
398 tm->tmAscent=12;
399 tm->tmDescent=4;
400 tm->tmHeight=16;
401 tm->tmAveCharWidth = 10;
403 if (!HDC_VALID(ct)||!tm) return 0;
405 return 1;
409 int DrawText(HDC ctx, const char *buf, int buflen, RECT *r, int align)
411 HDC__ *ct=(HDC__ *)ctx;
412 if (!HDC_VALID(ct)) return 0;
413 if (r && (align&DT_CALCRECT))
415 r->top=r->left=0;
416 r->bottom=10;
417 r->right = ( buflen < 0 ? strlen(buf) : buflen ) *8;
419 else printf("DrawText: %s\n",buf);
420 return 10;
423 void SetBkColor(HDC ctx, int col)
425 HDC__ *ct=(HDC__ *)ctx;
426 if (!HDC_VALID(ct)) return;
427 ct->curbkcol=col;
430 void SetBkMode(HDC ctx, int col)
432 HDC__ *ct=(HDC__ *)ctx;
433 if (!HDC_VALID(ct)) return;
434 ct->curbkmode=col;
436 int GetTextColor(HDC ctx)
438 HDC__ *ct=(HDC__ *)ctx;
439 if (!HDC_VALID(ct)) return -1;
440 return ct->cur_text_color_int;
443 void SetTextColor(HDC ctx, int col)
445 HDC__ *ct=(HDC__ *)ctx;
446 if (!HDC_VALID(ct)) return;
447 ct->cur_text_color_int = col;
451 HICON LoadNamedImage(const char *name, bool alphaFromMask)
453 return 0; // todo
456 void DrawImageInRect(HDC ctx, HICON img, const RECT *r)
458 // todo
462 BOOL GetObject(HICON icon, int bmsz, void *_bm)
464 memset(_bm,0,bmsz);
465 if (bmsz != sizeof(BITMAP)) return false;
466 HGDIOBJ__ *i = (HGDIOBJ__ *)icon;
467 if (!HGDIOBJ_VALID(i,TYPE_BITMAP)) return false;
468 //BITMAP *bm=(BITMAP *)_bm;
470 return false;
473 void BitBltAlphaFromMem(HDC hdcOut, int x, int y, int w, int h, void *inbufptr, int inbuf_span, int inbuf_h, int xin, int yin, int mode, bool useAlphaChannel, float opacity)
477 void BitBltAlpha(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode, bool useAlphaChannel, float opacity)
481 void BitBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int mode)
485 void StretchBlt(HDC hdcOut, int x, int y, int w, int h, HDC hdcIn, int xin, int yin, int srcw, int srch, int mode)
489 void StretchBltFromMem(HDC hdcOut, int x, int y, int w, int h, const void *bits, int srcw, int srch, int srcspan)
493 void SWELL_PushClipRegion(HDC ctx)
495 // HDC__ *ct=(HDC__ *)ctx;
498 void SWELL_SetClipRegion(HDC ctx, const RECT *r)
500 // HDC__ *ct=(HDC__ *)ctx;
504 void SWELL_PopClipRegion(HDC ctx)
506 // HDC__ *ct=(HDC__ *)ctx;
509 void *SWELL_GetCtxFrameBuffer(HDC ctx)
511 HDC__ *ct=(HDC__ *)ctx;
512 if (HDC_VALID(ct)) return ct->ownedData;
513 return 0;
517 HDC GetDC(HWND h)
519 return NULL;
522 HDC GetWindowDC(HWND h)
524 return NULL;
527 void ReleaseDC(HWND h, HDC hdc)
531 void SWELL_FillDialogBackground(HDC hdc, const RECT *r, int level)
535 HGDIOBJ SWELL_CloneGDIObject(HGDIOBJ a)
537 if (HGDIOBJ_VALID(a))
539 a->additional_refcnt++;
540 return a;
542 return NULL;
545 HDC BeginPaint(HWND hwnd, PAINTSTRUCT *ps)
547 if (!ps) return 0;
548 memset(ps,0,sizeof(PAINTSTRUCT));
549 if (!hwnd) return 0;
551 return NULL;
555 HBITMAP CreateBitmap(int width, int height, int numplanes, int bitsperpixel, unsigned char* bits)
557 return NULL;
560 HICON CreateIconIndirect(ICONINFO* iconinfo)
562 return NULL;
564 HIMAGELIST ImageList_CreateEx()
566 return (HIMAGELIST)new WDL_PtrList<HGDIOBJ__>;
568 BOOL ImageList_Remove(HIMAGELIST list, int idx)
570 WDL_PtrList<HGDIOBJ__>* imglist=(WDL_PtrList<HGDIOBJ__>*)list;
571 if (imglist && idx < imglist->GetSize())
573 if (idx < 0)
575 int x,n=imglist->GetSize();
576 for (x=0;x<n;x++)
578 HGDIOBJ__ *a = imglist->Get(x);
579 if (a) DeleteObject(a);
581 imglist->Empty();
583 else
585 HGDIOBJ__ *a = imglist->Get(idx);
586 imglist->Set(idx, NULL);
587 if (a) DeleteObject(a);
589 return TRUE;
592 return FALSE;
595 void ImageList_Destroy(HIMAGELIST list)
597 if (!list) return;
598 WDL_PtrList<HGDIOBJ__> *p=(WDL_PtrList<HGDIOBJ__>*)list;
599 ImageList_Remove(list,-1);
600 delete p;
603 int ImageList_ReplaceIcon(HIMAGELIST list, int offset, HICON image)
605 if (!image || !list) return -1;
606 WDL_PtrList<HGDIOBJ__> *l=(WDL_PtrList<HGDIOBJ__> *)list;
608 HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image;
609 if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1;
611 HGDIOBJ__* icon=GDP_OBJECT_NEW();
612 icon->type=TYPE_BITMAP;
613 icon->wid=1;
614 // todo: copy underlying image
616 image = (HICON) icon;
618 if (offset<0||offset>=l->GetSize())
620 l->Add(image);
621 offset=l->GetSize()-1;
623 else
625 HICON old=l->Get(offset);
626 l->Set(offset,image);
627 if (old) DeleteObject(old);
629 return offset;
632 int ImageList_Add(HIMAGELIST list, HBITMAP image, HBITMAP mask)
634 if (!image || !list) return -1;
635 WDL_PtrList<HGDIOBJ__> *l=(WDL_PtrList<HGDIOBJ__> *)list;
637 HGDIOBJ__ *imgsrc = (HGDIOBJ__*)image;
638 if (!HGDIOBJ_VALID(imgsrc,TYPE_BITMAP)) return -1;
640 HGDIOBJ__* icon=GDP_OBJECT_NEW();
641 icon->type=TYPE_BITMAP;
642 icon->wid=1;
643 // todo: copy underlying image
645 image = (HICON) icon;
647 l->Add(image);
648 return l->GetSize();
652 int AddFontResourceEx(LPCTSTR str, DWORD fl, void *pdv)
654 return 0;
657 int GetGlyphIndicesW(HDC ctx, wchar_t *buf, int len, unsigned short *indices, int flags)
659 int i;
660 for (i=0; i < len; ++i) indices[i]=(flags == GGI_MARK_NONEXISTING_GLYPHS ? 0xFFFF : 0);
661 return 0;
664 #endif // !SWELL_LICE_GDI
666 #ifdef SWELL__MAKE_THEME
667 void print_ent(const char *x, int c, const char *def)
669 if (def)
670 printf("; %s #%02x%02x%02x ; defaults to %s\n",x,GetRValue(c),GetGValue(c),GetBValue(c),def);
671 else
673 if (strstr(x,"_size") ||
674 strstr(x,"_height") ||
675 strstr(x,"_width"))
676 printf("%s %d\n",x,c);
677 else printf("%s #%02x%02x%02x\n",x,GetRValue(c),GetGValue(c),GetBValue(c));
681 int main()
683 #define __def_theme_ent(x,c) print_ent(#x,c,NULL);
684 #define __def_theme_ent_fb(x,c,fb) print_ent(#x,c,#fb);
686 printf("default_font_face %s\n",g_swell_deffont_face);
687 SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
688 return 0;
690 #else
692 // load color theme
693 class swellColorThemeLoader
695 public:
696 swellColorThemeLoader()
698 char buf[1024];
699 GetModuleFileName(NULL,buf,sizeof(buf));
700 WDL_remove_filepart(buf);
701 lstrcatn(buf,"/libSwell.colortheme",sizeof(buf));
702 FILE *fp = fopen(buf,"r");
703 if (!fp) return;
705 swell_colortheme load;
706 memset(&load,-1,sizeof(load));
708 for (;;)
710 if (!fgets(buf,sizeof(buf),fp)) break;
711 char *p = buf;
712 while (*p == ' ' || *p == '\t') p++;
713 char *np = p;
714 while (*np > 0 && (*np == '_' || isalnum(*np))) np++;
715 if (!*np || np == p) continue;
716 *np++ = 0;
717 while (*np == ' ' || *np == '\t') np++;
719 if(!stricmp(p,"default_font_face"))
721 if (*np > 0 && !isspace(*np))
723 char *b = strdup(np);
724 g_swell_deffont_face = b;
725 while (*b>0 && !isspace(*b)) b++;
726 *b=0;
728 continue;
731 int col;
732 if (*np == '#')
734 np++;
735 char *next;
736 col = strtol(np,&next,16);
737 if (next != np+6)
739 if (next != np+3) continue;
740 col = ((col&0xf)<<4) | ((col&0xf0)<<8) | ((col&0xf00)<<12);
743 else if (*np >= '0' && *np <= '9')
745 col = atoi(np);
747 else continue;
749 if(0){}
750 #define __def_theme_ent(x,c) else if (!stricmp(p,#x)) load.x = col;
751 #define __def_theme_ent_fb(x,c,fb) else if (!stricmp(p,#x)) load.x = col;
752 SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
753 #undef __def_theme_ent
754 #undef __def_theme_ent_fb
756 #define __def_theme_ent(x,c) g_swell_ctheme.x = load.x == -1 ? c : load.x;
757 #define __def_theme_ent_fb(x,c,fb) g_swell_ctheme.x = load.x == -1 ? g_swell_ctheme.fb : load.x;
758 SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb)
759 #undef __def_theme_ent
760 #undef __def_theme_ent_fb
762 fclose(fp);
765 swellColorThemeLoader g_swell_themeloader;
769 #endif
771 #endif