|
|
|
@ -40,13 +40,15 @@ |
|
|
|
#include <class_base_screen.h>
|
|
|
|
|
|
|
|
|
|
|
|
#define EDA_DRAWBASE
|
|
|
|
#include <newstroke_font.h>
|
|
|
|
#include <plot_common.h>
|
|
|
|
|
|
|
|
/* factor used to calculate actual size of shapes from hershey fonts (could be adjusted depending on the font name)
|
|
|
|
* Its value is choosen in order to have letters like M, P .. vertical size equal to the vertical char size parameter |
|
|
|
* Of course some shapes can be bigger or smaller than the vertical char size parameter |
|
|
|
/* factor used to calculate actual size of shapes from hershey fonts
|
|
|
|
* (could be adjusted depending on the font name) |
|
|
|
* Its value is choosen in order to have letters like M, P .. vertical size |
|
|
|
* equal to the vertical char size parameter |
|
|
|
* Of course some shapes can be bigger or smaller than the vertical char size |
|
|
|
* parameter |
|
|
|
*/ |
|
|
|
#define HERSHEY_SCALE_FACTOR 1 / 21.0
|
|
|
|
double s_HerscheyScaleFactor = HERSHEY_SCALE_FACTOR; |
|
|
|
@ -59,6 +61,7 @@ int OverbarPositionY( int size_v, int thickness ) |
|
|
|
return KiROUND( ( (double) size_v * 1.1 ) + ( (double) thickness * 1.5 ) ); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function GetPensizeForBold |
|
|
|
* @return the "best" value for a pen size to draw/plot a bold text |
|
|
|
@ -84,12 +87,13 @@ int GetPenSizeForBold( int aTextSize ) |
|
|
|
*/ |
|
|
|
int Clamp_Text_PenSize( int aPenSize, int aSize, bool aBold ) |
|
|
|
{ |
|
|
|
int penSize = aPenSize; |
|
|
|
double scale = aBold ? 4.0 : 6.0; |
|
|
|
int maxWidth = KiROUND( std::abs( aSize ) / scale ); |
|
|
|
int penSize = aPenSize; |
|
|
|
double scale = aBold ? 4.0 : 6.0; |
|
|
|
int maxWidth = KiROUND( std::abs( aSize ) / scale ); |
|
|
|
|
|
|
|
if( penSize > maxWidth ) |
|
|
|
penSize = maxWidth; |
|
|
|
|
|
|
|
return penSize; |
|
|
|
} |
|
|
|
|
|
|
|
@ -112,17 +116,19 @@ int Clamp_Text_PenSize( int aPenSize, wxSize aSize, bool aBold ) |
|
|
|
|
|
|
|
/**
|
|
|
|
* Function NegableTextLength |
|
|
|
* Return the text length of a negable string, excluding the ~ markers */ |
|
|
|
* Return the text length (char count) of a negable string, |
|
|
|
* excluding the ~ markers |
|
|
|
*/ |
|
|
|
int NegableTextLength( const wxString& aText ) |
|
|
|
{ |
|
|
|
int char_count = aText.length(); |
|
|
|
|
|
|
|
/* Fix the character count, removing the ~ found */ |
|
|
|
// Fix the character count, removing the ~ found
|
|
|
|
for( int i = char_count - 1; i >= 0; i-- ) |
|
|
|
{ |
|
|
|
if( aText[i] == '~' ) |
|
|
|
{ |
|
|
|
/* '~~' draw as '~' and count as two chars */ |
|
|
|
// '~~' draw as '~' and count as two chars
|
|
|
|
if( i > 0 && aText[i - 1] == '~' ) |
|
|
|
i--; |
|
|
|
else |
|
|
|
@ -142,13 +148,15 @@ int NegableTextLength( const wxString& aText ) |
|
|
|
*/ |
|
|
|
static const char* GetHersheyShapeDescription( int AsciiCode ) |
|
|
|
{ |
|
|
|
/* calculate font length */ |
|
|
|
// calculate font length
|
|
|
|
int font_length_max = newstroke_font_bufsize; |
|
|
|
|
|
|
|
if( AsciiCode >= (32 + font_length_max) ) |
|
|
|
AsciiCode = '?'; |
|
|
|
|
|
|
|
if( AsciiCode < 32 ) |
|
|
|
AsciiCode = 32; /* Clamp control chars */ |
|
|
|
AsciiCode = 32; /* Clamp control chars */ |
|
|
|
|
|
|
|
AsciiCode -= 32; |
|
|
|
|
|
|
|
return newstroke_font[AsciiCode]; |
|
|
|
@ -162,48 +170,50 @@ int ReturnGraphicTextWidth( const wxString& aText, int aXSize, bool aItalic, boo |
|
|
|
|
|
|
|
for( int i = 0; i < char_count; i++ ) |
|
|
|
{ |
|
|
|
int AsciiCode = aText[i]; |
|
|
|
int asciiCode = aText[i]; |
|
|
|
|
|
|
|
/* Skip the negation marks
|
|
|
|
* and first '~' char of '~~' |
|
|
|
* ('~~' draw as '~') */ |
|
|
|
if( AsciiCode == '~' ) |
|
|
|
* ('~~' draw as '~') |
|
|
|
*/ |
|
|
|
if( asciiCode == '~' ) |
|
|
|
{ |
|
|
|
if( i > 0 && aText[i - 1] != '~' ) |
|
|
|
if( i == 0 || aText[i - 1] != '~' ) |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
const char* ptcar = GetHersheyShapeDescription( AsciiCode ); |
|
|
|
/* Get metrics */ |
|
|
|
int xsta = *ptcar++ - 'R'; |
|
|
|
int xsto = *ptcar++ - 'R'; |
|
|
|
const char* shape_ptr = GetHersheyShapeDescription( asciiCode ); |
|
|
|
// Get metrics
|
|
|
|
int xsta = *shape_ptr++ - 'R'; |
|
|
|
int xsto = *shape_ptr++ - 'R'; |
|
|
|
tally += KiROUND( aXSize * (xsto - xsta) * s_HerscheyScaleFactor ); |
|
|
|
} |
|
|
|
|
|
|
|
/* Italic correction, 1/8em */ |
|
|
|
// For italic correction, add 1/8 size
|
|
|
|
if( aItalic ) |
|
|
|
{ |
|
|
|
tally += KiROUND( aXSize * 0.125 ); |
|
|
|
} |
|
|
|
|
|
|
|
return tally; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Helper function for drawing character polygons */ |
|
|
|
static void DrawGraphicTextPline( |
|
|
|
EDA_RECT* aClipBox, |
|
|
|
wxDC* aDC, |
|
|
|
EDA_COLOR_T aColor, |
|
|
|
int aWidth, |
|
|
|
bool aSketchMode, |
|
|
|
int point_count, |
|
|
|
wxPoint* coord, |
|
|
|
void (* aCallback)(int x0, int y0, int xf, int yf ), |
|
|
|
PLOTTER* aPlotter ) |
|
|
|
// Helper function for drawing character polylines
|
|
|
|
static void DrawGraphicTextPline( EDA_RECT* aClipBox, |
|
|
|
wxDC* aDC, |
|
|
|
EDA_COLOR_T aColor, |
|
|
|
int aWidth, |
|
|
|
bool aSketchMode, |
|
|
|
int point_count, |
|
|
|
wxPoint* coord, |
|
|
|
void (* aCallback)( int x0, int y0, int xf, int yf ), |
|
|
|
PLOTTER* aPlotter ) |
|
|
|
{ |
|
|
|
if( aPlotter ) |
|
|
|
{ |
|
|
|
aPlotter->MoveTo( coord[0] ); |
|
|
|
|
|
|
|
for( int ik = 1; ik < point_count; ik++ ) |
|
|
|
{ |
|
|
|
aPlotter->LineTo( coord[ik] ); |
|
|
|
@ -268,26 +278,26 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
void (* aCallback)( int x0, int y0, int xf, int yf ), |
|
|
|
PLOTTER* aPlotter ) |
|
|
|
{ |
|
|
|
int AsciiCode; |
|
|
|
int x0, y0; |
|
|
|
int size_h, size_v; |
|
|
|
unsigned ptr; |
|
|
|
int dx, dy; // Draw coordinate for segments to draw. also used in some other calculation
|
|
|
|
wxPoint current_char_pos; // Draw coordinates for the current char
|
|
|
|
wxPoint overbar_pos; // Start point for the current overbar
|
|
|
|
int overbar_italic_comp; // Italic compensation for overbar
|
|
|
|
EDA_RECT* clipBox; // Clip box used in basic draw functions
|
|
|
|
int AsciiCode; |
|
|
|
int x0, y0; |
|
|
|
int size_h, size_v; |
|
|
|
unsigned ptr; |
|
|
|
int dx, dy; // Draw coordinate for segments to draw. also used in some other calculation
|
|
|
|
wxPoint current_char_pos; // Draw coordinates for the current char
|
|
|
|
wxPoint overbar_pos; // Start point for the current overbar
|
|
|
|
int overbar_italic_comp; // Italic compensation for overbar
|
|
|
|
EDA_RECT* clipBox; // Clip box used in basic draw functions
|
|
|
|
|
|
|
|
clipBox = aPanel ? aPanel->GetClipBox() : NULL; |
|
|
|
#define BUF_SIZE 100
|
|
|
|
wxPoint coord[BUF_SIZE + 1]; // Buffer coordinate used to draw polylines (one char shape)
|
|
|
|
bool sketch_mode = false; |
|
|
|
bool italic_reverse = false; // true for mirrored texts with m_Size.x < 0
|
|
|
|
bool sketch_mode = false; |
|
|
|
bool italic_reverse = false; // true for mirrored texts with m_Size.x < 0
|
|
|
|
|
|
|
|
size_h = aSize.x; /* PLEASE NOTE: H is for HORIZONTAL not for HEIGHT */ |
|
|
|
size_v = aSize.y; |
|
|
|
size_h = aSize.x; /* PLEASE NOTE: H is for HORIZONTAL not for HEIGHT */ |
|
|
|
size_v = aSize.y; |
|
|
|
|
|
|
|
if( aWidth == 0 && aBold ) // Use default values if aWidth == 0
|
|
|
|
if( aWidth == 0 && aBold ) // Use default values if aWidth == 0
|
|
|
|
aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); |
|
|
|
|
|
|
|
if( aWidth < 0 ) |
|
|
|
@ -300,17 +310,18 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
aWidth = Clamp_Text_PenSize( aWidth, aSize, aBold ); |
|
|
|
#endif
|
|
|
|
|
|
|
|
if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis)
|
|
|
|
if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis)
|
|
|
|
italic_reverse = true; |
|
|
|
|
|
|
|
unsigned char_count = NegableTextLength( aText ); |
|
|
|
|
|
|
|
if( char_count == 0 ) |
|
|
|
return; |
|
|
|
|
|
|
|
current_char_pos = aPos; |
|
|
|
|
|
|
|
dx = ReturnGraphicTextWidth( aText, size_h, aItalic, aWidth ); |
|
|
|
dy = size_v; |
|
|
|
dx = ReturnGraphicTextWidth( aText, size_h, aItalic, aWidth ); |
|
|
|
dy = size_v; |
|
|
|
|
|
|
|
/* Do not draw the text if out of draw area! */ |
|
|
|
if( aPanel ) |
|
|
|
@ -318,20 +329,23 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
int xm, ym, ll, xc, yc; |
|
|
|
ll = std::abs( dx ); |
|
|
|
|
|
|
|
xc = current_char_pos.x; |
|
|
|
yc = current_char_pos.y; |
|
|
|
xc = current_char_pos.x; |
|
|
|
yc = current_char_pos.y; |
|
|
|
|
|
|
|
x0 = aPanel->GetClipBox()->GetX() - ll; |
|
|
|
y0 = aPanel->GetClipBox()->GetY() - ll; |
|
|
|
xm = aPanel->GetClipBox()->GetRight() + ll; |
|
|
|
ym = aPanel->GetClipBox()->GetBottom() + ll; |
|
|
|
x0 = aPanel->GetClipBox()->GetX() - ll; |
|
|
|
y0 = aPanel->GetClipBox()->GetY() - ll; |
|
|
|
xm = aPanel->GetClipBox()->GetRight() + ll; |
|
|
|
ym = aPanel->GetClipBox()->GetBottom() + ll; |
|
|
|
|
|
|
|
if( xc < x0 ) |
|
|
|
return; |
|
|
|
|
|
|
|
if( yc < y0 ) |
|
|
|
return; |
|
|
|
|
|
|
|
if( xc > xm ) |
|
|
|
return; |
|
|
|
|
|
|
|
if( yc > ym ) |
|
|
|
return; |
|
|
|
} |
|
|
|
@ -404,6 +418,7 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
if( aItalic ) |
|
|
|
{ |
|
|
|
overbar_italic_comp = OverbarPositionY( size_v, aWidth ) / 8; |
|
|
|
|
|
|
|
if( italic_reverse ) |
|
|
|
{ |
|
|
|
overbar_italic_comp = -overbar_italic_comp; |
|
|
|
@ -412,17 +427,20 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
else |
|
|
|
{ |
|
|
|
overbar_italic_comp = 0; |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
; |
|
|
|
|
|
|
|
int overbars = 0; /* Number of '~' seen (except '~~') */ |
|
|
|
ptr = 0; /* ptr = text index */ |
|
|
|
|
|
|
|
int overbars = 0; /* Number of '~' seen (except '~~') */ |
|
|
|
ptr = 0; /* ptr = text index */ |
|
|
|
while( ptr < char_count ) |
|
|
|
{ |
|
|
|
if( aText[ptr + overbars] == '~' ) |
|
|
|
{ |
|
|
|
if( ptr + overbars + 1 < aText.length() && |
|
|
|
aText[ptr + overbars + 1] == '~' ) /* '~~' draw as '~' */ |
|
|
|
ptr++; // skip first '~' char and draw second
|
|
|
|
if( ptr + overbars + 1 < aText.length() |
|
|
|
&& aText[ptr + overbars + 1] == '~' ) /* '~~' draw as '~' */ |
|
|
|
ptr++; // skip first '~' char and draw second
|
|
|
|
|
|
|
|
else |
|
|
|
{ |
|
|
|
@ -431,41 +449,44 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
|
|
|
|
if( overbars & 1 ) // odd overbars count
|
|
|
|
{ |
|
|
|
/* Starting the overbar */ |
|
|
|
overbar_pos = current_char_pos; |
|
|
|
overbar_pos.x += overbar_italic_comp; |
|
|
|
overbar_pos.y -= OverbarPositionY( size_v, aWidth ); |
|
|
|
// Starting the overbar
|
|
|
|
overbar_pos = current_char_pos; |
|
|
|
overbar_pos.x += overbar_italic_comp; |
|
|
|
overbar_pos.y -= OverbarPositionY( size_v, aWidth ); |
|
|
|
RotatePoint( &overbar_pos, aPos, aOrient ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
/* Ending the overbar */ |
|
|
|
coord[0] = overbar_pos; |
|
|
|
overbar_pos = current_char_pos; |
|
|
|
overbar_pos.x += overbar_italic_comp; |
|
|
|
overbar_pos.y -= OverbarPositionY( size_v, aWidth ); |
|
|
|
// Ending the overbar
|
|
|
|
coord[0] = overbar_pos; |
|
|
|
overbar_pos = current_char_pos; |
|
|
|
overbar_pos.x += overbar_italic_comp; |
|
|
|
overbar_pos.y -= OverbarPositionY( size_v, aWidth ); |
|
|
|
RotatePoint( &overbar_pos, aPos, aOrient ); |
|
|
|
coord[1] = overbar_pos; |
|
|
|
/* Plot the overbar segment */ |
|
|
|
// Plot the overbar segment
|
|
|
|
DrawGraphicTextPline( clipBox, aDC, aColor, aWidth, |
|
|
|
sketch_mode, 2, coord, aCallback, aPlotter ); |
|
|
|
} |
|
|
|
continue; /* Skip ~ processing */ |
|
|
|
|
|
|
|
continue; /* Skip ~ processing */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
AsciiCode = aText.GetChar( ptr + overbars ); |
|
|
|
|
|
|
|
const char* ptcar = GetHersheyShapeDescription( AsciiCode ); |
|
|
|
/* Get metrics */ |
|
|
|
int xsta = *ptcar++ - 'R'; |
|
|
|
int xsto = *ptcar++ - 'R'; |
|
|
|
// Get metrics
|
|
|
|
int xsta = *ptcar++ - 'R'; |
|
|
|
int xsto = *ptcar++ - 'R'; |
|
|
|
int point_count = 0; |
|
|
|
bool endcar = false; |
|
|
|
|
|
|
|
while( !endcar ) |
|
|
|
{ |
|
|
|
int hc1, hc2; |
|
|
|
hc1 = *ptcar++; |
|
|
|
|
|
|
|
if( hc1 ) |
|
|
|
{ |
|
|
|
hc2 = *ptcar++; |
|
|
|
@ -473,12 +494,15 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
else |
|
|
|
{ |
|
|
|
// End of character, insert a synthetic pen up:
|
|
|
|
hc1 = ' '; |
|
|
|
hc2 = 'R'; |
|
|
|
endcar = true; |
|
|
|
hc1 = ' '; |
|
|
|
hc2 = 'R'; |
|
|
|
endcar = true; |
|
|
|
} |
|
|
|
// Do the Hershey decode thing: coordinates values are coded as <value> + 'R'
|
|
|
|
hc1 -= 'R'; hc2 -= 'R'; |
|
|
|
|
|
|
|
// Do the Hershey decode thing:
|
|
|
|
// coordinates values are coded as <value> + 'R'
|
|
|
|
hc1 -= 'R'; |
|
|
|
hc2 -= 'R'; |
|
|
|
|
|
|
|
/* Pen up request */ |
|
|
|
if( hc1 == -50 && hc2 == 0 ) |
|
|
|
@ -487,33 +511,36 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
{ |
|
|
|
if( aWidth <= 1 ) |
|
|
|
aWidth = 0; |
|
|
|
|
|
|
|
DrawGraphicTextPline( clipBox, aDC, aColor, aWidth, |
|
|
|
sketch_mode, point_count, coord, |
|
|
|
aCallback, aPlotter ); |
|
|
|
} |
|
|
|
|
|
|
|
point_count = 0; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
wxPoint currpoint; |
|
|
|
hc1 -= xsta; hc2 -= 11; /* Align the midpoint */ |
|
|
|
hc1 = KiROUND( hc1 * size_h * s_HerscheyScaleFactor ); |
|
|
|
hc2 = KiROUND( hc2 * size_v * s_HerscheyScaleFactor ); |
|
|
|
hc1 -= xsta; hc2 -= 11; // Align the midpoint
|
|
|
|
hc1 = KiROUND( hc1 * size_h * s_HerscheyScaleFactor ); |
|
|
|
hc2 = KiROUND( hc2 * size_v * s_HerscheyScaleFactor ); |
|
|
|
|
|
|
|
// To simulate an italic font, add a x offset depending on the y offset
|
|
|
|
// To simulate an italic font,
|
|
|
|
// add a x offset depending on the y offset
|
|
|
|
if( aItalic ) |
|
|
|
hc1 -= KiROUND( italic_reverse ? -hc2 / 8.0 : hc2 / 8.0 ); |
|
|
|
|
|
|
|
currpoint.x = hc1 + current_char_pos.x; |
|
|
|
currpoint.y = hc2 + current_char_pos.y; |
|
|
|
|
|
|
|
RotatePoint( &currpoint, aPos, aOrient ); |
|
|
|
coord[point_count] = currpoint; |
|
|
|
|
|
|
|
if( point_count < BUF_SIZE - 1 ) |
|
|
|
point_count++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* end draw 1 char */ |
|
|
|
} // end draw 1 char
|
|
|
|
|
|
|
|
ptr++; |
|
|
|
|
|
|
|
@ -524,9 +551,9 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, |
|
|
|
if( overbars % 2 ) |
|
|
|
{ |
|
|
|
/* Close the last overbar */ |
|
|
|
coord[0] = overbar_pos; |
|
|
|
overbar_pos = current_char_pos; |
|
|
|
overbar_pos.y -= OverbarPositionY( size_v, aWidth ); |
|
|
|
coord[0] = overbar_pos; |
|
|
|
overbar_pos = current_char_pos; |
|
|
|
overbar_pos.y -= OverbarPositionY( size_v, aWidth ); |
|
|
|
RotatePoint( &overbar_pos, aPos, aOrient ); |
|
|
|
coord[1] = overbar_pos; |
|
|
|
/* Plot the overbar segment */ |
|
|
|
@ -565,7 +592,7 @@ void PLOTTER::Text( const wxPoint& aPos, |
|
|
|
{ |
|
|
|
int textPensize = aWidth; |
|
|
|
|
|
|
|
if( textPensize == 0 && aBold ) // Use default values if aWidth == 0
|
|
|
|
if( textPensize == 0 && aBold ) // Use default values if aWidth == 0
|
|
|
|
textPensize = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); |
|
|
|
|
|
|
|
if( textPensize >= 0 ) |
|
|
|
|