Beispiel #1
0
void VCurve2DBase::SerializeX( VArchive &ar )
{
  char iVersion = 0;
  if (ar.IsLoading())
  {
    int iLookupCount;
    ar >> iVersion; VASSERT(iVersion==0);
    ar >> m_iNumCurvePoints;
    AllocatePoints(m_iNumCurvePoints);
    if (m_iNumCurvePoints>0)
      ar.Read(m_pPoints,m_iNumCurvePoints*sizeof(VCurvePoint2D),"ffffff",m_iNumCurvePoints);
    ar >> m_fDuration >> m_fMax;
    ar >> iLookupCount;
    if (iLookupCount>0)
      CreateLookup(iLookupCount);
  } else
Beispiel #2
0
void VCurve2DBase::CreateLookup(int iSampleCount, float fScaling)
{
  VASSERT(iSampleCount>1);

  // Lookup values
  if (iSampleCount!=m_iLookupCount)
  {
    FreeLookup();
    m_iLookupCount = iSampleCount;
    m_fLookupCount = ((float)iSampleCount)-0.001f;
    m_pLookupValues = new float[iSampleCount];
  }
  if (!m_pLookupValues)
    return;

  CreateLookup(iSampleCount,m_pLookupValues,1,fScaling);
}
Beispiel #3
0
void VCurve2DBase::UpdateCurve()
{
  m_fDuration = -1.f;
  m_fMax = -1000000000.f;
  if (!m_pPoints)
    return;

  // duration from the last point
  m_fDuration = m_pPoints[m_iNumCurvePoints-1].m_vPos.x;

  VCurvePoint2D *p = m_pPoints;
  for (int i=0;i<m_iNumCurvePoints;i++,p++)
  {
    if (i==0||p->m_vPos.y>m_fMax)
      m_fMax = p->m_vPos.y;
  }

  if (m_iLookupCount>0)
    CreateLookup(m_iLookupCount);
}
Beispiel #4
0
void SFD_AssignLookups(SplineFont1*sf) {
   PST1 *pst, *pst2;
   int isv;
   KernPair1 *kp, *kp2;
   KernClass1 *kc, *kc2;
   FPST1 *fpst;
   ASM1 *sm;
   AnchorClass1 *ac, *ac2;
   int gid, gid2, cnt, i, k, isgpos;
   SplineFont1 *subsf;
   SplineChar *sc, *sc2;
   OTLookup *otl, **all;
   struct lookup_subtable *sub;

   /* Fix up some gunk from really old versions of the sfd format */
   SFDCleanupAnchorClasses(&sf->sf);
   if (sf->sf.uni_interp==ui_unset)
      sf->sf.uni_interp=interp_from_encoding(sf->sf.map->enc, ui_none);

   /* Fixup for an old bug */
   if (sf->sf.pfminfo.os2_winascent<sf->sf.ascent/4
       && !sf->sf.pfminfo.winascent_add) {
      sf->sf.pfminfo.winascent_add=true;
      sf->sf.pfminfo.os2_winascent=0;
      sf->sf.pfminfo.windescent_add=true;
      sf->sf.pfminfo.os2_windescent=0;
   }

   /* First handle the PSTs, no complications here */
   k=0;
   do {
      subsf =
	 sf->sf.subfontcnt==0?sf:(SplineFont1 *) (sf->sf.subfonts[k]);
      for (gid=0; gid<subsf->sf.glyphcnt; ++gid)
	 if ((sc=subsf->sf.glyphs[gid]) != NULL) {
	    for (pst=(PST1 *) (sc->possub); pst != NULL;
		 pst=(PST1 *) (pst->pst.next)) {
	       if (pst->pst.type==pst_lcaret || pst->pst.subtable != NULL)
		  continue;	/* Nothing to do, or already done */
	       otl =
		  CreateLookup(sf, pst->tag, pst->script_lang_index,
			       pst->flags, pst->pst.type);
	       sub=CreateSubtable(otl, sf);
	       /* There might be another PST with the same flags on this glyph */
	       /* And we must fixup the current pst */
	       for (pst2=pst; pst2 != NULL;
		    pst2=(PST1 *) (pst2->pst.next)) {
		  if (pst2->tag==pst->tag
		      && pst2->script_lang_index==pst->script_lang_index
		      && pst2->flags==pst->flags
		      && pst2->pst.type==pst->pst.type)
		     pst2->pst.subtable=sub;
	       }
	       for (gid2=gid+1; gid2<subsf->sf.glyphcnt; ++gid2)
		  if ((sc2=subsf->sf.glyphs[gid2]) != NULL) {
		     for (pst2=(PST1 *) (sc2->possub); pst2 != NULL;
			  pst2=(PST1 *) (pst2->pst.next)) {
			if (pst2->tag==pst->tag
			    && pst2->script_lang_index ==
			    pst->script_lang_index
			    && pst2->flags==pst->flags
			    && pst2->pst.type==pst->pst.type)
			   pst2->pst.subtable=sub;
		     }
		  }
	    }
	 }
      ++k;
   } while (k<sf->sf.subfontcnt);

   /* Now kerns. May need to merge kernclasses to kernpair lookups (different subtables, of course */
   for (isv=0; isv<2; ++isv) {
      k=0;
      do {
	 subsf =
	    sf->sf.subfontcnt ==
	    0?sf:(SplineFont1 *) (sf->sf.subfonts[k]);
	 for (gid=0; gid<subsf->sf.glyphcnt; ++gid)
	    if ((sc=subsf->sf.glyphs[gid]) != NULL) {
	       for (kp=(KernPair1 *) (isv?sc->vkerns:sc->kerns);
		    kp != NULL; kp=(KernPair1 *) (kp->kp.next)) {
		  if (kp->kp.subtable != NULL)
		     continue;	/* already done */
		  otl =
		     CreateLookup(sf,
				  isv?CHR('v', 'k', 'r', 'n'):CHR('k',
								      'e',
								      'r',
								      'n'),
				  kp->sli, kp->flags, pst_pair);
		  sub=CreateSubtable(otl, sf);
		  /* There might be another kp with the same flags on this glyph */
		  /* And we must fixup the current kp */
		  for (kp2=kp; kp2 != NULL;
		       kp2=(KernPair1 *) (kp2->kp.next)) {
		     if (kp2->sli==kp->sli && kp2->flags==kp->flags)
			kp2->kp.subtable=sub;
		  }
		  for (gid2=gid+1; gid2<subsf->sf.glyphcnt; ++gid2)
		     if ((sc2=subsf->sf.glyphs[gid2]) != NULL) {
			for (kp2 =
			     (KernPair1 *) (isv?sc2->vkerns:sc2->kerns);
			     kp2 != NULL;
			     kp2=(KernPair1 *) (kp2->kp.next)) {
			   if (kp2->sli==kp->sli && kp2->flags==kp->flags)
			      kp2->kp.subtable=sub;
			}
		     }
		  /* And there might be a kerning class... */
		  for (kc =
		       (KernClass1 *) (isv?sf->sf.vkerns:sf->sf.kerns);
		       kc != NULL; kc=(KernClass1 *) (kc->kc.next)) {
		     if (kc->sli==kp->sli && kc->flags==kp->flags
			 && kc->kc.subtable==NULL) {
			sub=CreateSubtable(otl, sf);
			sub->per_glyph_pst_or_kern=false;
			sub->kc=&kc->kc;
			kc->kc.subtable=sub;
		     }
		  }
	       }
	    }
	 ++k;
      } while (k<sf->sf.subfontcnt);
      /* Or there might be a kerning class all by its lonesome */
      for (kc=(KernClass1 *) (isv?sf->sf.vkerns:sf->sf.kerns);
	   kc != NULL; kc=(KernClass1 *) (kc->kc.next)) {
	 if (kc->kc.subtable==NULL) {
	    otl =
	       CreateLookup(sf,
			    isv?CHR('v', 'k', 'r', 'n'):CHR('k', 'e', 'r',
								'n'), kc->sli,
			    kc->flags, pst_pair);
	    for (kc2=kc; kc2 != NULL; kc2=(KernClass1 *) (kc2->kc.next)) {
	       if (kc->sli==kc2->sli && kc->flags==kc2->flags
		   && kc2->kc.subtable==NULL) {
		  sub=CreateSubtable(otl, sf);
		  sub->per_glyph_pst_or_kern=false;
		  sub->kc=&kc2->kc;
		  kc2->kc.subtable=sub;
	       }
	    }
	 }
      }
   }

   /* Every FPST and ASM lives in its own lookup with one subtable */
   /* But the old format refered to nested lookups by tag, and now we refer */
   /*  to the lookup itself, so fix that up */
   for (fpst=(FPST1 *) sf->sf.possub; fpst != NULL;
	fpst=((FPST1 *) fpst->fpst.next)) {
      otl =
	 CreateLookup(sf, fpst->tag, fpst->script_lang_index, fpst->flags,
		      fpst->fpst.type);
      sub=CreateSubtable(otl, sf);
      sub->per_glyph_pst_or_kern=false;
      sub->fpst=&fpst->fpst;
      fpst->fpst.subtable=sub;
      FPSTReplaceTagsWithLookups(&fpst->fpst, sf);
   }
   for (sm=(ASM1 *) sf->sf.sm; sm != NULL; sm=((ASM1 *) sm->sm.next)) {
      otl=CreateMacLookup(sf, sm);
      sub=CreateSubtable(otl, sf);
      sub->per_glyph_pst_or_kern=false;
      sub->sm=&sm->sm;
      sm->sm.subtable=sub;
      if (sm->sm.type==asm_context)
	 ASMReplaceTagsWithLookups(&sm->sm, sf);
   }

   /* We retained the old nested feature tags so we could do the above conversion */
   /*  of tag to lookup. Get rid of them now */
   for (isgpos=0;isgpos<2;isgpos++) {
      for (otl=sf->sf.gsplookups[isgpos];otl!=NULL;otl=otl->next) {
	 if (otl->features != NULL && otl->features->scripts==NULL) {
	    chunkfree(otl->features, sizeof(FeatureScriptLangList));
	    otl->features=NULL;
	 }
      }
   }

   /* Anchor classes are complicated, because I foolishly failed to distinguish */
   /*  between mark to base and mark to ligature classes. So one AC might have */
   /*  both. If so we need to turn it into two ACs, and have separate lookups */
   /*  for each */
   for (ac=(AnchorClass1 *) (sf->sf.anchor); ac != NULL;
	ac=(AnchorClass1 *) ac->ac.next) {
      ACHasBaseLig(sf, ac);
      if (ac->has_ligatures && !ac->has_bases)
	 ac->ac.type=act_mklg;
      else if (ac->has_ligatures && ac->has_bases)
	 ACDisassociateLigatures(sf, ac);
   }
   for (ac=(AnchorClass1 *) (sf->sf.anchor); ac != NULL;
	ac=(AnchorClass1 *) ac->ac.next) {
      if (ac->ac.subtable==NULL) {
	 otl=CreateACLookup(sf, ac);
	 sub=CreateSubtable(otl, sf);
	 for (ac2=ac; ac2 != NULL; ac2=(AnchorClass1 *) ac2->ac.next) {
	    if (ac2->feature_tag==ac->feature_tag &&
		ac2->script_lang_index==ac->script_lang_index &&
		ac2->flags==ac->flags &&
		ac2->ac.type==ac->ac.type &&
		ac2->merge_with==ac->merge_with)
	       ac2->ac.subtable=sub;
	 }
      }
   }

   /* Now I want to order the gsub lookups. I shan't bother with the gpos */
   /*  lookups because I didn't before */
   for (otl=sf->sf.gsplookups[0], cnt=0; otl != NULL;
	otl=otl->next, ++cnt);
   if (cnt != 0) {
      all=malloc(cnt * sizeof(OTLookup *));
      for (otl=sf->sf.gsplookups[0], cnt=0; otl != NULL;
	   otl=otl->next, ++cnt) {
	 all[cnt]=otl;
	 otl->lookup_index=GSubOrder(sf, otl->features);
      }
      qsort(all, cnt, sizeof(OTLookup *), order_lookups);
      sf->sf.gsplookups[0]=all[0];
      for (i=1; i<cnt; ++i)
	 all[i-1]->next=all[i];
      all[cnt-1]->next=NULL;
      free(all);
   }

   for (isgpos=0;isgpos<2;isgpos++) {
      for (otl=sf->sf.gsplookups[isgpos],cnt=0;otl!=NULL;otl=otl->next) {
	 otl->lookup_index=cnt++;
	 NameOTLookup(otl,&sf->sf);
      }
   }
}