Rework on class EDA_TEXT and related classes and draw functions (Note: this is a work in progress):
* remove duplicate code between draw functions and STROKE_FONT used in GAL. Use only STROKE_FONT methods in draw, plot and test DRC function for texts. It remove slightly different shapes between GAL and other calculations. * fix incorrect bounding box for texts with overbar. Especially noticeable for texts with overbar inside a copper zone in Pcbnew. * fix a few minor other bugs related to graphic texts.
This commit is contained in:
parent
8a753adc33
commit
30d72045e7
|
@ -40,6 +40,7 @@ set( GAL_SRCS
|
||||||
# Common part
|
# Common part
|
||||||
draw_panel_gal.cpp
|
draw_panel_gal.cpp
|
||||||
painter.cpp
|
painter.cpp
|
||||||
|
newstroke_font.cpp
|
||||||
worksheet_viewitem.cpp
|
worksheet_viewitem.cpp
|
||||||
origin_viewitem.cpp
|
origin_viewitem.cpp
|
||||||
gal/graphics_abstraction_layer.cpp
|
gal/graphics_abstraction_layer.cpp
|
||||||
|
@ -235,7 +236,6 @@ set( COMMON_SRCS
|
||||||
lockfile.cpp
|
lockfile.cpp
|
||||||
msgpanel.cpp
|
msgpanel.cpp
|
||||||
netlist_keywords.cpp
|
netlist_keywords.cpp
|
||||||
newstroke_font.cpp
|
|
||||||
prependpath.cpp
|
prependpath.cpp
|
||||||
project.cpp
|
project.cpp
|
||||||
ptree.cpp
|
ptree.cpp
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
|
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
|
||||||
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2012 Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -41,30 +41,237 @@
|
||||||
|
|
||||||
#include <gal/stroke_font.h>
|
#include <gal/stroke_font.h>
|
||||||
|
|
||||||
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
#include <newstroke_font.h>
|
#include <newstroke_font.h>
|
||||||
|
|
||||||
#include <plot_common.h>
|
#include <plot_common.h>
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* class BASIC_GAL is a minimal GAL implementation to draw, plot and convert
|
||||||
|
* stroke texts to a set of segments for DRC tests.
|
||||||
|
* Currently it allows to use GAL and STROKE_FONT methods in legacy draw mode
|
||||||
|
* (using wxDC functions) in plot functions only for texts.
|
||||||
|
*
|
||||||
|
* The main purpose is to avoid duplicate code to do the same thing in GAL canvas
|
||||||
|
* legacy canvas, plotter canvas and DRC.
|
||||||
|
*
|
||||||
|
* It will be certainly removed when a full GAL canvas using wxDC is implemented
|
||||||
|
* (or at least restricted to plotter and DRC "canvas")
|
||||||
|
*/
|
||||||
|
|
||||||
// A ugly hack to avoid UTF8::uni_iter method not found at link stage
|
struct TRANSFORM_PRM // A helper class to transfort coordinates in BASIC_GAL canvas
|
||||||
// in gerbview and pl_editor.
|
|
||||||
// Hoping I (JPC) can remove that soon.
|
|
||||||
void dummy()
|
|
||||||
{
|
{
|
||||||
UTF8 text = "x";
|
VECTOR2D m_rotCenter;
|
||||||
for( UTF8::uni_iter it = text.ubegin(), end = text.uend(); it < end; ++it )
|
VECTOR2D m_moveOffset;
|
||||||
;
|
double m_rotAngle;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BASIC_GAL: public GAL
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxDC* m_DC;
|
||||||
|
EDA_COLOR_T m_Color;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TRANSFORM_PRM m_transform;
|
||||||
|
std::stack <TRANSFORM_PRM> m_transformHistory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BASIC_GAL()
|
||||||
|
{
|
||||||
|
m_DC = NULL;
|
||||||
|
m_Color = RED;
|
||||||
|
m_plotter = NULL;
|
||||||
|
m_callback = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPlotter( PLOTTER* aPlotter )
|
||||||
|
{
|
||||||
|
m_plotter = aPlotter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetCallback( void (* aCallback)( int x0, int y0, int xf, int yf ) )
|
||||||
|
{
|
||||||
|
m_callback = aCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set a clip box for drawings
|
||||||
|
/// If NULL, no clip will be made
|
||||||
|
void SetClipBox( EDA_RECT* aClipBox )
|
||||||
|
{
|
||||||
|
m_isClipped = aClipBox != NULL;
|
||||||
|
|
||||||
|
if( aClipBox )
|
||||||
|
m_clipBox = *aClipBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Save the context.
|
||||||
|
virtual void Save()
|
||||||
|
{
|
||||||
|
m_transformHistory.push( m_transform );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Restore()
|
||||||
|
{
|
||||||
|
m_transform = m_transformHistory.top();
|
||||||
|
m_transformHistory.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Draw a polyline
|
||||||
|
* @param aPointList is a list of 2D-Vectors containing the polyline points.
|
||||||
|
*/
|
||||||
|
virtual void DrawPolyline( const std::deque<VECTOR2D>& aPointList );
|
||||||
|
|
||||||
|
/** Start and end points are defined as 2D-Vectors.
|
||||||
|
* @param aStartPoint is the start point of the line.
|
||||||
|
* @param aEndPoint is the end point of the line.
|
||||||
|
*/
|
||||||
|
virtual void DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Translate the context.
|
||||||
|
*
|
||||||
|
* @param aTranslation is the translation vector.
|
||||||
|
*/
|
||||||
|
virtual void Translate( const VECTOR2D& aTranslation )
|
||||||
|
{
|
||||||
|
m_transform.m_moveOffset += aTranslation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Rotate the context.
|
||||||
|
*
|
||||||
|
* @param aAngle is the rotation angle in radians.
|
||||||
|
*/
|
||||||
|
virtual void Rotate( double aAngle )
|
||||||
|
{
|
||||||
|
m_transform.m_rotAngle = aAngle * M_PI/1800;
|
||||||
|
m_transform.m_rotCenter = m_transform.m_moveOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Apply the roation/translation transform to aPoint
|
||||||
|
const VECTOR2D transform( const VECTOR2D& aPoint ) const;
|
||||||
|
|
||||||
|
// A clip box, to clip drawings in a wxDC (mandatory to avoid draw issues)
|
||||||
|
EDA_RECT m_clipBox; // The clip box
|
||||||
|
bool m_isClipped; // Allows/disallows clipping
|
||||||
|
|
||||||
|
// When calling the draw functions outside a wxDC, to get the basic drawings
|
||||||
|
// lines / polylines ..., a callback function (used in DRC) to store
|
||||||
|
// coordinates of each segment:
|
||||||
|
void (* m_callback)( int x0, int y0, int xf, int yf );
|
||||||
|
|
||||||
|
// When calling the draw functions for plot, the plotter acts as a wxDC
|
||||||
|
// to plot basic items
|
||||||
|
PLOTTER* m_plotter;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const VECTOR2D BASIC_GAL::transform( const VECTOR2D& aPoint ) const
|
||||||
|
{
|
||||||
|
VECTOR2D point = aPoint + m_transform.m_moveOffset - m_transform.m_rotCenter;
|
||||||
|
point = point.Rotate( m_transform.m_rotAngle ) + m_transform.m_rotCenter;
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BASIC_GAL::DrawPolyline( const std::deque<VECTOR2D>& aPointList )
|
||||||
|
{
|
||||||
|
if( aPointList.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
|
||||||
|
std::vector <wxPoint> polyline_corners;
|
||||||
|
|
||||||
|
for( ; it != aPointList.end(); ++it )
|
||||||
|
{
|
||||||
|
VECTOR2D corner = transform(*it);
|
||||||
|
polyline_corners.push_back( wxPoint( corner.x, corner.y ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_DC )
|
||||||
|
{
|
||||||
|
if( isFillEnabled )
|
||||||
|
{
|
||||||
|
GRPoly( m_isClipped ? &m_clipBox : NULL, m_DC, polyline_corners.size(),
|
||||||
|
&polyline_corners[0], 0, GetLineWidth(), m_Color, m_Color );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( unsigned ii = 1; ii < polyline_corners.size(); ++ii )
|
||||||
|
{
|
||||||
|
GRCSegm( m_isClipped ? &m_clipBox : NULL, m_DC, polyline_corners[ii-1],
|
||||||
|
polyline_corners[ii], GetLineWidth(), m_Color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( m_plotter )
|
||||||
|
{
|
||||||
|
m_plotter->MoveTo( polyline_corners[0] );
|
||||||
|
|
||||||
|
for( unsigned ii = 1; ii < polyline_corners.size(); ii++ )
|
||||||
|
{
|
||||||
|
m_plotter->LineTo( polyline_corners[ii] );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_plotter->PenFinish();
|
||||||
|
}
|
||||||
|
else if( m_callback )
|
||||||
|
{
|
||||||
|
for( unsigned ii = 1; ii < polyline_corners.size(); ii++ )
|
||||||
|
{
|
||||||
|
m_callback( polyline_corners[ii-1].x, polyline_corners[ii-1].y,
|
||||||
|
polyline_corners[ii].x, polyline_corners[ii].y );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BASIC_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
|
||||||
|
{
|
||||||
|
VECTOR2D startVector = transform( aStartPoint );
|
||||||
|
VECTOR2D endVector = transform( aEndPoint );
|
||||||
|
|
||||||
|
if( m_DC )
|
||||||
|
{
|
||||||
|
if( isFillEnabled )
|
||||||
|
{
|
||||||
|
GRLine( m_isClipped ? &m_clipBox : NULL, m_DC, startVector.x, startVector.y,
|
||||||
|
endVector.x, endVector.y, GetLineWidth(), m_Color );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GRCSegm( m_isClipped ? &m_clipBox : NULL, m_DC, startVector.x, startVector.y,
|
||||||
|
endVector.x, endVector.y, GetLineWidth(), 0, m_Color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( m_plotter )
|
||||||
|
{
|
||||||
|
m_plotter->MoveTo( wxPoint( startVector.x, startVector.y ) );
|
||||||
|
m_plotter->LineTo( wxPoint( endVector.x, endVector.y ) );
|
||||||
|
m_plotter->PenFinish();
|
||||||
|
}
|
||||||
|
else if( m_callback )
|
||||||
|
{
|
||||||
|
m_callback( startVector.x, startVector.y,
|
||||||
|
endVector.x, endVector.y );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int OverbarPositionY( int size_v )
|
BASIC_GAL basic_gal;
|
||||||
{
|
|
||||||
return KiROUND( size_v * STROKE_FONT::OVERBAR_HEIGHT );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
int OverbarPositionY( int aVTextSize, int aThickness )
|
||||||
|
{
|
||||||
|
basic_gal.SetGlyphSize( VECTOR2D( aVTextSize, aVTextSize ) );
|
||||||
|
basic_gal.SetLineWidth( aThickness );
|
||||||
|
return KiROUND( basic_gal.GetOverbarVerticalPosition() );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetPensizeForBold
|
* Function GetPensizeForBold
|
||||||
* @return the "best" value for a pen size to draw/plot a bold text
|
* @return the "best" value for a pen size to draw/plot a bold text
|
||||||
|
@ -109,141 +316,15 @@ int Clamp_Text_PenSize( int aPenSize, wxSize aSize, bool aBold )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Functions to draw / plot a string.
|
int GraphicTextWidth( const wxString& aText, const wxSize& aSize, bool aItalic, bool aBold )
|
||||||
* texts have only one line.
|
|
||||||
* They can be in italic.
|
|
||||||
* Horizontal and Vertical justification are handled.
|
|
||||||
* Texts can be rotated
|
|
||||||
* substrings between ~ markers can be "negated" (i.e. with an over bar
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function NegableTextLength
|
|
||||||
* Return the text length (char count) of a negable string,
|
|
||||||
* excluding the ~ markers
|
|
||||||
*/
|
|
||||||
int NegableTextLength( const wxString& aText )
|
|
||||||
{
|
{
|
||||||
int char_count = aText.length();
|
basic_gal.SetItalic( aItalic );
|
||||||
|
basic_gal.SetBold( aBold );
|
||||||
|
basic_gal.SetGlyphSize( VECTOR2D( aSize ) );
|
||||||
|
|
||||||
// Fix the character count, removing the ~ found
|
VECTOR2D tsize = basic_gal.GetTextLineSize( aText );
|
||||||
for( int i = char_count - 1; i >= 0; i-- )
|
|
||||||
{
|
|
||||||
if( aText[i] == '~' )
|
|
||||||
{
|
|
||||||
// '~~' draw as '~' and count as two chars
|
|
||||||
if( i > 0 && aText[i - 1] == '~' )
|
|
||||||
i--;
|
|
||||||
else
|
|
||||||
char_count--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return char_count;
|
return KiROUND( tsize.x );
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Function GetHersheyShapeDescription
|
|
||||||
* return a pointer to the shape corresponding to unicode value AsciiCode
|
|
||||||
* Note we use the same font for Bold and Normal texts
|
|
||||||
* because KiCad handles a variable pen size to do that
|
|
||||||
* that gives better results in XOR draw mode.
|
|
||||||
*/
|
|
||||||
static const char* GetHersheyShapeDescription( int AsciiCode )
|
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
return newstroke_font[AsciiCode];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int GraphicTextWidth( const wxString& aText, int aXSize, bool aItalic, bool aWidth )
|
|
||||||
{
|
|
||||||
int tally = 0;
|
|
||||||
int char_count = aText.length();
|
|
||||||
|
|
||||||
for( int i = 0; i < char_count; i++ )
|
|
||||||
{
|
|
||||||
int asciiCode = aText[i];
|
|
||||||
|
|
||||||
/* Skip the negation marks
|
|
||||||
* and first '~' char of '~~'
|
|
||||||
* ('~~' draw as '~')
|
|
||||||
*/
|
|
||||||
if( asciiCode == '~' )
|
|
||||||
{
|
|
||||||
if( i == 0 || aText[i - 1] != '~' )
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* shape_ptr = GetHersheyShapeDescription( asciiCode );
|
|
||||||
// Get metrics
|
|
||||||
int xsta = *shape_ptr++ - 'R';
|
|
||||||
int xsto = *shape_ptr++ - 'R';
|
|
||||||
tally += KiROUND( aXSize * (xsto - xsta) * STROKE_FONT::STROKE_FONT_SCALE );
|
|
||||||
}
|
|
||||||
|
|
||||||
// For italic correction, add 1/8 size
|
|
||||||
if( aItalic )
|
|
||||||
{
|
|
||||||
tally += KiROUND( aXSize * STROKE_FONT::ITALIC_TILT );
|
|
||||||
}
|
|
||||||
|
|
||||||
return tally;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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] );
|
|
||||||
}
|
|
||||||
|
|
||||||
aPlotter->PenFinish();
|
|
||||||
}
|
|
||||||
else if( aCallback )
|
|
||||||
{
|
|
||||||
for( int ik = 0; ik < (point_count - 1); ik++ )
|
|
||||||
{
|
|
||||||
aCallback( coord[ik].x, coord[ik].y,
|
|
||||||
coord[ik + 1].x, coord[ik + 1].y );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( aDC )
|
|
||||||
{
|
|
||||||
if( aSketchMode )
|
|
||||||
{
|
|
||||||
for( int ik = 0; ik < (point_count - 1); ik++ )
|
|
||||||
GRCSegm( aClipBox, aDC, coord[ik].x, coord[ik].y,
|
|
||||||
coord[ik + 1].x, coord[ik + 1].y, aWidth, aColor );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
GRPoly( aClipBox, aDC, point_count, coord, 0,
|
|
||||||
aWidth, aColor, aColor );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -284,21 +365,7 @@ void DrawGraphicText( EDA_RECT* aClipBox,
|
||||||
void (* aCallback)( int x0, int y0, int xf, int yf ),
|
void (* aCallback)( int x0, int y0, int xf, int yf ),
|
||||||
PLOTTER* aPlotter )
|
PLOTTER* aPlotter )
|
||||||
{
|
{
|
||||||
int AsciiCode;
|
bool fill_mode = true;
|
||||||
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
|
|
||||||
#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
|
|
||||||
|
|
||||||
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 ) );
|
aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );
|
||||||
|
@ -306,263 +373,33 @@ void DrawGraphicText( EDA_RECT* aClipBox,
|
||||||
if( aWidth < 0 )
|
if( aWidth < 0 )
|
||||||
{
|
{
|
||||||
aWidth = -aWidth;
|
aWidth = -aWidth;
|
||||||
sketch_mode = true;
|
fill_mode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CLIP_PEN // made by draw and plot functions
|
basic_gal.SetIsFill( fill_mode );
|
||||||
aWidth = Clamp_Text_PenSize( aWidth, aSize, aBold );
|
basic_gal.SetLineWidth( aWidth );
|
||||||
#endif
|
|
||||||
|
|
||||||
if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis)
|
EDA_TEXT dummy;
|
||||||
italic_reverse = true;
|
dummy.SetItalic( aItalic );
|
||||||
|
dummy.SetBold( aBold );
|
||||||
|
dummy.SetHorizJustify( aH_justify );
|
||||||
|
dummy.SetVertJustify( aV_justify );
|
||||||
|
|
||||||
unsigned char_count = NegableTextLength( aText );
|
wxSize size = aSize;
|
||||||
|
dummy.SetMirrored( size.x < 0 );
|
||||||
|
|
||||||
if( char_count == 0 )
|
if( size.x < 0 )
|
||||||
return;
|
size.x = - size.x;
|
||||||
|
|
||||||
current_char_pos = aPos;
|
dummy.SetSize( size );
|
||||||
|
|
||||||
dx = GraphicTextWidth( aText, size_h, aItalic, aWidth );
|
basic_gal.SetTextAttributes( &dummy );
|
||||||
dy = size_v;
|
basic_gal.SetPlotter( aPlotter );
|
||||||
|
basic_gal.SetCallback( aCallback );
|
||||||
/* Do not draw the text if out of draw area! */
|
basic_gal.m_DC = aDC;
|
||||||
if( aClipBox )
|
basic_gal.m_Color = aColor;
|
||||||
{
|
basic_gal.SetClipBox( aClipBox );
|
||||||
int xm, ym, ll, xc, yc;
|
basic_gal.StrokeText( aText, VECTOR2D( aPos ), aOrient );
|
||||||
ll = std::abs( dx );
|
|
||||||
|
|
||||||
xc = current_char_pos.x;
|
|
||||||
yc = current_char_pos.y;
|
|
||||||
|
|
||||||
x0 = aClipBox->GetX() - ll;
|
|
||||||
y0 = aClipBox->GetY() - ll;
|
|
||||||
xm = aClipBox->GetRight() + ll;
|
|
||||||
ym = aClipBox->GetBottom() + ll;
|
|
||||||
|
|
||||||
if( xc < x0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( yc < y0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( xc > xm )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( yc > ym )
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Compute the position of the first letter of the text
|
|
||||||
* this position is the position of the left bottom point of the letter
|
|
||||||
* this is the same as the text position only for a left and bottom justified text
|
|
||||||
* In others cases, this position must be calculated from the text position ans size
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch( aH_justify )
|
|
||||||
{
|
|
||||||
case GR_TEXT_HJUSTIFY_CENTER:
|
|
||||||
current_char_pos.x -= dx / 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_TEXT_HJUSTIFY_RIGHT:
|
|
||||||
current_char_pos.x -= dx;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_TEXT_HJUSTIFY_LEFT:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( aV_justify )
|
|
||||||
{
|
|
||||||
case GR_TEXT_VJUSTIFY_CENTER:
|
|
||||||
current_char_pos.y += dy / 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_TEXT_VJUSTIFY_TOP:
|
|
||||||
current_char_pos.y += dy;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GR_TEXT_VJUSTIFY_BOTTOM:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: if aPanel == NULL, we are using a GL Canvas that handle scaling
|
|
||||||
if( aSize.x == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* if a text size is too small, the text cannot be drawn, and it is drawn as a single
|
|
||||||
* graphic line */
|
|
||||||
if( aDC && ( aDC->LogicalToDeviceYRel( std::abs( aSize.y ) ) < MIN_DRAWABLE_TEXT_SIZE ))
|
|
||||||
{
|
|
||||||
// draw the text as a line always vertically centered
|
|
||||||
wxPoint end( current_char_pos.x + dx, current_char_pos.y );
|
|
||||||
|
|
||||||
RotatePoint( ¤t_char_pos, aPos, aOrient );
|
|
||||||
RotatePoint( &end, aPos, aOrient );
|
|
||||||
|
|
||||||
if( aPlotter )
|
|
||||||
{
|
|
||||||
aPlotter->MoveTo( current_char_pos );
|
|
||||||
aPlotter->FinishTo( end );
|
|
||||||
}
|
|
||||||
else if( aCallback )
|
|
||||||
{
|
|
||||||
aCallback( current_char_pos.x, current_char_pos.y, end.x, end.y );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
GRLine( aClipBox, aDC,
|
|
||||||
current_char_pos.x, current_char_pos.y, end.x, end.y, aWidth, aColor );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aItalic )
|
|
||||||
{
|
|
||||||
overbar_italic_comp = KiROUND( OverbarPositionY( size_v ) * STROKE_FONT::ITALIC_TILT );
|
|
||||||
|
|
||||||
if( italic_reverse )
|
|
||||||
{
|
|
||||||
overbar_italic_comp = -overbar_italic_comp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
overbar_italic_comp = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Found an overbar, adjust the pointers
|
|
||||||
overbars++;
|
|
||||||
|
|
||||||
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 );
|
|
||||||
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 );
|
|
||||||
RotatePoint( &overbar_pos, aPos, aOrient );
|
|
||||||
coord[1] = overbar_pos;
|
|
||||||
// Plot the overbar segment
|
|
||||||
DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
|
|
||||||
sketch_mode, 2, coord, aCallback, aPlotter );
|
|
||||||
}
|
|
||||||
|
|
||||||
continue; // Skip ~ processing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AsciiCode = aText.GetChar( ptr + overbars );
|
|
||||||
|
|
||||||
const char* ptcar = GetHersheyShapeDescription( AsciiCode );
|
|
||||||
// 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++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// End of character, insert a synthetic pen up:
|
|
||||||
hc1 = ' ';
|
|
||||||
hc2 = 'R';
|
|
||||||
endcar = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the Hershey decode thing:
|
|
||||||
// coordinates values are coded as <value> + 'R'
|
|
||||||
hc1 -= 'R';
|
|
||||||
hc2 -= 'R';
|
|
||||||
|
|
||||||
// Pen up request
|
|
||||||
if( hc1 == -50 && hc2 == 0 )
|
|
||||||
{
|
|
||||||
if( point_count )
|
|
||||||
{
|
|
||||||
if( aWidth <= 1 )
|
|
||||||
aWidth = 0;
|
|
||||||
|
|
||||||
DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
|
|
||||||
sketch_mode, point_count, coord,
|
|
||||||
aCallback, aPlotter );
|
|
||||||
}
|
|
||||||
|
|
||||||
point_count = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxPoint currpoint;
|
|
||||||
hc1 -= xsta; hc2 -= 10; // Align the midpoint
|
|
||||||
hc1 = KiROUND( hc1 * size_h * STROKE_FONT::STROKE_FONT_SCALE );
|
|
||||||
hc2 = KiROUND( hc2 * size_v * STROKE_FONT::STROKE_FONT_SCALE );
|
|
||||||
|
|
||||||
// To simulate an italic font,
|
|
||||||
// add a x offset depending on the y offset
|
|
||||||
if( aItalic )
|
|
||||||
hc1 -= KiROUND( italic_reverse ? -hc2 * STROKE_FONT::ITALIC_TILT
|
|
||||||
: hc2 * STROKE_FONT::ITALIC_TILT );
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
// Apply the advance width
|
|
||||||
current_char_pos.x += KiROUND( size_h * (xsto - xsta) * STROKE_FONT::STROKE_FONT_SCALE );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( overbars % 2 )
|
|
||||||
{
|
|
||||||
// Close the last overbar
|
|
||||||
coord[0] = overbar_pos;
|
|
||||||
overbar_pos = current_char_pos;
|
|
||||||
overbar_pos.y -= OverbarPositionY( size_v );
|
|
||||||
RotatePoint( &overbar_pos, aPos, aOrient );
|
|
||||||
coord[1] = overbar_pos;
|
|
||||||
|
|
||||||
// Plot the overbar segment
|
|
||||||
DrawGraphicTextPline( aClipBox, aDC, aColor, aWidth,
|
|
||||||
sketch_mode, 2, coord, aCallback, aPlotter );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawGraphicHaloText( EDA_RECT* aClipBox, wxDC * aDC,
|
void DrawGraphicHaloText( EDA_RECT* aClipBox, wxDC * aDC,
|
||||||
|
|
|
@ -90,7 +90,7 @@ EDA_TEXT::~EDA_TEXT()
|
||||||
|
|
||||||
int EDA_TEXT::LenSize( const wxString& aLine ) const
|
int EDA_TEXT::LenSize( const wxString& aLine ) const
|
||||||
{
|
{
|
||||||
return GraphicTextWidth( aLine, m_Size.x, m_Italic, m_Bold );
|
return GraphicTextWidth( aLine, m_Size, m_Italic, m_Bold );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -128,6 +128,7 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const
|
||||||
wxString text = GetShownText();
|
wxString text = GetShownText();
|
||||||
int thickness = ( aThickness < 0 ) ? m_Thickness : aThickness;
|
int thickness = ( aThickness < 0 ) ? m_Thickness : aThickness;
|
||||||
int linecount = 1;
|
int linecount = 1;
|
||||||
|
bool hasOverBar = false; // true if the first line of text as an overbar
|
||||||
|
|
||||||
if( m_MultilineAllowed )
|
if( m_MultilineAllowed )
|
||||||
{
|
{
|
||||||
|
@ -144,9 +145,20 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search for overbar symbol. Only text is scanned,
|
||||||
|
// because only this line can change the bounding box
|
||||||
|
for( unsigned ii = 1; ii < text.size(); ii++ )
|
||||||
|
{
|
||||||
|
if( text[ii-1] == '~' && text[ii] != '~' )
|
||||||
|
{
|
||||||
|
hasOverBar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// calculate the H and V size
|
// calculate the H and V size
|
||||||
int dx = LenSize( text );
|
int dx = LenSize( text );
|
||||||
int dy = GetInterline( aThickness );
|
int dy = GetInterline( thickness );
|
||||||
|
|
||||||
// Creates bounding box (rectangle) for an horizontal text
|
// Creates bounding box (rectangle) for an horizontal text
|
||||||
wxSize textsize = wxSize( dx, dy );
|
wxSize textsize = wxSize( dx, dy );
|
||||||
|
@ -161,7 +173,16 @@ EDA_RECT EDA_TEXT::GetTextBox( int aLine, int aThickness, bool aInvertY ) const
|
||||||
// The interval below the last line is not usefull, and we can use its half value
|
// The interval below the last line is not usefull, and we can use its half value
|
||||||
// as vertical margin above the text
|
// as vertical margin above the text
|
||||||
// the full interval is roughly m_Size.y * 0.4 - aThickness/2
|
// the full interval is roughly m_Size.y * 0.4 - aThickness/2
|
||||||
rect.Move( wxPoint( 0, aThickness/4 - KiROUND( m_Size.y * 0.2 ) ) );
|
rect.Move( wxPoint( 0, thickness/4 - KiROUND( m_Size.y * 0.2 ) ) );
|
||||||
|
|
||||||
|
if( hasOverBar )
|
||||||
|
{
|
||||||
|
// A overbar adds an extra size to the text
|
||||||
|
double curr_height = m_Size.y * 1.15; // Height from the base line text of chars like [ or {
|
||||||
|
int extra_height = KiROUND( OverbarPositionY( m_Size.y, thickness ) - curr_height );
|
||||||
|
textsize.y += extra_height;
|
||||||
|
rect.Move( wxPoint( 0, -extra_height ) );
|
||||||
|
}
|
||||||
|
|
||||||
// for multiline texts and aLine < 0, merge all rectangles
|
// for multiline texts and aLine < 0, merge all rectangles
|
||||||
// ( if aLine < 0, we want the full text bounding box )
|
// ( if aLine < 0, we want the full text bounding box )
|
||||||
|
|
|
@ -84,6 +84,14 @@ void GAL::SetTextAttributes( const EDA_TEXT* aText )
|
||||||
strokeFont.SetMirrored( aText->IsMirrored() );
|
strokeFont.SetMirrored( aText->IsMirrored() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VECTOR2D GAL::GetTextLineSize( const UTF8& aText ) const
|
||||||
|
{
|
||||||
|
// Compute the X and Y size of a given text.
|
||||||
|
// Because computeTextLineSize expects a one line text,
|
||||||
|
// aText is expected to be only one line text.
|
||||||
|
return strokeFont.computeTextLineSize( aText );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void GAL::ComputeWorldScreenMatrix()
|
void GAL::ComputeWorldScreenMatrix()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* Stroke font class
|
* Stroke font class
|
||||||
*
|
*
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
const double STROKE_FONT::INTERLINE_PITCH_RATIO = 1.5;
|
const double STROKE_FONT::INTERLINE_PITCH_RATIO = 1.5;
|
||||||
const double STROKE_FONT::OVERBAR_HEIGHT = 1.22;
|
const double STROKE_FONT::OVERBAR_POSITION_FACTOR = 1.22;
|
||||||
const double STROKE_FONT::BOLD_FACTOR = 1.3;
|
const double STROKE_FONT::BOLD_FACTOR = 1.3;
|
||||||
const double STROKE_FONT::STROKE_FONT_SCALE = 1.0 / 21.0;
|
const double STROKE_FONT::STROKE_FONT_SCALE = 1.0 / 21.0;
|
||||||
const double STROKE_FONT::ITALIC_TILT = 1.0 / 8;
|
const double STROKE_FONT::ITALIC_TILT = 1.0 / 8;
|
||||||
|
@ -202,7 +202,7 @@ void STROKE_FONT::Draw( const UTF8& aText, const VECTOR2D& aPosition, double aRo
|
||||||
}
|
}
|
||||||
|
|
||||||
m_gal->SetIsStroke( true );
|
m_gal->SetIsStroke( true );
|
||||||
m_gal->SetIsFill( false );
|
//m_gal->SetIsFill( false );
|
||||||
|
|
||||||
if( m_bold )
|
if( m_bold )
|
||||||
m_gal->SetLineWidth( m_gal->GetLineWidth() * BOLD_FACTOR );
|
m_gal->SetLineWidth( m_gal->GetLineWidth() * BOLD_FACTOR );
|
||||||
|
@ -237,10 +237,13 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
|
||||||
|
|
||||||
double xOffset;
|
double xOffset;
|
||||||
VECTOR2D glyphSize( m_glyphSize );
|
VECTOR2D glyphSize( m_glyphSize );
|
||||||
double overbar_italic_comp = 0.0;
|
double overbar_italic_comp = computeOverbarVerticalPosition() * ITALIC_TILT;
|
||||||
|
|
||||||
|
if( m_mirrored )
|
||||||
|
overbar_italic_comp = -overbar_italic_comp;
|
||||||
|
|
||||||
// Compute the text size
|
// Compute the text size
|
||||||
VECTOR2D textSize = computeTextSize( aText );
|
VECTOR2D textSize = computeTextLineSize( aText );
|
||||||
|
|
||||||
m_gal->Save();
|
m_gal->Save();
|
||||||
|
|
||||||
|
@ -305,24 +308,12 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
|
||||||
GLYPH& glyph = m_glyphs[dd];
|
GLYPH& glyph = m_glyphs[dd];
|
||||||
BOX2D& bbox = m_glyphBoundingBoxes[dd];
|
BOX2D& bbox = m_glyphBoundingBoxes[dd];
|
||||||
|
|
||||||
if( m_overbar && m_italic )
|
|
||||||
{
|
|
||||||
if( m_mirrored )
|
|
||||||
{
|
|
||||||
overbar_italic_comp = (-m_glyphSize.y * OVERBAR_HEIGHT) / ITALIC_TILT;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
overbar_italic_comp = (m_glyphSize.y * OVERBAR_HEIGHT) / ITALIC_TILT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_overbar )
|
if( m_overbar )
|
||||||
{
|
{
|
||||||
double overbar_start_x = xOffset;
|
double overbar_start_x = xOffset;
|
||||||
double overbar_start_y = -m_glyphSize.y * OVERBAR_HEIGHT;
|
double overbar_start_y = - computeOverbarVerticalPosition();
|
||||||
double overbar_end_x = xOffset + glyphSize.x * bbox.GetEnd().x;
|
double overbar_end_x = xOffset + glyphSize.x * bbox.GetEnd().x;
|
||||||
double overbar_end_y = -m_glyphSize.y * OVERBAR_HEIGHT;
|
double overbar_end_y = overbar_start_y;
|
||||||
|
|
||||||
if( !last_had_overbar )
|
if( !last_had_overbar )
|
||||||
{
|
{
|
||||||
|
@ -355,9 +346,9 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
|
||||||
// FIXME should be done other way - referring to the lowest Y value of point
|
// FIXME should be done other way - referring to the lowest Y value of point
|
||||||
// because now italic fonts are translated a bit
|
// because now italic fonts are translated a bit
|
||||||
if( m_mirrored )
|
if( m_mirrored )
|
||||||
pointPos.x += pointPos.y * 0.1;
|
pointPos.x += pointPos.y * STROKE_FONT::ITALIC_TILT;
|
||||||
else
|
else
|
||||||
pointPos.x -= pointPos.y * 0.1;
|
pointPos.x -= pointPos.y * STROKE_FONT::ITALIC_TILT;
|
||||||
}
|
}
|
||||||
|
|
||||||
pointListScaled.push_back( pointPos );
|
pointListScaled.push_back( pointPos );
|
||||||
|
@ -373,7 +364,15 @@ void STROKE_FONT::drawSingleLineText( const UTF8& aText )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VECTOR2D STROKE_FONT::computeTextSize( const UTF8& aText ) const
|
double STROKE_FONT::computeOverbarVerticalPosition() const
|
||||||
|
{
|
||||||
|
// Compute the Y position of the overbar. This is the distance between
|
||||||
|
// the text base line and the overbar axis.
|
||||||
|
return m_glyphSize.y * OVERBAR_POSITION_FACTOR + m_gal->GetLineWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VECTOR2D STROKE_FONT::computeTextLineSize( const UTF8& aText ) const
|
||||||
{
|
{
|
||||||
VECTOR2D result = VECTOR2D( 0.0, m_glyphSize.y );
|
VECTOR2D result = VECTOR2D( 0.0, m_glyphSize.y );
|
||||||
|
|
||||||
|
@ -399,5 +398,9 @@ VECTOR2D STROKE_FONT::computeTextSize( const UTF8& aText ) const
|
||||||
result.x += m_glyphSize.x * m_glyphBoundingBoxes[dd].GetEnd().x;
|
result.x += m_glyphSize.x * m_glyphBoundingBoxes[dd].GetEnd().x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For italic correction, take in account italic tilt
|
||||||
|
if( m_italic )
|
||||||
|
result.x += result.y * STROKE_FONT::ITALIC_TILT;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 1992-2016 Kicad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 1992-2016 Kicad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -642,9 +642,12 @@ const EDA_RECT SCH_SHEET::GetBoundingBox() const
|
||||||
|
|
||||||
// Determine length of texts
|
// Determine length of texts
|
||||||
wxString text = wxT( "Sheet: " ) + m_name;
|
wxString text = wxT( "Sheet: " ) + m_name;
|
||||||
int textlen = GraphicTextWidth( text, m_sheetNameSize, false, lineWidth );
|
int textlen = GraphicTextWidth( text, wxSize( m_sheetNameSize, m_sheetNameSize ),
|
||||||
|
false, false );
|
||||||
|
|
||||||
text = wxT( "File: " ) + m_fileName;
|
text = wxT( "File: " ) + m_fileName;
|
||||||
int textlen2 = GraphicTextWidth( text, m_fileNameSize, false, lineWidth );
|
int textlen2 = GraphicTextWidth( text, wxSize( m_fileNameSize, m_fileNameSize ),
|
||||||
|
false, false );
|
||||||
|
|
||||||
// Calculate bounding box X size:
|
// Calculate bounding box X size:
|
||||||
textlen = std::max( textlen, textlen2 );
|
textlen = std::max( textlen, textlen2 );
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
|
|
||||||
extern void IncrementLabelMember( wxString& name, int aIncrement );
|
extern void IncrementLabelMember( wxString& name, int aIncrement );
|
||||||
|
|
||||||
|
#define DRAW_BBOX 1 // Only for tests: set to 1 to draw the boudding box of labels
|
||||||
|
|
||||||
/* Names of sheet label types. */
|
/* Names of sheet label types. */
|
||||||
const char* SheetLabelType[] =
|
const char* SheetLabelType[] =
|
||||||
|
@ -361,7 +362,7 @@ void SCH_TEXT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& aOffset,
|
||||||
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
|
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
|
||||||
|
|
||||||
// Enable these line to draw the bounding box (debug tests purposes only)
|
// Enable these line to draw the bounding box (debug tests purposes only)
|
||||||
#if 0
|
#if DRAW_BBOX
|
||||||
{
|
{
|
||||||
EDA_RECT BoundaryBox = GetBoundingBox();
|
EDA_RECT BoundaryBox = GetBoundingBox();
|
||||||
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
||||||
|
@ -957,49 +958,22 @@ void SCH_LABEL::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
|
||||||
|
|
||||||
const EDA_RECT SCH_LABEL::GetBoundingBox() const
|
const EDA_RECT SCH_LABEL::GetBoundingBox() const
|
||||||
{
|
{
|
||||||
int x, y, dx, dy, length, height;
|
int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
||||||
|
EDA_RECT rect = GetTextBox( -1, linewidth );
|
||||||
|
|
||||||
x = m_Pos.x;
|
if( m_Orient )
|
||||||
y = m_Pos.y;
|
{ // Rotate rect
|
||||||
int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
wxPoint pos = rect.GetOrigin();
|
||||||
length = LenSize( GetShownText() );
|
wxPoint end = rect.GetEnd();
|
||||||
height = m_Size.y + width;
|
RotatePoint( &pos, m_Pos, m_Orient );
|
||||||
dx = dy = 0;
|
RotatePoint( &end, m_Pos, m_Orient );
|
||||||
|
rect.SetOrigin( pos );
|
||||||
|
rect.SetEnd( end );
|
||||||
|
|
||||||
switch( m_schematicOrientation )
|
rect.Normalize();
|
||||||
{
|
|
||||||
case 0: /* Horiz Normal Orientation (left justified) */
|
|
||||||
dx = 2 * DANGLING_SYMBOL_SIZE + length;
|
|
||||||
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
||||||
x -= DANGLING_SYMBOL_SIZE;
|
|
||||||
y += DANGLING_SYMBOL_SIZE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: /* Vert Orientation UP */
|
|
||||||
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
||||||
dy = -2 * DANGLING_SYMBOL_SIZE - length;
|
|
||||||
x += DANGLING_SYMBOL_SIZE;
|
|
||||||
y += DANGLING_SYMBOL_SIZE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: /* Horiz Orientation - Right justified */
|
|
||||||
dx = -2 * DANGLING_SYMBOL_SIZE - length;
|
|
||||||
dy = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
||||||
x += DANGLING_SYMBOL_SIZE;
|
|
||||||
y += DANGLING_SYMBOL_SIZE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3: /* Vert Orientation BOTTOM */
|
|
||||||
dx = -2 * DANGLING_SYMBOL_SIZE - height - TXTMARGE;
|
|
||||||
dy = 2 * DANGLING_SYMBOL_SIZE + length;
|
|
||||||
x += DANGLING_SYMBOL_SIZE;
|
|
||||||
y -= DANGLING_SYMBOL_SIZE;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EDA_RECT box( wxPoint( x, y ), wxSize( dx, dy ) );
|
return rect;
|
||||||
box.Normalize();
|
|
||||||
return box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1169,7 +1143,7 @@ wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset() const
|
||||||
int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
int width = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
||||||
|
|
||||||
width = Clamp_Text_PenSize( width, m_Size, m_Bold );
|
width = Clamp_Text_PenSize( width, m_Size, m_Bold );
|
||||||
int HalfSize = m_Size.x / 2;
|
int halfSize = m_Size.x / 2;
|
||||||
int offset = width;
|
int offset = width;
|
||||||
|
|
||||||
switch( m_shape )
|
switch( m_shape )
|
||||||
|
@ -1177,7 +1151,7 @@ wxPoint SCH_GLOBALLABEL::GetSchematicTextOffset() const
|
||||||
case NET_INPUT:
|
case NET_INPUT:
|
||||||
case NET_BIDI:
|
case NET_BIDI:
|
||||||
case NET_TRISTATE:
|
case NET_TRISTATE:
|
||||||
offset += HalfSize;
|
offset += halfSize;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NET_OUTPUT:
|
case NET_OUTPUT:
|
||||||
|
@ -1277,7 +1251,7 @@ void SCH_GLOBALLABEL::Draw( EDA_DRAW_PANEL* panel,
|
||||||
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
|
DrawDanglingSymbol( panel, DC, m_Pos + aOffset, color );
|
||||||
|
|
||||||
// Enable these line to draw the bounding box (debug tests purposes only)
|
// Enable these line to draw the bounding box (debug tests purposes only)
|
||||||
#if 0
|
#if DRAW_BBOX
|
||||||
{
|
{
|
||||||
EDA_RECT BoundaryBox = GetBoundingBox();
|
EDA_RECT BoundaryBox = GetBoundingBox();
|
||||||
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
||||||
|
@ -1288,7 +1262,7 @@ void SCH_GLOBALLABEL::Draw( EDA_DRAW_PANEL* panel,
|
||||||
|
|
||||||
void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
|
void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
|
||||||
{
|
{
|
||||||
int HalfSize = m_Size.y / 2;
|
int halfSize = m_Size.y / 2;
|
||||||
int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
int linewidth = (m_Thickness == 0) ? GetDefaultLineThickness() : m_Thickness;
|
||||||
|
|
||||||
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
|
linewidth = Clamp_Text_PenSize( linewidth, m_Size, m_Bold );
|
||||||
|
@ -1301,13 +1275,31 @@ void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const
|
||||||
int x = symb_len + linewidth + 3;
|
int x = symb_len + linewidth + 3;
|
||||||
|
|
||||||
// Use negation bar Y position to calculate full vertical size
|
// Use negation bar Y position to calculate full vertical size
|
||||||
#define Y_CORRECTION 1.3
|
// Search for overbar symbol
|
||||||
// Note: this factor is due to the fact the negation bar Y position
|
bool hasOverBar = false;
|
||||||
// does not give exactly the full Y size of text
|
|
||||||
// and is experimentally set to this value
|
for( unsigned ii = 1; ii < m_Text.size(); ii++ )
|
||||||
int y = KiROUND( OverbarPositionY( HalfSize ) * Y_CORRECTION );
|
{
|
||||||
// add room for line thickness and space between top of text and graphic shape
|
if( m_Text[ii-1] == '~' && m_Text[ii] != '~' )
|
||||||
y += linewidth;
|
{
|
||||||
|
hasOverBar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Y_CORRECTION 1.40
|
||||||
|
// Note: this factor is due to the fact the Y size of a few letters like [
|
||||||
|
// are bigger than the y size value, and we need a margin for the graphic symbol.
|
||||||
|
int y = KiROUND( halfSize * Y_CORRECTION );
|
||||||
|
|
||||||
|
// Note: this factor is due to the fact we need a margin for the graphic symbol.
|
||||||
|
#define Y_OVERBAR_CORRECTION 1.2
|
||||||
|
if( hasOverBar )
|
||||||
|
y = KiROUND( OverbarPositionY( halfSize, linewidth ) * Y_OVERBAR_CORRECTION );
|
||||||
|
|
||||||
|
// Gives room for line thickess and margin
|
||||||
|
y += linewidth // for line thickess
|
||||||
|
+ linewidth/2; // for margin
|
||||||
|
|
||||||
// Starting point(anchor)
|
// Starting point(anchor)
|
||||||
aPoints.push_back( wxPoint( 0, 0 ) );
|
aPoints.push_back( wxPoint( 0, 0 ) );
|
||||||
|
@ -1322,19 +1314,19 @@ void SCH_GLOBALLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const
|
||||||
switch( m_shape )
|
switch( m_shape )
|
||||||
{
|
{
|
||||||
case NET_INPUT:
|
case NET_INPUT:
|
||||||
x_offset = -HalfSize;
|
x_offset = -halfSize;
|
||||||
aPoints[0].x += HalfSize;
|
aPoints[0].x += halfSize;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NET_OUTPUT:
|
case NET_OUTPUT:
|
||||||
aPoints[3].x -= HalfSize;
|
aPoints[3].x -= halfSize;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NET_BIDI:
|
case NET_BIDI:
|
||||||
case NET_TRISTATE:
|
case NET_TRISTATE:
|
||||||
x_offset = -HalfSize;
|
x_offset = -halfSize;
|
||||||
aPoints[0].x += HalfSize;
|
aPoints[0].x += halfSize;
|
||||||
aPoints[3].x -= HalfSize;
|
aPoints[3].x -= halfSize;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NET_UNSPECIFIED:
|
case NET_UNSPECIFIED:
|
||||||
|
@ -1609,7 +1601,7 @@ void SCH_HIERLABEL::Draw( EDA_DRAW_PANEL* panel,
|
||||||
DrawDanglingSymbol( panel, DC, m_Pos + offset, color );
|
DrawDanglingSymbol( panel, DC, m_Pos + offset, color );
|
||||||
|
|
||||||
// Enable these line to draw the bounding box (debug tests purposes only)
|
// Enable these line to draw the bounding box (debug tests purposes only)
|
||||||
#if 0
|
#if DRAW_BBOX
|
||||||
{
|
{
|
||||||
EDA_RECT BoundaryBox = GetBoundingBox();
|
EDA_RECT BoundaryBox = GetBoundingBox();
|
||||||
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
GRRect( clipbox, DC, BoundaryBox, 0, BROWN );
|
||||||
|
@ -1621,7 +1613,7 @@ void SCH_HIERLABEL::Draw( EDA_DRAW_PANEL* panel,
|
||||||
void SCH_HIERLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
|
void SCH_HIERLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wxPoint& Pos )
|
||||||
{
|
{
|
||||||
int* Template = TemplateShape[m_shape][m_schematicOrientation];
|
int* Template = TemplateShape[m_shape][m_schematicOrientation];
|
||||||
int HalfSize = m_Size.x / 2;
|
int halfSize = m_Size.x / 2;
|
||||||
|
|
||||||
int imax = *Template; Template++;
|
int imax = *Template; Template++;
|
||||||
|
|
||||||
|
@ -1630,10 +1622,10 @@ void SCH_HIERLABEL::CreateGraphicShape( std::vector <wxPoint>& aPoints, const wx
|
||||||
for( int ii = 0; ii < imax; ii++ )
|
for( int ii = 0; ii < imax; ii++ )
|
||||||
{
|
{
|
||||||
wxPoint corner;
|
wxPoint corner;
|
||||||
corner.x = ( HalfSize * (*Template) ) + Pos.x;
|
corner.x = ( halfSize * (*Template) ) + Pos.x;
|
||||||
Template++;
|
Template++;
|
||||||
|
|
||||||
corner.y = ( HalfSize * (*Template) ) + Pos.y;
|
corner.y = ( halfSize * (*Template) ) + Pos.y;
|
||||||
Template++;
|
Template++;
|
||||||
|
|
||||||
aPoints.push_back( corner );
|
aPoints.push_back( corner );
|
||||||
|
|
|
@ -78,18 +78,15 @@ int GetPenSizeForBold( int aTextSize );
|
||||||
* @return the X size of the graphic text
|
* @return the X size of the graphic text
|
||||||
* the full X size is GraphicTextWidth + the thickness of graphic lines
|
* the full X size is GraphicTextWidth + the thickness of graphic lines
|
||||||
*/
|
*/
|
||||||
int GraphicTextWidth( const wxString& aText, int size_h, bool italic, bool bold );
|
int GraphicTextWidth( const wxString& aText, const wxSize& aSize, bool italic, bool bold );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function NegableTextLength
|
* @return the verical position of the overbar of a text
|
||||||
* Return the text length of a negable string, excluding the ~ markers */
|
* (relative to a horizontal text)
|
||||||
int NegableTextLength( const wxString& aText );
|
* @param aVTextSize = the text vertical size
|
||||||
|
* @param aThickness = the thickness of text
|
||||||
/**
|
|
||||||
* Helper function for texts with over bar, can be used as strut value
|
|
||||||
* for multiline text (add interline spacing)
|
|
||||||
*/
|
*/
|
||||||
int OverbarPositionY( int size_v );
|
int OverbarPositionY( int aVTextSize, int aThickness );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function DrawGraphicText
|
* Function DrawGraphicText
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* Graphics Abstraction Layer (GAL) - base class
|
* Graphics Abstraction Layer (GAL) - base class
|
||||||
*
|
*
|
||||||
|
@ -282,6 +282,25 @@ public:
|
||||||
strokeFont.Draw( aText, aPosition, aRotationAngle );
|
strokeFont.Draw( aText, aPosition, aRotationAngle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Compute the X and Y size of a given text. The text is expected to be
|
||||||
|
* a only one line text.
|
||||||
|
*
|
||||||
|
* @param aText is the text string (one line).
|
||||||
|
* @return is the text size.
|
||||||
|
*/
|
||||||
|
VECTOR2D GetTextLineSize( const UTF8& aText ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the vertical position of an overbar, sometimes used in texts.
|
||||||
|
* This is the distance between the text base line and the overbar.
|
||||||
|
* @return the relative position of the overbar axis.
|
||||||
|
*/
|
||||||
|
double GetOverbarVerticalPosition() const
|
||||||
|
{
|
||||||
|
return strokeFont.computeOverbarVerticalPosition();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loads attributes of the given text (bold/italic/underline/mirrored and so on).
|
* @brief Loads attributes of the given text (bold/italic/underline/mirrored and so on).
|
||||||
*
|
*
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
* This program source code file is part of KICAD, a free EDA CAD application.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
|
||||||
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
|
|
||||||
* Copyright (C) 2013 CERN
|
* Copyright (C) 2013 CERN
|
||||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
* Copyright (C) 2016 Kicad Developers, see change_log.txt for contributors.
|
||||||
*
|
*
|
||||||
* Stroke font class
|
* Stroke font class
|
||||||
*
|
*
|
||||||
|
@ -50,6 +50,8 @@ typedef std::vector<GLYPH> GLYPH_LIST;
|
||||||
*/
|
*/
|
||||||
class STROKE_FONT
|
class STROKE_FONT
|
||||||
{
|
{
|
||||||
|
friend GAL;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructor
|
/// Constructor
|
||||||
STROKE_FONT( GAL* aGal );
|
STROKE_FONT( GAL* aGal );
|
||||||
|
@ -142,6 +144,23 @@ public:
|
||||||
m_gal = aGal;
|
m_gal = aGal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* @brief Compute the X and Y size of a given text. The text is expected to be
|
||||||
|
* a only one line text.
|
||||||
|
*
|
||||||
|
* @param aText is the text string (one line).
|
||||||
|
* @return the text size.
|
||||||
|
*/
|
||||||
|
VECTOR2D computeTextLineSize( const UTF8& aText ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the vertical position of an overbar, sometimes used in texts.
|
||||||
|
* This is the distance between the text base line and the overbar.
|
||||||
|
* @return the relative position of the overbar axis.
|
||||||
|
*/
|
||||||
|
double computeOverbarVerticalPosition() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GAL* m_gal; ///< Pointer to the GAL
|
GAL* m_gal; ///< Pointer to the GAL
|
||||||
GLYPH_LIST m_glyphs; ///< Glyph list
|
GLYPH_LIST m_glyphs; ///< Glyph list
|
||||||
|
@ -175,14 +194,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void drawSingleLineText( const UTF8& aText );
|
void drawSingleLineText( const UTF8& aText );
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Compute the size of a given text.
|
|
||||||
*
|
|
||||||
* @param aText is the text string.
|
|
||||||
* @return is the text size.
|
|
||||||
*/
|
|
||||||
VECTOR2D computeTextSize( const UTF8& aText ) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns number of lines for a given text.
|
* @brief Returns number of lines for a given text.
|
||||||
*
|
*
|
||||||
|
@ -198,18 +209,8 @@ private:
|
||||||
return std::count( aText.begin(), aText.end() - 1, '\n' ) + 1;
|
return std::count( aText.begin(), aText.end() - 1, '\n' ) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
///> Factor that determines relative vertical position of the overbar.
|
||||||
// These members are declared public only to be (temporary, I am expecting)
|
static const double OVERBAR_POSITION_FACTOR;
|
||||||
// used in legacy canvas, to avoid multiple declarations of the same constants,
|
|
||||||
// having multiple declarations of the same constants is really a thing to avoid.
|
|
||||||
//
|
|
||||||
// They will be private later, when the legacy canvas is removed.
|
|
||||||
|
|
||||||
///> Factor that determines the pitch between 2 lines.
|
|
||||||
static const double INTERLINE_PITCH_RATIO;
|
|
||||||
|
|
||||||
///> Factor that determines relative height of overbar.
|
|
||||||
static const double OVERBAR_HEIGHT;
|
|
||||||
|
|
||||||
///> Factor that determines relative line width for bold text.
|
///> Factor that determines relative line width for bold text.
|
||||||
static const double BOLD_FACTOR;
|
static const double BOLD_FACTOR;
|
||||||
|
@ -220,6 +221,16 @@ public:
|
||||||
///> Tilt factor for italic style (the is is the scaling factor
|
///> Tilt factor for italic style (the is is the scaling factor
|
||||||
///> on dY relative coordinates to give a tilst shape
|
///> on dY relative coordinates to give a tilst shape
|
||||||
static const double ITALIC_TILT;
|
static const double ITALIC_TILT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// These members are declared public only to be (temporary, I am expecting)
|
||||||
|
// used in legacy canvas, to avoid multiple declarations of the same constants,
|
||||||
|
// having multiple declarations of the same constants is really a thing to avoid.
|
||||||
|
//
|
||||||
|
// They will be private later, when the legacy canvas is removed.
|
||||||
|
|
||||||
|
///> Factor that determines the pitch between 2 lines.
|
||||||
|
static const double INTERLINE_PITCH_RATIO;
|
||||||
};
|
};
|
||||||
} // namespace KIGFX
|
} // namespace KIGFX
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue