From: <and...@us...> - 2012-10-10 22:17:17
|
Revision: 12243 http://plplot.svn.sourceforge.net/plplot/?rev=12243&view=rev Author: andrewross Date: 2012-10-10 22:17:10 +0000 (Wed, 10 Oct 2012) Log Message: ----------- Commit on behalf of Phil Rosenberg. Fixes to the wxwidgets driver to properly support newline characters in strings. Modified Paths: -------------- trunk/drivers/wxwidgets.cpp trunk/drivers/wxwidgets.h trunk/drivers/wxwidgets_dc.cpp trunk/drivers/wxwidgets_gc.cpp trunk/src/plfreetype.c Modified: trunk/drivers/wxwidgets.cpp =================================================================== --- trunk/drivers/wxwidgets.cpp 2012-10-05 21:31:41 UTC (rev 12242) +++ trunk/drivers/wxwidgets.cpp 2012-10-10 22:17:10 UTC (rev 12243) @@ -176,6 +176,8 @@ devDesc = (const char **) malloc( NDEV * sizeof ( char** ) ); memset( devDesc, '\0', NDEV * sizeof ( char** ) ); ndev = NDEV; + + lineSpacing = 1.0; } @@ -234,14 +236,11 @@ char plplotEsc; plgesc( &plplotEsc ); - // Get the curent font - fontScale = 1.0; - yOffset = 0.0; - PLUNICODE fci; - plgfci( &fci ); - PSSetFont( fci ); - textWidth = 0; - textHeight = 0; + //Reset the size metrics + textWidth = 0; + textHeight = 0; + superscriptHeight = 0; + subscriptDepth = 0; while ( i < ucs4Len ) { Modified: trunk/drivers/wxwidgets.h =================================================================== --- trunk/drivers/wxwidgets.h 2012-10-05 21:31:41 UTC (rev 12242) +++ trunk/drivers/wxwidgets.h 2012-10-10 22:17:10 UTC (rev 12243) @@ -165,6 +165,10 @@ double fontSize; double fontScale; wxCoord textWidth, textHeight, textDescent, textLeading; + PLUNICODE fci; + //the distance between the superscript top and subscript base from the baseline + wxCoord superscriptHeight, subscriptDepth; + double lineSpacing; double yOffset; PLINT posX, posY; PLFLT rotation, cos_rot, sin_rot; Modified: trunk/drivers/wxwidgets_dc.cpp =================================================================== --- trunk/drivers/wxwidgets_dc.cpp 2012-10-05 21:31:41 UTC (rev 12242) +++ trunk/drivers/wxwidgets_dc.cpp 2012-10-10 22:17:10 UTC (rev 12243) @@ -337,15 +337,65 @@ wxCoord w, h, d, l; wxString str( wxConvUTF8.cMB2WC( utf8_string ), *wxConvCurrent ); + m_dc->GetTextExtent( str, &w, &h, &d, &l ); + if ( drawText ) - m_dc->DrawRotatedText( str, (wxCoord) ( posX / scalex - yOffset / scaley * sin_rot ), - (wxCoord) ( height - ( posY + yOffset * cos_rot ) / scaley ), + { + m_dc->DrawRotatedText( str, (wxCoord) ( posX - yOffset / scaley * sin_rot ), + (wxCoord) ( height - (wxCoord) ( posY + yOffset * cos_rot / scaley ) ), rotation * 180.0 / M_PI ); - posX += (PLINT) ( w * scalex * cos_rot ); - posY += (PLINT) ( w * scaley * sin_rot ); + posX += (PLINT) ( w * cos_rot ); + posY += (PLINT) ( w * sin_rot ); + } + textWidth += w; - textHeight = (wxCoord) ( textHeight > ( h + yOffset / scaley ) ? textHeight : ( h + yOffset / scaley ) ); + + //keep track of the height of superscript text, the depth of subscript + //text and the height of regular text + if ( yOffset > 0.0001 ) + { + //determine the height the text would have if it were full size + double currentOffset = yOffset; + double currentHeight = h; + while ( currentOffset > 0.0001 ) + { + currentOffset -= scaley * fontSize * fontScale / 2.; + currentHeight *= 1.25; + } + textHeight = (wxCoord) textHeight > ( currentHeight ) + ? textHeight + : currentHeight; + //work out the height including superscript + superscriptHeight = superscriptHeight > ( currentHeight + yOffset / scaley ) + ? superscriptHeight + : static_cast<int>( ( currentHeight + yOffset / scaley ) ); + } + else if ( yOffset < -0.0001 ) + { + //determine the height the text would have if it were full size + double currentOffset = yOffset; + double currentHeight = h; + double currentDepth = d; + while ( currentOffset < -0.0001 ) + { + currentOffset += scaley * fontSize * fontScale * 1.25 / 2.; + currentHeight *= 1.25; + currentDepth *= 1.25; + } + textHeight = (wxCoord) textHeight > currentHeight ? textHeight : currentHeight; + //work out the additional depth for subscript note an assumption has been made + //that the font size of (non-superscript and non-subscript) text is the same + //along a line. Currently there is no escape to change font size mid string + //so this should be fine + subscriptDepth = (wxCoord) subscriptDepth > ( ( -yOffset / scaley + h + d ) - ( currentDepth + textHeight ) ) + ? subscriptDepth + : ( ( -yOffset / scaley + h + d ) - ( currentDepth + textHeight ) ); + subscriptDepth = subscriptDepth > 0 ? subscriptDepth : 0; + } + else + textHeight = (wxCoord) textHeight > ( h ) ? textHeight : h; + memset( utf8_string, '\0', max_string_length ); } @@ -422,14 +472,67 @@ m_dc->SetTextForeground( wxColour( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b ) ); m_dc->SetTextBackground( wxColour( pls->curcolor.r, pls->curcolor.g, pls->curcolor.b ) ); - posX = args->x; - posY = args->y; - PSDrawText( args->unicode_array, args->unicode_array_len, false ); + PLUNICODE *lineStart = args->unicode_array; + int lineLen = 0; + bool lineFeed = false; + bool carriageReturn = false; + wxCoord paraHeight = 0; + // Get the curent font + fontScale = 1.0; + yOffset = 0.0; + plgfci( &fci ); + PSSetFont( fci ); + while ( lineStart != args->unicode_array + args->unicode_array_len ) + { + while ( lineStart + lineLen != args->unicode_array + args->unicode_array_len + && *( lineStart + lineLen ) != (PLUNICODE) '\n' ) + { + lineLen++; + } + //set line feed for the beginning of this line and + //carriage return for the end + lineFeed = carriageReturn; + carriageReturn = lineStart + lineLen != args->unicode_array + args->unicode_array_len + && *( lineStart + lineLen ) == (PLUNICODE) ( '\n' ); + if ( lineFeed ) + paraHeight += textHeight + subscriptDepth; - posX = (PLINT) ( args->x - ( ( args->just * textWidth ) * cos_rot + ( 0.5 * textHeight ) * sin_rot ) * scalex ); - posY = (PLINT) ( args->y - ( ( args->just * textWidth ) * sin_rot - ( 0.5 * textHeight ) * cos_rot ) * scaley ); - PSDrawText( args->unicode_array, args->unicode_array_len, true ); + //remember the text parameters so they can be restored + double startingFontScale = fontScale; + double startingYOffset = yOffset; + PLUNICODE startingFci = fci; + // determine extent of text + posX = args->x / scalex; + posY = args->y / scaley; + + PSDrawText( lineStart, lineLen, false ); + + if ( lineFeed && superscriptHeight > textHeight ) + paraHeight += superscriptHeight - textHeight; + + // actually draw text, resetting the font first + fontScale = startingFontScale; + yOffset = startingYOffset; + fci = startingFci; + PSSetFont( fci ); + posX = (PLINT) ( args->x / scalex - ( args->just * textWidth ) * cos_rot - ( 0.5 * textHeight - paraHeight * lineSpacing ) * sin_rot ); //move to set alignment + posY = (PLINT) ( args->y / scaley - ( args->just * textWidth ) * sin_rot + ( 0.5 * textHeight - paraHeight * lineSpacing ) * cos_rot ); + PSDrawText( lineStart, lineLen, true ); //draw text + + lineStart += lineLen; + if ( carriageReturn ) + lineStart++; + lineLen = 0; + } + //posX = args->x; + //posY = args->y; + //PSDrawText( args->unicode_array, args->unicode_array_len, false ); + + //posX = (PLINT) ( args->x - ( ( args->just * textWidth ) * cos_rot + ( 0.5 * textHeight ) * sin_rot ) * scalex ); + //posY = (PLINT) ( args->y - ( ( args->just * textWidth ) * sin_rot - ( 0.5 * textHeight ) * cos_rot ) * scaley ); + //PSDrawText( args->unicode_array, args->unicode_array_len, true ); + AddtoClipRegion( 0, 0, width, height ); } Modified: trunk/drivers/wxwidgets_gc.cpp =================================================================== --- trunk/drivers/wxwidgets_gc.cpp 2012-10-05 21:31:41 UTC (rev 12242) +++ trunk/drivers/wxwidgets_gc.cpp 2012-10-10 22:17:10 UTC (rev 12243) @@ -36,6 +36,9 @@ // std and driver headers #include "wxwidgets.h" +#include <wx/string.h> +#include <string> + // only compile code if wxGraphicsContext available #if wxUSE_GRAPHICS_CONTEXT @@ -370,7 +373,10 @@ wxDouble w, h, d, l; wxString str( wxConvUTF8.cMB2WC( utf8_string ), *wxConvCurrent ); + + w = 0; m_context->GetTextExtent( str, &w, &h, &d, &l ); + if ( drawText ) { m_context->DrawText( str, 0, -yOffset / scaley ); @@ -378,9 +384,52 @@ } textWidth += static_cast<int>( w ); - textHeight = textHeight > ( h + yOffset / scaley ) - ? textHeight - : static_cast<int>( ( h + yOffset / scaley ) ); + + //keep track of the height of superscript text, the depth of subscript + //text and the height of regular text + if ( yOffset > 0.0001 ) + { + //determine the height the text would have if it were full size + double currentOffset = yOffset; + double currentHeight = h; + while ( currentOffset > 0.0001 ) + { + currentOffset -= scaley * fontSize * fontScale / 2.; + currentHeight *= 1.25; + } + textHeight = textHeight > ( currentHeight ) + ? textHeight + : static_cast<int>( ( currentHeight ) ); + //work out the height including superscript + superscriptHeight = superscriptHeight > ( currentHeight + yOffset / scaley ) + ? superscriptHeight + : static_cast<int>( ( currentHeight + yOffset / scaley ) ); + } + else if ( yOffset < -0.0001 ) + { + //determine the height the text would have if it were full size + double currentOffset = yOffset; + double currentHeight = h; + double currentDepth = d; + while ( currentOffset < -0.0001 ) + { + currentOffset += scaley * fontSize * fontScale * 1.25 / 2.; + currentHeight *= 1.25; + currentDepth *= 1.25; + } + textHeight = textHeight > currentHeight ? textHeight : static_cast<int>( ( currentHeight ) ); + //work out the additional depth for subscript note an assumption has been made + //that the font size of (non-superscript and non-subscript) text is the same + //along a line. Currently there is no escape to change font size mid string + //so this should be fine + subscriptDepth = subscriptDepth > ( ( -yOffset / scaley + h + d ) - ( currentDepth + textHeight ) ) + ? subscriptDepth + : static_cast<int>( ( -yOffset / scaley + h + d ) - ( currentDepth + textHeight ) ); + subscriptDepth = subscriptDepth > 0 ? subscriptDepth : 0; + } + else + textHeight = textHeight > h ? textHeight : static_cast<int>( h ); + memset( utf8_string, '\0', max_string_length ); } @@ -416,9 +465,9 @@ } // Check that unicode string isn't longer then the max we allow - if ( args->unicode_array_len >= 500 ) + if ( args->unicode_array_len >= max_string_length ) { - printf( "Sorry, the wxWidgets drivers only handles strings of length < %d\n", 500 ); + printf( "Sorry, the wxWidgets drivers only handles strings of length < %d\n", max_string_length ); return; } @@ -464,22 +513,67 @@ cos_shear = cos( shear ); sin_shear = sin( shear ); - // determine extend of text - PSDrawText( args->unicode_array, args->unicode_array_len, false ); - // actually draw text - m_context->PushState(); - m_context->Translate( args->x / scalex, height - args->y / scaley ); - wxGraphicsMatrix matrix = m_context->CreateMatrix( - cos_rot * stride, -sin_rot * stride, - cos_rot * sin_shear + sin_rot * cos_shear, - -sin_rot * sin_shear + cos_rot * cos_shear, - 0.0, 0.0 ); - m_context->ConcatTransform( matrix ); - m_context->Translate( -args->just * textWidth, -0.5 * textHeight ); - PSDrawText( args->unicode_array, args->unicode_array_len, true ); - m_context->PopState(); + PLUNICODE *lineStart = args->unicode_array; + int lineLen = 0; + bool lineFeed = false; + bool carriageReturn = false; + wxCoord paraHeight = 0; + // Get the curent font + fontScale = 1.0; + yOffset = 0.0; + plgfci( &fci ); + PSSetFont( fci ); + while ( lineStart != args->unicode_array + args->unicode_array_len ) + { + while ( lineStart + lineLen != args->unicode_array + args->unicode_array_len + && *( lineStart + lineLen ) != (PLUNICODE) '\n' ) + { + lineLen++; + } + //set line feed for the beginning of this line and + //carriage return for the end + lineFeed = carriageReturn; + carriageReturn = lineStart + lineLen != args->unicode_array + args->unicode_array_len + && *( lineStart + lineLen ) == (PLUNICODE) ( '\n' ); + if ( lineFeed ) + paraHeight += textHeight + subscriptDepth; + //remember the text parameters so they can be restored + double startingFontScale = fontScale; + double startingYOffset = yOffset; + PLUNICODE startingFci = fci; + + // determine extent of text + PSDrawText( lineStart, lineLen, false ); + + if ( lineFeed && superscriptHeight > textHeight ) + paraHeight += superscriptHeight - textHeight; + + // actually draw text, resetting the font first + fontScale = startingFontScale; + yOffset = startingYOffset; + fci = startingFci; + PSSetFont( fci ); + m_context->PushState(); //save current position + m_context->Translate( args->x / scalex, height - args->y / scaley ); //move to text starting position + wxGraphicsMatrix matrix = m_context->CreateMatrix( + cos_rot * stride, -sin_rot * stride, + cos_rot * sin_shear + sin_rot * cos_shear, + -sin_rot * sin_shear + cos_rot * cos_shear, + 0.0, 0.0 ); //create rotation transformation matrix + m_context->ConcatTransform( matrix ); //rotate + m_context->Translate( -args->just * textWidth, -0.5 * textHeight + paraHeight * lineSpacing ); //move to set alignment + PSDrawText( lineStart, lineLen, true ); //draw text + m_context->PopState(); //return to original position + + lineStart += lineLen; + if ( carriageReturn ) + lineStart++; + lineLen = 0; + } + + AddtoClipRegion( 0, 0, width, height ); m_context->ResetClip(); Modified: trunk/src/plfreetype.c =================================================================== --- trunk/src/plfreetype.c 2012-10-05 21:31:41 UTC (rev 12242) +++ trunk/src/plfreetype.c 2012-10-10 22:17:10 UTC (rev 12243) @@ -148,7 +148,7 @@ // static void FT_WriteStrW( PLStream *pls, const PLUNICODE *text, short len, int x, int y ); -static void FT_StrX_YW( PLStream *pls, const PLUNICODE *text, short len, int *xx, int *yy ); +static void FT_StrX_YW( PLStream *pls, const PLUNICODE *text, short len, int *xx, int *yy, int *overyy, int *underyy ); //-------------------------------------------------------------------------- // FT_StrX_YW() @@ -161,12 +161,12 @@ //-------------------------------------------------------------------------- void -FT_StrX_YW( PLStream *pls, const PLUNICODE *text, short len, int *xx, int *yy ) +FT_StrX_YW( PLStream *pls, const PLUNICODE *text, short len, int *xx, int *yy, int *overyy, int *underyy ) { FT_Data *FT = (FT_Data *) pls->FT; short i = 0; - FT_Vector akerning; - int x = 0, y = 0; + FT_Vector akerning, adjust; + int x = 0, y = 0, startingy; char esc; plgesc( &esc ); @@ -178,7 +178,13 @@ // and this is the best thing I could think of. // - y -= (int) FT->face->size->metrics.height; + y -= (int) FT->face->size->metrics.height; + startingy = y; + *yy = y; //note height is negative! + *overyy = 0; + *underyy = 0; + adjust.x = 0; + adjust.y = 0; // walk through the text character by character for ( i = 0; i < len; i++ ) @@ -191,9 +197,26 @@ switch ( text[i + 1] ) { case 'u': // super script + case 'U': // super script + adjust.y = FT->face->size->metrics.height / 2; + adjust.x = 0; + FT_Vector_Transform( &adjust, &FT->matrix ); + x += (int) adjust.x; + y -= (int) adjust.y; + //calculate excess height from superscripts, this will need changing if scale of sub/superscripts changes + *overyy = y - startingy < *overyy ? y - startingy : *overyy; + i++; + break; + case 'd': // subscript - case 'U': - case 'D': + case 'D': // subscript + adjust.y = -FT->face->size->metrics.height / 2; + adjust.x = 0; + FT_Vector_Transform( &adjust, &FT->matrix ); + x += (int) adjust.x; + y -= (int) adjust.y; + //calculate excess depth from subscripts, this will need changing if scale of sub/superscripts changes + *underyy = startingy - y < *underyy ? startingy - y : *underyy; i++; break; } @@ -202,6 +225,7 @@ { // FCI in text stream; change font accordingly. FT_SetFace( pls, text[i] ); + *yy = FT->face->size->metrics.height > -*yy ? -FT->face->size->metrics.height : *yy; } else { @@ -250,7 +274,6 @@ //yy=y>> 6; //xx=x>> 6; // - *yy = y; *xx = x; } @@ -772,8 +795,11 @@ fclose( infile ); } } - FontLookup[i].fci = TrueTypeLookup[i].fci; - FontLookup[i].pfont = (unsigned char *) FT->font_name[i]; + FontLookup[i].fci = TrueTypeLookup[i].fci; + if ( FT->font_name[i][0] == '\0' ) + FontLookup[i].pfont = NULL; + else + FontLookup[i].pfont = (unsigned char *) FT->font_name[i]; } // // Next, we check to see if -drvopt has been used on the command line to @@ -847,11 +873,14 @@ { FT_Data *FT = (FT_Data *) pls->FT; int x, y; - int w = 0, h = 0; + int w = 0, h = 0, overh = 0, underh = 0; PLFLT *t = args->xform; FT_Matrix matrix; PLFLT angle = PI * pls->diorot / 2; -// + PLUNICODE *line = args->unicode_array; + int linelen; + int prevlineheights = 0; + // Used later in a commented out section (See Rotate The Page), if that // section will never be used again, remove these as well. // PLINT clxmin, clxmax, clymin, clymax; @@ -862,7 +891,7 @@ FT_Fixed height; PLFLT height_factor; - if ( ( args->string != NULL ) || ( args->unicode_array_len > 0 ) ) + if ( ( args->unicode_array_len > 0 ) ) { // // Work out if either the font size, the font face or the @@ -885,6 +914,15 @@ // +// Split the text into lines based on the newline character +// + while ( line < args->unicode_array + args->unicode_array_len ) + { + linelen = 0; + while ( line[linelen] != '\n' && line + linelen < args->unicode_array + args->unicode_array_len ) + ++linelen; + +// // Now we work out how long the text is (for justification etc...) and how // high the text is. This is done on UN-TRANSFORMED text, since we will // apply our own transformations on it later, so it's necessary for us @@ -892,15 +930,15 @@ // that calculates the text size. // - FT->matrix.xx = 0x10000; - FT->matrix.xy = 0x00000; - FT->matrix.yx = 0x00000; - FT->matrix.yy = 0x10000; + FT->matrix.xx = 0x10000; + FT->matrix.xy = 0x00000; + FT->matrix.yx = 0x00000; + FT->matrix.yy = 0x10000; - FT_Vector_Transform( &FT->pos, &FT->matrix ); - FT_Set_Transform( FT->face, &FT->matrix, &FT->pos ); + FT_Vector_Transform( &FT->pos, &FT->matrix ); + FT_Set_Transform( FT->face, &FT->matrix, &FT->pos ); - FT_StrX_YW( pls, args->unicode_array, (short) args->unicode_array_len, &w, &h ); + FT_StrX_YW( pls, line, (short) linelen, &w, &h, &overh, &underh ); // // Set up the transformation Matrix @@ -925,20 +963,20 @@ // always a negative quantity. // - height_factor = (PLFLT) ( FT->face->ascender - FT->face->descender ) - / FT->face->ascender; - height = (FT_Fixed) ( 0x10000 * height_factor ); + height_factor = (PLFLT) ( FT->face->ascender - FT->face->descender ) + / FT->face->ascender; + height = (FT_Fixed) ( 0x10000 * height_factor ); #ifdef DJGPP - FT->matrix.xx = (FT_Fixed) ( (PLFLT) height * t[0] ); - FT->matrix.xy = (FT_Fixed) ( (PLFLT) height * t[2] ); - FT->matrix.yx = (FT_Fixed) ( (PLFLT) height * t[1] ); - FT->matrix.yy = (FT_Fixed) ( (PLFLT) height * t[3] ); + FT->matrix.xx = (FT_Fixed) ( (PLFLT) height * t[0] ); + FT->matrix.xy = (FT_Fixed) ( (PLFLT) height * t[2] ); + FT->matrix.yx = (FT_Fixed) ( (PLFLT) height * t[1] ); + FT->matrix.yy = (FT_Fixed) ( (PLFLT) height * t[3] ); #else - FT->matrix.xx = (FT_Fixed) ( (PLFLT) height * t[0] ); - FT->matrix.xy = (FT_Fixed) ( (PLFLT) height * t[1] ); - FT->matrix.yx = (FT_Fixed) ( (PLFLT) height * t[2] ); - FT->matrix.yy = (FT_Fixed) ( (PLFLT) height * t[3] ); + FT->matrix.xx = (FT_Fixed) ( (PLFLT) height * t[0] ); + FT->matrix.xy = (FT_Fixed) ( (PLFLT) height * t[1] ); + FT->matrix.yx = (FT_Fixed) ( (PLFLT) height * t[2] ); + FT->matrix.yy = (FT_Fixed) ( (PLFLT) height * t[3] ); #endif @@ -949,22 +987,22 @@ // will use freetypes matrix math stuff to do this for us. // - Cos_A = cos( angle ); - Sin_A = sin( angle ); + Cos_A = cos( angle ); + Sin_A = sin( angle ); - matrix.xx = (FT_Fixed) ( (PLFLT) 0x10000 * Cos_A ); + matrix.xx = (FT_Fixed) ( (PLFLT) 0x10000 * Cos_A ); #ifdef DJGPP - matrix.xy = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A * -1.0 ); - matrix.yx = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A ); + matrix.xy = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A * -1.0 ); + matrix.yx = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A ); #else - matrix.xy = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A ); - matrix.yx = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A * -1.0 ); + matrix.xy = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A ); + matrix.yx = (FT_Fixed) ( (PLFLT) 0x10000 * Sin_A * -1.0 ); #endif - matrix.yy = (FT_Fixed) ( (PLFLT) 0x10000 * Cos_A ); + matrix.yy = (FT_Fixed) ( (PLFLT) 0x10000 * Cos_A ); - FT_Matrix_Multiply( &matrix, &FT->matrix ); + FT_Matrix_Multiply( &matrix, &FT->matrix ); // Calculate a Vector from the matrix @@ -976,7 +1014,7 @@ // - FT_Vector_Transform( &FT->pos, &FT->matrix ); + FT_Vector_Transform( &FT->pos, &FT->matrix ); // Transform the font face @@ -988,7 +1026,7 @@ // it is asked for. // - FT_Set_Transform( FT->face, &FT->matrix, &FT->pos ); + FT_Set_Transform( FT->face, &FT->matrix, &FT->pos ); // Rotate the Page @@ -1004,51 +1042,51 @@ // Convert into normal coordinates from virtual coordinates // - if ( FT->scale != 0.0 ) // scale was set - { - x = (int) ( args->x / FT->scale ); + if ( FT->scale != 0.0 ) // scale was set + { + x = (int) ( args->x / FT->scale ); - if ( FT->invert_y == 1 ) - y = (int) ( FT->ymax - ( args->y / FT->scale ) ); + if ( FT->invert_y == 1 ) + y = (int) ( FT->ymax - ( args->y / FT->scale ) ); + else + y = (int) ( args->y / FT->scale ); + } else - y = (int) ( args->y / FT->scale ); - } - else - { - x = (int) ( args->x / FT->scalex ); + { + x = (int) ( args->x / FT->scalex ); - if ( FT->invert_y == 1 ) - y = (int) ( FT->ymax - ( args->y / FT->scaley ) ); - else - y = (int) ( args->y / FT->scaley ); - } + if ( FT->invert_y == 1 ) + y = (int) ( FT->ymax - ( args->y / FT->scaley ) ); + else + y = (int) ( args->y / FT->scaley ); + } - // Adjust for the justification and character height - // - // Eeeksss... this wasn't a nice bit of code to work out, let me tell you. - // I could not work out an entirely satisfactory solution that made - // logical sense, so came up with an "illogical" one as well. - // The logical one works fine for text in the normal "portrait" - // orientation, and does so for reasons you might expect it to work; But - // for all other orientations, the text's base line is either a little - // high, or a little low. This is because of the way the base-line pos - // is calculated from the decender height. The "dodgie" way of calculating - // the position is to use the character height here, then adjust for the - // decender height by a three-fold factor later on. That approach seems to - // work a little better for rotated pages, but why it should be so, I - // don't understand. You can compile in or out which way you want it by - // defining "DODGIE_DECENDER_HACK". - // - // note: the logic of the page rotation coming up next is that we pump in - // the justification factor and then use freetype to rotate and transform - // the values, which we then use to change the plotting location. - // + // Adjust for the justification and character height + // + // Eeeksss... this wasn't a nice bit of code to work out, let me tell you. + // I could not work out an entirely satisfactory solution that made + // logical sense, so came up with an "illogical" one as well. + // The logical one works fine for text in the normal "portrait" + // orientation, and does so for reasons you might expect it to work; But + // for all other orientations, the text's base line is either a little + // high, or a little low. This is because of the way the base-line pos + // is calculated from the decender height. The "dodgie" way of calculating + // the position is to use the character height here, then adjust for the + // decender height by a three-fold factor later on. That approach seems to + // work a little better for rotated pages, but why it should be so, I + // don't understand. You can compile in or out which way you want it by + // defining "DODGIE_DECENDER_HACK". + // + // note: the logic of the page rotation coming up next is that we pump in + // the justification factor and then use freetype to rotate and transform + // the values, which we then use to change the plotting location. + // #ifdef DODGIE_DECENDER_HACK - adjust.y = h; + adjust.y = h; #else - adjust.y = 0; + adjust.y = 0; #endif // (RL, on 2005-01-24) The code below uses floating point and division @@ -1069,14 +1107,14 @@ // only one glyph in the string in this case, we are okay here). // - if ( ( args->unicode_array_len == 2 ) - && ( args->unicode_array[0] == ( PL_FCI_MARK | 0x004 ) ) ) - { - adjust.x = (FT_Pos) ( args->just * ROUND( (PLFLT) FT->face->glyph->metrics.width / 64.0 ) ); - adjust.y = (FT_Pos) ROUND( (PLFLT) FT->face->glyph->metrics.height / 128.0 ); - } - else - { + if ( ( args->unicode_array_len == 2 ) + && ( args->unicode_array[0] == ( PL_FCI_MARK | 0x004 ) ) ) + { + adjust.x = (FT_Pos) ( args->just * ROUND( (PLFLT) FT->face->glyph->metrics.width / 64.0 ) ); + adjust.y = (FT_Pos) ROUND( (PLFLT) FT->face->glyph->metrics.height / 128.0 ); + } + else + { // (RL, on 2005-01-21) The vertical adjustment is set below, making // the DODGIE conditional moot. I use the value of h as return by FT_StrX_YW, // which should correspond to the total height of the text being @@ -1086,17 +1124,24 @@ // height_factor below. // - adjust.y = (FT_Pos) - ROUND( (PLFLT) FT->face->size->metrics.height / height_factor / 128.0 ); - adjust.x = (FT_Pos) ( args->just * ROUND( w / 64.0 ) ); - } + adjust.y = (FT_Pos) + ROUND( (PLFLT) FT->face->size->metrics.height / height_factor / 128.0 - ( prevlineheights + overh ) / 64.0 ); + adjust.x = (FT_Pos) ( args->just * ROUND( w / 64.0 ) ); + } - FT_Vector_Transform( &adjust, &FT->matrix ); // was /&matrix); - was I using the wrong matrix all this time ? + FT_Vector_Transform( &adjust, &FT->matrix ); // was /&matrix); - was I using the wrong matrix all this time ? - x -= (int) adjust.x; - y += (int) adjust.y; + x -= (int) adjust.x; + y += (int) adjust.y; - FT_WriteStrW( pls, args->unicode_array, (short) args->unicode_array_len, x, y ); // write it out + FT_WriteStrW( pls, line, (short) linelen, x, y ); // write it out + +// +// Move to the next line +// + line += linelen + 1; + prevlineheights += h + overh + underh; + } } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |