~ubuntu-branches/ubuntu/trusty/lmms/trusty

« back to all changes in this revision

Viewing changes to plugins/zynaddsubfx/fltk/src/fl_rect.cxx

  • Committer: Charlie Smotherman
  • Date: 2012-12-05 22:08:38 UTC
  • mfrom: (33.1.7 lmms_0.4.13)
  • Revision ID: cjsmo@cableone.net-20121205220838-09pjfzew9m5023hr
* New  Upstream release.
  - Minor tweaking to ZynAddSubFX, CALF, SWH plugins  and Stefan Fendt's RC
    filters.
  - Added UI fixes: Magnentic effect of knobs and Piano-roll fixes
  - Updated German localization and copyright year
* debian/lmms-common.install:
  - added /usr/share/applications so the lmms.desktop file will correctly
    install (LP: #863366)
  - This should also fix the Software Center not displaying lmms in sound
    and video (LP: #824231)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//
2
 
// "$Id: fl_rect.cxx 7617 2010-05-27 17:20:18Z manolo $"
 
2
// "$Id: fl_rect.cxx 8630 2011-05-01 12:45:29Z AlbrechtS $"
3
3
//
4
4
// Rectangle drawing routines for the Fast Light Tool Kit (FLTK).
5
5
//
6
 
// Copyright 1998-2009 by Bill Spitzak and others.
 
6
// Copyright 1998-2010 by Bill Spitzak and others.
7
7
//
8
8
// This library is free software; you can redistribute it and/or
9
9
// modify it under the terms of the GNU Library General Public
42
42
#include <FL/fl_draw.H>
43
43
#include <FL/x.H>
44
44
 
 
45
// fl_line_width_ must contain the absolute value of the current
 
46
// line width to be used for X11 clipping (see below).
 
47
// This is defined in src/fl_line_style.cxx
 
48
extern int fl_line_width_;
 
49
 
45
50
#ifdef __APPLE_QUARTZ__
46
51
extern float fl_quartz_line_width_;
47
 
#define USINGQUARTZPRINTER  (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type)
48
 
#endif
 
52
#define USINGQUARTZPRINTER  (Fl_Surface_Device::surface()->class_name() == Fl_Printer::class_id)
 
53
#endif
 
54
 
 
55
#ifdef USE_X11
 
56
 
 
57
#ifndef SHRT_MAX
 
58
#define SHRT_MAX (32767)
 
59
#endif
 
60
 
 
61
/*
 
62
  We need to check some coordinates for areas for clipping before we
 
63
  use X functions, because X can't handle coordinates outside the 16-bit
 
64
  range. Since all windows use relative coordinates > 0, we do also
 
65
  check for negative values. X11 only, see also STR #2304.
 
66
  
 
67
  Note that this is only necessary for large objects, where only a
 
68
  part of the object is visible. The draw() functions (e.g. box
 
69
  drawing) must be clipped correctly. This is usually only a matter
 
70
  for large container widgets. The individual child widgets will be
 
71
  clipped completely.
 
72
 
 
73
  We define the usable X coordinate space as [ -LW : SHRT_MAX - LW ]
 
74
  where LW = current line width for drawing. This is done so that
 
75
  horizontal and vertical line drawing works correctly, even in real
 
76
  border cases, e.g. drawing a rectangle slightly outside the top left
 
77
  window corner, but with a line width so that a part of the line should
 
78
  be visible (in this case 2 of 5 pixels):
 
79
 
 
80
    fl_line_style (FL_SOLID,5); // line width = 5
 
81
    fl_rect (-1,-1,100,100);    // top/left: 2 pixels visible
 
82
  
 
83
  In this example case, no clipping would be done, because X can
 
84
  handle it and clip unneeded pixels.
 
85
  
 
86
  Note that we must also take care of the case where fl_line_width_
 
87
  is zero (maybe unitialized). If this is the case, we assume a line
 
88
  width of 1.
 
89
 
 
90
  Todo: Arbitrary line drawings (e.g. polygons) and clip regions
 
91
  are not yet done.
 
92
 
 
93
  Note:
 
94
 
 
95
  We could use max. screen coordinates instead of SHRT_MAX, but that
 
96
  would need more work and would probably be slower. We assume that
 
97
  all window coordinates are >= 0 and that no window extends up to
 
98
  32767 - LW (where LW = current line width). Thus it is safe to clip
 
99
  all coordinates to this range before calling X functions. If this
 
100
  is not true, then clip_to_short() and clip_x() must be redefined.
 
101
 
 
102
  It would be somewhat easier if we had fl_clip_w and fl_clip_h, as
 
103
  defined in FLTK 2.0 (for the upper clipping bounds)...
 
104
*/
 
105
 
 
106
/*
 
107
  clip_to_short() returns 1, if the area is invisible (clipped),
 
108
  because ...
 
109
 
 
110
    (a) w or h are <= 0         i.e. nothing is visible
 
111
    (b) x+w or y+h are < kmin   i.e. left of or above visible area
 
112
    (c) x or y are > kmax       i.e. right of or below visible area
 
113
 
 
114
  kmin and kmax are the minimal and maximal X coordinate values,
 
115
  as defined above. In this case x, y, w, and h are not changed.
 
116
 
 
117
  It returns 0, if the area is potentially visible and X can handle
 
118
  clipping. x, y, w, and h may have been adjusted to fit into the
 
119
  X coordinate space.
 
120
 
 
121
  Use this for clipping rectangles, as used in fl_rect() and
 
122
  fl_rectf().
 
123
*/
 
124
 
 
125
static int clip_to_short(int &x, int &y, int &w, int &h) {
 
126
 
 
127
  int lw = (fl_line_width_ > 0) ? fl_line_width_ : 1;
 
128
  int kmin = -lw;
 
129
  int kmax = SHRT_MAX - lw;
 
130
 
 
131
  if (w <= 0 || h <= 0) return 1;               // (a)
 
132
  if (x+w < kmin || y+h < kmin) return 1;       // (b)
 
133
  if (x > kmax || y > kmax) return 1;           // (c)
 
134
 
 
135
  if (x < kmin) { w -= (kmin-x); x = kmin; }
 
136
  if (y < kmin) { h -= (kmin-y); y = kmin; }
 
137
  if (x+w > kmax) w = kmax - x;
 
138
  if (y+h > kmax) h = kmax - y;
 
139
 
 
140
  return 0;
 
141
}
 
142
 
 
143
/*
 
144
  clip_x() returns a coordinate value clipped to the 16-bit coordinate
 
145
  space (see above). This can be used to draw horizontal and vertical
 
146
  lines that can be handled by X11. Each single coordinate value can
 
147
  be clipped individually, and the result can be used directly, e.g.
 
148
  in fl_xyline() and fl_yxline(). Note that this can't be used for
 
149
  arbitrary lines (not horizontal or vertical).
 
150
*/
 
151
static int clip_x (int x) {
 
152
 
 
153
  int lw = (fl_line_width_ > 0) ? fl_line_width_ : 1;
 
154
  int kmin = -lw;
 
155
  int kmax = SHRT_MAX - lw;
 
156
 
 
157
  if (x < kmin)
 
158
    x = kmin;
 
159
  else if (x > kmax)
 
160
    x = kmax;
 
161
  return x;
 
162
}
 
163
 
 
164
#endif  // USE_X11
 
165
 
49
166
 
50
167
void Fl_Graphics_Driver::rect(int x, int y, int w, int h) {
51
168
 
52
169
  if (w<=0 || h<=0) return;
53
170
#if defined(USE_X11)
54
 
  XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
 
171
  if (!clip_to_short(x, y, w, h))
 
172
    XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
55
173
#elif defined(WIN32)
56
174
  MoveToEx(fl_gc, x, y, 0L); 
57
175
  LineTo(fl_gc, x+w-1, y);
59
177
  LineTo(fl_gc, x, y+h-1);
60
178
  LineTo(fl_gc, x, y);
61
179
#elif defined(__APPLE_QUARTZ__)
62
 
  if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
 
180
  if ( (!USINGQUARTZPRINTER) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
63
181
  CGRect rect = CGRectMake(x, y, w-1, h-1);
64
182
  CGContextStrokeRect(fl_gc, rect);
65
 
  if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
 
183
  if ( (!USINGQUARTZPRINTER) && fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
66
184
#else
67
185
# error unsupported platform
68
186
#endif
71
189
void Fl_Graphics_Driver::rectf(int x, int y, int w, int h) {
72
190
  if (w<=0 || h<=0) return;
73
191
#if defined(USE_X11)
74
 
  if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
 
192
  if (!clip_to_short(x, y, w, h))
 
193
    XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
75
194
#elif defined(WIN32)
76
195
  RECT rect;
77
196
  rect.left = x; rect.top = y;  
78
197
  rect.right = x + w; rect.bottom = y + h;
79
198
  FillRect(fl_gc, &rect, fl_brush());
80
199
#elif defined(__APPLE_QUARTZ__)
81
 
  if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
82
 
  CGRect rect = CGRectMake(x, y, w-1, h-1);
 
200
  CGFloat delta_size =  0.9;
 
201
  CGFloat delta_ori = 0;
 
202
  if (USINGQUARTZPRINTER) {
 
203
    delta_size = 0;
 
204
    delta_ori = 0.5;
 
205
    }
 
206
  CGRect  rect = CGRectMake(x - delta_ori, y - delta_ori, w - delta_size , h - delta_size);
83
207
  CGContextFillRect(fl_gc, rect);
84
 
  if (USINGQUARTZPRINTER || fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
85
208
#else
86
209
# error unsupported platform
87
210
#endif
89
212
 
90
213
void Fl_Graphics_Driver::xyline(int x, int y, int x1) {
91
214
#if defined(USE_X11)
92
 
  XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y);
 
215
  XDrawLine(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y), clip_x(x1), clip_x(y));
93
216
#elif defined(WIN32)
94
217
  MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y);
95
218
#elif defined(__APPLE_QUARTZ__)
106
229
void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2) {
107
230
#if defined (USE_X11)
108
231
  XPoint p[3];
109
 
  p[0].x = x;  p[0].y = p[1].y = y;
110
 
  p[1].x = p[2].x = x1; p[2].y = y2;
 
232
  p[0].x = clip_x(x);  p[0].y = p[1].y = clip_x(y);
 
233
  p[1].x = p[2].x = clip_x(x1); p[2].y = clip_x(y2);
111
234
  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
112
235
#elif defined(WIN32)
113
236
  if (y2 < y) y2--;
130
253
void Fl_Graphics_Driver::xyline(int x, int y, int x1, int y2, int x3) {
131
254
#if defined(USE_X11)
132
255
  XPoint p[4];
133
 
  p[0].x = x;  p[0].y = p[1].y = y;
134
 
  p[1].x = p[2].x = x1; p[2].y = p[3].y = y2;
135
 
  p[3].x = x3;
 
256
  p[0].x = clip_x(x);  p[0].y = p[1].y = clip_x(y);
 
257
  p[1].x = p[2].x = clip_x(x1); p[2].y = p[3].y = clip_x(y2);
 
258
  p[3].x = clip_x(x3);
136
259
  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
137
260
#elif defined(WIN32)
138
261
  if(x3 < x1) x3--;
156
279
 
157
280
void Fl_Graphics_Driver::yxline(int x, int y, int y1) {
158
281
#if defined(USE_X11)
159
 
  XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1);
 
282
  XDrawLine(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y), clip_x(x), clip_x(y1));
160
283
#elif defined(WIN32)
161
284
  if (y1 < y) y1--;
162
285
  else y1++;
175
298
void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2) {
176
299
#if defined(USE_X11)
177
300
  XPoint p[3];
178
 
  p[0].x = p[1].x = x;  p[0].y = y;
179
 
  p[1].y = p[2].y = y1; p[2].x = x2;
 
301
  p[0].x = p[1].x = clip_x(x);  p[0].y = clip_x(y);
 
302
  p[1].y = p[2].y = clip_x(y1); p[2].x = clip_x(x2);
180
303
  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
181
304
#elif defined(WIN32)
182
305
  if (x2 > x) x2++;
199
322
void Fl_Graphics_Driver::yxline(int x, int y, int y1, int x2, int y3) {
200
323
#if defined(USE_X11)
201
324
  XPoint p[4];
202
 
  p[0].x = p[1].x = x;  p[0].y = y;
203
 
  p[1].y = p[2].y = y1; p[2].x = p[3].x = x2;
204
 
  p[3].y = y3;
 
325
  p[0].x = p[1].x = clip_x(x);  p[0].y = clip_x(y);
 
326
  p[1].y = p[2].y = clip_x(y1); p[2].x = p[3].x = clip_x(x2);
 
327
  p[3].y = clip_x(y3);
205
328
  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
206
329
#elif defined(WIN32)
207
330
  if(y3<y1) y3--;
378
501
 
379
502
void Fl_Graphics_Driver::point(int x, int y) {
380
503
#if defined(USE_X11)
381
 
  XDrawPoint(fl_display, fl_window, fl_gc, x, y);
 
504
  XDrawPoint(fl_display, fl_window, fl_gc, clip_x(x), clip_x(y));
382
505
#elif defined(WIN32)
383
506
  SetPixel(fl_gc, x, y, fl_RGB());
384
507
#elif defined(__APPLE_QUARTZ__)
385
 
  if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, true);
386
 
  CGContextMoveToPoint(fl_gc, x-.5, y); // Quartz needs a line that is one pixel long, or it will not draw anything
387
 
  CGContextAddLineToPoint(fl_gc, x+.5, y);
388
 
  CGContextStrokePath(fl_gc);
389
 
  if (fl_quartz_line_width_ > 1.5f) CGContextSetShouldAntialias(fl_gc, false);
 
508
  CGContextFillRect(fl_gc, CGRectMake(x - 0.5, y - 0.5, 1, 1) );
390
509
#else
391
510
# error unsupported platform
392
511
#endif
394
513
 
395
514
////////////////////////////////////////////////////////////////
396
515
 
397
 
#define STACK_SIZE 10
398
 
#define STACK_MAX (STACK_SIZE - 1)
399
 
static Fl_Region rstack[STACK_SIZE];
400
 
static int rstackptr=0;
401
 
int fl_clip_state_number=0; // used by gl_begin.cxx to update GL clip
402
 
 
403
516
#if !defined(WIN32) && !defined(__APPLE__)
404
517
// Missing X call: (is this the fastest way to init a 1-rectangle region?)
405
518
// MSWindows equivalent exists, implemented inline in win32.H
406
519
Fl_Region XRectangleRegion(int x, int y, int w, int h) {
407
520
  XRectangle R;
 
521
  clip_to_short(x, y, w, h);
408
522
  R.x = x; R.y = y; R.width = w; R.height = h;
409
523
  Fl_Region r = XCreateRegion();
410
524
  XUnionRectWithRegion(&R, r, r);
412
526
}
413
527
#endif
414
528
 
415
 
void fl_restore_clip() {
 
529
void Fl_Graphics_Driver::restore_clip() {
416
530
  fl_clip_state_number++;
417
531
  Fl_Region r = rstack[rstackptr];
418
532
#if defined(USE_X11)
440
554
#endif
441
555
}
442
556
 
443
 
void fl_clip_region(Fl_Region r) {
 
557
void Fl_Graphics_Driver::clip_region(Fl_Region r) {
444
558
  Fl_Region oldr = rstack[rstackptr];
445
559
  if (oldr) XDestroyRegion(oldr);
446
560
  rstack[rstackptr] = r;
447
561
  fl_restore_clip();
448
562
}
449
563
 
450
 
Fl_Region fl_clip_region() {
 
564
Fl_Region Fl_Graphics_Driver::clip_region() {
451
565
  return rstack[rstackptr];
452
566
}
453
567
 
466
580
      CombineRgn(r,r,current,RGN_AND);
467
581
#elif defined(__APPLE_QUARTZ__)
468
582
      XDestroyRegion(r);
469
 
      r = MacRectRegionIntersect(current, x,y,w,h);
 
583
      r = Fl_X::intersect_region_and_rect(current, x,y,w,h);
470
584
#else
471
585
# error unsupported platform
472
586
#endif
482
596
# error unsupported platform
483
597
#endif
484
598
  }
485
 
  if (rstackptr < STACK_MAX) rstack[++rstackptr] = r;
 
599
  if (rstackptr < region_stack_max) rstack[++rstackptr] = r;
486
600
  else Fl::warning("fl_push_clip: clip stack overflow!\n");
487
601
  fl_restore_clip();
488
602
}
489
603
 
490
604
// make there be no clip (used by fl_begin_offscreen() only!)
491
605
void Fl_Graphics_Driver::push_no_clip() {
492
 
  if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0;
 
606
  if (rstackptr < region_stack_max) rstack[++rstackptr] = 0;
493
607
  else Fl::warning("fl_push_no_clip: clip stack overflow!\n");
494
608
  fl_restore_clip();
495
609
}
506
620
int Fl_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
507
621
  if (x+w <= 0 || y+h <= 0) return 0;
508
622
  Fl_Region r = rstack[rstackptr];
 
623
  if (!r) return 1;
509
624
#if defined (USE_X11)
510
 
  return r ? XRectInRegion(r, x, y, w, h) : 1;
 
625
  // get rid of coordinates outside the 16-bit range the X calls take.
 
626
  if (clip_to_short(x,y,w,h)) return 0; // clipped
 
627
  return XRectInRegion(r, x, y, w, h);
511
628
#elif defined(WIN32)
512
 
  if (!r) return 1;
513
629
  RECT rect;
514
 
  if (Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // in case of print context, convert coords from logical to device
 
630
  if (Fl_Surface_Device::surface()->class_name() == Fl_Printer::class_id) { // in case of print context, convert coords from logical to device
515
631
    POINT pt[2] = { {x, y}, {x + w, y + h} };
516
632
    LPtoDP(fl_gc, pt, 2);
517
633
    rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y;
518
 
    }
519
 
  else {
 
634
  } else {
520
635
    rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
521
 
    }
 
636
  }
522
637
  return RectInRegion(r,&rect);
523
638
#elif defined(__APPLE_QUARTZ__)
524
 
  if (!r) return 1;
525
639
  CGRect arg = fl_cgrectmake_cocoa(x, y, w, h);
526
 
  for(int i = 0; i < r->count; i++) {
 
640
  for (int i = 0; i < r->count; i++) {
527
641
    CGRect test = CGRectIntersection(r->rects[i], arg);
528
 
    if( ! CGRectIsEmpty(test)) return 1;
 
642
    if (!CGRectIsEmpty(test)) return 1;
529
643
  }
530
644
  return 0;
531
645
#else
573
687
  } else {      // partial intersection
574
688
    RECT rect;
575
689
    GetRgnBox(temp, &rect);
576
 
    if(Fl_Surface_Device::surface()->type() == Fl_Printer::device_type) { // if print context, convert coords from device to logical
 
690
    if(Fl_Surface_Device::surface()->class_name() == Fl_Printer::class_id) { // if print context, convert coords from device to logical
577
691
      POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} };
578
692
      DPtoLP(fl_gc, pt, 2);
579
693
      X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y;
597
711
      else u = CGRectUnion(u, test);
598
712
    }
599
713
  }
600
 
  X = u.origin.x;
601
 
  Y = u.origin.y;
602
 
  W = u.size.width + 1;
603
 
  H = u.size.height + 1;
 
714
  X = int(u.origin.x);
 
715
  Y = int(u.origin.y);
 
716
  W = int(u.size.width + 1);
 
717
  H = int(u.size.height + 1);
604
718
  if(CGRectIsEmpty(u)) W = H = 0;
605
719
  return ! CGRectEqualToRect(arg, u);
606
720
#else
609
723
}
610
724
 
611
725
//
612
 
// End of "$Id: fl_rect.cxx 7617 2010-05-27 17:20:18Z manolo $".
 
726
// End of "$Id: fl_rect.cxx 8630 2011-05-01 12:45:29Z AlbrechtS $".
613
727
//