home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 21 / CD_ASCQ_21_040595.iso / dos / graphic / font3d11 / f3d_src / font3d.cpp < prev    next >
Text File  |  1994-10-12  |  13KB  |  422 lines

  1. //=================================================================================================
  2. //   Font3D.CPP
  3. //-------------------------------------------------------------------------------------------------
  4. //
  5. //   Copyright (c) 1994 by Todd A. Prater
  6. //   All rights reserved.
  7. //
  8. //-------------------------------------------------------------------------------------------------
  9.  
  10. #include <iostream.h>
  11. #include <fstream.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include "List.H"
  15. #include "Geometry.H"
  16. #include "TrueType.H"
  17. #include "Build.H"
  18.  
  19. #define FORMAT_POV  0
  20. #define FORMAT_RAW  1
  21.  
  22. #define PI 3.1415926536
  23.  
  24. #define NONE        0
  25. #define BEVELED     1
  26. #define SMOOTH      2
  27.  
  28.  
  29.  
  30. //  Put your name somewhere here if you compile a version of Font3D for
  31. //  your setup...
  32.  
  33.  
  34. void PrintGreeting(void)
  35. {
  36.    cout<<"-------------------------------------------------------------------"<<endl;
  37.    cout<<"         Font3D, Version 1.1, Copyright 1994, Todd A. Prater       "<<endl;
  38.    cout<<endl;
  39.    cout<<"-------------------------------------------------------------------"<<endl;
  40. }
  41.  
  42. void PrintOptions(void)
  43. {
  44.    cout<<"  Command Line Switches:"<<endl;
  45.    cout<<endl;
  46.    cout<<"    /ifilename    TrueType Font File to use."<<endl;
  47.    cout<<"    /ofilename    Output File to be later included in a scene "<<endl;
  48.    cout<<"                  description file."<<endl;
  49.    cout<<"    /nstring      Name of the object to generate (POV formats only)."<<endl;
  50.    cout<<"    /cnnn         ASCII Character Code of the letter to generate"<<endl;
  51.    cout<<"    /rnnn         Curve resolution."<<endl;
  52.    cout<<"    /dfloat       Depth of the generated object."<<endl;
  53.    cout<<"    /fr           Output RAW triangles."<<endl;
  54.    cout<<"    /fs           Output POV smooth_triangles."<<endl;
  55.    cout<<"    /eb           Make bevels flat."<<endl;
  56.    cout<<"    /er           Make bevels rounded."<<endl;
  57.    cout<<"    /tnnn         Angle threshold for smooth triangle output."<<endl;
  58.    cout<<"    /ma           Use Macintosh character mappings."<<endl;
  59.    cout<<"    /sfloat       Shrink factor for beveling."<<endl;
  60.    cout<<endl;
  61. }
  62.  
  63.  
  64.  
  65. void OutputGlyph(ofstream& outputfile,
  66.                  TTFont&   font,
  67.                  CHARPTR   objName,
  68.                  USHORT    code,
  69.                  USHORT    format,
  70.                  USHORT    resolution,
  71.                  INT       effects,
  72.                  double    frontDepth,
  73.                  double    backDepth,
  74.                  double    edgeShrinkFactor,
  75.                  double    faceShrinkFactor,
  76.                  DOUBLE    angleThreshold )
  77. {
  78.  
  79.    int j;
  80.    SHORT upem;
  81.    DOUBLE  xmin,ymin,xmax,ymax;
  82.    LIST<TRIANGLE>  faceTriList;
  83.    LIST<TRIANGLE>  edgeTriList;
  84.    LIST<TRIANGLE>  bevelTriList;
  85.  
  86.  
  87.    cout<<"Triangulating Face...";cout.flush();
  88.    TriangulateFace(font,font.CharacterMap(code),
  89.                    resolution,faceShrinkFactor,faceTriList);
  90.    cout<<"Done."<<endl;
  91.  
  92.    cout<<"Triangulating Edges...";cout.flush();
  93.  
  94.    TriangulateEdges(font,
  95.                     font.CharacterMap(code),
  96.                     resolution,
  97.                     effects,
  98.                     frontDepth,
  99.                     backDepth,
  100.                     faceShrinkFactor,
  101.                     edgeShrinkFactor,
  102.                     angleThreshold,
  103.                     edgeTriList,
  104.                     bevelTriList);
  105.  
  106.    cout<<"Done."<<endl;
  107.  
  108.    cout<<"Writing Output...";cout.flush();
  109.  
  110.    if (format==POV_SMOOTH || format==POV_FLAT)
  111.    {
  112.      upem = font.UnitsPerEm();
  113.      xmin = (DOUBLE)font.GlyphXMin(font.CharacterMap(code))/(DOUBLE)upem;
  114.      ymin = (DOUBLE)font.GlyphYMin(font.CharacterMap(code))/(DOUBLE)upem;
  115.      xmax = (DOUBLE)font.GlyphXMax(font.CharacterMap(code))/(DOUBLE)upem;
  116.      ymax = (DOUBLE)font.GlyphYMax(font.CharacterMap(code))/(DOUBLE)upem;
  117.  
  118.      if (objName==NULL)
  119.      {
  120.          outputfile<<"#declare ALPHA_"<<code<<"_XMin  = "<<xmin<<endl;
  121.          outputfile<<"#declare ALPHA_"<<code<<"_YMin  = "<<ymin<<endl;
  122.          outputfile<<"#declare ALPHA_"<<code<<"_ZMin  = "<<backDepth<<endl;
  123.          outputfile<<"#declare ALPHA_"<<code<<"_XMax  = "<<xmax<<endl;
  124.          outputfile<<"#declare ALPHA_"<<code<<"_YMax  = "<<ymax<<endl;
  125.          outputfile<<"#declare ALPHA_"<<code<<"_ZMax  = "<<frontDepth<<endl;
  126.          outputfile<<endl;
  127.          outputfile<<"#declare ALPHA_"<<code<<"_Width = "<<(xmax-xmin)<<endl;
  128.          outputfile<<"#declare ALPHA_"<<code<<"_Height= "<<(ymax-ymin)<<endl;
  129.          outputfile<<"#declare ALPHA_"<<code<<"_Depth = "<<(frontDepth-backDepth)<<endl;
  130.          outputfile<<endl;
  131.          outputfile<<"#declare ALPHA_"<<code<<" ="<<endl;
  132.          outputfile<<"  union {"<<endl;
  133.      }
  134.      else
  135.      {
  136.          outputfile<<"#declare "<<objName<<"_XMin   = "<<xmin<<endl;
  137.          outputfile<<"#declare "<<objName<<"_YMin   = "<<ymin<<endl;
  138.          outputfile<<"#declare "<<objName<<"_ZMin   = "<<backDepth<<endl;
  139.          outputfile<<"#declare "<<objName<<"_XMax   = "<<xmax<<endl;
  140.          outputfile<<"#declare "<<objName<<"_YMax   = "<<ymax<<endl;
  141.          outputfile<<"#declare "<<objName<<"_ZMax   = "<<frontDepth<<endl;
  142.          outputfile<<endl;
  143.          outputfile<<"#declare "<<objName<<"_Width  = "<<(xmax-xmin)<<endl;
  144.          outputfile<<"#declare "<<objName<<"_Height = "<<(ymax-ymin)<<endl;
  145.          outputfile<<"#declare "<<objName<<"_Depth  = "<<(frontDepth-backDepth)<<endl;
  146.          outputfile<<endl;
  147.          outputfile<<"#declare "<<objName<<" = "<<endl;
  148.          outputfile<<"  union {"<<endl;
  149.      }
  150.    }
  151.  
  152.    faceTriList.gotoFirst();
  153.    for (j=0;j<faceTriList.Count();j++)
  154.    {
  155.       faceTriList.Current()->v1.z=frontDepth;
  156.       faceTriList.Current()->v2.z=frontDepth;
  157.       faceTriList.Current()->v3.z=frontDepth;
  158.  
  159.       outputfile<<"    ";
  160.  
  161.       if (format==RAW)
  162.          faceTriList.Current()->Output(outputfile,format);
  163.       else
  164.          faceTriList.Current()->Output(outputfile,POV_FLAT);
  165.  
  166.       outputfile<<endl;
  167.       faceTriList.gotoNext();
  168.    }
  169.  
  170.  
  171.    faceTriList.gotoFirst();
  172.    for (j=0;j<faceTriList.Count();j++)
  173.    {
  174.       faceTriList.Current()->v1.z=backDepth;
  175.       faceTriList.Current()->v2.z=backDepth;
  176.       faceTriList.Current()->v3.z=backDepth;
  177.       faceTriList.Current()->n1= -faceTriList.Current()->n1;
  178.       faceTriList.Current()->n2= -faceTriList.Current()->n2;
  179.       faceTriList.Current()->n3= -faceTriList.Current()->n3;
  180.  
  181.       outputfile<<"    ";
  182.  
  183.       if (format==RAW)
  184.          faceTriList.Current()->Output(outputfile,format);
  185.       else
  186.          faceTriList.Current()->Output(outputfile,POV_FLAT);
  187.  
  188.       outputfile<<endl;
  189.       faceTriList.gotoNext();
  190.    }
  191.  
  192.    faceTriList.Empty();
  193.  
  194.  
  195.    edgeTriList.gotoFirst();
  196.    for(j=0;j<edgeTriList.Count();j++)
  197.    {
  198.       outputfile<<"    ";
  199.  
  200.       edgeTriList.Current()->Output(outputfile,format);
  201.       outputfile<<endl;
  202.       edgeTriList.gotoNext();
  203.    }
  204.  
  205.    edgeTriList.Empty();
  206.  
  207.    if (edgeShrinkFactor!=0.0 && faceShrinkFactor!=0.0)
  208.    {
  209.       bevelTriList.gotoFirst();
  210.       for (j=0;j<bevelTriList.Count();j++)
  211.       {
  212.          outputfile<<"    ";
  213.          bevelTriList.Current()->Output(outputfile,format);
  214.          outputfile<<endl;
  215.          bevelTriList.gotoNext();
  216.       }
  217.       bevelTriList.Empty();
  218.    }
  219.  
  220.  
  221.    if (format==POV_SMOOTH || format==POV_FLAT)
  222.    {
  223.      outputfile<<"  }"<<endl;
  224.      outputfile<<endl;
  225.    }
  226.  
  227.    outputfile<<endl;
  228.  
  229.    cout<<"Done."<<endl;
  230.  
  231.  
  232. }
  233.  
  234.  
  235.  
  236.  
  237. int main(int argc, char* argv[])
  238. {
  239.    ULONG   code;
  240.    ULONG   i;
  241.    char    switchChar;
  242.    CHAR    fontFileName[255];
  243.    CHARPTR objName = NULL;
  244.    char    outputFileName[255];
  245.  
  246.    double  frontDepth    = 0.1;
  247.    double  backDepth     = 0.0;
  248.    double  shrinkFactor  = 0.0;
  249.    ULONG   threshold     = 20;
  250.    double  angleThreshold = threshold*PI/180;
  251.    ULONG   resolution    = 3;
  252.    INT     effects       = BEVEL;
  253.    USHORT  format        = POV_FLAT;
  254.    USHORT  mapType       = MICROSOFT;
  255.  
  256.    BOOLEAN resolutionSpecified=FALSE;
  257.    BOOLEAN codeSpecified = FALSE;
  258.    BOOLEAN objectNameSpecified = FALSE;
  259.    BOOLEAN fontFileSpecified = FALSE;
  260.    BOOLEAN outputFileSpecified = FALSE;
  261.    BOOLEAN depthSpecified = FALSE;
  262.    BOOLEAN effectsSpecified = FALSE;
  263.    BOOLEAN angleThresholdSpecified = FALSE;
  264.    BOOLEAN shrinkFactorSpecified = FALSE;
  265.  
  266.    PrintGreeting();
  267.  
  268.    if (argc==1)
  269.    {
  270.       cout<<endl;
  271.       PrintOptions();
  272.       exit(1);
  273.    }
  274.  
  275.    for (i=1;i<argc;i++)
  276.    {
  277.  
  278.       if (strlen(argv[i])<3)
  279.       {
  280.          cout<<endl<<"  ERROR:  Illegal switch -- '"<<argv[i]<<"'"<<endl;
  281.          exit(1);
  282.       }
  283.       
  284.       if (argv[i][0]!='/')
  285.       {
  286.          cout<<endl<<"  ERROR:  Illegal switch -- '"<<argv[i]<<"'"<<endl;
  287.          exit(1);
  288.       }
  289.  
  290.       switchChar = argv[i][1];
  291.  
  292.       switch (switchChar)
  293.       {
  294.          case 'f':   switch((CHAR)(argv[i][2]))
  295.                      {
  296.                         case 'r':  format=RAW;
  297.                                    break;
  298.                         case 's':  format=POV_SMOOTH;
  299.                                    break;
  300.                         default:   cout<<endl<<"  ERROR:  Illegal switch -- '/f"
  301.                                        <<((CHAR)(argv[i][2]))<<"'."<<endl;
  302.                                    break;
  303.                      }
  304.                      break;
  305.          case 'e':   switch((CHAR)(argv[i][2]))
  306.                      {
  307.                         case 'b':  effects=BEVEL;
  308.                                    break;
  309.                         case 'r':  effects=ROUND;
  310.                                    break;
  311.                         default:   cout<<endl<<"  ERROR:  Illegal switch -- '/e"
  312.                                        <<((CHAR)(argv[i][2]))<<"'."<<endl;
  313.                                    break;
  314.                      }
  315.                      break;
  316.          case 't':   sscanf(argv[i]+2,"%d",&threshold);
  317.                      angleThresholdSpecified=TRUE;
  318.                      break;
  319.          case 'r':   sscanf(argv[i]+2,"%d",&resolution);
  320.                      resolutionSpecified=TRUE;
  321.                      break;
  322.          case 'c':   sscanf(argv[i]+2,"%d",&code);
  323.                      codeSpecified=TRUE;
  324.                      break;
  325.          case 'n':   if (objectNameSpecified==FALSE)
  326.                         objName = new CHAR[255];
  327.                      strcpy((char*)objName,argv[i]+2);
  328.                      objectNameSpecified=TRUE;
  329.                      break;
  330.          case 'i':   strcpy((char*)fontFileName,argv[i]+2);
  331.                      fontFileSpecified=TRUE;
  332.                      break;
  333.          case 'o':   strcpy(outputFileName,argv[i]+2);
  334.                      outputFileSpecified=TRUE;
  335.                      break;
  336.          case 'd':   sscanf(argv[i]+2,"%9lf",&frontDepth);
  337.                      depthSpecified=TRUE;
  338.                      break;
  339.          case 'm':   switch((CHAR)(argv[i][2]))
  340.                      {
  341.                         case 'a':  mapType = MACINTOSH;
  342.                                    break;
  343.                         case 'i':  mapType = MICROSOFT;
  344.                                    break;
  345.                         default:   cout<<endl<<"  ERROR:  Illegal switch -- '/m"
  346.                                        <<((CHAR)(argv[i][2]))<<"',"<<endl;
  347.                                    break;
  348.                      }
  349.                      break;
  350.          case 's':   sscanf(argv[i]+2,"%9lf",&shrinkFactor);
  351.                      shrinkFactorSpecified=TRUE;
  352.                      break;
  353.          default:    cout<<endl<<"  ERROR:  Illegal switch -- '"<<argv[i]<<"'"<<endl;
  354.                      exit(1);
  355.                      break;
  356.       }
  357.    }
  358.  
  359.  
  360.    if (fontFileSpecified==FALSE)
  361.    {
  362.       cout<<endl<<"  ERROR:  No font file specified."<<endl;
  363.       exit(1);
  364.    }
  365.  
  366.    if (outputFileSpecified==FALSE)
  367.    {
  368.       cout<<endl<<"  ERROR:  No output file specified."<<endl;
  369.       exit(1);
  370.    }
  371.  
  372.    if (codeSpecified==FALSE)
  373.    {
  374.       cout<<endl<<"  ERROR:  No character code specified."<<endl;
  375.       exit(1);
  376.    }
  377.  
  378.    if (angleThresholdSpecified==TRUE)
  379.    {
  380.       angleThreshold = threshold*PI/180;
  381.    }
  382.  
  383.  
  384.    TTFont UserFont(fontFileName,mapType);
  385.    ofstream outputfile(outputFileName);
  386.  
  387.    cout<<endl;
  388.  
  389.    cout<<"Font:             "<<UserFont.FullName()<<endl;
  390.  
  391.    cout<<"Curve Resolution: "<<resolution;
  392.    if (resolutionSpecified) cout<<endl;
  393.    else cout<<" (default)"<<endl;
  394.  
  395.    cout<<"Character Code:   "<<(USHORT)code<<endl;
  396.    cout<<"Character:        "<<(char)code<<endl;
  397.  
  398.    cout<<"Depth:            "<<frontDepth;
  399.    if(depthSpecified) cout<<endl;
  400.    else cout<<" (default)"<<endl;
  401.  
  402.    cout<<"Output File:      "<<outputFileName<<endl;
  403.    cout<<"Angle Threshold:  "<<threshold<<" Degrees, "<<endl;
  404.    cout<<"Shrink Factor:    "<<shrinkFactor<<endl;
  405.  
  406.    if (format == POV_SMOOTH)
  407.       cout<<"Generating Smooth Triangles."<<endl;
  408.    else if (format == RAW)
  409.       cout<<"Generating RAW Output."<<endl;
  410.  
  411.  
  412.    cout<<endl;
  413.  
  414.    OutputGlyph(outputfile, UserFont, objName, code,
  415.                format, resolution, effects,
  416.                frontDepth, backDepth,
  417.                shrinkFactor,shrinkFactor,angleThreshold);
  418.  
  419.  
  420.    return 0;
  421. }
  422.