void ShapeMaker::curveToR( double _cx, double _cy, double ax, double ay ) { int cx = roundX(factorx * ( _cx ) ); int cy = roundY(factory * ( _cy ) ); int x = roundX(factorx * ( ax - _cx ) ); int y = roundY(factory * ( ay - _cy) ); smoothx = lastx + _cx; smoothy = lasty + _cy; diffx += cx + x; diffy += cy + y; CurveTo *segment = new CurveTo; segment->setType(2); segment->setbits( SWFMaxBitsNeeded( true, 4, x, y, cx, cy ) ); segment->setx1( cx ); segment->sety1( cy ); segment->setx2( x ); segment->sety2( y ); edges->append( segment ); minmax( x+cx+(lastx*factorx), y+cy+(lasty*factory) ); lastx += ax; lasty += ay; smoothx = ax - _cx; smoothy = ay - _cy; }
void ShapeMaker::doSetup( double _x, double _y, bool hasMoveTo, int _fillStyle0, int _fillStyle1, int _lineStyle ) { // append shapesetup (whithout styles, this is glyph only for now) ShapeSetup *setup = new ShapeSetup; if( _fillStyle0 != -1 ) { setup->setfillStyle0( _fillStyle0 ); setup->sethasFillStyle0( 1 ); } if( _fillStyle1 != -1 ) { setup->setfillStyle1( _fillStyle1 ); setup->sethasFillStyle1( 1 ); } if( _lineStyle != -1 ) { setup->setlineStyle( _lineStyle ); setup->sethasLineStyle( 1 ); } if( hasMoveTo ) { roundReset(); int x = roundX(factorx * ( _x ) ); int y = roundY(factory * ( _y ) ); diffx = diffy = 0; setup->setxybits( SWFMaxBitsNeeded( true, 2, x, y ) ); setup->sethasMoveTo( 1 ); setup->setx( x ); setup->sety( y ); minmax( x, y ); lastx = _x; lasty = _y; lastsetupx = _x; lastsetupy = _y; } edges->append( setup ); // fprintf(stderr,"setup %i/%i\n", x, y ); }
void importDefineFont2( DefineFont2 *tag, const char *filename, xmlNodePtr node ) { FT_Library swfft_library; FT_Face face; int error; FT_UInt glyph_index; FT_ULong character; FT_Outline *outline; xmlChar *glyphs_xml = xmlGetProp( node, (const xmlChar *)"glyphs" ); const char *glyphs = (const char *)glyphs_xml; GlyphList *glyphList = tag->getglyphs(); List<Short>* advance = tag->getadvance(); List<Rectangle>* bounds = tag->getbounds(); // NYI: kerning Shape *shape; int glyph_n; int n, ofs; if( FT_Init_FreeType( &swfft_library ) ) { fprintf( stderr, "WARNING: could not initialize FreeType\n" ); goto fail; } error = FT_New_Face( swfft_library, filename, 0, &face ); if( error ) { fprintf( stderr, "WARNING: FreeType does not like %s\n", filename ); goto fail; } if( face->num_faces > 1 ) { fprintf( stderr, "WARNING: %s contains %i faces, but only the first is imported.\n", filename, face->num_faces ); } if( face->charmap == 0 ) { fprintf( stderr, "WARNING: %s doesn't seem to contain a unicode charmap.\n", filename ); } FT_Set_Char_Size(face, 1024<<6, 1024<<6, 75, 75); // we should only import @glyphs, lets do all for now. // count availably glyphs n = 0; if( (character = FT_Get_First_Char( face, &glyph_index )) != 0 ) n++; while( (character = FT_Get_Next_Char( face, character, &glyph_index )) != 0 ) n++; if( n>255 ) n=255; // FIXME ofs = 0; n-=ofs; fprintf( stderr, "importing %s: %i glyphs\n", filename, n ); glyphList->allocate( n ); tag->setglyphCount( n ); tag->setname( "helvetica" ); // FIXME tag->sethasLayout( 1 ); tag->setascent( face->ascender * 1024 / face->units_per_EM ); tag->setdescent( labs(face->descender)* 1024 / face->units_per_EM ); tag->setleading( face->height* 1024 / face->units_per_EM ); tag->setwideGlyphOffsets( 1 ); tag->setwideMap( 1 ); character = FT_Get_First_Char( face, &glyph_index ); for( int i=0; i<ofs; i++ ) character=FT_Get_Next_Char( face, character, &glyph_index ); for( int glyph_n=0; character && glyph_n<n; glyph_n++ ) { // glyph_index = FT_Get_Char_Index( face, character ); if( FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_BITMAP ) ) { fprintf( stderr, "WARNING: couldnt load glyph %i (%c) from %s.\n", character, character, filename ); } if( face->glyph->format != FT_GLYPH_FORMAT_OUTLINE ) { fprintf( stderr, "WARNING: %s seems to be a bitmap font.\n", filename ); goto fail; } outline = &face->glyph->outline; // fprintf(stderr,"importing glyph %i ('%c') of %s (advance %i, %i points)\n", character, character, filename, face->glyph->advance.x, outline->n_points ); { Short *adv = new Short(); adv->setvalue( (short)(face->glyph->advance.x * (1.0/64)) ); advance->append(adv); Rectangle *r = new Rectangle(); /* r->settop( -face->bbox.yMax * 1024 / face->units_per_EM ); r->setright( face->bbox.xMax - face->bbox.xMin ); r->setbottom( -face->bbox.yMin * 1024 / face->units_per_EM ); */ r->setbits( SWFMaxBitsNeeded( true, 3, r->gettop(), r->getright(), r->getbottom() ) ); bounds->append(r); glyphList->setMapN(glyph_n, character); shape = glyphList->getShapeN(glyph_n); ShapeMaker shaper( shape->getedges(), (1.0/64), -(1.0/64), 0, 0 ); // set fillBits shape->setfillBits(1); int start = 0, end; bool control, cubic; int n; for( int contour = 0; contour < outline->n_contours; contour++ ) { end = outline->contours[contour]; // fprintf(stderr," contour %i: %i-%i\n", contour, start, end ); n=0; for( int p = start; p<=end; p++ ) { control = !(outline->tags[p] & 0x01); cubic = outline->tags[p] & 0x02; /* if( character == 'h' ) fprintf( stderr, " point %i: %s%s %i %i\n", p, control?(cubic?"third-order ":"second-order "):"", control?"control":"on-curve", outline->points[p].x, outline->points[p].y); */ if( p==start ) { shaper.setup( outline->points[p-n].x, outline->points[p-n].y, 1 ); } if( !control && n > 0 ) { importGlyphPoints( &(outline->points[(p-n)+1]), n-1, shaper, cubic ); n=1; } else { n++; } } if( n ) { // special case: repeat first point FT_Vector points[n+1]; int s=(end-n)+2; for( int 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, shaper, false ); } shaper.close(); start = end+1; } shaper.finish(); } character = FT_Get_Next_Char( face, character, &glyph_index ); } return; fail: fprintf( stderr, "WARNING: could not import %s\n", filename ); return; }