2016-03-19 06:57:51 +13:00
# include "tgl.h"
# include "tvectorgl.h"
# include "tregion.h"
# include "tregionprop.h"
# include "tstrokeutil.h"
# include "tvectorrenderdata.h"
# include "tvectorimage.h"
# include "tpalette.h"
# include "tcolorfunctions.h"
# include "tsimplecolorstyles.h"
# include "tthreadmessage.h"
# include "tstrokeprop.h"
# include "tconvert.h"
# include "tcurves.h"
# include "tstrokeoutline.h"
2016-04-15 17:11:23 +12:00
# ifndef _WIN32
2016-03-19 06:57:51 +13:00
# define CALLBACK
# endif
# ifndef checkErrorsByGL
# define checkErrorsByGL \
{ \
GLenum err = glGetError ( ) ; \
assert ( err ! = GL_INVALID_ENUM ) ; \
assert ( err ! = GL_INVALID_VALUE ) ; \
assert ( err ! = GL_INVALID_OPERATION ) ; \
assert ( err ! = GL_STACK_OVERFLOW ) ; \
assert ( err ! = GL_STACK_UNDERFLOW ) ; \
assert ( err ! = GL_OUT_OF_MEMORY ) ; \
assert ( err = = GL_NO_ERROR ) ; \
}
# endif
# undef checkErrorsByGL
# define checkErrorsByGL
using namespace std ;
//-----------------------------------------------------------------------------
/*
DV_EXPORT_API void mylog ( std : : string s )
{
static TThread : : Mutex mutex ;
QMutexLocker sl ( mutex ) ;
std : : ofstream os ( " C: \\ gmt \\ buttami \\ bu.txt " , std : : ios : : app ) ;
LARGE_INTEGER ticksPerSecond ;
LARGE_INTEGER tick ;
static LARGE_INTEGER firstTick ;
static bool firstTime = true ;
long dt = 0 ;
QueryPerformanceFrequency ( & ticksPerSecond ) ;
QueryPerformanceCounter ( & tick ) ;
if ( firstTime ) { firstTick = tick ; firstTime = false ; }
else
{
dt = ( long ) ( 1000000 * ( tick . QuadPart - firstTick . QuadPart ) / ticksPerSecond . QuadPart ) ;
}
os < < dt < < " : " < < s < < std : : endl ;
}
*/
//=============================================================================
# ifdef _DEBUG
bool checkQuadraticDistance ( TStroke * stroke , bool checkThickness )
{
UINT i , qCount = stroke - > getChunkCount ( ) ;
const TThickQuadratic * q ;
TThickPoint p1 , p2 , p3 ;
//se i punti coincidono e' una stroke puntiforme ed e' ammessa
if ( qCount = = 1 )
return true ;
for ( i = 0 ; i ! = qCount ; i + + ) {
q = stroke - > getChunk ( i ) ;
p1 = q - > getThickP0 ( ) ;
p2 = q - > getThickP1 ( ) ;
p3 = q - > getThickP2 ( ) ;
if ( areAlmostEqual ( p1 . x , p2 . x ) & & areAlmostEqual ( p2 . x , p3 . x ) & &
areAlmostEqual ( p1 . y , p2 . y ) & & areAlmostEqual ( p2 . y , p3 . y ) & &
( ! checkThickness | |
( areAlmostEqual ( p1 . thick , p2 . thick ) & & areAlmostEqual ( p2 . thick , p3 . thick ) ) ) )
return false ;
}
return true ;
}
//-----------------------------------------------------------------------------
void drawControlPoints ( const TVectorRenderData & rd , TStroke * stroke , double pixelSize , bool allPoints = true )
{
int i ;
TPointD p ;
glPushMatrix ( ) ;
tglMultMatrix ( rd . m_aff ) ;
glPointSize ( 2.0 ) ;
glBegin ( GL_POINTS ) ;
if ( allPoints ) {
int n = stroke - > getControlPointCount ( ) ;
for ( i = 0 ; i < n ; + + i ) {
p = stroke - > getControlPoint ( i ) ;
glColor3d ( ( i + 1 ) & 1 , i & 1 , 0.0 ) ;
glVertex2d ( p . x , p . y ) ;
}
} else {
int n = stroke - > getChunkCount ( ) ;
for ( i = 0 ; i < n ; + + i ) {
const TThickQuadratic * chunk = stroke - > getChunk ( i ) ;
p = chunk - > getP0 ( ) ;
glColor3d ( 1.0 , 0.0 , 0.0 ) ;
glVertex2d ( p . x , p . y ) ;
}
const TThickQuadratic * chunk = stroke - > getChunk ( n - 1 ) ;
glColor3d ( 1.0 , 0.0 , 0.0 ) ;
p = chunk - > getP2 ( ) ;
glVertex2d ( p . x , p . y ) ;
}
glEnd ( ) ;
glPopMatrix ( ) ;
}
# endif
//=============================================================================
/*TPixel TransparencyCheckBlackBgInk = TPixel(255,255,255);
TPixel TransparencyCheckWhiteBgInk = TPixel ( 0 , 0 , 0 ) ;
TPixel TransparencyCheckPaint = TPixel ( 127 , 127 , 127 ) ; */
static int Index = 0 ;
void tglDraw ( const TVectorRenderData & rd , TRegion * r , bool pushAttribs )
{
checkErrorsByGL ;
assert ( r ) ;
checkErrorsByGL ;
if ( ! r )
return ;
bool alphaChannel = rd . m_alphaChannel ;
checkErrorsByGL ;
int j = 0 ;
bool visible = false ;
int colorCount = 0 ;
TColorStyleP style ;
if ( rd . m_paintCheckEnabled & & r - > getStyle ( ) = = rd . m_colorCheckIndex ) {
static TSolidColorStyle * redColor = new TSolidColorStyle ( ) ;
redColor - > addRef ( ) ;
redColor - > setMainColor ( TPixel : : Red ) ;
style = redColor ;
} else if ( rd . m_tcheckEnabled ) {
static TSolidColorStyle * color = new TSolidColorStyle ( ) ;
color - > addRef ( ) ;
color - > setMainColor ( rd . m_tCheckPaint ) ;
style = color ;
} else
style = rd . m_palette - > getStyle ( r - > getStyle ( ) ) ;
colorCount = style - > getColorParamCount ( ) ;
if ( colorCount = = 0 ) { //for example texture
visible = true ;
} else {
visible = false ;
for ( j = 0 ; j < colorCount & & ! visible ; j + + ) {
TPixel32 color = style - > getColorParamValue ( j ) ;
if ( rd . m_cf )
color = ( * ( rd . m_cf ) ) ( color ) ;
if ( color . m ! = 0 )
visible = true ;
}
}
if ( visible ) {
TRegionProp * prop = r - > getProp ( /*rd.m_palette*/ ) ;
///questo codice satva dentro tregion::getprop/////
int styleId = r - > getStyle ( ) ;
if ( styleId ) {
// TColorStyle * style = rd.m_palette->getStyle(styleId);
if ( ! style - > isRegionStyle ( ) | | style - > isEnabled ( ) = = false ) {
prop = 0 ;
} else {
//Warning: The same remark of stroke props holds here.
if ( ! prop | | style . getPointer ( ) ! = prop - > getColorStyle ( ) ) {
r - > setProp ( style - > makeRegionProp ( r ) ) ;
prop = r - > getProp ( ) ;
}
}
}
////// draw
if ( prop ) {
if ( pushAttribs )
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
tglEnableLineSmooth ( true ) ;
//#define DRAW_EDGE_NUMBERS
# ifdef DRAW_EDGE_NUMBERS
glPushMatrix ( ) ;
tglMultMatrix ( rd . m_aff ) ;
switch ( Index % 7 ) {
case 0 :
tglColor ( TPixel : : Red ) ;
break ;
case 1 :
tglColor ( TPixel : : Green ) ;
break ;
case 2 :
tglColor ( TPixel : : Blue ) ;
break ;
case 3 :
tglColor ( TPixel : : Cyan ) ;
break ;
case 4 :
tglColor ( TPixel : : Magenta ) ;
break ;
case 5 :
tglColor ( TPixel : : Yellow ) ;
break ;
case 6 :
tglColor ( TPixel : : Black ) ;
break ;
default :
tglColor ( TPixel : : Red ) ;
break ;
}
Index + + ;
if ( rIndex = = 2 ) {
double y = r - > getEdge ( 0 ) - > m_s - > getThickPoint ( ( r - > getEdge ( 0 ) - > m_w0 + r - > getEdge ( 0 ) - > m_w1 ) / 2.0 ) . y ;
tglDrawSegment ( TPointD ( - 1000 , y ) , TPointD ( 1000 , y ) ) ;
}
for ( int i = 0 ; i < ( int ) r - > getEdgeCount ( ) ; i + + ) {
TEdge * e = r - > getEdge ( i ) ;
TPointD p = e - > m_s - > getPoint ( 0.8 * e - > m_w0 + 0.2 * e - > m_w1 ) ;
if ( i = = 0 )
tglDrawText ( p , ( QString : : number ( rIndex ) + QString ( " -0 " ) ) . toStdString ( ) ) ;
else
tglDrawText ( p , QString : : number ( i ) . toStdString ( ) ) ;
if ( e - > m_index = = 3 ) {
tglColor ( TPixel : : Black ) ;
TStroke * s = e - > m_s ;
drawPoint ( s - > getChunk ( 0 ) - > getP0 ( ) , .3 ) ;
tglColor ( TPixel : : Red ) ;
tglDrawText ( s - > getChunk ( 0 ) - > getP0 ( ) , QString : : number ( 0 ) . toStdString ( ) ) ;
for ( int ii = 0 ; ii < s - > getChunkCount ( ) ; ii + + ) {
drawPoint ( s - > getChunk ( ii ) - > getP2 ( ) , .3 ) ;
if ( ii < s - > getChunkCount ( ) - 1 ) {
tglColor ( TPixel : : Red ) ;
tglDrawText ( s - > getChunk ( ii ) - > getP2 ( ) , QString : : number ( ii + 1 ) . toStdString ( ) ) ;
}
}
}
}
glPopMatrix ( ) ;
# endif
if ( alphaChannel ) {
GLboolean red , green , blue , alpha ;
tglGetColorMask ( red , green , blue , alpha ) ;
//Draw RGB channels
tglEnableBlending ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glColorMask ( red , green , blue , GL_FALSE ) ;
prop - > draw ( rd ) ;
//Draw Matte channel
tglEnableBlending ( GL_ONE , GL_ONE_MINUS_SRC_ALPHA ) ;
glColorMask ( GL_FALSE , GL_FALSE , GL_FALSE , alpha ) ;
prop - > draw ( rd ) ;
glColorMask ( red , green , blue , alpha ) ;
} else {
//pezza: in render, le aree fillate dei custom styles sparivano.
if ( ! rd . m_isOfflineRender | | ! rd . m_isImagePattern )
tglRgbOnlyColorMask ( ) ; //RGB components only
prop - > draw ( rd ) ;
}
if ( pushAttribs )
glPopAttrib ( ) ;
}
}
for ( UINT i = 0 ; i < r - > getSubregionCount ( ) ; i + + )
tglDraw ( rd , r - > getSubregion ( i ) , pushAttribs ) ;
checkErrorsByGL ;
}
//-----------------------------------------------------------------------------
void tglDrawMask ( const TVectorRenderData & rd1 , const TVectorImage * vim )
{
UINT i ;
assert ( vim ) ;
if ( ! vim )
return ;
TVectorRenderData rd ( rd1 ) ;
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
if ( ! rd . m_palette ) {
TPalette * vPalette = vim - > getPalette ( ) ;
assert ( vPalette ) ;
rd . m_palette = vPalette ;
}
for ( i = 0 ; i < vim - > getRegionCount ( ) ; i + + )
tglDraw ( rd , vim - > getRegion ( i ) , false ) ;
glPopAttrib ( ) ;
}
//-----------------------------------------------------------------------------
namespace
{
bool isOThick ( const TStroke * s )
{
int i ;
for ( i = 0 ; i < s - > getControlPointCount ( ) ; i + + )
if ( s - > getControlPoint ( i ) . thick ! = 0 )
return false ;
return true ;
}
}
void tglDraw ( const TVectorRenderData & rd , const TStroke * s , bool pushAttribs )
{
assert ( s ) ;
if ( ! s )
return ;
TStrokeProp * prop = 0 ;
bool pushedAttribs = false ;
try {
TColorStyleP style ;
TStroke * stroke = const_cast < TStroke * > ( s ) ;
if ( rd . m_inkCheckEnabled & & s - > getStyle ( ) = = rd . m_colorCheckIndex ) {
static TSolidColorStyle * redColor = new TSolidColorStyle ( ) ;
redColor - > addRef ( ) ;
redColor - > setMainColor ( TPixel : : Red ) ;
style = redColor ;
} else if ( rd . m_tcheckEnabled ) {
static TSolidColorStyle * color = new TSolidColorStyle ( ) ;
color - > addRef ( ) ;
color - > setMainColor ( rd . m_tCheckInk ) ;
style = color ;
} else
style = rd . m_palette - > getStyle ( stroke - > getStyle ( ) ) ;
if ( ! rd . m_show0ThickStrokes & & isOThick ( s ) & & dynamic_cast < TSolidColorStyle * > ( style . getPointer ( ) ) // This is probably to exclude TCenterlineStrokeStyle-like styles
& & ! rd . m_tcheckEnabled ) // I wonder why this?
return ;
// const TStroke& stroke = *s; //serve???
assert ( rd . m_palette ) ;
prop = s - > getProp ( /*rd.m_palette*/ ) ;
/////questo codice stava dentro tstroke::getprop/////////
if ( prop )
prop - > getMutex ( ) - > lock ( ) ;
if ( ! style - > isStrokeStyle ( ) | | style - > isEnabled ( ) = = false ) {
if ( prop )
prop - > getMutex ( ) - > unlock ( ) ;
prop = 0 ;
} else {
//Warning: the following pointers check is conceptually wrong - we
//keep it because the props maintain SMART POINTER-like reference to
//the associated style. This prevents the style from being destroyed
//while still referenced by the prop.
if ( ! prop | | style . getPointer ( ) ! = prop - > getColorStyle ( ) ) {
if ( prop )
prop - > getMutex ( ) - > unlock ( ) ;
stroke - > setProp ( style - > makeStrokeProp ( stroke ) ) ;
prop = stroke - > getProp ( ) ;
if ( prop )
prop - > getMutex ( ) - > lock ( ) ;
}
}
//--------- draw ------------
if ( ! prop )
return ;
if ( pushAttribs )
glPushAttrib ( GL_ALL_ATTRIB_BITS ) , pushedAttribs = true ;
bool alphaChannel = rd . m_alphaChannel , antialias = rd . m_antiAliasing ;
TVectorImagePatternStrokeProp * aux = dynamic_cast < TVectorImagePatternStrokeProp * > ( prop ) ;
if ( aux ) //gli image pattern vettoriali tornano in questa funzione....non facendo il corpo dell'else'si evita di disegnarli due volte!
prop - > draw ( rd ) ;
else {
if ( antialias )
tglEnableLineSmooth ( true ) ;
else
tglEnableLineSmooth ( false ) ;
if ( alphaChannel ) {
GLboolean red , green , blue , alpha ;
tglGetColorMask ( red , green , blue , alpha ) ;
//Draw RGB channels
tglEnableBlending ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glColorMask ( red , green , blue , GL_FALSE ) ;
prop - > draw ( rd ) ;
//Draw Matte channel
tglEnableBlending ( GL_ONE , GL_ONE_MINUS_SRC_ALPHA ) ;
glColorMask ( GL_FALSE , GL_FALSE , GL_FALSE , alpha ) ;
prop - > draw ( rd ) ;
glColorMask ( red , green , blue , alpha ) ;
} else {
tglEnableBlending ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
prop - > draw ( rd ) ;
}
}
if ( pushAttribs )
glPopAttrib ( ) , pushedAttribs = false ;
prop - > getMutex ( ) - > unlock ( ) ;
//---------------------
} catch ( . . . ) {
if ( prop )
prop - > getMutex ( ) - > unlock ( ) ;
if ( pushedAttribs )
glPopAttrib ( ) ;
}
}
//------------------------------------------------------------------------------------
void tglDoDraw ( const TVectorRenderData & rd , TRegion * r )
{
bool visible = false ;
int colorCount = 0 ;
if ( ! r )
return ;
TColorStyleP style = rd . m_palette - > getStyle ( r - > getStyle ( ) ) ;
colorCount = style - > getColorParamCount ( ) ;
if ( colorCount = = 0 ) //for example texture
visible = true ;
else {
visible = false ;
for ( int j = 0 ; j < colorCount & & ! visible ; j + + ) {
TPixel32 color = style - > getColorParamValue ( j ) ;
if ( rd . m_cf )
color = ( * ( rd . m_cf ) ) ( color ) ;
if ( color . m ! = 0 )
visible = true ;
}
}
if ( visible )
tglDraw ( rd , r , false ) ;
else
for ( UINT j = 0 ; j < r - > getSubregionCount ( ) ; j + + )
tglDraw ( rd , r - > getSubregion ( j ) , false ) ;
}
//------------------------------------------------------------------------------------
void tglDoDraw ( const TVectorRenderData & rd , const TStroke * s )
{
bool visible = false ;
int colorCount = 0 ;
const TPalette * palette = rd . m_palette ;
int styleId = s - > getStyle ( ) ;
//assert(0<=styleId && styleId<stylesCount);
TColorStyleP style = palette - > getStyle ( styleId ) ;
assert ( style ) ;
colorCount = style - > getColorParamCount ( ) ;
if ( colorCount = = 0 )
visible = true ;
else {
visible = false ;
for ( int j = 0 ; j < style - > getColorParamCount ( ) & & ! visible ; j + + ) {
TPixel32 color = style - > getColorParamValue ( j ) ;
if ( rd . m_cf )
color = ( * ( rd . m_cf ) ) ( color ) ;
if ( color . m ! = 0 )
visible = true ;
}
}
# if DISEGNO_OUTLINE == 0
if ( visible )
# endif
tglDraw ( rd , s , false ) ;
# ifdef _DEBUG
//drawControlPoints(rd, vim->getStroke(i), sqrt(tglGetPixelSize2()), true);
//assert(checkQuadraticDistance(vim->getStroke(i),true));
# endif
}
//------------------------------------------------------------------------------------
namespace
{
void doDraw ( const TVectorImage * vim , const TVectorRenderData & _rd , bool drawEnteredGroup )
{
static TOnionFader * fade = new TOnionFader ( TPixel : : White , 0.5 ) ;
TVectorRenderData rd ( _rd ) ;
if ( ! rd . m_palette ) {
TPalette * vPalette = vim - > getPalette ( ) ;
rd . m_palette = vPalette ;
if ( ! vPalette )
return ;
}
if ( ! drawEnteredGroup & & ! rd . m_isIcon & & vim - > isInsideGroup ( ) > 0 )
rd . m_cf = fade ;
TVectorRenderData rdRegions = rd ;
/*if (rd.m_drawRegions && rd.m_isImagePattern)//gli image pattern hanno bisogno dell'antialiasig per le linee, ma sulle aree ci sarebbero un sacco di assert
rdRegions . m_alphaChannel = rdRegions . m_antiAliasing = false ; */
UINT strokeIndex = 0 ;
Index = 0 ;
while ( strokeIndex < vim - > getStrokeCount ( ) ) // ogni ciclo di while disegna un gruppo
{
int currStrokeIndex = strokeIndex ;
if ( ! rd . m_isIcon & & vim - > isInsideGroup ( ) > 0 & &
( ( drawEnteredGroup & & ! vim - > isEnteredGroupStroke ( strokeIndex ) ) | |
! drawEnteredGroup & & vim - > isEnteredGroupStroke ( strokeIndex ) ) ) {
while ( strokeIndex < vim - > getStrokeCount ( ) & & vim - > sameGroup ( strokeIndex , currStrokeIndex ) )
strokeIndex + + ;
continue ;
}
if ( rd . m_drawRegions )
for ( UINT regionIndex = 0 ; regionIndex < vim - > getRegionCount ( ) ; regionIndex + + )
if ( vim - > sameGroupStrokeAndRegion ( currStrokeIndex , regionIndex ) )
tglDoDraw ( rdRegions , vim - > getRegion ( regionIndex ) ) ;
while ( strokeIndex < vim - > getStrokeCount ( ) & & vim - > sameGroup ( strokeIndex , currStrokeIndex ) ) {
# if DISEGNO_OUTLINE == 1
CurrStrokeIndex = strokeIndex ;
CurrVimg = vim ;
# endif
tglDoDraw ( rd , vim - > getStroke ( strokeIndex ) ) ;
strokeIndex + + ;
}
}
}
}
//------------------------------------------------------------------------------------
void tglDraw ( const TVectorRenderData & rd , const TVectorImage * vim )
{
assert ( vim ) ;
if ( ! vim )
return ;
QMutexLocker sl ( vim - > getMutex ( ) ) ;
checkErrorsByGL ;
checkErrorsByGL ;
glPushAttrib ( GL_ALL_ATTRIB_BITS ) ;
//if(!rd.m_palette) rd.m_palette = vim->getPalette();
//mylog("tglDraw start; mutex=" + toString((unsigned long)&vim->getMutex()));
glEnable ( GL_ALPHA_TEST ) ;
glAlphaFunc ( GL_GREATER , 0 ) ;
doDraw ( vim , rd , false ) ;
if ( ! rd . m_isIcon & & vim - > isInsideGroup ( ) > 0 )
doDraw ( vim , rd , true ) ;
glDisable ( GL_ALPHA_TEST ) ;
glPopAttrib ( ) ;
# ifdef _DEBUG
vim - > drawAutocloses ( rd ) ;
# endif
checkErrorsByGL ;
//mylog("tglDraw stop");
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------