home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 21 / CD_ASCQ_21_040595.iso / dos / graphic / font3d11 / f3d_src / build.cpp < prev    next >
C/C++ Source or Header  |  1994-10-12  |  18KB  |  498 lines

  1. //=================================================================================================
  2. //   Build.CPP
  3. //-------------------------------------------------------------------------------------------------
  4. //
  5. //   Copyright (c) 1994 by Todd A. Prater
  6. //   All rights reserved.
  7. //
  8. //=================================================================================================
  9.  
  10.  
  11. #include <stdlib.h>
  12. #include <fstream.h>
  13. #include "Config.H"
  14. #include "Vector.H"
  15. #include "TrueType.H"
  16. #include "Geometry.H"
  17. #include "Build.H"
  18.  
  19. #define IGNORE  2
  20. #define INSIDE  1
  21. #define OUTSIDE 0
  22.  
  23.  
  24.  
  25. //  ******************************************************
  26. //         NOTE:  Please excuse the debugging code
  27. //  ******************************************************
  28.  
  29.  
  30.  
  31. //===========================================================================================================
  32. //  PolygonizeContour                                                                                        
  33. //-----------------------------------------------------------------------------------------------------------
  34. //===========================================================================================================
  35.  
  36. void PolygonizeContour(TTFont&   font,
  37.                        USHORT  glyphnum,
  38.                        USHORT  contournum,
  39.                        USHORT  resolution,
  40.                        DOUBLE    depth,
  41.                        POLYGON&  polygon    )
  42. {
  43.  
  44.    ULONG  i,j;
  45.    ULONG  polyi;
  46.    ULONG  offcount;
  47.    ULONG  consecutiveoffcount;
  48.    INT    lastwasoff;
  49.    VECTOR cp1,cp2,cp3,cur_point,prev_point,next_point;
  50.    DOUBLE tstep;
  51.  
  52.    if (font.NumContours(glyphnum)<1)
  53.       return;
  54.  
  55.    if (contournum>=font.NumContours(glyphnum))
  56.       return;
  57.  
  58.    if(polygon.numpoints>0)
  59.    {
  60.       delete polygon.pointlist;
  61.       polygon.numpoints=0;
  62.    }
  63.  
  64.    lastwasoff=0; 
  65.    consecutiveoffcount=0; 
  66.    offcount=0;
  67.    for(i=0;i<font.NumPoints(glyphnum,contournum);i++)
  68.    {
  69. //      if (font.FontPointType(glyphnum,contournum,i)==ON_CURVE) cout<<i<<": ON"<<endl;
  70. //      else cout<<i<<": OFF"<<endl;
  71.       if(font.FontPointType(glyphnum,contournum,i)==OFF_CURVE)
  72.       {
  73.          offcount++;
  74.          if(lastwasoff)
  75.             consecutiveoffcount++;
  76.          lastwasoff=1;
  77.       }
  78.       else
  79.          lastwasoff=0;
  80.    }
  81.  
  82.    polygon.numpoints = font.NumPoints(glyphnum,contournum) + offcount*(resolution-2) + consecutiveoffcount;
  83.    polygon.pointlist = new VECTOR[polygon.numpoints+40];  // Temporary fix (give some playing room...)
  84.  
  85.    polyi=0;
  86.  
  87. //   pointcount = font.NumPoints(glyphnum,contournum);
  88.    for(i=0;i<font.NumPoints(glyphnum,contournum);i++)
  89.    {
  90.  
  91.       if (font.FontPointType(glyphnum,contournum,i)==ON_CURVE)
  92.       {
  93. //cout<<"OnCURVE: "<<i<<endl;
  94.          polygon.pointlist[polyi] = VECTOR((DOUBLE)font.FontPointX(glyphnum,contournum,i)/(DOUBLE)font.UnitsPerEm(),
  95.                                     (DOUBLE)font.FontPointY(glyphnum,contournum,i)/(DOUBLE)font.UnitsPerEm(), depth);
  96.          polyi++;
  97.       }
  98.       else
  99.       {
  100. //cout<<"OffCURVE:  "<<i<<endl;
  101.          if(font.FontPointType(glyphnum,contournum,i-1)==ON_CURVE)
  102.          {
  103.             cp1 = VECTOR((DOUBLE)font.FontPointX(glyphnum,contournum,i-1)/(DOUBLE)font.UnitsPerEm(),
  104.                         (DOUBLE)font.FontPointY(glyphnum,contournum,i-1)/(DOUBLE)font.UnitsPerEm(), depth);
  105.          }
  106.          else
  107.          {
  108.             cp1 = VECTOR(((DOUBLE)font.FontPointX(glyphnum,contournum,i-1)+(DOUBLE)font.FontPointX(glyphnum,contournum,i))/2/(DOUBLE)font.UnitsPerEm(),
  109.                         ((DOUBLE)font.FontPointY(glyphnum,contournum,i-1)+(DOUBLE)font.FontPointY(glyphnum,contournum,i))/2/(DOUBLE)font.UnitsPerEm(), depth);
  110.          }
  111.  
  112.          cp2 = VECTOR((DOUBLE)font.FontPointX(glyphnum,contournum,i)/(DOUBLE)font.UnitsPerEm(),
  113.                      (DOUBLE)font.FontPointY(glyphnum,contournum,i)/(DOUBLE)font.UnitsPerEm(), depth);
  114.  
  115.          if (i==(font.NumPoints(glyphnum,contournum)-1))
  116.          {
  117. //cout<<"THE LAST ONE"<<endl;
  118.             cp3 = VECTOR((DOUBLE)font.FontPointX(glyphnum,contournum,0)/(DOUBLE)font.UnitsPerEm(),
  119.                         (DOUBLE)font.FontPointY(glyphnum,contournum,0)/(DOUBLE)font.UnitsPerEm(), depth);
  120.          }
  121.          else
  122.          {
  123.             if(font.FontPointType(glyphnum,contournum,i+1)==ON_CURVE)
  124.             {
  125.                cp3 = VECTOR((DOUBLE)font.FontPointX(glyphnum,contournum,i+1)/(DOUBLE)font.UnitsPerEm(),
  126.                            (DOUBLE)font.FontPointY(glyphnum,contournum,i+1)/(DOUBLE)font.UnitsPerEm(), depth);
  127.                i++;
  128.             }
  129.             else
  130.             {
  131.                cp3 = VECTOR(((DOUBLE)font.FontPointX(glyphnum,contournum,i)+(DOUBLE)font.FontPointX(glyphnum,contournum,i+1))/2/(DOUBLE)font.UnitsPerEm(),
  132.                            ((DOUBLE)font.FontPointY(glyphnum,contournum,i)+(DOUBLE)font.FontPointY(glyphnum,contournum,i+1))/2/(DOUBLE)font.UnitsPerEm(), depth);
  133.             }
  134.          }
  135.  
  136.          tstep = 1.0/(DOUBLE)resolution;
  137.          for(j=0;j<resolution;j++)
  138.          {
  139.             polygon.pointlist[polyi] = ApproximateQuadraticSpline(cp1,cp2,cp3,tstep*(j+1));
  140.             polyi++;
  141.          }
  142.       }
  143.    }
  144.  
  145. if (   (polygon.pointlist[polyi-1].x==polygon.pointlist[0].x)
  146.     && (polygon.pointlist[polyi-1].y==polygon.pointlist[0].y))
  147. //cout<<"LAST IS FIRST"<<endl;
  148. polyi--;  //temporary fix....
  149. }
  150.  
  151.    polygon.numpoints = polyi;
  152.    polygon.orientation = polygon.findOrientation();
  153.  
  154. //cout<<polygon<<"P";
  155. }
  156.  
  157.  
  158.  
  159. //===========================================================================================================
  160. //  TriangulateFace                                                                                          
  161. //-----------------------------------------------------------------------------------------------------------
  162. //===========================================================================================================
  163.  
  164.  
  165. void TriangulateFace (TTFont&         font,
  166.                       USHORT        glyphnum,
  167.                       USHORT        resolution,
  168.                       DOUBLE           shrinkFactor,
  169.                       LIST<TRIANGLE>&  triangleList)
  170. {
  171.  
  172.  
  173.    int         i,j,k;
  174.    BOOLEAN     isAPair;
  175.    SHORT     contourCount;
  176.    POLYGON*    polyarray;
  177.    POLYGON*    shrunkpolyarray;
  178.    BYTEPTR*  relationship;
  179.  
  180.    contourCount = font.NumContours(glyphnum);
  181.    if (contourCount<1) return;
  182.  
  183.    polyarray = new POLYGON[contourCount];
  184.    if (polyarray==NULL) { cout<<"ERROR: Out of memory."<<endl; exit(1); }
  185.  
  186.    shrunkpolyarray=new POLYGON[contourCount];
  187.    if (shrunkpolyarray==NULL) { cout<<"ERROR: Out of memory."<<endl; exit(1); }
  188.  
  189.    relationship = new BYTEPTR[contourCount];
  190.    if (relationship==NULL) { cout<<"ERROR: Out of memory."<<endl; exit(1); }
  191.    for (i=0;i<contourCount;i++)
  192.    {
  193.       relationship[i] = new BYTE[contourCount];
  194.       if (relationship[i]==NULL) { cout<<"ERROR: Out of memory."<<endl; exit(1); }
  195.    }
  196.  
  197.    for (i=0;i<contourCount;i++)
  198.    {
  199.       PolygonizeContour(font,glyphnum,i,resolution,0.0,polyarray[i]);
  200.       if (shrinkFactor>0.0)
  201.          polyarray[i].Shrink(shrunkpolyarray[i],shrinkFactor);
  202.    }
  203.  
  204.  
  205.  
  206.    for (i=0;i<contourCount;i++)
  207.       for (j=0;j<contourCount;j++)
  208.          if (i==j)
  209.             relationship[i][j]=IGNORE;
  210.          else if (polyarray[j].isInside(polyarray[i]))
  211.             relationship[i][j]=INSIDE;
  212.          else
  213.             relationship[i][j]=OUTSIDE;
  214.  
  215.  
  216.    for (i=0;i<contourCount;i++)
  217.    {
  218.       if (polyarray[i].orientation==CLOCKWISE)
  219.       {
  220.          for (j=0;j<contourCount;j++)
  221.          {
  222.             isAPair=FALSE;
  223.             if (relationship[i][j]==INSIDE && polyarray[j].orientation==COUNTER_CLOCKWISE)
  224.             {
  225.                isAPair=TRUE;
  226.                for (k=0;k<contourCount;k++)
  227.                {
  228.                   if (k==j || k==i || relationship[k][j]==IGNORE) continue;
  229.                   if (relationship[k][j]==INSIDE)
  230.                   {
  231.                      if (relationship[i][k]==INSIDE)
  232.                      {
  233.                         isAPair=FALSE;
  234.                         exit;
  235.                      }
  236.                   }
  237.                   else
  238.                      continue;
  239.                }
  240.             }
  241.             if (isAPair)
  242.             {
  243.                if (shrinkFactor>0.0)
  244.                  shrunkpolyarray[i].Combine(shrunkpolyarray[j]);
  245.                else
  246.                   polyarray[i].Combine(polyarray[j]);
  247.  
  248.                relationship[i][j]=IGNORE;
  249.             }
  250.          }
  251.       }
  252.    }
  253.  
  254.  
  255.    for (i=0;i<contourCount;i++)
  256.    {
  257.       if (polyarray[i].orientation==CLOCKWISE)
  258.       {
  259.          if (shrinkFactor>0.0)
  260.             shrunkpolyarray[i].Triangulate(triangleList);
  261.          else
  262.             polyarray[i].Triangulate(triangleList);
  263.       }
  264.    }
  265.  
  266.  
  267.    for (i=0;i<contourCount;i++)
  268.    {
  269.       delete polyarray[i].pointlist;
  270.       delete shrunkpolyarray[i].pointlist;
  271.       delete relationship[i];
  272.    }
  273.    delete polyarray;
  274.    delete shrunkpolyarray;
  275.    delete relationship;
  276.  
  277. }
  278.  
  279.  
  280.  
  281. //===========================================================================================================
  282. //  TriangulateEdges                                                                                         
  283. //-----------------------------------------------------------------------------------------------------------
  284. //===========================================================================================================
  285.  
  286.  
  287. void TriangulateEdges(TTFont&          font,
  288.                       USHORT           glyphnum,
  289.                       USHORT           resolution,
  290.                       INT              effects,
  291.                       DOUBLE           frontDepth,
  292.                       DOUBLE           backDepth,
  293.                       DOUBLE           faceShrink,
  294.                       DOUBLE           edgeShrink,
  295.                       DOUBLE           angleThreshold,
  296.                       LIST<TRIANGLE>&  edgeList,
  297.                       LIST<TRIANGLE>&  bevelList)
  298. {
  299.  
  300.  
  301.    INT         i,j;
  302.    TRIANGLE*   t1;
  303.    TRIANGLE*   t2;
  304.    TRIANGLE*   t3;
  305.    TRIANGLE*   t4;
  306.    TRIANGLE*   t5;
  307.    TRIANGLE*   t6;
  308.    VECTOR      tt1,tt2,tt3,tt4;
  309.    VECTOR      previous,current1,current2,next;
  310.    VECTOR      shrunkCurrent1,shrunkCurrent2;
  311.    VECTOR      previousFacet,currentFacet,nextFacet;
  312.    VECTOR      previousFacetNormal,currentFacetNormal,nextFacetNormal;
  313.    VECTOR      averageNormal1,averageNormal2;
  314.    VECTOR      frontBevelNormal1,frontBevelNormal2,backBevelNormal1,backBevelNormal2;
  315.    VECTOR      p1,p2,p3,p4,p5,p6,p7,p8;
  316.    ULONG       numberOfPoints;
  317.    SHORT       contourCount;
  318.    POLYGON*    polyarray;
  319.    POLYGON*    shrunkPolyarray;
  320.    VECTOR      zDir(0,0,1);
  321.    DOUBLE      angle1,angle2;
  322.    BOOLEAN     doBevels=TRUE;
  323.    
  324.    contourCount = font.NumContours(glyphnum);
  325.    if (contourCount<1) return;
  326.  
  327.    polyarray = new POLYGON[contourCount];
  328.    if (polyarray==NULL)
  329.    {
  330.       cout<<"ERROR: Out of memory."<<endl;
  331.       exit(1);
  332.    }
  333.  
  334.  
  335.    if (faceShrink==0.0 && edgeShrink==0.0) doBevels=FALSE;
  336.  
  337.    if (doBevels)
  338.    {
  339.      shrunkPolyarray = new POLYGON[contourCount];
  340.      if (shrunkPolyarray==NULL)
  341.      {
  342.        cout<<"ERROR: Out of memory."<<endl;
  343.        exit(1);
  344.      }
  345.    }
  346.  
  347.    for (i=0;i<contourCount;i++)
  348.    {
  349.       PolygonizeContour(font,glyphnum,i,resolution,0.0,polyarray[i]);
  350.       if (doBevels) polyarray[i].Shrink(shrunkPolyarray[i],faceShrink);
  351.    }
  352.  
  353.  
  354.    for (i=0;i<contourCount;i++)
  355.    {
  356.       numberOfPoints  = polyarray[i].numpoints;
  357.  
  358.       for (j=0;j<numberOfPoints;j++)
  359.       {
  360.  
  361.          if (j==numberOfPoints-2)
  362.          {
  363.             previous = polyarray[i].pointlist[j-1];
  364.             current1 = polyarray[i].pointlist[j];
  365.             if (doBevels) shrunkCurrent1 = shrunkPolyarray[i].pointlist[j];
  366.             current2 = polyarray[i].pointlist[j+1];
  367.             if (doBevels) shrunkCurrent2 = shrunkPolyarray[i].pointlist[j+1];
  368.             next     = polyarray[i].pointlist[0];
  369.          }
  370.          else if (j==numberOfPoints-1)
  371.          {
  372.             previous = polyarray[i].pointlist[j-1];
  373.             current1 = polyarray[i].pointlist[j];
  374.             if (doBevels) shrunkCurrent1 = shrunkPolyarray[i].pointlist[j];
  375.             current2 = polyarray[i].pointlist[0];
  376.             if (doBevels) shrunkCurrent2 = shrunkPolyarray[i].pointlist[0];
  377.             next     = polyarray[i].pointlist[1];
  378.          }
  379.          else if (j==0)
  380.          {
  381.             previous = polyarray[i].pointlist[numberOfPoints-1];
  382.             current1 = polyarray[i].pointlist[j];
  383.             if (doBevels) shrunkCurrent1 = shrunkPolyarray[i].pointlist[j];
  384.             current2 = polyarray[i].pointlist[j+1];
  385.             if (doBevels) shrunkCurrent2 = shrunkPolyarray[i].pointlist[j+1];
  386.             next     = polyarray[i].pointlist[j+2];
  387.          }
  388.          else
  389.          {
  390.             previous = polyarray[i].pointlist[j-1];
  391.             current1 = polyarray[i].pointlist[j];
  392.             if (doBevels) shrunkCurrent1 = shrunkPolyarray[i].pointlist[j];
  393.             current2 = polyarray[i].pointlist[j+1];
  394.             if (doBevels) shrunkCurrent2 = shrunkPolyarray[i].pointlist[j+1];
  395.             next     = polyarray[i].pointlist[j+2];
  396.          }
  397.             
  398.          previousFacet = ~(current1-previous);
  399.          currentFacet  = ~(current2-current1);
  400.          nextFacet     = ~(next-current2);
  401.  
  402.          previousFacetNormal = zDir^previousFacet;
  403.          currentFacetNormal  = zDir^currentFacet;
  404.          nextFacetNormal     = zDir^nextFacet;
  405.  
  406.          
  407.  
  408.          angle1 = acos(previousFacetNormal%currentFacetNormal);
  409.          angle2 = acos(currentFacetNormal%nextFacetNormal);
  410.  
  411.          if (angle1<angleThreshold)
  412.             averageNormal1 = ~(previousFacetNormal+currentFacetNormal);
  413.          else
  414.             averageNormal1 = currentFacetNormal;
  415.  
  416.          tt1 = zDir*edgeShrink;
  417.          tt2 = averageNormal1*faceShrink;
  418.  
  419.          tt3 = tt1+tt2;
  420.          tt4 = tt2-tt1;
  421.  
  422.          if (doBevels) frontBevelNormal1   = ~(tt3);
  423.          if (doBevels) backBevelNormal1    = ~(tt4);
  424.  
  425.          if (angle2<angleThreshold)
  426.             averageNormal2 = ~(currentFacetNormal+nextFacetNormal);
  427.          else
  428.             averageNormal2 = currentFacetNormal;
  429.  
  430.          if (doBevels) frontBevelNormal2 = ~(zDir*edgeShrink + averageNormal2*faceShrink);
  431.          if (doBevels) backBevelNormal2  = ~(-zDir*edgeShrink + averageNormal2*faceShrink);
  432.  
  433.          if (doBevels) p1 = shrunkCurrent1; p1.z=frontDepth;
  434.          if (doBevels) p2 = shrunkCurrent2; p2.z=frontDepth;
  435.          p3 = current1      ; p3.z=frontDepth-edgeShrink;
  436.          p4 = current2      ; p4.z=frontDepth-edgeShrink;
  437.          p5 = current1      ; p5.z=backDepth+edgeShrink;
  438.          p6 = current2      ; p6.z=backDepth+edgeShrink;
  439.          if (doBevels) p7 = shrunkCurrent1; p7.z=backDepth;
  440.          if (doBevels) p8 = shrunkCurrent2; p8.z=backDepth;
  441.  
  442.  
  443.          t3 = new TRIANGLE(p3,p5,p6,averageNormal1,averageNormal1,averageNormal2);
  444.          if (t3==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  445.          t4 = new TRIANGLE(p3,p6,p4,averageNormal1,averageNormal2,averageNormal2);
  446.          if (t4==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  447.  
  448.          if (doBevels)
  449.          {
  450.            if (effects==BEVEL)
  451.            {
  452.              t1 = new TRIANGLE(p1,p2,p3,frontBevelNormal1,frontBevelNormal2,frontBevelNormal1);
  453.              if (t1==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  454.              t2 = new TRIANGLE(p2,p3,p4,frontBevelNormal2,frontBevelNormal1,frontBevelNormal2);
  455.              if (t2==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  456.              t5 = new TRIANGLE(p5,p7,p6,backBevelNormal1,backBevelNormal1,backBevelNormal2);
  457.              if (t5==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  458.              t6 = new TRIANGLE(p7,p8,p6,backBevelNormal1,backBevelNormal2,backBevelNormal2);
  459.              if (t6==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  460.            }
  461.            else
  462.            {
  463.              t1 = new TRIANGLE(p1,p2,p3,zDir,zDir,averageNormal1);
  464.              if (t1==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  465.              t2 = new TRIANGLE(p2,p3,p4,zDir,averageNormal1,averageNormal2);
  466.              if (t2==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  467.              t5 = new TRIANGLE(p5,p7,p6,averageNormal1,-zDir,averageNormal2);
  468.              if (t5==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  469.              t6 = new TRIANGLE(p7,p8,p6,-zDir,-zDir,averageNormal2);
  470.              if (t6==NULL) { cout<<"ERROR: Out of memory"<<endl; exit(1); }
  471.            }
  472.          }
  473.  
  474.          edgeList.Add(t3);
  475.          edgeList.Add(t4);
  476.          if (doBevels)
  477.          {
  478.            bevelList.Add(t1);
  479.            bevelList.Add(t2);
  480.            bevelList.Add(t5);
  481.            bevelList.Add(t6);
  482.          }
  483.       }
  484.  
  485.    }
  486.  
  487.    for (i=0;i<contourCount;i++)
  488.    {
  489.      delete polyarray[i].pointlist;
  490.      if (doBevels) delete shrunkPolyarray[i].pointlist;
  491.    }
  492.    delete polyarray;
  493.    if (doBevels) delete shrunkPolyarray;
  494.  
  495. }
  496.  
  497.