85 jfloat dash[], jint numdashes, 86 jfloat phase) 87 { 88 memset(pDasher, 0, sizeof(Dasher)); 89 PathConsumer_init(&this.consumer, 90 Dasher_MoveTo, 91 Dasher_LineTo, 92 Dasher_QuadTo, 93 Dasher_CurveTo, 94 Dasher_ClosePath, 95 Dasher_PathDone); 96 97 this.firstSegmentsBufferSIZE = 7; 98 this.firstSegmentsBuffer = new_float(this.firstSegmentsBufferSIZE); 99 this.firstSegidx = 0; 100 101 this.out = out; 102 Dasher_reset(pDasher, dash, numdashes, phase); 103 } 104 105 void Dasher_reset(Dasher *pDasher, jfloat dash[], jint ndashes, jfloat phase) { 106 jint sidx; 107 jfloat d; 108 109 if (phase < 0) { 110 phase = 0; 111 // throw new IllegalArgumentException("phase < 0 !"); 112 } 113 114 // Normalize so 0 <= phase < dash[0] 115 sidx = 0; 116 this.dashOn = JNI_TRUE; 117 while (phase >= (d = dash[sidx])) { 118 phase -= d; 119 sidx = (sidx + 1) % ndashes; 120 this.dashOn = !this.dashOn; 121 } 122 123 this.dash = dash; 124 this.numdashes = ndashes; 125 this.startPhase = this.phase = phase; 126 this.startDashOn = this.dashOn; 127 this.startIdx = sidx; 128 this.starting = JNI_TRUE; 129 } 130 131 void Dasher_destroy(Dasher *pDasher) { 132 free(pDasher->firstSegmentsBuffer); 133 pDasher->firstSegmentsBuffer = NULL; 134 pDasher->firstSegmentsBufferSIZE = 0; 135 } 136 137 static void emitSeg(PathConsumer *pDasher, jfloat buf[], jint off, jint type) { 138 switch (type) { 139 case 8: 140 this.out->curveTo(this.out, 141 buf[off+0], buf[off+1], | 85 jfloat dash[], jint numdashes, 86 jfloat phase) 87 { 88 memset(pDasher, 0, sizeof(Dasher)); 89 PathConsumer_init(&this.consumer, 90 Dasher_MoveTo, 91 Dasher_LineTo, 92 Dasher_QuadTo, 93 Dasher_CurveTo, 94 Dasher_ClosePath, 95 Dasher_PathDone); 96 97 this.firstSegmentsBufferSIZE = 7; 98 this.firstSegmentsBuffer = new_float(this.firstSegmentsBufferSIZE); 99 this.firstSegidx = 0; 100 101 this.out = out; 102 Dasher_reset(pDasher, dash, numdashes, phase); 103 } 104 105 #define MAX_CYCLES 16000000.0f 106 void Dasher_reset(Dasher *pDasher, jfloat dash[], jint ndashes, jfloat phase) { 107 jint sidx; 108 jfloat d, sum, cycles; 109 jint i; 110 111 // Normalize so 0 <= phase < dash[0] 112 sidx = 0; 113 this.dashOn = JNI_TRUE; 114 sum = 0.0f; 115 for (i = 0; i < ndashes; i++) { 116 sum += dash[i]; 117 } 118 cycles = phase / sum; 119 if (phase < 0) { 120 if (-cycles >= MAX_CYCLES) { 121 phase = 0; 122 } else { 123 jint fullcycles = (jint) floor(-cycles); 124 if ((fullcycles & ndashes & 1) != 0) { 125 this.dashOn = !this.dashOn; 126 } 127 phase += fullcycles * sum; 128 while (phase < 0) { 129 if (--sidx < 0) sidx = ndashes-1; 130 phase += dash[sidx]; 131 this.dashOn = !this.dashOn; 132 } 133 } 134 } else if (phase > 0) { 135 if (cycles >= MAX_CYCLES) { 136 phase = 0; 137 } else { 138 jint fullcycles = (jint) floor(cycles); 139 if ((fullcycles & ndashes & 1) != 0) { 140 this.dashOn = !this.dashOn; 141 } 142 phase -= fullcycles * sum; 143 while (phase >= (d = dash[sidx])) { 144 phase -= d; 145 sidx = (sidx + 1) % ndashes; 146 this.dashOn = !this.dashOn; 147 } 148 } 149 } 150 151 this.dash = dash; 152 this.numdashes = ndashes; 153 this.startPhase = this.phase = phase; 154 this.startDashOn = this.dashOn; 155 this.startIdx = sidx; 156 this.starting = JNI_TRUE; 157 } 158 159 void Dasher_destroy(Dasher *pDasher) { 160 free(pDasher->firstSegmentsBuffer); 161 pDasher->firstSegmentsBuffer = NULL; 162 pDasher->firstSegmentsBufferSIZE = 0; 163 } 164 165 static void emitSeg(PathConsumer *pDasher, jfloat buf[], jint off, jint type) { 166 switch (type) { 167 case 8: 168 this.out->curveTo(this.out, 169 buf[off+0], buf[off+1], |