xref: /aoo4110/main/vcl/os2/source/gdi/salgdi.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include <string.h>
25 #include <svpm.h>
26 
27 #define _SV_SALGDI_CXX
28 #include <tools/debug.hxx>
29 #include <os2/saldata.hxx>
30 #include <os2/salgdi.h>
31 #include <tools/debug.hxx>
32 #include <os2/salframe.h>
33 #include <tools/poly.hxx>
34 #ifndef _RTL_STRINGBUF_HXX
35 #include <rtl/strbuf.hxx>
36 #endif
37 
38 #ifndef __H_FT2LIB
39 #include <os2/wingdi.h>
40 #include <ft2lib.h>
41 #endif
42 
43 // -----------
44 // - Defines -
45 // -----------
46 
47 // ClipRegions funktionieren immer noch nicht auf allen getesteten Druckern
48 #define SAL_PRINTER_CLIPPATH	1
49 // #define SAL_PRINTER_POLYPATH 1
50 
51 // =======================================================================
52 
ImplInitSalGDI()53 void ImplInitSalGDI()
54 {
55 }
56 
57 // -----------------------------------------------------------------------
58 
ImplFreeSalGDI()59 void ImplFreeSalGDI()
60 {
61 	SalData*	pSalData = GetSalData();
62 
63     // delete icon cache
64     SalIcon* pIcon = pSalData->mpFirstIcon;
65     while( pIcon )
66     {
67         SalIcon* pTmp = pIcon->pNext;
68         WinDestroyPointer( pIcon->hIcon );
69         delete pIcon;
70         pIcon = pTmp;
71     }
72 
73 }
74 
75 // =======================================================================
76 
ImplSalInitGraphics(Os2SalGraphics * pData)77 void ImplSalInitGraphics( Os2SalGraphics* pData )
78 {
79 	GpiCreateLogColorTable( pData->mhPS, LCOL_RESET, LCOLF_RGB, 0, 0, NULL );
80 }
81 
82 // -----------------------------------------------------------------------
83 
ImplSalDeInitGraphics(Os2SalGraphics * pData)84 void ImplSalDeInitGraphics( Os2SalGraphics* pData )
85 {
86 }
87 
88 // =======================================================================
89 
Os2SalGraphics()90 Os2SalGraphics::Os2SalGraphics()
91 {
92     for( int i = 0; i < MAX_FALLBACK; ++i )
93     {
94         mhFonts[ i ] = 0;
95         mpOs2FontData[ i ]  = NULL;
96         mpOs2FontEntry[ i ] = NULL;
97     }
98 
99     mfFontScale = 1.0;
100 
101 	mhPS 			= 0;
102 	mhDC 			= 0;
103 	mbLine				= FALSE;
104 	mbFill				= FALSE;
105 	mbXORMode			= FALSE;
106 	mnFontMetricCount	= 0;
107 	mpFontMetrics		= NULL;
108 	mpClipRectlAry		= NULL;
109 
110 	mhDefFont			= 0;
111 	mpFontKernPairs		= NULL;
112 	mnFontKernPairCount	= 0;
113 	mbFontKernInit		= FALSE;
114 
115 }
116 
117 // -----------------------------------------------------------------------
118 
~Os2SalGraphics()119 Os2SalGraphics::~Os2SalGraphics()
120 {
121 	Ft2DeleteSetId( mhPS, LCID_BASE);
122 
123 	if ( mpFontMetrics )
124 		delete mpFontMetrics;
125 
126 	if ( mpFontKernPairs )
127 		delete mpFontKernPairs;
128 
129 }
130 
131 // -----------------------------------------------------------------------
132 
ImplGetROPSalColor(SalROPColor nROPColor)133 static SalColor ImplGetROPSalColor( SalROPColor nROPColor )
134 {
135 	SalColor nSalColor;
136 
137 	switch( nROPColor )
138 	{
139 		case SAL_ROP_0:
140 			nSalColor = MAKE_SALCOLOR( 0, 0, 0 );
141 		break;
142 
143 		case SAL_ROP_1:
144 		case SAL_ROP_INVERT:
145 			nSalColor = MAKE_SALCOLOR( 255, 255, 255 );
146 		break;
147 	}
148 
149 	return nSalColor;
150 }
151 
152 // -----------------------------------------------------------------------
153 
GetResolution(sal_Int32 & rDPIX,sal_Int32 & rDPIY)154 void Os2SalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
155 {
156 	// since OOo asks for DPI, I will query FONT_RES, which seems to be
157 	// more correct than _RESOLUTION fields (on my wide screen lcd)
158 	// and does not require conversion
159 	long nDPIX = 72, nDPIY = 72;
160 	DevQueryCaps( mhDC, CAPS_HORIZONTAL_FONT_RES, 1, &nDPIX );
161 	DevQueryCaps( mhDC, CAPS_VERTICAL_FONT_RES, 1, &nDPIY );
162 	rDPIX = nDPIX;
163 	rDPIY = nDPIY;
164 }
165 
166 // -----------------------------------------------------------------------
167 
GetBitCount()168 USHORT Os2SalGraphics::GetBitCount()
169 {
170 	LONG nBitCount;
171 	DevQueryCaps( mhDC, CAPS_COLOR_BITCOUNT, 1, &nBitCount );
172 	return (USHORT)nBitCount;
173 }
174 
175 // -----------------------------------------------------------------------
176 
GetGraphicsWidth() const177 long Os2SalGraphics::GetGraphicsWidth() const
178 {
179     if( mhWnd )
180     {
181         Os2SalFrame* pFrame = (Os2SalFrame*)GetWindowPtr( mhWnd );
182         if( pFrame )
183         {
184             if( pFrame->maGeometry.nWidth )
185                 return pFrame->maGeometry.nWidth;
186             else
187             {
188                 // TODO: perhaps not needed, maGeometry should always be up-to-date
189                 RECTL aRect;
190                 WinQueryWindowRect( mhWnd, &aRect );
191                 return aRect.xRight;
192             }
193         }
194     }
195 
196     return 0;
197 }
198 
199 // -----------------------------------------------------------------------
200 
ResetClipRegion()201 void Os2SalGraphics::ResetClipRegion()
202 {
203 #ifdef SAL_PRINTER_CLIPPATH
204 	if ( mbPrinter )
205 		GpiSetClipPath( mhPS, 0, SCP_RESET );
206 	else
207 #endif
208 	{
209 		HRGN hOldRegion;
210 
211 		GpiSetClipRegion( mhPS, NULL, &hOldRegion );
212 		if ( hOldRegion )
213 			GpiDestroyRegion( mhPS, hOldRegion );
214 	}
215 }
216 
217 // -----------------------------------------------------------------------
218 
setClipRegion(const Region & i_rClip)219 bool Os2SalGraphics::setClipRegion( const Region& i_rClip )
220 {
221     RectangleVector aRectangles;
222     i_rClip.GetRegionRectangles(aRectangles);
223     mnClipElementCount = aRectangles.size();
224     mpClipRectlAry = 0;
225 
226     if(mnClipElementCount)
227     {
228         mpClipRectlAry = new RECTL[mnClipElementCount];
229 
230         for(sal_uInt32 a(0); a < mnClipElementCount; a++)
231         {
232             const Rectangle& rRect = aRectangles[a];
233             RECTL* pClipRect = &mpClipRectlAry[a];
234 
235             pClipRect->xLeft = rRect.Left();
236             pClipRect->yTop = mnHeight - rRect.Top();
237             pClipRect->xRight = rRect.Right() + 1; // nX + nW -> L + ((R - L) + 1) -> R + 1
238             pClipRect->yBottom = mnHeight - (rRect.Bottom() + 1); // same for height
239         }
240     }
241 
242 //    ULONG nCount = i_rClip.GetRectCount();
243 //
244 //	mpClipRectlAry	  = new RECTL[ nCount ];
245 //	mnClipElementCount = 0;
246 //
247 //    ImplRegionInfo aInfo;
248 //    long nX, nY, nW, nH;
249 //    bool bRegionRect = i_rClip.ImplGetFirstRect(aInfo, nX, nY, nW, nH );
250 //    while( bRegionRect )
251 //    {
252 //        if ( nW && nH )
253 //        {
254 //            RECTL* pClipRect = &mpClipRectlAry[ mnClipElementCount ];
255 //            pClipRect->xLeft   = nX;
256 //            pClipRect->yTop    = mnHeight - nY;
257 //            pClipRect->xRight  = nX + nW;
258 //            pClipRect->yBottom = mnHeight - (nY + nH);
259 //            mnClipElementCount++;
260 //        }
261 //        bRegionRect = i_rClip.ImplGetNextRect( aInfo, nX, nY, nW, nH );
262 //    }
263 #ifdef SAL_PRINTER_CLIPPATH
264 	if ( mbPrinter )
265 	{
266 		GpiSetClipPath( mhPS, 0, SCP_RESET );
267 		GpiBeginPath( mhPS, 1L );
268 
269 		for( int i = 0; i < mnClipElementCount; i++ )
270 		{
271 			POINTL aPt;
272 			RECTL* pClipRect = &mpClipRectlAry[ i ];
273 
274 			aPt.x = pClipRect->xLeft;
275 			aPt.y = pClipRect->yTop-1;
276 			Ft2Move( mhPS, &aPt );
277 
278 			aPt.x = pClipRect->xRight-1;
279 			aPt.y = pClipRect->yBottom;
280 
281 			Ft2Box( mhPS, DRO_OUTLINE, &aPt, 0, 0 );
282 		}
283 
284 		GpiEndPath( mhPS );
285 		GpiSetClipPath( mhPS, 1L, SCP_ALTERNATE | SCP_AND );
286 	}
287 	else
288 #endif
289 	{
290 		HRGN hClipRegion = GpiCreateRegion( mhPS,
291 											mnClipElementCount,
292 											mpClipRectlAry );
293 		HRGN hOldRegion;
294 
295 		GpiSetClipRegion( mhPS, hClipRegion, &hOldRegion );
296 		if( hOldRegion )
297 			GpiDestroyRegion( mhPS, hOldRegion );
298 	}
299 
300 	delete [] mpClipRectlAry;
301 
302     return true;
303 }
304 
305 // -----------------------------------------------------------------------
306 
SetLineColor()307 void Os2SalGraphics::SetLineColor()
308 {
309 	// don't draw line!
310 	mbLine = FALSE;
311 }
312 
313 // -----------------------------------------------------------------------
314 
SetLineColor(SalColor nSalColor)315 void Os2SalGraphics::SetLineColor( SalColor nSalColor )
316 {
317 	LINEBUNDLE lb;
318 
319 	// set color
320 	lb.lColor = MAKE_SALCOLOR( SALCOLOR_RED( nSalColor ),
321 						  SALCOLOR_GREEN( nSalColor ),
322 						  SALCOLOR_BLUE( nSalColor ) );
323 
324 	Ft2SetAttrs( mhPS,
325 				 PRIM_LINE,
326 				 LBB_COLOR,
327 				 0,
328 				 &lb );
329 
330 	// draw line!
331 	mbLine = TRUE;
332 }
333 
334 // -----------------------------------------------------------------------
335 
SetFillColor()336 void Os2SalGraphics::SetFillColor()
337 {
338 	// don't fill area!
339 	mbFill = FALSE;
340 }
341 
342 // -----------------------------------------------------------------------
343 
SetFillColor(SalColor nSalColor)344 void Os2SalGraphics::SetFillColor( SalColor nSalColor )
345 {
346 	AREABUNDLE ab;
347 
348 	// set color
349 	ab.lColor = MAKE_SALCOLOR( SALCOLOR_RED( nSalColor ),
350 						  SALCOLOR_GREEN( nSalColor ),
351 						  SALCOLOR_BLUE( nSalColor ) );
352 
353 	Ft2SetAttrs( mhPS,
354 				 PRIM_AREA,
355 				 ABB_COLOR,
356 				 0,
357 				 &ab );
358 
359 	// fill area!
360 	mbFill = TRUE;
361 }
362 
363 // -----------------------------------------------------------------------
364 
SetXORMode(bool bSet,bool)365 void Os2SalGraphics::SetXORMode( bool bSet, bool )
366 {
367 	mbXORMode = bSet;
368 	LONG nMixMode = bSet ? FM_XOR : FM_OVERPAINT;
369 
370 	// set mix mode for lines
371 	LINEBUNDLE lb;
372 	lb.usMixMode = nMixMode;
373 	Ft2SetAttrs( mhPS,
374 				 PRIM_LINE,
375 				 LBB_MIX_MODE,
376 				 0,
377 				 &lb );
378 
379 	// set mix mode for areas
380 	AREABUNDLE ab;
381 	ab.usMixMode = nMixMode;
382 	Ft2SetAttrs( mhPS,
383 				 PRIM_AREA,
384 				 ABB_MIX_MODE,
385 				 0,
386 				 &ab );
387 
388 	// set mix mode for text
389 	CHARBUNDLE cb;
390 	cb.usMixMode = nMixMode;
391 	Ft2SetAttrs( mhPS,
392 				 PRIM_CHAR,
393 				 CBB_MIX_MODE,
394 				 0,
395 				 &cb );
396 }
397 
398 // -----------------------------------------------------------------------
399 
SetROPLineColor(SalROPColor nROPColor)400 void Os2SalGraphics::SetROPLineColor( SalROPColor nROPColor )
401 {
402 	SetLineColor( ImplGetROPSalColor( nROPColor ) );
403 }
404 
405 // -----------------------------------------------------------------------
406 
SetROPFillColor(SalROPColor nROPColor)407 void Os2SalGraphics::SetROPFillColor( SalROPColor nROPColor )
408 {
409 	SetFillColor( ImplGetROPSalColor( nROPColor ) );
410 }
411 
412 // -----------------------------------------------------------------------
413 
drawPixel(long nX,long nY)414 void Os2SalGraphics::drawPixel( long nX, long nY )
415 {
416 	POINTL aPt;
417 
418 	aPt.x = nX;
419 	aPt.y = TY( nY );
420 
421 	// set color
422 	Ft2SetPel( mhPS, &aPt );
423 }
424 
425 // -----------------------------------------------------------------------
426 
drawPixel(long nX,long nY,SalColor nSalColor)427 void Os2SalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
428 {
429 	// save old color
430 	LINEBUNDLE oldLb;
431 	GpiQueryAttrs( mhPS,
432 				   PRIM_LINE,
433 				   LBB_COLOR,
434 				   &oldLb );
435 
436 	// set new color
437 	LINEBUNDLE lb;
438 	lb.lColor = MAKE_SALCOLOR( SALCOLOR_RED( nSalColor ),
439 						  SALCOLOR_GREEN( nSalColor ),
440 						  SALCOLOR_BLUE( nSalColor ) );
441 	Ft2SetAttrs( mhPS,
442 				 PRIM_LINE,
443 				 LBB_COLOR,
444 				 0,
445 				 &lb );
446 
447 	// set color of pixel
448 	POINTL aPt;
449 	aPt.x = nX;
450 	aPt.y = TY( nY );
451 	Ft2SetPel( mhPS, &aPt );
452 
453 	// restore old color
454 	Ft2SetAttrs( mhPS,
455 				 PRIM_LINE,
456 				 LBB_COLOR,
457 				 0,
458 				 &oldLb );
459 }
460 
461 // -----------------------------------------------------------------------
462 
drawLine(long nX1,long nY1,long nX2,long nY2)463 void Os2SalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
464 {
465 	// OS2 zeichnet den Endpunkt mit
466 	POINTL aPt;
467 	aPt.x = nX1;
468 	aPt.y = TY( nY1 );
469 	Ft2Move( mhPS, &aPt );
470 	aPt.x = nX2;
471 	aPt.y = TY( nY2 );
472 	GpiLine( mhPS, &aPt );
473 }
474 
475 // -----------------------------------------------------------------------
476 
drawRect(long nX,long nY,long nWidth,long nHeight)477 void Os2SalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
478 {
479 	POINTL aPt;
480 	long lControl;
481 
482 	if ( mbFill )
483 	{
484 		if ( mbLine )
485 			lControl = DRO_OUTLINEFILL;
486 		else
487 			lControl = DRO_FILL;
488 	}
489 	else
490 	{
491 		if ( mbLine )
492 			lControl = DRO_OUTLINE;
493 		else
494 			return;
495 	}
496 
497 	aPt.x = nX;
498 	aPt.y = TY( nY );
499 	Ft2Move( mhPS, &aPt );
500 	aPt.x = nX + nWidth - 1;
501 	aPt.y = TY( nY + nHeight - 1 );
502 	Ft2Box( mhPS, lControl, &aPt, 0, 0 );
503 }
504 
505 // -----------------------------------------------------------------------
506 
drawPolyLine(sal_uInt32 nPoints,const SalPoint * pPtAry)507 void Os2SalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
508 {
509 	// convert all points to sys orientation
510 	POINTL* 			pOS2PtAry = new POINTL[ nPoints ];
511 	POINTL* 			pTempOS2PtAry = pOS2PtAry;
512 	const SalPoint* 	pTempPtAry = pPtAry;
513 	sal_uInt32			nTempPoints = nPoints;
514 	long				nHeight = mnHeight - 1;
515 
516 	while( nTempPoints-- )
517 	{
518 		(*pTempOS2PtAry).x = (*pTempPtAry).mnX;
519 		(*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
520 		pTempOS2PtAry++;
521 		pTempPtAry++;
522 	}
523 
524 	Ft2Move( mhPS, pOS2PtAry );
525 	GpiPolyLine( mhPS, nPoints, pOS2PtAry );
526 	delete [] pOS2PtAry;
527 }
528 
529 // -----------------------------------------------------------------------
530 
drawPolygon(sal_uInt32 nPoints,const SalPoint * pPtAry)531 void Os2SalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
532 {
533 	PM_POLYGON aPolygon;
534 
535 	// create polygon
536 	aPolygon.aPointl = new POINTL[ nPoints ];
537 	aPolygon.ulPoints = nPoints;
538 
539 	// convert all points to sys orientation
540 	POINTL* 			pTempOS2PtAry = aPolygon.aPointl;
541 	const SalPoint* 	pTempPtAry = pPtAry;
542 	sal_uInt32			nTempPoints = nPoints;
543 	long				nHeight = mnHeight - 1;
544 
545 	while( nTempPoints-- )
546 	{
547 		(*pTempOS2PtAry).x = (*pTempPtAry).mnX;
548 		(*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
549 		pTempOS2PtAry++;
550 		pTempPtAry++;
551 	}
552 
553 	// Innenleben zeichnen
554 	if ( mbFill )
555 	{
556 #ifdef SAL_PRINTER_POLYPATH
557 		if ( mbPrinter )
558 		{
559 			Ft2BeginPath( mhPS, 1 );
560 			Ft2Move( mhPS, aPolygon.aPointl );
561 			Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl );
562 			Ft2EndPath( mhPS );
563 			Ft2FillPath( mhPS, 1, 0 );
564 
565 			if ( mbLine )
566 			{
567 				Ft2Move( mhPS, aPolygon.aPointl );
568 				Ft2PolyLine( mhPS, aPolygon.ulPoints, aPolygon.aPointl );
569 			}
570 		}
571 		else
572 #endif
573 		{
574 			ULONG nOptions = POLYGON_ALTERNATE;
575 
576 			if ( mbLine )
577 				nOptions |= POLYGON_BOUNDARY;
578 			else
579 				nOptions |= POLYGON_NOBOUNDARY;
580 
581 			Ft2Move( mhPS, aPolygon.aPointl );
582 			GpiPolygons( mhPS, 1, &aPolygon, nOptions, POLYGON_EXCL );
583 		}
584 	}
585 	else
586 	{
587 		if ( mbLine )
588 		{
589 			Ft2Move( mhPS, aPolygon.aPointl );
590 			GpiPolyLine( mhPS, nPoints, aPolygon.aPointl );
591 		}
592 	}
593 
594 	delete [] aPolygon.aPointl;
595 }
596 
597 // -----------------------------------------------------------------------
598 
drawPolyPolygon(sal_uInt32 nPoly,const sal_uInt32 * pPoints,PCONSTSALPOINT * pPtAry)599 void Os2SalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints,
600 								   PCONSTSALPOINT* pPtAry )
601 {
602 	ULONG		i;
603 	long		nHeight = mnHeight - 1;
604 	PM_POLYGON*	aPolygonAry = new PM_POLYGON[ nPoly ];
605 
606 	for( i = 0; i < nPoly; i++ )
607 	{
608 		const SalPoint * pTempPtAry = (const SalPoint*)pPtAry[ i ];
609 
610 		// create polygon
611 		ULONG nTempPoints = pPoints[ i ];
612 		POINTL * pTempOS2PtAry = new POINTL[ nTempPoints ];
613 
614 		// convert all points to sys orientation
615 		aPolygonAry[ i ].ulPoints = nTempPoints;
616 		aPolygonAry[ i ].aPointl = pTempOS2PtAry;
617 
618 		while( nTempPoints-- )
619 		{
620 			(*pTempOS2PtAry).x = (*pTempPtAry).mnX;
621 			(*pTempOS2PtAry).y = nHeight - (*pTempPtAry).mnY;
622 			pTempOS2PtAry++;
623 			pTempPtAry++;
624 		}
625 	}
626 
627 	// Innenleben zeichnen
628 	if ( mbFill )
629 	{
630 #ifdef SAL_PRINTER_POLYPATH
631 		if ( mbPrinter )
632 		{
633 			Ft2BeginPath( mhPS, 1 );
634 			for ( i = 0; i < nPoly; i++ )
635 			{
636 				Ft2Move( mhPS, aPolygonAry[i].aPointl );
637 				Ft2PolyLine( mhPS, aPolygonAry[i].ulPoints, aPolygonAry[i].aPointl );
638 			}
639 			Ft2EndPath( mhPS );
640 			Ft2FillPath( mhPS, 1, 0 );
641 		}
642 		else
643 #endif
644 		{
645 			ULONG nOptions = POLYGON_ALTERNATE;
646 
647 			if ( mbLine )
648 				nOptions |= POLYGON_BOUNDARY;
649 			else
650 				nOptions |= POLYGON_NOBOUNDARY;
651 
652 			Ft2Move( mhPS, aPolygonAry[ 0 ].aPointl );
653 			GpiPolygons( mhPS, nPoly, aPolygonAry, nOptions, POLYGON_EXCL );
654 		}
655 	}
656 	else
657 	{
658 		if ( mbLine )
659 		{
660 			for( i = 0; i < nPoly; i++ )
661 			{
662 				Ft2Move( mhPS, aPolygonAry[ i ].aPointl );
663 				GpiPolyLine( mhPS, aPolygonAry[ i ].ulPoints, aPolygonAry[ i ].aPointl );
664 			}
665 		}
666 	}
667 
668 	// cleanup
669 	for( i = 0; i < nPoly; i++ )
670 		delete [] aPolygonAry[ i ].aPointl;
671 	delete [] aPolygonAry;
672 }
673 
674 // -----------------------------------------------------------------------
675 
drawPolyPolygon(const::basegfx::B2DPolyPolygon &,double)676 bool Os2SalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
677 {
678 	// TODO: implement and advertise OutDevSupport_B2DDraw support
679 	return false;
680 }
681 
682 // -----------------------------------------------------------------------
683 
drawPolyLine(const basegfx::B2DPolygon &,double,const basegfx::B2DVector &,basegfx::B2DLineJoin,com::sun::star::drawing::LineCap)684 bool Os2SalGraphics::drawPolyLine(
685     const basegfx::B2DPolygon& /*rPolygon*/,
686     double /*fTransparency*/,
687     const basegfx::B2DVector& /*rLineWidths*/,
688     basegfx::B2DLineJoin /*eLineJoin*/,
689     com::sun::star::drawing::LineCap /*eLineCap*/)
690 {
691     // TODO: implement
692     return false;
693 }
694 
695 // -----------------------------------------------------------------------
696 
drawPolyLineBezier(sal_uInt32,const SalPoint * pPtAry,const sal_uInt8 * pFlgAry)697 sal_Bool Os2SalGraphics::drawPolyLineBezier( sal_uInt32 /*nPoints*/, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
698 {
699     return sal_False;
700 }
701 
702 // -----------------------------------------------------------------------
703 
drawPolygonBezier(sal_uInt32,const SalPoint * pPtAry,const sal_uInt8 * pFlgAry)704 sal_Bool Os2SalGraphics::drawPolygonBezier( sal_uInt32 /*nPoints*/, const SalPoint* pPtAry, const sal_uInt8* pFlgAry )
705 {
706     return sal_False;
707 }
708 
709 // -----------------------------------------------------------------------
710 
drawPolyPolygonBezier(sal_uInt32,const sal_uInt32 *,const SalPoint * const * pPtAry,const sal_uInt8 * const * pFlgAry)711 sal_Bool Os2SalGraphics::drawPolyPolygonBezier( sal_uInt32 /*nPoly*/, const sal_uInt32* /*pPoints*/,
712                                              const SalPoint* const* pPtAry, const sal_uInt8* const* pFlgAry )
713 {
714     return sal_False;
715 }
716 
717 // =======================================================================
718 
719 // MAXIMUM BUFSIZE EQ 0xFFFF
720 #define POSTSCRIPT_BUFSIZE			0x4000
721 // we only try to get the BoundingBox in the first 4096 PM_BYTEs
722 #define POSTSCRIPT_BOUNDINGSEARCH	0x1000
723 
ImplSearchEntry(PM_BYTE * pSource,PM_BYTE * pDest,ULONG nComp,ULONG nSize)724 static PM_BYTE* ImplSearchEntry( PM_BYTE* pSource, PM_BYTE* pDest, ULONG nComp, ULONG nSize )
725 {
726 	while ( nComp-- >= nSize )
727 	{
728 		ULONG	i;
729 		for ( i = 0; i < nSize; i++ )
730 		{
731 			if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
732 				break;
733 		}
734 		if ( i == nSize )
735 			return pSource;
736 		pSource++;
737 	}
738 	return NULL;
739 }
740 
741 
ImplGetBoundingBox(double * nNumb,PM_BYTE * pSource,ULONG nSize)742 static PM_BOOL ImplGetBoundingBox( double* nNumb, PM_BYTE* pSource, ULONG nSize )
743 {
744 	PM_BOOL	bRetValue = FALSE;
745 	PM_BYTE* pDest = ImplSearchEntry( pSource, (PM_BYTE*)"%%BoundingBox:", nSize, 14 );
746 	if ( pDest )
747 	{
748 		nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
749 		pDest += 14;
750 
751 		int nSizeLeft = nSize - ( pDest - pSource );
752 		if ( nSizeLeft > 100 )
753 			nSizeLeft = 100;	// only 100 PM_BYTEs following the bounding box will be checked
754 
755 		int i;
756 		for ( i = 0; ( i < 4 ) && nSizeLeft; i++ )
757 		{
758 			int 	nDivision = 1;
759 			PM_BOOL	bDivision = FALSE;
760 			PM_BOOL	bNegative = FALSE;
761 			PM_BOOL	bValid = TRUE;
762 
763 			while ( ( --nSizeLeft ) && ( *pDest == ' ' ) || ( *pDest == 0x9 ) ) pDest++;
764 			PM_BYTE nPM_BYTE = *pDest;
765 			while ( nSizeLeft && ( nPM_BYTE != ' ' ) && ( nPM_BYTE != 0x9 ) && ( nPM_BYTE != 0xd ) && ( nPM_BYTE != 0xa ) )
766 			{
767 				switch ( nPM_BYTE )
768 				{
769 					case '.' :
770 						if ( bDivision )
771 							bValid = FALSE;
772 						else
773 							bDivision = TRUE;
774 						break;
775 					case '-' :
776 						bNegative = TRUE;
777 						break;
778 					default :
779 						if ( ( nPM_BYTE < '0' ) || ( nPM_BYTE > '9' ) )
780 							nSizeLeft = 1; 	// error parsing the bounding box values
781 						else if ( bValid )
782 						{
783 							if ( bDivision )
784 								nDivision*=10;
785 							nNumb[i] *= 10;
786 							nNumb[i] += nPM_BYTE - '0';
787 						}
788 						break;
789 				}
790 				nSizeLeft--;
791 				nPM_BYTE = *(++pDest);
792 			}
793 			if ( bNegative )
794 				nNumb[i] = -nNumb[i];
795 			if ( bDivision && ( nDivision != 1 ) )
796 				nNumb[i] /= nDivision;
797 		}
798 		if ( i == 4 )
799 			bRetValue = TRUE;
800 	}
801 	return bRetValue;
802 }
803 
804 #if 0
805 static void ImplWriteDouble( PM_BYTE** pBuf, double nNumber )
806 {
807 //	*pBuf += sprintf( (char*)*pBuf, "%f", nNumber );
808 
809 	if ( nNumber < 0 )
810 	{
811 		*(*pBuf)++ = (PM_BYTE)'-';
812 		nNumber = -nNumber;
813 	}
814 	ULONG nTemp = (ULONG)nNumber;
815 	const String aNumber1( nTemp );
816 	ULONG nLen = aNumber1.Len();
817 
818 	for ( USHORT n = 0; n < nLen; n++ )
819 		*(*pBuf)++ = aNumber1[ n ];
820 
821 	nTemp = (ULONG)( ( nNumber - nTemp ) * 100000 );
822 	if ( nTemp )
823 	{
824 		*(*pBuf)++ = (PM_BYTE)'.';
825 		const String aNumber2( nTemp );
826 
827 		ULONG nLen = aNumber2.Len();
828 		if ( nLen < 8 )
829 		{
830 			for ( n = 0; n < ( 5 - nLen ); n++ )
831 			{
832 				*(*pBuf)++ = (PM_BYTE)'0';
833 			}
834 		}
835 		for ( USHORT n = 0; n < nLen; n++ )
836 		{
837 			*(*pBuf)++ = aNumber2[ n ];
838 		}
839 	}
840 	*(*pBuf)++ = ' ';
841 }
842 #endif
843 
ImplWriteString(PM_BYTE ** pBuf,const char * sString)844 inline void ImplWriteString( PM_BYTE** pBuf, const char* sString )
845 {
846 	strcpy( (char*)*pBuf, sString );
847 	*pBuf += strlen( sString );
848 }
849 
drawEPS(long nX,long nY,long nWidth,long nHeight,void * pPtr,ULONG nSize)850 sal_Bool Os2SalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void* pPtr, ULONG nSize )
851 {
852 	if ( !mbPrinter )
853 		return FALSE;
854 
855 	PM_BOOL	bRet  = FALSE;
856 	LONG	nLong = 0;
857 	if ( !(DevQueryCaps( mhDC, CAPS_TECHNOLOGY, 1, &nLong ) &&
858 		   (CAPS_TECH_POSTSCRIPT == nLong)) )
859 		return FALSE;
860 
861 	PM_BYTE*	pBuf = new PM_BYTE[ POSTSCRIPT_BUFSIZE ];
862 	double	nBoundingBox[4];
863 
864 	if ( pBuf && ImplGetBoundingBox( nBoundingBox, (PM_BYTE*)pPtr, nSize ) )
865 	{
866 		LONG pOS2DXAry[4];		  // hack -> print always 2 white space
867 		POINTL aPt;
868 		aPt.x = 0;
869 		aPt.y = 0;
870 		PCH pStr = (PCH) "  ";
871 		for( long i = 0; i < 4; i++ )
872 			pOS2DXAry[i] = i;
873 		Ft2CharStringPosAt( mhPS, &aPt, NULL, 0, 2, (PCH)pStr,(PLONG)&pOS2DXAry[0] );
874 
875 		OStringBuffer aBuf( POSTSCRIPT_BUFSIZE );
876 
877                 // reserve place for a USHORT
878                 aBuf.append( "aa" );
879 
880                 // #107797# Write out EPS encapsulation header
881                 // ----------------------------------------------------------------------------------
882 
883                 // directly taken from the PLRM 3.0, p. 726. Note:
884                 // this will definitely cause problems when
885                 // recursively creating and embedding PostScript files
886                 // in OOo, since we use statically-named variables
887                 // here (namely, b4_Inc_state_salWin, dict_count_salWin and
888                 // op_count_salWin). Currently, I have no idea on how to
889                 // work around that, except from scanning and
890                 // interpreting the EPS for unused identifiers.
891 
892                 // append the real text
893                 aBuf.append( "\n\n/b4_Inc_state_salWin save def\n"
894                              "/dict_count_salWin countdictstack def\n"
895                              "/op_count_salWin count 1 sub def\n"
896                              "userdict begin\n"
897                              "/showpage {} def\n"
898                              "0 setgray 0 setlinecap\n"
899                              "1 setlinewidth 0 setlinejoin\n"
900                              "10 setmiterlimit [] 0 setdash newpath\n"
901                              "/languagelevel where\n"
902                              "{\n"
903                              "  pop languagelevel\n"
904                              "  1 ne\n"
905                              "  {\n"
906                              "    false setstrokeadjust false setoverprint\n"
907                              "  } if\n"
908                              "} if\n\n" );
909 
910 #if 0
911                 // #i10737# Apply clipping manually
912                 // ----------------------------------------------------------------------------------
913 
914                 // Windows seems to ignore any clipping at the HDC,
915                 // when followed by a POSTSCRIPT_PASSTHROUGH
916 
917                 // Check whether we've got a clipping, consisting of
918                 // exactly one rect (other cases should be, but aren't
919                 // handled currently)
920 
921                 // TODO: Handle more than one rectangle here (take
922                 // care, the buffer can handle only POSTSCRIPT_BUFSIZE
923                 // characters!)
924                 if ( mhRegion != 0 &&
925                      mpStdClipRgnData != NULL &&
926                      mpClipRgnData == mpStdClipRgnData &&
927                      mpClipRgnData->rdh.nCount == 1 )
928                 {
929                     RECT* pRect = &(mpClipRgnData->rdh.rcBound);
930 
931                     aBuf.append( "\nnewpath\n" );
932                     aBuf.append( pRect->left );
933                     aBuf.append( " " );
934                     aBuf.append( pRect->top );
935                     aBuf.append( " moveto\n" );
936                     aBuf.append( pRect->right );
937                     aBuf.append( " " );
938                     aBuf.append( pRect->top );
939                     aBuf.append( " lineto\n" );
940                     aBuf.append( pRect->right );
941                     aBuf.append( " " );
942                     aBuf.append( pRect->bottom );
943                     aBuf.append( " lineto\n" );
944                     aBuf.append( pRect->left );
945                     aBuf.append( " " );
946                     aBuf.append( pRect->bottom );
947                     aBuf.append( " lineto\n"
948                                  "closepath\n"
949                                  "clip\n"
950                                  "newpath\n" );
951                 }
952 #endif
953 
954                 // #107797# Write out buffer
955                 // ----------------------------------------------------------------------------------
956 				*((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
957 				//Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 );
958 				DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
959 						(PM_BYTE*)aBuf.getStr(), 0, NULL );
960 
961 		double dM11 = nWidth / ( nBoundingBox[2] - nBoundingBox[0] );
962 		double dM22 = - ( nHeight / (nBoundingBox[1] - nBoundingBox[3] ) );
963 
964                 // reserve a USHORT again
965                 aBuf.setLength( 2 );
966                 aBuf.append( "\n\n[" );
967                 aBuf.append( dM11 );
968                 aBuf.append( " 0 0 " );
969                 aBuf.append( dM22 );
970                 aBuf.append( ' ' );
971                 aBuf.append( nX - ( dM11 * nBoundingBox[0] ) );
972                 aBuf.append( ' ' );
973                 aBuf.append( nY - ( dM22 * nBoundingBox[3] ) );
974                 aBuf.append( "] concat\n"
975                              "%%BeginDocument:\n" );
976 				*((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
977 				DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
978 						(PM_BYTE*)aBuf.getStr(), 0, NULL );
979 #if 0
980 		PM_BYTE* pTemp = pBuf;
981 		ImplWriteString( &pTemp, "save\n[ " );
982 		ImplWriteDouble( &pTemp, dM11 );
983 		ImplWriteDouble( &pTemp, 0 );
984 		ImplWriteDouble( &pTemp, 0 );
985 		ImplWriteDouble( &pTemp, dM22 );
986 		ImplWriteDouble( &pTemp, nX - ( dM11 * nBoundingBox[0] ) );
987 		ImplWriteDouble( &pTemp, mnHeight - nY - ( dM22 * nBoundingBox[3] ) );
988 		ImplWriteString( &pTemp, "] concat /showpage {} def\n" );
989 
990 		if ( DevEscape( mhDC, DEVESC_RAWDATA, pTemp - pBuf,
991 			(PM_BYTE*)pBuf, 0, NULL ) == DEV_OK )
992 #endif //
993 		{
994 			sal_uInt32 nToDo = nSize;
995 			sal_uInt32 nDoNow;
996 			bRet = TRUE;
997 			while( nToDo && bRet )
998 			{
999 				nDoNow = 0x4000;
1000 				if ( nToDo < nDoNow )
1001 					nDoNow = nToDo;
1002 
1003 				if ( DevEscape( mhDC, DEVESC_RAWDATA, nDoNow, (PM_BYTE*)pPtr + nSize - nToDo,
1004 				   0, NULL ) == -1 )
1005 					bRet = FALSE;
1006 				nToDo -= nDoNow;
1007 			}
1008 
1009 			if ( bRet )
1010 			{
1011 				strcpy ( (char*)pBuf, "\nrestore\n" );
1012 				if ( DevEscape( mhDC, DEVESC_RAWDATA, 9, (PM_BYTE*)pBuf,
1013 					0, NULL ) == DEV_OK ) bRet = TRUE;
1014 			}
1015 
1016                 // #107797# Write out EPS encapsulation footer
1017                 // ----------------------------------------------------------------------------------
1018                 // reserve a USHORT again
1019                 aBuf.setLength( 2 );
1020                 aBuf.append( "%%EndDocument\n"
1021                              "count op_count_salWin sub {pop} repeat\n"
1022                              "countdictstack dict_count_salWin sub {end} repeat\n"
1023                              "b4_Inc_state_salWin restore\n\n" );
1024 				*((USHORT*)aBuf.getStr()) = (USHORT)( aBuf.getLength() - 2 );
1025 				DevEscape( mhDC, DEVESC_RAWDATA, aBuf.getLength(),
1026 						(PM_BYTE*)aBuf.getStr(), 0, NULL );
1027 				bRet = TRUE;
1028 
1029 		}
1030 	}
1031 	delete [] pBuf;
1032 	return bRet;
1033 }
1034 
1035 /*
1036  * IsNativeControlSupported()
1037  *
1038  *  Returns TRUE if the platform supports native
1039  *  drawing of the control defined by nPart
1040  */
IsNativeControlSupported(ControlType nType,ControlPart nPart)1041 sal_Bool Os2SalGraphics::IsNativeControlSupported( ControlType nType, ControlPart nPart )
1042 {
1043 	return( FALSE );
1044 }
1045 
1046 // -----------------------------------------------------------------------
1047 
GetGraphicsData() const1048 SystemGraphicsData Os2SalGraphics::GetGraphicsData() const
1049 {
1050     SystemGraphicsData aRes;
1051     aRes.nSize = sizeof(aRes);
1052 #if 0
1053     aRes.hDC = mhDC;
1054 #endif
1055     return aRes;
1056 }
1057 
1058 // -----------------------------------------------------------------------
1059