plCachedFileReader::plCachedFileReader(const char *path, plAudioCore::ChannelSelect whichChan) : fFileHandle(nil), fCurPosition(0) { hsAssert(path != nil, "Invalid path specified in plCachedFileReader"); strncpy(fFilename, path, sizeof(fFilename)); /// Open the file as a plain binary stream fFileHandle = fopen(path, "rb"); if (fFileHandle != nil) { if (fread(&fHeader, 1, sizeof(plWAVHeader), fFileHandle) != sizeof(plWAVHeader)) { IError("Invalid WAV file header in plCachedFileReader"); return; } // Check format if (fHeader.fFormatTag != kPCMFormatTag) { IError("Invalid format in plCachedFileReader"); return; } fseek(fFileHandle, 0, SEEK_END); fDataLength = ftell(fFileHandle) - sizeof(plWAVHeader); fseek(fFileHandle, sizeof(plWAVHeader), SEEK_SET); } }
double TOfNextMajor(Edge *e, EdgeList *es, double sought_m ) { /* We want to find t so that Mspline(t) = sought_m */ /* the curve is monotonic */ Spline1D *msp = &e->spline->splines[es->major]; double new_t; if ( es->is_overlap ) { /* if we've adjusted the height then we won't be able to find it restricting */ /* t between [0,1] as we do. So it's a special case. (this is to handle */ /* hstem hints) */ if ( e->max_adjusted && sought_m==e->mmax ) { e->m_cur = sought_m; return( e->up?1.0:0.0 ); } new_t = IterateSplineSolve(msp,e->t_mmin,e->t_mmax,(sought_m+es->mmin)/es->scale,.001); if ( new_t==-1 ) IError( "No Solution"); e->m_cur = (((msp->a*new_t + msp->b)*new_t+msp->c)*new_t + msp->d)*es->scale - es->mmin; return( new_t ); } else { Spline *sp = e->spline; if ( sp->islinear ) { new_t = e->t_cur + (sought_m-e->m_cur)/(es->scale * msp->c); e->m_cur = (msp->c*new_t + msp->d)*es->scale - es->mmin; return( new_t ); } /* if we have a spline that is nearly horizontal at its max. endpoint */ /* then finding A value of t for which y has the right value isn't good */ /* enough (at least not when finding intersections) */ if ( sought_m+1>e->mmax ) { e->m_cur = e->mmax; return( e->t_mmax ); } /* if we've adjusted the height then we won't be able to find it restricting */ /* t between [0,1] as we do. So it's a special case. (this is to handle */ /* hstem hints) */ if ( e->max_adjusted && sought_m==e->mmax ) { e->m_cur = sought_m; return( e->up?1.0:0.0 ); } new_t = IterateSplineSolve(msp,e->t_mmin,e->t_mmax,(sought_m+es->mmin)/es->scale,.001); if ( new_t==-1 ) IError( "No Solution"); e->m_cur = (((msp->a*new_t + msp->b)*new_t+msp->c)*new_t + msp->d)*es->scale - es->mmin; return( new_t ); } }
static int SFAddScriptLangIndex(SplineFont *_sf,uint32 script,uint32 lang) { int i; SplineFont1 *sf; if ( _sf->cidmaster ) _sf = _sf->cidmaster; else if ( _sf->mm!=NULL ) _sf=_sf->mm->normal; if ( _sf->sfd_version>=2 ) IError( "SFFindBiggestScriptLangIndex called with bad version number.\n" ); sf = (SplineFont1 *) _sf; if ( script==0 ) script=DEFAULT_SCRIPT; if ( lang==0 ) lang=DEFAULT_LANG; if ( sf->script_lang==NULL ) sf->script_lang = calloc(2,sizeof(struct script_record *)); for ( i=0; sf->script_lang[i]!=NULL; ++i ) { if ( sf->script_lang[i][0].script==script && sf->script_lang[i][1].script==0 && sf->script_lang[i][0].langs[0]==lang && sf->script_lang[i][0].langs[1]==0 ) return( i ); } sf->script_lang = realloc(sf->script_lang,(i+2)*sizeof(struct script_record *)); sf->script_lang[i] = calloc(2,sizeof(struct script_record)); sf->script_lang[i][0].script = script; sf->script_lang[i][0].langs = malloc(2*sizeof(uint32)); sf->script_lang[i][0].langs[0] = lang; sf->script_lang[i][0].langs[1] = 0; sf->script_lang[i+1] = NULL; sf->sli_cnt = i+1; return( i ); }
static void AddMajorEdge(EdgeList *es, Spline *sp) { Edge *e, *pr; real m1; Spline1D *msp = &sp->splines[es->major], *osp = &sp->splines[es->other]; e = gcalloc(1,sizeof(Edge)); e->spline = sp; e->mmin = e->mmax = m1 = msp->d * es->scale - es->mmin; e->t_mmin = 0; e->t_mmax = 1; e->up = false; e->o_mmin = osp->d * es->scale; e->o_mmax = ( osp->a + osp->b + osp->c + osp->d ) * es->scale; if ( e->o_mmin == e->o_mmax ) { /* Just a point? */ free(e); return; } if ( e->mmin<0 ) IError("Grg!"); if ( ceil(e->m_cur)>e->mmax ) { free(e); return; } if ( es->majors==NULL || es->majors->mmin>=m1 ) { e->esnext = es->majors; es->majors = e; } else { for ( pr=es->majors; pr->esnext!=NULL && pr->esnext->mmin<m1; pr = pr->esnext ); e->esnext = pr->esnext; pr->esnext = e; } }
static OTLookup *CreateLookup(SplineFont1 *sf,uint32 tag, int sli, int flags,enum possub_type type) { OTLookup *otl = XZALLOC(OTLookup); otl->lookup_type = type == pst_position ? gpos_single : type == pst_pair ? gpos_pair : type == pst_contextpos ? gpos_context : type == pst_chainpos ? gpos_contextchain : type == pst_substitution ? gsub_single : type == pst_alternate ? gsub_alternate : type == pst_multiple ? gsub_multiple : type == pst_ligature ? gsub_ligature : type == pst_contextsub ? gsub_context : type == pst_chainsub ? gsub_contextchain : ot_undef; if ( otl->lookup_type == ot_undef ) IError("Unknown lookup type"); if ( otl->lookup_type<gpos_single ) { otl->next = sf->sf.gsub_lookups; sf->sf.gsub_lookups = otl; } else { otl->next = sf->sf.gpos_lookups; sf->sf.gpos_lookups = otl; } otl->lookup_flags = flags; otl->features = FeaturesFromTagSli(tag,sli,sf); /* We will set the lookup_index after we've ordered the list */ /* We will set the lookup_name after we've assigned the index */ /* We will add subtables as we need them */ return( otl ); }
plBufferedFileReader::plBufferedFileReader( const plFileName &path, plAudioCore::ChannelSelect whichChan ) { // Init some stuff fBufferSize = 0; fBuffer = nil; fCursor = 0; hsAssert( path.IsValid(), "Invalid path specified in plBufferedFileReader" ); // Ask plAudioFileReader for another reader to get this file // Note: have this reader do the chanSelect for us plAudioFileReader *reader = plAudioFileReader::CreateReader( path, whichChan ); if( reader == nil || !reader->IsValid() ) { delete reader; IError( "Unable to open file to read in to RAM buffer" ); return; } fHeader = reader->GetHeader(); fBufferSize = reader->GetDataSize(); fBuffer = new uint8_t[ fBufferSize ]; //plProfile_NewMem( SndBufferedMem, fBufferSize ); if( fBuffer == nil ) { delete reader; IError( "Unable to allocate RAM buffer" ); return; } if( !reader->Read( fBufferSize, fBuffer ) ) { delete reader; IError( "Unable to read file into RAM buffer" ); return; } // All done! delete reader; }
static void ttf_dumpcvar(struct alltabs *at, MMSet *mm) { int16 **deltas; int ptcnt, cnt, pcnt; int i,j,rj,big; int tuple_size; uint32 start, end; uint16 *pts; deltas = CvtFindDeltas(mm,&ptcnt); if ( deltas == NULL ) return; for ( i=cnt=0; i<mm->instance_count; ++i ) if ( deltas[i]!=NULL ) ++cnt; if ( cnt==0 ) { free(deltas); return; } tuple_size = 4+2*mm->axis_count; at->cvar = tmpfile2(); putlong( at->cvar, 0x00010000 ); /* Format */ putshort( at->cvar, cnt ); /* Number of instances with cvt tables (tuple count of interesting tuples) */ putshort( at->cvar, 8+cnt*tuple_size ); /* Offset to data */ for ( i=0; i<mm->instance_count; ++i ) if ( deltas[i]!=NULL ) { putshort( at->cvar, 0 ); /* tuple data size, figure out later */ putshort( at->cvar, 0xa000 ); /* tuple coords follow, private points in data */ for ( j=0; j<mm->axis_count; ++j ) putshort( at->cvar, rint(16384*mm->positions[i*mm->axis_count+j]) ); } if ( ftell( at->cvar )!=8+cnt*tuple_size ) IError( "Data offset wrong" ); for ( i=cnt=0; i<mm->instance_count; ++i ) if ( deltas[i]!=NULL ) { start = ftell(at->cvar); for ( j=pcnt=0; j<ptcnt; ++j ) if ( deltas[i][j]!=0 ) ++pcnt; pts = malloc(pcnt*sizeof(uint16)); for ( j=pcnt=0; j<ptcnt; ++j ) if ( deltas[i][j]!=0 ) pts[pcnt++]=j; if ( pcnt>0x7f ) { putc(0x80|(pcnt>>8), at->cvar ); putc(pcnt&0xff, at->cvar); } else
static void CVMergeSPLS(CharView *cv,SplineSet *ss, SplinePoint *base,SplinePoint *sp) { int order2 = cv->b.layerheads[cv->b.drawmode]->order2; cv->joinvalid = true; cv->joinpos = *sp; cv->joinpos.selected = false; if ( sp->prev!=NULL ) SplineSetReverse(cv->p.spl); if ( sp->prev!=NULL ) IError("Base point not at start of splineset in CVMouseDownPoint"); /* remove the old spl entry from the chain */ if ( cv->p.spl==cv->b.layerheads[cv->b.drawmode]->splines ) cv->b.layerheads[cv->b.drawmode]->splines = cv->p.spl->next; else { SplineSet *temp; for ( temp = cv->b.layerheads[cv->b.drawmode]->splines; temp->next!=cv->p.spl; temp = temp->next ); temp->next = cv->p.spl->next; } if ( order2 && (!RealNear(base->nextcp.x,sp->prevcp.x) || !RealNear(base->nextcp.y,sp->prevcp.y)) ) { base->nonextcp = sp->noprevcp = true; base->nextcp = base->me; sp->prevcp = sp->me; } SplineMake(base,sp,order2); SplineCharDefaultNextCP(base); SplineCharDefaultPrevCP(sp); if ( sp->pointtype==pt_tangent ) { SplineCharTangentNextCP(sp); if ( sp->next ) SplineRefigure(sp->next ); } ss->last = cv->p.spl->last; if ( ss->spiros && cv->p.spl->spiros ) { if ( ss->spiro_cnt+cv->p.spl->spiro_cnt > ss->spiro_max ) ss->spiros = realloc(ss->spiros, (ss->spiro_max = ss->spiro_cnt+cv->p.spl->spiro_cnt)*sizeof(spiro_cp)); memcpy(ss->spiros+ss->spiro_cnt-1, cv->p.spl->spiros+1, (cv->p.spl->spiro_cnt-1)*sizeof(spiro_cp)); ss->spiro_cnt += cv->p.spl->spiro_cnt-2; } else SplineSetSpirosClear(ss); cv->p.spl->last = cv->p.spl->first = NULL; cv->p.spl->spiros = 0; SplinePointListFree(cv->p.spl); cv->p.spl = NULL; }
static OTLookup *CreateACLookup(SplineFont1 *sf,AnchorClass1 *ac) { OTLookup *otl = XZALLOC(OTLookup); otl->lookup_type = ac->ac.type == act_mark ? gpos_mark2base : ac->ac.type == act_mkmk ? gpos_mark2mark : ac->ac.type == act_curs ? gpos_cursive : ac->ac.type == act_mklg ? gpos_mark2ligature : ot_undef; if ( otl->lookup_type == ot_undef ) IError("Unknown AnchorClass type"); otl->next = sf->sf.gpos_lookups; sf->sf.gpos_lookups = otl; otl->lookup_flags = ac->flags; otl->features = FeaturesFromTagSli(ac->feature_tag,ac->script_lang_index,sf); /* We will set the lookup_index after we've ordered the list */ /* We will set the lookup_name after we've assigned the index */ /* We will add one subtable soon */ return( otl ); }
/* Builds up a menu containing the titles of all the unused recent files */ void MenuRecentBuild(GWindow base,struct gmenuitem *mi,GEvent *e) { int i, cnt, cnt1; FontViewBase *fv; GMenuItem *sub; if ( mi->sub!=NULL ) { GMenuItemArrayFree(mi->sub); mi->sub = NULL; } cnt = 0; for ( i=0; i<RECENT_MAX && RecentFiles[i]!=NULL; ++i ) { for ( fv=(FontViewBase *) fv_list; fv!=NULL; fv=fv->next ) if ( fv->sf->filename!=NULL && strcmp(fv->sf->filename,RecentFiles[i])==0 ) break; if ( fv==NULL ) ++cnt; } if ( cnt==0 ) { /* This can't happen */ return; } sub = calloc(cnt+1,sizeof(GMenuItem)); cnt1 = 0; for ( i=0; i<RECENT_MAX && RecentFiles[i]!=NULL; ++i ) { for ( fv=(FontViewBase *) fv_list; fv!=NULL; fv=fv->next ) if ( fv->sf->filename!=NULL && strcmp(fv->sf->filename,RecentFiles[i])==0 ) break; if ( fv==NULL ) { GMenuItem *mi = &sub[cnt1++]; mi->ti.userdata = RecentFiles[i]; mi->ti.bg = mi->ti.fg = COLOR_DEFAULT; mi->invoke = RecentSelect; mi->ti.text = def2u_copy(GFileNameTail(RecentFiles[i])); } } if ( cnt!=cnt1 ) IError( "Bad counts in MenuRecentBuild"); mi->sub = sub; }
int SFFindBiggestScriptLangIndex(SplineFont *_sf,uint32 script,uint32 lang) { int i, best_sli= -1, best_cnt= -1, cnt; SplineFont1 *sf = (SplineFont1 *) _sf; if ( _sf->sfd_version>=2 ) IError( "SFFindBiggestScriptLangIndex called with bad version number.\n" ); if ( sf->script_lang==NULL ) SFGuessScriptList(sf); for ( i=0; sf->script_lang[i]!=NULL; ++i ) { if ( SLContains(sf->script_lang[i],script,lang)) { cnt = SLCount(sf->script_lang[i]); if ( cnt>best_cnt ) { best_sli = i; best_cnt = cnt; } } } if ( best_sli==-1 ) return( SFAddScriptLangIndex(_sf,script,lang) ); return( best_sli ); }
hsBool plCachedFileReader::OpenForWriting(const char *path, plWAVHeader &header) { hsAssert(path != nil, "Invalid path specified in plCachedFileReader"); fHeader = header; fCurPosition = 0; fDataLength = 0; strncpy(fFilename, path, sizeof(fFilename)); /// Open the file as a plain binary stream fFileHandle = fopen(path, "wb"); if (fFileHandle != nil) { if (fwrite(&fHeader, 1, sizeof(plWAVHeader), fFileHandle) != sizeof(plWAVHeader)) { IError("Could not write WAV file header in plCachedFileReader"); return false; } } return fFileHandle != nil; }
const char *FindUnicharName(void) { /* Iconv and libiconv use different names for UCS2. Just great. Perhaps */ /* different versions of each use still different names? */ /* Even worse, both accept UCS-2, but under iconv it means native byte */ /* ordering and under libiconv it means big-endian */ iconv_t test; static char *goodname = NULL; #ifdef UNICHAR_16 static char *names[] = { "UCS-2-INTERNAL", "UCS-2", "UCS2", "ISO-10646/UCS2", "UNICODE", NULL }; static char *namesle[] = { "UCS-2LE", "UNICODELITTLE", NULL }; static char *namesbe[] = { "UCS-2BE", "UNICODEBIG", NULL }; #else static char *names[] = { "UCS-4-INTERNAL", "UCS-4", "UCS4", "ISO-10646-UCS-4", "UTF-32", NULL }; static char *namesle[] = { "UCS-4LE", "UTF-32LE", NULL }; static char *namesbe[] = { "UCS-4BE", "UTF-32BE", NULL }; #endif char **testnames; int i; union { short s; char c[2]; } u; if ( goodname!=NULL ) return( goodname ); u.c[0] = 0x1; u.c[1] = 0x2; if ( u.s==0x201 ) { /* Little endian */ testnames = namesle; } else { testnames = namesbe; } for ( i=0; testnames[i]!=NULL; ++i ) { test = iconv_open(testnames[i],"ISO-8859-1"); if ( test!=(iconv_t) -1 && test!=NULL ) { iconv_close(test); goodname = testnames[i]; break; } } if ( goodname==NULL ) { for ( i=0; names[i]!=NULL; ++i ) { test = iconv_open(names[i],"ISO-8859-1"); if ( test!=(iconv_t) -1 && test!=NULL ) { iconv_close(test); goodname = names[i]; break; } } } if ( goodname==NULL ) { #ifdef UNICHAR_16 IError( "I can't figure out your version of iconv(). I need a name for the UCS-2 encoding and I can't find one. Reconfigure --without-iconv. Bye."); #else IError( "I can't figure out your version of iconv(). I need a name for the UCS-4 encoding and I can't find one. Reconfigure --without-iconv. Bye."); #endif exit( 1 ); } test = iconv_open(goodname,"Mac"); if ( test==(iconv_t) -1 || test==NULL ) { IError( "Your version of iconv does not support the \"Mac Roman\" encoding.\nIf this causes problems, reconfigure --without-iconv." ); } else iconv_close(test); /* I really should check for ISO-2022-JP, KR, CN, and all the other encodings */ /* I might find in a ttf 'name' table. But those tables take too long to build */ return( goodname ); }
static int Trans_OK(GGadget *g, GEvent *e) { real transform[6], trans[6], t[6]; bigreal angle, angle2; int i, index, err; int alllayers = false, round_2_int = false, dokerns = false, dokp=false; int dogrid = false, dowidth = false; BasePoint base; int origin, bvpos=0; BVTFunc bvts[TCnt+1]; static int warned = false; int isapply = GGadgetGetCid(g) == CID_Apply; if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) { TransData *td = GDrawGetUserData(GGadgetGetWindow(g)); transform[0] = transform[3] = 1.0; transform[1] = transform[2] = transform[4] = transform[5] = 0; base.x = base.y = 0; origin = GGadgetGetFirstListSelectedItem( GWidgetGetControl(td->gw,CID_Origin)); if ( GWidgetGetControl(td->gw,CID_AllLayers)!=NULL ) alllayers = GGadgetIsChecked(GWidgetGetControl(td->gw,CID_AllLayers)); if ( GWidgetGetControl(td->gw,CID_DoGrid)!=NULL ) dogrid = GGadgetIsChecked(GWidgetGetControl(td->gw,CID_DoGrid)); if ( GWidgetGetControl(td->gw,CID_DoWidth)!=NULL ) dowidth = GGadgetIsChecked(GWidgetGetControl(td->gw,CID_DoWidth)); else dowidth = true; if ( GWidgetGetControl(td->gw,CID_DoSimplePos)!=NULL ) dokp = GGadgetIsChecked(GWidgetGetControl(td->gw,CID_DoSimplePos)); if ( GWidgetGetControl(td->gw,CID_DoKerns)!=NULL ) dokerns = GGadgetIsChecked(GWidgetGetControl(td->gw,CID_DoKerns)); round_2_int = GGadgetIsChecked(GWidgetGetControl(td->gw,CID_Round2Int)); if ( isapply ) alllayers = dogrid = dokp = dokerns = false; if ( td->getorigin!=NULL ) { (td->getorigin)(td->userdata,&base,origin ); transform[4] = -base.x; transform[5] = -base.y; } for ( i=0; i<TCnt; ++i ) { index = GGadgetGetFirstListSelectedItem( GWidgetGetControl(td->gw,CID_Type+i*TBlock_CIDOffset)); trans[0] = trans[3] = 1.0; trans[1] = trans[2] = trans[4] = trans[5] = 0; err = 0; switch ( index ) { case 0: /* Do Nothing */ break; case 1: /* Move */ trans[4] = GetReal8(td->gw,CID_XMove+i*TBlock_CIDOffset,_("X Movement"),&err); trans[5] = GetReal8(td->gw,CID_YMove+i*TBlock_CIDOffset,_("Y Movement"),&err); bvts[bvpos].x = trans[4]; bvts[bvpos].y = trans[5]; bvts[bvpos++].func = bvt_transmove; break; case 2: /* Rotate */ angle = GetReal8(td->gw,CID_Angle+i*TBlock_CIDOffset,_("Rotation Angle"),&err); if ( GGadgetIsChecked( GWidgetGetControl(td->gw,CID_Clockwise+i*TBlock_CIDOffset)) ) angle = -angle; if ( fmod(angle,90)!=0 ) bvts[0].func = bvt_none; /* Bad trans=> No trans */ else { angle = fmod(angle,360); if ( angle<0 ) angle+=360; if ( angle==90 ) bvts[bvpos++].func = bvt_rotate90ccw; else if ( angle==180 ) bvts[bvpos++].func = bvt_rotate180; else if ( angle==270 ) bvts[bvpos++].func = bvt_rotate90cw; } angle *= 3.1415926535897932/180; trans[0] = trans[3] = cos(angle); trans[2] = -(trans[1] = sin(angle)); break; case 3: /* Scale Uniformly */ trans[0] = trans[3] = GetReal8(td->gw,CID_Scale+i*TBlock_CIDOffset,_("Scale Factor"),&err)/100.0; bvts[0].func = bvt_none; /* Bad trans=> No trans */ break; case 4: /* Scale */ trans[0] = GetReal8(td->gw,CID_XScale+i*TBlock_CIDOffset,_("X Scale Factor"),&err)/100.0; trans[3] = GetReal8(td->gw,CID_YScale+i*TBlock_CIDOffset,_("Y Scale Factor"),&err)/100.0; bvts[0].func = bvt_none; /* Bad trans=> No trans */ break; case 5: /* Flip */ if ( GGadgetIsChecked( GWidgetGetControl(td->gw,CID_Horizontal+i*TBlock_CIDOffset)) ) { trans[0] = -1; bvts[bvpos++].func = bvt_fliph; } else { trans[3] = -1; bvts[bvpos++].func = bvt_flipv; } break; case 6: /* Skew */ angle = GetReal8(td->gw,CID_SkewAng+i*TBlock_CIDOffset,_("Skew Angle"),&err); if ( GGadgetIsChecked( GWidgetGetControl(td->gw,CID_CounterClockwise+i*TBlock_CIDOffset)) ) angle = -angle; angle *= 3.1415926535897932/180; trans[2] = tan(angle); skewselect(&bvts[bvpos],trans[2]); ++bvpos; break; case 7: /* 3D rotate */ angle = GetReal8(td->gw,CID_XAxis+i*TBlock_CIDOffset,_("Rotation about X Axis"),&err) * 3.1415926535897932/180; angle2 = GetReal8(td->gw,CID_YAxis+i*TBlock_CIDOffset,_("Rotation about Y Axis"),&err) * 3.1415926535897932/180; trans[0] = cos(angle2); trans[3] = cos(angle ); bvts[0].func = bvt_none; /* Bad trans=> No trans */ break; default: IError("Unexpected selection in Transform"); err = 1; break; } if ( err ) return(true); #if 0 printf( "(%g,%g,%g,%g,%g,%g)*(%g,%g,%g,%g,%g,%g) = ", trans[0], trans[1], trans[2], trans[3], trans[4], trans[5], transform[0], transform[1], transform[2], transform[3], transform[4], transform[5]); #endif t[0] = transform[0]*trans[0] + transform[1]*trans[2]; t[1] = transform[0]*trans[1] + transform[1]*trans[3]; t[2] = transform[2]*trans[0] + transform[3]*trans[2]; t[3] = transform[2]*trans[1] + transform[3]*trans[3]; t[4] = transform[4]*trans[0] + transform[5]*trans[2] + trans[4]; t[5] = transform[4]*trans[1] + transform[5]*trans[3] + trans[5]; memcpy(transform,t,sizeof(t)); #if 0 printf( "(%g,%g,%g,%g,%g,%g)\n", transform[0], transform[1], transform[2], transform[3], transform[4], transform[5]); #endif } bvts[bvpos++].func = bvt_none; /* Done */ for ( i=0; i<6; ++i ) if ( RealNear(transform[i],0)) transform[i] = 0; transform[4] += base.x; transform[5] += base.y; if (( transform[1]!=0 || transform[2]!=0 ) && !warned ) { ff_post_notice(_("Warning"),_("After rotating or skewing a glyph you should probably apply Element->Add Extrema")); warned = true; } (td->transfunc)(td->userdata,transform,origin,bvts, (alllayers?fvt_alllayers:0)| (dogrid?fvt_dogrid:0)| (dowidth?0:fvt_dontmovewidth)| (round_2_int?fvt_round_to_int:0)| (dokp?fvt_scalepstpos:0)| (dokerns?fvt_scalekernclasses:0)| (isapply?fvt_justapply:0)); td->done = !isapply; td->applied = isapply; } return( true ); }
static int splash_e_h(GWindow gw, GEvent *event) { static int splash_cnt; GRect old; int i, y, x; static char *foolishness[] = { /* GT: These strings are for fun. If they are offensive or incomprehensible */ /* GT: simply translate them as something dull like: "FontForge" */ /* GT: This is a spoof of political slogans, designed to point out how foolish they are */ N_("A free press discriminates\nagainst the illiterate."), N_("A free press discriminates\nagainst the illiterate."), /* GT: This is a pun on the old latin drinking song "Gaudeamus igature!" */ N_("Gaudeamus Ligature!"), N_("Gaudeamus Ligature!"), /* GT: Spoof on the bible */ N_("In the beginning was the letter..."), /* GT: Some wit at MIT came up with this ("ontology recapitulates phylogony" is the original) */ N_("fontology recapitulates file-ogeny") }; switch ( event->type ) { case et_create: GDrawGrabSelection(gw,sn_user1); break; case et_expose: GDrawPushClip(gw,&event->u.expose.rect,&old); GDrawDrawImage(gw,&splashimage,NULL,0,0); GDrawSetFont(gw,splash_font); y = splashimage.u.image->height + as + fh/2; for ( i=1; i<linecnt; ++i ) { if ( is>=lines[i-1]+1 && is<lines[i] ) { x = 8+GDrawDrawText(gw,8,y,lines[i-1]+1,is-lines[i-1]-1,0x000000); GDrawSetFont(gw,splash_italic); GDrawDrawText(gw,x,y,is,lines[i]-is,0x000000); } else if ( ie>=lines[i-1]+1 && ie<lines[i] ) { x = 8+GDrawDrawText(gw,8,y,lines[i-1]+1,ie-lines[i-1]-1,0x000000); GDrawSetFont(gw,splash_font); GDrawDrawText(gw,x,y,ie,lines[i]-ie,0x000000); } else GDrawDrawText(gw,8,y,lines[i-1]+1,lines[i]-lines[i-1]-1,0x000000); y += fh; } GDrawPopClip(gw,&old); break; case et_map: splash_cnt = 0; break; case et_timer: if ( event->u.timer.timer==autosave_timer ) { DoAutoSaves(); } else if ( event->u.timer.timer==splasht ) { if ( ++splash_cnt==1 ) GDrawResize(gw,splashimage.u.image->width,splashimage.u.image->height-30); else if ( splash_cnt==2 ) GDrawResize(gw,splashimage.u.image->width,splashimage.u.image->height); else if ( splash_cnt>=7 ) { GGadgetEndPopup(); GDrawSetVisible(gw,false); GDrawCancelTimer(splasht); splasht = NULL; } } else { DoDelayedEvents(event); } break; case et_char: case et_mousedown: case et_close: GGadgetEndPopup(); GDrawSetVisible(gw,false); break; case et_mousemove: GGadgetPreparePopup8(gw,_(foolishness[rand()%(sizeof(foolishness)/sizeof(foolishness[0]))]) ); break; case et_selclear: /* If this happens, it means someone wants to send us a message with a*/ /* filename to open. So we need to ask for it, process it, and then */ /* take the selection back again */ if ( event->u.selclear.sel == sn_user1 ) { int len; char *arg; arg = GDrawRequestSelection(splashw,sn_user1,"STRING",&len); if ( arg==NULL ) return( true ); if ( strcmp(arg,"-new")==0 || strcmp(arg,"--new")==0 ) FontNew(); else if ( strcmp(arg,"-open")==0 || strcmp(arg,"--open")==0 ) _FVMenuOpen(NULL); else if ( strcmp(arg,"-quit")==0 || strcmp(arg,"--quit")==0 ) MenuExit(NULL,NULL,NULL); else ViewPostScriptFont(arg,0); free(arg); GDrawGrabSelection(splashw,sn_user1); } break; case et_destroy: IError("Who killed the splash screen?"); break; } return( true ); }
void plOGGCodec::IOpen( const char *path, plAudioCore::ChannelSelect whichChan ) { hsAssert( path != nil, "Invalid path specified in plOGGCodec reader" ); // plNetClientApp::StaticDebugMsg("Ogg Open %s, t=%f, start", path, hsTimer::GetSeconds()); strncpy( fFilename, path, sizeof( fFilename ) ); fWhichChannel = whichChan; /// Open the file as a plain binary stream fFileHandle = fopen( path, "rb" ); if( fFileHandle != nil ) { /// Create the OGG data struct fOggFile = new OggVorbis_File; /// Open the OGG decompressor if( ov_open( fFileHandle, fOggFile, NULL, 0 ) < 0 ) { IError( "Unable to open OGG source file" ); return; } /// Construct some header info from the ogg info vorbis_info *vInfo = ov_info( fOggFile, -1 ); fHeader.fFormatTag = 1; fHeader.fNumChannels = vInfo->channels; fHeader.fNumSamplesPerSec = vInfo->rate; // Funny thing about the bits per sample: we get to CHOOSE. Go figure! fHeader.fBitsPerSample = ( fDecodeFormat == k8bitUnsigned ) ? 8 : 16; // Why WAV files hold this info when it can be calculated is beyond me... fHeader.fBlockAlign = ( fHeader.fBitsPerSample * fHeader.fNumChannels ) >> 3; fHeader.fAvgBytesPerSec = fHeader.fNumSamplesPerSec * fHeader.fBlockAlign; /// The size in bytes of our PCM data stream /// Note: OGG sometimes seems to be off by 1 sample, which causes our reads to suck /// because we end up waiting for 1 more sample than we actually have. So, on the /// assumption that OGG is just slightly wrong sometimes, we just subtract 1 sample /// from what it tells us. As Brice put it, who's going to miss 1/40,000'ths of a second? fDataSize = (uint32_t)(( ov_pcm_total( fOggFile, -1 ) - 1 ) * fHeader.fBlockAlign); /// Channel select if( fWhichChannel != plAudioCore::kAll ) { fChannelAdjust = 2; fChannelOffset = ( fWhichChannel == plAudioCore::kLeft ) ? 0 : 1; } else { fChannelAdjust = 1; fChannelOffset = 0; } /// Construct our fake header for channel adjustment fFakeHeader = fHeader; fFakeHeader.fAvgBytesPerSec /= fChannelAdjust; fFakeHeader.fNumChannels /= (uint16_t)fChannelAdjust; fFakeHeader.fBlockAlign /= (uint16_t)fChannelAdjust; SetPosition( 0 ); }
static int Delta_OK(GGadget *g, GEvent *e) { if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) { QGData *qg = GDrawGetUserData(GGadgetGetWindow(g)); int err=false; int dpi, depth; double within; char *sizes; within = GetReal8(qg->gw,CID_Within,_("Proximity"),&err); dpi = GetInt8(qg->gw,CID_DPI,_("DPI"),&err); if ( err ) return(true); if ( within<=0 || within>=.5 ) { ff_post_error(_("Bad Number"),_("The \"Proximity\" field must be more than 0 and less than a half.")); return( true ); } if ( dpi<10 || dpi>5000 ) { ff_post_error(_("Unreasonable DPI"),_("The \"DPI\" field must be more than 10 and less than 5000.")); return( true ); } depth = GGadgetIsChecked(GWidgetGetControl(qg->gw,CID_BW)) ? 1 : 8; sizes = GGadgetGetTitle8(GWidgetGetControl(qg->gw,CID_Sizes)); GGadgetSetVisible(GWidgetGetControl(qg->gw,CID_Msg),true); GGadgetSetVisible(GWidgetGetControl(qg->gw,CID_Ok),false); GGadgetSetVisible(GWidgetGetControl(qg->gw,CID_Cancel),false); GDrawSetCursor(qg->gw,ct_watch); GDrawProcessPendingEvents(NULL); qg->within = within; qg->dpi = dpi; qg->pixelsizes = sizes; qg->depth = depth; TopFindQuestionablePoints(qg); GGadgetSetVisible(GWidgetGetControl(qg->gw,CID_Msg),false); GGadgetSetVisible(GWidgetGetControl(qg->gw,CID_Ok),true); GGadgetSetVisible(GWidgetGetControl(qg->gw,CID_Cancel),true); GDrawSetCursor(qg->gw,ct_pointer); GDrawProcessPendingEvents(NULL); if ( qg->error!=qg_ok ) { switch ( qg->error ) { case qg_notnumber: ff_post_error(_("Bad Number"),_("An entry in the \"Sizes\" field is not a number.")); break; case qg_badnumber: ff_post_error(_("Bad Number"),_("An entry in the \"Sizes\" field is unreasonable.")); break; case qg_badrange: ff_post_error(_("Bad Number"),_("An range in the \"Sizes\" field is incorrectly ordered.")); break; case qg_nofont: ff_post_error(_("FreeType unavailable"),_("FreeType unavailable.")); break; default: IError(_("Unexpected error")); break; } free(sizes); qg->cur = 0; return( true ); } free(delta_sizes); delta_within = within; delta_dpi = dpi; delta_depth = depth; delta_sizes = sizes; if ( qg->cur==0 ) { ff_post_error(_("Nothing found"),_("Nothng found.")); qg->done = true; return( true ); } if ( qg->cur >= qg->max ) qg->qg = realloc(qg->qg,(qg->max += 1) * sizeof(QuestionableGrid)); memset(qg->qg+qg->cur,0,sizeof(QuestionableGrid)); GDrawSetVisible(qg->gw,false); StartDeltaDisplay(qg); qg->done = true; } return( true ); }
/* When the user tries to add a point (by doing a mouse down with a point tool selected) there are several cases to be looked at: If there is a single point selected and it is at the begining/end of an open spline set if we clicked on another point which is the begining/end of an open splineset draw a spline connecting the two spline sets and merge them (or if it's the same spline set, then close it) else create a new point where we clicked draw a spline between the selected point and the new one deselect the old point select the new one endif else if they clicked on a spline split the spline into two bits at the point where they clicked else create a new point where they clicked put it on a new splineset select it endif and, if the old point is a tangent, we may need to adjust its control pt With the introduction of spiro mode (Raph Levien's clothoid splines) we've got to worry about all the above cases for spiro points too. */ void CVMouseDownPoint(CharView *cv, GEvent *event) { SplineSet *sel, *ss; SplinePoint *sp, *base = NULL; SplineChar *sc = cv->b.sc; enum pointtype ptype = (cv->active_tool==cvt_curve?pt_curve: cv->active_tool==cvt_hvcurve?pt_hvcurve: cv->active_tool==cvt_corner?pt_corner: cv->active_tool==cvt_tangent?pt_tangent: /*cv->active_tool==cvt_pen?*/pt_corner); int order2 = cv->b.layerheads[cv->b.drawmode]->order2; int order2_style = (order2 && !(event->u.mouse.state&ksm_meta)) || (!order2 && (event->u.mouse.state&ksm_meta)); cv->active_spl = NULL; cv->active_sp = NULL; if ( cv->b.sc->inspiro && hasspiro()) { CVMouseDownSpiroPoint(cv, event); return; } sel = CVAnySelPointList(cv); if ( sel!=NULL ) { if ( sel->first->selected ) base = sel->first; else base = sel->last; if ( base==cv->p.sp ) return; /* We clicked on the active point, that's a no-op */ } CVPreserveState(&cv->b); CVClearSel(cv); if ( sel!=NULL ) { sp = cv->p.sp; cv->lastselpt = base; ss = sel; if ( base->next!=NULL ) SplineSetReverse(sel); if ( base->next!=NULL ) IError("Base point not at end of splineset in CVMouseDownPoint"); if ( sp==NULL || (sp->next!=NULL && sp->prev!=NULL) || sp==base ) { /* Add a new point */ SplineSetSpirosClear(sel); sp = SplinePointCreate( cv->p.cx, cv->p.cy ); sp->noprevcp = sp->nonextcp = 1; sp->nextcpdef = sp->prevcpdef = 1; sp->pointtype = ptype; sp->selected = true; if ( !base->nonextcp && order2_style && cv->active_tool==cvt_pen ) { sp->prevcp = base->nextcp; sp->noprevcp = false; sp->me.x = ( sp->prevcp.x + sp->nextcp.x )/2; sp->me.y = ( sp->prevcp.y + sp->nextcp.y )/2; sp->nonextcp = false; sp->pointtype = pt_curve; } else if ( order2 && !base->nonextcp ) { sp->prevcp = base->nextcp; sp->noprevcp = false; if ( cv->active_tool==cvt_pen ) { sp->nextcp.x = sp->me.x - (sp->prevcp.x-sp->me.x); sp->nextcp.y = sp->me.y - (sp->prevcp.y-sp->me.y); sp->nonextcp = false; sp->pointtype = pt_curve; } } if ( base->nonextcp ) base->nextcpdef = true; SplineMake(base,sp,order2); if ( cv->active_tool!=cvt_pen ) { SplineCharDefaultNextCP(base); SplineCharDefaultPrevCP(sp); } ss->last = sp; } else if ( cv->p.spl==sel ) { /* Close the current spline set */ SplineSetSpirosClear(sel); cv->joinvalid = true; cv->joinpos = *sp; cv->joinpos.selected = false; if ( order2 ) { if ( base->nonextcp || sp->noprevcp ) { base->nonextcp = sp->noprevcp = true; base->nextcp = base->me; sp->prevcp = sp->me; } else { base->nextcp.x = sp->prevcp.x = (base->nextcp.x+sp->prevcp.x)/2; base->nextcp.y = sp->prevcp.y = (base->nextcp.y+sp->prevcp.y)/2; } base->nextcpdef = sp->prevcpdef = true; } SplineMake(base,sp,order2); if ( cv->active_tool!=cvt_pen ) SplineCharDefaultNextCP(base); SplineCharDefaultPrevCP(sp); ss->last = sp; if ( sp->pointtype==pt_tangent ) { SplineCharTangentNextCP(sp); if ( sp->next ) SplineRefigure(sp->next ); } } else { /* Merge two spline sets */ SplineSetSpirosClear(sel); CVMergeSPLS(cv,sel, base,sp); } sp->selected = true; if ( base->pointtype==pt_tangent ) { SplineCharTangentPrevCP(base); if ( base->prev!=NULL ) SplineRefigure(base->prev); } } else if ( cv->p.spline!=NULL ) { sp = SplineBisect(cv->p.spline,cv->p.t); cv->joinvalid = true; cv->joinpos = *sp; cv->joinpos.selected = false; if ( cv->active_tool==cvt_pen ) ptype = pt_curve; sp->pointtype = ptype; if ( ptype==pt_hvcurve ) { SPHVCurveForce(sp); } sp->selected = true; ss = cv->p.spl; } else { ss = chunkalloc(sizeof(SplineSet)); sp = SplinePointCreate( cv->p.cx, cv->p.cy ); ss->first = ss->last = sp; ss->next = cv->b.layerheads[cv->b.drawmode]->splines; cv->b.layerheads[cv->b.drawmode]->splines = ss; sp->nonextcp = sp->noprevcp = 1; sp->nextcpdef = sp->prevcpdef = 1; sp->pointtype = ptype; sp->selected = true; } cv->active_spl = ss; cv->active_sp = sp; CVSetCharChanged(cv,true); CVInfoDraw(cv,cv->gw); SCUpdateAll(sc); if ( cv->active_tool == cvt_pen ) cv->p.constrain = sp->me; }
static void AnchorD_FindComplements(AnchorDlg *a) { AnchorClass *ac = a->ap->anchor; enum anchor_type match; AnchorPoint *ap; int i, k, j, cnt; SplineFont *_sf = a->sc->parent, *sf; uint8 *sel, *oldsel; FontView *fv = (FontView *) _sf->fv; EncMap *map = fv->b.map; switch ( a->ap->type ) { case at_mark: switch ( a->ap->anchor->type ) { case act_mark: match = at_basechar; break; case act_mklg: match = at_baselig; break; case act_mkmk: match = at_basemark; break; default: IError( "Unexpected anchor class type" ); match = at_basechar; } break; case at_basechar: case at_baselig: case at_basemark: match = at_mark; break; case at_centry: match = at_cexit; break; case at_cexit: match = at_centry; break; default: match = at_max; break; } if ( _sf->cidmaster!=NULL ) _sf = _sf->cidmaster; for ( j=0; j<2; ++j ) { k = cnt = 0; do { sf = _sf->subfontcnt==0 ? _sf : _sf->subfonts[k]; for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) { for ( ap= sf->glyphs[i]->anchor; ap!=NULL; ap=ap->next ) { if ( ap->anchor == ac && ap->type==match ) { if ( j ) { a->apmatch[cnt].ap = ap; a->apmatch[cnt++].sc = sf->glyphs[i]; } else ++cnt; /* Don't break out of the loop as ligatures can have multiple locations */ } } } ++k; } while ( k<_sf->subfontcnt ); a->cnt = cnt; if ( cnt==0 ) break; if ( j==0 ) a->apmatch = calloc(cnt,sizeof(struct apmatch)); } if ( hasFreeType() && _sf->subfontcnt==0 ) { int enc = map->backmap[a->sc->orig_pos]; if ( enc!=-1 ) { sel = calloc(map->enccount,1); sel[enc] = true; for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) { enc = map->backmap[i]; if ( enc!=-1 ) { for ( ap= sf->glyphs[i]->anchor; ap!=NULL; ap=ap->next ) { if ( ap->anchor == ac && ap->type==match ) { sel[enc] = true; break; } } } } oldsel = fv->b.selected; fv->b.selected = sel; a->freetypecontext = FreeTypeFontContext(_sf,NULL,(FontViewBase *) fv,a->layer); fv->b.selected = oldsel; free(sel); } } }