canvas.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:29k
- /*
- * canvas.cxx
- *
- * Canvas classes implementation
- *
- * Portable Windows Library
- *
- * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Portable Windows Library.
- *
- * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
- *
- * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
- * All Rights Reserved.
- *
- * Contributor(s): ______________________________________.
- *
- * $Log: canvas.cxx,v $
- * Revision 1.49 1999/02/16 08:08:07 robertj
- * MSVC 6.0 compatibility changes.
- *
- * Revision 1.48 1998/10/15 11:32:53 robertj
- * New memory leak detection system.
- *
- * Revision 1.47 1998/09/24 03:42:31 robertj
- * Added open software license.
- *
- * Revision 1.46 1998/09/22 15:09:58 robertj
- * Added delayed HDC creation in PDrawCanvas.
- *
- * Revision 1.45 1998/09/18 13:59:31 robertj
- * Fixed FillRect leaving small gaps in pattern filled rectangles next to each other.
- *
- * Revision 1.44 1998/09/07 14:03:41 robertj
- * Fixed printing transforms being reset after each page.
- *
- * Revision 1.43 1998/09/04 07:00:10 robertj
- * Fixed double print dialog.
- * Can now print more than one page.
- * Fixed uninitialised variable for win95 StartDoc()
- *
- * Revision 1.42 1998/03/20 03:13:25 robertj
- * Added function to get physical bounds of canvas. Allows to scale drawing.
- *
- * Revision 1.41 1996/10/31 12:39:55 robertj
- * Added RCS keywords.
- *
- */
- #include <pwlib.h>
- #define new PNEW
- PCanvas::PCanvas()
- : _hDC(NULL),
- _hPen((HPEN)GetStockObject(BLACK_PEN)),
- _hBrush((HBRUSH)GetStockObject(HOLLOW_BRUSH)),
- _hFont(NULL)
- {
- deviceResX = deviceResY = 1;
- font = realFont;
- }
- PCanvas::~PCanvas()
- {
- if (_hDC != NULL)
- PAssertOS(DeleteDC(_hDC));
- if (_hPen != NULL)
- PAssertOS(DeleteObject(_hPen));
- if (_hBrush != NULL)
- PAssertOS(DeleteObject(_hBrush));
- if (_hFont != NULL)
- PAssertOS(DeleteObject(_hFont));
- }
- PCanvasState & PCanvas::operator=(const PCanvasState & state)
- {
- PCanvasState::operator=(state);
- if (_hDC != NULL)
- SetHDC(_hDC);
- return *this;
- }
- PObject::Comparison PCanvas::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PCanvas::Class()), PInvalidCast);
- return _hDC == ((const PCanvas &)obj)._hDC ? EqualTo : GreaterThan;
- }
- int PEXPORTED PEnumFontFamilyProc(const ENUMLOGFONT FAR * lpelf,
- const NEWTEXTMETRIC FAR *,
- int fontType,
- LPARAM lParam)
- {
- PFontFamily * family = new PFontFamily(lpelf->elfLogFont.lfFaceName);
- family->scalable = (fontType & RASTER_FONTTYPE) == 0;
- ((PFontFamilyList *)lParam)->Append(family);
- return TRUE;
- }
- int PEXPORTED PEnumFontFaceProc(const ENUMLOGFONT FAR * lpelf,
- const NEWTEXTMETRIC FAR * lpntm,
- int fontType,
- LPARAM lParam)
- {
- PFontFamily * family = (PFontFamily *)lParam;
- if ((fontType & TRUETYPE_FONTTYPE) != 0) {
- if (family->sizes.GetSize() == 0) {
- WORD sizes[] = {
- 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72
- };
- family->sizes = PWORDArray(sizes, PARRAYSIZE(sizes));
- }
- WORD style = PFont::Regular;
- if ((lpntm->ntmFlags&0x20) != 0)
- style |= PFont::Bold;
- if ((lpntm->ntmFlags&1) != 0)
- style |= PFont::Italic;
- if ((lpntm->ntmFlags&2) != 0)
- style |= PFont::Underline;
- family->styles[family->styles.GetSize()] = style;
- family->styleNames[family->styleNames.GetSize()] =
- PString((const char *)lpelf->elfStyle);
- }
- else {
- family->sizes[family->sizes.GetSize()] = (WORD)lpelf->elfLogFont.lfHeight;
- if (family->styles.GetSize() == 0) {
- family->sizes[0] = 0;
- if (lpelf->elfStyle[0] != ' ')
- family->styleNames[0] = PString((const char *)lpelf->elfStyle);
- else
- family->styleNames[0] = "Regular";
- }
- }
- return TRUE;
- }
- PFontFamilyList PCanvas::GetAvailableFonts() const
- {
- PFontFamilyList list;
- EnumFontFamilies(GetHDC(),
- NULL, (FONTENUMPROC)PEnumFontFamilyProc, (LPARAM)&list);
- for (PINDEX i = 0; i < list.GetSize(); i++)
- EnumFontFamilies(GetHDC(), list[i].GetFacename(),
- (FONTENUMPROC)PEnumFontFaceProc, (LPARAM)&list[i]);
- return list;
- }
- void PCanvas::SetHDC(HDC newDC)
- {
- _hDC = PAssertNULL(newDC);
- deviceResX = GetDeviceCaps(_hDC, LOGPIXELSX);
- deviceResY = GetDeviceCaps(_hDC, LOGPIXELSY);
- realFont = PRealFont(*this, font);
- SetMapMode(_hDC, MM_ANISOTROPIC);
- SetTransform();
- MakePen();
- MakeBrush();
- #if defined(_WIN32)
- SetBrushOrgEx(GetHDC(), patternOrigin.X(), patternOrigin.Y(), NULL);
- #else
- SetBrushOrg(GetHDC(), patternOrigin.X(), patternOrigin.Y());
- #endif
- PAssertOS(SelectPalette(_hDC, palette.GetHPALETTE(), TRUE) != NULL);
- ::SetPolyFillMode(_hDC, polyFillMode == Winding ? WINDING : ALTERNATE);
- SetTextAlign(_hDC, TA_LEFT|TA_TOP|TA_NOUPDATECP);
- }
- BOOL PCanvas::SetPenStyle(PenStyles style)
- {
- if (PCanvasState::SetPenStyle(style)) {
- MakePen();
- return TRUE;
- }
- return FALSE;
- }
- BOOL PCanvas::SetPenWidth(int width)
- {
- if (PCanvasState::SetPenWidth(width)) {
- MakePen();
- return TRUE;
- }
- return FALSE;
- }
- BOOL PCanvas::SetPenFgColour(const PColour & colour)
- {
- if (PCanvasState::SetPenFgColour(colour)) {
- MakePen();
- return TRUE;
- }
- return FALSE;
- }
- void PCanvas::MakePen()
- {
- HPEN oldPen = _hPen;
- if (penFgColour.GetAlpha() == 0)
- _hPen = (HPEN)GetStockObject(NULL_PEN);
- else {
- static int msStyle[] = { PS_SOLID, PS_DOT, PS_DASH, PS_DASHDOT };
- PAssert(penStyle < sizeof(msStyle)/sizeof(msStyle[0]), PInvalidParameter);
- _hPen = CreatePen(msStyle[penStyle],
- penWidth, penFgColour.ToCOLORREF());
- }
- PAssertNULL(_hPen);
- if (_hDC != NULL)
- PAssertOS(SelectObject(_hDC, _hPen) != NULL);
- if (oldPen != NULL)
- PAssertOS(DeleteObject(oldPen));
- }
- BOOL PCanvas::SetFillPattern(const PPattern & pattern)
- {
- if (PCanvasState::SetFillPattern(pattern)) {
- MakeBrush();
- return TRUE;
- }
- return FALSE;
- }
- BOOL PCanvas::SetPatternOrigin(const PPoint & pt)
- {
- if (PCanvasState::SetPatternOrigin(pt)) {
- #ifdef WIN32
- SetBrushOrgEx(GetHDC(), pt.X(), pt.Y(), NULL);
- #else
- SetBrushOrg(GetHDC(), pt.X(), pt.Y());
- #endif
- return TRUE;
- }
- return FALSE;
- }
- BOOL PCanvas::SetFillFgColour(const PColour & colour)
- {
- if (PCanvasState::SetFillFgColour(colour)) {
- MakeBrush();
- return TRUE;
- }
- return FALSE;
- }
- void PCanvas::MakeBrush()
- {
- HBRUSH oldBrush = _hBrush;
- if (fillFgColour.GetAlpha() == 0)
- _hBrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
- else if (fillPattern.GetHBITMAP() == NULL)
- _hBrush = CreateSolidBrush(fillFgColour.ToCOLORREF());
- else
- _hBrush = CreatePatternBrush(fillPattern.GetHBITMAP());
- PAssertNULL(_hBrush);
- if (_hDC != NULL)
- PAssertOS(SelectObject(_hDC, _hBrush) != NULL);
- if (oldBrush != NULL)
- PAssertOS(DeleteObject(oldBrush));
- }
- BOOL PCanvas::SetFont(const PFont & newFont)
- {
- if (!PCanvasState::SetFont(newFont))
- return FALSE;
- GetHDC();
- realFont = PRealFont(*this, newFont);
- MakeFont();
- return TRUE;
- }
- void PCanvas::MakeFont()
- {
- HFONT oldFont = _hFont;
- _hFont = CreateFont(FromPointsY(realFont.GetHeight()),
- 0, 0, 0,
- realFont.IsBold() ? FW_BOLD : FW_NORMAL,
- (BYTE)realFont.IsItalic(),
- (BYTE)realFont.IsUnderlined(),
- 0, 0, 0, 0, 0, 0,
- realFont.GetFacename());
- PAssertNULL(_hFont);
- if (_hDC != NULL)
- PAssertOS(SelectObject(_hDC, _hFont) != NULL);
- if (oldFont != NULL)
- PAssertOS(DeleteObject(oldFont));
- }
- BOOL PCanvas::SetPalette(const PPalette & newPal)
- {
- if (PCanvasState::SetPalette(newPal)) {
- if (_hDC != NULL)
- PAssertOS(SelectPalette(_hDC, palette.GetHPALETTE(), TRUE) != NULL);
- return TRUE;
- }
- return FALSE;
- }
- BOOL PCanvas::SetPolyFillMode(PolyFillMode newMode)
- {
- if (PCanvasState::SetPolyFillMode(newMode)) {
- if (_hDC != NULL)
- ::SetPolyFillMode(_hDC, polyFillMode == Winding ? WINDING : ALTERNATE);
- return TRUE;
- }
- return FALSE;
- }
- BOOL PCanvas::SetViewportRect(const PRect & rect)
- {
- if (PCanvasState::SetViewportRect(rect)) {
- SetTransform();
- return TRUE;
- }
- return FALSE;
- }
- BOOL PCanvas::SetMappingRect(const PRect & rect)
- {
- if (PCanvasState::SetMappingRect(rect)) {
- SetTransform();
- return TRUE;
- }
- return FALSE;
- }
- void PCanvas::SetTransform()
- {
- if (_hDC == NULL)
- return;
- SetViewportOrgEx(_hDC, viewport.Left(), viewport.Top(), NULL);
- SetViewportExtEx(_hDC, viewport.Width(), viewport.Height(), NULL);
- SetWindowOrgEx(_hDC, map.Left(), map.Top(), NULL);
- SetWindowExtEx(_hDC, map.Width(), map.Height(), NULL);
- if (GetPenWidth() != 0)
- MakePen();
- MakeFont();
- }
- void PCanvas::MoveCurrentPosition(PORDINATE x, PORDINATE y)
- {
- POINT p;
- PAssertOS(GetCurrentPositionEx(GetHDC(), &p));
- MoveToEx(_hDC, p.x+x, p.y+y, NULL);
- }
- PPoint PCanvas::GetCurrentPosition() const
- {
- PPoint p;
- PAssertOS(::GetCurrentPositionEx(GetHDC(), p));
- return p;
- }
- void PCanvas::DrawLine(PORDINATE x, PORDINATE y)
- {
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, -1);
- LineTo(GetHDC(), x, y);
- }
- void PCanvas::DrawLine(PORDINATE x1, PORDINATE y1, PORDINATE x2, PORDINATE y2)
- {
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, -1);
- POINT p;
- MoveToEx(GetHDC(), x1, y1, &p);
- LineTo(_hDC, x2, y2);
- MoveToEx(_hDC, (int)p.x, (int)p.y, NULL);
- }
- void PCanvas::DrawLineRelative(PORDINATE x, PORDINATE y)
- {
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, -1);
- POINT p;
- PAssertOS(GetCurrentPositionEx(GetHDC(), &p));
- LineTo(_hDC, p.x+x, p.y+y);
- }
- void PCanvas::_DrawRect(PORDINATE x, PORDINATE y, PDIMENSION dx, PDIMENSION dy)
- {
- if (penMode == fillMode) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- Rectangle(_hDC, x, y, x+dx, y+dy);
- }
- else {
- HGDIOBJ oldBrush =
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, NULL_BRUSH);
- Rectangle(_hDC, x, y, x+dx, y+dy);
- HGDIOBJ oldPen =
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, oldBrush, NULL_PEN);
- Rectangle(_hDC, x, y, x+dx, y+dy);
- SelectObject(_hDC, oldPen);
- }
- }
- void PCanvas::_FillRect(PORDINATE x, PORDINATE y, PDIMENSION dx, PDIMENSION dy)
- {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- PRect r(x, y, dx, dy);
- ::FillRect(GetHDC(), r, _hBrush);
- }
- void PCanvas::DrawRoundRect(const PRect & rect,
- PDIMENSION cornerWidth, PDIMENSION cornerHeight)
- {
- if (penMode == fillMode) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- RoundRect(_hDC, rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- cornerWidth, cornerHeight);
- }
- else {
- HGDIOBJ oldBrush =
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, NULL_BRUSH);
- RoundRect(_hDC, rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- cornerWidth, cornerHeight);
- HGDIOBJ oldPen =
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, oldBrush, NULL_PEN);
- RoundRect(_hDC, rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- cornerWidth, cornerHeight);
- SelectObject(_hDC, oldPen);
- }
- }
- void PCanvas::DrawEllipse(const PRect & rect)
- {
- if (penMode == fillMode) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- Ellipse(_hDC, rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
- }
- else {
- HGDIOBJ oldBrush =
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, NULL_BRUSH);
- Ellipse(_hDC, rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
- HGDIOBJ oldPen =
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, oldBrush, NULL_PEN);
- Ellipse(_hDC, rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
- SelectObject(_hDC, oldPen);
- }
- }
- void PCanvas::DrawArc(const PRect & rect,
- const PPoint & startPt, const PPoint & endPt)
- {
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, -1);
- Arc(GetHDC(), rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- startPt.X(), startPt.Y(), endPt.X(), endPt.Y());
- }
- static PPoint PointFromAngle(int angle)
- {
- static int sine[] = {
- 0, 17, 35, 52, 70, 87, 105, 122, 139, 156, 174, 191, 208,
- 225, 242, 259, 276, 292, 309, 326, 342, 358, 375, 391, 407, 423,
- 438, 454, 469, 485, 500, 515, 530, 545, 559, 574, 588, 602, 616,
- 629, 643, 656, 669, 682, 695, 707, 719, 731, 743, 755, 766, 777,
- 788, 799, 809, 819, 829, 839, 848, 857, 866, 875, 883, 891, 899,
- 906, 914, 921, 927, 934, 940, 946, 951, 956, 961, 966, 970, 974,
- 978, 982, 985, 988, 990, 993, 995, 996, 998, 999, 999, 1000, 1000
- };
- while (angle < 0)
- angle += 360;
- angle %= 360;
- switch (angle/45) {
- default:
- case 0 :
- return PPoint(1000, sine[angle]);
- case 1 :
- return PPoint(sine[90-angle], 1000);
- case 2 :
- return PPoint(sine[angle], -1000);
- case 3 :
- return PPoint(1000, sine[angle]);
- case 4 :
- return PPoint(1000, sine[angle]);
- case 5 :
- return PPoint(sine[90-angle], 1000);
- case 6 :
- return PPoint(sine[90-angle], 1000);
- case 7 :
- return PPoint(1000, sine[angle]);
- }
- }
- void PCanvas::DrawArc(const PRect & rect, int startAngle, int endAngle)
- {
- DrawArc(rect, PointFromAngle(startAngle), PointFromAngle(endAngle));
- }
- void PCanvas::DrawPie(const PRect & rect,
- const PPoint & startPt, const PPoint & endPt)
- {
- if (penMode == fillMode) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- Pie(GetHDC(), rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- startPt.X(), startPt.Y(), endPt.X(), endPt.Y());
- }
- else {
- HGDIOBJ oldBrush =
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, NULL_BRUSH);
- Pie(GetHDC(), rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- startPt.X(), startPt.Y(), endPt.X(), endPt.Y());
- HGDIOBJ oldPen =
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, oldBrush, NULL_PEN);
- Pie(GetHDC(), rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- startPt.X(), startPt.Y(), endPt.X(), endPt.Y());
- SelectObject(_hDC, oldPen);
- }
- }
- void PCanvas::DrawPie(const PRect & rect, int startAngle, int endAngle)
- {
- DrawPie(rect, PointFromAngle(startAngle), PointFromAngle(endAngle));
- }
- void PCanvas::DrawChord(const PRect & rect,
- const PPoint & startPt, const PPoint & endPt)
- {
- if (penMode == fillMode) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- Chord(GetHDC(), rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- startPt.X(), startPt.Y(), endPt.X(), endPt.Y());
- }
- else {
- HGDIOBJ oldBrush =
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, NULL_BRUSH);
- Chord(GetHDC(), rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- startPt.X(), startPt.Y(), endPt.X(), endPt.Y());
- HGDIOBJ oldPen =
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, oldBrush, NULL_PEN);
- Chord(GetHDC(), rect.Left(), rect.Top(), rect.Right(), rect.Bottom(),
- startPt.X(), startPt.Y(), endPt.X(), endPt.Y());
- SelectObject(_hDC, oldPen);
- }
- }
- void PCanvas::DrawChord(const PRect & rect, int startAngle, int endAngle)
- {
- DrawChord(rect, PointFromAngle(startAngle), PointFromAngle(endAngle));
- }
- void PCanvas::DrawPolyLine(const PPointArray & ptArray)
- {
- DrawPolyLine(MakePOINTArray(ptArray), ptArray.GetSize());
- }
- void PCanvas::DrawPolyLine(const PPoint * ptArray, PINDEX numPts)
- {
- DrawPolyLine(MakePOINTArray(ptArray, numPts), numPts);
- }
- void PCanvas::DrawPolyLine(LPPOINT ptArray, PINDEX numPts)
- {
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, -1);
- Polyline(GetHDC(), ptArray, numPts);
- delete [] ptArray;
- }
- void PCanvas::DrawPolygon(const PPointArray & ptArray)
- {
- DrawPolygon(MakePOINTArray(ptArray), ptArray.GetSize());
- }
- void PCanvas::DrawPolygon(const PPoint * ptArray, PINDEX numPts)
- {
- DrawPolygon(MakePOINTArray(ptArray, numPts), numPts);
- }
- void PCanvas::DrawPolygon(LPPOINT ptArray, PINDEX numPts)
- {
- if (penMode == fillMode) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- Polygon(GetHDC(), ptArray, numPts);
- }
- else {
- HGDIOBJ oldBrush =
- SetUpDrawModes(penMode, penFgColour, penBkColour, NULL, NULL_BRUSH);
- Polygon(GetHDC(), ptArray, numPts);
- HGDIOBJ oldPen =
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, oldBrush, NULL_PEN);
- Polygon(GetHDC(), ptArray, numPts);
- SelectObject(_hDC, oldPen);
- }
- delete [] ptArray;
- }
- LPPOINT PCanvas::MakePOINTArray(const PPointArray & ptArray)
- {
- PINDEX size = ptArray.GetSize();
- LPPOINT pa = new POINT[size];
- for (PINDEX i = 0; i < size; i++)
- pa[i] = *(LPPOINT)ptArray[i];
- return pa;
- }
- LPPOINT PCanvas::MakePOINTArray(const PPoint * ptArray, PINDEX numPts)
- {
- LPPOINT pa = new POINT[numPts];
- for (PINDEX i = 0; i < numPts; i++)
- pa[i] = *(const POINT *)ptArray[i];
- return pa;
- }
- void PCanvas::DrawImgIcon(PORDINATE x, PORDINATE y, const PImgIcon & icn)
- {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- SetMapMode(_hDC, MM_TEXT);
- SetViewportOrgEx(_hDC, 0, 0, NULL);
- SetWindowOrgEx(_hDC, 0, 0, NULL);
- HDC hSrcDC = CreateCompatibleDC(_hDC);
- HGDIOBJ oldBitmap = SelectObject(PAssertNULL(hSrcDC), icn.GetHBITMAP());
- BITMAP bm;
- GetObject(icn.GetHBITMAP(), sizeof(bm), (LPSTR)&bm);
- PAssertOS(BitBlt(_hDC,
- ToPixelsX(x), ToPixelsY(y),
- (int)bm.bmWidth, (int)bm.bmHeight,
- hSrcDC, 0, 0, SRCCOPY));
- SelectObject(hSrcDC, oldBitmap);
- DeleteDC(hSrcDC);
- SetMapMode(_hDC, MM_ANISOTROPIC);
- SetTransform();
- }
- void PCanvas::DrawIcon(PORDINATE x, PORDINATE y, const PIcon & icn)
- {
- ::DrawIcon(GetHDC(), x, y, icn.GetHICON());
- }
- void PCanvas::DrawPixels(PORDINATE x, PORDINATE y, const PPixelImage & pix)
- {
- if (pix->GetPixelDataPtr() != NULL) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- RealizePalette(_hDC);
- PPixelBase::DIBInfo dib(*pix, palette.GetHPALETTE());
- SetDIBitsToDevice(_hDC,
- x, y, dib.Width(), dib.Height(),
- 0, 0, 0, dib.Height(),
- pix->GetPixelDataPtr(), dib, dib.Usage());
- }
- }
- void PCanvas::DrawPixels(const PRect & rect, const PPixelImage & pix)
- {
- if (pix->GetPixelDataPtr() != NULL) {
- SetUpDrawModes(fillMode, fillFgColour, fillBkColour, NULL, -1);
- RealizePalette(_hDC);
- PPixelBase::DIBInfo dib(*pix, palette.GetHPALETTE());
- StretchDIBits(_hDC,
- rect.X(), rect.Y(), rect.Width(), rect.Height(),
- 0, 0, dib.Width(), dib.Height(),
- pix->GetPixelDataPtr(), dib, dib.Usage(), SRCCOPY);
- }
- }
- void PCanvas::DrawPict(PORDINATE x, PORDINATE y, const PPictImage & pic)
- {
- POINT org;
- SetWindowOrgEx(_hDC, x, y, &org);
- #if defined(_WIN32)
- PlayEnhMetaFile(GetHDC(), pic->GetMETAFILE(), NULL);
- #else
- PlayMetaFile(GetHDC(), pic->GetMETAFILE());
- #endif
- SetWindowOrgEx(_hDC, (int)org.x, (int)org.y, NULL);
- }
- void PCanvas::DrawPict(const PRect & rect, const PPictImage & pic)
- {
- #if defined(_WIN32)
- PlayEnhMetaFile(GetHDC(), pic->GetMETAFILE(), rect);
- #else
- POINT org;
- SIZE ext;
- SetWindowOrgEx(_hDC, rect.X(), rect.Y(), &org);
- SetWindowExtEx(_hDC, rect.Width(), rect.Height(), &ext);
- PlayMetaFile(GetHDC(), pic->GetMETAFILE());
- SetWindowOrgEx(_hDC, (int)org.x, (int)org.y, NULL);
- SetWindowExtEx(_hDC, (int)ext.cx, (int)ext.cy, NULL);
- #endif
- }
- void PCanvas::DrawString(PORDINATE x, PORDINATE y,
- const PString & str, int options)
- {
- SetUpDrawModes(SrcCopy, textFgColour, textBkColour, NULL, -1);
- PDim dim;
- switch (options&VerticalAlignmentMask) {
- case BottomAlign :
- if (dim.Height() == 0)
- dim = MeasureString(str);
- y -= dim.Height();
- break;
- case CentreVertical :
- if (dim.Height() == 0)
- dim = MeasureString(str);
- y -= dim.Height()/2;
- break;
- case BaseLine :
- y -= FromPointsY(realFont.GetAscent());
- }
- switch (options&HorizontalAlignmentMask) {
- case RightAlign :
- if (dim.Width() == 0)
- dim = MeasureString(str);
- x -= dim.Width();
- break;
- case Centred :
- if (dim.Width() == 0)
- dim = MeasureString(str);
- x -= dim.Width()/2;
- }
- if (str.FindOneOf("rn") == P_MAX_INDEX)
- TabbedTextOut(GetHDC(), x, y, str, str.GetLength(), 0, NULL, 0);
- else {
- PRect r(x, y, 10000, 10000);
- DrawText(GetHDC(), str, -1, r,
- DT_LEFT|DT_TOP|DT_NOPREFIX|DT_EXPANDTABS|DT_EXTERNALLEADING);
- }
- }
- PDim PCanvas::MeasureString(const PString & str)
- {
- PDim dim;
- if (str.FindOneOf("rn") == P_MAX_INDEX)
- dim = PDim::FromDWORD(GetTabbedTextExtent(GetHDC(),
- str, str.GetLength(), 0, NULL));
- else {
- PStringArray lines = str.Lines();
- for (PINDEX line = 0; line < lines.GetSize(); line++) {
- DWORD lineDim = GetTabbedTextExtent(GetHDC(),
- lines[line], lines[line].GetLength(), 0, NULL);
- if (dim.Width() < (PDIMENSION)LOWORD(lineDim))
- dim.SetWidth(LOWORD(lineDim));
- dim.SetHeight(dim.Height() + HIWORD(lineDim));
- }
- }
- return dim;
- }
- void PCanvas::DrawTextLine(PORDINATE x, PORDINATE y,
- const char * textChars,
- const PDIMENSION * charWidths,
- PINDEX len)
- {
- SetUpDrawModes(SrcCopy, textFgColour, textBkColour, NULL, -1);
- PRect rect(x, y, 1, 1);
- ExtTextOut(_hDC, x, y, 0, rect, textChars, len, (LPINT)charWidths);
- }
- HGDIOBJ PCanvas::SetUpDrawModes(DrawingModes mode,
- const PColour & fg, const PColour & bg,
- HGDIOBJ restoreObj, int saveObj)
- {
- if (restoreObj)
- SelectObject(GetHDC(), restoreObj);
- static int modeTable[] = {
- R2_COPYPEN, R2_NOTCOPYPEN,
- R2_MASKPEN, R2_MASKNOTPEN, R2_MASKPENNOT, R2_NOTMASKPEN,
- R2_MERGEPEN, R2_MERGENOTPEN, R2_MERGEPENNOT, R2_NOTMERGEPEN,
- R2_XORPEN, R2_NOTXORPEN,
- R2_NOT, R2_NOP
- };
- PAssert(mode < PARRAYSIZE(modeTable), PInvalidParameter);
- SetROP2(GetHDC(), modeTable[mode]);
- SetTextColor(_hDC, fg.ToCOLORREF());
- SetBkColor(_hDC, bg.ToCOLORREF());
- SetBkMode(_hDC, bg.GetAlpha() == 0 ? TRANSPARENT : OPAQUE);
- return saveObj < 0 ? NULL : SelectObject(_hDC, GetStockObject(saveObj));
- }
- void PCanvas::SetClipRect(const PRect & rect)
- {
- PRegion rgn = ToPixels(rect);
- SelectClipRgn(GetHDC(), rgn.GetHRGN());
- }
- PRect PCanvas::GetClipRect() const
- {
- PRect r;
- GetClipBox(GetHDC(), r);
- return r;
- }
- void PCanvas::SetClipRegion(const PRegion & rgn)
- {
- SelectClipRgn(GetHDC(), rgn.GetHRGN());
- }
- PRegion PCanvas::GetClipRegion() const
- {
- #if defined(_WIN32)
- PRegion rgn;
- GetClipRgn(GetHDC(), rgn.GetHRGN());
- return rgn;
- #else
- PRect r;
- GetClipBox(GetHDC(), r);
- return r;
- #endif
- }
- PRect PCanvas::GetDrawingBounds() const
- {
- return FromPixels(PRect(0, 0, (PDIMENSION)GetDeviceCaps(_hDC,HORZRES),
- (PDIMENSION)GetDeviceCaps(_hDC,VERTRES)));
- }
- PRect PCanvas::GetPhysicalBounds(BOOL inPixels) const
- {
- if (inPixels)
- return PRect(0, 0, (PDIMENSION)GetDeviceCaps(_hDC,HORZRES),
- (PDIMENSION)GetDeviceCaps(_hDC,VERTRES));
- else
- return PRect(0, 0, (PDIMENSION)GetDeviceCaps(_hDC,HORZSIZE),
- (PDIMENSION)GetDeviceCaps(_hDC,VERTSIZE));
- }
- //////////////////////////////////////////////////////////////////////////////
- PRect PInteractorCanvas::GetDrawingBounds() const
- {
- return FromPixels(interactor->GetDrawingBounds(PInteractor::PixelCoords));
- }
- //////////////////////////////////////////////////////////////////////////////
- PDrawCanvas::PDrawCanvas(PInteractor * theInteractor,
- BOOL inPixels, BOOL overDrawChildWindows)
- : PInteractorCanvas(theInteractor, inPixels)
- {
- if (overDrawChildWindows)
- SetWindowLong(interactor->GetHWND(), GWL_STYLE,
- GetWindowLong(interactor->GetHWND(), GWL_STYLE)&~WS_CLIPCHILDREN);
- Construct(inPixels);
- SetHDC(GetDC(interactor->GetHWND()));
- deleteDC = TRUE;
- }
- PDrawCanvas::PDrawCanvas(PInteractor * theInteractor,
- HDC newDC, BOOL autoDelete, BOOL inPixels)
- : PInteractorCanvas(theInteractor, inPixels)
- {
- Construct(inPixels);
- preAllocatedDC = newDC;
- deleteDC = autoDelete;
- }
- PDrawCanvas::~PDrawCanvas()
- {
- if (_hDC == NULL)
- return;
- if (deleteDC) {
- PAssertOS(ReleaseDC(interactor->GetHWND(), _hDC));
- SetWindowLong(interactor->GetHWND(), GWL_STYLE,
- GetWindowLong(interactor->GetHWND(), GWL_STYLE)|WS_CLIPCHILDREN);
- }
- else {
- SelectObject(_hDC, GetStockObject(BLACK_PEN));
- SelectObject(_hDC, GetStockObject(WHITE_BRUSH));
- SelectObject(_hDC, GetStockObject(SYSTEM_FONT));
- SelectPalette(_hDC, (HPALETTE)GetStockObject(DEFAULT_PALETTE), FALSE);
- }
- _hDC = NULL;
- }
- HDC PDrawCanvas::GetHDC() const
- {
- if (_hDC == NULL)
- ((PDrawCanvas*)this)->SetHDC(preAllocatedDC);
- return _hDC;
- }
- //////////////////////////////////////////////////////////////////////////////
- PRedrawCanvas::PRedrawCanvas(PInteractor * theInteractor, BOOL inPixels)
- : PInteractorCanvas(theInteractor, inPixels)
- {
- Construct(inPixels);
- SetHDC(GetDC(interactor->GetHWND()));
- PAssertOS(ReleaseDC(interactor->GetHWND(), _hDC));
- paint.hdc = _hDC = NULL;
- }
- PRedrawCanvas::~PRedrawCanvas()
- {
- if (paint.hdc != NULL)
- EndPaint(interactor->GetHWND(), &paint);
- else if (_hDC != NULL)
- PAssertOS(ReleaseDC(interactor->GetHWND(), _hDC));
- _hDC = NULL;
- }
- HDC PRedrawCanvas::GetHDC() const
- {
- if (_hDC == NULL)
- ((PRedrawCanvas*)this)->SetHDC(
- BeginPaint(interactor->GetHWND(), &((PRedrawCanvas*)this)->paint));
- return _hDC;
- }
- //////////////////////////////////////////////////////////////////////////////
- PPrintCanvas::~PPrintCanvas()
- {
- if (_hDC != NULL) {
- PAssertOS(EndPage(_hDC) > 0);
- EndDoc(_hDC);
- }
- }
- void PPrintCanvas::Construct()
- {
- HDC newDC = CreateDC(printInfo.GetDriver(),
- printInfo.GetPrinter(),
- printInfo.GetDevice(),
- printInfo.GetDEVMODE());
- DOCINFO docInfo;
- memset(&docInfo, 0, sizeof(docInfo));
- docInfo.cbSize = sizeof(docInfo);
- docInfo.lpszDocName = jobName;
- StartDoc(newDC, &docInfo);
- if (StartPage(newDC) < 0)
- DeleteDC(newDC);
- else
- SetHDC(newDC);
- }
- BOOL PPrintCanvas::NewPage()
- {
- if (EndPage(GetHDC()) > 0) {
- if (StartPage(_hDC) > 0) {
- SetHDC(_hDC);
- return TRUE;
- }
- }
- return FALSE;
- }
- //////////////////////////////////////////////////////////////////////////////
- void PMemoryCanvas::Construct()
- {
- SetHDC(image->CreateImageDC());
- }
- // End Of File ///////////////////////////////////////////////////////////////