ultimatepp/uppsrc/Draw/DrawWin32.cpp
mdelfede 263ff5f895 changed svn layout
git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2008-06-07 22:31:27 +00:00

451 lines
9.6 KiB
C++

#include "Draw.h"
NAMESPACE_UPP
#define LLOG(x) // LOG(x)
#define LTIMING(x) // RTIMING(x)
#ifdef PLATFORM_WIN32
static COLORREF sLightGray;
void StaticExitDraw_()
{
Draw::FreeFonts();
}
EXITBLOCK
{
StaticExitDraw_();
}
#ifndef PLATFORM_WINCE
void Add(LOGPALETTE *pal, int r, int g, int b)
{
pal->palPalEntry[pal->palNumEntries].peRed = min(r, 255);
pal->palPalEntry[pal->palNumEntries].peGreen = min(g, 255);
pal->palPalEntry[pal->palNumEntries].peBlue = min(b, 255);
pal->palPalEntry[pal->palNumEntries++].peFlags = PC_NOCOLLAPSE;
}
HPALETTE GetQlibPalette()
{
static HPALETTE hQlibPalette;
if(hQlibPalette) return hQlibPalette;
Draw::InitColors();
LOGPALETTE *pal = (LOGPALETTE *) new byte[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
pal->palNumEntries = 0;
pal->palVersion = 0x300;
for(int r = 0; r < 6; r++)
for(int g = 0; g < 6; g++)
for(int b = 0; b < 6; b++)
Add(pal, 255 * r / 5, 255 * g / 5, 255 * b / 5);
for(int q = 0; q <= 16; q++)
Add(pal, 16 * q, 16 * q, 16 * q);
Add(pal, GetRValue(sLightGray), GetGValue(sLightGray), GetBValue(sLightGray));
hQlibPalette = CreatePalette(pal);
delete[] pal;
return hQlibPalette;
}
#endif
Draw& GLOBAL_VP(ScreenDraw, ScreenInfo, (true))
HDC ScreenHDC()
{
return ScreenInfo();
}
static bool _AutoPalette = true;
bool Draw::AutoPalette() { return _AutoPalette; }
void Draw::SetAutoPalette(bool ap) { _AutoPalette = ap; }
COLORREF Draw::GetColor(Color c) const {
COLORREF color = c;
#ifdef PLATFORM_WINCE
return color;
#else
if(!palette)
return color;
static Index<dword> *SColor;
ONCELOCK {
static Index<dword> StaticColor;
StaticColor << RGB(0x00, 0x00, 0x00) << RGB(0x80, 0x00, 0x00) << RGB(0x00, 0x80, 0x00)
<< RGB(0x80, 0x80, 0x00) << RGB(0x00, 0x00, 0x80) << RGB(0x80, 0x00, 0x80)
<< RGB(0x00, 0x80, 0x80) << RGB(0xC0, 0xC0, 0xC0) << RGB(0xC0, 0xDC, 0xC0)
<< RGB(0xA6, 0xCA, 0xF0) << RGB(0xFF, 0xFB, 0xF0) << RGB(0xA0, 0xA0, 0xA4)
<< RGB(0x80, 0x80, 0x80) << RGB(0xFF, 0x00, 0x00) << RGB(0x00, 0xFF, 0x00)
<< RGB(0xFF, 0xFF, 0x00) << RGB(0x00, 0x00, 0xFF) << RGB(0xFF, 0x00, 0xFF)
<< RGB(0x00, 0xFF, 0xFF) << RGB(0xFF, 0xFF, 0xFF);
SColor = &StaticColor;
}
if(color16 || !AutoPalette())
return GetNearestColor(handle, color);
if(SColor->Find(color) >= 0)
return color;
if(color == sLightGray)
return PALETTEINDEX(216 + 17);
int r = GetRValue(color);
int g = GetGValue(color);
int b = GetBValue(color);
return PALETTEINDEX(r == g && g == b ? (r + 8) / 16 + 216
: (r + 25) / 51 * 36 +
(g + 25) / 51 * 6 +
(b + 25) / 51);
#endif
}
void Draw::InitColors()
{
}
void Draw::SetColor(Color color)
{
DrawLock __;
LLOG("SetColor " << color);
if(color != lastColor) {
LLOG("Setting, lastColor:" << FormatIntHex(lastColor.GetRaw())
<< " color:" << FormatIntHex(color.GetRaw()) <<
" GetColor:" << FormatIntHex(GetColor(color)) << " palette:" << palette);
HBRUSH oldBrush = actBrush;
HBRUSH h;
if(!IsNull(color))
h = (HBRUSH) SelectObject(handle, actBrush = CreateSolidBrush(GetColor(color)));
else {
HGDIOBJ empty = GetStockObject(HOLLOW_BRUSH);
h = (HBRUSH) SelectObject(handle, empty);
actBrush = NULL;
}
ASSERT(h);
if(!orgBrush) orgBrush = h;
if(oldBrush) DeleteObject(oldBrush);
lastColor = color;
}
}
void Draw::SetDrawPen(int width, Color color) {
DrawLock __;
if(IsNull(width))
width = PEN_NULL;
if(width != lastPen || color != lastPenColor) {
static int penstyle[] = {
PS_NULL, PS_SOLID, PS_DASH,
#ifndef PLATFORM_WINCE
PS_DOT, PS_DASHDOT, PS_DASHDOTDOT
#endif
};
HPEN oldPen = actPen;
actPen = CreatePen(width < 0 ? penstyle[-width - 1] : PS_SOLID,
width < 0 ? 0 : width, GetColor(color));
HPEN h = (HPEN) SelectObject(handle, actPen);
if(!orgPen) orgPen = h;
if(oldPen) DeleteObject(oldPen);
lastPen = width;
lastPenColor = color;
}
}
void Draw::SetOrg() {
DrawLock __;
#ifdef PLATFORM_WINCE
::SetViewportOrgEx(handle, actual_offset.x, actual_offset.y, 0);
#else
LLOG("Draw::SetOrg: clip = " << GetClip() << ", offset = " << actual_offset);
::SetWindowOrgEx(handle, -actual_offset.x, -actual_offset.y, 0);
LLOG("//Draw::SetOrg: clip = " << GetClip());
#endif
}
#ifndef PLATFORM_WINCE
Point Draw::LPtoDP(Point p) const {
DrawLock __;
::LPtoDP(handle, p, 1);
return p;
}
Point Draw::DPtoLP(Point p) const {
DrawLock __;
::DPtoLP(handle, p, 1);
return p;
}
Rect Draw::LPtoDP(const Rect& r) const {
DrawLock __;
Rect w = r;
::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
return w;
}
Rect Draw::DPtoLP(const Rect& r) const {
DrawLock __;
Rect w = r;
::LPtoDP(handle, reinterpret_cast<POINT *>(&w), 2);
return w;
}
#endif
Size Draw::GetSizeCaps(int i, int j) const {
DrawLock __;
return Size(GetDeviceCaps(handle, i), GetDeviceCaps(handle, j));
}
void Draw::LoadCaps() {
DrawLock __;
color16 = false;
palette = (GetDeviceCaps(handle, RASTERCAPS) & RC_PALETTE);
if(palette)
color16 = GetDeviceCaps(handle, SIZEPALETTE) != 256;
pagePixels = GetSizeCaps(HORZRES, VERTRES);
pageMMs = GetSizeCaps(HORZSIZE, VERTSIZE);
inchPixels = GetSizeCaps(LOGPIXELSX, LOGPIXELSY);
sheetPixels = GetSizeCaps(PHYSICALWIDTH, PHYSICALHEIGHT);
pageOffset = GetSizeCaps(PHYSICALOFFSETX, PHYSICALOFFSETY);
is_mono = GetDeviceCaps(handle, BITSPIXEL) == 1 && GetDeviceCaps(handle, PLANES) == 1;
/*
if(!is_mono)
{
HBITMAP hbmp = (HBITMAP)GetCurrentObject(handle, OBJ_BITMAP);
if(hbmp)
{
BITMAP bmp;
GetObject(hbmp, sizeof(bmp), &bmp);
is_mono = bmp.bmPlanes == 1 && bmp.bmBitsPixel == 1;
}
}
*/
}
void Draw::SetDevice(const char *s) {
DrawLock __;
static Index<String> map;
device = map.FindAdd(s) + 1;
LoadCaps();
}
void Draw::Cinit() {
DrawLock __;
lastColor = Color::FromCR(COLORREF(-5));
lastPenColor = Color::FromCR(COLORREF(-5));
lastTextColor = COLORREF(-1);
lastPen = Null;
actBrush = orgBrush = NULL;
actPen = orgPen = NULL;
orgFont = NULL;
lastFont.Clear();
}
void Draw::Init() {
DrawLock __;
Cinit();
SetBkMode(handle, TRANSPARENT);
::SetTextAlign(handle, TA_BASELINE);
#ifdef PLATFORM_WINCE
actual_offset = Point(0, 0);
#else
::GetViewportOrgEx(handle, actual_offset);
#endif
LoadCaps();
}
void Draw::Reset() {
DrawLock __;
device = 0;
pixels = true;
printer = aborted = backdraw = is_mono = false;
}
Draw::Draw() {
DrawLock __;
InitColors();
InitFonts();
actual_offset = Point(0, 0);
Reset();
handle = NULL;
}
Draw::Draw(HDC hdc) {
DrawLock __;
InitColors();
InitFonts();
Reset();
Attach(hdc);
}
void Draw::Unselect0() {
DrawLock __;
if(orgPen) SelectObject(handle, orgPen);
if(orgBrush) SelectObject(handle, orgBrush);
if(orgFont) SelectObject(handle, orgFont);
if(actPen) DeleteObject(actPen);
if(actBrush) DeleteObject(actBrush);
Cinit();
}
void Draw::Unselect() {
DrawLock __;
while(cloff.GetCount())
End();
Unselect0();
}
Draw::~Draw() {
DrawLock __;
if(handle)
Unselect();
}
HDC Draw::BeginGdi() {
DrawLock __;
Begin();
return handle;
}
void Draw::EndGdi() {
DrawLock __;
Unselect0();
End();
}
NilDraw::NilDraw() {
DrawLock __;
Attach(ScreenInfo().GetHandle());
pixels = false;
cloff.Clear();
}
NilDraw::~NilDraw() {
DrawLock __;
Detach();
}
void BackDraw::Create(Draw& w, int cx, int cy) {
ASSERT(w.GetHandle());
DrawLock __;
Destroy();
size.cx = cx;
size.cy = cy;
hbmp = ::CreateCompatibleBitmap(w.GetHandle(), cx, cy);
handle = ::CreateCompatibleDC(w.GetHandle());
ASSERT(hbmp);
ASSERT(handle);
#ifndef PLATFORM_WINCE
if(w.PaletteMode() && AutoPalette()) {
::SelectPalette(handle, GetQlibPalette(), FALSE);
::RealizePalette(handle);
}
#endif
hbmpold = (HBITMAP) ::SelectObject(handle, hbmp);
Init();
backdraw = true;
}
void BackDraw::Put(Draw& w, int x, int y) {
DrawLock __;
ASSERT(handle);
LTIMING("BackDraw::Put");
#ifdef PLATFORM_WINCE
::SetViewportOrgEx(handle, 0, 0, 0);
#else
::SetWindowOrgEx(handle, 0, 0, NULL);
#endif
::BitBlt(w, x, y, size.cx, size.cy, *this, 0, 0, SRCCOPY);
}
void BackDraw::Destroy() {
DrawLock __;
if(handle) {
Unselect();
::SelectObject(handle, hbmpold);
::DeleteDC(handle);
::DeleteObject(hbmp);
handle = NULL;
}
}
ScreenDraw::ScreenDraw(bool ic) {
DrawLock __;
#ifdef PLATFORM_WINCE
Attach(CreateDC(NULL, NULL, NULL, NULL));
#else
Attach((ic ? CreateIC : CreateDC)("DISPLAY", NULL, NULL, NULL));
if(PaletteMode() && AutoPalette()) {
SelectPalette(handle, GetQlibPalette(), TRUE);
RealizePalette(handle);
}
#endif
}
ScreenDraw::~ScreenDraw() {
DrawLock __;
Unselect();
DeleteDC(handle);
}
#ifndef PLATFORM_WINCE
void PrintDraw::InitPrinter()
{
DrawLock __;
Init();
printer = true;
pixels = false;
::SetMapMode(handle, MM_ANISOTROPIC);
::SetViewportExtEx(handle, inchPixels.cx, inchPixels.cy, NULL);
::SetViewportOrgEx(handle, 0, 0, NULL);
::SetWindowExtEx(handle, 600, 600, NULL);
::SetWindowOrgEx(handle, 0, 0, NULL);
actual_offset = Point(0, 0);
}
void PrintDraw::StartPage()
{
DrawLock __;
if(IsAborted()) return;
Unselect();
if(::StartPage(handle) <= 0)
Abort();
else
InitPrinter();
}
void PrintDraw::EndPage()
{
DrawLock __;
if(IsAborted()) return;
Unselect();
ASSERT(printer);
if(::EndPage(handle) <= 0)
Abort();
}
PrintDraw::PrintDraw(HDC hdc, const char *docname)
: Draw(hdc)
{
DrawLock __;
DOCINFO di;
memset(&di, 0, sizeof(di));
di.cbSize = sizeof(di);
String sys_docname = ToSystemCharset(docname);
di.lpszDocName = ~sys_docname;
if(::StartDoc(hdc, &di) <= 0) {
Abort();
return;
}
InitPrinter();
}
PrintDraw::~PrintDraw() {
DrawLock __;
if(IsAborted())
::AbortDoc(handle);
else
::EndDoc(handle);
DeleteDC(handle);
handle = NULL;
}
#endif
#endif
END_UPP_NAMESPACE