1 /************************************************************************/
2 /* */
3 /* Drawing surface implementation implementation. */
4 /* */
5 /************************************************************************/
6
7 # include "appFrameConfig.h"
8
9 # include "guiWidgetDrawingSurface.h"
10 # include <drawDrawingSurface.h>
11 # include "drawDrawingSurfaceImpl.h"
12 # include "drawScreenFontImpl.h"
13 # include "drawTextImplX11.h"
14 # include "drawScreenFontAdmin.h"
15 # include "drawUtilMotif.h"
16 # include "drawImpl.h"
17 # include "drawImplXft.h"
18 # include <appDebugon.h>
19
20 # ifdef USE_MOTIF
21
22 /************************************************************************/
23
drawMakeDrawingSurfaceForParent(DrawingSurface parent,int wide,int high)24 DrawingSurface drawMakeDrawingSurfaceForParent(
25 DrawingSurface parent,
26 int wide,
27 int high )
28 {
29 int depth;
30 DrawingSurface ds= malloc(sizeof(struct DrawingSurface));
31
32 if ( ! ds )
33 { PDEB(ds); return ds; }
34 drawInitDrawingSurface( ds );
35
36 depth= DefaultDepth( parent->dsDisplay, parent->dsScreen );
37
38 ds->dsDisplay= parent->dsDisplay;
39 ds->dsScreen= parent->dsScreen;
40
41 ds->dsColors= parent->dsColors;
42 ds->dsDrawable= XCreatePixmap( parent->dsDisplay, parent->dsDrawable,
43 wide, high, depth );
44 ds->dsAvoidFontconfig= parent->dsAvoidFontconfig;
45 ds->dsIsPixmap= 1;
46
47 if ( ! ds->dsDrawable )
48 {
49 XDEB(ds->dsDrawable);
50 drawFreeDrawingSurface( ds );
51 return (DrawingSurface)0;
52 }
53
54 ds->dsGc= XCreateGC( ds->dsDisplay, ds->dsDrawable, 0, NULL );
55 if ( ! ds->dsGc )
56 {
57 XDEB(ds->dsGc);
58 drawFreeDrawingSurface( ds );
59 return (DrawingSurface)0;
60 }
61
62 # ifdef USE_XFT
63 if ( ! ds->dsAvoidFontconfig )
64 {
65 ds->dsXftDrawable= appMotifXftDrawCreate(
66 ds->dsDisplay, ds->dsScreen,
67 ds->dsDrawable, &(ds->dsXftColorList) );
68 if ( ! ds->dsXftDrawable )
69 { XDEB(ds->dsXftDrawable); }
70 }
71 # endif
72
73 return ds;
74 }
75
drawMakeDrawingSurfaceForImageAndParent(DrawingSurface parent,const RasterImage * abi,const DocumentRectangle * drSrc,int pixelsWide,int pixelsHigh)76 DrawingSurface drawMakeDrawingSurfaceForImageAndParent(
77 DrawingSurface parent,
78 const RasterImage * abi,
79 const DocumentRectangle * drSrc,
80 int pixelsWide,
81 int pixelsHigh )
82 {
83 DrawingSurface ds;
84 APP_IMAGE * xim= (APP_IMAGE *)0;
85
86 ds= drawMakeDrawingSurfaceForParent( parent, pixelsWide, pixelsHigh );
87 if ( ! ds )
88 { XDEB(ds); return ds; }
89
90 if ( drawUtilMotifMakeImage( ds->dsDisplay, ds->dsScreen,
91 &xim, pixelsWide, pixelsHigh,
92 ds->dsColors, abi, drSrc ) )
93 { drawFreeDrawingSurface( ds ); return (DrawingSurface)0; }
94
95 XPutImage( ds->dsDisplay, ds->dsDrawable, ds->dsGc, xim, 0, 0, 0, 0,
96 pixelsWide, pixelsHigh );
97
98 XDestroyImage( xim );
99
100 return ds;
101 }
102
103 /************************************************************************/
104
drawRasterImage(DrawingSurface ds,const DocumentRectangle * drDest,const RasterImage * abi,const DocumentRectangle * drSrc)105 int drawRasterImage( DrawingSurface ds,
106 const DocumentRectangle * drDest,
107 const RasterImage * abi,
108 const DocumentRectangle * drSrc )
109 {
110 APP_IMAGE * xim= (APP_IMAGE *)0;
111 int pixelsWide= drDest->drX1- drDest->drX0+ 1;
112 int pixelsHigh= drDest->drY1- drDest->drY0+ 1;
113
114 if ( drawUtilMotifMakeImage( ds->dsDisplay, ds->dsScreen,
115 &xim, pixelsWide, pixelsHigh,
116 ds->dsColors, abi, drSrc ) )
117 { LLDEB(pixelsWide,pixelsHigh); return -1; }
118
119 XPutImage( ds->dsDisplay, ds->dsDrawable, ds->dsGc, xim, 0, 0,
120 drDest->drX0, drDest->drY0,
121 pixelsWide, pixelsHigh );
122
123 XDestroyImage( xim );
124
125 return 0;
126 }
127
128 /************************************************************************/
129 /* */
130 /* Cause subsequent drawing to be done in a certain color. */
131 /* */
132 /************************************************************************/
133
drawSetForegroundColor(DrawingSurface ds,const RGB8Color * rgb8)134 int drawSetForegroundColor( DrawingSurface ds,
135 const RGB8Color * rgb8 )
136 {
137 APP_COLOR_RGB xc;
138
139 if ( appColorRgb( &xc, ds->dsColors,
140 rgb8->rgb8Red,
141 rgb8->rgb8Green,
142 rgb8->rgb8Blue ) )
143 { LDEB(1); return -1; }
144
145 XSetForeground( ds->dsDisplay, ds->dsGc, xc.pixel );
146
147 # ifdef USE_XFT
148 appSolidXftColor( &(ds->dsXftColorList.axclCurrentColor), &xc );
149 # endif
150
151 return 0;
152 }
153
154 /************************************************************************/
155 /* */
156 /* Destroy a drawing surface. Only free resources allocated by the */
157 /* DrawingSurface itself. */
158 /* */
159 /* 1) Older versions of GTK/XFT crash here if the cleaning action is */
160 /* called from a destroy callback. MdD Jun 2007. */
161 /* */
162 /************************************************************************/
163
drawFreeDrawingSurface(DrawingSurface ds)164 void drawFreeDrawingSurface( DrawingSurface ds )
165 {
166 # ifdef USE_XFT
167 appCleanAppXftColorList( &(ds->dsXftColorList) );
168
169 /* 1 */
170 if ( ds->dsXftDrawable )
171 { XftDrawDestroy( ds->dsXftDrawable ); }
172 # endif
173
174 if ( ds->dsGc )
175 { XFreeGC( ds->dsDisplay, ds->dsGc ); }
176
177 if ( ds->dsPoints )
178 { free( ds->dsPoints ); }
179
180 if ( ds->dsIsPixmap )
181 { XFreePixmap( ds->dsDisplay, ds->dsDrawable ); }
182
183 free( ds );
184 }
185
186
187 /************************************************************************/
188 /* */
189 /* Fill a rectangle. */
190 /* */
191 /************************************************************************/
192
drawFillRectangle(DrawingSurface ds,const DocumentRectangle * dr)193 void drawFillRectangle( DrawingSurface ds,
194 const DocumentRectangle * dr )
195 {
196 # ifdef USE_XFT
197 if ( ! drawFillRectangleXft( ds->dsXftDrawable,
198 &(ds->dsXftColorList), dr ) )
199 { return; }
200 # endif
201
202 XFillRectangle( ds->dsDisplay, ds->dsDrawable, ds->dsGc,
203 dr->drX0, dr->drY0,
204 dr->drX1- dr->drX0+ 1, dr->drY1- dr->drY0+ 1 );
205 }
206
drawRectangle(DrawingSurface ds,const DocumentRectangle * dr)207 void drawRectangle( DrawingSurface ds,
208 const DocumentRectangle * dr )
209 {
210 XDrawRectangle( ds->dsDisplay, ds->dsDrawable, ds->dsGc,
211 dr->drX0, dr->drY0,
212 dr->drX1- dr->drX0+ 1, dr->drY1- dr->drY0+ 1 );
213 }
214
215 /************************************************************************/
216 /* */
217 /* Draw a line. */
218 /* */
219 /************************************************************************/
220
drawLine(DrawingSurface ds,int x0,int y0,int x1,int y1)221 int drawLine( DrawingSurface ds,
222 int x0,
223 int y0,
224 int x1,
225 int y1 )
226 {
227 XDrawLine( ds->dsDisplay, ds->dsDrawable, ds->dsGc, x0, y0, x1, y1 );
228 return 0;
229 }
230
231 /************************************************************************/
232 /* */
233 /* Convert points to native type. */
234 /* */
235 /************************************************************************/
236
drawSetPoints(DrawingSurface ds,const Point2DI * points,int pointCount)237 static int drawSetPoints( DrawingSurface ds,
238 const Point2DI * points,
239 int pointCount )
240 {
241 int i;
242
243 if ( ds->dsPointCount < pointCount )
244 {
245 APP_POINT * fresh= (APP_POINT *)realloc( ds->dsPoints,
246 pointCount* sizeof(APP_POINT) );
247 if ( ! fresh )
248 { LXDEB(pointCount,fresh); return -1; }
249
250 ds->dsPoints= fresh;
251 ds->dsPointCount= pointCount;
252 }
253
254 for ( i= 0; i < pointCount; i++ )
255 {
256 ds->dsPoints[i].x= points[i].x;
257 ds->dsPoints[i].y= points[i].y;
258 }
259
260 return 0;
261 }
262
263 /************************************************************************/
264 /* */
265 /* Draw a series of lines. */
266 /* */
267 /************************************************************************/
268
drawLines(DrawingSurface ds,const Point2DI * points,int pointCount,int close)269 int drawLines( DrawingSurface ds,
270 const Point2DI * points,
271 int pointCount,
272 int close )
273 {
274 int i;
275
276 if ( drawSetPoints( ds, points, pointCount ) )
277 { LDEB(pointCount); return -1; }
278
279 pointCount--;
280
281 for ( i= 0; i < pointCount; i++ )
282 {
283 XDrawLine( ds->dsDisplay, ds->dsDrawable, ds->dsGc,
284 ds->dsPoints[i+0].x, ds->dsPoints[i+0].y,
285 ds->dsPoints[i+1].x, ds->dsPoints[i+1].y );
286 }
287
288 if ( close )
289 {
290 XDrawLine( ds->dsDisplay, ds->dsDrawable, ds->dsGc,
291 ds->dsPoints[i].x, ds->dsPoints[i].y,
292 ds->dsPoints[0].x, ds->dsPoints[0].y );
293 }
294
295 return 0;
296 }
297
298 /************************************************************************/
299 /* */
300 /* Fill a polygon. */
301 /* */
302 /************************************************************************/
303
drawFillPolygon(DrawingSurface ds,const Point2DI * points,int pointCount)304 int drawFillPolygon( DrawingSurface ds,
305 const Point2DI * points,
306 int pointCount )
307 {
308 if ( drawSetPoints( ds, points, pointCount ) )
309 { LDEB(pointCount); return -1; }
310
311 XFillPolygon( ds->dsDisplay, ds->dsDrawable, ds->dsGc,
312 ds->dsPoints, pointCount,
313 Complex, CoordModeOrigin );
314
315 return 0;
316 }
317
318 /************************************************************************/
319 /* */
320 /* Set line attributes. */
321 /* */
322 /************************************************************************/
323
324 static const int LineStyleMap[LineStyle_Count]=
325 { LineSolid, LineOnOffDash, LineDoubleDash, };
326
327 static const int CapStyleMap[LineCap_Count]=
328 { CapNotLast, CapButt, CapRound, CapProjecting };
329
330 static const int JoinStyleMap[LineJoin_Count]=
331 { JoinMiter, JoinRound, JoinBevel };
332
drawSetLineAttributes(DrawingSurface ds,int lineWidth,int lineStyle,int capStyle,int joinStyle,const unsigned char * dashList,int dashCount)333 int drawSetLineAttributes( DrawingSurface ds,
334 int lineWidth,
335 int lineStyle,
336 int capStyle,
337 int joinStyle,
338 const unsigned char * dashList,
339 int dashCount )
340 {
341 XSetLineAttributes( ds->dsDisplay, ds->dsGc, lineWidth,
342 LineStyleMap[lineStyle],
343 CapStyleMap[capStyle],
344 JoinStyleMap[joinStyle] );
345
346 if ( lineStyle != LineStyleSolid )
347 {
348 if ( ! dashList || dashCount == 0 )
349 { XLDEB(dashList,dashCount); }
350 else{
351 XSetDashes( ds->dsDisplay, ds->dsGc,
352 0, (char *)dashList, dashCount );
353 }
354 }
355
356 return 0;
357 }
358
drawArc(DrawingSurface ds,const Arc2DI * arc)359 void drawArc( DrawingSurface ds,
360 const Arc2DI * arc )
361 {
362 XDrawArc( ds->dsDisplay, ds->dsDrawable, ds->dsGc,
363 arc->a2diRect.drX0, arc->a2diRect.drY0,
364 arc->a2diRect.drX1- arc->a2diRect.drX0+ 1,
365 arc->a2diRect.drY1- arc->a2diRect.drY0+ 1,
366 arc->a2diAngleFrom, arc->a2diAngleStep );
367 }
368
drawFillArc(DrawingSurface ds,const Arc2DI * arc)369 void drawFillArc( DrawingSurface ds,
370 const Arc2DI * arc )
371 {
372 XFillArc( ds->dsDisplay, ds->dsDrawable, ds->dsGc,
373 arc->a2diRect.drX0, arc->a2diRect.drY0,
374 arc->a2diRect.drX1- arc->a2diRect.drX0+ 1,
375 arc->a2diRect.drY1- arc->a2diRect.drY0+ 1,
376 arc->a2diAngleFrom, arc->a2diAngleStep );
377 }
378
379 /************************************************************************/
380 /* */
381 /* Set a cached system color as the current foreground color. */
382 /* */
383 /************************************************************************/
384
drawSetSystemColor(DrawingSurface ds,APP_COLOR_RGB * xc)385 void drawSetSystemColor( DrawingSurface ds,
386 APP_COLOR_RGB * xc )
387 {
388 XSetForeground( ds->dsDisplay, ds->dsGc, xc->pixel );
389
390 # ifdef USE_XFT
391 appSolidXftColor( &(ds->dsXftColorList.axclCurrentColor), xc );
392 # endif
393 }
394
395 /************************************************************************/
396 /* */
397 /* Draw a string. */
398 /* */
399 /************************************************************************/
400
drawString(DrawingSurface ds,int x0,int y0,int screenFont,const char * s,int len)401 int drawString( DrawingSurface ds,
402 int x0,
403 int y0,
404 int screenFont,
405 const char * s,
406 int len )
407 {
408 const NumberedPropertiesList * npl= &(ds->dsScreenFontAdmin);
409 DrawScreenFont * dsf;
410
411 TextProgress tp;
412
413 dsf= drawGetScreenFontByNumber( npl, screenFont );
414 if ( ! dsf )
415 { LXDEB(screenFont,dsf); return -1; }
416
417 /* HACK: Font might have been allocated before the widget wasrealized */
418 if ( ! dsf->dsfDrawable )
419 { dsf->dsfDrawable= ds->dsDrawable; }
420 if ( ! dsf->dsfGc )
421 { dsf->dsfGc= ds->dsGc; }
422
423 # ifdef USE_XFT
424 if ( ! dsf->dsfXftDrawable )
425 { dsf->dsfXftDrawable= ds->dsXftDrawable; }
426
427 if ( dsf->dsfXftDrawable &&
428 dsf->dsfXftFont &&
429 ! drawStringXft( dsf, &(ds->dsXftColorList), x0, y0, s, len ) )
430 { return 0; }
431 # endif
432
433 tp.tpX= x0;
434 tp.tpY= y0;
435
436 drawHandleTextSegmentsX11( &tp, dsf, s, len, drawTextSegment8X11,
437 drawTextSegment16X11, &(dsf->dsfEncodedFonts) );
438
439 return 0;
440 }
441
drawOpenScreenFont(DrawingSurface ds,const AfmFontInfo * afi,int pixelSize,const IndexSet * unicodesWanted)442 int drawOpenScreenFont( DrawingSurface ds,
443 const AfmFontInfo * afi,
444 int pixelSize,
445 const IndexSet * unicodesWanted)
446 {
447 DrawScreenFont * dsf;
448 int fresh;
449 int screenFont;
450
451 screenFont= drawGetScreenFont( &dsf, &fresh, &(ds->dsScreenFontAdmin),
452 unicodesWanted, afi, pixelSize );
453 if ( screenFont < 0 )
454 { LDEB(screenFont); return -1; }
455
456 if ( fresh )
457 {
458 if ( ! dsf->dsfDisplay )
459 { dsf->dsfDisplay= ds->dsDisplay; }
460 if ( ! dsf->dsfDrawable )
461 { dsf->dsfDrawable= ds->dsDrawable; }
462 if ( ! dsf->dsfGc )
463 { dsf->dsfGc= ds->dsGc; }
464
465 if ( drawFontOpenScreenFont( dsf, ds->dsAvoidFontconfig ) )
466 { LDEB(1); return -1; }
467 }
468
469 return screenFont;
470 }
471
drawNoClipping(DrawingSurface ds)472 void drawNoClipping( DrawingSurface ds )
473 {
474 # ifdef USE_XFT
475 if ( ds->dsXftDrawable )
476 {
477 XftDrawSetClip( ds->dsXftDrawable, 0 );
478 }
479 # endif
480
481 XSetClipMask( ds->dsDisplay, ds->dsGc, None );
482
483 return;
484 }
485
drawSetClipRect(DrawingSurface ds,const DocumentRectangle * drClip)486 void drawSetClipRect( DrawingSurface ds,
487 const DocumentRectangle * drClip )
488 {
489 XRectangle xRect;
490
491 xRect.x= drClip->drX0;
492 xRect.y= drClip->drY0;
493 xRect.width= drClip->drX1- drClip->drX0+ 1;
494 xRect.height= drClip->drY1- drClip->drY0+ 1;
495
496 if ( xRect.width < 1 || xRect.height < 1 )
497 { LLDEB(xRect.width,xRect.height); return; }
498
499 # ifdef USE_XFT
500 if ( ds->dsXftDrawable )
501 {
502 XftDrawSetClipRectangles( ds->dsXftDrawable, 0, 0, &xRect, 1 );
503 }
504 # endif
505
506 XSetClipRectangles( ds->dsDisplay, ds->dsGc, 0, 0, &xRect, 1, Unsorted );
507
508 return;
509 }
510
511 /************************************************************************/
512
drawChildSurface(DrawingSurface ds,const DrawingSurface child,int xDest,int yDest,const DocumentRectangle * drChild)513 void drawChildSurface( DrawingSurface ds,
514 const DrawingSurface child,
515 int xDest,
516 int yDest,
517 const DocumentRectangle * drChild )
518 {
519 if ( drChild->drX1 >= drChild->drX0 &&
520 drChild->drY1 >= drChild->drY0 )
521 {
522 XCopyArea( ds->dsDisplay, child->dsDrawable, ds->dsDrawable, ds->dsGc,
523 drChild->drX0, drChild->drY0,
524 drChild->drX1- drChild->drX0+ 1,
525 drChild->drY1- drChild->drY0+ 1,
526 xDest, yDest );
527 }
528
529 return;
530 }
531
532
533 /************************************************************************/
534
drawMoveArea(DrawingSurface ds,int xDest,int yDest,const DocumentRectangle * drSrc)535 void drawMoveArea( DrawingSurface ds,
536 int xDest,
537 int yDest,
538 const DocumentRectangle * drSrc )
539 {
540 XCopyArea( ds->dsDisplay, ds->dsDrawable, ds->dsDrawable, ds->dsGc,
541 drSrc->drX0, drSrc->drY0,
542 drSrc->drX1- drSrc->drX0+ 1,
543 drSrc->drY1- drSrc->drY0+ 1,
544 xDest, yDest );
545 }
546
547 # endif
548