FLTK logo

[Library] r9012 - branches/branch-3.0/src/fltk3gl

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Library      Forums      Links      Apps     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[Library] r9012 - branches/branch-3.0/src/fltk3gl fltk-dev Aug 25, 2011  
 
Author: matt
Date: 2011-08-25 15:05:10 -0700 (Thu, 25 Aug 2011)
New Revision: 9012
Log:
Missing files

Added:
   branches/branch-3.0/src/fltk3gl/gl_draw.cxx
   branches/branch-3.0/src/fltk3gl/gl_start.cxx
   branches/branch-3.0/src/fltk3gl/glut_compatability.cxx
   branches/branch-3.0/src/fltk3gl/glut_font.cxx

Added: branches/branch-3.0/src/fltk3gl/gl_draw.cxx
===================================================================
--- branches/branch-3.0/src/fltk3gl/gl_draw.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/gl_draw.cxx	2011-08-25 22:05:10 UTC (rev 9012)
@@ -0,0 +1,580 @@
+//
+// "$Id: gl_draw.cxx 8991 2011-08-22 15:21:44Z matt $"
+//
+// OpenGL drawing support routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2011 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Functions from <fltk3/gl.h>
+// See also fltk3::GLWindow and gl_start.cxx
+
+#include "../fltk3/flstring.h"
+#if HAVE_GL || defined(FLTK3_DOXYGEN)
+
+#include <fltk3/run.h>
+#include <fltk3gl/gl.h>
+#include <fltk3/x.h>
+#include <fltk3/draw.h>
+#include <fltk3/Device.h>
+#include "GLChoice.H"
+#include "../fltk3/font.h"
+#include <fltk3/utf8.h>
+
+#if !defined(WIN32) && !defined(__APPLE__)
+#include <fltk3/Xutf8.h>
+#endif
+
+#if USE_XFT
+//extern XFontStruct* fl_xxfont();
+#endif // USE_XFT
+
+/** Returns the current font's height */
+int   gl_height() {return fltk3::height();}
+/** Returns the current font's descent */
+int   gl_descent() {return fltk3::descent();}
+/** Returns the width of the string in the current fnt */
+double gl_width(const char* s) {return fltk3::width(s);}
+/** Returns the width of n characters of the string in the current font */
+double gl_width(const char* s, int n) {return fltk3::width(s,n);}
+/** Returns the width of the character in the current font */
+double gl_width(uchar c) {return fltk3::width(c);}
+
+static Fl_Font_Descriptor *gl_fontsize;
+
+#define GL_DRAW_USES_TEXTURES  (defined(__APPLE__) && !__ppc__) // 1 only for non-PPC OSX
+#ifndef __APPLE__
+#  define USE_OksiD_style_GL_font_selection 1  // Most hosts except OSX
+#else
+#  undef USE_OksiD_style_GL_font_selection  // OSX
+#endif
+
+#if USE_XFT
+#  undef USE_OksiD_style_GL_font_selection  // turn this off for XFT also
+#endif
+
+/**
+  Sets the current OpenGL font to the same font as calling fltk3::font()
+  */
+void  gl_font(int fontid, int size) {
+  fltk3::font(fontid, size);
+  Fl_Font_Descriptor *fontsize = fltk3::graphics_driver->font_descriptor();
+#if !GL_DRAW_USES_TEXTURES
+  if (!fontsize->listbase) {
+
+#ifdef  USE_OksiD_style_GL_font_selection
+    fontsize->listbase = glGenLists(0x10000);
+#else // Fltk-1.1.8 style GL font selection
+
+#if defined (USE_X11) // X-windows options follow, either XFT or "plain" X
+// FIXME:  warning Ideally, for XFT, we really need a glXUseXftFont implementation here...
+// FIXME:  warning GL font selection is basically wrong here
+/* OksiD had a fairly sophisticated scheme for storing multiple X fonts in a XUtf8FontStruct,
+ * then sorting through them at draw time (for normal X rendering) to find which one can
+ * render the current glyph... But for now, just use the first font in the list for GL...
+ */
+    XFontStruct *font = fl_xfont;
+    int base = font->min_char_or_byte2;
+    int count = font->max_char_or_byte2-base+1;
+    fontsize->listbase = glGenLists(256);
+    glXUseXFont(font->fid, base, count, fontsize->listbase+base);
+# elif defined(WIN32)
+    // this is unused because USE_OksiD_style_GL_font_selection == 1
+    int base = fontsize->metr.tmFirstChar;
+    int count = fontsize->metr.tmLastChar-base+1;
+    HFONT oldFid = (HFONT)SelectObject(fl_gc, fontsize->fid);
+    fontsize->listbase = glGenLists(256);
+    wglUseFontBitmaps(fl_gc, base, count, fontsize->listbase+base);
+    SelectObject(fl_gc, oldFid);
+# elif defined(__APPLE_QUARTZ__)
+//AGL is not supported for use in 64-bit applications:
+//http://developer.apple.com/mac/library/documentation/Carbon/Conceptual/Carbon64BitGuide/OtherAPIChanges/OtherAPIChanges.html
+    short font, face, size;
+    uchar fn[256];
+    fn[0]=strlen(fontsize->q_name);
+    strcpy((char*)(fn+1), fontsize->q_name);
+    GetFNum(fn, &font);
+    face = 0;
+    size = fontsize->size;
+    fontsize->listbase = glGenLists(256);
+	aglUseFont(aglGetCurrentContext(), font, face,
+               size, 0, 256, fontsize->listbase);
+# else 
+#   error unsupported platform
+# endif
+
+#endif // USE_OksiD_style_GL_font_selection
+  }
+  glListBase(fontsize->listbase);
+#endif // !GL_DRAW_USES_TEXTURES
+  gl_fontsize = fontsize;
+}
+
+#ifndef __APPLE__
+static void get_list(int r) {
+  gl_fontsize->glok[r] = 1;
+#if defined(USE_X11)
+# if USE_XFT
+// FIXME
+# else
+  unsigned int ii = r * 0x400;
+  for (int i = 0; i < 0x400; i++) {
+    XFontStruct *font = NULL;
+    unsigned short id;
+    XGetUtf8FontAndGlyph(gl_fontsize->font, ii, &font, &id);
+    if (font) glXUseXFont(font->fid, id, 1, gl_fontsize->listbase+ii);
+    ii++;
+   }
+# endif
+#elif defined(WIN32)
+  unsigned int ii = r * 0x400;
+  HFONT oldFid = (HFONT)SelectObject(fl_gc, gl_fontsize->fid);
+  wglUseFontBitmapsW(fl_gc, ii, ii + 0x03ff, gl_fontsize->listbase+ii);
+  SelectObject(fl_gc, oldFid);
+#elif defined(__APPLE_QUARTZ__)
+// handled by textures
+#else
+#  error unsupported platform
+#endif
+} // get_list
+#endif
+
+void gl_remove_displaylist_fonts()
+{
+# if HAVE_GL
+
+  // clear variables used mostly in fltk3::font
+  fltk3::graphics_driver->font(0, 0);
+
+  for (int j = 0 ; j < fltk3::FREE_FONT ; ++j)
+  {
+    Fl_Font_Descriptor* past = 0;
+    Fl_Fontdesc* s    = fltk3::fonts + j ;
+    Fl_Font_Descriptor* f    = s->first;
+    while (f != 0) {
+      if(f->listbase) {
+        if(f == s->first) {
+          s->first = f->next;
+        }
+        else {
+          past->next = f->next;
+        }
+
+        // It would be nice if this next line was in a desctructor somewhere
+        glDeleteLists(f->listbase, 256);
+
+        Fl_Font_Descriptor* tmp = f;
+        f = f->next;
+        delete tmp;
+      }
+      else {
+        past = f;
+        f = f->next;
+      }
+    }
+  }
+
+#endif
+}
+
+#if GL_DRAW_USES_TEXTURES
+static void gl_draw_textures(const char* str, int n);
+#endif
+
+/**
+  Draws an array of n characters of the string in the current font
+  at the current position.
+ \see On the Mac OS X platform, see gl_texture_pile_height(int)
+  */
+void gl_draw(const char* str, int n) {
+#ifdef __APPLE__  
+  
+#if GL_DRAW_USES_TEXTURES
+  gl_draw_textures(str, n);
+#else
+  glCallLists(n, GL_UNSIGNED_BYTE, str);
+#endif
+  
+#else
+  static xchar *buf = NULL;
+  static int l = 0;
+  int wn = fltk3::utf8toUtf16(str, n, (unsigned short*)buf, l);
+  if(wn >= l) {
+    buf = (xchar*) realloc(buf, sizeof(xchar) * (wn + 1));
+    l = wn + 1;
+    wn = fltk3::utf8toUtf16(str, n, (unsigned short*)buf, l);
+  }
+  n = wn;
+
+  int i;
+  for (i = 0; i < n; i++) {
+    unsigned int r;
+    r = (str[i] & 0xFC00) >> 10;
+    if (!gl_fontsize->glok[r]) get_list(r);
+  }
+  glCallLists(n, GL_UNSIGNED_SHORT, buf);
+#endif
+}
+
+/**
+  Draws n characters of the string in the current font at the given position 
+ \see On the Mac OS X platform, see gl_texture_pile_height(int)
+  */
+void gl_draw(const char* str, int n, int x, int y) {
+  glRasterPos2i(x, y);
+  gl_draw(str, n);
+}
+
+/**
+  Draws n characters of the string in the current font at the given position 
+ \see On the Mac OS X platform, see gl_texture_pile_height(int)
+  */
+void gl_draw(const char* str, int n, float x, float y) {
+  glRasterPos2f(x, y);
+  gl_draw(str, n);
+}
+
+/**
+  Draws a nul-terminated string in the current font at the current position
+ \see On the Mac OS X platform, see gl_texture_pile_height(int)
+  */
+void gl_draw(const char* str) {
+  gl_draw(str, strlen(str));
+}
+
+/**
+  Draws a nul-terminated string in the current font at the given position 
+ \see On the Mac OS X platform, see gl_texture_pile_height(int)
+  */
+void gl_draw(const char* str, int x, int y) {
+  gl_draw(str, strlen(str), x, y);
+}
+
+/**
+  Draws a nul-terminated string in the current font at the given position 
+ \see On the Mac OS X platform, see gl_texture_pile_height(int)
+  */
+void gl_draw(const char* str, float x, float y) {
+  gl_draw(str, strlen(str), x, y);
+}
+
+static void gl_draw_invert(const char* str, int n, int x, int y) {
+  glRasterPos2i(x, -y);
+  gl_draw(str, n);
+}
+
+/**
+  Draws a string formatted into a box, with newlines and tabs expanded,
+  other control characters changed to ^X. and aligned with the edges or
+  center. Exactly the same output as fltk3::draw().
+  */
+void gl_draw(
+  const char* str, 	// the (multi-line) string
+  int x, int y, int w, int h, 	// bounding box
+  fltk3::Align align) {
+  fltk3::draw(str, x, -y-h, w, h, align, gl_draw_invert);
+}
+
+/** Measure how wide and tall the string will be when drawn by the gl_draw() function */
+void gl_measure(const char* str, int& x, int& y) {fltk3::measure(str,x,y);}
+
+/**
+  Outlines the given rectangle with the current color.
+  If fltk3::GLWindow::ortho() has been called, then the rectangle will
+  exactly fill the given pixel rectangle.
+  */
+void gl_rect(int x, int y, int w, int h) {
+  if (w < 0) {w = -w; x = x-w;}
+  if (h < 0) {h = -h; y = y-h;}
+  glBegin(GL_LINE_STRIP);
+  glVertex2i(x+w-1, y+h-1);
+  glVertex2i(x+w-1, y);
+  glVertex2i(x, y);
+  glVertex2i(x, y+h-1);
+  glVertex2i(x+w, y+h-1);
+  glEnd();
+}
+
+#if HAVE_GL_OVERLAY
+extern uchar fl_overlay;
+extern int fl_overlay_depth;
+#endif
+
+/**
+  Sets the curent OpenGL color to an FLTK color.
+
+  For color-index modes it will use fl_xpixel(c), which is only
+  right if the window uses the default colormap!
+  */
+void gl_color(fltk3::Color i) {
+#if HAVE_GL_OVERLAY
+#if defined(WIN32)
+  if (fl_overlay && fl_overlay_depth) {
+    if (fl_overlay_depth < 8) {
+      // only black & white produce the expected colors.  This could
+      // be improved by fixing the colormap set in Fl_Gl_Overlay.cxx
+      int size = 1<<fl_overlay_depth;
+      if (!i) glIndexi(size-2);
+      else if (i >= size-2) glIndexi(size-1);
+      else glIndexi(i);
+    } else {
+      glIndexi(i ? i : fltk3::GRAY_RAMP);
+    }
+    return;
+  }
+#else
+  if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return;}
+#endif
+#endif
+  uchar red, green, blue;
+  fltk3::get_color(i, red, green, blue);
+  glColor3ub(red, green, blue);
+}
+
+void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
+  if (!ld) ld = w*d;
+  glPixelStorei(GL_UNPACK_ROW_LENGTH, ld/d);
+  glRasterPos2i(x,y);
+  glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
+}
+
+#if GL_DRAW_USES_TEXTURES || defined(FLTK3_DOXYGEN)
+
+#include <fltk3gl/glu.h>
+
+// manages a fifo pile of pre-computed string textures
+class gl_texture_fifo {
+  friend void gl_draw_textures(const char *, int);
+private:
+  typedef struct { // information for a pre-computed texture
+    GLuint texName; // its name
+    char *utf8; //its text
+    Fl_Font_Descriptor *fdesc; // its font
+    int width; // its width
+    int height; // its height
+  } data;
+  data *fifo; // array of pile elements
+  int size_; // pile height
+  int current; // the oldest texture to have entered the pile
+  int last; // pile top
+  int textures_generated; // true iff glGenTextures has been called
+  void display_texture(int rank);
+  int compute_texture(const char* str, int n);
+  int already_known(const char *str, int n);
+public:
+  gl_texture_fifo(int max = 100); // 100 = default height of texture pile
+  inline int size(void) {return size_; };
+  ~gl_texture_fifo(void);
+};
+
+gl_texture_fifo::gl_texture_fifo(int max)
+{
+  size_ = max;
+  last = current = -1;
+  textures_generated = 0;
+  fifo = (data*)calloc(size_, sizeof(data));
+}
+
+gl_texture_fifo::~gl_texture_fifo()
+{
+  for (int i = 0; i < size_; i++) {
+    if (fifo[i].utf8) free(fifo[i].utf8);
+    if (textures_generated) glDeleteTextures(1, &fifo[i].texName);
+    }
+  free(fifo);
+}
+
+// displays a pre-computed texture on the GL scene
+void gl_texture_fifo::display_texture(int rank)
+{
+  //setup matrices
+  GLint matrixMode;
+  glGetIntegerv (GL_MATRIX_MODE, &matrixMode);
+  glMatrixMode (GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity ();
+  glMatrixMode (GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity ();
+  float winw = fltk3::Window::current()->w();
+  float winh = fltk3::Window::current()->h();
+  glScalef (2.0f / winw, 2.0f /  winh, 1.0f);
+  glTranslatef (-winw / 2.0f, -winh / 2.0f, 0.0f);
+  //write the texture on screen
+  GLfloat pos[4];
+  glGetFloatv(GL_CURRENT_RASTER_POSITION, pos);
+  CGRect bounds = CGRectMake (pos[0], pos[1] - fltk3::descent(), fifo[rank].width, fifo[rank].height);
+  
+  // GL_COLOR_BUFFER_BIT for glBlendFunc, GL_ENABLE_BIT for glEnable / glDisable
+  glPushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT | GL_COLOR_BUFFER_BIT); 
+  glDisable (GL_DEPTH_TEST); // ensure text is not removed by depth buffer test.
+  glEnable (GL_BLEND); // for text fading
+  glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // ditto
+  glEnable (GL_TEXTURE_RECTANGLE_EXT);	
+  glDisable(GL_LIGHTING);
+  glBindTexture (GL_TEXTURE_RECTANGLE_EXT, fifo[rank].texName);
+  glBegin (GL_QUADS);
+  glTexCoord2f (0.0f, 0.0f); // draw lower left in world coordinates
+  glVertex2f (bounds.origin.x, bounds.origin.y);
+  
+  glTexCoord2f (0.0f, fifo[rank].height); // draw upper left in world coordinates
+  glVertex2f (bounds.origin.x, bounds.origin.y + bounds.size.height);
+  
+  glTexCoord2f (fifo[rank].width, fifo[rank].height); // draw upper right in world coordinates
+  glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height);
+  
+  glTexCoord2f (fifo[rank].width, 0.0f); // draw lower right in world coordinates
+  glVertex2f (bounds.origin.x + bounds.size.width, bounds.origin.y);
+  glEnd ();
+  glPopAttrib();
+  
+  // reset original matrices
+  glPopMatrix(); // GL_MODELVIEW
+  glMatrixMode (GL_PROJECTION);
+  glPopMatrix();
+  glMatrixMode (matrixMode);
+  
+  //set the raster position to end of string
+  pos[0] += fifo[rank].width;
+  GLdouble modelmat[16];
+  glGetDoublev (GL_MODELVIEW_MATRIX, modelmat);
+  GLdouble projmat[16];
+  glGetDoublev (GL_PROJECTION_MATRIX, projmat);
+  GLdouble objX, objY, objZ;
+  GLint viewport[4];
+  glGetIntegerv (GL_VIEWPORT, viewport);
+  gluUnProject(pos[0], pos[1], pos[2], modelmat, projmat, viewport, &objX, &objY, &objZ);
+  glRasterPos2d(objX, objY);
+}
+
+// pre-computes a string texture
+int gl_texture_fifo::compute_texture(const char* str, int n)
+{
+  current = (current + 1) % size_;
+  if (current > last) last = current;
+  //write str to a bitmap just big enough  
+  if ( fifo[current].utf8 ) free(fifo[current].utf8);
+  fifo[current].utf8 = (char *)malloc(n + 1);
+  memcpy(fifo[current].utf8, str, n);
+  fifo[current].utf8[n] = 0;
+  fifo[current].width = 0, fifo[current].height = 0;
+  fltk3::measure(fifo[current].utf8, fifo[current].width, fifo[current].height, 0);
+  CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
+  void *base = calloc(4*fifo[current].width, fifo[current].height);
+  if (base == NULL) return -1;
+  fl_gc = CGBitmapContextCreate(base, fifo[current].width, fifo[current].height, 8, fifo[current].width*4, lut, kCGImageAlphaPremultipliedLast);
+  CGColorSpaceRelease(lut);
+  fltk3::graphics_driver->font_descriptor(gl_fontsize);
+  GLfloat colors[4];
+  glGetFloatv(GL_CURRENT_COLOR, colors);
+  fltk3::color((uchar)(colors[0]*255), (uchar)(colors[1]*255), (uchar)(colors[2]*255));
+  fltk3::draw(str, n, 0, fifo[current].height - fltk3::descent());
+  //put this bitmap in a texture  
+  glPushAttrib(GL_TEXTURE_BIT);
+  glBindTexture (GL_TEXTURE_RECTANGLE_EXT, fifo[current].texName);
+  glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, fifo[current].width, fifo[current].height, 0,  GL_RGBA, GL_UNSIGNED_BYTE, base);
+  glPopAttrib();
+  CGContextRelease(fl_gc);
+  fl_gc = NULL;
+  free(base);
+  fifo[current].fdesc = gl_fontsize;
+  return current;
+}
+
+// returns rank of pre-computed texture for a string if it exists
+int gl_texture_fifo::already_known(const char *str, int n)
+{
+  int rank;
+  for ( rank = 0; rank <= last; rank++) {
+    if ( memcmp(str, fifo[rank].utf8, n) == 0 && fifo[rank].utf8[n] == 0 &&
+      fifo[rank].fdesc == gl_fontsize) return rank;
+  }
+  return -1;
+}
+
+static gl_texture_fifo *gl_fifo = NULL; // points to the texture pile class instance
+
+// draws a utf8 string using pre-computed texture if available
+static void gl_draw_textures(const char* str, int n) 
+{
+  if (! gl_fifo) gl_fifo = new gl_texture_fifo();
+  if (!gl_fifo->textures_generated) {
+    for (int i = 0; i < gl_fifo->size_; i++) glGenTextures (1, &(gl_fifo->fifo[i].texName));
+    gl_fifo->textures_generated = 1;
+  }
+  int rank = gl_fifo->already_known(str, n);
+  if (rank == -1) {
+    rank = gl_fifo->compute_texture(str, n);
+  }
+  gl_fifo->display_texture(rank);
+}
+
+/** \addtogroup group_macosx
+ @{ */
+
+/**
+ \brief Returns the current height of the pile of pre-computed string textures
+ *
+ The default value is 100
+ */
+int gl_texture_pile_height(void)
+{
+  if (! gl_fifo) gl_fifo = new gl_texture_fifo();
+  return gl_fifo->size();
+}
+
+/**
+ \brief Changes the height of the pile of pre-computed string textures
+ *
+ Strings that are often re-displayed can be processed much faster if
+ this pile is set high enough to hold all of them.
+ \param max Height of the texture pile
+ */
+void gl_texture_pile_height(int max)
+{
+  if (gl_fifo) delete gl_fifo;
+  gl_fifo = new gl_texture_fifo(max);
+}
+
+/** @} */
+
+#elif defined(__APPLE__)
+// used only if __ppc__
+int gl_texture_pile_height(void) {return 0;}
+void gl_texture_pile_height(int max) {}
+#endif // GL_DRAW_USES_TEXTURES
+#if defined(__APPLE__)
+void gl_texture_reset()
+{
+#if GL_DRAW_USES_TEXTURES
+  if (gl_fifo) gl_texture_pile_height(gl_texture_pile_height());
+#endif // GL_DRAW_USES_TEXTURES
+}
+#endif // __APPLE__
+
+#endif // HAVE_GL
+
+//
+// End of "$Id: gl_draw.cxx 8991 2011-08-22 15:21:44Z matt $".
+//

Added: branches/branch-3.0/src/fltk3gl/gl_start.cxx
===================================================================
--- branches/branch-3.0/src/fltk3gl/gl_start.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/gl_start.cxx	2011-08-25 22:05:10 UTC (rev 9012)
@@ -0,0 +1,132 @@
+//
+// "$Id: gl_start.cxx 8991 2011-08-22 15:21:44Z matt $"
+//
+// OpenGL context routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// You MUST use gl_visual() to select the default visual before doing
+// show() of any windows.  Mesa will crash if you try to use a visual
+// not returned by glxChooseVisual.
+
+// This does not work with fltk3::DoubleWindow's!  It will try to draw
+// into the front buffer.  Depending on the system this will either
+// crash or do nothing (when pixmaps are being used as back buffer
+// and GL is being done by hardware), work correctly (when GL is done
+// with software, such as Mesa), or draw into the front buffer and
+// be erased when the buffers are swapped (when double buffer hardware
+// is being used)
+
+#include <config.h>
+#if HAVE_GL
+
+#include <fltk3/run.h>
+#include <fltk3/Window.h>
+#include <fltk3/x.h>
+#include <fltk3/draw.h>
+#include "GLChoice.H"
+
+static GLContext context;
+static int clip_state_number=-1;
+static int pw, ph;
+
+#ifdef WIN32
+static fltk3::GLChoice* gl_choice;
+#endif
+
+#ifdef __APPLE__
+static fltk3::GLChoice* gl_choice;
+#endif
+
+fltk3::Region XRectangleRegion(int x, int y, int w, int h); // in fltk3::rect.cxx
+
+/** Creates an OpenGL context */
+void gl_start() {
+  if (!context) {
+#if defined(USE_X11)
+    context = fl_create_gl_context(fl_visual);
+#elif defined(WIN32)
+    if (!gl_choice) fltk3::gl_visual(0);
+    context = fl_create_gl_context(fltk3::Window::current(), gl_choice);
+#elif defined(__APPLE_QUARTZ__)
+    // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+    context = fl_create_gl_context(fltk3::Window::current(), gl_choice);
+#else
+#  error Unsupported platform
+#endif
+  }
+  fl_set_gl_context(fltk3::Window::current(), context);
+#if !defined(WIN32) && !defined(__APPLE__)
+  glXWaitX();
+#endif
+  if (pw != fltk3::Window::current()->w() || ph != fltk3::Window::current()->h()) {
+    pw = fltk3::Window::current()->w();
+    ph = fltk3::Window::current()->h();
+    glLoadIdentity();
+    glViewport(0, 0, pw, ph);
+    glOrtho(0, pw, 0, ph, -1, 1);
+    glDrawBuffer(GL_FRONT);
+  }
+  if (clip_state_number != fltk3::graphics_driver->fl_clip_state_number) {
+    clip_state_number = fltk3::graphics_driver->fl_clip_state_number;
+    int x, y, w, h;
+    if (fltk3::clip_box(0, 0, fltk3::Window::current()->w(), fltk3::Window::current()->h(),
+		    x, y, w, h)) {
+      fltk3::clip_region(XRectangleRegion(x,y,w,h));
+      glScissor(x, fltk3::Window::current()->h()-(y+h), w, h);
+      glEnable(GL_SCISSOR_TEST);
+    } else {
+      glDisable(GL_SCISSOR_TEST);
+    }
+  }
+}
+
+/** Releases an OpenGL context */
+void gl_finish() {
+  glFlush();
+#if !defined(WIN32) && !defined(__APPLE__)
+  glXWaitGL();
+#endif
+}
+
+int fltk3::gl_visual(int mode, int *alist) {
+  fltk3::GLChoice *c = fltk3::GLChoice::find(mode,alist);
+  if (!c) return 0;
+#if defined(USE_X11)
+  fl_visual = c->vis;
+  fl_colormap = c->colormap;
+#elif defined(WIN32)
+  gl_choice = c;
+#elif defined(__APPLE_QUARTZ__)
+  // warning: the Quartz version should probably use Core GL (CGL) instead of AGL
+  gl_choice = c;
+#else
+#  error Unsupported platform
+#endif
+  return 1;
+}
+#endif
+
+//
+// End of "$Id: gl_start.cxx 8991 2011-08-22 15:21:44Z matt $".
+//

Added: branches/branch-3.0/src/fltk3gl/glut_compatability.cxx
===================================================================
--- branches/branch-3.0/src/fltk3gl/glut_compatability.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/glut_compatability.cxx	2011-08-25 22:05:10 UTC (rev 9012)
@@ -0,0 +1,526 @@
+//
+// "$Id: glut_compatability.cxx 8991 2011-08-22 15:21:44Z matt $"
+//
+// GLUT emulation routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+
+// Emulation of Glut using fltk.
+
+// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996.
+// "This program is freely distributable without licensing fees  and is
+// provided without guarantee or warrantee expressed or  implied. This
+// program is -not- in the public domain."
+
+// Although I have copied the GLUT API, none of my code is based on
+// any Glut implementation details and is therefore covered by the LGPL.
+
+#include "../fltk3/flstring.h"
+#if HAVE_GL
+
+#  include <fltk3gl/glut.h>
+#  ifdef HAVE_GLXGETPROCADDRESSARB
+#    define GLX_GLXEXT_LEGACY
+#    include <GL/glx.h>
+#  endif // HAVE_GLXGETPROCADDRESSARB
+#  ifdef HAVE_DLFCN_H
+#    include <dlfcn.h>
+#  endif // HAVE_DLFCN_H
+#  define MAXWINDOWS 32
+#include <fltk3/Wrapper.h>
+
+static fltk3::GlutWindow *windows[MAXWINDOWS+1];
+
+static void (*glut_idle_func)() = 0; // global glut idle function
+
+fltk3::GlutWindow *glut_window;
+int glut_menu;
+void (*glut_menustate_function)(int);
+void (*glut_menustatus_function)(int,int,int);
+
+static void default_reshape(int w, int h) {glViewport(0,0,w,h);}
+static void default_display() {}
+
+void fltk3::GlutWindow::make_current() {
+  glut_window = this;
+  if (shown()) GLWindow::make_current();
+}
+
+static int indraw;
+void fltk3::GlutWindow::draw() {
+  FLTK3_OBJECT_VCALLS_WRAPPER(draw(), Draw)
+  glut_window = this;
+  indraw = 1;
+  if (!valid()) {reshape(w(),h()); valid(1);}
+  display();
+  indraw = 0;
+}
+
+void glutSwapBuffers() {
+  if (!indraw) glut_window->swap_buffers();
+}
+
+void fltk3::GlutWindow::draw_overlay() {
+  glut_window = this;
+  if (!valid()) {reshape(w(),h()); valid(1);}
+  overlaydisplay();
+}
+
+static void domenu(int, int, int);
+
+int fltk3::GlutWindow::handle(int event) {
+  FLTK3_OBJECT_VCALLS_WRAPPER_RET(int, handle(event), Handle)
+  make_current();
+  int ex = fltk3::event_x();
+  int ey = fltk3::event_y();
+  int button;
+  switch (event) {
+
+  case fltk3::PUSH:
+    if (keyboard || special) fltk3::focus(this);
+    button = fltk3::event_button()-1;
+    if (button<0) button = 0;
+    if (button>2) button = 2;
+    if (menu[button]) {domenu(menu[button],ex,ey); return 1;}
+    mouse_down |= 1<<button;
+    if (mouse) {mouse(button,GLUT_DOWN,ex,ey); return 1;}
+    if (motion) return 1;
+    break;
+
+  case fltk3::MOUSEWHEEL:
+    button = fltk3::event_dy();
+    while (button < 0) {if (mouse) mouse(3,GLUT_DOWN,ex,ey); ++button;}
+    while (button > 0) {if (mouse) mouse(4,GLUT_DOWN,ex,ey); --button;}
+    return 1;
+
+  case fltk3::RELEASE:
+    for (button = 0; button < 3; button++) if (mouse_down & (1<<button)) {
+      if (mouse) mouse(button,GLUT_UP,ex,ey);
+    }
+    mouse_down = 0;
+    return 1;
+
+  case fltk3::ENTER:
+    if (entry) {entry(GLUT_ENTERED); return 1;}
+    if (passivemotion) return 1;
+    break;
+
+  case fltk3::LEAVE:
+    if (entry) {entry(GLUT_LEFT); return 1;}
+    if (passivemotion) return 1;
+    break;
+
+  case fltk3::DRAG:
+    if (motion) {motion(ex, ey); return 1;}
+    break;
+
+  case fltk3::MOVE:
+    if (passivemotion) {passivemotion(ex, ey); return 1;}
+    break;
+
+  case fltk3::FOCUS:
+    if (keyboard || special) return 1;
+    break;
+
+  case fltk3::SHORTCUT:
+    if (!keyboard && !special) break;
+
+  case fltk3::KEYBOARD:
+    if (fltk3::event_text()[0]) {
+      if (keyboard) {keyboard(fltk3::event_text()[0],ex,ey); return 1;}
+      break;
+    } else {
+      if (special) {
+	unsigned k = fltk3::event_key();
+	if (k > fltk3::FKey && k <= fltk3::FLastKey) k -= fltk3::FKey;
+	special(k,ex,ey);
+	return 1;
+      }
+      break;
+    }
+
+  case fltk3::HIDE:
+    if (visibility) visibility(GLUT_NOT_VISIBLE);
+    break;
+
+  case fltk3::SHOW:
+    if (visibility) visibility(GLUT_VISIBLE);
+    break;
+  }
+
+  return GLWindow::handle(event);
+}
+
+static int glut_mode = GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
+
+void fltk3::GlutWindow::_init() {
+  for (number=1; number<MAXWINDOWS; number++) if (!windows[number]) break;
+  windows[number] = this;
+  menu[0] = menu[1] = menu[2] = 0;
+  reshape = default_reshape;
+  display = default_display;
+  overlaydisplay = default_display;
+  keyboard = 0;
+  mouse = 0;
+  motion = 0;
+  passivemotion = 0;
+  entry = 0;
+  visibility = 0;
+  special = 0;
+  mouse_down = 0;
+  mode(glut_mode);
+}
+
+/** Creates a glut window, registers to the glut windows list.*/
+fltk3::GlutWindow::GlutWindow(int W, int H, const char *t) :
+  fltk3::GLWindow(W,H,t) {_init();}
+
+/** Creates a glut window, registers to the glut windows list.*/
+fltk3::GlutWindow::GlutWindow(int X,int Y,int W,int H, const char *t) :
+  fltk3::GLWindow(X,Y,W,H,t) {_init();}
+
+static int initargc;
+static char **initargv;
+
+void glutInit(int *argc, char **argv) {
+  initargc = *argc;
+  initargv = new char*[*argc+1];
+  int i,j;
+  for (i=0; i<=*argc; i++) initargv[i] = argv[i];
+  for (i=j=1; i<*argc; ) {
+    if (fltk3::arg(*argc,argv,i));
+    else argv[j++] = argv[i++];
+  }
+  argv[j] = 0;
+  *argc = j;
+}
+
+void glutInitDisplayMode(unsigned int mode) {
+  glut_mode = mode;
+}
+
+void glutMainLoop() {fltk3::run();}
+
+////////////////////////////////////////////////////////////////
+
+static int initx=0, inity=0, initw=300, inith=300, initpos=0;
+
+void glutInitWindowPosition(int x, int y) {
+  initx = x; inity = y; initpos = 1;
+}
+
+void glutInitWindowSize(int w, int h) {
+  initw = w; inith = h;
+}
+
+int glutCreateWindow(char *title) {
+  return glutCreateWindow((const char*)title);
+}
+
+int glutCreateWindow(const char *title) {
+  fltk3::GlutWindow *W;
+  if (initpos) {
+    W = new fltk3::GlutWindow(initx,inity,initw,inith,title);
+    initpos = 0;
+  } else {
+    W = new fltk3::GlutWindow(initw,inith,title);
+  }
+  W->resizable(W);
+  if (initargc) {
+    W->show(initargc,initargv);
+    initargc = 0;
+  } else {
+    W->show();
+  }
+  W->valid(0);
+  W->context_valid(0);
+  W->make_current();
+  return W->number;
+}
+
+int glutCreateSubWindow(int win, int x, int y, int w, int h) {
+  fltk3::GlutWindow *W = new fltk3::GlutWindow(x,y,w,h,0);
+  windows[win]->add(W);
+  if (windows[win]->shown()) W->show();
+  W->make_current();
+  return W->number;
+}
+/** Destroys the glut window, first unregister it from the glut windows list */
+fltk3::GlutWindow::~GlutWindow() {
+  if (glut_window == this) glut_window = 0;
+  windows[number] = 0;
+}
+
+void glutDestroyWindow(int win) {
+  // should destroy children!!!
+  delete windows[win];
+}
+
+void glutPostWindowRedisplay(int win) {
+  windows[win]->redraw();
+}
+
+void glutSetWindow(int win) {
+  windows[win]->make_current();
+}
+
+////////////////////////////////////////////////////////////////
+#include <fltk3/MenuItem.h>
+
+struct menu {
+  void (*cb)(int);
+  fltk3::MenuItem *m;
+  int size;
+  int alloc;
+};
+
+#define MAXMENUS 32
+static menu menus[MAXMENUS+1];
+
+static void domenu(int n, int ex, int ey) {
+  glut_menu = n;
+  menu *m = &menus[n];
+  if (glut_menustate_function) glut_menustate_function(1);
+  if (glut_menustatus_function) glut_menustatus_function(1,ex,ey);
+  const fltk3::MenuItem* g = m->m->popup(fltk3::event_x(), fltk3::event_y(), 0);
+  if (g && g->callback_) ((void (*)(int))(g->callback_))(int(g->argument()));
+  if (glut_menustatus_function) glut_menustatus_function(0,ex,ey);
+  if (glut_menustate_function) glut_menustate_function(0);
+}
+
+int glutCreateMenu(void (*cb)(int)) {
+  int i;
+  for (i=1; i<MAXMENUS; i++) if (!menus[i].cb) break;
+  menu *m = &menus[i];
+  m->cb = cb;
+  return glut_menu = i;
+}
+
+void glutDestroyMenu(int n) {
+  menu *m = &menus[n];
+  delete[] m->m;
+  m->m = 0;
+  m->cb = 0;
+  m->size = m->alloc = 0;
+}
+
+static fltk3::MenuItem* additem(menu *m) {
+  if (m->size+1 >= m->alloc) {
+    m->alloc = m->size*2+10;
+    fltk3::MenuItem* nm = new fltk3::MenuItem[m->alloc];
+    for (int i=0; i<m->size; i++) nm[i] = m->m[i];
+    delete[] m->m;
+    m->m = nm;
+  }
+  int n = m->size++;
+  m->m[n+1].text = 0;
+  fltk3::MenuItem* i = &(m->m[n]);
+  i->shortcut_ = 0;
+  i->flags = 0;
+  i->labeltype_ = i->labelfont_ = i->labelsize_ = i->labelcolor_ = 0;
+  return i;
+}
+
+void glutAddMenuEntry(char *label, int value) {
+  menu *m = &menus[glut_menu];
+  fltk3::MenuItem* i = additem(m);
+  i->text = label;
+  i->callback_ = (fltk3::Callback*)(m->cb);
+  i->user_data_ = (void *)value;
+}
+
+void glutAddSubMenu(char *label, int submenu) {
+  menu *m = &menus[glut_menu];
+  fltk3::MenuItem* i = additem(m);
+  i->text = label;
+  i->callback_ = 0;
+  i->user_data_ = (void *)(menus[submenu].m);
+  i->flags = fltk3::SUBMENU;
+}
+
+void glutChangeToMenuEntry(int item, char *label, int value) {
+  menu *m = &menus[glut_menu];
+  fltk3::MenuItem* i = &m->m[item-1];
+  i->text = label;
+  i->callback_ = (fltk3::Callback*)(m->cb);
+  i->user_data_ = (void *)value;
+  i->flags = 0;
+}
+
+void glutChangeToSubMenu(int item, char *label, int submenu) {
+  menu *m = &menus[glut_menu];
+  fltk3::MenuItem* i = &m->m[item-1];
+  i->text = label;
+  i->callback_ = 0;
+  i->user_data_ = (void *)(menus[submenu].m);
+  i->flags = fltk3::SUBMENU;
+}
+
+void glutRemoveMenuItem(int item) {
+  menu *m = &menus[glut_menu];
+  if (item > m->size || item < 1) return;
+  for (int i = item-1; i <= m->size; i++) m->m[i] = m->m[i+1];
+  m->size--;
+}
+
+////////////////////////////////////////////////////////////////
+
+int glutGet(GLenum type) {
+  switch (type) {
+  case GLUT_RETURN_ZERO: return 0;
+  case GLUT_WINDOW_X: return glut_window->x();
+  case GLUT_WINDOW_Y: return glut_window->y();
+  case GLUT_WINDOW_WIDTH: return glut_window->w();
+  case GLUT_WINDOW_HEIGHT: return glut_window->h();
+  case GLUT_WINDOW_PARENT:
+    if (glut_window->parent())
+      return ((fltk3::GlutWindow *)(glut_window->parent()))->number;
+    else
+      return 0;
+//case GLUT_WINDOW_NUM_CHILDREN:
+//case GLUT_WINDOW_CURSOR: return 
+  case GLUT_SCREEN_WIDTH: return fltk3::w();
+  case GLUT_SCREEN_HEIGHT: return fltk3::h();
+//case GLUT_SCREEN_WIDTH_MM:
+//case GLUT_SCREEN_HEIGHT_MM:
+  case GLUT_MENU_NUM_ITEMS: return menus[glut_menu].size;
+  case GLUT_DISPLAY_MODE_POSSIBLE: return fltk3::GLWindow::can_do(glut_mode);
+  case GLUT_INIT_WINDOW_X: return initx;
+  case GLUT_INIT_WINDOW_Y: return inity;
+  case GLUT_INIT_WINDOW_WIDTH: return initw;
+  case GLUT_INIT_WINDOW_HEIGHT: return inith;
+  case GLUT_INIT_DISPLAY_MODE: return glut_mode;
+//case GLUT_ELAPSED_TIME:
+  case GLUT_WINDOW_BUFFER_SIZE:
+    if (glutGet(GLUT_WINDOW_RGBA))
+      return glutGet(GLUT_WINDOW_RED_SIZE)+
+	glutGet(GLUT_WINDOW_GREEN_SIZE)+
+	glutGet(GLUT_WINDOW_BLUE_SIZE)+
+	glutGet(GLUT_WINDOW_ALPHA_SIZE);
+    else
+      return glutGet(GLUT_WINDOW_COLORMAP_SIZE);
+  case GLUT_VERSION: return 20400;
+  default: {GLint p; glGetIntegerv(type, &p); return p;}
+  }
+}
+
+int glutLayerGet(GLenum type) {
+  switch (type) {
+  case GLUT_OVERLAY_POSSIBLE: return glut_window->can_do_overlay();
+//case GLUT_LAYER_IN_USE:
+//case GLUT_HAS_OVERLAY:
+  case GLUT_TRANSPARENT_INDEX: return 0; // true for SGI
+  case GLUT_NORMAL_DAMAGED: return glut_window->damage();
+  case GLUT_OVERLAY_DAMAGED: return 1; // kind of works...
+  default: return 0;
+  }
+}
+
+int glutDeviceGet(GLenum type) {
+  switch (type) {
+    case GLUT_HAS_KEYBOARD : return 1;
+    case GLUT_HAS_MOUSE : return 1;
+    case GLUT_NUM_MOUSE_BUTTONS : return 3;
+    default : return 0;
+  }
+}
+
+// Get extension function address...
+GLUTproc glutGetProcAddress(const char *procName) {
+#  ifdef WIN32
+  return (GLUTproc)wglGetProcAddress((LPCSTR)procName);
+
+#  elif defined(HAVE_DLSYM) && defined(HAVE_DLFCN_H)
+  char symbol[1024];
+
+  snprintf(symbol, sizeof(symbol), "_%s", procName);
+
+#    ifdef RTLD_DEFAULT
+  return (GLUTproc)dlsym(RTLD_DEFAULT, symbol);
+
+#    else // No RTLD_DEFAULT support, so open the current a.out symbols...
+  static void *rtld_default = 0;
+
+  if (!rtld_default) rtld_default = dlopen(0, RTLD_LAZY);
+
+  if (rtld_default) return (GLUTproc)dlsym(rtld_default, symbol);
+  else return 0;
+
+#    endif // RTLD_DEFAULT
+
+#  elif defined(HAVE_GLXGETPROCADDRESSARB)
+  return (GLUTproc)glXGetProcAddressARB((const GLubyte *)procName);
+
+#  else
+  return (GLUTproc)0;
+#  endif // WIN32
+}
+
+// Parse the GL_EXTENSIONS string to see if the named extension is
+// supported.
+//
+// This code was copied from FreeGLUT 2.4.0 which carries the
+// following notice:
+//
+//     Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+int glutExtensionSupported( const char* extension )
+{
+  if (!extension || strchr(extension, ' ')) return 0;
+
+  const char *extensions, *start;
+  const int len = strlen( extension );
+  
+  start = extensions = (const char *) glGetString(GL_EXTENSIONS);
+
+  if (!extensions) return 0;
+
+  for (;;) {
+    const char *p = strstr(extensions, extension);
+    if (!p) return 0;  /* not found */
+    /* check that the match isn't a super string */
+    if ((p == start || p[-1] == ' ') &&
+        (p[len] == ' ' || p[len] == 0)) return 1;
+    /* skip the false match and continue */
+    extensions = p + len;
+  }
+}
+
+// Add a mechanism to handle adding/removing the glut idle function
+// without depending on the (deprecated) set_idle method.
+void glutIdleFunc(void (*f)())
+{
+  // no change
+  if(glut_idle_func == f) return;
+  // remove current idle
+  if(glut_idle_func) fltk3::remove_idle((void (*)(void *))glut_idle_func);
+  // install new idle func - if one was passed
+  if(f) fltk3::add_idle((void (*)(void *))f);
+  // record new idle func - even if it is NULL
+  glut_idle_func = f;
+} // glutIdleFunc
+
+#endif // HAVE_GL
+
+//
+// End of "$Id: glut_compatability.cxx 8991 2011-08-22 15:21:44Z matt $".
+//

Added: branches/branch-3.0/src/fltk3gl/glut_font.cxx
===================================================================
--- branches/branch-3.0/src/fltk3gl/glut_font.cxx	                        (rev 0)
+++ branches/branch-3.0/src/fltk3gl/glut_font.cxx	2011-08-25 22:05:10 UTC (rev 9012)
@@ -0,0 +1,198 @@
+//
+// "$Id: glut_font.cxx 8991 2011-08-22 15:21:44Z matt $"
+//
+// GLUT font routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems on the following page:
+//
+//     http://www.fltk.org/str.php
+//
+// The stroked text code was copied from FreeGLUT 2.4.0 which carries
+// the following notice:
+//
+//     Copyright (c) 1999-2000 Pawel W. Olszta. All Rights Reserved.
+//
+
+// (sort of) emulation of Glut's bitmap drawing functions, using fltk3's
+// font stuff.  Not all the fonts match!
+
+#include <config.h>
+#if HAVE_GL
+#  include <fltk3gl/glut.h>
+
+Fl_Glut_Bitmap_Font glutBitmap9By15 = {fltk3::SCREEN, 15};
+Fl_Glut_Bitmap_Font glutBitmap8By13 = {fltk3::SCREEN, 13};
+Fl_Glut_Bitmap_Font glutBitmapTimesRoman10 = {fltk3::TIMES, 10};
+Fl_Glut_Bitmap_Font glutBitmapTimesRoman24 = {fltk3::TIMES, 24};
+Fl_Glut_Bitmap_Font glutBitmapHelvetica10 = {fltk3::HELVETICA, 10};
+Fl_Glut_Bitmap_Font glutBitmapHelvetica12 = {fltk3::HELVETICA, 12};
+Fl_Glut_Bitmap_Font glutBitmapHelvetica18 = {fltk3::HELVETICA, 18};
+
+void glutBitmapCharacter(void* font, int character) {
+  gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size);
+  char a[1]; a[0] = character;
+  gl_draw(a,1);
+}
+
+int glutBitmapHeight(void* font) {
+  gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size);
+  return gl_height();
+}
+
+int glutBitmapLength(void *font, const unsigned char *string) {
+  gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size);
+  const char *s = (const char*)string;
+  return int(gl_width(s)+.5);
+}
+
+void glutBitmapString(void *font, const unsigned char *string) {
+  gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size);
+  const char *s = (const char*)string;
+  gl_draw(s);
+}
+
+int glutBitmapWidth(void* font, int character) {
+  gl_font(((Fl_Glut_Bitmap_Font *)font)->font,((Fl_Glut_Bitmap_Font *)font)->size);
+  return int(gl_width(character)+.5);
+}
+
+
+/*
+ * Draw a stroke character
+ */
+void glutStrokeCharacter(void* fontID, int character) {
+  const Fl_Glut_StrokeChar *schar;
+  const Fl_Glut_StrokeStrip *strip;
+  int i, j;
+  Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID;
+
+  if (character < 0 || character >= font->Quantity) return;
+
+  schar = font->Characters[character];
+  if (!schar) return;
+
+  strip = schar->Strips;
+  
+  for (i = 0; i < schar->Number; i++, strip++)
+  {
+    glBegin(GL_LINE_STRIP);
+    for (j = 0; j < strip->Number; j++)
+      glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y);
+    glEnd();
+  }
+
+  glTranslatef(schar->Right, 0.0, 0.0);
+}
+
+void glutStrokeString(void* fontID, const unsigned char *string) {
+  unsigned char c;
+  int i, j;
+  float length = 0.0;
+  Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID;
+
+  if (!string || ! *string) return;
+  
+ /*
+  * Step through the string, drawing each character.
+  * A newline will simply translate the next character's insertion
+  * point back to the start of the line and down one line.
+  */
+  while ((c = *string++) != 0) {
+    if (c < font->Quantity) {
+      if (c == '\n') {
+	glTranslatef(-length, -(float)(font->Height), 0.0);
+	length = 0.0;
+      } else  {
+        /* Not an EOL, draw the bitmap character */
+	const Fl_Glut_StrokeChar *schar = font->Characters[c];
+	if (schar) {
+	  const Fl_Glut_StrokeStrip *strip = schar->Strips;
+
+	  for (i = 0; i < schar->Number; i++, strip++) {
+	    glBegin(GL_LINE_STRIP);
+	    for (j = 0; j < strip->Number; j++)
+	      glVertex2f(strip->Vertices[j].X, strip->Vertices[j].Y);
+	    glEnd();
+	  }
+
+	  length += schar->Right;
+	  glTranslatef(schar->Right, 0.0, 0.0);
+	}
+      }
+    }
+  }
+}
+
+/*
+ * Return the width in pixels of a stroke character
+ */
+int glutStrokeWidth( void* fontID, int character )
+{
+  const Fl_Glut_StrokeChar *schar;
+  Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID;
+  if (character < 0 || character >= font->Quantity) return 0;
+  schar = font->Characters[ character ];
+
+  return schar ? (int)(schar->Right + 0.5) : 0;
+}
+
+/*
+ * Return the width of a string drawn using a stroke font
+ */
+int glutStrokeLength(void* fontID, const unsigned char* string) {
+  unsigned char c;
+  float length = 0.0;
+  float this_line_length = 0.0;
+  Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID;
+
+  if (!string || ! *string) return 0;
+
+  while ((c = *string++) != 0) {
+    if (c < font->Quantity) {
+      if (c == '\n') {
+        /* EOL; reset the length of this line */
+	if (length < this_line_length) length = this_line_length;
+	this_line_length = 0.0;
+      } else {
+        /* Not an EOL, increment the length of this line */
+	const Fl_Glut_StrokeChar *schar = font->Characters[c];
+	if (schar) this_line_length += schar->Right;
+      }
+    }
+  }
+
+  if (length < this_line_length) length = this_line_length;
+
+  return (int)(length + 0.5);
+}
+
+/*
+ * Returns the height of a stroke font
+ */
+GLfloat glutStrokeHeight(void* fontID) {
+  Fl_Glut_StrokeFont* font = (Fl_Glut_StrokeFont *)fontID;
+  return font->Height;
+}
+
+#endif // HAVE_GL
+
+//
+// End of "$Id: glut_font.cxx 8991 2011-08-22 15:21:44Z matt $".
+//

Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2025 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.