예제 #1
0
void importGlyphPoints( FT_Vector *points, int n, value callbacks, field lineTo, field curveTo, bool cubic ) {
    value arg[4];
    int i;
	if( n==0 ) {
        val_ocall2( callbacks, lineTo, 
                    alloc_int( points[0].x ), alloc_int( points[0].y ) );
	} else if( n==1 ) {
        arg[0] = alloc_int( points[0].x );
        arg[1] = alloc_int( points[0].y );
        arg[2] = alloc_int( points[1].x );
        arg[3] = alloc_int( points[1].y );
        val_ocallN( callbacks, curveTo, arg, 4 );
	} else if( n>=2	) {
		if( cubic ) {
			// printf(stderr,"ERROR: cubic beziers in fonts are not yet implemented.\n");
		} else {
			int x1, y1, x2, y2, midx, midy;
			for( i=0; i<n-1; i++ ) { 
				x1 = points[i].x;
				y1 = points[i].y;
				x2 = points[i+1].x;
				y2 = points[i+1].y;
				midx = x1 + ((x2-x1)/2);
				midy = y1 + ((y2-y1)/2);
                
                arg[0] = alloc_int( x1 );
                arg[1] = alloc_int( y1 );
                arg[2] = alloc_int( midx );
                arg[3] = alloc_int( midy );
                val_ocallN( callbacks, curveTo, arg, 4 );
			}
            arg[0] = alloc_int( x2 );
            arg[1] = alloc_int( y2 );
            arg[2] = alloc_int( points[n].x );
            arg[3] = alloc_int( points[n].y );
            val_ocallN( callbacks, curveTo, arg, 4 );
		}
	} else {
	}
}
예제 #2
0
파일: serialize.c 프로젝트: MattTuttle/neko
static value unserialize_rec( sbuffer *b, value loader ) {
	switch( read_char(b) ) {
	case 'N':
		return val_null;
	case 'T':
		return val_true;
	case 'F':
		return val_false;
	case 'i':
		return alloc_int(read_int(b));
	case 'I':
		return alloc_int32(read_int(b));
	case 'f':
		{
			tfloat d;
			read_str(b,sizeof(tfloat),&d);
			return alloc_float(d);
		}
	case 's':
		{
			int l = read_int(b);
			value v;
			if( l < 0 || l > max_string_size )
				ERROR();
			v = alloc_empty_string(l);
			add_ref(b,v);
			read_str(b,l,(char*)val_string(v));
			return v;
		}
	case 'o':
		{
			int f;
			value o = alloc_object(NULL);
			add_ref(b,o);
			while( (f = read_int(b)) != 0 ) {
				value fval = unserialize_rec(b,loader);
				alloc_field(o,(field)f,fval);
			}
			switch( read_char(b) ) {
			case 'p':
				{
					value v = unserialize_rec(b,loader);
					if( !val_is_object(v) )
						ERROR();
					((vobject*)o)->proto = (vobject*)v;
				}
				break;
			case 'z':
				break;
			default:
				ERROR();
			}
			return o;
		}
	case 'r':
		{
			int n = read_int(b);
			if( n < 0 || n >= b->nrefs )
				ERROR();
			return b->trefs[b->nrefs - n - 1];
		}
	case 'a':
		{
			int i;
			int n = read_int(b);
			value o;
			value *t;
			if( n < 0 || n > max_array_size )
				ERROR();
			o = alloc_array(n);
			t = val_array_ptr(o);
			add_ref(b,o);
			for(i=0;i<n;i++)
				t[i] = unserialize_rec(b,loader);
			return o;

		}
	case 'p':
		{
			int nargs = read_int(b);
			vfunction *f = (vfunction*)alloc_function((void*)1,nargs,NULL);
			vfunction *f2;
			value name;
			add_ref(b,(value)f);
			name = unserialize_rec(b,loader);
			f2 = (vfunction*)val_ocall2(loader,id_loadprim,name,alloc_int(nargs));
			if( !val_is_function(f2) || val_fun_nargs(f2) != nargs )
				failure("Loader returned not-a-function");
			f->t = f2->t;
			f->addr = f2->addr;
			f->module = f2->module;
			return (value)f;
		}
	case 'L':
		{
			vfunction *f = (vfunction*)alloc_function((void*)1,0,NULL);
			value mname;
			int pos;
			int nargs;
			value env;
			add_ref(b,(value)f);
			mname = unserialize_rec(b,loader);
			pos = read_int(b);
			nargs = read_int(b);
			env = unserialize_rec(b,loader);
			if( !val_is_array(env) )
				ERROR();
			{
				value exp = val_ocall2(loader,id_loadmodule,mname,loader);
				value mval;
				unsigned int i;
				int_val *mpos;
				neko_module *m;
				if( !val_is_object(exp) ) {
					buffer b = alloc_buffer("module ");
					val_buffer(b,mname);
					buffer_append(b," is not an object");
					bfailure(b);
				}
				mval = val_field(exp,id_module);
				if( !val_is_kind(mval,neko_kind_module) ) {
					buffer b = alloc_buffer("module ");
					val_buffer(b,mname);
					buffer_append(b," has invalid type");
					bfailure(b);
				}
				m = (neko_module*)val_data(mval);
				mpos = m->code + pos;
				for(i=0;i<m->nglobals;i++) {
					vfunction *g = (vfunction*)m->globals[i];
					if( val_is_function(g) && g->addr == mpos && g->module == m && g->nargs == nargs ) {
						f->t = VAL_FUNCTION;
						f->env = env;
						f->addr = mpos;
						f->nargs = nargs;
						f->module = m;
						return (value)f;
					}
				}
				{
					buffer b = alloc_buffer("module ");
					val_buffer(b,mname);
					buffer_append(b," has been modified");
					bfailure(b);
				}
			}
			return val_null;
		}
	case 'x':
		{
			value mname = unserialize_rec(b,loader);
			value data = unserialize_rec(b,loader);
			value exports = val_ocall2(loader,id_loadmodule,mname,loader);
			value s;
			if( !val_is_object(exports) ) {
				buffer b = alloc_buffer("module ");
				val_buffer(b,mname);
				buffer_append(b," is not an object");
				bfailure(b);
			}
			s = val_field(exports,id_unserialize);
			if( !val_is_function(s) || (val_fun_nargs(s) != 1 && val_fun_nargs(s) != VAR_ARGS) ) {
				buffer b = alloc_buffer("module ");
				val_buffer(b,mname);
				buffer_append(b," has invalid __unserialize function");
			}
			s = val_call1(s,data);
			add_ref(b,s);
			return s;
		}
	case 'h':
		{
			int i;
			vhash *h = (vhash*)alloc(sizeof(vhash));
			h->ncells = read_int(b);
			h->nitems = read_int(b);
			h->cells = (hcell**)alloc(sizeof(hcell*)*h->ncells);
			for(i=0;i<h->ncells;i++)
				h->cells[i] = NULL;
			for(i=0;i<h->nitems;i++) {
				hcell **p;
				hcell *c = (hcell*)alloc(sizeof(hcell));
				c->hkey = read_int(b);
				c->key = unserialize_rec(b,loader);
				c->val = unserialize_rec(b,loader);
				c->next = NULL;
				p = &h->cells[c->hkey % h->ncells];
				while( *p != NULL )
					p = &(*p)->next;
				*p = c;
			}
			return alloc_abstract(k_hash,h);
		}
	default:
		ERROR();
		return val_null;
	}
}
예제 #3
0
value ftIterateGlyphs( value font, value callbacks ) {
    if( !val_is_object(callbacks) ) {
        ft_failure_v("not a callback function object: ", callbacks );
    }
// printf("A\n");
    field endGlyph = val_id("endGlyph");
    field startContour = val_id("startContour");
    field endContour = val_id("endContour");
    field lineTo = val_id("lineTo");
    field curveTo = val_id("curveTo");
// printf("B\n");
    
    if( !val_is_object(font) ) {
        ft_failure_v("not a freetype font face: ", font );
    }
    value __f = val_field( font, val_id("__f") );
    if( __f == NULL || !val_is_abstract( __f ) || !val_is_kind( __f, k_ft_face ) ) {
        ft_failure_v("not a freetype font face: ", font );
    }
    FT_Face *face = val_data( __f );
// printf("C\n");

	FT_UInt glyph_index;
	FT_ULong character;
	FT_Outline *outline;

    field f_character = val_id("character");
    field f_advance = val_id("advance");
    
    character = FT_Get_First_Char( *face, &glyph_index );

// printf("D\n");
    while( character != 0 ) {
        if( FT_Load_Glyph( *face, glyph_index, FT_LOAD_NO_BITMAP ) ) {
            // ignore (TODO report?)
        } else if( (*face)->glyph->format != FT_GLYPH_FORMAT_OUTLINE ) {
            // ignore (TODO)
        } else {
            outline = &((*face)->glyph->outline);
		    int start = 0, end, contour, p;
		    char control, cubic;
		    int n,i;
// printf("  1\n");
		    for( contour = 0; contour < outline->n_contours; contour++ ) {
			    end = outline->contours[contour];
			    n=0;

    
			    for( p = start; p<=end; p++ ) {
				    control = !(outline->tags[p] & 0x01);
				    cubic = outline->tags[p] & 0x02;

				    if( p==start ) {
                        val_ocall2( callbacks, startContour, 
                                    alloc_int( outline->points[p-n].x ),
                                    alloc_int( outline->points[p-n].y ) );
				    }

				    if( !control && n > 0 ) {
					    importGlyphPoints( &(outline->points[(p-n)+1]), n-1, callbacks, lineTo, curveTo, cubic );
					    n=1;
				    } else {
					    n++;
				    }
			    }

			    if( n ) {
				    // special case: repeat first point
				    FT_Vector points[n+1];
				    int s=(end-n)+2;
				    for( i=0; i<n-1; i++ ) {
					    points[i].x = outline->points[s+i].x;
					    points[i].y = outline->points[s+i].y;
				    }
				    points[n-1].x = outline->points[start].x;
				    points[n-1].y = outline->points[start].y;

				    importGlyphPoints( points, n-1, callbacks, lineTo, curveTo, false );
			    }

			    start = end+1;
                val_ocall0( callbacks, endContour );
		    }

// printf("  2\n");
            val_ocall2( callbacks, endGlyph, alloc_int( character ), alloc_int( (*face)->glyph->advance.x ) );
// printf("  3\n");
        }
// printf("  E\n");
        character = FT_Get_Next_Char( *face, character, &glyph_index );
// printf("  F\n");
    }
    
// printf("  Goo\n");
    return val_true;
}
예제 #4
0
value  api_val_ocall2(value  arg1,int arg2,value  arg3,value  arg4)
{
	return val_ocall2(arg1,arg2,arg3,arg4);
}
예제 #5
0
static void do_parse_xml( const char *xml, const char **lp, int *line, value callb, const char *parentname ) {
	STATE state = BEGIN;
	STATE next = BEGIN;
	field aname = (field)0;
	value attribs = NULL_VAL;
	value nodename = NULL_VAL;
	const char *start = NULL;
	const char *p = *lp;
	char c = *p;
	int nsubs = 0, nbrackets = 0;
	while( c ) {
		switch( state ) {
		case IGNORE_SPACES:
			switch( c ) {
			case '\n':
			case '\r':
			case '\t':
			case ' ':
				break;
			default:
				state = next;
				continue;
			}
			break;
		case BEGIN:
			switch( c ) {
			case '<':
				state = IGNORE_SPACES;
				next = BEGIN_NODE;
				break;
			default:
				start = p;
				state = PCDATA;
				continue;
			}
			break;
		case PCDATA:
			if( c == '<' ) {
				val_ocall1(callb,id_pcdata,copy_string(start,p-start));
				nsubs++;
				state = IGNORE_SPACES;
				next = BEGIN_NODE;
			}
			break;
		case CDATA:
			if( c == ']' && p[1] == ']' && p[2] == '>' ) {
				val_ocall1(callb,id_cdata,copy_string(start,p-start));
				nsubs++;
				p += 2;
				state = BEGIN;
			}
			break;
		case BEGIN_NODE:
			switch( c ) {
			case '!':
				if( p[1] == '[' ) {
					p += 2;
					if( (p[0] != 'C' && p[0] != 'c') ||
						(p[1] != 'D' && p[1] != 'd') ||
						(p[2] != 'A' && p[2] != 'a') ||
						(p[3] != 'T' && p[3] != 't') ||
						(p[4] != 'A' && p[4] != 'a') ||
						(p[5] != '[') )
						ERROR("Expected <![CDATA[");
					p += 5;
					state = CDATA;
					start = p + 1;
					break;
				}
				if( p[1] == 'D' || p[1] == 'd' ) {
					if( (p[2] != 'O' && p[2] != 'o') ||
						(p[3] != 'C' && p[3] != 'c') ||
						(p[4] != 'T' && p[4] != 't') ||
						(p[5] != 'Y' && p[5] != 'y') ||
						(p[6] != 'P' && p[6] != 'p') ||
						(p[7] != 'E' && p[7] != 'e') )
						ERROR("Expected <!DOCTYPE");
					p += 7;
					state = DOCTYPE;
					start = p + 1;
					break;
				}
				if( p[1] != '-' || p[2] != '-' )
					ERROR("Expected <!--");
				p += 2;
				state = COMMENT;
				start = p + 1;
				break;
			case '?':
				state = HEADER;
				start = p;
				break;
			case '/':
				if( parentname == NULL )
					ERROR("Expected node name");
				start = p + 1;
				state = IGNORE_SPACES;
				next = CLOSE;
				break;
			default:
				state = TAG_NAME;
				start = p;
				continue;
			}
			break;
		case TAG_NAME:
			if( !is_valid_char(c) ) {
				if( p == start )
					ERROR("Expected node name");
				nodename = copy_string(start,p-start);
				attribs = alloc_empty_object();
				state = IGNORE_SPACES;
				next = BODY;
				continue;
			}
			break;
		case BODY:
			switch( c ) {
			case '/':
				state = WAIT_END;
				nsubs++;
				val_ocall2(callb,id_xml,nodename,attribs);
				break;
			case '>':
				state = CHILDS;
				nsubs++;
				val_ocall2(callb,id_xml,nodename,attribs);
				break;
			default:
				state = ATTRIB_NAME;
				start = p;
				continue;
			}
			break;
		case ATTRIB_NAME:
			if( !is_valid_char(c) ) {
				value tmp;
				if( start == p )
					ERROR("Expected attribute name");
				tmp = copy_string(start,p-start);
				aname = val_id(val_string(tmp));
				if( !val_is_null(val_field(attribs,aname)) )
					ERROR("Duplicate attribute");
				state = IGNORE_SPACES;
				next = EQUALS;
				continue;
			}
			break;
		case EQUALS:
			switch( c ) {
			case '=':
				state = IGNORE_SPACES;
				next = ATTVAL_BEGIN;
				break;
			default:
				ERROR("Expected =");
			}
			break;
		case ATTVAL_BEGIN:
			switch( c ) {
			case '"':
			case '\'':
				state = ATTRIB_VAL;
				start = p;
				break;
			default:
				ERROR("Expected \"");
			}
			break;
		case ATTRIB_VAL:
			if( c == *start ) {
				value aval = copy_string(start+1,p-start-1);
				alloc_field(attribs,aname,aval);
				state = IGNORE_SPACES;
				next = BODY;
			}
			break;
		case CHILDS:
			*lp = p;
			do_parse_xml(xml,lp,line,callb,val_string(nodename));
			p = *lp;
			start = p;
			state = BEGIN;
			break;
		case WAIT_END:
			switch( c ) {
			case '>':
				val_ocall0(callb,id_done);
				state = BEGIN;
				break;
			default :
				ERROR("Expected >");
			}
			break;
		case WAIT_END_RET:
			switch( c ) {
			case '>':
				if( nsubs == 0 )
					val_ocall1(callb,id_pcdata,alloc_string(""));
				val_ocall0(callb,id_done);
				*lp = p;
				return;
			default :
				ERROR("Expected >");
			}
			break;
		case CLOSE:
			if( !is_valid_char(c) ) {
				if( start == p )
					ERROR("Expected node name");
				{
					value v = copy_string(start,p - start);
					if( _strcmpi(parentname,val_string(v)) != 0 ) {
						buffer b = alloc_buffer("Expected </");
						buffer_append(b,parentname);
						buffer_append(b,">");
						ERROR(buffer_data(b));
					}
				}
				state = IGNORE_SPACES;
				next = WAIT_END_RET;
				continue;
			}
			break;
		case COMMENT:
			if( c == '-' && p[1] == '-' && p[2] == '>' ) {
				val_ocall1(callb,id_comment,copy_string(start,p-start));
				p += 2;
				state = BEGIN;
			}
			break;
		case DOCTYPE:
			if( c == '[' )
				nbrackets++;
			else if( c == ']' )
				nbrackets--;
			else if( c == '>' && nbrackets == 0 ) {
				val_ocall1(callb,id_doctype,copy_string(start,p-start));
				state = BEGIN;
			}
			break;
		case HEADER:
			if( c == '?' && p[1] == '>' ) {
				p++;
				val_ocall1(callb,id_comment,copy_string(start,p-start));
				state = BEGIN;
			}
			break;
		}
		c = *++p;
		if( c == '\n' )
			(*line)++;
	}
	if( state == BEGIN ) {
		start = p;
		state = PCDATA;
	}
	if( parentname == NULL && state == PCDATA ) {
		if( p != start || nsubs == 0 )
			val_ocall1(callb,id_pcdata,copy_string(start,p-start));
		return;
	}
	ERROR("Unexpected end");
}