home *** CD-ROM | disk | FTP | other *** search
/ CD/PC Actual 15 / CDACTUAL15.iso / cdactual / w95 / povray / Font.exe / font.inc next >
Encoding:
Text File  |  1996-05-23  |  12.3 KB  |  380 lines

  1. //
  2. // font.inc v0.3
  3. // Semi-Intelligent text manager for POVRay
  4. // 
  5. // current version available at 
  6. //    http://quark.gmi.edu/~redbeard/raytracing/POVRay-util.html
  7. // 
  8. // Written by Michael D Johnson
  9. //           mjohnson@ccm.tdsnet.com or redbeard@quark.gmi.edu
  10. //           http://quark.gmi.edu/~redbeard
  11. //
  12. // You're free to do what you like with this... I'm hereby donating it to the
  13. // public domain.  If you do find it useful, or do anything with or to it,
  14. // I would like to hear from you.
  15. // 
  16. // This version supports timrom.ttf, included with POVRay
  17. // 
  18. // Variables:
  19. //
  20. // fontMode    Indicates what action to take:
  21. //          -2 & -3 reserved for testing purposes
  22. //          -1  Set LetterWidth to width of character
  23. //          0  Generate a text object of one character
  24. //           1  Determine length of string.  SpaceWidth must be set
  25. //             Note that this string as NO INTERCHARACTER SPACING.
  26. //             That is, the characters are calculated as all run
  27. //             together.
  28. //           2  Place letters of a string in an arc.
  29. //           3  Place the letters of two strings about a circle.  The
  30. //             top has the first message centered at 12 oclock, with
  31. //             the letters upright.  The bottom has the second
  32. //             message, centered at 6 oclock, again with the letters
  33. //             upright.
  34. //           The default value is 0.
  35. //
  36. // ---------- Single character variables (modes -1 and 0)
  37. // Letter     Letter to generate the object for or get the width of.
  38. // Align     -1 = baseline left at origin, 0 = baseline center at origin,
  39. //          1 = basline right at origin
  40. // 
  41. // ---------- String arrangement variables
  42. // SpaceWidth    The width of a space character in units.
  43. //
  44. // Message    Mode 1: String to create to measure the length of
  45. //         Mode 2: String to create
  46. //         Mode 3: Top string
  47. //          There is no default
  48. // 
  49. // Message2    Mode 3: Bottom string.  No default
  50. // 
  51. // StartAng    Mode 2: Starting angle.  Negative Z-rotation, (clockwise) 
  52. //        with 9 oclock position being 0 degrees.  Default = 0
  53. //        Mode 3: Returned angle of center of left side gap
  54. // 
  55. // EndAng    Mode 2: Ending angle.  If EndAng < StartAng, text will be
  56. //            backwards.  Default = 180
  57. //         Mode 3: Returned angle of center of right side gap
  58. // 
  59. // Rad        Modes 2 & 3: Radius of baseline of text.  Default = 10
  60. // 
  61. // Facing    Mode 2: Bottom of letters face towards center (0) or
  62. //            outside (1).  Default = 0
  63. // 
  64. // Spacing    Modes 2 & 3: keep this many degrees gap between letters
  65. //        Font will be scaled to achieve this.  Defaults to 2.
  66. // 
  67. // Height    Modes 2 & 3: Set by the file to the maximum (?) height of
  68. //        the letters.
  69. // 
  70. // Gap        Mode 3: Angle of gap between top and bottom.  This gap will
  71. //             on the left and right sides.  Default = 5
  72. // 
  73. // Tilt        Modes 2 & 3: Incline from the plane of the arc, in degrees. 
  74. //        Angle about curve with positive curve in clockwise direction.
  75. //        I.e., place left hand with thumb pointing clockwise about
  76. //        curve. Fingers point in direction of positive rotation.
  77. // 
  78. // Thick    Modes 2 & 3: Thickness of the letters
  79. //
  80. // 
  81. // Call with Letter set to the string value of the letter (e.g. "A") and
  82. // fontMode set to 0 for the text object or 1 for the LetterWidth to be
  83. // set.  LetterWidth is set, regardless, to the width in units of the text
  84. // object.  This value is approximate.
  85. // 
  86. // When a text object is created (i.e. fontMode = 0), it is centered on the
  87. // X axis, the baseline of the letter is on the Y axis, and the face is in
  88. // the XY plane.  The thickness of the object is 1.
  89. //
  90. // WARNING!
  91. //   Using the arc/circle modes (fontModes 2 and 3) incur vast recursion.
  92. //   This can make parsing a lengthy process.  Maybe in POVRay 4.0
  93. //   true subroutines will be introduced.  Then I won't have keep re-calling 
  94. //   this file :)
  95. // 
  96. // Limitations:
  97. //   Currently only handles ASCII characters 32 - 126
  98. //   Can only generate strings arrayed in circles and arcs
  99. //   Doesnt know anything about kerning.
  100. //   Cannot be simply changed for different fonts.
  101. //   Widths are only accurate to 0.01 units.
  102. //   Documentation is still a little lacking... but you should be able to
  103. //     get by. :)
  104. // 
  105. // Bugs:
  106. //   I think that the returned value for StartAng and EndAng from
  107. //   fontMode = 3 are incorrect.  I'll get that figured out sooner or later
  108. //   Sooner if someone needs it.
  109. // 
  110. // 
  111.  
  112. #declare font_inc_Ver = "0.3"
  113.  
  114. #ifndef (NOBANNER) #declare NOBANNER = 0 #end
  115. #if (NOBANNER = 0)
  116.   #debug concat("---font.inc v", font_inc_Ver, ", Mode: ",
  117.         str(fontMode, 0, 0), "---\n")
  118. #end
  119.  
  120. // This stuff is just so the banner only appears once each time it is called
  121. // by an external file.  Otherwise, with NOBANNER undefined or set to 0,
  122. // the banner would appear everytime the file recurses another level.
  123. #ifndef (_FI_recurse) #declare _FI_recurse = 0 #end
  124. #declare _FI_recurse = _FI_recurse + 1
  125.  
  126. #if (_FI_recurse = 1)
  127.   #declare _FI_oldbanner = NOBANNER
  128.   #declare NOBANNER = 1
  129. #end
  130.  
  131. //#declare TEST_SPACING = "~"
  132. //#declare TEST_PHRASE = "April 1996"
  133.  
  134. #declare TIMROM_Space = 
  135. concat(
  136.        /*    !  "  #  $  %  &  '  (  )  *  +  ,  -  .  / */
  137.            "012027050043079076011030030036051016025011027",
  138.        /* 0  1  2  3  4  5  6  7  8  9  :  ;  <  =  >  ? */
  139.         "045029045039047039044043040044011016052052052037",
  140.        /* @  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O */
  141.         "097074060052069059051070071030038074059089073069",
  142.        /* P  Q  R  S  T  U  V  W  X  Y  Z  [  \  ]  ^  _ */
  143.         "052067068044057073072095073071059022027022047055",
  144.        /* `  a  b  c  d  e  f  g  h  i  j  k  l  m  n  o */
  145.         "018031047039048040039045050023025051023079050044",
  146.        /* p  q  r  s  t  u  v  w  x  y  z  {  |  }  ~     */
  147.         "048047035032028051049075059050042030004030053")
  148.  
  149. #declare fontHeight = 0.68
  150.  
  151. // This section is for calculating spacing
  152.  
  153. #ifdef   (TEST_SPACING) #declare fontMode = -2
  154. #else
  155.   #ifdef (TEST_PHRASE)  #declare fontMode = -3
  156.   #end
  157. #end
  158.  
  159. #ifndef (fontMode) #declare fontMode = 0 #end
  160.  
  161. #switch (int(fontMode))
  162.   #range (-3, -2)
  163.     #include "colors.inc"
  164.     camera
  165.     {
  166.     orthographic
  167.     location <1, 0.5, -3> look_at <1, 0.5, 0>
  168.     right x * 2 * (-1 - fontMode) up y * 1.5 * (-1 - fontMode)
  169.     }
  170.     
  171.     plane
  172.     {
  173.     z, 1
  174.     texture
  175.     {
  176.         pigment
  177.         {
  178.         checker
  179.         pigment { checker color Red color Yellow translate -5 scale 0.1 }
  180.         pigment { checker color Green color Blue translate -5 scale 0.1 }
  181.         translate -5 scale 0.1
  182.         }
  183.         finish { ambient 0.8 }
  184.     }
  185.     }
  186.     
  187.     text
  188.     {
  189.     ttf "timrom.ttf"
  190.     #if (fontMode = -2)
  191.       TEST_SPACING 1, 0
  192.     #else
  193.       TEST_PHRASE 1, 0 scale 0.5
  194.     #end
  195.     texture { pigment { Black } finish { ambient 0.8 } }
  196.     }
  197.   #break
  198.   
  199.   #case (0)    // Generate an aligned text object
  200.     #ifndef (Align) #declare Align = 0 #end
  201.     #if (Align < -1 | Align > 1)
  202.       #error concat("Align value of ", str(Align, 0, 0),
  203.             " illegal for font.inc.  Must be -1, 0, or 1")
  204.     #end
  205.     #declare Align = int(Align)
  206.     
  207.     #declare fontMode = -1
  208.     #include "font.inc"    // Recursive call to get letter width
  209.     #declare fontMode = 0
  210.     text
  211.     {
  212.     ttf "timrom.ttf" Letter 1, 0
  213.     translate x * LetterWidth * (-1 - Align) / 2
  214.     }
  215.   #break
  216.   
  217.   #case (1)    // Determine the length of a string
  218.     #ifndef (SpaceWidth) #declare SpaceWidth = 0.5 #end
  219.     #declare fontMode = -1
  220.     #declare _FI_I = 0
  221.     #declare MessageLength = 0
  222.     
  223.     #while (_FI_I < strlen(Message))
  224.       #declare Letter = substr(Message, _FI_I+1, 1)
  225.       #if (asc(Letter) = 32)
  226.     #declare LetterWidth = SpaceWidth
  227.       #else
  228.     #include "font.inc"  // Recursive call to get width of letter
  229.       #end
  230.       #declare MessageLength = MessageLength + LetterWidth
  231.       #declare _FI_I = _FI_I + 1
  232.     #end
  233.     #declare fontMode = 1
  234.   #break
  235.   
  236.   #range (2, 3) // Circular arrangements
  237.     // Circular general defaults
  238.     #ifndef (Rad)    #declare Rad = 10    #end
  239.     #ifndef (Spacing)    #declare Spacing = 2    #end
  240.     #ifndef (Gap)    #declare Gap = 5    #end
  241.     #ifndef (Tilt)    #declare Tilt = 0    #end
  242.     #ifndef (Thick)    #declare Thick = 1    #end
  243.     #ifndef (FixHeight) #declare FixHeight = 0    #end
  244.  
  245.     union
  246.     {
  247.     #switch (int(fontMode))
  248.       #case (2)
  249.         // Single string defaults
  250.         #ifndef (StartAng)    #declare StartAng = 0    #end
  251.         #ifndef (EndAng)    #declare EndAng = 180    #end
  252.         #ifndef (Facing)    #declare Facing = 0    #end
  253.         
  254.         #declare _FI_Facing = int(Facing)
  255.         #if ((_FI_Facing < 0) | (_FI_Facing > 1))
  256.           #error concat("Invalid value for Facing: ", str(Facing, 0,-1),
  257.                 " in textarc.inc\n")
  258.         #end
  259.     
  260.         // Calculate the message length
  261.         #declare _FI_Len = strlen(Message)
  262.         
  263.         // Determine the direction to go and the amount to go.
  264.         #declare _FI_Dir = ((EndAng < StartAng) ? -1 : 1)
  265.         #declare _FI_Ang = abs(EndAng - StartAng)
  266.         
  267.         // Calculate the length of the arc
  268.         #declare _FI_Circ = 2 * pi * Rad
  269.         #declare _FI_ArcLen = _FI_Circ * _FI_Ang / 360
  270.         
  271.         // Get the length of the text in a straight line
  272.         #declare fontMode = 1 #include "font.inc"
  273.         
  274.         // Find the scale for the letters.  This is intended to get the
  275.         // spacing angle correct.  If FixHeight is set, base everything
  276.         // on a provided Height value instead.
  277.         #if (FixHeight)
  278.           #declare _FI_Scale = Height / fontHeight
  279.           #declare Spacing = ((360 *
  280.                    (_FI_ArcLen - _FI_Scale * MessageLength)) /
  281.                   (_FI_ArcLen * (_FI_Len - 1)))
  282.         #else
  283.           #declare _FI_Scale = ((_FI_ArcLen -
  284.                      (_FI_Len-1)*Spacing*_FI_ArcLen/360) /
  285.                     MessageLength)
  286.         #end
  287.         #declare _FI_WFact = ((_FI_Ang - Spacing * (_FI_Len - 1)) /
  288.                   MessageLength)
  289.         
  290.         #declare fontMode = 0 // Cause font.inc to return objects
  291.         #declare Align = 0    // Put the center baseline at the origin
  292.         
  293.         #declare _FI_Rot = StartAng - 90
  294.         #declare _FI_I = 0
  295.         #while (_FI_I < _FI_Len)
  296.           #declare Letter = substr(Message, _FI_I + 1, 1)
  297.           #if (asc(Letter) != 32)
  298.         object
  299.         {
  300.             #include "font.inc" // Recursive call
  301.             scale <_FI_Scale, _FI_Scale, Thick>
  302.             rotate <0, (_FI_Dir - 1) * 90, Facing * 180>
  303.             rotate x * Tilt
  304.             translate y * Rad
  305.             #declare _FI_LetAng = _FI_WFact * LetterWidth
  306.             rotate (z * ((_FI_Rot + _FI_LetAng / 2) * _FI_Dir *
  307.                  (-1 + Facing * 2) - 180 * Facing))
  308.         }
  309.           #else #declare _FI_LetAng = SpaceWidth * _FI_WFact
  310.           #end
  311.           #declare _FI_Rot = _FI_Rot + Spacing + _FI_LetAng
  312.           #declare _FI_I = _FI_I + 1
  313.         #end
  314.         #declare Height = fontHeight * _FI_Scale
  315.         #declare fontMode = 2
  316.       #break
  317.       
  318.       #case (3)
  319.         #ifndef (Gap) #declare Gap = 5 #end
  320.         // Figure out sizes
  321.         #declare _FI_message = Message
  322.         #declare fontMode = 1
  323.         #include "font.inc"
  324.         #declare _FI_TopLen = MessageLength
  325.         #declare Message = Message2
  326.         #include "font.inc"
  327.         #declare _FI_BotLen = MessageLength
  328.         #declare _FI_TotLen = _FI_TopLen + _FI_BotLen
  329.         #declare _FI_TopRat = _FI_TopLen / _FI_TotLen
  330.         #declare _FI_BotRat = _FI_BotLen / _FI_TotLen
  331.         #declare _FI_TotAng = 360 - Gap * 2
  332.         #declare _FI_TopAng = _FI_TotAng * _FI_TopRat
  333.         #declare _FI_BotAng = _FI_TotAng * _FI_BotRat
  334.         #declare _FI_TopStart = 90 - _FI_TopAng / 2
  335.         #declare _FI_TopEnd = _FI_TopStart + _FI_TopAng
  336.         #declare _FI_BotStart = 90 - _FI_BotAng / 2
  337.         #declare _FI_BotEnd = _FI_BotStart + _FI_BotAng
  338.  
  339.         #declare fontMode = 2
  340.         #declare StartAng = _FI_TopStart
  341.         #declare EndAng = _FI_TopEnd
  342.         #declare Facing = 0
  343.         #declare Message = _FI_message
  344.         #include "font.inc"
  345.         
  346.         #declare _FI_rad = Rad
  347.         #declare _FI_spacing = Spacing
  348.         #declare _FI_FixHeight = FixHeight
  349.         #declare FixHeight = 1
  350.         #declare Rad = Rad + Height
  351.         #declare StartAng = _FI_BotStart
  352.         #declare EndAng = _FI_BotEnd
  353.         #declare Facing = 1
  354.         #declare Message = Message2
  355.         #include "font.inc"
  356.         
  357.         #declare Rad = _FI_rad
  358.         #declare Spacing = _FI_spacing
  359.         #declare FixHeight = _FI_FixHeight
  360.         #declare StartAng = _FI_TopStart - Gap / 2
  361.         #declare EndAng = _FI_TopEnd + Gap / 2
  362.         
  363.         #declare fontMode = 3
  364.       #break
  365.       
  366.     #end
  367.     }
  368.     
  369.   #break
  370.   
  371. #else
  372.   #declare LetterWidth = 
  373.   val(substr(TIMROM_Space, (asc(Letter) - 33) * 3 + 1,3)) / 100
  374. #end
  375.  
  376. #declare _FI_recurse = _FI_recurse - 1
  377. #if (_FI_recurse = 0)
  378.   #declare NOBANNER = _FI_oldbanner
  379. #end
  380.