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 Apps      FLTK Library      Forums      Links     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-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.