fltk 1.3.0rc3
About: FLTK (Fast Light Tool Kit) is a cross-platform C++ GUI toolkit for UNIX/Linux (X11), Microsoft Windows, and MacOS X. Release candidate.
  SfR Fresh Dox: fltk-1.3.0rc3-source.tar.gz ("inofficial" and yet experimental doxygen-generated source code documentation)  

fl_line_style.cxx

Go to the documentation of this file.
00001 //
00002 // "$Id: fl_line_style.cxx 8190 2011-01-05 10:21:45Z manolo $"
00003 //
00004 // Line style code for the Fast Light Tool Kit (FLTK).
00005 //
00006 // Copyright 1998-2010 by Bill Spitzak and others.
00007 //
00008 // This library is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU Library General Public
00010 // License as published by the Free Software Foundation; either
00011 // version 2 of the License, or (at your option) any later version.
00012 //
00013 // This library is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU Library General Public
00019 // License along with this library; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00021 // USA.
00022 //
00023 // Please report all bugs and problems on the following page:
00024 //
00025 //     http://www.fltk.org/str.php
00026 //
00027 
00033 #include <FL/Fl.H>
00034 #include <FL/fl_draw.H>
00035 #include <FL/x.H>
00036 #include <FL/Fl_Printer.H>
00037 #include "flstring.h"
00038 #include <stdio.h>
00039 
00040 // We save the current line width (absolute value) here.
00041 // This is currently used only for X11 clipping, see src/fl_rect.cxx.
00042 // FIXME: this would probably better be in class Fl::
00043 int fl_line_width_ = 0;
00044 
00045 #ifdef __APPLE_QUARTZ__
00046 float fl_quartz_line_width_ = 1.0f;
00047 static enum CGLineCap fl_quartz_line_cap_ = kCGLineCapButt;
00048 static enum CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter;
00049 static CGFloat *fl_quartz_line_pattern = 0;
00050 static int fl_quartz_line_pattern_size = 0;
00051 void fl_quartz_restore_line_style_() {
00052   CGContextSetLineWidth(fl_gc, fl_quartz_line_width_);
00053   CGContextSetLineCap(fl_gc, fl_quartz_line_cap_);
00054   CGContextSetLineJoin(fl_gc, fl_quartz_line_join_);
00055   CGContextSetLineDash(fl_gc, 0, fl_quartz_line_pattern, fl_quartz_line_pattern_size);
00056 }
00057 #endif
00058 
00059 void Fl_Graphics_Driver::line_style(int style, int width, char* dashes) {
00060 
00061   // save line width in global variable for X11 clipping
00062   if (width == 0) fl_line_width_ = 1;
00063   else fl_line_width_ = width>0 ? width : -width;
00064 
00065 #if defined(USE_X11)
00066   int ndashes = dashes ? strlen(dashes) : 0;
00067   // emulate the WIN32 dash patterns on X
00068   char buf[7];
00069   if (!ndashes && (style&0xff)) {
00070     int w = width ? width : 1;
00071     char dash, dot, gap;
00072     // adjust lengths to account for cap:
00073     if (style & 0x200) {
00074       dash = char(2*w);
00075       dot = 1; // unfortunately 0 does not work
00076       gap = char(2*w-1);
00077     } else {
00078       dash = char(3*w);
00079       dot = gap = char(w);
00080     }
00081     char* p = dashes = buf;
00082     switch (style & 0xff) {
00083     case FL_DASH:       *p++ = dash; *p++ = gap; break;
00084     case FL_DOT:        *p++ = dot; *p++ = gap; break;
00085     case FL_DASHDOT:    *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break;
00086     case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break;
00087     }
00088     ndashes = p-buf;
00089   }
00090   static int Cap[4] = {CapButt, CapButt, CapRound, CapProjecting};
00091   static int Join[4] = {JoinMiter, JoinMiter, JoinRound, JoinBevel};
00092   XSetLineAttributes(fl_display, fl_gc, width, 
00093                      ndashes ? LineOnOffDash : LineSolid,
00094                      Cap[(style>>8)&3], Join[(style>>12)&3]);
00095   if (ndashes) XSetDashes(fl_display, fl_gc, 0, dashes, ndashes);
00096 #elif defined(WIN32)
00097   // According to Bill, the "default" cap and join should be the
00098   // "fastest" mode supported for the platform.  I don't know why
00099   // they should be different (same graphics cards, etc., right?) MRS
00100   static DWORD Cap[4]= {PS_ENDCAP_FLAT, PS_ENDCAP_FLAT, PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE};
00101   static DWORD Join[4]={PS_JOIN_ROUND, PS_JOIN_MITER, PS_JOIN_ROUND, PS_JOIN_BEVEL};
00102   int s1 = PS_GEOMETRIC | Cap[(style>>8)&3] | Join[(style>>12)&3];
00103   DWORD a[16]; int n = 0;
00104   if (dashes && dashes[0]) {
00105     s1 |= PS_USERSTYLE;
00106     for (n = 0; n < 16 && *dashes; n++) a[n] = *dashes++;
00107   } else {
00108     s1 |= style & 0xff; // allow them to pass any low 8 bits for style
00109   }
00110   if ((style || n) && !width) width = 1; // fix cards that do nothing for 0?
00111   LOGBRUSH penbrush = {BS_SOLID,fl_RGB(),0}; // can this be fl_brush()?
00112   HPEN newpen = ExtCreatePen(s1, width, &penbrush, n, n ? a : 0);
00113   if (!newpen) {
00114     Fl::error("fl_line_style(): Could not create GDI pen object.");
00115     return;
00116   }
00117   HPEN oldpen = (HPEN)SelectObject(fl_gc, newpen);
00118   DeleteObject(oldpen);
00119   DeleteObject(fl_current_xmap->pen);
00120   fl_current_xmap->pen = newpen;
00121 #elif defined(__APPLE_QUARTZ__)
00122   static enum CGLineCap Cap[4] = { kCGLineCapButt, kCGLineCapButt, 
00123                                    kCGLineCapRound, kCGLineCapSquare };
00124   static enum CGLineJoin Join[4] = { kCGLineJoinMiter, kCGLineJoinMiter, 
00125                                     kCGLineJoinRound, kCGLineJoinBevel };
00126   if (width<1) width = 1;
00127   fl_quartz_line_width_ = (float)width; 
00128   fl_quartz_line_cap_ = Cap[(style>>8)&3];
00129   // when printing kCGLineCapSquare seems better for solid lines
00130   if ( Fl_Surface_Device::surface()->class_name() == Fl_Printer::class_id && style == FL_SOLID && dashes == NULL ) {
00131     fl_quartz_line_cap_ = kCGLineCapSquare;
00132     }
00133   fl_quartz_line_join_ = Join[(style>>12)&3];
00134   char *d = dashes; 
00135   static CGFloat pattern[16];
00136   if (d && *d) {
00137         CGFloat *p = pattern;
00138     while (*d) { *p++ = (float)*d++; }
00139     fl_quartz_line_pattern = pattern;
00140     fl_quartz_line_pattern_size = d-dashes;
00141   } else if (style & 0xff) {
00142     char dash, dot, gap;
00143     // adjust lengths to account for cap:
00144     if (style & 0x200) {
00145       dash = char(2*width);
00146       dot = 1; 
00147       gap = char(2*width-1);
00148     } else {
00149       dash = char(3*width);
00150       dot = gap = char(width);
00151     }
00152         CGFloat *p = pattern;
00153     switch (style & 0xff) {
00154     case FL_DASH:       *p++ = dash; *p++ = gap; break;
00155     case FL_DOT:        *p++ = dot; *p++ = gap; break;
00156     case FL_DASHDOT:    *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break;
00157     case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break;
00158     }
00159     fl_quartz_line_pattern_size = p-pattern;
00160     fl_quartz_line_pattern = pattern;
00161   } else {
00162     fl_quartz_line_pattern = 0; 
00163                 fl_quartz_line_pattern_size = 0;
00164   }
00165   fl_quartz_restore_line_style_();
00166 #else
00167 # error unsupported platform
00168 #endif
00169 }
00170 
00171 
00172 //
00173 // End of "$Id: fl_line_style.cxx 8190 2011-01-05 10:21:45Z manolo $".
00174 //