~ubuntu-branches/ubuntu/hoary/gnustep-back/hoary

« back to all changes in this revision

Viewing changes to Source/cairo/CairoGState.m

  • Committer: Bazaar Package Importer
  • Author(s): Eric Heintzmann
  • Date: 2004-11-18 20:18:30 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041118201830-h8fv5qdh4drqengh
Tags: 0.9.4-2
Rebuild using latest GNUstep libs (closes: #281007).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * CairoGState.m
 
3
 
 
4
 * Copyright (C) 2003 Free Software Foundation, Inc.
 
5
 * August 31, 2003
 
6
 * Written by Banlu Kemiyatorn <object at gmail dot com>
 
7
 * This library is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Library General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2 of the License, or (at your option) any later version.
 
11
 
 
12
 * This library is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Library General Public License for more details.
 
16
 
 
17
 * You should have received a copy of the GNU Library General Public
 
18
 * License along with this library; if not, write to the Free
 
19
 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
 
20
 */
 
21
 
 
22
#include <AppKit/NSBezierPath.h>
 
23
#include <AppKit/NSColor.h>
 
24
#include <AppKit/NSGraphics.h>
 
25
#include "cairo/CairoGState.h"
 
26
#include "cairo/CairoFontInfo.h"
 
27
#include "cairo/CairoSurface.h"
 
28
#include "cairo/CairoContext.h"
 
29
#include "NSBezierPathCairo.h"
 
30
#include <math.h>
 
31
 
 
32
#define FIXME()  NSLog(@":::FIXME::: %@ %s", [self description], sel_get_name(_cmd))
 
33
 
 
34
static cairo_matrix_t *local_matrix;
 
35
 
 
36
/* Be warned that CairoGState didn't derived GSGState */
 
37
@implementation CairoGState 
 
38
 
 
39
+ (void) initialize
 
40
{
 
41
  if (self == [CairoGState class])
 
42
    {
 
43
      local_matrix = cairo_matrix_create();
 
44
    }
 
45
}
 
46
 
 
47
- (void) forwardInvocation: (NSInvocation *)anInvocation
 
48
{
 
49
  /* only for trapping any unknown message. */
 
50
  NSLog (@":::UNKNOWN::: %@ %@", self, anInvocation);
 
51
  exit(1);
 
52
}
 
53
 
 
54
- (id) copyWithZone: (NSZone *)zone
 
55
{
 
56
  CairoGState *copy = (CairoGState *)NSCopyObject(self, 0, zone);
 
57
 
 
58
  copy->_ct = cairo_create();
 
59
  cairo_copy(copy->_ct, _ct);
 
60
  /*
 
61
     NSLog(@"copy state %p(%p) to %p(%p)",self,
 
62
     cairo_current_target_surface(_ct),
 
63
     copy,
 
64
     cairo_current_target_surface(copy->_ct)
 
65
     );
 
66
   */
 
67
 
 
68
  RETAIN(_font);
 
69
  RETAIN(_surface);
 
70
 
 
71
  return copy;
 
72
}
 
73
 
 
74
- (id) init
 
75
{
 
76
  [self DPSinitgraphics];
 
77
  return self;
 
78
}
 
79
 
 
80
- (id) initWithDrawContext: (CairoContext *)drawContext
 
81
{
 
82
  //NSLog (@"CairoGState initWithDrawContext:%@", drawContext);
 
83
  [self init];
 
84
 
 
85
  return self;
 
86
}
 
87
 
 
88
- (void) dealloc
 
89
{
 
90
  //NSLog(@"destate %p",self);
 
91
  cairo_destroy(_ct);
 
92
  RELEASE(_font);
 
93
  RELEASE(_surface);
 
94
 
 
95
  [super dealloc];
 
96
}
 
97
 
 
98
static void
 
99
_flipCairoSurfaceMatrix(cairo_t *ct, CairoSurface *surface)
 
100
{
 
101
  cairo_matrix_set_identity(local_matrix);
 
102
  cairo_matrix_scale(local_matrix, 1, -1);
 
103
 
 
104
  if (surface != nil)
 
105
    {
 
106
      cairo_matrix_translate(local_matrix, 0, -[surface size].height);
 
107
    }
 
108
  cairo_set_matrix(ct, local_matrix);
 
109
}
 
110
 
 
111
- (void) setOffset: (NSPoint)theOffset
 
112
{
 
113
  _offset = theOffset;
 
114
}
 
115
 
 
116
- (NSPoint) offset
 
117
{
 
118
  return _offset;
 
119
}
 
120
 
 
121
- (void) GSCurrentDevice: (void **)device: (int *)x : (int *)y
 
122
{
 
123
  if (x)
 
124
    *x = 0;
 
125
  if (y)
 
126
    *y = 0;
 
127
  if (device)
 
128
    {
 
129
      if (_surface)
 
130
        {
 
131
          *device = _surface->gsDevice;
 
132
        }
 
133
      else
 
134
        {
 
135
          *device = NULL;
 
136
          NSLog(@":::FIXME::: surface isn't set. %@ %s", [self description],
 
137
                sel_get_name(_cmd));
 
138
        }
 
139
    }
 
140
}
 
141
 
 
142
- (void) GSSetDevice: (void *)device : (int)x : (int)y
 
143
{
 
144
  CairoInfo cairo_info;
 
145
 
 
146
  ASSIGN(_surface, [CairoSurface surfaceForDevice: device depthInfo: &cairo_info]);
 
147
  _offset = NSMakePoint(x, y);
 
148
/*
 
149
  NSLog(@"before: surface %p on state %p",
 
150
        cairo_current_target_surface(_ct), self);
 
151
*/
 
152
  [_surface setAsTargetOfCairo: _ct];
 
153
  _flipCairoSurfaceMatrix(_ct, _surface);
 
154
/*
 
155
  NSLog(@"after: surface %p on state %p %@",
 
156
        cairo_current_target_surface (_ct), self,
 
157
        NSStringFromSize([_surface size]));
 
158
*/
 
159
}
 
160
 
 
161
@end 
 
162
 
 
163
@implementation CairoGState (Ops)
 
164
/*
 
165
 * Color operations
 
166
 */
 
167
- (void) DPScurrentalpha: (float *)a
 
168
{
 
169
  *a = cairo_current_alpha(_ct);
 
170
}
 
171
 
 
172
- (void) DPScurrentcmykcolor: (float *)c : (float *)m : (float *)y :(float *)k
 
173
{
 
174
  double color[3];
 
175
 
 
176
  cairo_current_rgb_color(_ct, &color[0], &color[1], &color[2]);
 
177
  *c = 1 - color[0];
 
178
  *m = 1 - color[1];
 
179
  *y = 1 - color[2];
 
180
  *k = 0;
 
181
}
 
182
 
 
183
- (void) DPScurrentgray: (float *)gray
 
184
{
 
185
  double dr, dg, db;
 
186
 
 
187
  cairo_current_rgb_color(_ct, &dr, &dg, &db);
 
188
  *gray = (dr + dg + db) / 3.0;
 
189
}
 
190
 
 
191
- (void) DPScurrenthsbcolor: (float *)h : (float *)s : (float *)b
 
192
{
 
193
  NSColor *color;
 
194
  double dr, dg, db;
 
195
  float alpha;
 
196
 
 
197
  cairo_current_rgb_color(_ct, &dr, &dg, &db);
 
198
  color = [NSColor colorWithCalibratedRed: dr
 
199
                                    green: dg
 
200
                                     blue: db
 
201
                                    alpha: 1.0];
 
202
  [color getHue: h
 
203
         saturation: s
 
204
         brightness: b
 
205
         alpha: &alpha];
 
206
}
 
207
 
 
208
- (void) DPScurrentrgbcolor: (float *)r : (float *)g : (float *)b
 
209
{
 
210
  double dr, dg, db;
 
211
 
 
212
  cairo_current_rgb_color(_ct, &dr, &dg, &db);
 
213
  *r = dr;
 
214
  *g = dg;
 
215
  *b = db;
 
216
}
 
217
 
 
218
- (void) DPSsetalpha: (float)a
 
219
{
 
220
  cairo_set_alpha(_ct, a);
 
221
}
 
222
 
 
223
- (void) DPSsetcmykcolor: (float)c : (float)m : (float)y : (float)k
 
224
{
 
225
  double r, g, b;
 
226
 
 
227
  r = 1 - c;
 
228
  g = 1 - m;
 
229
  b = 1 - y;
 
230
  cairo_set_rgb_color(_ct, r, g, b);
 
231
}
 
232
 
 
233
- (void) DPSsetgray: (float)gray
 
234
{
 
235
  cairo_set_rgb_color(_ct, gray, gray, gray);
 
236
}
 
237
 
 
238
- (void) DPSsethsbcolor: (float)h : (float)s : (float)b
 
239
{
 
240
  NSColor *color;
 
241
  float red, green, blue, alpha;
 
242
 
 
243
  color = [NSColor colorWithCalibratedHue: h
 
244
                               saturation: s
 
245
                               brightness: b
 
246
                                    alpha: 1.0];
 
247
  [color getRed: &red
 
248
          green: &green
 
249
           blue: &blue
 
250
          alpha: &alpha];
 
251
  [self DPSsetrgbcolor: red : green : blue];
 
252
}
 
253
 
 
254
- (void) DPSsetrgbcolor: (float)r : (float)g: (float)b
 
255
{
 
256
  cairo_set_rgb_color(_ct, r, g, b);
 
257
}
 
258
 
 
259
- (void) GSSetFillColorspace: (void *)spaceref
 
260
{
 
261
  FIXME();
 
262
}
 
263
 
 
264
- (void) GSSetStrokeColorspace: (void *)spaceref
 
265
{
 
266
  FIXME();
 
267
}
 
268
 
 
269
- (void) GSSetFillColor: (const float *)values
 
270
{
 
271
  FIXME();
 
272
}
 
273
 
 
274
- (void) GSSetStrokeColor: (const float *)values
 
275
{
 
276
  FIXME();
 
277
}
 
278
 
 
279
/*
 
280
 * Text operations
 
281
 */
 
282
 
 
283
- (void) DPSashow: (float)x : (float)y : (const char *)s
 
284
{
 
285
  FIXME();
 
286
}
 
287
 
 
288
- (void) DPSawidthshow: (float)cx : (float)cy : (int)c : (float)ax 
 
289
                      : (float)ay : (const char *)s
 
290
{
 
291
  FIXME();
 
292
}
 
293
 
 
294
- (void) DPScharpath: (const char *)s : (int)b
 
295
{
 
296
  char *c = malloc(b + 1);
 
297
 
 
298
  memcpy(c, s, b);
 
299
  c[b + 1] = 0;
 
300
 
 
301
  cairo_text_path(_ct, c);
 
302
  free (c);
 
303
}
 
304
 
 
305
- (void) DPSshow: (const char *)s
 
306
{
 
307
  cairo_show_text(_ct, s);
 
308
}
 
309
 
 
310
- (void) DPSwidthshow: (float)x : (float)y : (int)c : (const char *)s
 
311
{
 
312
  FIXME();
 
313
}
 
314
 
 
315
- (void) DPSxshow: (const char *)s : (const float *)numarray : (int)size
 
316
{
 
317
  FIXME();
 
318
}
 
319
 
 
320
- (void) DPSxyshow: (const char *)s : (const float *)numarray : (int)size
 
321
{
 
322
  FIXME();
 
323
}
 
324
 
 
325
- (void) DPSyshow: (const char *)s : (const float *)numarray : (int)size
 
326
{
 
327
  FIXME();
 
328
}
 
329
 
 
330
- (void) GSSetCharacterSpacing: (float)extra
 
331
{
 
332
  FIXME();
 
333
}
 
334
 
 
335
- (void) GSSetFont: (GSFontInfo *)fontref
 
336
{
 
337
  if (_font == fontref)
 
338
    {
 
339
      return;
 
340
    }
 
341
 
 
342
  ASSIGN(_font, fontref);
 
343
  cairo_set_font(_ct, ((CairoFontInfo *)_font)->xrFont);
 
344
}
 
345
 
 
346
- (void) GSSetFontSize: (float)size
 
347
{
 
348
  FIXME();
 
349
}
 
350
 
 
351
- (NSAffineTransform *) GSGetTextCTM
 
352
{
 
353
  return [self GSCurrentCTM];
 
354
}
 
355
 
 
356
- (NSPoint) GSGetTextPosition
 
357
{
 
358
  float x, y;
 
359
 
 
360
  [self DPScurrentpoint: &x : &y];
 
361
  return NSMakePoint(x, y);
 
362
}
 
363
 
 
364
- (void) GSSetTextCTM: (NSAffineTransform *)ctm
 
365
{
 
366
  [self GSSetCTM: ctm];
 
367
}
 
368
 
 
369
- (void) GSSetTextDrawingMode: (GSTextDrawingMode)mode
 
370
{
 
371
  FIXME();
 
372
}
 
373
 
 
374
- (void) GSSetTextPosition: (NSPoint)loc
 
375
{
 
376
  FIXME();
 
377
}
 
378
 
 
379
- (void) GSShowText: (const char *)string : (size_t)length
 
380
{
 
381
  FIXME();
 
382
}
 
383
 
 
384
- (void) GSShowGlyphs: (const NSGlyph *)glyphs : (size_t)length
 
385
{
 
386
  double dx, dy;
 
387
 
 
388
  cairo_current_point(_ct, &dx, &dy);
 
389
 
 
390
  [_font drawGlyphs: glyphs
 
391
             length: length
 
392
                 on: _ct
 
393
                atX: dx
 
394
                  y: dy];
 
395
}
 
396
 
 
397
/*
 
398
 * GState operations
 
399
 */
 
400
 
 
401
- (void) DPSinitgraphics
 
402
{
 
403
  DESTROY(_font);
 
404
 
 
405
  if (_ct)
 
406
    {
 
407
      cairo_destroy(_ct);
 
408
    }
 
409
  _ct = cairo_create();
 
410
  /* Cairo's default line width is 2.0 */
 
411
  _flipCairoSurfaceMatrix(_ct, _surface);
 
412
  //NSLog(@"in flip %p (%p)", self, cairo_current_target_surface(_ct));
 
413
  cairo_set_line_width(_ct, 1.0);
 
414
}
 
415
 
 
416
- (void) DPScurrentflat: (float *)flatness
 
417
{
 
418
  *flatness = cairo_current_tolerance(_ct);
 
419
}
 
420
 
 
421
- (void) DPScurrentlinecap: (int *)linecap
 
422
{
 
423
  cairo_line_cap_t lc;
 
424
 
 
425
  lc = cairo_current_line_cap(_ct);
 
426
  *linecap = lc;
 
427
  /*
 
428
     switch (lc)
 
429
     {
 
430
     case CAIRO_LINE_CAP_BUTT:
 
431
     *linecap = 0;
 
432
     break;
 
433
     case CAIRO_LINE_CAP_ROUND:
 
434
     *linecap = 1;
 
435
     break;
 
436
     case CAIRO_LINE_CAP_SQUARE:
 
437
     *linecap = 2;
 
438
     break;
 
439
     default:
 
440
     NSLog(@"ERROR Line cap unknown");
 
441
     exit(-1);
 
442
     }
 
443
   */
 
444
}
 
445
 
 
446
- (void) DPScurrentlinejoin: (int *)linejoin
 
447
{
 
448
  cairo_line_join_t lj;
 
449
 
 
450
  lj = cairo_current_line_join(_ct);
 
451
  *linejoin = lj;
 
452
  /*
 
453
     switch (lj)
 
454
     {
 
455
     case CAIRO_LINE_JOIN_MITER:
 
456
     *linejoin = 0;
 
457
     break;
 
458
     case CAIRO_LINE_JOIN_ROUND:
 
459
     *linejoin = 1;
 
460
     break;
 
461
     case CAIRO_LINE_JOIN_BEVEL:
 
462
     *linejoin = 2;
 
463
     break;
 
464
     default:
 
465
     NSLog(@"ERROR Line join unknown");
 
466
     exit(-1);
 
467
     }
 
468
   */
 
469
}
 
470
 
 
471
- (void) DPScurrentlinewidth: (float *)width
 
472
{
 
473
  *width = cairo_current_line_width(_ct);
 
474
}
 
475
 
 
476
- (void) DPScurrentmiterlimit: (float *)limit
 
477
{
 
478
  *limit = cairo_current_miter_limit(_ct);
 
479
}
 
480
 
 
481
- (void) DPScurrentpoint: (float *)x : (float *)y
 
482
{
 
483
  double dx, dy;
 
484
 
 
485
  cairo_current_point(_ct, &dx, &dy);
 
486
  *x = dx;
 
487
  *y = dy;
 
488
}
 
489
 
 
490
- (void) DPScurrentstrokeadjust: (int *)b
 
491
{
 
492
  FIXME();
 
493
}
 
494
 
 
495
- (void) DPSsetdash: (const float *)pat : (int)size : (float)offset
 
496
{
 
497
  double *dpat;
 
498
  int i;
 
499
 
 
500
  i = size;
 
501
  dpat = malloc(sizeof(double) * size);
 
502
  while (i)
 
503
    {
 
504
      i--;
 
505
      dpat[i] = pat[i];
 
506
    }
 
507
  cairo_set_dash(_ct, dpat, size, offset);
 
508
  free(dpat);
 
509
}
 
510
 
 
511
- (void) DPSsetflat: (float)flatness
 
512
{
 
513
  cairo_set_tolerance(_ct, flatness);
 
514
}
 
515
 
 
516
- (void) DPSsetlinecap: (int)linecap
 
517
{
 
518
  cairo_set_line_cap(_ct, (cairo_line_cap_t)linecap);
 
519
}
 
520
 
 
521
- (void) DPSsetlinejoin: (int)linejoin
 
522
{
 
523
  cairo_set_line_join(_ct, (cairo_line_join_t)linejoin);
 
524
}
 
525
 
 
526
- (void) DPSsetlinewidth: (float)width
 
527
{
 
528
  cairo_set_line_width(_ct, width);
 
529
}
 
530
 
 
531
- (void) DPSsetmiterlimit: (float)limit
 
532
{
 
533
  cairo_set_miter_limit(_ct, limit);
 
534
}
 
535
 
 
536
- (void) DPSsetstrokeadjust: (int)b
 
537
{
 
538
  FIXME();
 
539
}
 
540
 
 
541
/*
 
542
 * Matrix operations
 
543
 */
 
544
 
 
545
- (void) DPSconcat: (const float *)m
 
546
{
 
547
  cairo_matrix_set_affine(local_matrix, m[0], m[1], m[2], m[3], m[4], m[5]);
 
548
  cairo_concat_matrix(_ct, local_matrix);
 
549
}
 
550
 
 
551
- (void) DPSinitmatrix
 
552
{
 
553
  cairo_matrix_set_identity(local_matrix);
 
554
  cairo_set_matrix(_ct, local_matrix);
 
555
  _flipCairoSurfaceMatrix(_ct, _surface);
 
556
}
 
557
 
 
558
- (void) DPSrotate: (float)angle
 
559
{
 
560
  cairo_rotate(_ct, angle);
 
561
}
 
562
 
 
563
- (void) DPSscale: (float)x : (float)y
 
564
{
 
565
  cairo_scale(_ct, x, y);
 
566
}
 
567
 
 
568
- (void) DPStranslate: (float)x : (float)y
 
569
{
 
570
  cairo_translate(_ct, x, y);
 
571
}
 
572
 
 
573
- (void) _flipCairoFont
 
574
{
 
575
  cairo_matrix_set_identity(local_matrix);
 
576
  cairo_matrix_scale(local_matrix, 1, -1);
 
577
  cairo_transform_font(_ct, local_matrix);
 
578
}
 
579
 
 
580
/*
 
581
static void
 
582
_log_matrix(cairo_t * ct)
 
583
{
 
584
  double da, db, dc, dd, dtx, dty;
 
585
 
 
586
  cairo_current_matrix(ct, local_matrix);
 
587
  cairo_matrix_get_affine(local_matrix, &da, &db, &dc, &dd, &dtx, &dty);
 
588
 
 
589
  NSLog(@"%g %g %g %g %g %g", da, db, dc, dd, dtx, dty);
 
590
}
 
591
*/
 
592
 
 
593
- (NSAffineTransform *) GSCurrentCTM
 
594
{
 
595
  NSAffineTransform *transform;
 
596
  NSAffineTransformStruct tstruct;
 
597
  double da, db, dc, dd, dtx, dty;
 
598
 
 
599
  transform = [NSAffineTransform transform];
 
600
  cairo_current_matrix(_ct, local_matrix);
 
601
  cairo_matrix_get_affine(local_matrix, &da, &db, &dc, &dd, &dtx, &dty);
 
602
  tstruct.m11 = da;
 
603
  tstruct.m12 = db;
 
604
  tstruct.m21 = dc;
 
605
  tstruct.m22 = dd;
 
606
  tstruct.tX = dtx;
 
607
  tstruct.tY = dty;
 
608
  [transform setTransformStruct:tstruct];
 
609
  return transform;
 
610
}
 
611
 
 
612
- (void) GSSetCTM: (NSAffineTransform *)ctm
 
613
{
 
614
  NSAffineTransformStruct tstruct;
 
615
 
 
616
  tstruct = [ctm transformStruct];
 
617
  cairo_matrix_set_affine(local_matrix,
 
618
                          tstruct.m11, tstruct.m12,
 
619
                          tstruct.m21, tstruct.m22, tstruct.tX, tstruct.tY);
 
620
  cairo_set_matrix(_ct, local_matrix);
 
621
}
 
622
 
 
623
- (void) GSConcatCTM: (NSAffineTransform *)ctm
 
624
{
 
625
  NSAffineTransformStruct tstruct;
 
626
 
 
627
  tstruct =  [ctm transformStruct];
 
628
  cairo_matrix_set_affine(local_matrix,
 
629
                          tstruct.m11, tstruct.m12,
 
630
                          tstruct.m21, tstruct.m22, tstruct.tX, tstruct.tY);
 
631
  cairo_concat_matrix(_ct, local_matrix);
 
632
}
 
633
 
 
634
/*
 
635
 * Paint operations
 
636
 */
 
637
 
 
638
- (NSPoint) currentPoint
 
639
{
 
640
  double dx, dy;
 
641
 
 
642
  //FIXME();
 
643
  cairo_current_point(_ct, &dx, &dy);
 
644
  return NSMakePoint(dx, dy);
 
645
}
 
646
 
 
647
- (void) DPSarc: (float)x : (float)y : (float)r : (float)angle1 : (float)angle2
 
648
{
 
649
  //NSLog(@"%g %g", angle1, angle2);
 
650
  cairo_arc(_ct, x, y, r, angle1 * M_PI / 180, angle2 * M_PI / 180);
 
651
}
 
652
 
 
653
- (void) DPSarcn: (float)x : (float)y : (float)r : (float)angle1 : (float)angle2
 
654
{
 
655
  cairo_arc_negative(_ct, x, y, r, angle1 * M_PI / 180, angle2 * M_PI / 180);
 
656
}
 
657
 
 
658
- (void) DPSarct: (float)x1 : (float)y1 : (float)x2 : (float)y2 : (float)r
 
659
{
 
660
  FIXME();
 
661
  /*
 
662
     cairo_arc_to(_ct, x1, y1, x2, y2, r);
 
663
   */
 
664
  /*
 
665
     NSBezierPath *newPath;
 
666
 
 
667
     newPath = [[NSBezierPath alloc] init];
 
668
     if ((path != nil) && ([path elementCount] != 0))
 
669
     {
 
670
     [newPath lineToPoint: [self currentPoint]];
 
671
     }
 
672
     [newPath appendBezierPathWithArcFromPoint: NSMakePoint(x1, y1)
 
673
     toPoint: NSMakePoint(x2, y2)
 
674
     radius: r];
 
675
     [newPath transformUsingAffineTransform: ctm];
 
676
     CHECK_PATH;
 
677
     [path appendBezierPath: newPath];
 
678
     RELEASE(newPath);
 
679
   */
 
680
}
 
681
 
 
682
- (void) DPSclip
 
683
{
 
684
  cairo_clip(_ct);
 
685
}
 
686
 
 
687
- (void) DPSclosepath
 
688
{
 
689
  cairo_close_path(_ct);
 
690
}
 
691
 
 
692
- (void) DPScurveto: (float)x1 : (float)y1 : (float)x2 
 
693
                   : (float)y2 : (float)x3 : (float)y3
 
694
{
 
695
  cairo_curve_to(_ct, x1, y1, x2, y2, x3, y3);
 
696
}
 
697
 
 
698
- (void) DPSeoclip
 
699
{
 
700
  cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
 
701
  cairo_clip(_ct);
 
702
  cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_WINDING);
 
703
}
 
704
 
 
705
- (void) DPSeofill
 
706
{
 
707
 
 
708
  cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_EVEN_ODD);
 
709
  cairo_fill(_ct);
 
710
  cairo_set_fill_rule(_ct, CAIRO_FILL_RULE_WINDING);
 
711
}
 
712
 
 
713
- (void) DPSfill
 
714
{
 
715
  cairo_fill(_ct);
 
716
}
 
717
 
 
718
static void
 
719
_c2cmoveto(void *cl, double x, double y)
 
720
{
 
721
  cairo_t *ct = (cairo_t *)cl;
 
722
  cairo_move_to(ct, x, y);
 
723
}
 
724
 
 
725
static void
 
726
_c2clineto(void *cl, double x, double y)
 
727
{
 
728
  cairo_t *ct = (cairo_t *)cl;
 
729
  cairo_line_to(ct, x, y);
 
730
}
 
731
 
 
732
static void
 
733
_c2cclosepath(void *cl)
 
734
{
 
735
  cairo_t *ct = (cairo_t *)cl;
 
736
  cairo_close_path(ct);
 
737
}
 
738
 
 
739
- (void) DPSflattenpath
 
740
{
 
741
  /* recheck this in plrm */
 
742
  cairo_t *fct = cairo_create();
 
743
 
 
744
  cairo_copy(fct, _ct);
 
745
  cairo_new_path(_ct);
 
746
  cairo_current_path_flat(fct, _c2cmoveto, _c2clineto, _c2cclosepath, _ct);
 
747
  cairo_destroy(fct);
 
748
}
 
749
 
 
750
- (void) DPSinitclip
 
751
{
 
752
  cairo_init_clip(_ct);
 
753
}
 
754
 
 
755
- (void) DPSlineto: (float)x : (float)y
 
756
{
 
757
  cairo_line_to(_ct, x, y);
 
758
}
 
759
 
 
760
- (void) DPSmoveto: (float)x : (float)y
 
761
{
 
762
  cairo_move_to(_ct, x, y);
 
763
}
 
764
 
 
765
- (void) DPSnewpath
 
766
{
 
767
  cairo_new_path(_ct);
 
768
}
 
769
 
 
770
- (void) DPSpathbbox: (float *)llx : (float *)lly : (float *)urx : (float *)ury
 
771
{
 
772
  NSBezierPath *path = [NSBezierPath bezierPathFromCairo: _ct];
 
773
  NSRect rect = [path controlPointBounds];
 
774
 
 
775
  if (llx)
 
776
    *llx = NSMinX(rect);
 
777
  if (lly)
 
778
    *lly = NSMinY(rect);
 
779
  if (urx)
 
780
    *urx = NSMaxX(rect);
 
781
  if (ury)
 
782
    *ury = NSMaxY(rect);
 
783
}
 
784
 
 
785
- (void) DPSrcurveto: (float)x1 : (float)y1 : (float)x2 
 
786
                    : (float)y2 : (float)x3 : (float)y3
 
787
{
 
788
  cairo_rel_curve_to(_ct, x1, y1, x2, y2, x3, y3);
 
789
}
 
790
 
 
791
- (void) DPSrectclip: (float)x : (float)y : (float)w : (float)h
 
792
{
 
793
  cairo_new_path(_ct);
 
794
  cairo_move_to(_ct, x, y);
 
795
  cairo_rel_line_to(_ct, w, 0);
 
796
  cairo_rel_line_to(_ct, 0, h);
 
797
  cairo_rel_line_to(_ct, -w, 0);
 
798
  cairo_close_path(_ct);
 
799
  cairo_clip(_ct);
 
800
  cairo_new_path(_ct);
 
801
}
 
802
 
 
803
- (void) DPSrectfill: (float)x : (float)y : (float)w : (float)h
 
804
{
 
805
  cairo_save(_ct);
 
806
  cairo_new_path(_ct);
 
807
  cairo_move_to(_ct, x, y);
 
808
  cairo_rel_line_to(_ct, w, 0);
 
809
  cairo_rel_line_to(_ct, 0, h);
 
810
  cairo_rel_line_to(_ct, -w, 0);
 
811
  cairo_close_path(_ct);
 
812
  cairo_fill(_ct);
 
813
  cairo_restore(_ct);
 
814
}
 
815
 
 
816
- (void) DPSrectstroke: (float)x : (float)y : (float)w : (float)h
 
817
{
 
818
  cairo_save(_ct);
 
819
  cairo_new_path(_ct);
 
820
  cairo_move_to(_ct, x, y);
 
821
  cairo_rel_line_to(_ct, w, 0);
 
822
  cairo_rel_line_to(_ct, 0, h);
 
823
  cairo_rel_line_to(_ct, -w, 0);
 
824
  cairo_close_path(_ct);
 
825
  cairo_stroke(_ct);
 
826
  cairo_restore(_ct);
 
827
}
 
828
 
 
829
- (void) DPSreversepath
 
830
{
 
831
  NSBezierPath *path = [NSBezierPath bezierPathFromCairo: _ct];
 
832
 
 
833
  path = [path bezierPathByReversingPath];
 
834
  cairo_new_path(_ct);
 
835
  [path appendBezierPathToCairo: _ct];
 
836
}
 
837
 
 
838
- (void) DPSrlineto: (float)x : (float)y
 
839
{
 
840
  cairo_rel_line_to(_ct, x, y);
 
841
}
 
842
 
 
843
- (void) DPSrmoveto: (float)x : (float)y
 
844
{
 
845
  cairo_rel_move_to(_ct, x, y);
 
846
}
 
847
 
 
848
- (void) DPSstroke
 
849
{
 
850
  cairo_stroke(_ct);
 
851
}
 
852
 
 
853
- (void) GSSendBezierPath: (NSBezierPath *)path
 
854
{
 
855
  cairo_new_path(_ct);
 
856
  [path appendBezierPathToCairo: _ct];
 
857
}
 
858
 
 
859
- (void) GSRectClipList: (const NSRect *)rects : (int)count
 
860
{
 
861
  int i;
 
862
  NSRect union_rect;
 
863
 
 
864
  if (count == 0)
 
865
    return;
 
866
 
 
867
  /* FIXME see gsc
 
868
     The specification is not clear if the union of the rects 
 
869
     should produce the new clip rect or if the outline of all rects 
 
870
     should be used as clip path.
 
871
   */
 
872
  union_rect = rects[0];
 
873
  for (i = 1; i < count; i++)
 
874
    union_rect = NSUnionRect(union_rect, rects[i]);
 
875
 
 
876
  [self DPSrectclip: NSMinX(union_rect) : NSMinY(union_rect)
 
877
                   : NSWidth(union_rect) : NSHeight(union_rect)];
 
878
}
 
879
 
 
880
- (void) GSRectFillList: (const NSRect *)rects : (int)count
 
881
{
 
882
  int i;
 
883
 
 
884
  for (i = 0; i < count; i++)
 
885
    {
 
886
      [self DPSrectfill: NSMinX(rects[i]) : NSMinY(rects[i])
 
887
                       : NSWidth(rects[i]) : NSHeight(rects[i])];
 
888
    }
 
889
}
 
890
 
 
891
/*
 
892
static NSString *
 
893
_opName(NSCompositingOperation op)
 
894
{
 
895
  switch (op)
 
896
    {
 
897
    case NSCompositeClear:
 
898
      return @"NSCompositeClear";
 
899
 
 
900
    case NSCompositeCopy:
 
901
      return @"NSCompositeCopy";
 
902
 
 
903
    case NSCompositeSourceOver:
 
904
      return @"NSCompositeSourceOver";
 
905
 
 
906
    case NSCompositeSourceIn:
 
907
      return @"NSCompositeSourceIn";
 
908
 
 
909
    case NSCompositeSourceOut:
 
910
      return @"NSCompositeSourceOut";
 
911
 
 
912
    case NSCompositeSourceAtop:
 
913
      return @"NSCompositeSourceAtop";
 
914
 
 
915
    case NSCompositeDestinationOver:
 
916
      return @"NSCompositeDestinationOver";
 
917
 
 
918
    case NSCompositeDestinationIn:
 
919
      return @"NSCompositeDestinationIn";
 
920
 
 
921
    case NSCompositeDestinationOut:
 
922
      return @"NSCompositeDestinationOut";
 
923
 
 
924
    case NSCompositeDestinationAtop:
 
925
      return @"NSCompositeDestinationAtop";
 
926
 
 
927
    case NSCompositeXOR:
 
928
      return @"NSCompositeXOR";
 
929
 
 
930
    case NSCompositePlusDarker:
 
931
      return @"NSCompositePlusDarker";
 
932
 
 
933
    case NSCompositeHighlight:
 
934
      return @"NSCompositeHighlight";
 
935
 
 
936
    case NSCompositePlusLighter:
 
937
      return @"NSCompositePlusLighter";
 
938
 
 
939
    default:
 
940
      return @"default";
 
941
 
 
942
    }
 
943
}
 
944
*/
 
945
 
 
946
static void
 
947
_set_op(cairo_t * ct, NSCompositingOperation op)
 
948
{
 
949
  switch (op)
 
950
    {
 
951
    case NSCompositeClear:
 
952
      cairo_set_operator(ct, CAIRO_OPERATOR_CLEAR);
 
953
      break;
 
954
    case NSCompositeCopy:
 
955
      cairo_set_operator(ct, CAIRO_OPERATOR_SRC);
 
956
      break;
 
957
    case NSCompositeSourceOver:
 
958
      cairo_set_operator(ct, CAIRO_OPERATOR_OVER);
 
959
      break;
 
960
    case NSCompositeSourceIn:
 
961
      cairo_set_operator(ct, CAIRO_OPERATOR_IN);
 
962
      break;
 
963
    case NSCompositeSourceOut:
 
964
      cairo_set_operator(ct, CAIRO_OPERATOR_OUT);
 
965
      break;
 
966
    case NSCompositeSourceAtop:
 
967
      cairo_set_operator(ct, CAIRO_OPERATOR_ATOP);
 
968
      break;
 
969
    case NSCompositeDestinationOver:
 
970
      cairo_set_operator(ct, CAIRO_OPERATOR_OVER_REVERSE);
 
971
      break;
 
972
    case NSCompositeDestinationIn:
 
973
      cairo_set_operator(ct, CAIRO_OPERATOR_IN_REVERSE);
 
974
      break;
 
975
    case NSCompositeDestinationOut:
 
976
      cairo_set_operator(ct, CAIRO_OPERATOR_OUT_REVERSE);
 
977
      break;
 
978
    case NSCompositeDestinationAtop:
 
979
      cairo_set_operator(ct, CAIRO_OPERATOR_ATOP_REVERSE);
 
980
      break;
 
981
    case NSCompositeXOR:
 
982
      cairo_set_operator(ct, CAIRO_OPERATOR_XOR);
 
983
      break;
 
984
    case NSCompositePlusDarker:
 
985
      break;
 
986
    case NSCompositeHighlight:
 
987
      cairo_set_operator(ct, CAIRO_OPERATOR_SATURATE);
 
988
      break;
 
989
    case NSCompositePlusLighter:
 
990
      cairo_set_operator(ct, CAIRO_OPERATOR_ADD);
 
991
      break;
 
992
    default:
 
993
      cairo_set_operator(ct, CAIRO_OPERATOR_SRC);
 
994
    }
 
995
}
 
996
 
 
997
- (void) DPSimage: (NSAffineTransform *)matrix : (int)pixelsWide
 
998
                 : (int)pixelsHigh : (int)bitsPerSample 
 
999
                 : (int)samplesPerPixel : (int)bitsPerPixel
 
1000
                 : (int)bytesPerRow : (BOOL)isPlanar
 
1001
                 : (BOOL)hasAlpha : (NSString *)colorSpaceName
 
1002
                 : (const unsigned char *const[5])data
 
1003
{
 
1004
  cairo_format_t format;
 
1005
  NSAffineTransformStruct tstruct;
 
1006
  cairo_t *ict;
 
1007
  cairo_surface_t *surface;
 
1008
 
 
1009
/*
 
1010
  NSLog(@"%@ DPSimage %dx%d (%p)", self, pixelsWide, pixelsHigh,
 
1011
        cairo_current_target_surface (_ct));
 
1012
*/
 
1013
  if (isPlanar || !([colorSpaceName isEqualToString: NSDeviceRGBColorSpace] ||
 
1014
                    [colorSpaceName isEqualToString: NSCalibratedRGBColorSpace]))
 
1015
    {
 
1016
      NSLog(@"Image format not support");
 
1017
      return;
 
1018
    }
 
1019
 
 
1020
  switch (bitsPerSample * samplesPerPixel)
 
1021
    {
 
1022
    case 32:
 
1023
      format = CAIRO_FORMAT_ARGB32;
 
1024
      break;
 
1025
    case 24:
 
1026
      format = CAIRO_FORMAT_RGB24;
 
1027
      break;
 
1028
    default:
 
1029
      NSLog(@"Image format not support");
 
1030
      return;
 
1031
    }
 
1032
//      [self DPSinitclip];
 
1033
 
 
1034
  tstruct = [matrix transformStruct];
 
1035
  /*
 
1036
     NSLog(@"%g %g %g %g %g %g",
 
1037
     tstruct.m11, tstruct.m12,
 
1038
     tstruct.m21, tstruct.m22,
 
1039
     tstruct.tX, tstruct.tY);
 
1040
  */
 
1041
 
 
1042
  ict = cairo_create();
 
1043
  [_surface setAsTargetOfCairo: ict];
 
1044
  _flipCairoSurfaceMatrix(ict, _surface);
 
1045
  cairo_matrix_set_affine(local_matrix,
 
1046
                          tstruct.m11, tstruct.m12,
 
1047
                          tstruct.m21, tstruct.m22, tstruct.tX, tstruct.tY);
 
1048
  cairo_concat_matrix(ict, local_matrix);
 
1049
 
 
1050
  surface = cairo_surface_create_for_image((void*)data, 
 
1051
                                           format,
 
1052
                                           pixelsWide,
 
1053
                                           pixelsHigh,
 
1054
                                           bytesPerRow);
 
1055
  cairo_matrix_set_identity(local_matrix);
 
1056
  cairo_matrix_scale(local_matrix, 1, -1);
 
1057
  cairo_matrix_translate(local_matrix, 0, -pixelsHigh);
 
1058
  cairo_surface_set_matrix(surface, local_matrix);
 
1059
  cairo_show_surface(ict,
 
1060
                     surface,
 
1061
                     pixelsWide,
 
1062
                     pixelsHigh);
 
1063
  cairo_surface_destroy(surface);
 
1064
  cairo_destroy(ict);
 
1065
}
 
1066
 
 
1067
- (void) compositerect: (NSRect)aRect op: (NSCompositingOperation)op
 
1068
{
 
1069
  _set_op(_ct, op);
 
1070
  cairo_rectangle(_ct, NSMinX(aRect), NSMinY(aRect), NSWidth(aRect),
 
1071
                  NSHeight(aRect));
 
1072
  cairo_fill(_ct);
 
1073
}
 
1074
 
 
1075
- (void) compositeGState: (CairoGState *)source 
 
1076
                fromRect: (NSRect)aRect 
 
1077
                 toPoint: (NSPoint)aPoint 
 
1078
                      op: (NSCompositingOperation)op
 
1079
                fraction: (float)delta
 
1080
{
 
1081
  cairo_surface_t *src;
 
1082
 
 
1083
  /*
 
1084
    NSLog(NSStringFromRect(aRect));
 
1085
    NSLog(@"src %p(%p,%@) des %p(%p,%@)",source,cairo_current_target_surface(source->_ct),NSStringFromSize([source->_surface size]),
 
1086
    self,cairo_current_target_surface(_ct),NSStringFromSize([_surface size]));
 
1087
  */
 
1088
  cairo_save(_ct);
 
1089
  _set_op(_ct, op);
 
1090
  cairo_set_alpha(_ct, delta);
 
1091
  cairo_translate(_ct, aPoint.x, aPoint.y);
 
1092
 
 
1093
  cairo_matrix_set_identity(local_matrix);
 
1094
  cairo_matrix_scale(local_matrix, 1, -1);
 
1095
  cairo_matrix_translate(local_matrix, 0, -[source->_surface size].height);
 
1096
  // cairo_matrix_translate(local_matrix, NSMinX(aRect), NSMinY(aRect));
 
1097
  src = cairo_current_target_surface(source->_ct);
 
1098
  cairo_surface_set_matrix(src, local_matrix);
 
1099
  cairo_show_surface(_ct, src, NSWidth(aRect), NSHeight(aRect));
 
1100
  cairo_restore(_ct);
 
1101
}
 
1102
 
 
1103
- (void) compositeGState: (CairoGState *)source 
 
1104
                fromRect: (NSRect)aRect 
 
1105
                 toPoint: (NSPoint)aPoint 
 
1106
                      op: (NSCompositingOperation)op
 
1107
{
 
1108
  [self compositeGState: source 
 
1109
               fromRect: aRect 
 
1110
                toPoint: aPoint 
 
1111
                     op: op
 
1112
               fraction: 1.0];
 
1113
}
 
1114
 
 
1115
- (void) dissolveGState: (CairoGState *)source
 
1116
               fromRect: (NSRect)aRect
 
1117
                toPoint: (NSPoint)aPoint 
 
1118
                  delta: (float)delta
 
1119
{
 
1120
  [self compositeGState: source 
 
1121
               fromRect: aRect 
 
1122
                toPoint: aPoint 
 
1123
                     op: NSCompositeSourceOver
 
1124
               fraction: delta];
 
1125
}
 
1126
 
 
1127
@end