Advertisement
ChristophKnoth

The Primitive Font Design Tool 1

Mar 22nd, 2011
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 35.40 KB | None | 0 0
  1. """ This application helps designing letters. """
  2.  
  3. #__author__ = 'Christoph Knoth, ECAL/Ecole cantonale d art de Lausanne'
  4.  
  5. # to do:
  6. # childconnection that is a bowl
  7. # child connection that is a lose arm
  8. # Eclipse or xcode and pyobj or tkinter? vanilla
  9. # make neigbours more clear, that you can compare neighbour connections
  10. # look at super ellipse piet hein
  11. # glyph is an array with arrays
  12. # glue inbetween the strokes
  13.  
  14. from math import atan2, atan, pi
  15. import wx
  16.  
  17.  
  18. ########################################################################
  19. # preferences vars
  20.  
  21. #DebugMode = False
  22. DebugMode = True
  23.  
  24. NodeNames = False
  25. #NodeNames = True
  26.  
  27. Guidelines = False
  28. #Guidelines = True
  29.  
  30. ShowOffCurvePoints = False
  31. ShowOffCurvePoints = True
  32.  
  33. #sortedLetters = False
  34. #sortedLetters = True
  35.  
  36.  
  37. row = 0
  38. letter = 0
  39. globalWidth = 500.
  40.  
  41. StrokeWidth = 6.
  42.  
  43. PenWidth = 10. #thickness
  44.  
  45. ConnectionDotColor= (1, 0, 0)
  46.  
  47. ##################
  48. # type based Variables
  49.  
  50.  
  51. #connectionType = "straight"  #straight only
  52. connectionType = "round" #straight and round mixed
  53.  
  54.  
  55. baseline = 0.
  56. xHeight = 400.
  57. descHeight = -300.
  58.  
  59. SerifHeight = StrokeWidth * 0.9
  60. xHeightSerif = xHeight - SerifHeight
  61.  
  62. capHeight = xHeight*15/10.
  63.  
  64.  
  65. # things that have to do with the beginning and ending of strokes or with arms and ...
  66. openess = 0.2 #0 very open -> too 0.5 closed
  67. openAngle = 1.5
  68.  
  69. StemShoulderConnectionHeight = xHeight * 6/10.
  70. BottomBowlConnectionHeight = xHeight * 3/10.
  71.  
  72.  
  73. rightOpenContourFromTopCaps = (1 - openess) * capHeight + baseline
  74. rightOpenContourFromBottomCaps = openess * capHeight + baseline
  75.  
  76. rightOpenContourFromTopMinors = (1 - openess) * xHeight + baseline
  77. rightOpenContourFromBottomMinors = openess * xHeight + baseline
  78.  
  79. left = 0.
  80.  
  81. offsetdrawing = 200.
  82.  
  83.  
  84. #roundness / curviness
  85.    
  86. exponent= 4. #if bigger it makes the extrema: very thin and extended more pronounced, if smaller there is no squariness in thin and wide letters
  87. stretchFactor = pi/800. #the perfect roundness is at this point
  88. minimumCurveHori = 0.58
  89. minimumCurveVerti = 0.6
  90.  
  91.  
  92.  
  93. ########################################################################
  94. # Viewport
  95.  
  96. ScaleFactor = 0.27
  97.  
  98.  
  99. #############
  100. # Colors Display
  101.  
  102. #wx.Colour(r, g, b, wx.ALPHA_OPAQUE)
  103. blue = wx.Colour(0, 255, 0, 255)
  104. black = wx.Colour(0, 0, 0, 255)
  105. HandlePenWidth = 4.
  106. HandleOvalWidth = 5
  107.            
  108.  
  109. # Class that defines a Guideline
  110.  
  111. class Guideline(object):
  112.     fonts = 20
  113.     guideName = "Guideline"
  114.     nameOffset = 5, 0
  115.    
  116.     def __init__(self, y, name=""):
  117.         self.y = y
  118.         self.name = name
  119.  
  120.         if self.name and (Guidelines is True):
  121.            
  122.             gc.SetPen(wx.Pen("#dddddd",PenWidth))
  123.             path=gc.CreatePath()
  124.             path.MoveToPoint(-1000, self.y)
  125.             path.AddLineToPoint(10000, self.y)
  126.             gc.DrawPath(path)
  127.             strokewidth(StrokeWidth)
  128.  
  129.        
  130.     def draw(self,gc):
  131.         #stroke(None)
  132.  
  133.         if self.name and (Guidelines is True):
  134.             font(self.guideName)
  135.             fontsize(self.fonts)
  136.             x, y = self.nameOffset
  137.             text(self.name, self.x+x, self.y+y)
  138.  
  139.    
  140.  
  141. # Class that defines a Node
  142.  
  143. class Node(object):
  144.     """Defining a Node with the parameters x, y and its name.
  145.    Draws an oval at the position of the node with the name next to it."""
  146.    
  147.     fonts = 10. / ScaleFactor
  148.     fontName = "Helvetica"  #Why?
  149.     nameOffset = 15, 15
  150.     dotSize = StrokeWidth/ 2.
  151.    
  152.     def __init__(self, x, y, name=""):
  153.         self.x = x
  154.         self.y = y
  155.         self.name = name
  156.        
  157.     def draw(self,gc):
  158.        
  159.         if DebugMode is True:
  160.             gc.SetPen(wx.Pen("#000000", PenWidth))
  161.         else:
  162.             gc.SetPen(wx.Pen("#FF0000", PenWidth))
  163.  
  164.         #round endings?
  165.         #path.AddCircle(self.x-self.dotSize, self.y-self.dotSize, self.dotSize*2)
  166.         #stroke(1,0,0)
  167.        
  168.         #fill(0.6,0.6,0.6)
  169.        
  170.         if self.name and DebugMode is True and NodeNames is True:
  171.             font(self.fontName)
  172.             fontsize(self.fonts)
  173.            
  174.             x, y = self.nameOffset
  175.             translate(self.x+x, self.y+y)
  176.             rotate(30)
  177.             text(self.name, 0, 0)
  178.             rotate(-30)
  179.             translate(-self.x-x, -self.y-y)
  180.         #fill(None)
  181.            
  182.  
  183.  
  184. class Connection(object):
  185.     """Defining a connection with the start and end point and a name.
  186.    Draws a stroke from the start to the end."""
  187.    
  188.     def __init__(self, start, end, name=""):
  189.         self.start = start
  190.         self.end = end
  191.         self.name = name
  192.         self._parent = None
  193.    
  194.     def setParent(self, obj):
  195.         self._parent = obj
  196.        
  197.     def getParent(self):
  198.         return self._parent
  199.    
  200.     def angle(self):
  201.         xDiff = self.end.x - self.start.x
  202.         yDiff = self.end.y - self.start.y
  203.         angle = atan2(xDiff, yDiff)
  204.         return angle
  205.        
  206.     def getPreviousConnection(self):
  207.         p = self.getParent()
  208.         i = p.index(self)
  209.         if i <= 0:
  210.             return None
  211.         elif i >= len(p):
  212.             return None
  213.         return p[i-1]
  214.        
  215.     def getFollowingConnection(self):
  216.         p = self.getParent()
  217.         i = p.index(self)
  218.         if i <= 0:
  219.             return None
  220.         elif i >= len(p):
  221.             return None
  222.         return p[i]
  223.        
  224.     def draw(self,gc):
  225.                
  226.         #print self.angle() #works
  227.        
  228.         #print self.getPreviousConnection()
  229.         #print self.getFollowingConnection()
  230.        
  231.        
  232.         debugPath=gc.CreatePath()
  233.         path=gc.CreatePath()
  234.        
  235.        
  236.         path.MoveToPoint(self.start.x, self.start.y)
  237.        
  238.         offCurvePoint1x = self.start.x
  239.         offCurvePoint1y = self.start.y
  240.         offCurvePoint2x = self.end.x
  241.         offCurvePoint2y = self.end.y
  242.        
  243.        
  244.         #test if there is any roundness involved. if yes, check in which direction the roundness points
  245.        
  246.         if (("rb" in self.name) or ("lb" in self.name) or ("rt" in self.name) or ("lt" in self.name)):
  247.  
  248.             if "lt" in self.name:
  249.                 if self.start.x >= self.end.x and self.start.y >= self.end.y:
  250.                     inwards = True
  251.                 else:
  252.                     inwards = False
  253.  
  254.             elif "rt" in self.name:
  255.                 if (self.start.x <= self.end.x) and (self.start.y >= self.end.y):
  256.                     inwards = True
  257.                 else:
  258.                     inwards = False
  259.  
  260.             elif "lb" in self.name:
  261.                 if (self.start.x >= self.end.x) and (self.start.y <= self.end.y):
  262.                     inwards = True
  263.                 else:
  264.                     inwards = False
  265.                    
  266.             elif "rb" in self.name:
  267.                 if (self.start.x <= self.end.x) and (self.start.y <= self.end.y):
  268.                     inwards = True
  269.                 else:
  270.                     inwards = False
  271.            
  272.             if inwards is True:
  273.                 offCurvePoint1xMultiplicator = -1
  274.                 offCurvePoint1yMultiplicator = 0
  275.                 offCurvePoint2xMultiplicator = 0
  276.                 offCurvePoint2yMultiplicator = 1
  277.             else:
  278.                 offCurvePoint1xMultiplicator = 0
  279.                 offCurvePoint1yMultiplicator = -1
  280.                 offCurvePoint2xMultiplicator = 1
  281.                 offCurvePoint2yMultiplicator = 0
  282.                
  283.                
  284.             distanceHori = self.start.x - self.end.x
  285.             distanceVerti = self.start.y - self.end.y  
  286.  
  287.             # no division by zero
  288.             if distanceHori == 0:
  289.                 distanceHori = distanceHori + 0.00001
  290.            
  291.             if distanceVerti == 0:
  292.                 distanceVerti = distanceVerti + 0.00001
  293.            
  294.            
  295.             CurveHori = distanceHori * ((1-minimumCurveHori) * 2./pi * (atan(stretchFactor*(distanceVerti / distanceHori ) **exponent)) + minimumCurveHori)
  296.             CurveVerti = distanceVerti * ((1-minimumCurveVerti) * 2./pi * (atan(stretchFactor*(distanceHori / distanceVerti ) **exponent)) +  minimumCurveVerti)
  297.            
  298.  
  299.             offCurvePoint1x = self.start.x + offCurvePoint1xMultiplicator * CurveHori
  300.             offCurvePoint1y = self.start.y + offCurvePoint1yMultiplicator * CurveVerti
  301.  
  302.             offCurvePoint2x = self.end.x   + offCurvePoint2xMultiplicator * CurveHori
  303.             offCurvePoint2y = self.end.y   + offCurvePoint2yMultiplicator * CurveVerti
  304.                                
  305.                            
  306.                            
  307.             if DebugMode is True:
  308.                 if "rb" in self.name:
  309.                     gc.SetPen(wx.Pen(black, HandlePenWidth))
  310.                 elif "lb" in self.name:
  311.                     gc.SetPen(wx.Pen(black, HandlePenWidth))
  312.                 elif "rt" in self.name:
  313.                     gc.SetPen(wx.Pen(black, HandlePenWidth))
  314.                 elif "lt" in self.name:
  315.                     gc.SetPen(wx.Pen(black, HandlePenWidth))
  316.                 else:
  317.                     gc.SetPen(wx.Pen(black, HandlePenWidth))
  318.                
  319.                 if (ShowOffCurvePoints is True) and (("rb" in self.name) or ("lb" in self.name) or ("rt" in self.name) or ("lt" in self.name)):
  320.                
  321.                     debugPath.MoveToPoint(self.start.x, self.start.y)
  322.                     debugPath.AddLineToPoint(offCurvePoint1x, offCurvePoint1y)
  323.                     debugPath.MoveToPoint(offCurvePoint2x, offCurvePoint2y)
  324.                     debugPath.AddLineToPoint(self.end.x, self.end.y)
  325.                    
  326.                     gc.DrawEllipse(offCurvePoint1x-HandleOvalWidth/2., offCurvePoint1y-HandleOvalWidth/2., HandleOvalWidth, HandleOvalWidth)
  327.                     gc.DrawEllipse(offCurvePoint2x-HandleOvalWidth/2., offCurvePoint2y-HandleOvalWidth/2., HandleOvalWidth, HandleOvalWidth)
  328.                    
  329.                     gc.DrawPath(debugPath)
  330.                    
  331.             if "rb" in self.name:
  332.                 gc.SetPen(wx.Pen(blue, PenWidth))
  333.             elif "lb" in self.name:
  334.                 gc.SetPen(wx.Pen("#0000FF", PenWidth))
  335.             elif "rt" in self.name:
  336.                 gc.SetPen(wx.Pen("#FF0000", PenWidth))
  337.             elif "lt" in self.name:
  338.                 gc.SetPen(wx.Pen("#FFFF00", PenWidth))
  339.             else:
  340.                 gc.SetPen(wx.Pen("#000000", PenWidth))
  341.  
  342.             path.AddCurveToPoint(offCurvePoint1x, offCurvePoint1y, offCurvePoint2x, offCurvePoint2y, self.end.x, self.end.y)
  343.        
  344.        
  345.         #if there is no roundness, it is probably a straight line, so draw it
  346.         else:
  347.             gc.SetPen(wx.Pen("#000000", PenWidth))
  348.             path.AddLineToPoint(self.end.x, self.end.y)
  349.        
  350.        
  351.         gc.DrawPath(path)
  352.        
  353.  
  354. # Class that defines a Childconnection of two Nodes
  355. # for now it splits those two connections and connects the cutting points useful for A, H,  for B, E, F,P, R, T, X, Y i need something else i guess?
  356.  
  357. class ccCrossbar(object):
  358.     """Takes two connections and draws a crossbar in between them"""
  359.    
  360.     def __init__(self, firstConnection, lastConnection, t1=.51, t2=.51):
  361.         self.firstConnection = firstConnection
  362.         self.lastConnection = lastConnection
  363.        
  364.         self.t1 = t1
  365.         self.t2 = t2
  366.  
  367.        
  368.     def draw(self,gc):
  369.         firstDiffX = self.firstConnection.end.x - self.firstConnection.start.x
  370.         firstDiffY = self.firstConnection.end.y - self.firstConnection.start.y
  371.        
  372.         lastDiffX = self.lastConnection.end.x - self.lastConnection.start.x
  373.         lastDiffY = self.lastConnection.end.y - self.lastConnection.start.y
  374.        
  375.         s = Node(self.firstConnection.start.x + firstDiffX*self.t1, self.firstConnection.start.y + firstDiffY*self.t1)
  376.         s.draw(gc)
  377.        
  378.         e = Node(self.lastConnection.start.x + lastDiffX* self.t2, self.lastConnection.start.y + lastDiffY* self.t2)
  379.         e.draw(gc)
  380.        
  381.         if DebugMode is True:
  382.             gc.SetPen(wx.Pen("#AAAAAA", PenWidth))
  383.        
  384.         debugPath=gc.CreatePath()
  385.         path=gc.CreatePath()
  386.        
  387.         path.MoveToPoint(s.x, s.y)
  388.         path.AddLineToPoint(e.x, e.y)
  389.        
  390.         gc.DrawPath(debugPath)
  391.         gc.DrawPath(path)
  392.        
  393.        
  394. class Stroke(object):
  395.  
  396.     def __init__(self, connections):
  397.         self.connections = connections
  398.         for connection in self.connections:
  399.             connection.setParent(self.connections)
  400.  
  401.     def subscribeStrokes(self):
  402.         for connection in self.connections:
  403.             connection.setParent(self)
  404.    
  405.     def __len__(self):
  406.         return len(self.connections)
  407.    
  408.     def index(self, obj):
  409.         if obj in self.connections:
  410.             return None
  411.         return self.connections.index(obj)
  412.    
  413.     def getStrokes(self, index):
  414.         return self.connections[index]
  415.  
  416.     def draw(self,gc):
  417.         for c in self.connections:
  418.             c1=c.getPreviousConnection()
  419.             #c1=c.getFollowingConnection()
  420.             #c.draw(gc)
  421.             if c1 != None:
  422.                 c1.draw(gc)
  423.                 print c.angle()
  424.                
  425.             #if c.getFollowingConnection()
  426.  
  427.            
  428. # Class that defines a Glyph and draws it        
  429.        
  430. class Glyph(object):
  431.  
  432.     def __init__(self, strokes):
  433.         self.strokes = strokes
  434.  
  435.     def subscribeStrokes(self):
  436.         for stroke in self.strokes:
  437.             stroke.setParent(self)
  438.    
  439.     def __len__(self):
  440.         return len(self.strokes)
  441.    
  442.     def index(self, obj):
  443.         if obj in self.strokes:
  444.             return None
  445.         return self.strokes.index(obj)
  446.    
  447.     def getStrokes(self, index):
  448.         return self.strokes[index]
  449.    
  450.     def draw(self,gc):
  451.         for c in self.strokes:
  452.             c.draw(gc)
  453.            
  454.        
  455.        
  456. class Info(object):
  457.     def __init__(self):
  458.         self.unitsPerEm = 1000
  459.  
  460.  
  461. class Font(dict):
  462.     """ Class that defines a Font as a Dictonary with its inherited Glyphs"""
  463.    
  464.     def _get_info(self):
  465.         if not hasattr(self, "_info"):
  466.             self._info = Info()
  467.         return self._info
  468.    
  469.     info = property(_get_info)
  470.    
  471.     def draw(self,gc):
  472.         print "Font.draw"
  473.         row = 0
  474.         translateWidth = globalWidth
  475.         line = 0
  476.  
  477.         for key in sorted(self):
  478.             glyph = self[key]
  479.             glyph.draw(gc)
  480.            
  481.             #make rowsthat letters wont go out of the screen
  482.            
  483.             gc.Translate((glyph.individualWidth * 1.4), 0)
  484.             row = row + 1
  485.            
  486.             translateWidth = translateWidth + glyph.individualWidth * 1.4
  487.  
  488.             if translateWidth > globalWidth * 6:
  489.                 line = line + 1
  490.                 #print "line", line    
  491.                 row = 0
  492.                 gc.Translate(-translateWidth + globalWidth , -capHeight*1.5)
  493.                 translateWidth = globalWidth
  494.  
  495.                        
  496.     def createGlyphs(self):
  497.         functionName = "_glyph_"
  498.        
  499.         #cycle through all the names of def in font
  500.         for key in dir(self):
  501.             if functionName in key:
  502.                 name = key.replace(functionName, "")
  503.                 #print key
  504.                 #print(name)
  505.                 #call _glyph_function
  506.                 getattr(self, key)(name)
  507.  
  508.    
  509.  
  510.     def _glyph_A(self, name):
  511.         #print "initializing ", name
  512.         individualWidth = globalWidth*0.9
  513.  
  514.         n = {0:0}
  515.         n[1] = Node(left, baseline, "left, bottom")    
  516.         n[2] = Node((left + individualWidth)/ 2., capHeight+baseline, "top, middle")
  517.    
  518.         c = {0:0}
  519.         c[1] = Connection(n[1], n[2], "straight")
  520.    
  521.        
  522.         n[3] = Node(individualWidth, baseline, "right, bottom")
  523.        
  524.         c[2] = Connection(n[3], n[2], "straight")
  525.    
  526.         cb = ccCrossbar(c[1], c[2], .3, .3)
  527.    
  528.         self[name] = Glyph([c[1], c[2], cb])
  529.         self[name].individualWidth = individualWidth
  530.        
  531.  
  532.     def _glyph_B(self, name):
  533.  
  534.         individualWidth = globalWidth*0.6
  535.         n = {0:0}
  536.         c = {0:0}
  537.         s = {0:0}
  538.        
  539.         #top bowl
  540.         n[1] = Node( left, capHeight + baseline, "left, top") #make list
  541.         n[2] = Node( individualWidth * 600/self.info.unitsPerEm, capHeight + baseline, "top bowl, start curve, right ")  
  542.         n[3] = Node( individualWidth * 960/1000, (capHeight + baseline) * 760/1000, "right extrema, bowl, middle curve")  
  543.         n[4] = Node( individualWidth* 600/1000, (capHeight + baseline) / 2., "right, bowl, curve, vertical middle of letter")
  544.         n[5] = Node( left, (capHeight + baseline) / 2., "touching stem, middle vertical, joint")
  545.        
  546.         #connecting all nodes
  547.         c[1] = Connection(n[1], n[2])        
  548.         c[2] = Connection(n[2], n[3], "rt")
  549.         c[3] = Connection(n[3], n[4], "rb")
  550.         c[4] = Connection(n[4], n[5])    
  551.        
  552.         s[1] = Stroke([ c[1], c[2], c[3], c[4] ])
  553.        
  554.  
  555.  
  556.         #bottom bowl
  557.        
  558.         n[5] = Node( individualWidth * 600/1000, (capHeight + baseline) / 2., "rightStart")
  559.         n[6] = Node( individualWidth * 1050/1000, (capHeight + baseline) * 1/4, "rightStart")
  560.         n[7] = Node( individualWidth * 600/1000, baseline, "rightStart")
  561.         n[8] = Node( left, baseline, "rightStart")
  562.        
  563.         c[5] = Connection(n[5], n[6], "rt")        
  564.         c[6] = Connection(n[6], n[7], "rb")
  565.         c[7] = Connection(n[7], n[8])
  566.  
  567.         s[2] = Stroke([c[5], c[6], c[7]])        
  568.  
  569.  
  570.         #stem
  571.         c[8] = Connection(n[1], n[8])
  572.  
  573.         s[3] = Stroke([c[8]])        
  574.        
  575.         self[name] = Glyph([s[1], s[2], s[3]])
  576.         self[name].individualWidth = individualWidth
  577.  
  578.  
  579.     def _glyph_C(self, name):
  580.         #print "initializing ", name
  581.         individualWidth = globalWidth*0.7
  582.        
  583.         n1 = Node( individualWidth, rightOpenContourFromTopCaps, "rightTopStart")
  584.         n2 = Node( (left + individualWidth)/ 2., capHeight+baseline, "middleTop")
  585.         n3 = Node( left, (capHeight)/ 2. + baseline, "leftMiddle")
  586.         n4 = Node( (left + individualWidth)/ 2., baseline, "middleBottom")
  587.         n5 = Node( individualWidth, rightOpenContourFromBottomCaps, "right Bottom End")
  588.        
  589.         c1 = Connection(n1, n2, "rt")        
  590.         c2 = Connection(n2, n3, "lt")
  591.         c3 = Connection(n3, n4, "lb")
  592.         c4 = Connection(n4, n5, "rb")
  593.        
  594.         s1 = Stroke([c1, c2, c3, c4])
  595.        
  596.         self[name] = Glyph([s1])
  597.         self[name].individualWidth = individualWidth
  598.        
  599.    
  600.     def _glyph_E(self, name):
  601.  
  602.         individualWidth = globalWidth*0.55
  603.        
  604.         n1 = Node( individualWidth, capHeight + baseline, "rightStart")  
  605.         n2 = Node( left, capHeight + baseline, "middleTop")
  606.         n3 = Node( left, (capHeight)/ 2. + baseline, "leftMiddle")
  607.         n4 = Node( individualWidth, (capHeight)/ 2. + baseline, "leftMiddle")
  608.         n5 = Node( left, baseline, "middleBottom")
  609.         n6 = Node( individualWidth, baseline, "rightEnd")
  610.        
  611.         c1 = Connection(n1, n2, "top stroke")        
  612.         c2 = Connection(n2, n3, "left stroke")
  613.         c3 = Connection(n3, n4, "middle bar")
  614.         c4 = Connection(n3, n5)
  615.         c5 = Connection(n5, n6, "bottom stroke")
  616.        
  617.         s1 = Stroke([c1, c2, c3, c4, c5])
  618.            
  619.         self[name] = Glyph([s1])
  620.         self[name].individualWidth = individualWidth
  621.      
  622.  
  623.     def _glyph_H(self, name):
  624.        
  625.         individualWidth = globalWidth * 0.7
  626.        
  627.         s = Node(left, baseline, "left")    
  628.         e = Node(left, capHeight + baseline, "top")
  629.    
  630.         c = Connection(s, e)
  631.    
  632.         s = Node(left + individualWidth, baseline, "left")    
  633.         e = Node(left + individualWidth, capHeight + baseline, "top")
  634.         c2 = Connection(s, e)
  635.    
  636.         cc = ccCrossbar(c, c2, .5, .5)
  637.    
  638.         self[name] = Glyph([c, c2, cc])
  639.         self[name].individualWidth = individualWidth  
  640.                
  641.  
  642.     def _glyph_M1(self, name):
  643.        
  644.         individualWidth = globalWidth * 1.0
  645.        
  646.         n1 = Node(left, baseline, "leftStart")  
  647.         n2 = Node(2/10. * (left + individualWidth), capHeight + baseline, "leftTop")
  648.         n3 = Node(1/ 2. * (left + individualWidth), baseline, "middleBottom")
  649.         n4 = Node(8/10. * (left + individualWidth), capHeight + baseline, "rightTop")
  650.         n5 = Node(left + individualWidth, baseline, "rightEnd")
  651.        
  652.         c1 = Connection(n1, n2)        
  653.         c2 = Connection(n2, n3)
  654.         c3 = Connection(n3, n4)
  655.         c4 = Connection(n4, n5)
  656.        
  657.         s = Stroke([c1, c2, c3, c4])
  658.            
  659.         self[name] = Glyph([s])
  660.         self[name].individualWidth = individualWidth
  661.        
  662.  
  663.     def _glyph_N(self, name):
  664.         individualWidth = globalWidth * 0.7
  665.        
  666.         n1 = Node(left, baseline, "leftTop")
  667.         n2 = Node(left, capHeight, "middleBottom")
  668.         n3 = Node(left + individualWidth, baseline, "rightTop")
  669.         n4 = Node(left + individualWidth, capHeight, "rightEnd")
  670.        
  671.         c1 = Connection(n1, n2)
  672.         c2 = Connection(n2, n3)
  673.         c3 = Connection(n3, n4)
  674.            
  675.         s = Stroke([c1, c2, c3])
  676.            
  677.         self[name] = Glyph([s])
  678.        
  679.         self[name].individualWidth = individualWidth      
  680.        
  681.  
  682.     def _glyph_U(self, name):
  683.         #print "initializing ", name
  684.         individualWidth = globalWidth*0.8
  685.        
  686.         n={0:0}
  687.         n[1] = Node( left, capHeight+baseline, "middleTop")
  688.         n[2] = Node( left, capHeight * 1/3 + baseline, "leftMiddle")
  689.         n[3] = Node( (left + individualWidth) / 2., baseline, "middleBottom")
  690.         n[4] = Node( individualWidth, capHeight * 1/3  + baseline, "rightEnd")
  691.         n[5] = Node( individualWidth, capHeight, "rightEnd")
  692.        
  693.         c1 = Connection(n[1], n[2],)        
  694.         c2 = Connection(n[2], n[3], "lb")
  695.         c3 = Connection(n[3], n[4], "rb")
  696.         c4 = Connection(n[4], n[5],)
  697.            
  698.         s = Stroke([c1, c2, c3, c4])
  699.            
  700.         self[name] = Glyph([s])
  701.         self[name].individualWidth = individualWidth
  702.  
  703.    
  704.     def _glyph_W2(self, name):
  705.         individualWidth = globalWidth * 1.2
  706.        
  707.         n1 = Node(left, capHeight, "leftStart")  
  708.         n2 = Node(1/3.*(left + individualWidth), baseline, "leftTop")
  709.         n3 = Node(3/5.*(left + individualWidth), capHeight, "middleBottom")
  710.        
  711.         n4 = Node(2/5.*(left + individualWidth), capHeight, "middleBottom")
  712.         n5 = Node(2/3.*(left + individualWidth), baseline, "rightTop")
  713.         n6 = Node(left + individualWidth, capHeight, "rightEnd")
  714.        
  715.         c1 = Connection(n1, n2)        
  716.         c2 = Connection(n2, n3)
  717.         c3 = Connection(n4, n5)
  718.         c4 = Connection(n5, n6)
  719.            
  720.            
  721.         stroke1 = Stroke([c1, c2])
  722.         stroke2 = Stroke([c3, c4])
  723.  
  724.         self[name] = Glyph([stroke1, stroke2])
  725.         self[name].individualWidth = individualWidth  
  726.        
  727.        
  728.     def _glyph_n1(self, name):
  729.         individualWidth = globalWidth * 0.6
  730.  
  731.         #stem
  732.        
  733.         n1 = Node(left, baseline, "leftTop")
  734.         n2 = Node(left, xHeight, "middleBottom")
  735.        
  736.         c1 = Connection(n1, n2)
  737.        
  738.         stroke1 = Stroke([c1])
  739.  
  740.        
  741.         #bogen
  742.        
  743.         n3 = Node( left, StemShoulderConnectionHeight, "rightTop")
  744.        
  745.         n4 = Node( (left + individualWidth)*550/1000 , xHeight, "rightTop")
  746.         n5 = Node(left + individualWidth, xHeight*650/1000, "rightEnd")
  747.         n6 = Node(left + individualWidth, baseline, "rightEnd")
  748.  
  749.         c2 = Connection(n3, n4, "lt")
  750.         c3 = Connection(n4, n5, "rt")
  751.         c4 = Connection(n5, n6)
  752.        
  753.         stroke2 = Stroke([c2,c3,c4])
  754.            
  755.         self[name] = Glyph([stroke1, stroke2])
  756.         self[name].individualWidth = individualWidth  
  757.  
  758.  
  759.     def _glyph_a1(self, name):
  760.         individualWidth = globalWidth * 0.65
  761.  
  762.         n1 = Node(left + individualWidth, StemShoulderConnectionHeight, "rightTopStartBowl")
  763.         n2 = Node( (left + individualWidth) / 2. , xHeight, "MiddleTopBowl")
  764.         n3 = Node( left, xHeight / 2., "leftHorizontalMiddle")
  765.         n4 = Node( (left + individualWidth) / 2. , baseline, "rightTop")
  766.         n5 = Node(left + individualWidth, BottomBowlConnectionHeight, "rightEnd")
  767.  
  768.         c1 = Connection(n1, n2, "rt")
  769.         c2 = Connection(n2, n3, "lt")
  770.         c3 = Connection(n3, n4, "lb")
  771.         c4 = Connection(n4, n5, "rb")
  772.        
  773.         stroke1 = Stroke([c1, c2, c3, c4])
  774.  
  775.  
  776.         #stem
  777.         st1 = Node(left + individualWidth, baseline, "leftTop")
  778.         st2 = Node(left + individualWidth, xHeight, "middleBottom")
  779.        
  780.         cs1 = Connection(st1, st2)
  781.        
  782.         stroke2 = Stroke([cs1])
  783.  
  784.            
  785.         self[name] = Glyph([stroke1, stroke2])
  786.         self[name].individualWidth = individualWidth  
  787.        
  788.  
  789.     def _glyph_a2(self, name):
  790.         individualWidth = globalWidth * 0.65
  791.  
  792.         n1 = Node(left + individualWidth, xHeight * 300/1000, "rightTopStartBowl")
  793.         n2 = Node( (left + individualWidth) / 2. , xHeight* 6/10, "MiddleTopBowl")
  794.         n3 = Node( left, xHeight * 300/1000, "leftHorizontalMiddle")
  795.         n4 = Node( (left + individualWidth) / 2. , baseline, "rightTop")
  796.         n5 = Node(left + individualWidth, xHeight * 300/1000, "rightEnd")
  797.  
  798.         c1 = Connection(n1, n2, "rt")
  799.         c2 = Connection(n2, n3, "lt")
  800.         c3 = Connection(n3, n4, "lb")
  801.         c4 = Connection(n4, n5, "rb")
  802.  
  803.         stroke1 = Stroke([c1, c2, c3, c4])
  804.  
  805.  
  806.         #stem
  807.         st1 = Node(left, xHeight*750/1000, "left Arm, Start")
  808.         st2 = Node(left + individualWidth/ 2., xHeight, "MiddleTop")
  809.         st3 = Node(left + individualWidth, xHeight*750/1000, "Right Shoulder")
  810.         st4 = Node(left + individualWidth, baseline, "leftTop")
  811.        
  812.         cs1 = Connection(st1, st2, "lt")
  813.         cs2 = Connection(st2, st3, "rt")
  814.         cs3 = Connection(st3, st4)        
  815.        
  816.         stroke2 = Stroke([cs1, cs2, cs3])
  817.  
  818.            
  819.         self[name] = Glyph([stroke1, stroke2])
  820.         self[name].individualWidth = individualWidth  
  821.        
  822.  
  823.     def _glyph_c(self, name):
  824.         individualWidth = globalWidth * 0.65
  825.  
  826.         n1 = Node(left + individualWidth, rightOpenContourFromTopMinors, "rightTopStartBowl")
  827.         n2 = Node( (left + individualWidth) / 2. , xHeight, "MiddleTopBowl")
  828.         n3 = Node( left, xHeight/ 2., "leftHorizontalMiddle")
  829.         n4 = Node( (left + individualWidth) / 2. , baseline, "rightTop")
  830.         n5 = Node(left + individualWidth, rightOpenContourFromBottomMinors, "rightEnd")
  831.  
  832.         c1 = Connection(n1, n2, "rt start")
  833.         c2 = Connection(n2, n3, "lt")
  834.         c3 = Connection(n3, n4, "lb")
  835.         c4 = Connection(n4, n5, "rb end")
  836.  
  837.         s = Stroke([c1, c2, c3, c4])
  838.            
  839.         self[name] = Glyph([s])
  840.         self[name].individualWidth = individualWidth              
  841.  
  842.  
  843.     def _glyph_e3(self, name):
  844.         individualWidth = globalWidth * 0.65
  845.  
  846.         #crossbar
  847.        
  848.         n1 = Node(left, xHeight / 2., "crossbar, left")
  849.         n2 = Node((left + individualWidth) * 950 / 1000 , xHeight / 2., "crossbar, right")
  850.  
  851.         #round stroke
  852.         n3 = Node(left + individualWidth, xHeight * 2/3, "right, top, bowl")
  853.         n4 = Node( (left + individualWidth) / 2. , xHeight, "vertical middle, top, bowl")
  854.         n5 = Node( left, xHeight / 2., "left, vertical middle")
  855.         n6 = Node( (left + individualWidth) / 2. , baseline, "horizontal, middle, bottom")
  856.         n7 = Node(left + individualWidth, rightOpenContourFromBottomMinors, "right, bottom, arm")
  857.  
  858.         c1 = Connection(n1, n2)
  859.         c2 = Connection(n2, n3, "rb")
  860.         c3 = Connection(n3, n4, "rt")
  861.         c4 = Connection(n4, n5, "lt")
  862.         c5 = Connection(n5, n6, "lb")
  863.         c6 = Connection(n6, n7, "rb")
  864.  
  865.         s1 = Stroke([c1])
  866.         s2 = Stroke([c2, c3, c4, c5, c6])
  867.  
  868.         self[name] = Glyph([s1, s2])
  869.         self[name].individualWidth = individualWidth        
  870.        
  871.        
  872.     def _glyph_g1(self, name):
  873.         individualWidth = globalWidth * 0.7
  874.  
  875.         n1 = Node(left + individualWidth, xHeight * 500/1000, "rightTopStartBowl")
  876.         n2 = Node( (left + individualWidth) / 2. , xHeight, "MiddleTopBowl")
  877.         n3 = Node( left, xHeight / 2., "leftHorizontalMiddle")
  878.         n4 = Node( (left + individualWidth) / 2. , baseline, "rightTop")
  879.        
  880.         c={0:0}
  881.         c[1] = Connection(n1, n2, "rt")
  882.         c[2] = Connection(n2, n3, "lt")
  883.         c[3] = Connection(n3, n4, "lb")
  884.         c[4] = Connection(n4, n1, "rb")
  885.        
  886.         s={0:0}
  887.         s[1] = Stroke([c[1], c[2], c[3], c[4]])
  888.        
  889.        
  890.         #lower thingy
  891.         n5 = Node(left + individualWidth, descHeight * 500/1000, "rightTopStartBowl")
  892.         n6 = Node( (left + individualWidth) / 2. , descHeight, "MiddleTopBowl")
  893.         n7 = Node( left, descHeight / 2., "leftHorizontalMiddle")
  894.         n8 = Node( (left + individualWidth) / 2. , baseline, "rightTop")
  895.        
  896.         c[5] = Connection(n5, n6, "rb")
  897.         c[6] = Connection(n6, n7, "lb")
  898.         c[7] = Connection(n7, n8, "lt")
  899.         c[8] = Connection(n8, n5, "rt")
  900.        
  901.         s[2] = Stroke([c[5], c[6], c[7], c[8]])
  902.  
  903.         self[name] = Glyph([s[1],s[2]])
  904.         self[name].individualWidth = individualWidth  
  905.  
  906.  
  907.     def _glyph_g2(self, name):
  908.         individualWidth = globalWidth * 0.7
  909.  
  910.         n1 = Node(left + individualWidth, xHeight * 600/1000, "rightTopStartBowl")
  911.         n2 = Node( (left + individualWidth) / 2. , xHeight, "MiddleTopBowl")
  912.         n3 = Node( left, xHeight  * 600/1000, "leftHorizontalMiddle")
  913.         n4 = Node( (left + individualWidth) / 2. , xHeight*200/1000, "rightTop")
  914.        
  915.         c={0:0}
  916.         c[1] = Connection(n1, n2, "rt")
  917.         c[2] = Connection(n2, n3, "lt")
  918.         c[3] = Connection(n3, n4, "lb")
  919.         c[4] = Connection(n4, n1, "rb")
  920.        
  921.         s={0:0}
  922.         s[1] = Stroke([c[1], c[2], c[3], c[4]])
  923.        
  924.        
  925.         #lower thingy
  926.         n5 = Node( (left+ individualWidth)*0.1 , xHeight*0.3, "rightTop")
  927.         n6 = Node( left , xHeight*0.15, "rightTop")
  928.         n7 = Node( (left + individualWidth)*0.2 , baseline, "rightTop")
  929.         n8 = Node( (left + individualWidth)*0.7 , baseline, "rightTop")
  930.         n9 = Node( left + individualWidth, descHeight / 2., "leftHorizontalMiddle")
  931.         n10 = Node( (left + individualWidth) / 2. , descHeight, "MiddleTopBowl")
  932.         n11 = Node(left, descHeight * 500/1000, "rightTopStartBowl")
  933.                
  934.         c[5] = Connection(n5, n6, "lt")
  935.         c[6] = Connection(n6, n7, "lb")
  936.         c[7] = Connection(n7, n8, "")
  937.         c[8] = Connection(n8, n9, "rt")
  938.         c[9] = Connection(n9, n10, "rb")
  939.         c[10] = Connection(n10, n11, "lb")
  940.        
  941.         s[2] = Stroke([c[5], c[6], c[7], c[8], c[9], c[10]])
  942.  
  943.         self[name] = Glyph([s[1],s[2]])
  944.         self[name].individualWidth = individualWidth  
  945.              
  946.        
  947.  
  948.     def _glyph_o(self, name):
  949.         individualWidth = globalWidth * 0.7
  950.  
  951.         n1 = Node(left + individualWidth, xHeight * 500/1000, "rightTopStartBowl")
  952.         n2 = Node( (left + individualWidth) / 2. , xHeight, "MiddleTopBowl")
  953.         n3 = Node( left, xHeight / 2., "leftHorizontalMiddle")
  954.         n4 = Node( (left + individualWidth) / 2. , baseline, "rightTop")
  955.        
  956.         c={0:0}
  957.         c[1] = Connection(n1, n2, "rt")
  958.         c[2] = Connection(n2, n3, "lt")
  959.         c[3] = Connection(n3, n4, "lb")
  960.         c[4] = Connection(n4, n1, "rb")
  961.        
  962.         s1 = Stroke([c[1], c[2], c[3], c[4]])
  963.  
  964.         self[name] = Glyph([s1])
  965.         self[name].individualWidth = individualWidth  
  966.  
  967.  
  968.     def _glyph_s1(self, name):
  969.         individualWidth = globalWidth * 0.6
  970.        
  971.         n={0:0}
  972.         n[1] = Node(left + individualWidth, rightOpenContourFromTopMinors, "right top bowl")
  973.         n[2] = Node( (left + individualWidth) / 2. , xHeight, "MiddleTopBowl")
  974.         n[3] = Node( left, xHeight*800/1000, "left top bowl middle")
  975.         n[4] = Node( left  + individualWidth*300/1000, xHeight*600/1000, "tob bowl, connection to straight middle part")
  976.         n[5] = Node( left  + individualWidth*700/1000, xHeight*500/1000, "lower bowl, connection to straight middle part")
  977.         n[6] = Node( left  + individualWidth, xHeight*250/1000, "right, verical middle of bottom bowl")
  978.         n[7] = Node( left  + individualWidth*500/1000, baseline, "bottom, horizontal middle")
  979.         n[8] = Node( left, rightOpenContourFromBottomMinors, "left, vertical middle of bottom bowl")
  980.        
  981.         c={0:0}
  982.         c[1] = Connection(n[1], n[2], "rt arm")
  983.         c[2] = Connection(n[2], n[3], "lt")
  984.         c[3] = Connection(n[3], n[4], "lb")
  985.         c[4] = Connection(n[4], n[5], "crossbar straight")
  986.         c[5] = Connection(n[5], n[6], "rt")
  987.         c[6] = Connection(n[6], n[7], "rb")
  988.         c[7] = Connection(n[7], n[8], "lb")
  989.            
  990.         s1 = Stroke([c[1], c[2], c[3], c[4], c[5], c[6], c[7] ])
  991.  
  992.         self[name] = Glyph([s1])
  993.         self[name].individualWidth = individualWidth              
  994.              
  995.  
  996.     def _glyph_z(self, name):
  997.         individualWidth = globalWidth * 0.55
  998.  
  999.         n1 = Node(left, xHeight, "rightTopStartBowl")
  1000.         n2 = Node( (left + individualWidth), xHeight, "MiddleTopBowl")
  1001.         n3 = Node( left, baseline, "leftHorizontalMiddle")
  1002.         n4 = Node( (left + individualWidth) , baseline, "rightTop")
  1003.  
  1004.         c={0:0}        
  1005.         c[1] = Connection(n1, n2)
  1006.         c[2] = Connection(n2, n3)
  1007.         c[3] = Connection(n3, n4)
  1008.  
  1009.         s1 = Stroke([c[1], c[2], c[3]])
  1010.  
  1011.         self[name] = Glyph([s1])
  1012.         self[name].individualWidth = individualWidth
  1013.  
  1014.                        
  1015.    
  1016. class Path(object):
  1017.     def paint(self,gc):
  1018.         print "Path Drawn"
  1019.            
  1020.         b = Guideline(baseline, "baseline")
  1021.         x = Guideline(300, "x-Height")
  1022.         x = Guideline(capHeight, "Cap-Height")
  1023.        
  1024.        
  1025.         f = Font()
  1026.         f.createGlyphs()
  1027.        
  1028.         print "drawing font"
  1029.         f.draw(gc)
  1030.  
  1031.  
  1032.  
  1033. class LetterPanel(wx.Panel):
  1034.     def __init__(self,parent=None,id=-1):
  1035.         wx.Panel.__init__(self,parent,id,style=wx.TAB_TRAVERSAL)        
  1036.         self.SetBackgroundColour("#FFFFFF")
  1037.         self.Bind(wx.EVT_PAINT,self.onPaint)
  1038.         self.SetDoubleBuffered(True)
  1039.         self.path=Path()
  1040.  
  1041.     def onPaint(self, event):
  1042.         event.Skip()
  1043.  
  1044.         dc=wx.PaintDC(self)
  1045.         dc.BeginDrawing()
  1046.         gc = wx.GraphicsContext.Create(dc)
  1047.        
  1048.         #size(10 * ScaleFactor*globalWidth, 6000 * ScaleFactor)
  1049.        
  1050.         gc.Scale(ScaleFactor, -ScaleFactor)
  1051.         gc.Translate(1000 * ScaleFactor, 1000 * ScaleFactor - 1100)
  1052.  
  1053.         gc.PushState()
  1054.  
  1055.         self.path.paint(gc)
  1056.         gc.PopState()
  1057.         dc.EndDrawing()
  1058.  
  1059.  
  1060. class LetterFrame(wx.Frame):
  1061.     def __init__(self, parent, title):
  1062.        
  1063.         #opening a window
  1064.         wx.Frame.__init__(self, parent, title=title, pos=(0, 22), size=(wx.DisplaySize()[0],wx.DisplaySize()[1]-200))
  1065.         #wx.Frame.__init__(self, parent, title=title, pos=(0, 22), size=(wx.DisplaySize()[0],wx.DisplaySize()[1]-22))
  1066.        
  1067.         #create a panel in that window
  1068.         self.mainPanel=LetterPanel(self,-1)
  1069.  
  1070.         self.Show(True)
  1071.  
  1072.  
  1073. app = wx.App(False)
  1074. frame = LetterFrame(None,"Type as Graph")
  1075. app.MainLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement