Example #1
0
static VALUE pen_x(VALUE self)
{
  SWFShape shape;

  Data_Get_Struct(self, struct SWFShape_s, shape);

  return rb_float_new(SWFShape_getPenX(shape));
}
Example #2
0
void swfDrawStyledLineTo(SWFShape shape, double x, double y, const pGEcontext gc)
{
    int lty = gc->lty;
    int lwd = gc->lwd;
    /* Original positions */
    double x0 = SWFShape_getPenX(shape);
    double y0 = SWFShape_getPenY(shape);
    double x_next, y_next;
    /* Distance between (x0, y0) and (x, y) */
    double dist = sqrt(pow(x - x0, 2) + pow(y - y0, 2));
    
    unsigned char dashlist[8];
    int ndash = 0;
    /* Length of one cycle of dashlines */
    int cycle_len = 0;
    /* How many full cycles will we have in drawing the line? */
    int ncycle = 0;
    /* How many pen-up and pen-down segments? */
    int nseg = 0;
    /* Distance the pen has moved */
    /* s is a temp variable */
    double dist_moved = 0.0, s = 0.0;
    int i;
    
    /* Is the pen for next segment up or down? */
    Rboolean is_down = TRUE;
    
    /* If it is a solid line */
    /* NOTE: Here lty == 0 corresponds to lty = 1 in R */
    if(lty == LTY_SOLID) /* LTY_SOLID == 0 */
    {
        SWFShape_drawLineTo(shape, x, y);
        return;
    }
    if(lty == LTY_BLANK) /* LTY_BLANK == -1 */
    {
        SWFShape_movePenTo(shape, x, y);
        return;
    }

    /* Decode texture description */
    for(i = 0; i < 8 && lty & 15; i++)
    {
        dashlist[ndash++] = lty & 15;
        lty = lty >> 4;
        cycle_len += dashlist[i];
    }
    
    /* Cycle length proportional to lwd */
    cycle_len *= lwd;
    ncycle = (int) floor(dist / cycle_len);
    nseg = ncycle * ndash;
    /* Length of the last incomplete cycle */
    s = dist - cycle_len * ncycle;
    for(i = 0; i < ndash; i++)
    {
        if(dist_moved + dashlist[i] * lwd >= s)
            break;

        dist_moved += dashlist[i] * lwd;
        nseg++;
    }

    dist_moved = 0.0;
    for(i = 0; i < nseg; i++)
    {
        dist_moved += dashlist[i % ndash] * lwd;
        x_next = x0 + dist_moved / dist * (x - x0);
        y_next = y0 + dist_moved / dist * (y - y0);
        if(is_down)
        {
            SWFShape_drawLineTo(shape, x_next, y_next);
        } else {
            SWFShape_movePenTo(shape, x_next, y_next);
        }
        is_down = !is_down;
    }
    if(is_down)
    {
        SWFShape_drawLineTo(shape, x, y);
    } else {
        SWFShape_movePenTo(shape, x, y);
    }
}
Example #3
0
static void SWF_drawStyledLineTo(SWFShape line, double x_end, 
	double y_end, int lty)
{
	byte dashlist[8];
	int i, nlty;
	
	/* From ?par
	 * Line types can either be specified by giving an index into a small 
	 * built-in table of line types (1 = solid, 2 = dashed, etc, see lty 
	 * above) or directly as the lengths of on/off stretches of line. This 
	 * is done with a string of an even number (up to eight) of characters, 
	 * namely non-zero (hexadecimal) digits which give the lengths in 
	 * consecutive positions in the string. For example, the string "33" 
	 * specifies three units on followed by three off and "3313" specifies 
	 * three units on followed by three off followed by one on and finally 
	 * three off. The ‘units’ here are (on most devices) proportional to lwd, 
	 * and with lwd = 1 are in pixels or points or 1/96 inch.

	 * The five standard dash-dot line types (lty = 2:6) correspond to 
	 * c("44", "13", "1343", "73", "2262").
	 * 
	 * (0=blank, 1=solid (default), 2=dashed, 
	 *  3=dotted, 4=dotdash, 5=longdash, 6=twodash) 
	*/
	
	/*Retrieve the line type pattern*/
	for(i = 0; i < 8 && lty & 15 ; i++) {
		dashlist[i] = lty & 15;
		lty = lty >> 4;
		//if( DEBUG == TRUE )
		//	Rprintf("\tDash List: %d\n", dashlist[i]);
	}
	nlty = i; i = 0;
	
	if(nlty == 0){
		SWFShape_drawLineTo(line, x_end, y_end);
		return;
	}
	
		/* Do the drawing of dashed line manually
		 * this is very sucky, it sould be done for me
		 * In my opinion, this is a huge limitation of libming.
		 *
		 * 1. Calculate end point of dash segment
		 * 2a. If past end point of line, draw to end of line, end
		 * 2b. Otherwise draw to end point of dash segment
		 * 3. Repeat
		 */
		
		//Current position
	double x_cur = SWFShape_getPenX(line);
	//double y1 = GEcurrentDevice()->dev->top - SWFShape_getPenY(line);
	double y_cur = SWFShape_getPenY(line);
	
		//end of dash segment
	double x_next, y_next, ang = atan((y_end-y_cur)/(x_end-x_cur));
		//distance to end of dash segment and end of line
	double d_dash, d_line = 10000, old_d_line;
	Rboolean at_line_end = FALSE;
	
	//Rprintf("x_cur=%f x_end=%f\n",x_cur,x_end);
	//Rprintf("y_cur=%f y_end=%f\n",y_cur,y_end);
	
	while( at_line_end == FALSE ){
		while(i < nlty){
			//Rprintf("INNER LOOP\n");
			
			/*
			 * This part is so whacked out, basically the different origins of 
			 * R and ming make drawing dashed lines REALLY confusing. This 
			 * seems to work though :). A lot of things in R graphics seem to
			 * go this way. 
			*/
			if(x_end < x_cur && y_end <= y_cur){
				x_next = x_cur - (double)dashlist[i] * cos(ang);
				y_next = y_cur - (double)dashlist[i] * sin(ang);
			}
			if(x_end > x_cur && y_end <= y_cur){
				x_next = x_cur + (double)dashlist[i] * cos(ang);
				y_next = y_cur + (double)dashlist[i] * sin(ang);
			}
			if(x_end < x_cur && y_end > y_cur){
				x_next = x_cur - (double)dashlist[i] * cos(ang);
				y_next = y_cur - (double)dashlist[i] * sin(ang);
			}
			if(x_end > x_cur && y_end > y_cur){
				x_next = x_cur + (double)dashlist[i] * cos(ang);
				y_next = y_cur + (double)dashlist[i] * sin(ang);
			}
			
			old_d_line = d_line;
			d_line = sqrt(pow(abs(x_end-x_cur),2)+pow(abs(y_end-y_cur),2));
			d_dash = sqrt(pow(abs(x_next-x_cur),2)+pow(abs(y_next-y_cur),2));

			//Rprintf("i=%d nlty=%d\n",i,nlty);
			//Rprintf("x_cur=%f x_end=%f x_next=%f\n",x_cur,x_end,x_next);
			//Rprintf("y_cur=%f y_end=%f y_next=%f\n",y_cur,y_end,y_next);
			//Rprintf("ang=%f\n",ang);
			//Rprintf("d_dash=%f\n",d_dash);
			//Rprintf("d_line=%f\n",d_line);
			//Rprintf("old_d_line=%f\n",old_d_line);
			
			if( (d_dash >= d_line) || old_d_line < d_line ){
				//Rprintf("%s\n\n\n","Time to break");
				if( (i % 2) == 0 ){
						//draw to the end of the line segment
					SWFShape_drawLineTo(line, x_end, y_end);
				}else{
					SWFShape_movePenTo(line, x_end, y_end);
				}
				at_line_end = TRUE; //out of main loop
				break; //out of inner loop
			}
				
			if( (i % 2) == 0 ){
					//draw to the end point of the dash segment
				SWFShape_drawLineTo(line, x_next, y_next);
				//if( DEBUG == TRUE )
				//Rprintf("\tDrawing dash line to: (%f,%f)\n", x_next, y_next);
			}else{
				SWFShape_movePenTo(line, x_next, y_next);
				//if( DEBUG == TRUE )
				//Rprintf("\tMoving dash pen to: (%f,%f)\n", x_next, y_next);
			}
			// Update coordinates
			x_cur = x_next; y_cur = y_next; 
			i++;
		}
		i = 0;
	}
		
}
Example #4
0
/* ming.cには実装されていなかったけれども一応 */
EXPORT BOOL WINAPI s_getPenX(float *p1, int p2, int p3, int p4)
{
	lstrcpy(funcname, "s_getPenX");
	*p1 = SWFShape_getPenX(mhsp_shape);
	return 0;
}