home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
yacl-012.zip
/
ui
/
dwgsurf.cxx
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-09
|
20KB
|
658 lines
/*
*
* Copyright (C) 1994, M. A. Sridhar
*
*
* This software is Copyright M. A. Sridhar, 1994. You are free
* to copy, modify or distribute this software as you see fit,
* and to use it for any purpose, provided this copyright
* notice and the following disclaimer are included with all
* copies.
*
* DISCLAIMER
*
* The author makes no warranties, either expressed or implied,
* with respect to this software, its quality, performance,
* merchantability, or fitness for any particular purpose. This
* software is distributed AS IS. The user of this software
* assumes all risks as to its quality and performance. In no
* event shall the author be liable for any direct, indirect or
* consequential damages, even if the author has been advised
* as to the possibility of such damages.
*
*/
#if defined(__GNUC__)
#pragma implementation
#endif
#include "ui/dwgsurf.h"
#include "ui/visualob.h"
#include "ui/bitmap.h"
#include "ui/arc.h"
#include "ui/chord.h"
#include "ui/ellipse.h"
#include "ui/piewedge.h"
#if defined(__MS_WINDOWS__)
#include <windows.h>
static HRGN getRectRgnMS (const UI_Rectangle& r);
static HRGN getPolyRgnMS (UI_Point par[], short numpts);
#elif defined(__OS2__)
#include <string.h>
#include "ui/applic.h"
#include "ui/cntroler.h"
#endif
UI_DrawingSurface::UI_DrawingSurface ()
{
_pen = NULL;
_font = NULL;
_brush = NULL;
_horzPixels = 0;
_vertPixels = 0;
}
UI_Rectangle UI_DrawingSurface::DrawingArea () const
{
#if defined(__MS_WINDOWS__)
return UI_Rectangle (0, 0, _horzPixels, _vertPixels);
#else
NotImplemented ("DrawingArea");
return UI_Rectangle (0, 0, 0, 0);
#endif
}
UI_Rectangle UI_DrawingSurface::DrawingAreaInMM () const
{
#if defined(__MS_WINDOWS__)
return UI_Rectangle (0, 0, GetDeviceCaps (_handle, HORZSIZE),
GetDeviceCaps (_handle, VERTSIZE));
#elif defined(__OS2__)
HDC hdc = GpiQueryDevice (_handle);
LONG w, h; // w and h will be in pixels per meter
DevQueryCaps (hdc, CAPS_HORIZONTAL_RESOLUTION, 1L, &w);
DevQueryCaps (hdc, CAPS_VERTICAL_RESOLUTION, 1L, &h);
UI_Rectangle r = DrawingArea();
return UI_Rectangle (0, 0, r.Width() * 100 / w, r.Height() * 100 / h);
#else
NotImplemented ("DrawingAreaInMM");
return UI_Rectangle (0, 0, 0, 0);
#endif
}
void UI_DrawingSurface::ColorRectangle (const UI_Rectangle& r,
const UI_Color& cs)
{
#if defined(__MS_WINDOWS__)
HBRUSH hbr = CreateSolidBrush (cs.NativeForm ());
HBRUSH old = SelectObject (_handle, hbr);
HRGN hregion = getRectRgnMS (r);
PaintRgn(_handle, hregion);
SelectObject (_handle, old);
DeleteObject (hbr);
DeleteObject (hregion);
#elif defined (__OS2__)
UI_Rectangle area = DrawingArea ();
RECTL rect;
rect.xLeft = r.Left();
rect.yBottom = area.Height() - r.Bottom () + 1;
rect.xRight = r.Right();
rect.yTop = area.Height() + 1 - r.Top ();
UI_NativeColorRep color = cs.NativeForm();
GpiSavePS (_handle);
if (SupportsColor())
GpiSetColor (_handle, color);
GpiMove (_handle, (PPOINTL) &rect);
GpiBox (_handle, DRO_FILL, ((PPOINTL) &rect) + 1, 0, 0);
GpiRestorePS (_handle, -1);
#endif
}
void UI_DrawingSurface::DrawEllipse (const UI_Rectangle& r,
ushort opt)
{
if (!opt)
return;
#if defined(__MS_WINDOWS__)
HBRUSH hbr, old;
if (opt & UID_Fill) {
old = SelectObject (_handle, _brush->Handle());
}
else {
hbr = GetStockObject (HOLLOW_BRUSH);
old = SelectObject (_handle, hbr);
}
if (! (opt & UID_Outline))
SelectObject (_handle, GetStockObject (NULL_PEN));
Ellipse (_handle, r.Left (), r.Top (), r.Right (), r.Bottom ());
if (! (opt & UID_Outline))
SelectObject (_handle, _pen->Handle());
SelectObject (_handle, old);
#elif defined(__OS2__)
long width = r.Width();
long height = r.Height ();
POINTL ptLB, ptTR;
ptLB.x = r.Left();
ptLB.y = DrawingArea().Height() - r.Bottom() - 1;
ptTR.x = r.Right();
ptTR.y = ptLB.y + r.Height() - 1;
GpiSavePS (_handle);
if ((opt & UID_Fill) && (_brush->Pattern() != UIBrush_Hollow)) {
if (SupportsColor())
GpiSetColor (_handle, _brush->Color().NativeForm());
GpiMove (_handle, &ptLB);
GpiBox (_handle, DRO_FILL, &ptTR, width, height);
}
if (opt & UID_Outline) {
if (SupportsColor())
GpiSetColor (_handle, _pen->Color().NativeForm());
GpiMove (_handle, &ptLB);
GpiBox (_handle, DRO_OUTLINE, &ptTR, width, height);
}
GpiRestorePS (_handle, -1);
#endif
}
void UI_DrawingSurface::DrawArc (const UI_Arc& arc)
{
UI_Rectangle rect = arc.Ellipse().BoundingRectangle();
#if defined (__MS_WINDOWS__)
UI_Point pa, pb;
UI_PointPair pp = arc.EndPoints();
pa = pp.p1;
pb = pp.p2;
Arc (Handle(),
rect.Left(), rect.Top(),
rect.Right(), rect.Bottom(),
pa.XCoord(), pa.YCoord(),
pb.XCoord(), pb.YCoord());
#elif defined(__OS2__)
long width = rect.Width ();
long height = rect.Height ();
ARCPARAMS arcParams = {width/2, height/2, 0, 0};
GpiSetArcParams (_handle, &arcParams);
POINTL center;
UI_Point centerPt = rect.Center();
center.x = centerPt.XCoord();
center.y = DrawingArea().Height() - 1 - centerPt.YCoord();
long start = arc.StartAngle(), sweep = arc.SubtendedAngle();
GpiSetLineType (_handle, LINETYPE_INVISIBLE);
GpiPartialArc (_handle, ¢er, MAKEFIXED(1,0),
MAKEFIXED (start / 64, start % 64),
MAKEFIXED (0, 0));
if (_pen)
GpiSetLineType (_handle, _pen->OS2Pattern());
GpiPartialArc (_handle, ¢er, MAKEFIXED(1,0),
MAKEFIXED (start / 64, start % 64),
MAKEFIXED (sweep / 64, sweep % 64));
#else
NotImplemented ("DrawArc");
#endif
}
void UI_DrawingSurface::DrawChord (const UI_Chord& chord,
ushort opt)
{
UI_Rectangle rect = chord.Ellipse().BoundingRectangle();
#if defined (__MS_WINDOWS__)
HBRUSH hbr, old;
if (opt & UID_Fill) {
old = SelectObject (_handle, _brush->Handle());
}
else {
hbr = GetStockObject (HOLLOW_BRUSH);
old = SelectObject (_handle, hbr);
}
if (! (opt & UID_Outline))
SelectObject (_handle, GetStockObject (NULL_PEN));
UI_PointPair pp = chord.EndPoints();
Chord (Handle(),
rect.Left(), rect.Top(),
rect.Right(), rect.Bottom(),
pp.p1.XCoord(), pp.p1.YCoord(),
pp.p2.XCoord(), pp.p2.YCoord());
if (! (opt & UID_Outline))
SelectObject (_handle, _pen->Handle());
SelectObject (_handle, old);
#elif defined(__OS2__)
long width = rect.Width ();
long height = rect.Height ();
ARCPARAMS arcParams = {width/2, height/2, 0, 0};
GpiSetArcParams (_handle, &arcParams);
POINTL center;
UI_Point centerPt = rect.Center();
center.x = centerPt.XCoord();
center.y = DrawingArea().Height() - 1 - centerPt.YCoord();
long start = chord.StartAngle(), sweep = chord.SubtendedAngle();
GpiSetLineType (_handle, LINETYPE_INVISIBLE);
GpiPartialArc (_handle, ¢er, MAKEFIXED(1,0),
MAKEFIXED (start / 64, start % 64),
MAKEFIXED (0, 0));
POINTL startPt;
GpiQueryCurrentPosition (_handle, &startPt);
if ((opt & UID_Fill) && (_brush->Pattern() != UIBrush_Hollow)) {
if (SupportsColor())
GpiSetColor (_handle, _brush->Color().NativeForm());
GpiBeginArea (_handle, 0L);
GpiPartialArc (_handle, ¢er, MAKEFIXED(1,0),
MAKEFIXED (start / 64, start % 64),
MAKEFIXED (sweep / 64, sweep % 64));
GpiEndArea (_handle);
}
if (opt & UID_Outline) {
if (_pen) {
if (SupportsColor())
GpiSetColor (_handle, _pen->Color().NativeForm());
GpiSetLineType (_handle, _pen->OS2Pattern());
}
GpiPartialArc (_handle, ¢er, MAKEFIXED(1,0),
MAKEFIXED (start / 64, start % 64),
MAKEFIXED (sweep / 64, sweep % 64));
GpiLine (_handle, &startPt);
}
#else
NotImplemented ("DrawChord");
#endif
}
void UI_DrawingSurface::DrawPieWedge (const UI_PieWedge& pie,
ushort opt)
{
UI_Rectangle rect = pie.Ellipse().BoundingRectangle();
#if defined (__MS_WINDOWS__)
HBRUSH hbr, old;
if (opt & UID_Fill) {
old = SelectObject (_handle, _brush->Handle());
}
else {
hbr = GetStockObject (HOLLOW_BRUSH);
old = SelectObject (_handle, hbr);
}
if (! (opt & UID_Outline))
SelectObject (_handle, GetStockObject (NULL_PEN));
UI_PointPair pp = pie.EndPoints();
Pie (Handle(),
rect.Left(), rect.Top(),
rect.Right(), rect.Bottom(),
pp.p1.XCoord(), pp.p1.YCoord(),
pp.p2.XCoord(), pp.p2.YCoord());
if (! (opt & UID_Outline))
SelectObject (_handle, _pen->Handle());
SelectObject (_handle, old);
#elif defined(__OS2__)
long width = rect.Width ();
long height = rect.Height ();
ARCPARAMS arcParams = {width/2, height/2, 0, 0};
GpiSetArcParams (_handle, &arcParams);
POINTL center;
UI_Point centerPt = rect.Center();
center.x = centerPt.XCoord();
center.y = DrawingArea().Height() - 1 - centerPt.YCoord();
long start = pie.StartAngle(), sweep = pie.SubtendedAngle();
GpiMove (_handle, ¢er);
if ((opt & UID_Fill) && (_brush->Pattern() != UIBrush_Hollow)) {
if (SupportsColor())
GpiSetColor (_handle, _brush->Color().NativeForm());
GpiBeginArea (_handle, 0L);
GpiPartialArc (_handle, ¢er, MAKEFIXED(1,0),
MAKEFIXED (start / 64, start % 64),
MAKEFIXED (sweep / 64, sweep % 64));
GpiLine (_handle, ¢er);
GpiEndArea (_handle);
}
if (opt & UID_Outline) {
if (_pen) {
if (SupportsColor())
GpiSetColor (_handle, _pen->Color().NativeForm());
GpiSetLineType (_handle, _pen->OS2Pattern());
}
GpiPartialArc (_handle, ¢er, MAKEFIXED(1,0),
MAKEFIXED (start / 64, start % 64),
MAKEFIXED (sweep / 64, sweep % 64));
GpiLine (_handle, ¢er);
}
#else
NotImplemented ("DrawPieWedge");
#endif
}
void UI_DrawingSurface::DrawPolygon
(UI_Point point[], short num_pts, ushort opt)
{
if (num_pts < 2 || !opt)
return;
if (opt & UID_Fill) {
#if defined(__MS_WINDOWS__)
HRGN h = getPolyRgnMS (point, num_pts);
FillRgn (_handle, h, _brush->Handle());
DeleteObject (h);
#else
NotImplemented ("FillPolygon");
#endif
}
DrawPolyLine (point, num_pts);
DrawLine (point[num_pts-1], point[0]);
}
bool UI_DrawingSurface::DrawLine (const UI_Point& p, const UI_Point& q)
{
#if defined(__MS_WINDOWS__)
POINT array[2];
array[0].x = p.XCoord();
array[0].y = p.YCoord();
array[1].x = q.XCoord();
array[1].y = q.YCoord();
if (Polyline (Handle(), array, 2)) {
return TRUE;
}
return FALSE;
#elif defined(__OS2__)
if (!_handle)
return FALSE;
long height = DrawingArea().Height();
POINTL pt;
pt.x = p.XCoord();
pt.y = height - p.YCoord() + 1;
GpiSavePS (_handle);
GpiMove (_handle, &pt);
if (SupportsColor())
GpiSetColor (_handle, _pen->Color().NativeForm());
pt.x = q.XCoord();
pt.y = height - q.YCoord() + 1;
GpiLine (_handle, &pt);
GpiRestorePS (_handle, -1);
return TRUE;
#else
NotImplemented ("DrawLine");
return FALSE;
#endif
}
void UI_DrawingSurface::DrawPolyLine (UI_Point point[], short num_pts)
{
if (num_pts <= 1)
return;
#if defined(__MS_WINDOWS__)
for (short i = 1; i < num_pts; i++)
DrawLine (point[i-1], point[i]);
#elif defined(__OS2__)
POINTL* pts = new POINTL [num_pts-1];
if (!pts)
return; // No memory
long height = DrawingArea().Height();
pts[0].x = point[0].XCoord();
pts[0].y = height - point[0].YCoord() - 1;
GpiSavePS (_handle);
GpiMove (_handle, pts);
for (short i = 1; i < num_pts; i++) {
pts[i-1].x = point[i].XCoord();
pts[i-1].y = height - point[i].YCoord() - 1;
}
GpiPolyLine (_handle, num_pts-1, pts);
GpiRestorePS (_handle, -1);
delete pts;
#else
NotImplemented ("DrawPolyLine");
#endif
}
void UI_DrawingSurface::DrawRectangle (const UI_Rectangle& r,
ushort opt)
{
if (!opt)
return;
#if defined(__MS_WINDOWS__)
HBRUSH hbr, old;
if (opt & UID_Fill) {
old = SelectObject (_handle, _brush->Handle());
}
else {
hbr = GetStockObject (HOLLOW_BRUSH);
old = SelectObject (_handle, hbr);
}
if (! (opt & UID_Outline))
SelectObject (_handle, GetStockObject (NULL_PEN));
UI_Rectangle area = DrawingArea ();
long right = minl (r.Right() + 1, area.Right());
long bottom = minl (r.Bottom() + 1, area.Bottom());
Rectangle (_handle, r.Left (), r.Top (), right, bottom);
if (! (opt & UID_Outline))
SelectObject (_handle, _pen->Handle());
SelectObject (_handle, old);
#elif defined(__OS2__)
POINTL ptLB, ptTR;
ptLB.x = r.Left();
ptLB.y = DrawingArea().Height() - r.Bottom() - 1;
ptTR.x = r.Right();
ptTR.y = ptLB.y + r.Height() - 1;
GpiSavePS (_handle);
if ((opt & UID_Fill) && (_brush->Pattern() != UIBrush_Hollow)) {
if (SupportsColor())
GpiSetColor (_handle, _brush->Color().NativeForm());
GpiMove (_handle, &ptLB);
GpiBox (_handle, DRO_FILL, &ptTR, 0, 0);
}
if (opt & UID_Outline) {
if (SupportsColor())
GpiSetColor (_handle, _pen->Color().NativeForm());
GpiMove (_handle, &ptLB);
GpiBox (_handle, DRO_OUTLINE, &ptTR, 0, 0);
}
GpiRestorePS (_handle, -1);
#endif
}
void UI_DrawingSurface::DrawPoint (const UI_Point& p, const UI_Color& color)
{
#if defined(__MS_WINDOWS__)
SetPixel (_handle, p.XCoord(), p.YCoord(), color.NativeForm());
#elif defined(__OS2__)
GpiSavePS (_handle);
if (SupportsColor())
GpiSetColor (_handle, color.NativeForm());
POINTL pt;
pt.x = p.XCoord();
pt.y = DrawingArea().Height() - 1 - p.YCoord();
GpiSetPel (_handle, &pt);
GpiRestorePS (_handle, -1);
#else
NotImplemented ("DrawPoint");
#endif
}
void UI_DrawingSurface::WriteString (const CL_String& str,
const UI_Rectangle& tRect,
UI_TextStyle tStyle)
{
UI_Point p = tRect.Origin();
#if defined(__MS_WINDOWS__)
long style;
TEXTMETRIC tm;
RECT rect = tRect.AsMSRect();
rect.right++; rect.bottom++; // Fix for off-by-one
GetTextMetrics (_handle, &tm);
style = (tStyle == UIText_Left) ? DT_LEFT
: (tStyle == UIText_Center ? DT_CENTER : DT_RIGHT);
int oldMode = SetBkMode (_handle, TRANSPARENT);
DrawText(_handle, (const char*)str, str.Size(), &rect, style);
SetBkMode (_handle, oldMode);
#elif defined(__OS2__)
if (SupportsColor())
GpiSetColor (_handle, _pen->Color().NativeForm());
GpiSetBackMix (_handle, BM_LEAVEALONE);
UI_Font& fnt = Font();
short fontDescent = fnt.Descent(), fontAscent = fnt.Ascent();
long ht = DrawingArea().Height();
// Now adjust for the base line of the font
// (See p. 109 of Petzold's book)
POINTL stringBase;
stringBase.x = tRect.Left();
stringBase.y = ht - tRect.Top() - fontAscent;
RECTL clipRect;
clipRect.xLeft = tRect.Left();
if (tStyle == UIText_Center)
stringBase.x += (tRect.Width() - TextWidth (str))/2;
else if (tStyle == UIText_Right)
stringBase.x += tRect.Width() - TextWidth (str);
clipRect.yBottom = stringBase.y - fontDescent;
clipRect.xRight = tRect.Right();
clipRect.yTop = clipRect.yBottom + fontAscent + fontDescent - 1;
HRGN hrgn = GpiCreateRegion (_handle, 1, &clipRect);
HRGN oldRegion;
GpiSetClipRegion (_handle, hrgn, &oldRegion);
if (GpiCharStringAt (_handle, (PPOINTL) &stringBase, str.Length(),
(char*) str.AsPtr()) == GPI_ERROR)
UI_Application::PMError();
GpiSetClipRegion (_handle, NULLHANDLE, &oldRegion);
#else
NotImplemented ("WriteString");
#endif
}
short UI_DrawingSurface::TextWidth (const char* strg) const
{
#if defined (__MS_WINDOWS__)
CL_String s (strg);
return GetTextExtent (_handle, s.AsPtr(), s.Size());
#elif defined(__OS2__)
POINTL textBox[TXTBOX_COUNT];
GpiQueryTextBox (_handle, strlen (strg), (char*) strg,
TXTBOX_COUNT, textBox);
return textBox[TXTBOX_CONCAT].x;
#else
NotImplemented ("TextWidth"); // Implemented in DisplaySurface
return 0;
#endif
}
bool UI_DrawingSurface::DrawBitmap (const UI_Bitmap& b, const UI_Point& p)
{
#if defined (__MS_WINDOWS__)
long bmpHandle = b.Handle();
if (!bmpHandle)
return FALSE;
HDC destdc = Handle ();
if (!destdc)
return FALSE;
HDC hdc = CreateCompatibleDC (destdc);
if (!hdc)
return FALSE;
HANDLE oldh = SelectObject (hdc, bmpHandle);
SetMapMode (hdc, GetMapMode (destdc));
BITMAP bm;
POINT ptsize, ptorg;
GetObject (bmpHandle, sizeof (BITMAP), (LPSTR) &bm);
ptsize.x = bm.bmWidth;
ptsize.y = bm.bmHeight;
DPtoLP (destdc, &ptsize, 1);
ptorg.x = 0; ptorg.y = 0;
DPtoLP (hdc, &ptorg, 1);
BitBlt (destdc, p.XCoord(), p.YCoord(), b.Width(), b.Height(), hdc, 0, 0,
SRCCOPY);
SelectObject (hdc, oldh);
DeleteDC (hdc);
return TRUE;
#elif defined(__OS2__)
POINTL pt[4];
pt[0].x = p.XCoord();
pt[0].y = DrawingArea().Height() - p.YCoord() - b.Height() + 1;
pt[1].x = pt[0].x + b.Width () - 1;
pt[1].y = pt[0].y + b.Height () - 1;
pt[2].x = pt[2].y = 0;
pt[3].x = b.Width () - 1;
pt[3].y = b.Height () - 1;
GpiWCBitBlt (_handle, b.Handle(), 4, pt, ROP_SRCCOPY, BBO_AND);
return TRUE;
#else
NotImplemented ("DrawBitmap");
return FALSE;
#endif
}
#if defined(__MS_WINDOWS__)
HRGN getRectRgnMS (const UI_Rectangle& r)
{
int x1,y1,x2,y2;
x1 = r.TopLeftX();
y1 = r.TopLeftY();
x2 = x1 + r.Width();
y2 = y1 + r.Height();
return CreateRectRgn(x1,y1,x2,y2);
}
HRGN getPolyRgnMS (UI_Point p[], short numpts)
{
HRGN h;
POINT *msp;
msp = new POINT[numpts];
for (short i = 0; i < numpts; i++) {
msp[i].x = p[i].XCoord();
msp[i].y = p[i].YCoord();
}
h = CreatePolygonRgn (msp, numpts, WINDING);
delete msp;
return h;
}
#endif