source: trunk/src/gdi32/line.cpp@ 10563

Last change on this file since 10563 was 10563, checked in by sandervl, 21 years ago

bugfix

File size: 8.0 KB
Line 
1/* $Id: line.cpp,v 1.16 2004-03-25 15:06:37 sandervl Exp $ */
2/*
3 * Line API's
4 *
5 * Copyright 1999 Christoph Bratschi (cbratschi@datacomm.ch)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11#include <os2win.h>
12#include <math.h>
13#include "misc.h"
14#include "callback.h"
15#include "oslibgpi.h"
16#include <dcdata.h>
17#include "region.h"
18
19#define DBG_LOCALLOG DBG_line
20#include "dbglocal.h"
21
22#define ROUND_FLOAT(x) ((INT)((x < 0) ? x-0.5:x+0.5))
23
24//******************************************************************************
25//******************************************************************************
26VOID toWin32LineEnd(pDCData pHps, PPOINTLOS2 startPt,INT nXEnd,INT nYEnd,PPOINTLOS2 pt)
27{
28// SvL: This breaks path creation when used as a clip region in a printer DC
29// (offset by one for x coordinates make the rectangle not so rectangular anymore)
30// Removing it alltogether causes nice drawing errors on the screen, so
31// we'll simply ignore it when we're inside a path definition.
32 if(pHps->inPath)
33 {
34 LONG vertRes = hdcHeight(pHps->hwnd, pHps);
35 LONG horzRes = hdcWidth(pHps->hwnd, pHps);
36
37 // LineTo will return an error if the coordinates are outside the DC
38 pt->x = (nXEnd >= horzRes) ? horzRes-1 : nXEnd;
39 pt->y = (nYEnd >= vertRes) ? vertRes-1 : nYEnd;
40 }
41 else
42 if ((startPt->x != nXEnd) || (startPt->y != nYEnd))
43 {
44 if (nXEnd == startPt->x)
45 {
46 pt->x = nXEnd;
47 pt->y = (nYEnd > startPt->y) ? nYEnd-1:nYEnd+1;
48 } else if (nYEnd == startPt->y)
49 {
50 pt->x = (nXEnd > startPt->x) ? nXEnd-1:nXEnd+1;
51 pt->y = nYEnd;
52 } else
53 {
54 INT w = nXEnd-startPt->x,h = nYEnd-startPt->y;
55 DOUBLE len = hypot(w,h);
56 DOUBLE lenQuot = (len-1)/len;
57
58 pt->x = startPt->x+ROUND_FLOAT(w*lenQuot);
59 pt->y = startPt->y+ROUND_FLOAT(h*lenQuot);
60 }
61 } else
62 {
63 pt->x = nXEnd;
64 pt->y = nYEnd;
65 }
66}
67//******************************************************************************
68//******************************************************************************
69BOOL drawSingleLinePoint(HDC hdc,pDCData pHps,PPOINTLOS2 pt)
70{
71 LOGPEN penInfo;
72 EXTLOGPEN extpenInfo;
73
74 if (!GetObjectA(GetCurrentObject(hdc,OBJ_PEN),sizeof(penInfo),(LPVOID)&penInfo))
75 {//try extlogpen
76 if (!GetObjectA(GetCurrentObject(hdc,OBJ_PEN),sizeof(extpenInfo),(LPVOID)&extpenInfo)) {
77 return FALSE;
78 }
79 penInfo.lopnStyle = extpenInfo.elpPenStyle;
80 penInfo.lopnWidth.x = extpenInfo.elpWidth;
81 penInfo.lopnWidth.y = 0; //??????
82 penInfo.lopnColor = extpenInfo.elpColor;
83 }
84
85 if ((penInfo.lopnWidth.x > 1) || (penInfo.lopnWidth.y > 1))
86 {
87 if ((penInfo.lopnStyle != PS_INSIDEFRAME) && (penInfo.lopnStyle != PS_SOLID))
88 return FALSE;
89
90 LONG color = GetBValue(penInfo.lopnColor) | (GetGValue(penInfo.lopnColor)<<8) | (GetRValue(penInfo.lopnColor)<<16);
91
92 return drawLinePointCircle(pHps,penInfo.lopnWidth.x,penInfo.lopnWidth.y,color);
93 } else
94 {
95 LONG color = GetBValue(penInfo.lopnColor) | (GetGValue(penInfo.lopnColor)<<8) | (GetRValue(penInfo.lopnColor)<<16);
96
97 return drawLinePoint(pHps,pt,color);
98 }
99}
100//******************************************************************************
101//******************************************************************************
102BOOL WIN32API MoveToEx( HDC hdc, int X, int Y, LPPOINT lpPoint)
103{
104 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
105
106 dprintf(("GDI32: MoveToEx %x (%d,%d)", hdc, X, Y));
107
108 if (pHps)
109 {
110 POINTLOS2 newPoint = {X,Y};
111
112 if (lpPoint)
113 {
114 POINTLOS2 lastPoint;
115
116 OSLibGpiQueryCurrentPosition(pHps,&lastPoint);
117 lpPoint->x = lastPoint.x;
118 lpPoint->y = lastPoint.y;
119 }
120
121#ifndef INVERT
122 if(pHps->yInvert > 0) {
123 newPoint.y = pHps->yInvert - newPoint.y;
124 if (lpPoint) {
125 lpPoint->y = pHps->yInvert - lpPoint->y;
126 }
127 }
128#endif
129
130 if(OSLibGpiMove(pHps,&newPoint))
131 {
132 //CB: add metafile info
133 return TRUE;
134 }
135
136 return FALSE;
137 }
138
139 SetLastError(ERROR_INVALID_HANDLE);
140 return FALSE;
141}
142//******************************************************************************
143//******************************************************************************
144BOOL WIN32API LineTo( HDC hdc, int nXEnd, int nYEnd)
145{
146 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
147 BOOL rc = TRUE;
148
149 dprintf(("GDI32: LineTo %x (%d,%d)", hdc, nXEnd, nYEnd));
150
151 if (pHps)
152 {
153 POINTLOS2 oldPoint,newPoint;
154 BOOL bWideLine;
155
156#ifndef INVERT
157 if (pHps->yInvert > 0) {
158 nYEnd = pHps->yInvert - nYEnd;
159 }
160#endif
161
162 //CB: add metafile info
163
164 OSLibGpiQueryCurrentPosition(pHps,&oldPoint);
165 toWin32LineEnd(pHps, &oldPoint,nXEnd,nYEnd,&newPoint);
166
167 if ((oldPoint.x == newPoint.x) && (oldPoint.y == newPoint.y))
168 {
169 rc = drawSingleLinePoint(hdc,pHps,&newPoint);
170 } else
171 {
172 if (getIsWideLine(pHps))
173 {
174 rc = O32_LineTo(hdc,newPoint.x,newPoint.y); //CB: wide line not supported
175 } else
176 {
177 if (OSLibGpiLine(pHps,&newPoint) == FALSE)
178 rc = FALSE;
179 }
180 }
181
182 newPoint.x = nXEnd;
183 newPoint.y = nYEnd;
184 // Do not change the current position when we're defining a path.
185 // toWin32LineEnd can change the coordinates which would break up the path.
186 if (!pHps->inPath)
187 OSLibGpiMove(pHps,&newPoint);
188 }
189 else
190 {
191 SetLastError(ERROR_INVALID_HANDLE);
192 rc = FALSE;
193 }
194
195 return rc;
196}
197//******************************************************************************
198//******************************************************************************
199BOOL WIN32API LineDDA( int nXStart, int nYStart, int nXEnd, int nYEnd, LINEDDAPROC lpLineFunc, LPARAM lpData)
200{
201 BOOL rc;
202 LineDDAProcCallback *callback = new LineDDAProcCallback(lpLineFunc, lpData);
203 POINTLOS2 startPt,endPt;
204
205#if 0 //CB: the Open32 function is ok -> to check
206 startPt.x = nXStart;
207 startPt.y = nYStart;
208 toWin32LineEnd(&startPt,nXEnd,nYEnd,&endPt);
209
210 rc = O32_LineDDA(startPt.x,startPt.y,endPt.x,endPt.y, lpLineFunc, lpData);
211#else
212 rc = O32_LineDDA(nXStart,nYStart,nXEnd,nYEnd,callback->GetOS2Callback(),(LPARAM)callback);
213 if(callback)
214 delete callback;
215#endif
216 return(rc);
217}
218//******************************************************************************
219//******************************************************************************
220BOOL WIN32API Polyline( HDC hdc, const POINT *lppt, int cPoints)
221{
222 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
223
224 if (!pHps)
225 {
226 SetLastError(ERROR_INVALID_HANDLE);
227 return FALSE;
228 }
229
230 if (cPoints == 0) return TRUE;
231 if (cPoints < 0)
232 {
233 SetLastError(ERROR_INVALID_PARAMETER);
234 return FALSE;
235 }
236
237 if (cPoints == 1)
238 {
239 drawSingleLinePoint(hdc,pHps,(PPOINTLOS2)lppt); //CB: check metafile recording
240 return TRUE;
241 }
242
243 POINT *points = (POINT*)lppt;
244 POINT lastPt = lppt[cPoints-1];
245 BOOL rc;
246
247 toWin32LineEnd(pHps, (PPOINTLOS2)&lppt[cPoints-2],lastPt.x,lastPt.y,(PPOINTLOS2)&points[cPoints-1]);
248 rc = O32_Polyline(hdc,lppt,cPoints);
249 points[cPoints-1] = lastPt;
250
251 return rc;
252}
253//******************************************************************************
254//******************************************************************************
255BOOL WIN32API PolylineTo( HDC hdc, const POINT * lppt, DWORD cCount)
256{
257 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
258
259 if (!pHps)
260 {
261 SetLastError(ERROR_INVALID_HANDLE);
262 return FALSE;
263 }
264
265 if (cCount == 0) return TRUE;
266
267 //CB: add metafile info
268
269 if (cCount == 1)
270 {
271 drawSingleLinePoint(hdc,pHps,(PPOINTLOS2)lppt);
272 return TRUE;
273 }
274
275 POINT *points = (POINT*)lppt;
276 POINT lastPt = lppt[cCount-1];
277 BOOL rc;
278
279 toWin32LineEnd(pHps, (PPOINTLOS2)&lppt[cCount-2],lastPt.x,lastPt.y,(PPOINTLOS2)&points[cCount-1]);
280 rc = O32_PolylineTo(hdc,lppt,cCount);
281 points[cCount-1] = lastPt;
282 OSLibGpiMove(pHps,(PPOINTLOS2)&lastPt);
283
284 return rc;
285}
286//******************************************************************************
287//******************************************************************************
288
Note: See TracBrowser for help on using the repository browser.