graph.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:27k
- /*
- * graph.cxx
- *
- * Graphics 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: graph.cxx,v $
- * Revision 1.27 1999/08/17 03:46:41 robertj
- * Fixed usage of inlines in optimised version.
- *
- * Revision 1.26 1998/12/12 00:44:03 robertj
- * Added functions for user request on printing selection only.
- * Fixed transfer of start and end pages from PPrintDialog.
- *
- * Revision 1.25 1998/10/15 11:32:55 robertj
- * New memory leak detection system.
- *
- * Revision 1.24 1998/09/24 03:42:42 robertj
- * Added open software license.
- *
- * Revision 1.23 1998/09/07 14:34:01 robertj
- * Fixed setting of print info parameters from DEVMODE structure.
- *
- * Revision 1.22 1998/09/04 07:01:38 robertj
- * Added a lot of DEVMODE infor for win95 to propagate from PrintDlg to PPrintCanvas.
- *
- * Revision 1.21 1998/01/26 00:20:42 robertj
- * Fixed creation of pattern bitmaps (word alignment).
- *
- * Revision 1.20 1997/04/27 05:50:29 robertj
- * DLL support.
- *
- * Revision 1.19 1996/10/31 12:39:56 robertj
- * Added RCS keywords.
- *
- */
- #include <pwlib.h>
- #if !P_USE_INLINES
- #include <pwlib/graphics.inl>
- #endif
- #define new PNEW
- ///////////////////////////////////////////////////////////////////////////////
- PPoint::PPoint(DWORD dw)
- {
- #if defined(_WIN32)
- POINTS ps = MAKEPOINTS(dw);
- p.x = ps.x;
- p.y = ps.y;
- #else
- p = MAKEPOINT(dw);
- #endif
- }
- ///////////////////////////////////////////////////////////////////////////////
- PRect::PRect(PORDINATE x, PORDINATE y, PDIMENSION dx, PDIMENSION dy)
- {
- r.left = x;
- r.top = y;
- r.right = x + dx;
- r.bottom = y + dy;
- }
- PRect::PRect(const PDim & dim)
- {
- r.left = r.top = 0;
- r.right = dim.Width();
- r.bottom = dim.Height();
- }
- PRect::PRect(const PPoint & p1, const PPoint & p2)
- {
- if (p1.X() > p2.X()) {
- r.left = p2.X();
- r.right = p1.X();
- }
- else {
- r.left = p1.X();
- r.right = p2.X();
- }
- if (p1.Y() > p2.Y()) {
- r.top = p2.Y();
- r.bottom = p1.Y();
- }
- else {
- r.top = p1.Y();
- r.bottom = p2.Y();
- }
- }
- PRect::PRect(const PPoint & topLeft, const PDim & dim)
- {
- r.left = topLeft.X();
- r.top = topLeft.Y();
- r.right = topLeft.X() + dim.Width();
- r.bottom = topLeft.Y() + dim.Height();
- }
- PObject::Comparison PRect::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PRect::Class()), PInvalidCast);
- return EqualRect(&r, &((const PRect &)obj).r) ? EqualTo : GreaterThan;
- }
- void PRect::SetX(PORDINATE nx)
- {
- PORDINATE diff = nx - (PORDINATE)r.left;
- r.left = nx;
- r.right += diff;
- }
- void PRect::SetY(PORDINATE ny)
- {
- PORDINATE diff = ny - (PORDINATE)r.top;
- r.top = ny;
- r.bottom += diff;
- }
- void PRect::SetTop(PORDINATE t)
- {
- r.top = t;
- if (t > r.bottom)
- r.bottom = t;
- }
- void PRect::SetLeft(PORDINATE l)
- {
- r.left = l;
- if (l > r.right)
- r.right = l;
- }
- void PRect::SetBottom(PORDINATE b)
- {
- r.bottom = b;
- if (b < r.top)
- r.top = b;
- }
- void PRect::SetRight(PORDINATE rt)
- {
- r.right = rt;
- if (rt < r.left)
- r.left = rt;
- }
- PRect PRect::Intersection(const PRect & rect) const
- {
- PRect newRect;
- IntersectRect(newRect, &r, rect);
- return newRect;
- }
- PRect PRect::Union(const PRect & rect) const
- {
- PRect newRect;
- UnionRect(newRect, &r, rect);
- return newRect;
- }
- ///////////////////////////////////////////////////////////////////////////////
- PRegion::PRegion(const PRect & rect)
- {
- hRegion = CreateRectRgnIndirect(rect);
- PAssertNULL(hRegion);
- }
- PRegion::PRegion(const PRegion & rgn)
- {
- hRegion = CreateRectRgn(0, 0, 0, 0);
- PAssertNULL(hRegion);
- PAssertOS(CombineRgn(hRegion, rgn.hRegion, NULL, RGN_COPY) != ERROR);
- }
- PRegion & PRegion::operator=(const PRegion & rgn)
- {
- PAssertOS(DeleteObject(hRegion));
- hRegion = CreateRectRgn(0, 0, 0, 0);
- PAssertNULL(hRegion);
- PAssertOS(CombineRgn(hRegion, rgn.hRegion, NULL, RGN_COPY) != ERROR);
- return *this;
- }
- PObject::Comparison PRegion::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PRegion::Class()), PInvalidCast);
- return EqualRgn(hRegion, ((const PRegion &)obj).hRegion)
- ? EqualTo : GreaterThan;
- }
- void PRegion::Add(const PRect & rect)
- {
- HRGN hRgnNew = CreateRectRgn(0, 0, 0, 0);
- HRGN hRgnRect = CreateRectRgnIndirect(rect);
- PAssertNULL(hRgnNew);
- PAssertNULL(hRgnRect);
- PAssertOS(CombineRgn(hRgnNew, hRegion, hRgnRect, RGN_OR) != ERROR);
- PAssertOS(DeleteObject(hRgnRect));
- PAssertOS(DeleteObject(hRegion));
- hRegion = PAssertNULL(hRgnNew);
- }
- void PRegion::Add(const PRegion & rgn)
- {
- HRGN hRgnNew = CreateRectRgn(0, 0, 0, 0);
- PAssertNULL(hRgnNew);
- PAssertOS(CombineRgn(hRgnNew, hRegion, rgn.hRegion, RGN_OR) != ERROR);
- PAssertOS(DeleteObject(hRegion));
- hRegion = PAssertNULL(hRgnNew);
- }
- BOOL PRegion::OverlapsRect(const PRect & rect) const
- {
- HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
- HRGN hRect = CreateRectRgnIndirect(rect);
- PAssertNULL(hRgn);
- PAssertNULL(hRect);
- PAssertOS(CombineRgn(hRgn, hRect, hRegion, RGN_AND) != ERROR);
- PAssertOS(DeleteObject(hRect));
- RECT dummy;
- BOOL empty = GetRgnBox(PAssertNULL(hRgn), &dummy) == NULLREGION;
- PAssertOS(DeleteObject(hRgn));
- return !empty;
- }
- BOOL PRegion::IsEmpty() const
- {
- RECT dummy;
- return GetRgnBox(hRegion, &dummy) == NULLREGION;
- }
- PRect PRegion::GetBounds() const
- {
- PRect rect;
- GetRgnBox(hRegion, rect);
- return rect;
- }
- PRegion PRegion::Intersection(const PRegion & rgn) const
- {
- HRGN hRgnNew = CreateRectRgn(0, 0, 0, 0);
- PAssertNULL(hRgnNew);
- PAssertOS(CombineRgn(hRgnNew, hRegion, rgn.hRegion, RGN_AND) != ERROR);
- return PRegion(PAssertNULL(hRgnNew));
- }
- PRegion PRegion::Union(const PRegion & rgn) const
- {
- HRGN hRgnNew = CreateRectRgn(0, 0, 0, 0);
- PAssertNULL(hRgnNew);
- PAssertOS(CombineRgn(hRgnNew, hRegion, rgn.hRegion, RGN_OR) != ERROR);
- return PRegion(PAssertNULL(hRgnNew));
- }
- ///////////////////////////////////////////////////////////////////////////////
- PColour::PColour(const PString & description)
- {
- memset(component, 0, sizeof(component));
- PStringArray compstr = description.Tokenise(" ,");
- switch (compstr.GetSize()) {
- case 4 :
- component[AlphaComponent] = (BYTE)compstr[3].AsInteger();
- // Then execute next case
- case 3 :
- component[BlueComponent] = (BYTE)compstr[2].AsInteger();
- // Then execute next case
- case 2 :
- component[GreenComponent] = (BYTE)compstr[1].AsInteger();
- // Then execute next case
- case 1 :
- component[RedComponent] = (BYTE)compstr[0].AsInteger();
- }
- }
- PString PColour::GetDescription() const
- {
- return psprintf("%u,%u,%u,%u", GetRed(), GetGreen(), GetBlue(), GetAlpha());
- }
- PColour & PColour::FromCOLORREF(COLORREF col)
- {
- component[RedComponent] = GetRValue(col);
- component[GreenComponent] = GetGValue(col);
- component[BlueComponent] = GetBValue(col);
- component[AlphaComponent] = 0xff;
- return *this;
- }
- //////////////////////////////////////////////////////////////////////////////
- #ifdef NOTYET
- PRealColour::PRealColour()
- {
- HDC hDC = CreateCompatibleDC(NULL);
- FromCOLORREF(GetNearestColor(hDC, ToCOLORREF()));
- DeleteDC(hDC);
- }
- PRealColour::PRealColour(const PColour & colour)
- : PColour(colour)
- {
- if (colour.GetAlpha() != 0) {
- HDC hDC = CreateCompatibleDC(NULL);
- FromCOLORREF(GetNearestColor(hDC, colour.ToCOLORREF()));
- DeleteDC(hDC);
- }
- }
- #endif
- PRealColour::PRealColour(PCanvas & canvas, const PColour & colour)
- : PColour(colour)
- {
- if (colour.GetAlpha() != 0)
- FromCOLORREF(GetNearestColor(canvas.GetHDC(), colour.ToCOLORREF()));
- }
- //////////////////////////////////////////////////////////////////////////////
- PPalette::PPalette()
- {
- LOGPALETTE logPal;
- logPal.palVersion = 0x300;
- logPal.palNumEntries = 1;
- logPal.palPalEntry[0].peRed = 0;
- logPal.palPalEntry[0].peGreen = 0;
- logPal.palPalEntry[0].peBlue = 0;
- logPal.palPalEntry[0].peFlags = 0;
- hPalette = CreatePalette(&logPal);
- PAssertNULL(hPalette);
- }
- void PPalette::DestroyContents()
- {
- PAssertOS(DeleteObject(hPalette));
- }
- PObject::Comparison PPalette::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PPalette::Class()), PInvalidCast);
- return hPalette == ((const PPalette &)obj).hPalette ? EqualTo : GreaterThan;
- }
- PINDEX PPalette::AddColour(const PColour & colour)
- {
- PINDEX count = GetSize();
- PAssertOS(SetColour(count, colour));
- return count;
- }
- BOOL PPalette::RemoveColour(const PColour & colour)
- {
- PINDEX index = GetNearestPaletteIndex(hPalette, colour.ToCOLORREF());
- if (colour != GetColour(index))
- return FALSE;
- return RemoveColour(index);
- }
- BOOL PPalette::RemoveColour(PINDEX index)
- {
- PINDEX numColours = GetSize()-1;
- if (index > numColours)
- return FALSE;
- PINDEX colourCount = numColours - index;
- if (colourCount > 0) {
- PALETTEENTRY * entries = new PALETTEENTRY[colourCount];
- GetPaletteEntries(hPalette, index+1, colourCount, entries);
- SetPaletteEntries(hPalette, index, colourCount, entries);
- delete [] entries;
- }
- return ResizePalette(hPalette, numColours);
- }
- BOOL PPalette::HasColour(const PColour & colour) const
- {
- return GetColour(GetIndex(colour)) == colour;
- }
- PINDEX PPalette::GetIndex(const PColour & colour) const
- {
- return GetNearestPaletteIndex(hPalette, colour.ToCOLORREF());
- }
- PColour PPalette::GetColour(PINDEX index) const
- {
- PALETTEENTRY entry;
- GetPaletteEntries(hPalette, index, 1, &entry);
- return PColour(entry.peRed, entry.peGreen, entry.peBlue);
- }
- BOOL PPalette::SetColour(PINDEX index, const PColour & colour)
- {
- if (!SetMinSize(index+1))
- return FALSE;
- PALETTEENTRY entry;
- entry.peRed = colour.GetRed();
- entry.peGreen = colour.GetGreen();
- entry.peBlue = colour.GetBlue();
- entry.peFlags = 0;
- SetPaletteEntries(hPalette, index, 1, &entry);
- return TRUE;
- }
- PINDEX PPalette::GetSize() const
- {
- short count;
- PAssertOS(GetObject(hPalette, sizeof(count), (LPSTR)&count)==sizeof(count));
- return count;
- }
- BOOL PPalette::SetSize(PINDEX size)
- {
- return ResizePalette(hPalette, size);
- }
- ///////////////////////////////////////////////////////////////////////////////
- PRealFont::PRealFont()
- : PFont(PApplication::Current().GetSystemFont())
- {
- Construct(CreateCompatibleDC(NULL));
- }
- PRealFont::PRealFont(const PFont & font)
- : PFont(font)
- {
- Construct(CreateCompatibleDC(NULL));
- }
- PRealFont::PRealFont(PCanvas & canvas, const PFont & font)
- : PFont(font)
- {
- Construct(CreateCompatibleDC(canvas.GetHDC()));
- }
- PRealFont::PRealFont(HFONT hFont)
- : PFont("", 0)
- {
- if (hFont == NULL)
- hFont = (HFONT)GetStockObject(SYSTEM_FONT);
- HDC dc = CreateCompatibleDC(NULL);
- deviceResY = (PDIMENSION)GetDeviceCaps(dc, LOGPIXELSY);
- PAssert(deviceResY != 0, PInvalidParameter);
- LOGFONT lf;
- GetObject(hFont, sizeof(lf), (LPSTR)&lf);
- facename = PCaselessString(lf.lfFaceName);
- size = PixelsToPointsY((PDIMENSION)PABS(lf.lfHeight));
- styles = Regular;
- if (lf.lfWeight > FW_NORMAL)
- styles |= Bold;
- if (lf.lfItalic)
- styles |= Italic;
- if (lf.lfUnderline)
- styles |= Underline;
- Construct(dc);
- }
- void PRealFont::Construct(HDC dc)
- {
- SetMapMode(PAssertNULL(dc), MM_TEXT);
- deviceResX = (PDIMENSION)GetDeviceCaps(dc, LOGPIXELSX);
- PAssert(deviceResX != 0, PInvalidParameter);
- deviceResY = (PDIMENSION)GetDeviceCaps(dc, LOGPIXELSY);
- PAssert(deviceResY != 0, PInvalidParameter);
- HFONT hFont = GetHFONT();
- HGDIOBJ oldFont = SelectObject(dc, hFont);
- TEXTMETRIC t;
- GetTextMetrics(dc, &t);
- PAssertOS(SelectObject(dc, PAssertNULL(oldFont)) != NULL);
- PAssertOS(DeleteObject(hFont));
- PAssertOS(DeleteDC(dc));
- size = PixelsToPointsY((PDIMENSION)t.tmHeight);
- height = PixelsToPointsY((PDIMENSION)(t.tmHeight + t.tmExternalLeading));
- avgWidth = PixelsToPointsX((PDIMENSION)t.tmAveCharWidth);
- maxWidth = PixelsToPointsX((PDIMENSION)t.tmMaxCharWidth);
- ascent = PixelsToPointsY((PDIMENSION)t.tmAscent);
- descent = PixelsToPointsY((PDIMENSION)t.tmDescent);
- leading = PixelsToPointsY((PDIMENSION)t.tmExternalLeading);
- styles = Regular;
- if (t.tmWeight > FW_NORMAL)
- styles |= Bold;
- if (t.tmItalic)
- styles |= Italic;
- if (t.tmUnderlined)
- styles |= Underline;
- }
- HFONT PRealFont::GetHFONT() const
- {
- HFONT hFont = ::CreateFont(PointsToPixelsY(size), 0, 0, 0,
- (styles&Bold) != 0 ? FW_BOLD : FW_NORMAL,
- (BYTE)((styles&Italic) != 0),
- (BYTE)((styles&Underline) != 0),
- 0, 0, 0, 0, 0, 0, facename);
- return PAssertNULL(hFont);
- }
- PDIMENSION PRealFont::GetHeight(BOOL inPixels) const
- {
- return inPixels ? PointsToPixelsY(height) : height;
- }
- PDIMENSION PRealFont::GetAvgWidth(BOOL inPixels) const
- {
- return inPixels ? PointsToPixelsX(avgWidth) : avgWidth;
- }
- PDIMENSION PRealFont::GetMaxWidth(BOOL inPixels) const
- {
- return inPixels ? PointsToPixelsX(maxWidth) : maxWidth;
- }
- PDIMENSION PRealFont::GetAscent(BOOL inPixels) const
- {
- return inPixels ? PointsToPixelsY(ascent) : ascent;
- }
- PDIMENSION PRealFont::GetDescent(BOOL inPixels) const
- {
- return inPixels ? PointsToPixelsY(descent) : descent;
- }
- PDIMENSION PRealFont::GetLeading(BOOL inPixels) const
- {
- return inPixels ? PointsToPixelsY(leading) : leading;
- }
- ///////////////////////////////////////////////////////////////////////////////
- PPattern::PPattern()
- {
- hBitmap = NULL;
- bitmap.bmWidth = bitmap.bmHeight = 1;
- }
- PPattern::PPattern(PRESOURCE_ID resID)
- {
- Construct(LoadBitmap(PApplication::Current().GetInstance(), MAKEINTRESOURCE(resID)));
- }
- PPattern::PPattern(Bits bits)
- {
- BYTE wordAlignedBits[16];
- memset(wordAlignedBits, 0, sizeof(wordAlignedBits));
- PINDEX i;
- for (i = 0; i < 8; i++)
- wordAlignedBits[i*2] = bits[i];
- Construct(CreateBitmap(8, 8, 1, 1, wordAlignedBits));
- }
- void PPattern::Construct(HBITMAP hBm)
- {
- hBitmap = PAssertNULL(hBm);
- GetObject(hBitmap, sizeof(bitmap), (LPSTR)&bitmap);
- }
- PObject::Comparison PPattern::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PPattern::Class()), PInvalidCast);
- return hBitmap == ((const PPattern &)obj).hBitmap ? EqualTo : GreaterThan;
- }
- void PPattern::DestroyContents()
- {
- if (hBitmap != NULL)
- PAssertOS(DeleteObject((HGDIOBJ)hBitmap));
- }
- void PPattern::CopyContents(const PPattern & pat)
- {
- hBitmap = pat.hBitmap;
- bitmap = pat.bitmap;
- }
- ///////////////////////////////////////////////////////////////////////////////
- PPixelBase::PPixelBase(PDIMENSION dx, PDIMENSION dy, BYTE depth)
- : PImageBase(dx, dy)
- {
- pixelLineBytes = (PINDEX)((((long)Width()*depth+31)/32)*4);
- #if defined(_WIN32)
- pixels = (PPixelDataPtr)malloc((size_t)dy*pixelLineBytes);
- #else
- pixels = (PPixelDataPtr)_halloc((long)dy*pixelLineBytes, 1);
- #endif
- if (pixels == NULL)
- memset(&info, 0, sizeof(info));
- else {
- info.biWidth = dx;
- info.biHeight = dy;
- info.biPlanes = 1;
- info.biBitCount = depth;
- info.biSizeImage = info.biHeight*pixelLineBytes;
- info.biCompression = BI_RGB;
- info.biXPelsPerMeter = 0;
- info.biYPelsPerMeter = 0;
- info.biClrImportant = 0;
- info.biClrUsed = info.biBitCount < 24 ? (1 << info.biBitCount) : 0;
- }
- info.biSize = sizeof(info);
- hBitmap = NULL;
- }
- PPixelBase::~PPixelBase()
- {
- if (hBitmap != NULL)
- PAssertOS(DeleteObject((HGDIOBJ)hBitmap));
- #if defined(_WIN32)
- free(pixels);
- #else
- _hfree(pixels);
- #endif
- }
- PObject::Comparison PPixelBase::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PPixelBase::Class()), PInvalidCast);
- return pixels == ((const PPixelBase &)obj).pixels ? EqualTo : GreaterThan;
- }
- PPixelBase::DIBInfo::DIBInfo(const PPixelBase & pix, HPALETTE hPal)
- {
- PINDEX numColours = pix.palette.GetSize();
- info = (BITMAPINFO *)malloc(
- sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*numColours);
- PAssertNULL(info);
- info->bmiHeader = pix.info;
- if (info->bmiHeader.biBitCount >= 24)
- colourUse = DIB_RGB_COLORS;
- else if (pix.palette.GetHPALETTE() != hPal) {
- colourUse = DIB_RGB_COLORS;
- for (PINDEX i = 0; i < numColours; i++) {
- PColour c = pix.palette.GetColour(i);
- info->bmiColors[i].rgbRed = c.GetRed();
- info->bmiColors[i].rgbGreen = c.GetGreen();
- info->bmiColors[i].rgbBlue = c.GetBlue();
- info->bmiColors[i].rgbReserved = 0;
- }
- }
- else {
- colourUse = DIB_PAL_COLORS;
- WORD * wp = (WORD *)info->bmiColors;
- for (PINDEX i = 0; i < numColours; i++)
- *wp++ = (WORD)i;
- }
- }
- HBITMAP PPixelBase::GetHBITMAP(HDC hDC) const
- {
- DIBInfo dib(*this, NULL);
- HDC tempDC = NULL;
- if (hDC == NULL)
- hDC = tempDC = CreateCompatibleDC(NULL);
- HBITMAP hBm = CreateDIBitmap(hDC, dib, CBM_INIT, pixels, dib, dib.Usage());
- if (tempDC)
- DeleteDC(tempDC);
- return hBm;
- }
- HDC PPixelBase::CreateImageDC()
- {
- HDC hDC = CreateCompatibleDC(NULL);
- hBitmap = GetHBITMAP(hDC);
- PAssertOS(SelectObject(PAssertNULL(hDC), hBitmap) != NULL);
- return hDC;
- }
- void PPixelBase::CloseImageDC(HDC hDC)
- {
- PAssertOS(SelectObject(hDC, NULL) != NULL);
- if (pixels != NULL)
- GetBitmapBits(hBitmap, info.biSizeImage, pixels);
- hBitmap = NULL;
- }
- PPixelDataPtr PPixelBase::GetRasterDataPtr(PORDINATE y) const
- {
- PAssert(y >= 0 && (PDIMENSION)y < Height(), "Pixel out of bounds");
- PAssert(pixels != NULL, "No pixel data");
- return pixels + (long)(Height()-y-1)*pixelLineBytes;
- }
- PPixelImage::PPixelImage(PRESOURCE_ID resID)
- {
- operator=(PPixelBase::CreateBitmap(LoadBitmap(
- PApplication::Current().GetInstance(), MAKEINTRESOURCE(resID))));
- }
- PPixelImage PPixelBase::CreateBitmap(HBITMAP hBm)
- {
- BITMAP bm;
- PAssertOS(GetObject(PAssertNULL(hBm), sizeof(bm), (LPSTR)&bm) > 0);
- PAssert(bm.bmPlanes == 1, PUnsupportedFeature);
- PPixelImage pix((PDIMENSION)bm.bmWidth,
- (PDIMENSION)bm.bmHeight, (BYTE)bm.bmBitsPixel);
- if (pix->pixels != NULL)
- GetBitmapBits(hBm, pix->info.biSizeImage, pix->pixels);
- return pix;
- }
- BOOL PPixelBase::Write(PFile & bmpFile)
- {
- if (!bmpFile.IsOpen())
- return FALSE;
- BITMAPFILEHEADER bmfh;
- bmfh.bfType = 0x4d42 /*'BM'*/;
- bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) +
- sizeof(BITMAPINFOHEADER) + info.biClrUsed*sizeof(RGBQUAD);
- bmfh.bfSize = bmfh.bfOffBits + info.biSizeImage;
- bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
- if (!bmpFile.Write(&bmfh, sizeof(bmfh)))
- return FALSE;
- if (!bmpFile.Write(&info, sizeof(info)))
- return FALSE;
- for (PINDEX i = 0; i < (PINDEX)info.biClrUsed; i++) {
- PColour colour = palette.GetColour(i);
- RGBQUAD rgb;
- rgb.rgbRed = colour.GetRed();
- rgb.rgbGreen = colour.GetGreen();
- rgb.rgbBlue = colour.GetBlue();
- rgb.rgbReserved = 0;
- if (!bmpFile.Write(&rgb, sizeof(rgb)))
- return FALSE;
- }
- if (pixels == NULL)
- return FALSE;
- #if defined(_WIN32)
- return bmpFile.Write(pixels, (PINDEX)info.biSizeImage);
- #else
- return _hwrite(bmpFile.GetHandle(),
- pixels, info.biSizeImage) == (long)info.biSizeImage;
- #endif
- }
- ///////////////////////////////////////////////////////////////////////////////
- PPictBase::PPictBase()
- : PImageBase(0, 0)
- {
- hMetafile = NULL;
- }
- PPictBase::PPictBase(PFile & dwg)
- : PImageBase(0, 0)
- {
- dwg.Close();
- #if defined(_WIN32)
- hMetafile = GetEnhMetaFile(dwg.GetFilePath());
- #else
- hMetafile = GetMetaFile(dwg.GetFilePath());
- #endif
- }
- PPictBase::PPictBase(PRESOURCE_ID)
- : PImageBase(0, 0)
- {
- hMetafile = NULL;
- }
- PPictBase::PPictBase(PMETAFILE hM)
- : PImageBase(0, 0)
- {
- hMetafile = PAssertNULL(hM);
- }
- PPictBase::~PPictBase()
- {
- #if defined(_WIN32)
- PAssertOS(DeleteEnhMetaFile(hMetafile));
- #else
- PAssertOS(DeleteMetaFile(hMetafile));
- #endif
- }
- PObject::Comparison PPictBase::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PPictBase::Class()), PInvalidCast);
- return hMetafile==((const PPictBase &)obj).hMetafile ? EqualTo : GreaterThan;
- }
- HDC PPictBase::CreateImageDC()
- {
- #if defined(_WIN32)
- HDC hDC = CreateEnhMetaFile(NULL, NULL, NULL, "PWLib");
- #else
- HDC hDC = CreateMetaFile(NULL);
- #endif
- return PAssertNULL(hDC);
- }
- void PPictBase::CloseImageDC(HDC hDC)
- {
- #if defined(_WIN32)
- hMetafile = CloseEnhMetaFile(hDC);
- #else
- hMetafile = CloseMetaFile(hDC);
- #endif
- }
- BOOL PPictBase::Write(PFile & dwg)
- {
- dwg.Close();
- #if defined(_WIN32)
- HENHMETAFILE hCopy = CopyEnhMetaFile(hMetafile, dwg.GetFilePath());
- return DeleteEnhMetaFile(PAssertNULL(hCopy));
- #else
- HMETAFILE hCopy = CopyMetaFile(hMetafile, dwg.GetFilePath());
- return DeleteMetaFile(PAssertNULL(hCopy));
- #endif
- }
- ///////////////////////////////////////////////////////////////////////////////
- PPrintInfo::PPrintInfo()
- {
- form = A4;
- startPage = 1;
- endPage = UINT_MAX;
- selectionOnly = NoSelectionOnly;
- copies = 1;
- orientation = TRUE;
- draftQuality = TRUE;
- PRINTDLG printDlg;
- memset(&printDlg, 0, sizeof(printDlg));
- printDlg.lStructSize = sizeof(printDlg);
- printDlg.Flags = PD_RETURNDEFAULT;
- PAssertOS(PrintDlg(&printDlg));
- SetFromPrintDlg(printDlg);
- if (printDlg.hDevMode != NULL)
- GlobalFree(printDlg.hDevMode);
- if (printDlg.hDevNames != NULL)
- GlobalFree(printDlg.hDevNames);
- }
- PPrintInfo::PPrintInfo(const PString & printerType,const PString & devicePort)
- : driver("WINSPOOL"),
- device(devicePort),
- printer(printerType)
- {
- form = A4;
- startPage = 0;
- endPage = (unsigned)-1;
- copies = 1;
- orientation = TRUE;
- draftQuality = TRUE;
- #if defined(_WIN32)
- HANDLE hPrinter;
- if (OpenPrinter((char *)(const char *)printerType, &hPrinter, NULL)) {
- devModeBuffer.SetSize(DocumentProperties(NULL, hPrinter, NULL, NULL, NULL, 0));
- if (DocumentProperties(NULL, hPrinter, NULL, GetDEVMODE(), NULL, DM_OUT_BUFFER) == IDOK)
- ProcessDEVMODE();
- PAssertOS(ClosePrinter(hPrinter));
- }
- #else
- char devLib[_MAX_PATH];
- GetProfileString("devices", printerType, "", devLib, sizeof(devLib));
- char * comma = strchr(devLib, ',');
- if (comma != NULL)
- *comma = ' ';
- strcat(devLib, ".DRV");
- HMODULE hDriver = LoadLibrary(devLib);
- if (hDriver >= HINSTANCE_ERROR) {
- LPFNDEVMODE extDevMode = (LPFNDEVMODE)GetProcAddress(hDriver, PROC_EXTDEVICEMODE);
- if (extDevMode != NULL) {
- char devType[CCHDEVICENAME];
- strcpy(devType, printerType);
- char devPort[_MAX_PATH];
- strcpy(devPort, devicePort);
- LONG bufSize = extDevMode(NULL, hDriver, NULL, pDevMode, devPort, NULL, NULL, 0);
- devMode = (LPDEVMODE)new char[bufSize];
- if (extDevMode(NULL, hDriver, devMode, devType, devPort,
- NULL, NULL, DM_OUT_BUFFER) == IDOK) {
- ProcessDEVMODE();
- driver = devicePort;
- printer = printerType;
- }
- }
- FreeLibrary(hDriver);
- }
- #endif
- }
- void PPrintInfo::SetFromPrintDlg(const PRINTDLG & printDlg)
- {
- if (printDlg.hDevMode != NULL) {
- devModeBuffer = PBYTEArray((BYTE *)GlobalLock(printDlg.hDevMode),
- GlobalSize(printDlg.hDevMode));
- GlobalUnlock(printDlg.hDevMode);
- ProcessDEVMODE();
- }
- if (printDlg.hDevNames != NULL) {
- LPSTR devNameBase = (LPSTR)GlobalLock(printDlg.hDevNames);
- LPDEVNAMES devNames = (LPDEVNAMES)devNameBase;
- driver = &devNameBase[devNames->wDriverOffset];
- printer = &devNameBase[devNames->wDeviceOffset];
- device = &devNameBase[devNames->wOutputOffset];
- GlobalUnlock(printDlg.hDevNames);
- }
- if ((printDlg.Flags&PD_NOPAGENUMS) != 0 || (printDlg.Flags&PD_PAGENUMS) == 0) {
- startPage = 0;
- endPage = UINT_MAX;
- }
- else {
- startPage = printDlg.nFromPage;
- endPage = printDlg.nToPage;
- }
- if ((printDlg.Flags&PD_NOSELECTION) != 0)
- selectionOnly = NoSelectionOnly;
- else if ((printDlg.Flags&PD_SELECTION) != 0)
- selectionOnly = SelectionOnlyOn;
- else
- selectionOnly = SelectionOnlyOff;
- copies = printDlg.nCopies;
- }
- void PPrintInfo::ProcessDEVMODE()
- {
- LPDEVMODE devMode = GetDEVMODE();
- orientation = devMode->dmOrientation == DMORIENT_PORTRAIT;
- const static struct {
- short form;
- PDIMENSION width;
- PDIMENSION height;
- } PaperSizes[PPrintInfo::MaxForm] = {
- { 0, 0, 0 },
- { DMPAPER_A3, 2970, 4200 },
- { DMPAPER_A4, 2100, 2970 },
- { DMPAPER_A5, 1485, 2100 },
- { DMPAPER_B4, 2500, 3540 },
- { DMPAPER_B5, 1820, 2570 },
- { DMPAPER_LETTER, 2163, 2800 },
- { DMPAPER_LEGAL, 2163, 3563 }
- };
- int f;
- for (f = A3; f < MaxForm; f++) {
- if (PaperSizes[f].form == devMode->dmPaperSize)
- break;
- }
- form = (Forms)f;
- if (form == Custom)
- paperSize = PDim((PDIMENSION)devMode->dmPaperWidth,
- (PDIMENSION)devMode->dmPaperLength);
- else if (orientation)
- paperSize = PDim(PaperSizes[f].width, PaperSizes[f].height);
- else
- paperSize = PDim(PaperSizes[f].height, PaperSizes[f].width);
- draftQuality = devMode->dmPrintQuality == DMRES_DRAFT;
- if (devMode->dmPrintQuality > 0)
- resolution = PDim((PDIMENSION)devMode->dmPrintQuality,
- (PDIMENSION)devMode->dmYResolution);
- else
- resolution = PDim();
- copies = devMode->dmCopies;
- }
- LPDEVMODE PPrintInfo::GetDEVMODE() const
- {
- PAssertOS(devModeBuffer.GetSize() > 0);
- return (LPDEVMODE)(const BYTE *)devModeBuffer;
- }
- HANDLE PPrintInfo::GetHDEVMODE() const
- {
- HANDLE h = GlobalAlloc(GHND, devModeBuffer.GetSize());
- memcpy(GlobalLock(h), devModeBuffer, devModeBuffer.GetSize());
- GlobalUnlock(h);
- return h;
- }
- HANDLE PPrintInfo::GetDevNames() const
- {
- PINDEX driverLen = driver.GetLength();
- PINDEX printerLen = printer.GetLength();
- PINDEX deviceLen = device.GetLength();
- HANDLE h = GlobalAlloc(GHND, sizeof(DEVNAMES)+driverLen+printerLen+deviceLen+4);
- LPDEVNAMES devNames = (LPDEVNAMES)GlobalLock(h);
- devNames->wDriverOffset = sizeof(DEVNAMES);
- devNames->wDeviceOffset = (WORD)(sizeof(DEVNAMES)+driverLen+1);
- devNames->wOutputOffset = (WORD)(sizeof(DEVNAMES)+driverLen+printerLen+2);
- LPSTR p = (LPSTR)devNames+sizeof(DEVNAMES);
- strcpy(p, driver);
- p += driverLen+1;
- strcpy(p, printer);
- p += printerLen+1;
- strcpy(p, device);
- GlobalUnlock(h);
- return h;
- }
- // End Of File ///////////////////////////////////////////////////////////////