Example #1
0
// 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
Example #2
0
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.);
}