|
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) ![]() |
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 //