// cnf. d3hf13.cpp (LEDA) leda::edge TriangulateXY(leda::nb::RatPolyMesh& mesh, leda::list<leda::node>& L, int orient) { typedef leda::d3_rat_point point_t; // assert(0 == mesh.number_of_edges()); // assert(IsSorted(mesh, L)); if(L.empty()) return NULL; leda::node last_v = L.pop_front(); point_t last_p = mesh.position_of(last_v); while(!L.empty() && equal_xy(last_p, mesh[L.front()])) { mesh.del_node(L.pop_front()); } if(!L.empty()) { leda::node v = L.pop_front(); leda::edge e0 = mesh.new_edge(last_v, v, 0); leda::edge e1 = mesh.new_edge(v, last_v, 0); mesh.set_reversal(e0, e1); SetColorU(mesh, e0, Color::BLACK); last_v = v; last_p = mesh.position_of(v); } // scan remaining points leda::node v; forall(v, L) { point_t p = mesh.position_of(v); if(equal_xy(p, last_p)) { mesh.del_node(v); continue; } // walk up to upper tangent leda::edge e = mesh.last_edge(); int orientXY; do { e = mesh.face_cycle_pred(e); orientXY = leda::orientation_xy( p, mesh.position_of(leda::source(e)), mesh.position_of(leda::target(e))); } while(orient == orientXY); // walk down to lower tangent and triangulate do { leda::edge succ = mesh.face_cycle_succ(e); leda::edge x = mesh.new_edge(succ, v, 0, leda::after); leda::edge y = mesh.new_edge(v, leda::source(succ), 0); mesh.set_reversal(x, y); SetColorU(mesh, x, Color::BLACK); e = succ; orientXY = leda::orientation_xy( p, mesh.position_of(leda::source(e)), mesh.position_of(leda::target(e))); } while(orient == orientXY); last_p = p; } // forall nodes in L
void draw_string_full(framebuffer_t fb, vector_font_t *font, char *string, xy_t p, xy_t off, double scale, col_t colour, double intensity, double line_thick, const int mode, int32_t len, double glyph_limit, double line_limit, const int bidi, const int recur, text_param_t *tp) { uint32_t i, is, c, co; double w=0., base_off=0.; xy_t off_ls=XY0; int drawline=0; unicode_data_t ucd; int c_bidi, len_sec, con_prev=0, use_textedit=0, curpos, bidi_change=0; col_t colm; xy_t expected_pos=XY0; static double closest_deltapos[3]; if (recur==0) // if it's the top recursion of the function for this string for (i=0; i<3; i++) closest_deltapos[i] = FLT_MAX; if (font==NULL) return ; if (scale < line_limit) return ; if (scale < glyph_limit) drawline = 1; if (recur==0) intensity *= intensity_scaling(scale, 1.); if (((mode&3)!=ALIG_LEFT && bidi!=-2) || ((mode&3)!=ALIG_RIGHT && bidi==-2)) { //w = calc_strwidth_len(font, string, scale, mode, len); w = calc_strwidth_firstline(font, string, scale, mode, len, NULL); if ((mode&3)==ALIG_CENTRE) if (bidi==-2) base_off += w*0.5; else base_off -= w*0.5; if ((mode&3)==ALIG_LEFT && bidi==-2) base_off += w; if ((mode&3)==ALIG_RIGHT && bidi!=-2) base_off -= w; } if (bidi==1) { if (w==0.) w = calc_strwidth_firstline(font, string, scale, mode, len, NULL); base_off -= w; } off.x += base_off; colm = colour; if (drawline==0) colm = colour_mul(colm, intensity); if (len < 0) len = strlen(string); if (cur_textedit) if (cur_textedit->string) if (string >= cur_textedit->string && string <= &cur_textedit->string[strlen(cur_textedit->string)]) // if the string belongs to text being edited { use_textedit = 1; curpos = &cur_textedit->string[cur_textedit->curpos] - string; if (curpos==0 && cur_textedit->click_on==0 && recur==0 && len==0) // draw cursor if the string is empty draw_textedit_cursor(fb, add_xy(p, off), scale, bidi, bidi_change, line_thick); if (cur_textedit->click_on) { expected_pos = add_xy( mul_xy(xy(0.5*LETTERSPACING * (bidi == -2 ? -1. : 1.), 3.), set_xy(scale)) , sub_xy(cur_textedit->click, p) ); expected_pos.y = MAXN(0., expected_pos.y); if (recur==0) cur_textedit->curpos = strlen(cur_textedit->string); } } for (i=0; i<len; i++) { is = i; // save i at start (it might get incremented right below) co = utf8_to_unicode32(&string[i], &i); // get (original) codepoint and increment i c = get_arabic_form(co, &string[i+1], len-(i+1), con_prev); // substitute for Arabic form if needed ucd = get_unicode_data(c); if (ucd.bidicat!=bidicat_NSM) // if character that is not a combining mark con_prev = unicode_arabic_can_connect(co, 1); // if the current character connects with the next (in Arabic) if (c > sc_start && c < sc_end) // custom colour-setting Unicode characters { switch (c) { case sc_white: colour = make_colour(1., 1., 1., 1.); break; case sc_black: colour = make_colour(0., 0., 0., 1.); break; case sc_red: colour = make_colour(1., 0., 0., 1.); break; case sc_green: colour = make_colour(0., 0.5, 0., 1.); break; case sc_blue: colour = make_colour(0., 0., 1., 1.); break; case sc_baby_azure: colour = make_colour(0.1, 0.3, 1., 1.); break; case sc_amber: colour = make_colour(1., 0.55, 0., 1.); break; case sc_azure: colour = make_colour(0., 0.45, 1., 1.); break; case sc_grey: colour = make_colour(0.184, 0.184, 0.184, 1.); break; default: colour = make_colour(0.184, 0.184, 0.184, 1.); } colm = colour_mul(colour, intensity); } else // regular Unicode characters { // draw the line for the last word it represents if (drawline && recur==0) if (c==' ' || c=='\t' || c=='\n') // if c is whitespace char if (equal_xy(off, off_ls)==0) draw_line_thin(fb, add_xy(add_xy(p, off_ls), xy(0., -2.5*scale)), add_xy(add_xy(p, off), xy(-LETTERSPACING*scale, -2.5*scale) ), line_thick, colour, cur_blend, intensity*3.); c_bidi = bidicat_direction(ucd.bidicat); bidi_change = (bidi!=-2 && c_bidi==-2) || (bidi==-2 && c_bidi>0); if (use_textedit) cursor_processing(fb, font, string, c, p, off, scale, expected_pos, is, curpos, recur, mode, bidi, bidi_change, line_thick, closest_deltapos); if (bidi_change) { len_sec = find_len_bidi_section(&string[is], len-is, c_bidi); draw_string_full(fb, font, &string[is], p, off, scale, colour, intensity, line_thick, mode, len_sec, glyph_limit, line_limit, c_bidi, recur+1, tp); off.x += (calc_strwidth_len(font, &string[is], scale, mode, len_sec) + LETTERSPACING * scale) * (bidi == -2 ? -1. : 1.); is += len_sec; i = is-1; } else switch (c) { case '\n': off.x = base_off; off.y += LINEVSPACING * scale; break; default: if (drawline==0) i += draw_vector_char_lookahead(fb, font, c, &string[i+1], p, &off, scale, colm, line_thick, mode, bidi); off.x += letter_width(font, off.x, c, scale, mode) * (bidi == -2 ? -1. : 1.); } if (use_textedit && i+1==len) // if we're reaching the end of the string cursor_processing(fb, font, string, 0, p, off, scale, expected_pos, i+1, curpos, recur, mode, bidi, bidi_change, line_thick, closest_deltapos); if (drawline) if (c==' ' || c=='\t' || c=='\n') // if c is whitespace char off_ls = off; // fix position in RTL } } if (drawline && recur==0) if (equal_xy(off, off_ls)==0) draw_line_thin(fb, add_xy(add_xy(p, off_ls), xy(0., -2.5*scale)), add_xy(add_xy(p, off), xy(-LETTERSPACING*scale, -2.5*scale) ), line_thick, colour, cur_blend, intensity*3.); }