const contours = require ( 'svg-path-contours' ) ; const triangle = require ( 'triangulate-contours' ) ; import { IPathResultItem } from '../../typings' ; import { combineA , combineHV , combineL } from './combine' ; import { complex } from './complex' ; import { getRel } from './translate' ; const hasBrother = ( subPath , index ) => { return index > 1 || index < subPath . length - 1 ; } ; const checkHV = ( subPath , index , hasStrokeCap ) => { if ( ! hasStrokeCap || hasBrother ( subPath , index ) ) { subPath . splice ( index , 1 ) ; } else { subPath [ index ] . type = 'z' ; } } ; const checkQ = ( pathItem , subPath , index , hasStrokeCap ) => { const prevItem = subPath [ index - 1 ] ; const complexItem = complex ( pathItem , prevItem ) ; const relVal = getRel ( complexItem ) ; let sameLine = true ; if ( relVal [ 1 ] !== 0 && relVal [ 0 ] !== 0 ) { sameLine = Math . atan2 ( relVal [ 1 ] , relVal [ 0 ] ) === Math . atan2 ( relVal [ 3 ] , relVal [ 2 ] ) ; } const pointsIsSort = ( ( relVal [ 0 ] >= 0 === relVal [ 2 ] >= 0 || relVal [ 0 ] <= 0 === relVal [ 2 ] <= 0 ) && ( relVal [ 1 ] >= 0 === relVal [ 3 ] >= 0 || relVal [ 1 ] <= 0 === relVal [ 3 ] <= 0 ) && Math . abs ( relVal [ 2 ] ) >= Math . abs ( relVal [ 0 ] ) && Math . abs ( relVal [ 3 ] ) >= Math . abs ( relVal [ 1 ] ) ) ; if ( sameLine && pointsIsSort ) { if ( relVal . every ( s => s === 0 ) ) { if ( ! hasStrokeCap || hasBrother ( subPath , index ) ) { subPath . splice ( index , 1 ) ; } else { pathItem . type = 'z' ; } return ; } if ( ! 'qt' . includes ( prevItem . type . toLowerCase ( ) ) && ( index === subPath . length - 1 || subPath [ index + 1 ] . type . toLowerCase ( ) !== 't' ) ) { pathItem . type = complexItem . type === 'q' ? 'l' : 'L' ; pathItem . val = complexItem . val . slice ( 2 ) ; } } } ; const checkC = ( pathItem , subPath , index , hasStrokeCap ) => { const prevItem = subPath [ index - 1 ] ; const complexItem = complex ( pathItem , prevItem ) ; const relVal = getRel ( complexItem ) ; let sameLine = true ; let arc = NaN ; for ( let i = 0 ; i < 6 ; i += 2 ) { if ( relVal [ i ] === 0 && relVal [ i + 1 ] === 0 ) { continue ; } if ( isNaN ( arc ) ) { arc = Math . atan2 ( relVal [ i + 1 ] , relVal [ i ] ) ; } else if ( arc !== Math . atan2 ( relVal [ i + 1 ] , relVal [ i ] ) ) { sameLine = false ; break ; } } const pointsIsSort = ( ( relVal [ 0 ] >= 0 === relVal [ 2 ] >= 0 || relVal [ 0 ] <= 0 === relVal [ 2 ] <= 0 ) && ( relVal [ 1 ] >= 0 === relVal [ 3 ] >= 0 || relVal [ 1 ] <= 0 === relVal [ 3 ] <= 0 ) && ( relVal [ 2 ] >= 0 === relVal [ 4 ] >= 0 || relVal [ 2 ] <= 0 === relVal [ 4 ] <= 0 ) && ( relVal [ 3 ] >= 0 === relVal [ 5 ] >= 0 || relVal [ 3 ] <= 0 === relVal [ 5 ] <= 0 ) && Math . abs ( relVal [ 2 ] ) >= Math . abs ( relVal [ 0 ] ) && Math . abs ( relVal [ 3 ] ) >= Math . abs ( relVal [ 1 ] ) && Math . abs ( relVal [ 4 ] ) >= Math . abs ( relVal [ 2 ] ) && Math . abs ( relVal [ 5 ] ) >= Math . abs ( relVal [ 3 ] ) ) ; if ( sameLine && pointsIsSort ) { if ( relVal . every ( s => s === 0 ) ) { if ( ! hasStrokeCap || hasBrother ( subPath , index ) ) { subPath . splice ( index , 1 ) ; } else { pathItem . type = 'z' ; } return ; } if ( ! 'cs' . includes ( prevItem . type . toLowerCase ( ) ) && ( index === subPath . length - 1 || subPath [ index + 1 ] . type . toLowerCase ( ) !== 's' ) ) { pathItem . type = complexItem . type === 'c' ? 'l' : 'L' ; pathItem . val = complexItem . val . slice ( 4 ) ; } } } ; export const checkSubPath = ( pathResult , hasStroke , hasStrokeCap , sizeDigit , angelDigit ) => { const result = [ ] ; pathResult . forEach ( subPath => { for ( let j = subPath . length ; j -- ; ) { const pathItem = subPath [ j ] ; switch ( pathItem . type ) { case 'm' : pathItem . type = 'M' ; pathItem . val [ 0 ] += subPath [ 0 ] . from [ 0 ] ; pathItem . val [ 1 ] += subPath [ 0 ] . from [ 1 ] ; break ; case 'z' : if ( ! hasStrokeCap && subPath [ j - 1 ] . type . toLowerCase ( ) === 'm' ) { subPath . splice ( j , 1 ) ; } break ; case 'h' : case 'v' : if ( pathItem . val [ 0 ] === 0 ) { checkHV ( subPath , j , hasStrokeCap ) ; } break ; case 't' : case 'T' : checkQ ( pathItem , subPath , j , hasStrokeCap ) ; break ; case 'q' : case 'Q' : checkQ ( pathItem , subPath , j , hasStrokeCap ) ; break ; case 's' : case 'S' : checkC ( pathItem , subPath , j , hasStrokeCap ) ; break ; case 'c' : case 'C' : checkC ( pathItem , subPath , j , hasStrokeCap ) ; break ; default : break ; } } } ) ; for ( let i = pathResult . length ; i -- ; ) { const subPath = pathResult [ i ] ; if ( ! hasStroke ) { try { const shapes = triangle ( contours ( subPath . map ( item => [ item . type , ... item . val ] ) ) ) ; if ( ! shapes . cells . length ) { continue ; } } catch { } } for ( let j = subPath . length ; j -- ; ) { const pathItem = subPath [ j ] ; switch ( pathItem . type . toLowerCase ( ) ) { case 'h' : case 'v' : combineHV ( subPath , pathItem , j ) ; break ; case 'l' : combineL ( subPath , pathItem , j , angelDigit ) ; break ; case 'a' : combineA ( subPath , pathItem , j , angelDigit ) ; break ; default : break ; } } if ( subPath . length > 1 ) { result . unshift ( subPath ) ; } } return result ; } ;