|
From: <ai...@us...> - 2009-08-15 04:03:20
|
Revision: 10259
http://plplot.svn.sourceforge.net/plplot/?rev=10259&view=rev
Author: airwin
Date: 2009-08-15 04:03:15 +0000 (Sat, 15 Aug 2009)
Log Message:
-----------
This driver does not implement pattern fills. Therefore,
correct setting of pls->dev_fill1 to be consistent with that.
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2009-08-15 03:59:46 UTC (rev 10258)
+++ trunk/drivers/pdf.c 2009-08-15 04:03:15 UTC (rev 10259)
@@ -216,7 +216,7 @@
pls->page = 0;
pls->dev_fill0 = 1; /* supports hardware solid fills */
- pls->dev_fill1 = 1;
+ pls->dev_fill1 = 0; /* Use PLplot core fallback for pattern fills */
pls->graphx = GRAPHICS_MODE;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ai...@us...> - 2010-04-27 21:53:15
|
Revision: 10939
http://plplot.svn.sourceforge.net/plplot/?rev=10939&view=rev
Author: airwin
Date: 2010-04-27 21:53:09 +0000 (Tue, 27 Apr 2010)
Log Message:
-----------
If standard font lookup fails for this Type 1 font device, then as "last
chance" switch to Type 1 symbol font and try again. But if that "last
chance" lookup also fails, then accept a blank result and move on.
This fix appears to give good results for examples 3, 6, 7, and 23. For the
examples 6 and 7 tests where hrshsym has an effect, I used -drvopt hrshsym=0
(which avoids Hershey fonts for plpoin and plsym). I also used the
-DHERSHEY_FALLBACK=OFF cmake option which replaces Hershey glyphs that do
not have a recognized unicode equivalent with a blank. Thus, in all cases
Type 1 fonts were used for these tests rather than Hershey fonts.
ToDo. Equivalent changes for the other Type1 font device driver (i.e.,
the ps device driver).
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2010-04-27 21:39:41 UTC (rev 10938)
+++ trunk/drivers/pdf.c 2010-04-27 21:53:09 UTC (rev 10939)
@@ -85,7 +85,7 @@
/* font variables */
HPDF_Font m_font;
- int nlookup;
+ int nlookup, if_symbol_font;
const Unicode_to_Type1_table *lookup;
HPDF_REAL fontSize;
HPDF_REAL fontScale;
@@ -504,16 +504,16 @@
/* jlo is invalid or it is valid and index > lookup[jlo].Unicode.
* jhi is invalid or it is valid and index < lookup[jhi].Unicode.
* All these conditions together imply index cannot be found in lookup.
- * Mark with 32 (which is normally a blank in type 1 fonts).
+ * Mark with ' ' (which is normally the index for blank in type 1 fonts).
*/
- return ( 32 );
+ return ( ' ' );
}
/***********************************************************************
* PSDrawTextToCanvas( pdfdev* dev, unsigned char* type1_string, short drawText )
*
- * This function determines the extend of the string and does
+ * This function determines the extent of the string and does
* the actual drawing to the page if drawText is true.
***********************************************************************/
void PSDrawTextToCanvas( pdfdev* dev, unsigned char* type1_string, short drawText )
@@ -550,30 +550,36 @@
{
char *font;
- /* convert the fci to Base14/Type1 font information */
- font = plP_FCI2FontName( fci, Type1Lookup, N_Type1Lookup );
+ // fci = 0 is a special value indicating the Type 1 Symbol font
+ // is desired. This value cannot be confused with a normal FCI value
+ // because it doesn't have the PL_FCI_MARK.
+ if ( fci == 0)
+ {
+ font = "Symbol";
+ dev->nlookup = number_of_entries_in_unicode_to_symbol_table;
+ dev->lookup = unicode_to_symbol_lookup_table;
+ dev->if_symbol_font = 1;
+ }
+ else
+ {
+ /* convert the fci to Base14/Type1 font information */
+ font = plP_FCI2FontName( fci, Type1Lookup, N_Type1Lookup );
+ dev->nlookup = number_of_entries_in_unicode_to_standard_table;
+ dev->lookup = unicode_to_standard_lookup_table;
+ dev->if_symbol_font = 0;
+ }
if ( !( dev->m_font = HPDF_GetFont( dev->pdf, font, NULL ) ) )
plexit( "ERROR: Couldn't open font\n" );
HPDF_Page_SetFontAndSize( dev->page, dev->m_font, dev->fontSize * dev->fontScale );
- if ( !strcmp( font, "Symbol" ) )
- {
- dev->nlookup = number_of_entries_in_unicode_to_symbol_table;
- dev->lookup = unicode_to_symbol_lookup_table;
- }
- else
- {
- dev->nlookup = number_of_entries_in_unicode_to_standard_table;
- dev->lookup = unicode_to_standard_lookup_table;
- }
}
/***********************************************************************
* PSDrawText( pdfdev* dev, PLUNICODE* ucs4, int ucs4Len, short drawText )
*
- * This function is called twice, first to determine the extend of the
+ * This function is called twice, first to determine the extent of the
* text written to the page and then a second time to actually draw
* the text.
***********************************************************************/
@@ -583,13 +589,14 @@
unsigned char type1_string[MAX_STRING_LEN];
char plplotEsc;
PLUNICODE fci;
+ int last_chance = 0;
memset( type1_string, '\0', MAX_STRING_LEN );
/* Get PLplot escape character */
plgesc( &plplotEsc );
- /* Get the curent font */
+ /* Get the current font */
dev->fontScale = 1.0;
dev->yOffset = 0.0;
plgfci( &fci );
@@ -604,16 +611,108 @@
{
if ( ucs4[i] != (PLUNICODE) plplotEsc ) /* a character to display */
{
- type1_string[s++] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
- i++;
- continue;
+ type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
+ if(ucs4[i] != ' ' && type1_string[s] == ' ')
+ {
+ // failed lookup
+ if(! dev->if_symbol_font)
+ {
+ // failed standard font lookup. Try "last chance"
+ // symbol font instead.
+ type1_string[s] = '\0';
+ PSDrawTextToCanvas( dev, type1_string, drawText );
+ s = 0;
+ last_chance = 1;
+ PSSetFont( dev, 0 );
+ continue;
+ }
+ else if(!last_chance)
+ {
+ // failed symbol font lookup that is not right
+ // after a failed standard font lookup (i.e.,
+ // last_change = 0). Try standard fonts lookup instead.
+ type1_string[s] = '\0';
+ PSDrawTextToCanvas( dev, type1_string, drawText );
+ s = 0;
+ last_chance = 0;
+ PSSetFont( dev, fci );
+ continue;
+ }
+ else
+ {
+ // failed "last_chance" symbol font lookup that
+ // has occurred right after a failed standard
+ // fonts lookup. Just accept blank result and
+ // move on using standard fonts.
+ PSDrawTextToCanvas( dev, type1_string, drawText );
+ s = 0;
+ last_chance = 0;
+ PSSetFont( dev, fci );
+ i++;
+ continue;
+ }
+ }
+ else
+ {
+ // font lookup succeeded.
+ s++;
+ i++;
+ last_chance = 0;
+ continue;
+ }
}
i++;
if ( ucs4[i] == (PLUNICODE) plplotEsc ) /* a escape character to display */
{
- type1_string[s++] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
- i++;
- continue;
+ type1_string[s] = plunicode2type1( ucs4[i], dev->lookup, dev->nlookup );
+ if(ucs4[i] != ' ' && type1_string[s] == ' ')
+ {
+ // failed lookup
+ if(! dev->if_symbol_font)
+ {
+ // failed standard font lookup. Try "last chance"
+ // symbol font instead.
+ type1_string[s] = '\0';
+ PSDrawTextToCanvas( dev, type1_string, drawText );
+ s = 0;
+ last_chance = 1;
+ PSSetFont( dev, 0 );
+ continue;
+ }
+ else if(!last_chance)
+ {
+ // failed symbol font lookup that is not right
+ // after a failed standard font lookup (i.e.,
+ // last_change = 0). Try standard fonts lookup instead.
+ type1_string[s] = '\0';
+ PSDrawTextToCanvas( dev, type1_string, drawText );
+ s = 0;
+ last_chance = 0;
+ PSSetFont( dev, fci );
+ continue;
+ }
+ else
+ {
+ // failed "last_chance" symbol font lookup that
+ // has occurred right after a failed standard
+ // fonts lookup. Just accept blank result and
+ // move on using standard fonts.
+ PSDrawTextToCanvas( dev, type1_string, drawText );
+ s = 0;
+ last_chance = 0;
+ PSSetFont( dev, fci );
+ i++;
+ continue;
+ }
+ }
+ else
+ {
+ // font lookup succeeded.
+ s++;
+ i++;
+ last_chance = 0;
+ continue;
+ }
}
else
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ai...@us...> - 2010-07-27 22:24:22
|
Revision: 11110
http://plplot.svn.sourceforge.net/plplot/?rev=11110&view=rev
Author: airwin
Date: 2010-07-27 22:24:16 +0000 (Tue, 27 Jul 2010)
Log Message:
-----------
Get rid of segfault when libhpdf (from the libharu project) produces an
error. Also, get rid of circular plexit call caused by plend calling
more libhpdf functions after an error was detected.
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2010-07-27 22:10:33 UTC (rev 11109)
+++ trunk/drivers/pdf.c 2010-07-27 22:24:16 UTC (rev 11110)
@@ -287,8 +287,13 @@
if ( setjmp( env ) )
{
- HPDF_Free( dev->pdf );
- plexit( "ERROR: ???\n" );
+ // HPDF_Free segfaults after error so skip this nicety.
+ //HPDF_Free( dev->pdf );
+ // can't call plexit because that appears to be circular via
+ // what happens with plend. Therefore, print out an error message
+ // and exit.
+ fprintf( stderr, "ERROR in haru library\n" );
+ exit( 1 );
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ai...@us...> - 2010-07-28 19:21:13
|
Revision: 11111
http://plplot.svn.sourceforge.net/plplot/?rev=11111&view=rev
Author: airwin
Date: 2010-07-28 19:21:04 +0000 (Wed, 28 Jul 2010)
Log Message:
-----------
Change use of DEBUG, pls->debug, pls->verbose, etc., to be consistent
with other device drivers.
Use one (commented out) call to pldebug to help figure out HPDF
requested font size.
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2010-07-27 22:24:16 UTC (rev 11110)
+++ trunk/drivers/pdf.c 2010-07-28 19:21:04 UTC (rev 11111)
@@ -41,8 +41,8 @@
#include "hpdf.h"
/* PLplot header files */
+#define DEBUG
#define NEED_PLDEBUG
-/* #define DEBUG */
#include "plplotP.h"
#include "drivers.h"
#include "plunicode-type1.h"
@@ -206,14 +206,6 @@
pls->width = 1;
pls->bytecnt = 0;
-#ifdef DEBUG
- pls->verbose = 1;
- pls->debug = 1;
-#else
- pls->verbose = 0;
- pls->debug = 0;
-#endif
-
if ( text )
{
pls->dev_text = 1; /* handles text */
@@ -576,6 +568,7 @@
if ( !( dev->m_font = HPDF_GetFont( dev->pdf, font, NULL ) ) )
plexit( "ERROR: Couldn't open font\n" );
+ //pldebug( "PSSetFont", "HPDF requested font size = %f\n", dev->fontSize * dev->fontScale );
HPDF_Page_SetFontAndSize( dev->page, dev->m_font, dev->fontSize * dev->fontScale );
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ai...@us...> - 2011-03-03 20:08:48
|
Revision: 11591
http://plplot.svn.sourceforge.net/plplot/?rev=11591&view=rev
Author: airwin
Date: 2011-03-03 20:08:42 +0000 (Thu, 03 Mar 2011)
Log Message:
-----------
Make the pdf device honour the -eofill option.
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2011-03-03 19:44:22 UTC (rev 11590)
+++ trunk/drivers/pdf.c 2011-03-03 20:08:42 UTC (rev 11591)
@@ -459,9 +459,16 @@
HPDF_Page_LineTo( dev->page, (HPDF_REAL) xa[i], (HPDF_REAL) ya[i] );
if ( fill == 1 )
- HPDF_Page_FillStroke( dev->page );
+ {
+ if ( pls->dev_eofill )
+ HPDF_Page_EofillStroke( dev->page );
+ else
+ HPDF_Page_FillStroke( dev->page );
+ }
else
+ {
HPDF_Page_Stroke( dev->page );
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ai...@us...> - 2011-07-10 17:27:06
|
Revision: 11804
http://plplot.svn.sourceforge.net/plplot/?rev=11804&view=rev
Author: airwin
Date: 2011-07-10 17:27:00 +0000 (Sun, 10 Jul 2011)
Log Message:
-----------
Use plP_script_scale method to replace idiosyncratic method of
determining superscript/subscript font sizes and offsets. The
test_superscript_subscript.py results are much improved by this
change.
However, a vertical offset issue for the pdf device driver that was
evident before this change still continues; superscript offsets shift
the entire string downwards (including all text before when "#u" is
used) while the corresponding result for subscripts (when "#d" is
used) has no such effect. I have looked hard for the origin of this
pdf bug but cannot find the source of it. The superscript and
subscript paths are absolutely identical in the code except for the
numerical calculation of dev->yOffset. So why does the correct offset
from the baseline being calculated in both cases affect the overall
baseline (including the unsuperscripted/unsubscripted _prior_ parts of
the string) in the superscript case but not in the subscript case?
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2011-07-10 17:08:00 UTC (rev 11803)
+++ trunk/drivers/pdf.c 2011-07-10 17:27:00 UTC (rev 11804)
@@ -579,6 +579,13 @@
HPDF_Page_SetFontAndSize( dev->page, dev->m_font, dev->fontSize * dev->fontScale );
}
+// 0.8 should mimic the offset of first superscript/subscript level
+// implemented in plstr (plsym.c) for Hershey fonts. However, when
+// comparing with -dev xwin and -dev xcairo results changing this
+// factor to 0.6 appears to offset the centers of the letters
+// appropriately while 0.8 gives much poorer agreement with the
+// other devices.
+# define RISE_FACTOR 0.6
//--------------------------------------------------------------------------
// PSDrawText( pdfdev* dev, PLUNICODE* ucs4, int ucs4Len, short drawText )
@@ -594,6 +601,8 @@
char plplotEsc;
PLUNICODE fci;
int last_chance = 0;
+ PLFLT old_sscale, sscale, old_soffset, soffset, dup;
+ PLINT level = 0;
memset( type1_string, '\0', MAX_STRING_LEN );
@@ -721,34 +730,38 @@
else
{
if ( ucs4[i] == (PLUNICODE) 'u' ) // Superscript
- { // draw string so far
+ {
+ // draw string so far
PSDrawTextToCanvas( dev, type1_string, drawText );
s = 0;
- // change font scale
- if ( dev->yOffset < 0.0 )
- dev->fontScale *= (HPDF_REAL) 1.25; // Subscript scaling parameter
- else
- dev->fontScale *= (HPDF_REAL) 0.8; // Subscript scaling parameter
+ plP_script_scale( TRUE, &level,
+ &old_sscale, &sscale, &old_soffset, &soffset );
+ // The correction for the difference in magnitude
+ // between the baseline and middle coordinate systems
+ // for superscripts should be
+ // 0.5*(base font size - superscript/subscript font size).
+ dup = 0.5 * ( 1.0 - sscale );
+ dev->fontScale = sscale;
PSSetFont( dev, fci );
-
- dev->yOffset += dev->fontSize * dev->fontScale / (HPDF_REAL) 2.;
+ dev->yOffset = dev->fontSize * ( soffset * RISE_FACTOR + dup );
}
if ( ucs4[i] == (PLUNICODE) 'd' ) // Subscript
{
- HPDF_REAL old_fontScale = dev->fontScale;
// draw string so far
PSDrawTextToCanvas( dev, type1_string, drawText );
s = 0;
- // change font scale
- if ( dev->yOffset > 0.0 )
- dev->fontScale *= (HPDF_REAL) 1.25; // Subscript scaling parameter
- else
- dev->fontScale *= (HPDF_REAL) 0.8; // Subscript scaling parameter
+ plP_script_scale( FALSE, &level,
+ &old_sscale, &sscale, &old_soffset, &soffset );
+ // The correction for the difference in magnitude
+ // between the baseline and middle coordinate systems
+ // for subcripts should be
+ // 0.5*(base font size - superscript/subscript font size).
+ dup = -0.5 * ( 1.0 - sscale );
+ dev->fontScale = sscale;
PSSetFont( dev, fci );
-
- dev->yOffset -= dev->fontSize * old_fontScale / (HPDF_REAL) 2.;
+ dev->yOffset = -dev->fontSize * ( soffset * RISE_FACTOR + dup );
}
if ( ucs4[i] == (PLUNICODE) '-' ) // underline
{ // draw string so far
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <and...@us...> - 2013-12-09 16:48:09
|
Revision: 12833
http://sourceforge.net/p/plplot/code/12833
Author: andrewross
Date: 2013-12-09 16:48:06 +0000 (Mon, 09 Dec 2013)
Log Message:
-----------
Fix another compiler warning.
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2013-12-09 14:39:59 UTC (rev 12832)
+++ trunk/drivers/pdf.c 2013-12-09 16:48:06 UTC (rev 12833)
@@ -552,7 +552,7 @@
//--------------------------------------------------------------------------
void PSSetFont( pdfdev* dev, PLUNICODE fci )
{
- char *font;
+ const char *font;
// fci = 0 is a special value indicating the Type 1 Symbol font
// is desired. This value cannot be confused with a normal FCI value
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <and...@us...> - 2013-12-10 00:14:11
|
Revision: 12837
http://sourceforge.net/p/plplot/code/12837
Author: andrewross
Date: 2013-12-10 00:14:08 +0000 (Tue, 10 Dec 2013)
Log Message:
-----------
Fix up various compiler warnings with pdf driver.
Modified Paths:
--------------
trunk/drivers/pdf.c
Modified: trunk/drivers/pdf.c
===================================================================
--- trunk/drivers/pdf.c 2013-12-09 19:33:53 UTC (rev 12836)
+++ trunk/drivers/pdf.c 2013-12-10 00:14:08 UTC (rev 12837)
@@ -37,12 +37,13 @@
#include <stdarg.h>
#include <math.h>
#include <setjmp.h>
+#include <strings.h>
#include "hpdf.h"
// PLplot header files
-#define DEBUG
-#define NEED_PLDEBUG
+//#define DEBUG
+//#define NEED_PLDEBUG
#include "plplotP.h"
#include "drivers.h"
#include "plunicode-type1.h"
@@ -103,7 +104,7 @@
//--------------------------------------------------------------------------
// General
-static short desired_offset( short, double );
+//static short desired_offset( short, double );
static void poly_line( PLStream *pls, short *xa, short *ya, PLINT npts, short fill );
// String processing
@@ -119,6 +120,10 @@
void plD_tidy_pdf( PLStream * );
void plD_state_pdf( PLStream *, PLINT );
void plD_esc_pdf( PLStream *, PLINT, void * );
+void error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no, void *user_data );
+void PSDrawTextToCanvas( pdfdev* dev, unsigned char* type1_string, short drawText );
+void PSSetFont( pdfdev* dev, PLUNICODE fci );
+void PSDrawText( pdfdev* dev, PLUNICODE* ucs4, int ucs4Len, short drawText );
//--------------------------------------------------------------------------
// error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no,
@@ -131,7 +136,7 @@
#else
void
#endif
-error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no, void *user_data )
+error_handler( HPDF_STATUS error_no, HPDF_STATUS detail_no, void * PL_UNUSED( user_data ) )
{
// invoke longjmp() when an error has occurred
printf( "ERROR: error_no=%04X, detail_no=%d\n", (unsigned int) error_no, (int) detail_no );
@@ -361,7 +366,7 @@
//
// End of page
//--------------------------------------------------------------------------
-void plD_eop_pdf( PLStream *pls )
+void plD_eop_pdf( PLStream * PL_UNUSED( pls ) )
{
// nothing to be done here
}
@@ -387,7 +392,8 @@
{
HPDF_BYTE buf[4096]; // TODO: not good
HPDF_UINT32 size = 4096;
- HPDF_STATUS ret = HPDF_ReadFromStream( dev->pdf, buf, &size );
+ // HPDF_STATUS ret = HPDF_ReadFromStream( dev->pdf, buf, &size );
+ HPDF_ReadFromStream( dev->pdf, buf, &size );
if ( size == 0 )
break;
@@ -411,7 +417,7 @@
// Nothing is done here because these attributes are aquired from
// PLStream for each element that is drawn.
//--------------------------------------------------------------------------
-void plD_state_pdf( PLStream *pls, PLINT op )
+void plD_state_pdf( PLStream * PL_UNUSED( pls ), PLINT PL_UNUSED( op ) )
{
// Nothing to be done here.
}
@@ -537,7 +543,7 @@
// determine text width and height
dev->textWidth += HPDF_Page_TextWidth( dev->page, (char *) type1_string ); // TODO: this conversion must be wrong
- th = (HPDF_REAL) ( HPDF_Font_GetCapHeight( dev->m_font ) * dev->fontSize * dev->fontScale / 1000.0 );
+ th = (HPDF_REAL) ( (HPDF_REAL) HPDF_Font_GetCapHeight( dev->m_font ) * dev->fontSize * dev->fontScale / 1000.0 );
dev->textHeight = dev->textHeight > ( th + dev->yOffset ) ? dev->textHeight : ( th + dev->yOffset );
// clear string
@@ -742,9 +748,9 @@
// for superscripts should be
// 0.5*(base font size - superscript/subscript font size).
dup = 0.5 * ( 1.0 - sscale );
- dev->fontScale = sscale;
+ dev->fontScale = (HPDF_REAL) sscale;
PSSetFont( dev, fci );
- dev->yOffset = dev->fontSize * ( soffset * RISE_FACTOR + dup );
+ dev->yOffset = (HPDF_REAL) (dev->fontSize * ( soffset * RISE_FACTOR + dup ));
}
if ( ucs4[i] == (PLUNICODE) 'd' ) // Subscript
{
@@ -759,9 +765,9 @@
// for subcripts should be
// 0.5*(base font size - superscript/subscript font size).
dup = -0.5 * ( 1.0 - sscale );
- dev->fontScale = sscale;
+ dev->fontScale = (HPDF_REAL) sscale;
PSSetFont( dev, fci );
- dev->yOffset = -dev->fontSize * ( soffset * RISE_FACTOR + dup );
+ dev->yOffset = (HPDF_REAL) ( -dev->fontSize * ( soffset * RISE_FACTOR + dup ) );
}
if ( ucs4[i] == (PLUNICODE) '-' ) // underline
{ // draw string so far
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|