/* * We hit the end of a map (rect or a new output) * */ static int outputs_end_map_cb(void *params_) { struct outputs_json_params *params = (struct outputs_json_params *)params_; if (params->in_rect) { params->in_rect = false; /* Ignore the end of a rect */ return 1; } /* See if we actually handle that output */ if (config.num_outputs > 0) { bool handle_output = false; for (int c = 0; c < config.num_outputs; c++) { if (strcasecmp(params->outputs_walk->name, config.outputs[c]) == 0 || (strcasecmp(config.outputs[c], "primary") == 0 && params->outputs_walk->primary)) { handle_output = true; break; } } if (!handle_output) { DLOG("Ignoring output \"%s\", not configured to handle it.\n", params->outputs_walk->name); clear_output(params->outputs_walk); FREE(params->outputs_walk); FREE(params->cur_key); return 1; } } i3_output *target = get_output_by_name(params->outputs_walk->name); if (target == NULL) { SLIST_INSERT_HEAD(outputs, params->outputs_walk, slist); } else { target->active = params->outputs_walk->active; target->primary = params->outputs_walk->primary; target->ws = params->outputs_walk->ws; target->rect = params->outputs_walk->rect; clear_output(params->outputs_walk); FREE(params->outputs_walk); } return 1; }
int main() { //set pin to output p.p_addr = GPIO_BASE_ADDR; map_gpio(&p); set_as_input(&p, 4); //set_as_output(&p, 4); set_output(&p, 4, 0); clear_output(&p, 4); read_pin(&p, 4); return 0; }
/* * free() all outputs data structures. * */ void free_outputs(void) { free_workspaces(); i3_output *outputs_walk; if (outputs == NULL) { return; } SLIST_FOREACH(outputs_walk, outputs, slist) { destroy_window(outputs_walk); if (outputs_walk->trayclients != NULL && !TAILQ_EMPTY(outputs_walk->trayclients)) { FREE_TAILQ(outputs_walk->trayclients, trayclient); } clear_output(outputs_walk); }
/*Begins threading the program to search. After creating * threads, waits for all threads to finish.*/ void begin_threading() { pthread_t threads[NT]; clear_output(); int i = 0, rc; for (i = 0; i < NT; i++) { if (rc = pthread_create(&threads[i], NULL, &search_slice, (void *)(intptr_t)i)) { fprintf(stderr, "return from pthread_create() is %d\n", rc); exit(-1); } } for (i = 0; i < NT; i++) { pthread_join(threads[i], NULL); } }
void PICLANG_next() { picos_size_t command; picos_size_t a,b,c;// parameters, can be shared picos_signed_t siga;// a, but signed. signed char sch1;// signed char parameters char ch1;// char parameter static bit flag1; extern char ARG_buffer[ARG_SIZE]; if(curr_process.page_size == 0) return; if(picos_processes[picos_curr_process].expires == 0) { if((curr_process.bitmap & PICLANG_BLOCKING_CALL) == 0 || PICLANG_debug == true)// Check for blocking call { PICLANG_save(PICLANG_SUSPENDED); return; } } if(picos_processes[picos_curr_process].signal_sent != PICOS_NUM_SIGNALS) { if(signal_valid_id(picos_processes[picos_curr_process].signal_sent) == false) { PICLANG_exception(THREAD_INVALID_SIGNAL); return; } curr_process.pc = signals[picos_processes[picos_curr_process].signal_sent].sig_action_addr; signal_free(picos_processes[picos_curr_process].signal_sent); picos_processes[picos_curr_process].signal_sent = PICOS_NUM_SIGNALS; } command = PICLANG_get_next_word(); if(curr_process.status != PICLANG_SUCCESS) return; if(PICLANG_debug == true) PICLANG_debug_out(command); switch(command) { case PICLANG_UMINUS: { picos_signed_t inv = (picos_signed_t)PICLANG_pop(); PICLANG_pushl(-inv); break; } case PICLANG_ADD: PICLANG_pushl(PICLANG_pop() + PICLANG_pop()); PICLANG_update_arith_status(); break; case PICLANG_MOD:case PICLANG_DIV: { // a/b --> c rem a b = PICLANG_pop(); a = PICLANG_pop(); c = 0; while(a >= b) { a -= b; c++; } if(command == PICLANG_MOD) PICLANG_pushl(a); else PICLANG_pushl(c); PICLANG_update_arith_status(); break; } case PICLANG_SUB: { b = PICLANG_pop(); a = PICLANG_pop(); PICLANG_pushl(a - b); PICLANG_update_arith_status(); break; } case PICLANG_MULT: a = PICLANG_pop(); b = PICLANG_pop(); c = a*b; PICLANG_pushl(c); PICLANG_update_arith_status(); break; case PICLANG_PUSHL: a = PICLANG_get_next_word(); PICLANG_pushl(a); break; case PICLANG_PUSH: { a = PICLANG_get_next_word(); b = PAGE_get(a,picos_curr_process); if(error_code != SUCCESS) PICLANG_exception(error_code); else PICLANG_pushl(b); break; } case PICLANG_DROP: PICLANG_pop(); break; case PICLANG_SWAP: a = PICLANG_pop(); b = PICLANG_pop(); PICLANG_pushl(a); PICLANG_pushl(b); break; case PICLANG_POP: { a = PICLANG_get_next_word(); b = PICLANG_pop(); PAGE_set(a,b,picos_curr_process); break; } case PICLANG_ARGC: PICLANG_pushl(picos_processes[picos_curr_process].nargs); break; case PICLANG_ARGV: { a = PICLANG_pop(); sch1 = ARG_get(a); if(sch1 < 0) { PICLANG_exception(PICLANG_INVALID_PARAMETER); break; } b = (picos_size_t)sch1; PICLANG_pushl(b); break; } case PICLANG_PRINT: { a = PICLANG_pop(); putch(a); IO_flush(); break; } case PICLANG_DEREF: { a = PICLANG_pop();// array index b = PICLANG_pop();// array starting address PICLANG_next_dereference(b+a,command); break; } case PICLANG_BSL: case PICLANG_BSR:// bit shifts { a /*shift_amount*/ = PICLANG_pop(); b /*val*/ = PICLANG_pop(); if(command == PICLANG_BSL) b <<= a; else b >>= a; PICLANG_pushl(b); PICLANG_update_arith_status(); break; } case PICLANG_FPUTD: { char hex_val[PICOS_SIZE_T_DECIMAL_DIGITS];//ch1 = index dec_to_word(hex_val,PICLANG_pop()); ch1 = 0; flag1 = false; for(;ch1 < 5;ch1++) { if(flag1 == true || hex_val[ch1] != 0x30) { SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER+PICLANG_file_buffer_index++,&hex_val[ch1],sizeof(char)); flag1 = true; } if(PICLANG_file_buffer_index >= FS_BUFFER_SIZE) { picfs_dump(picos_processes[picos_curr_process].program_file); SRAM_write(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE); memset((char*)picfs_buffer,0,FS_BUFFER_SIZE); SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE); SRAM_read(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE); PICLANG_file_buffer_index = 0; } } if(flag1 == false) { ch1 = '0'; SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER+PICLANG_file_buffer_index++,&ch1,sizeof(char)); if(PICLANG_file_buffer_index >= FS_BUFFER_SIZE) { picfs_dump(picos_processes[picos_curr_process].program_file); SRAM_write(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE); memset((char*)picfs_buffer,0,FS_BUFFER_SIZE); SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE); SRAM_read(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE); PICLANG_file_buffer_index = 0; } } break; } case PICLANG_PWDIR: PICLANG_pushl(curr_dir); break; case PICLANG_MOUNT: a = PICLANG_pop();// device b = PICLANG_pop();// address of first byte if(picfs_mount((picos_addr_t)b,(picos_dev_t)a) != SUCCESS) curr_process.status = error_code; break; case PICLANG_CHDIR: { a = PICLANG_pop(); picfs_chdir(a); break; } case PICLANG_MOVE: a = PICLANG_pop();// y b = PICLANG_pop();// x IO_move(a,b); break; case PICLANG_GETY: case PICLANG_GETX: IO_getxy(&a,&b); if(command == PICLANG_GETX) PICLANG_pushl(a); else PICLANG_pushl(b); break; case PICLANG_FPUTCH:// KEEP FPUTCH before FFLUSH { ch1 = (char)PICLANG_pop(); SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER+PICLANG_file_buffer_index++,&ch1,sizeof(char)); if(PICLANG_file_buffer_index < FS_BUFFER_SIZE) break; } case PICLANG_FFLUSH:// KEEP FPUTCH before FFLUSH KEEP FFLUSH before FCLEAR picfs_dump(picos_processes[picos_curr_process].program_file); case PICLANG_FCLEAR:// KEEP FFLUSH before FCLEAR SRAM_write(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE); memset((char*)picfs_buffer,0,FS_BUFFER_SIZE); SRAM_write(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE); SRAM_read(SRAM_PICLANG_NEXT_SWAP_ADDR,(void*)picfs_buffer,FS_BUFFER_SIZE); PICLANG_file_buffer_index = 0; break; case PICLANG_FSTAT: a = PICLANG_pop(); sch1 = picfs_stat(a); if(sch1 < 0) { PICLANG_set_errno(); sch1 = 0; } a = picfs_buffer[ST_SIZE] << 8; a += picfs_buffer[ST_SIZE+1]; PICLANG_pushl(a); break; case PICLANG_READDIR: a = PICLANG_pop(); sch1 = picfs_readdir(1,a); if(sch1 != SUCCESS) PICLANG_set_errno(); PICLANG_pushl(sch1); break; case PICLANG_FOPEN: { /* mount_t mount; SRAM_read(curr_dir*sizeof(mount_t)+SRAM_MTAB_ADDR,&mount,sizeof(mount_t));*/ a = PICLANG_pop(); if(a < ARG_SIZE) { sch1 = picfs_open(ARG_buffer+a,curr_dir); } else if(a < ARG_SIZE + FS_BUFFER_SIZE) { a -= ARG_SIZE; sch1 = picfs_open((const char*)picfs_buffer+a,curr_dir); } else { c = 0; a -= ARG_SIZE + picos_processes[picos_curr_process].block_size; sch1 = PICLANG_next_dereference(a,command); } if(sch1 == -1) PICLANG_set_errno(); PICLANG_pushl(sch1); break; } case PICLANG_FCLOSE: a = PICLANG_pop(); picfs_close(a); break; case PICLANG_FREAD: a = PICLANG_pop(); sch1 = picfs_load(a); b = sch1; if(sch1 < 0) { b = -1; error_code = SUCCESS; PICLANG_exception(error_code); } PICLANG_pushl(b); break; case PICLANG_PRINTL: IO_putd(PICLANG_pop()); IO_flush(); break; case PICLANG_CLEAR: clear_output(); break; case PICLANG_MUTEX_LOCK: PICLANG_block(); break; case PICLANG_MUTEX_UNLOCK: PICLANG_unblock(); break; case PICLANG_GETCH: { PICLANG_block(); PICLANG_pushl(getch()); PICLANG_unblock(); break; } case PICLANG_GETD: { PICLANG_block(); ch1 = getch(); PICLANG_unblock(); if(ch1 < '0' || ch1 > '9') { PICLANG_exception(ARG_INVALID); break; } ch1 -= 0x30; PICLANG_pushl(ch1); break; } case PICLANG_SPRINT:case PICLANG_SPRINTN: { // string addresses start with arguments then const strings in executable /*string_pointer*/a = PICLANG_pop(); PICLANG_next_dereference(a,command); IO_flush(); break; } case PICLANG_LSOF: IO_puts("Implement lsof"); break; case PICLANG_LSMOUNT: lsmount(); break; case PICLANG_ERRNO: PICLANG_pushl(PICLANG_get_errno()); break; case PICLANG_KVERSION: a = PICLANG_pop(); if(a > 3) { PICLANG_exception(PICFS_EINVAL); break; } if(a == 0) b = KERNEL_MAJOR_VERSION; else if(a == 1) b = KERNEL_MINOR_VERSION; else if(a == 2) b = KERNEL_REVISION; else b = KERNEL_ID_TAG; PICLANG_pushl(b); break; case PICLANG_SIGNAL: a = PICLANG_get_next_word();// signal id b = PICLANG_get_next_word();// signal action if(a == PICOS_NUM_SIGNALS) { signal_free(b); break; } sch1 = signal_assign(a,picos_curr_process,b); if(sch1 != 0) PICLANG_exception(error_code); break; case PICLANG_SLEEP: a = PICLANG_pop(); ch1 = picos_curr_process; PICLANG_save(PICLANG_SUSPENDED); picos_processes[ch1].expires = (quantum_t)a; break; case PICLANG_MORSE: { char two[2]; /*addr*/a = PICLANG_pop(); two[1] = PICLANG_pop();//char or string? if(two[1] == PICLANG_MORSE_STRING) SRAM_read(a++,two,1); else { two[0] = (char)a; two[1] = 0; morse_sound(two); break; } two[1] = 0; while(two[0] != 0) { morse_sound(two); SRAM_read(a++,two,1); } break; } case PICLANG_TIME: { const TIME_t *thetime = TIME_get(); ch1 = PICLANG_pop(); switch(ch1) { case 'Y': PICLANG_pushl(thetime->year); break; case 'm': PICLANG_pushl(thetime->month); break; case 'd': PICLANG_pushl(thetime->day); break; case 'H': PICLANG_pushl(thetime->hours); break; case 'M': PICLANG_pushl(thetime->minutes); break; case 'S': PICLANG_pushl(thetime->seconds); break; default: PICLANG_exception(PICLANG_INVALID_PARAMETER); break; } break; } case PICLANG_SET_TIME:case PICLANG_SET_DATE: { TIME_t newtime = *(TIME_get()); if(command == PICLANG_SET_TIME) { newtime.minutes = PICLANG_pop(); newtime.hours = PICLANG_pop(); if(newtime.minutes > 59 || newtime.hours > 23) { newtime.minutes = newtime.hours = 0; PICLANG_exception(TIME_INVALID); } } else { newtime.year = PICLANG_pop(); newtime.day = PICLANG_pop(); newtime.month = PICLANG_pop(); if(newtime.month > 12 || newtime.day > 31) { newtime.month = newtime.day = 0; PICLANG_exception(TIME_INVALID); } } TIME_set(&newtime); break; } case PICLANG_JZ:case PICLANG_JMP:case PICLANG_CALL: { b = curr_process.pc; a = PICLANG_get_next_word(); if(curr_process.status != PICLANG_SUCCESS) { curr_process.pc = b; break; } if(command == PICLANG_CALL) { PICLANG_call_push(curr_process.pc); curr_process.pc = a; } else if(command == PICLANG_JMP) curr_process.pc = a; else if((curr_process.bitmap & PICLANG_ZERO) == 0) curr_process.pc = a; if(curr_process.status != PICLANG_SUCCESS) { curr_process.pc = b; break; } break; } case PICLANG_RETURN: { b = curr_process.pc; curr_process.pc = PICLANG_call_pop(); if(curr_process.status != PICLANG_SUCCESS) { curr_process.pc = b; break; } break; } case PICLANG_EXIT: PICLANG_save(PICLANG_pop()); break; case PICLANG_LABEL: break; case PICLANG_COMPLT: { b = PICLANG_pop(); a = PICLANG_pop(); if(a < b) curr_process.bitmap |= PICLANG_ZERO; else curr_process.bitmap &= ~PICLANG_ZERO; break; } case PICLANG_COMPGT: { b = PICLANG_pop(); a = PICLANG_pop(); if(a > b) curr_process.bitmap |= PICLANG_ZERO; else curr_process.bitmap &= ~PICLANG_ZERO; break; } case PICLANG_COMPEQ:case PICLANG_COMPNE: { b = PICLANG_pop(); a = PICLANG_pop(); if(a == b) curr_process.bitmap |= PICLANG_ZERO; else curr_process.bitmap &= ~PICLANG_ZERO; if(command == PICLANG_COMPNE) curr_process.bitmap ^= PICLANG_ZERO; break; } case PICLANG_AND: a = PICLANG_pop(); b = PICLANG_pop(); PICLANG_pushl(a & b); break; case PICLANG_OR: a = PICLANG_pop(); b = PICLANG_pop(); PICLANG_pushl(a | b); break; case PICLANG_NOT: a = PICLANG_pop(); PICLANG_pushl(~a); break; case PICLANG_RAWLOAD: SRAM_read(SRAM_PICLANG_RAW_FILE_BUFFER,(void*)picfs_buffer,FS_BUFFER_SIZE); break; case PICLANG_NUM_COMMANDS:default: PICLANG_exception(PICLANG_UNKNOWN_COMMAND); break; } }
void LineBuilder::build() { // Need at least 2 points to draw a line if (points.size() < 2) { clear_output(); return; } const float hw = width / 2.f; const float hw_sq = hw * hw; const float sharp_limit_sq = sharp_limit * sharp_limit; const int len = points.size(); // Initial values Vector2 pos0 = points[0]; Vector2 pos1 = points[1]; Vector2 f0 = (pos1 - pos0).normalized(); Vector2 u0 = rotate90(f0); Vector2 pos_up0 = pos0 + u0 * hw; Vector2 pos_down0 = pos0 - u0 * hw; Color color0; Color color1; float current_distance0 = 0.f; float current_distance1 = 0.f; float total_distance; _interpolate_color = gradient != NULL; bool distance_required = _interpolate_color || texture_mode == LINE_TEXTURE_TILE; if (distance_required) total_distance = calculate_total_distance(points); if (_interpolate_color) color0 = gradient->get_color(0); else colors.push_back(default_color); float uvx0 = 0.f; float uvx1 = 0.f; // Begin cap if (begin_cap_mode == LINE_CAP_BOX) { // Push back first vertices a little bit pos_up0 -= f0 * hw; pos_down0 -= f0 * hw; // The line's outer length will be a little higher due to begin and end caps total_distance += width; current_distance0 += hw; current_distance1 = current_distance0; } else if (begin_cap_mode == LINE_CAP_ROUND) { if (texture_mode == LINE_TEXTURE_TILE) { uvx0 = 0.5f; } new_arc(pos0, pos_up0 - pos0, -Math_PI, color0, Rect2(0.f, 0.f, 1.f, 1.f)); total_distance += width; current_distance0 += hw; current_distance1 = current_distance0; } strip_begin(pos_up0, pos_down0, color0, uvx0); // pos_up0 ------------- pos_up1 -------------------- // | | // pos0 - - - - - - - - - pos1 - - - - - - - - - pos2 // | | // pos_down0 ------------ pos_down1 ------------------ // // i-1 i i+1 // http://labs.hyperandroid.com/tag/opengl-lines // (not the same implementation but visuals help a lot) // For each additional segment for (int i = 1; i < len - 1; ++i) { pos1 = points[i]; Vector2 pos2 = points[i + 1]; Vector2 f1 = (pos2 - pos1).normalized(); Vector2 u1 = rotate90(f1); // Determine joint orientation const float dp = u0.dot(f1); const Orientation orientation = (dp > 0.f ? UP : DOWN); Vector2 inner_normal0, inner_normal1; if (orientation == UP) { inner_normal0 = u0 * hw; inner_normal1 = u1 * hw; } else { inner_normal0 = -u0 * hw; inner_normal1 = -u1 * hw; } // --------------------------- // / // 0 / 1 // / / // --------------------x------ / // / / (here shown with orientation == DOWN) // / / // / / // / / // 2 / // / // Find inner intersection at the joint Vector2 corner_pos_in, corner_pos_out; SegmentIntersectionResult intersection_result = segment_intersection( pos0 + inner_normal0, pos1 + inner_normal0, pos1 + inner_normal1, pos2 + inner_normal1, &corner_pos_in); if (intersection_result == SEGMENT_INTERSECT) // Inner parts of the segments intersect corner_pos_out = 2.f * pos1 - corner_pos_in; else { // No intersection, segments are either parallel or too sharp corner_pos_in = pos1 + inner_normal0; corner_pos_out = pos1 - inner_normal0; } Vector2 corner_pos_up, corner_pos_down; if (orientation == UP) { corner_pos_up = corner_pos_in; corner_pos_down = corner_pos_out; } else { corner_pos_up = corner_pos_out; corner_pos_down = corner_pos_in; } LineJointMode current_joint_mode = joint_mode; Vector2 pos_up1, pos_down1; if (intersection_result == SEGMENT_INTERSECT) { // Fallback on bevel if sharp angle is too high (because it would produce very long miters) if (current_joint_mode == LINE_JOINT_SHARP && corner_pos_out.distance_squared_to(pos1) / hw_sq > sharp_limit_sq) { current_joint_mode = LINE_JOINT_BEVEL; } if (current_joint_mode == LINE_JOINT_SHARP) { // In this case, we won't create joint geometry, // The previous and next line quads will directly share an edge. pos_up1 = corner_pos_up; pos_down1 = corner_pos_down; } else { // Bevel or round if (orientation == UP) { pos_up1 = corner_pos_up; pos_down1 = pos1 - u0 * hw; } else { pos_up1 = pos1 + u0 * hw; pos_down1 = corner_pos_down; } } } else { // No intersection: fallback pos_up1 = corner_pos_up; pos_down1 = corner_pos_down; } // Add current line body quad // Triangles are clockwise if (distance_required) { current_distance1 += pos0.distance_to(pos1); } if (_interpolate_color) { color1 = gradient->get_color_at_offset(current_distance1 / total_distance); } if (texture_mode == LINE_TEXTURE_TILE) { uvx0 = current_distance0 / width; uvx1 = current_distance1 / width; } strip_add_quad(pos_up1, pos_down1, color1, uvx1); // Swap vars for use in the next line color0 = color1; u0 = u1; f0 = f1; pos0 = pos1; current_distance0 = current_distance1; if (intersection_result == SEGMENT_INTERSECT) { if (current_joint_mode == LINE_JOINT_SHARP) { pos_up0 = pos_up1; pos_down0 = pos_down1; } else { if (orientation == UP) { pos_up0 = corner_pos_up; pos_down0 = pos1 - u1 * hw; } else { pos_up0 = pos1 + u1 * hw; pos_down0 = corner_pos_down; } } } else { pos_up0 = pos1 + u1 * hw; pos_down0 = pos1 - u1 * hw; } // From this point, bu0 and bd0 concern the next segment // Add joint geometry if (current_joint_mode != LINE_JOINT_SHARP) { // ________________ cbegin // / \ // / \ // ____________/_ _ _\ cend // | | // | | // | | Vector2 cbegin, cend; if (orientation == UP) { cbegin = pos_down1; cend = pos_down0; } else { cbegin = pos_up1; cend = pos_up0; } if (current_joint_mode == LINE_JOINT_BEVEL) { strip_add_tri(cend, orientation); } else if (current_joint_mode == LINE_JOINT_ROUND) { Vector2 vbegin = cbegin - pos1; Vector2 vend = cend - pos1; strip_add_arc(pos1, vend.angle_to(vbegin), orientation); } if (intersection_result != SEGMENT_INTERSECT) // In this case the joint is too f****d up to be re-used, // start again the strip with fallback points strip_begin(pos_up0, pos_down0, color1, uvx1); } } // Last (or only) segment pos1 = points[points.size() - 1]; Vector2 pos_up1 = pos1 + u0 * hw; Vector2 pos_down1 = pos1 - u0 * hw; // End cap (box) if (end_cap_mode == LINE_CAP_BOX) { pos_up1 += f0 * hw; pos_down1 += f0 * hw; } if (distance_required) { current_distance1 += pos0.distance_to(pos1); } if (_interpolate_color) { color1 = gradient->get_color(gradient->get_points_count() - 1); } if (texture_mode == LINE_TEXTURE_TILE) { uvx1 = current_distance1 / width; } strip_add_quad(pos_up1, pos_down1, color1, uvx1); // End cap (round) if (end_cap_mode == LINE_CAP_ROUND) { // Note: color is not used in case we don't interpolate... Color color = _interpolate_color ? gradient->get_color(gradient->get_points_count() - 1) : Color(0, 0, 0); new_arc(pos1, pos_up1 - pos1, Math_PI, color, Rect2(uvx1 - 0.5f, 0.f, 1.f, 1.f)); } }