b709776f5f
- piccole mdofiche poco più che estetiche.
541 lines
18 KiB
C++
541 lines
18 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2014-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : FontNfe.cpp Data : 05.06.14 Versione : 1.5f2
|
|
// Contenuto : Implementazione della classe NfeFont (formato font proprietario).
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 29.05.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "FontNfe.h"
|
|
#include "FontAux.h"
|
|
#include "FontConst.h"
|
|
#include "GdbIterator.h"
|
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
|
#include "/EgtDev/Include/EGkCurve.h"
|
|
#include "/EgtDev/Include/EGkCurveAux.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkExtText.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include "/EgtDev/Include/EGnFileUtils.h"
|
|
#include "/EgtDev/Include/EgtStringDecoder.h"
|
|
#include "/EgtDev/Include/EgtStringEncoder.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string NFE_H = "H" ;
|
|
const string NFE_HCAP = "HCAP" ;
|
|
const string NFE_HX = "HX" ;
|
|
const string NFE_ASC = "ASC" ;
|
|
const string NFE_DESC = "DESC" ;
|
|
const string NFE_ADV = "ADV" ;
|
|
const string NFE_ITALIC = "ITL" ;
|
|
const double NFE_ITALIC_STD_SHEAR_COEFF = 0.25 ;
|
|
const int NFE_MIN_CHAR = 32 ;
|
|
const int NFE_ERR_CHAR = 127 ;
|
|
const string NFE_LEN_CHAR = "L" ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
NfeFont::NfeFont( void)
|
|
{
|
|
m_pGDB = nullptr ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
NfeFont::~NfeFont( void)
|
|
{
|
|
if ( m_pGDB != nullptr)
|
|
delete m_pGDB ;
|
|
m_pGDB = nullptr ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::SetCurrFont( const string& sFont, int nWeight, bool bItalic,
|
|
double dHeight, double dRatio, double dAddAdvance)
|
|
{
|
|
string sFontUp = sFont ;
|
|
ToUpper( sFontUp) ;
|
|
|
|
// se il font non è già caricato
|
|
if ( m_pGDB == nullptr || m_sFont != sFontUp) {
|
|
// pulisco la path del font
|
|
m_sFont.clear() ;
|
|
// se necessario creo GDB
|
|
if ( m_pGDB == nullptr) {
|
|
m_pGDB = CreateGeomDB() ;
|
|
if ( m_pGDB == nullptr)
|
|
return false ;
|
|
}
|
|
// pulisco e inizializzo GDB
|
|
m_pGDB->Init() ;
|
|
// carico il font
|
|
if ( ! m_pGDB->Load( sFont))
|
|
return false ;
|
|
// recupero i parametri generali del font (devono essere nel gruppo 1)
|
|
GdbIterator iIter( m_pGDB) ;
|
|
if ( ! iIter.GoTo( 1))
|
|
return false ;
|
|
if ( ! iIter.GetInfo( NFE_H, m_dH) ||
|
|
! iIter.GetInfo( NFE_HCAP, m_dHCap) ||
|
|
! iIter.GetInfo( NFE_HX, m_dHx) ||
|
|
! iIter.GetInfo( NFE_ASC, m_dAsc) ||
|
|
! iIter.GetInfo( NFE_DESC, m_dDesc) ||
|
|
! iIter.GetInfo( NFE_ADV, m_dAdv))
|
|
return false ;
|
|
if ( m_dH < EPS_SMALL || m_dHCap < EPS_SMALL || m_dHx < EPS_SMALL)
|
|
return false ;
|
|
if ( ! iIter.GetInfo( NFE_ITALIC, m_dItalicShearCoeff))
|
|
m_dItalicShearCoeff = NFE_ITALIC_STD_SHEAR_COEFF ;
|
|
// aggiorno la path del font
|
|
m_sFont = sFontUp ;
|
|
}
|
|
|
|
// salvo i dati
|
|
m_nWeight = nWeight ;
|
|
m_bItalic = bItalic ;
|
|
m_dHeight = max( dHeight, FNT_MIN_HEIGHT) ;
|
|
m_dRatio = dRatio ;
|
|
m_dAddAdvance = dAddAdvance ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::GetCapHeight( double& dCapH) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// uso il fattore di scala per Y = m_dHeight / m_dHCap
|
|
dCapH = m_dHCap * m_dHeight / m_dHCap ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::GetAscent( double& dAsc) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// uso il fattore di scala per Y = m_dHeight / m_dHCap
|
|
dAsc = m_dAsc * m_dHeight / m_dHCap ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::GetDescent( double& dDesc) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// uso il fattore di scala per Y = m_dHeight / m_dHCap
|
|
dDesc = m_dDesc * m_dHeight / m_dHCap ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::GetXBox( const string& sText, int nInsPos, bool bCapOrBound, BBox3d& b3Box) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// calcolo i fattori di scala
|
|
double dScaY = m_dHeight / m_dHCap ;
|
|
double dScaX = dScaY * m_dRatio ;
|
|
|
|
// recupero altezza maiuscole, ascent, descent e interlinea
|
|
double dHCap = m_dHeight ;
|
|
double dAscent = m_dAsc * m_dHeight / m_dHCap ;
|
|
double dDescent = m_dDesc * m_dHeight / m_dHCap ;
|
|
double dH = m_dH * m_dHeight / m_dHCap ;
|
|
|
|
// converto i byte della stringa in codici carattere
|
|
UINTVECTOR vCode ;
|
|
GetCodePoints( sText, vCode) ;
|
|
|
|
// scandisco i codici
|
|
double dCurrW = 0 ;
|
|
double dMaxW = 0 ;
|
|
double dMinH = 0 ;
|
|
for ( unsigned int i = 0 ; i < vCode.size() ; ++ i) {
|
|
// verifico se comando di a capo
|
|
int nLbLen ;
|
|
if ( IsLineBreak( vCode, i, nLbLen)) {
|
|
dCurrW = 0 ;
|
|
dMinH -= dH ;
|
|
i += nLbLen ;
|
|
continue ;
|
|
}
|
|
// gruppo del carattere
|
|
int nGroup = sText[i] ;
|
|
if ( nGroup < NFE_MIN_CHAR || m_pGDB->GetGdbType( nGroup) != GDB_TY_GROUP)
|
|
nGroup = NFE_ERR_CHAR ;
|
|
// recupero lo spostamento per il prossimo carattere
|
|
double dAdvance ;
|
|
if ( ! m_pGDB->GetInfo( nGroup, NFE_LEN_CHAR, dAdvance))
|
|
dAdvance = m_dAdv ;
|
|
dCurrW += dAdvance * dScaX + m_dAddAdvance ;
|
|
if ( dCurrW > dMaxW)
|
|
dMaxW = dCurrW ;
|
|
}
|
|
|
|
// punti estremi
|
|
Point3d ptMin( 0, dMinH - ( bCapOrBound ? 0 : dDescent), 0) ;
|
|
Point3d ptMax( dMaxW, ( bCapOrBound ? dHCap : dAscent), 0) ;
|
|
// sistemazioni per la posizione del punto di inserimento
|
|
Vector3d vtIpMove = GetTextInsertPointMove( dMaxW, dHCap, dMinH, nInsPos) ;
|
|
ptMin.Translate( vtIpMove) ;
|
|
ptMax.Translate( vtIpMove) ;
|
|
|
|
// assegno l'ingombro
|
|
b3Box.Set( ptMin, ptMax) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::GetOutline( const string& sText, int nInsPos, ICURVEPLIST& lstPC) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// creo un iteratore
|
|
GdbIterator iIter( m_pGDB) ;
|
|
|
|
// calcolo i fattori di scala
|
|
double dScaY = m_dHeight / m_dHCap ;
|
|
double dScaX = dScaY * m_dRatio ;
|
|
double dScaZ = 1 ;
|
|
|
|
// recupero altezza maiuscole e interlinea
|
|
double dHCap = m_dHeight ;
|
|
double dH = m_dH * m_dHeight / m_dHCap ;
|
|
|
|
// converto i byte della stringa in codici carattere
|
|
UINTVECTOR vCode ;
|
|
GetCodePoints( sText, vCode) ;
|
|
|
|
// scandisco i codici
|
|
double dMaxW = 0 ;
|
|
double dMinH = 0 ;
|
|
Vector3d vtMove ;
|
|
for ( unsigned int i = 0 ; i < vCode.size() ; ++ i) {
|
|
// verifico se comando di a capo
|
|
int nLbLen ;
|
|
if ( IsLineBreak( vCode, i, nLbLen)) {
|
|
vtMove.Set( 0, vtMove.y - dH, 0) ;
|
|
if ( vtMove.y < dMinH)
|
|
dMinH = vtMove.y ;
|
|
i += nLbLen ;
|
|
continue ;
|
|
}
|
|
// verifico esistenza del gruppo del carattere
|
|
int nGroup = vCode[i] ;
|
|
if ( nGroup < NFE_MIN_CHAR || m_pGDB->GetGdbType( nGroup) != GDB_TY_GROUP)
|
|
nGroup = NFE_ERR_CHAR ;
|
|
// ciclo sulle entità geometriche del carattere
|
|
bool bIter = iIter.GoToFirstInGroup( nGroup) ;
|
|
while ( bIter) {
|
|
const ICurve* pCrv = GetCurve( iIter.GetGeoObj()) ;
|
|
if ( pCrv != nullptr) {
|
|
// copio la curva (trasformando eventuali archi in CurveBezier)
|
|
ICurve* pCrvNew = CurveToNoArcsCurve( pCrv) ;
|
|
if ( pCrvNew == nullptr)
|
|
return false ;
|
|
// eseguo trasformazioni
|
|
if ( m_bItalic)
|
|
pCrvNew->Shear( ORIG, Y_AX, X_AX, m_dItalicShearCoeff) ;
|
|
pCrvNew->Scale( GLOB_FRM, dScaX, dScaY, dScaZ) ;
|
|
pCrvNew->Translate( vtMove) ;
|
|
// inserisco in lista la nuova curva
|
|
lstPC.push_back( pCrvNew) ;
|
|
}
|
|
bIter = iIter.GoToNext() ;
|
|
}
|
|
// recupero lo spostamento per il prossimo carattere
|
|
double dAdvance ;
|
|
if ( ! m_pGDB->GetInfo( nGroup, NFE_LEN_CHAR, dAdvance))
|
|
dAdvance = m_dAdv ;
|
|
vtMove += Vector3d( ( dAdvance * dScaX + m_dAddAdvance), 0, 0) ;
|
|
if ( vtMove.x > dMaxW)
|
|
dMaxW = vtMove.x ;
|
|
}
|
|
|
|
// sistemazioni per la posizione del punto di inserimento
|
|
Vector3d vtIpMove = GetTextInsertPointMove( dMaxW, dHCap, dMinH, nInsPos) ;
|
|
for ( const auto& pCrv : lstPC)
|
|
pCrv->Translate( vtIpMove) ;
|
|
|
|
// assegno l'estrusione
|
|
for ( const auto& pCrv : lstPC)
|
|
pCrv->SetExtrusion( Z_AX) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::ApproxWithLines( const string& sText, int nInsPos, double dLinTol, double dAngTolDeg,
|
|
POLYLINELIST& lstPL) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// creo un iteratore
|
|
GdbIterator iIter( m_pGDB) ;
|
|
|
|
// controllo valore tolleranza lineare
|
|
if ( dLinTol > FNT_MAX_LINTOL_TO_H * m_dHeight)
|
|
dLinTol = max( FNT_MAX_LINTOL_TO_H * m_dHeight, EPS_SMALL) ;
|
|
|
|
// calcolo i fattori di scala
|
|
double dScaY = m_dHeight / m_dHCap ;
|
|
double dScaX = dScaY * m_dRatio ;
|
|
double dScaZ = 1 ;
|
|
|
|
// recupero altezza maiuscole e interlinea
|
|
double dHCap = m_dHeight ;
|
|
double dH = m_dH * m_dHeight / m_dHCap ;
|
|
|
|
// converto i byte della stringa in codici carattere
|
|
UINTVECTOR vCode ;
|
|
GetCodePoints( sText, vCode) ;
|
|
|
|
// scandisco i codici
|
|
double dMaxW = 0 ;
|
|
double dMinH = 0 ;
|
|
Vector3d vtMove ;
|
|
for ( unsigned int i = 0 ; i < vCode.size() ; ++ i) {
|
|
// verifico se comando di a capo
|
|
int nLbLen ;
|
|
if ( IsLineBreak( vCode, i, nLbLen)) {
|
|
vtMove.Set( 0, vtMove.y - dH, 0) ;
|
|
if ( vtMove.y < dMinH)
|
|
dMinH = vtMove.y ;
|
|
i += nLbLen ;
|
|
continue ;
|
|
}
|
|
// verifico esistenza del gruppo del carattere
|
|
int nGroup = vCode[i] ;
|
|
if ( nGroup < NFE_MIN_CHAR || m_pGDB->GetGdbType( nGroup) != GDB_TY_GROUP)
|
|
nGroup = NFE_ERR_CHAR ;
|
|
// ciclo sulle entità geometriche del carattere
|
|
bool bIter = iIter.GoToFirstInGroup( nGroup) ;
|
|
while ( bIter) {
|
|
const ICurve* pCrv = GetCurve( iIter.GetGeoObj()) ;
|
|
if ( pCrv != nullptr) {
|
|
// copia temporanea della curva (trasformando eventuali archi in CurveBezier)
|
|
PtrOwner<ICurve> pCrvNew( CurveToNoArcsCurve( pCrv)) ;
|
|
if ( IsNull( pCrvNew))
|
|
return false ;
|
|
// eseguo trasformazioni
|
|
if ( m_bItalic)
|
|
pCrvNew->Shear( ORIG, Y_AX, X_AX, m_dItalicShearCoeff) ;
|
|
pCrvNew->Scale( GLOB_FRM, dScaX, dScaY, dScaZ) ;
|
|
pCrvNew->Translate( vtMove) ;
|
|
// approssimo con linee
|
|
lstPL.emplace_back() ;
|
|
pCrvNew->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_STD, lstPL.back()) ;
|
|
}
|
|
bIter = iIter.GoToNext() ;
|
|
}
|
|
// recupero lo spostamento per il prossimo carattere
|
|
double dAdvance ;
|
|
if ( ! m_pGDB->GetInfo( nGroup, NFE_LEN_CHAR, dAdvance))
|
|
dAdvance = m_dAdv ;
|
|
vtMove += Vector3d( ( dAdvance * dScaX + m_dAddAdvance), 0, 0) ;
|
|
if ( vtMove.x > dMaxW)
|
|
dMaxW = vtMove.x ;
|
|
}
|
|
|
|
// sistemazioni per la posizione del punto di inserimento
|
|
Vector3d vtIpMove = GetTextInsertPointMove( dMaxW, dHCap, dMinH, nInsPos) ;
|
|
for ( auto& PL : lstPL)
|
|
PL.Translate( vtIpMove) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::ApproxWithArcs( const string& sText, int nInsPos, double dLinTol, double dAngTolDeg,
|
|
POLYARCLIST& lstPA) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// creo un iteratore
|
|
GdbIterator iIter( m_pGDB) ;
|
|
|
|
// controllo valore tolleranza lineare
|
|
if ( dLinTol > FNT_MAX_LINTOL_TO_H * m_dHeight)
|
|
dLinTol = max( FNT_MAX_LINTOL_TO_H * m_dHeight, EPS_SMALL) ;
|
|
|
|
// calcolo i fattori di scala
|
|
double dScaY = m_dHeight / m_dHCap ;
|
|
double dScaX = dScaY * m_dRatio ;
|
|
double dScaZ = 1 ;
|
|
|
|
// recupero altezza maiuscole e interlinea
|
|
double dHCap = m_dHeight ;
|
|
double dH = m_dH * m_dHeight / m_dHCap ;
|
|
|
|
// converto i byte della stringa in codici carattere
|
|
UINTVECTOR vCode ;
|
|
GetCodePoints( sText, vCode) ;
|
|
|
|
// scandisco i codici
|
|
double dMaxW = 0 ;
|
|
double dMinH = 0 ;
|
|
Vector3d vtMove ;
|
|
for ( unsigned int i = 0 ; i < vCode.size() ; ++ i) {
|
|
// verifico se comando di a capo
|
|
int nLbLen ;
|
|
if ( IsLineBreak( vCode, i, nLbLen)) {
|
|
vtMove.Set( 0, vtMove.y - dH, 0) ;
|
|
if ( vtMove.y < dMinH)
|
|
dMinH = vtMove.y ;
|
|
i += nLbLen ;
|
|
continue ;
|
|
}
|
|
// verifico esistenza del gruppo del carattere
|
|
int nGroup = vCode[i] ;
|
|
if ( nGroup < NFE_MIN_CHAR || m_pGDB->GetGdbType( nGroup) != GDB_TY_GROUP)
|
|
nGroup = NFE_ERR_CHAR ;
|
|
// ciclo sulle entità geometriche del carattere
|
|
bool bIter = iIter.GoToFirstInGroup( nGroup) ;
|
|
while ( bIter) {
|
|
const ICurve* pCrv = GetCurve( iIter.GetGeoObj()) ;
|
|
if ( pCrv != nullptr) {
|
|
// copia temporanea della curva (trasformando eventuali archi in CurveBezier)
|
|
PtrOwner<ICurve> pCrvNew( CurveToNoArcsCurve( pCrv)) ;
|
|
if ( IsNull( pCrvNew))
|
|
return false ;
|
|
// eseguo trasformazioni
|
|
if ( m_bItalic)
|
|
pCrvNew->Shear( ORIG, Y_AX, X_AX, m_dItalicShearCoeff) ;
|
|
pCrvNew->Scale( GLOB_FRM, dScaX, dScaY, dScaZ) ;
|
|
pCrvNew->Translate( vtMove) ;
|
|
// approssimo con archi
|
|
lstPA.emplace_back() ;
|
|
pCrv->ApproxWithArcs( dLinTol, dAngTolDeg, lstPA.back()) ;
|
|
}
|
|
bIter = iIter.GoToNext() ;
|
|
}
|
|
// recupero lo spostamento per il prossimo carattere
|
|
double dAdvance ;
|
|
if ( ! m_pGDB->GetInfo( nGroup, NFE_LEN_CHAR, dAdvance))
|
|
dAdvance = m_dAdv ;
|
|
vtMove += Vector3d( ( dAdvance * dScaX + m_dAddAdvance), 0, 0) ;
|
|
if ( vtMove.x > dMaxW)
|
|
dMaxW = vtMove.x ;
|
|
}
|
|
|
|
// sistemazioni per la posizione del punto di inserimento
|
|
Vector3d vtIpMove = GetTextInsertPointMove( dMaxW, dHCap, dMinH, nInsPos) ;
|
|
for ( auto& PA : lstPA)
|
|
PA.Translate( vtIpMove) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
NfeFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECTOR& vLine) const
|
|
{
|
|
// verifico esistenza font corrente
|
|
if ( m_pGDB == nullptr || m_sFont.empty())
|
|
return false ;
|
|
|
|
// calcolo i fattori di scala
|
|
double dScaY = m_dHeight / m_dHCap ;
|
|
double dScaX = dScaY * m_dRatio ;
|
|
|
|
// recupero altezza maiuscole e interlinea
|
|
double dHCap = m_dHeight ;
|
|
double dH = m_dH * m_dHeight / m_dHCap ;
|
|
|
|
// converto i byte della stringa in codici carattere
|
|
UINTVECTOR vCode ;
|
|
GetCodePoints( sText, vCode) ;
|
|
|
|
// scandisco i codici
|
|
double dMaxW = 0 ;
|
|
double dMinH = 0 ;
|
|
Vector3d vtMove ;
|
|
UINTVECTOR vTmpCode ;
|
|
for ( unsigned int i = 0 ; i < vCode.size() ; ++ i) {
|
|
// verifico se comando di a capo
|
|
int nLbLen ;
|
|
if ( IsLineBreak( vCode, i, nLbLen)) {
|
|
// salvo la linea, se contiene qualcosa
|
|
if ( ! vTmpCode.empty()) {
|
|
string sLine ;
|
|
SetCodePoints( vTmpCode, sLine) ;
|
|
vLine.push_back( sLine) ;
|
|
vTmpCode.clear() ;
|
|
vPt.emplace_back( 0, vtMove.y, 0) ;
|
|
}
|
|
// sistemo la posizione
|
|
vtMove.Set( 0, vtMove.y - dH, 0) ;
|
|
if ( vtMove.y < dMinH)
|
|
dMinH = vtMove.y ;
|
|
// passo oltre
|
|
i += nLbLen ;
|
|
continue ;
|
|
}
|
|
// salvo il codice
|
|
vTmpCode.push_back( vCode[i]) ;
|
|
// verifico esistenza del gruppo del carattere
|
|
int nGroup = vCode[i] ;
|
|
if ( nGroup < NFE_MIN_CHAR || m_pGDB->GetGdbType( nGroup) != GDB_TY_GROUP)
|
|
nGroup = NFE_ERR_CHAR ;
|
|
// recupero lo spostamento per il prossimo carattere
|
|
double dAdvance ;
|
|
if ( ! m_pGDB->GetInfo( nGroup, NFE_LEN_CHAR, dAdvance))
|
|
dAdvance = m_dAdv ;
|
|
vtMove += Vector3d( ( dAdvance * dScaX + m_dAddAdvance), 0, 0) ;
|
|
if ( vtMove.x > dMaxW)
|
|
dMaxW = vtMove.x ;
|
|
}
|
|
// salvo eventuale ultima linea
|
|
if ( ! vTmpCode.empty()) {
|
|
string sLine ;
|
|
SetCodePoints( vTmpCode, sLine) ;
|
|
vLine.push_back( sLine) ;
|
|
vTmpCode.clear() ;
|
|
vPt.emplace_back( 0, vtMove.y, 0) ;
|
|
}
|
|
|
|
// sistemazioni per la posizione del punto di inserimento
|
|
Vector3d vtIpMove = GetTextInsertPointMove( dMaxW, dHCap, dMinH, nInsPos) ;
|
|
for ( auto& Pt : vPt)
|
|
Pt.Translate( vtIpMove) ;
|
|
|
|
return true ;
|
|
}
|