Initial community commit

This commit is contained in:
Jef 2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit fc06254474
16440 changed files with 4239995 additions and 2 deletions

View file

@ -0,0 +1,295 @@
#include "bltcanvas.h"
#include <tataki/bitmap/bitmap.h>
BltCanvas::~BltCanvas()
{
if (hdc == NULL) return ;
// kill the bitmap and its DC
SelectObject(hdc, prevbmp);
if (ourbmp)
{
//GdiFlush();
DeleteObject(hbmp);
}
DeleteDC(hdc);
hdc = NULL;
if (skinbmps)
{
for (int i=0;i<skinbmps->getNumItems();i++)
skinbmps->enumItem(i)->Release();
delete skinbmps;
}
if (envelope)
envelope->Release();
}
BltCanvas::BltCanvas(HBITMAP bmp)
{
prevbmp = NULL;
bits = NULL;
fcoord = TRUE;
ourbmp = FALSE;
skinbmps = NULL;
envelope = NULL;
hbmp = bmp;
ASSERT(hbmp != NULL);
// create tha DC
hdc = CreateCompatibleDC(NULL);
prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
}
BltCanvas::BltCanvas()
{
hbmp = NULL;
prevbmp = NULL;
bits = NULL;
fcoord = TRUE;
ourbmp = FALSE;
bpp = 32; // TODO: benski> pass as parameter?
skinbmps = NULL;
envelope = NULL;
hdc = CreateCompatibleDC(NULL);
}
BltCanvas::BltCanvas(int w, int h, HWND wnd, int nb_bpp/*, unsigned char *pal, int palsize*/)
{
hbmp = NULL;
prevbmp = NULL;
bits = NULL;
fcoord = TRUE;
ourbmp = FALSE;
bpp = nb_bpp;
skinbmps = NULL;
envelope = NULL;
hdc = CreateCompatibleDC(NULL);
AllocBitmap(w,h,nb_bpp);
if (hbmp)
{
// create tha DC
if (!hdc) {
// int x = GetLastError();
}
prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
}
}
void BltCanvas::AllocBitmap(int w, int h, int nb_bpp)
{
ASSERT(!hbmp);
ASSERT(w != 0 && h != 0);
if (w == 0) w = 1;
if (h == 0) h = 1;
BITMAPINFO bmi;
MEMZERO(&bmi, sizeof(BITMAPINFO));
//bmi.bmiHeader.biClrUsed = 0; // we memzero above, no need
//bmi.bmiHeader.biClrImportant = 0; // we memzero above, no need
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = ABS(w);
bmi.bmiHeader.biHeight = -ABS(h);
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = nb_bpp;
bmi.bmiHeader.biCompression = BI_RGB;
//bmi.bmiHeader.biSizeImage = 0; // we memzero above, no need
//bmi.bmiHeader.biXPelsPerMeter = 0; // we memzero above, no need
//bmi.bmiHeader.biYPelsPerMeter = 0; // we memzero above, no need
//GdiFlush();
hbmp = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &bits, NULL, 0);
if (hbmp == NULL)
{
return ;
}
ourbmp=TRUE;
GetObject(hbmp, sizeof(BITMAP), &bm);
width = bm.bmWidth;
height = ABS(bm.bmHeight);
pitch = bm.bmWidthBytes;
}
void *BltCanvas::getBits()
{
return bits;
}
HBITMAP BltCanvas::getBitmap()
{
return hbmp;
}
SkinBitmap *BltCanvas::getSkinBitmap()
{
// make a SkinBitmap envelope
if (!envelope)
envelope = new SkinBitmap(getBitmap(), getHDC(), 1, getBits());
// do not delete envelope, it's deleted in destructor
return envelope;
}
SkinBitmap *BltCanvas::makeSkinBitmap()
{
// make a clone of the bitmap - JF> what was that crap about envelopes?
SkinBitmap *clone = new SkinBitmap(getBitmap(), getHDC(), 1);
if (!skinbmps)
skinbmps = new PtrList<SkinBitmap>;
skinbmps->addItem(clone);
return clone;
}
void BltCanvas::disposeSkinBitmap(SkinBitmap *b)
{
if (skinbmps->haveItem(b))
{
skinbmps->removeItem(b);
b->Release();
}
else
{
DebugString("disposeSkinBitmap called on unknown pointer, you should call it from the object used to makeSkinBitmap()\n");
}
}
void BltCanvas::fillBits(COLORREF color)
{
if (bpp == 32)
{ // clear out the bits
DWORD *dwbits = (DWORD *)bits;
MEMFILL<DWORD>(dwbits, color, bm.bmWidth * bm.bmHeight);
}
}
void BltCanvas::vflip(int vert_cells)
{
ASSERT(bits != NULL);
// BITMAP bm;
// int r = GetObject(hbmp, sizeof(BITMAP), &bm);
// if (r == 0) return;
int w = bm.bmWidth, h = bm.bmHeight;
int bytes = 4 * w;
__int8 *tmpbuf = (__int8 *)MALLOC(bytes);
if (tmpbuf)
{
int cell_h = h / vert_cells;
for (int j = 0; j < vert_cells; j++)
for (int i = 0; i < cell_h / 2; i++)
{
char *p1, *p2;
p1 = (__int8 *)bits + bytes * i + (j * cell_h * bytes);
p2 = (__int8 *)bits + bytes * ((cell_h - 1) - i) + (j * cell_h * bytes);
if (p1 == p2) continue;
MEMCPY(tmpbuf, p1, bytes);
MEMCPY(p1, p2, bytes);
MEMCPY(p2, tmpbuf, bytes);
}
FREE(tmpbuf);
}
}
void BltCanvas::hflip(int hor_cells)
{
ASSERT(bits != NULL);
// todo: optimize
int w = bm.bmWidth, h = bm.bmHeight;
for (int i = 0;i < hor_cells;i++)
for (int x = 0;x < w / 2 / hor_cells;x++)
for (int y = 0;y < h;y++)
{
int *p = ((int *)bits) + x + y * w + (i * w / hor_cells);
int *d = ((int *)bits) + ((w / hor_cells) - x) + y * w + (i * w / hor_cells) - 1;
int t = *p;
*p = *d;
*d = t;
}
}
void BltCanvas::maskColor(COLORREF from, COLORREF to)
{
int n = bm.bmWidth * bm.bmHeight;
//GdiFlush();
DWORD *b = (DWORD *)getBits();
from &= 0xffffff;
while (n--)
{
if ((*b & 0xffffff) == from)
{
*b = to;
}
else *b |= 0xff000000; // force all other pixels non masked
b++;
}
}
void BltCanvas::makeAlpha(int newalpha)
{
int w, h;
getDim(&w, &h, NULL);
premultiply((ARGB32 *)getBits(), w*h, newalpha);
}
#if 0
void BltCanvas::premultiply(ARGB32 *m_pBits, int nwords, int newalpha)
{
if (newalpha == -1)
{
for (; nwords > 0; nwords--, m_pBits++)
{
unsigned char *pixel = (unsigned char *)m_pBits;
unsigned int alpha = pixel[3];
if (alpha == 255) continue;
pixel[0] = (pixel[0] * alpha) >> 8; // blue
pixel[1] = (pixel[1] * alpha) >> 8; // green
pixel[2] = (pixel[2] * alpha) >> 8; // red
}
}
else
{
for (; nwords > 0; nwords--, m_pBits++)
{
unsigned char *pixel = (unsigned char *)m_pBits;
pixel[0] = (pixel[0] * newalpha) >> 8; // blue
pixel[1] = (pixel[1] * newalpha) >> 8; // green
pixel[2] = (pixel[2] * newalpha) >> 8; // red
pixel[3] = (pixel[3] * newalpha) >> 8; // alpha
}
}
}
#endif
// benski> this may not be completely safe. it's meant for skinbitmap::blittorect
// it doesn't take into account skin bitmaps, enveloped bitmaps, or any other things like that
void BltCanvas::DestructiveResize(int w, int h, int nb_bpp)
{
if (hdc != NULL)
{
SelectObject(hdc, prevbmp);
prevbmp=0;
}
if (ourbmp && hbmp)
{
DeleteObject(hbmp);
hbmp=NULL;
ourbmp=FALSE;
}
// create tha DC
if (hdc == NULL)
hdc = CreateCompatibleDC(NULL);
AllocBitmap(w,h,nb_bpp);
prevbmp = (HBITMAP)SelectObject(hdc, hbmp);
if (envelope) envelope->Release();
envelope=0;
}

View file

@ -0,0 +1,41 @@
#ifndef _BLTCANVAS_H
#define _BLTCANVAS_H
#include "canvas.h"
#include <tataki/export.h>
#include <bfc/ptrlist.h>
class TATAKIAPI BltCanvas : public Canvas
{
public:
BltCanvas();
BltCanvas(int w, int h, HWND wnd=NULL, int nb_bpp=32/*, unsigned __int8 *pal=NULL,int palsize=0*/);
BltCanvas(HBITMAP bmp);
virtual ~BltCanvas();
void *getBits();
HBITMAP getBitmap();
SkinBitmap *makeSkinBitmap(); // this one makes a new, with own bits
SkinBitmap *getSkinBitmap(); // this one gives a skinbitmap envoloppe of this bltcanvas
void disposeSkinBitmap(SkinBitmap *b); // call only after makeSkinBitmap
void fillBits(COLORREF color);
void vflip(int vert_cells=1);
void hflip(int hor_cells=1);
void maskColor(COLORREF from, COLORREF to);
void makeAlpha(int newalpha=-1); // -1 = premultiply using current alpha
void DestructiveResize(int w, int h, int nb_bpp = 32); // resizes the bitmap, destroying the contents
private: // NONPORTABLE
void AllocBitmap(int w, int h, int nb_bpp);
HBITMAP hbmp, prevbmp;
PtrList<SkinBitmap> *skinbmps;
SkinBitmap *envelope;
BITMAP bm;
bool ourbmp;
int bpp;
//void premultiply(ARGB32 *m_pBits, int nwords, int newalpha=-1);
};
#endif

View file

@ -0,0 +1,368 @@
//NONPORTABLE: the interface is portable, but the implementation sure isn't
#ifndef _CANVAS_H
#define _CANVAS_H
#if defined _WIN64 || defined _WIN32
#include <ddraw.h>
#endif
//#include <bfc/common.h>
#include <tataki/export.h>
class Canvas;
class MemCanvasBmp;
class BaseWnd;
class ifc_window;
class api_region;
class SkinBitmap;
#include <bfc/stack.h>
#include <api/service/svcs/svc_font.h> // for STDFONT_* stuff. should make a std_font thingy later
#include <bfc/dispatch.h>
enum {
#ifdef WIN32
PENSTYLE_SOLID = PS_SOLID,
PENSTYLE_DASH = PS_DASH,
PENSTYLE_DOT = PS_DOT,
#else
PENSTYLE_SOLID = LineSolid,
PENSTYLE_DASH = LineDoubleDash,
PENSTYLE_DOT = LineDoubleDash,
#endif
};
#include <tataki/canvas/ifc_canvas.h>
class ifc_canvas;
class RegionI;
typedef struct
{
int style;
int width;
COLORREF color;
HPEN hpen;
}
penstruct;
class TATAKIAPI NOVTABLE Canvas : public ifc_canvas
{
protected:
Canvas();
public:
virtual ~Canvas();
// ifc_canvas stuff
HDC getHDC();
ifc_window *getRootWnd();
void *getBits();
void getOffsets(int *x, int *y);
bool isFixedCoords();
bool getDim(int *w, int *h, int *p);
void setBaseWnd(BaseWnd *b);
// end ifc_canvas stuff
virtual BaseWnd *getBaseWnd();
// graphics commands
void fillRect(const RECT *r, COLORREF color);
void fillRectAlpha(const RECT *r, COLORREF color, int alpha);
void fillRgn(RegionI *r, COLORREF color);
void drawRect(const RECT *r, int solid, COLORREF color, int alpha = 255);
// text commands
const wchar_t *getTextFont();
int getTextSize();
int getTextBold();
int getTextAntialias();
int getTextOpaque();
int getTextUnderline();
int getTextItalic();
int getTextAlign();
COLORREF getTextColor();
COLORREF getTextBkColor();
void pushPen(COLORREF color);
void pushPen(int style, int width, COLORREF color);
void popPen();
int getPenStyle();
COLORREF getPenColor();
int getPenWidth();
// normal text
void textOut(int x, int y, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
void textOut(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
void textOutEllipsed(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
// returns height used
void textOutWrapped(int x, int y, int w, int h, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
void textOutWrappedPathed(int x, int y, int w, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
void textOutCentered(RECT *r, const wchar_t *txt, const Wasabi::FontInfo *fontInfo);
int getTextWidth(const wchar_t *text, const Wasabi::FontInfo *fontInfo);
int getTextHeight(const wchar_t *text, const Wasabi::FontInfo *fontInfo);
void getTextExtent(const wchar_t *text, int *w, int *h, const Wasabi::FontInfo *fontInfo);
int getTextHeight(const Wasabi::FontInfo *fontInfo)
{
return getTextHeight(L"M", fontInfo);
}
void selectClipRgn(api_region *r);
int getClipBox(RECT *r); // returns 0 if no clipping region
int getClipRgn(api_region *r); // returns 0 if no clipping region
// Deprecated?
void moveTo(int x, int y);
void lineTo(int x, int y);
void lineDraw(int fromX, int fromY, int toX, int toY);
void drawSysObject(const RECT *r, int sysobj, int alpha = 255);
void blit(int srcx, int srcy, Canvas *dest, int dstx, int dsty, int dstw, int dsth);
void blitAlpha(ifc_canvas *canvas, int x, int y, int alpha = 255);
void blitToRect(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
void stretch(ifc_canvas *canvas, int x, int y, int w, int h);
// src* are in 16.16 fixed point
void stretchblit(int srcx, int srcy, int srcw, int srch, Canvas *dest, int dstx, int dsty, int dstw, int dsth);
void stretchToRectAlpha(ifc_canvas *canvas, RECT *src, RECT *dst, int alpha = 255);
void antiAliasTo(Canvas *dest, int w, int h, int aafactor);
int getXOffset() const
{
return xoffset;
}
int getYOffset() const
{
return yoffset;
}
void offsetRect(RECT *r);
void debug();
void colorToColor(COLORREF from, COLORREF to, RECT *r);
double getSystemFontScale();
static void premultiply(ARGB32 *m_pBits, int nwords, int newalpha = -1);
protected:
const Wasabi::FontInfo *getFontInfo()
{
if (userFontInfo)
return userFontInfo;
else
return &canvasFontInfo;
}
RECVS_DISPATCH;
HDC hdc;
void *bits;
int width, height, pitch;
bool fcoord;
int xoffset, yoffset;
BaseWnd *srcwnd;
Wasabi::FontInfo canvasFontInfo; // to hold our defaults
const Wasabi::FontInfo *userFontInfo; // passed from someone calling this function. usually is NULL
private:
Stack<penstruct> penstack;
int penstyle;
COLORREF pencolor;
int penwidth;
#ifdef WIN32
HPEN defpen;
HPEN curpen;
#endif
#ifdef LINUX
int raster_x, raster_y;
#endif
};
namespace DrawSysObj
{
enum {
BUTTON, BUTTON_PUSHED, BUTTON_DISABLED,
OSBUTTON, OSBUTTON_PUSHED, OSBUTTON_DISABLED,
OSBUTTON_CLOSE, OSBUTTON_CLOSE_PUSHED, OSBUTTON_CLOSE_DISABLED,
OSBUTTON_MINIMIZE, OSBUTTON_MINIMIZE_PUSHED, OSBUTTON_MINIMIZE_DISABLED,
OSBUTTON_MAXIMIZE, OSBUTTON_MAXIMIZE_PUSHED, OSBUTTON_MAXIMIZE_DISABLED,
};
};
class TATAKIAPI WndCanvas : public Canvas
{
public:
WndCanvas();
WndCanvas(BaseWnd *basewnd);
virtual ~WndCanvas();
// address client area
int attachToClient(BaseWnd *basewnd);
//CUT // address entire window
//CUT int attachToWnd(HWND _hWnd); // NONPORTABLE: avoid! mostly for mainwnd
private:
HWND hWnd;
};
class TATAKIAPI PaintCanvas : public Canvas
{
public:
PaintCanvas();
virtual ~PaintCanvas();
int beginPaint(BaseWnd *basewnd);
int beginPaint(HWND wnd);
void getRcPaint(RECT *r);
private: // NONPORTABLE
HWND hWnd;
PAINTSTRUCT ps;
};
class BltCanvas;
class TATAKIAPI PaintBltCanvas : public Canvas
{
public:
PaintBltCanvas();
virtual ~PaintBltCanvas();
int beginPaint(BaseWnd *basewnd);
int beginPaintNC(BaseWnd *basewnd);
void *getBits();
void getRcPaint(RECT *r);
private: // NONPORTABLE
HWND hWnd;
PAINTSTRUCT ps;
HDC wnddc;
HBITMAP hbmp, prevbmp;
bool nonclient;
#ifdef LINUX
BltCanvas *blitter;
#endif
};
class TATAKIAPI MemCanvas : public Canvas
{
public:
MemCanvas();
virtual ~MemCanvas();
int createCompatible(Canvas *canvas);
private:
};
class TATAKIAPI DCCanvas : public Canvas
{
public:
DCCanvas(HDC clone = NULL, BaseWnd *srcWnd = NULL);
virtual ~DCCanvas();
int cloneDC(HDC clone, BaseWnd *srcWnd = NULL);
};
class TATAKIAPI SysCanvas : public Canvas
{
public:
SysCanvas();
virtual ~SysCanvas();
};
/* benski>
a quick Canvas class to be created on-the-fly when you need to retrieve information about fonts
e.g. getTextExtent
don't try to draw with it or bad things will happen.
*/
class TATAKIAPI TextInfoCanvas : public Canvas
{
public:
TextInfoCanvas(BaseWnd *basewnd);
virtual ~TextInfoCanvas();
private:
HWND hWnd;
};
class TATAKIAPI DCBltCanvas : public Canvas
{
public:
DCBltCanvas();
virtual ~DCBltCanvas();
int cloneDC(HDC clone, RECT *r, BaseWnd *srcWnd = NULL);
int setOrigDC(HDC neworigdc); // set to null to prevent commitdc on delete, non null to change destination dc
int commitDC(void); // allows commit to DC without deleting
#if 0
int cloneCanvas(ifc_canvas *clone, RECT *r);
#endif
protected:
HDC origdc;
RECT rect;
HBITMAP hbmp, prevbmp;
};
class TATAKIAPI DCExBltCanvas : public DCBltCanvas
{
public:
DCExBltCanvas(HWND hWnd, HRGN hrgnClip, DWORD flags);
~DCExBltCanvas();
private:
HWND hwnd;
};
// note: getBaseWnd() returns NULL for this class
class TATAKIAPI BaseCloneCanvas : public Canvas
{
public:
BaseCloneCanvas(ifc_canvas *cloner = NULL);
virtual ~BaseCloneCanvas();
int clone(ifc_canvas *cloner);
};
#ifdef WIN32
class TATAKIAPI DDSurfaceCanvas : public Canvas
{
public:
DDSurfaceCanvas(LPDIRECTDRAWSURFACE surface, int w, int h);
virtual ~DDSurfaceCanvas();
int isready();
void enter();
void exit();
private:
LPDIRECTDRAWSURFACE surf;
int _w, _h;
};
#endif
class TATAKIAPI BitsCanvas : public Canvas
{
public:
BitsCanvas(void *_bits, int _w, int _h)
{
bits=_bits;
width=_w;
height=_h;
pitch=_w;
}
};
enum
{
ALIGN_LEFT,
ALIGN_CENTER,
ALIGN_RIGHT
};
#endif

File diff suppressed because it is too large Load diff