#!/usr/bin/env ruby # the paper foldings diagram class definitions are here include Math require 'win32ole' module AiEnum def self.ais # number of AiEnumarationConstants self.constants.select{ |c| /^Ai/=~c }.size end # def ais end # module AiEnum begin # WIN32OLE::const_load ole_name = 'Illustrator.Application' ole_const_loaded = false ole_connected = false ole_created = false ole_retry_times = 3 # The times of retring to create Illustrator Application object. ole_retry_sleep = 1 # times, sleep = 3,1 | 4,0 ...(3,12: sleep larger but times more than 3) puts 'flags are initialized' if $VERBOSE begin # WIN32OLE.const_load begin puts 'try connect' if $VERBOSE illustrator = WIN32OLE.connect(ole_name) # illustrator.Visible = true ole_connected = true puts 'connected' if $VERBOSE rescue WIN32OLERuntimeError => err puts err if $VERBOSE # raise puts 'not connected' if $VERBOSE begin puts "try to create(new): #{ole_retry_times}" if $VERBOSE illustrator = WIN32OLE.new(ole_name) # illustrator.Visible = true ole_created = true puts 'created(newed)' if $VERBOSE rescue WIN32OLERuntimeError => err puts err if $VERBOSE # raise puts 'not created(newed)' if $VERBOSE if (ole_retry_times -= 1)>0 and not illustrator sleep ole_retry_sleep retry end # if (ole_retry_times -= 1)>0 and not illustrator end end if illustrator and illustrator.type == WIN32OLE begin puts 'try to const_load' if $VERBOSE WIN32OLE::const_load(illustrator, AiEnum) ole_const_loaded = true puts 'const_loaded' if $VERBOSE rescue => err puts err puts 'const_load failed' if $VERBOSE ensure end end # if illustrator and illustrator.type == WIN32OLE rescue => err puts err if $VERBOSE puts 'not conset_load 1stly' if $VERBOSE raise # raise end # WIN32OLE.const_load ensure # WIN32OLE::const_load if illustrator puts 'illustrator defined' if $VERBOSE if (ole_created and not ole_connected) or (ole_const_loaded and not ole_connected) puts 'ole_created and not ole_connected' if $VERBOSE and ole_created and not ole_connected puts 'ole_const_loaded and not ole_connected' if $VERBOSE and ole_const_loaded and not ole_connected puts 'not ole_created' if $VERBOSE and not ole_created puts 'not ole_const_loaded' if $VERBOSE and not ole_const_loaded illustrator.quit puts 'quited (illustrator did quit)' if $VERBOSE end # if ole_created and not ole_connected end # if illustrator end # WIN32OLE::const_load puts 'end of constants section' if $VERBOSE # Constants, Constants, Constants. class Illu include AiEnum attr_reader :paper # attr_reader :margin, :size, :wide, :high attr_reader :left, :bottom Mkw = Math::tan(Math::PI/8) MkwH = (1.0 - Math::tan(Math::PI/8)) MkwS = Math::sin(Math::PI/8) MkwC = Math::cos(Math::PI/8) # Rakuda Base Point # Mkw/(1+Mkw) = tanPI/8 /(1 + tanPi/8) = (sinPI/8 / cosPi/8) / (1 + sinPI/8 / cosPi/8) # = sinPI/8 /(cosPI/8 + sinPI/8) # 1/(1+Mkw) = cosPI/8 /(cosPI/8 + sinPI/8) Rkd = Math::sin(Math::PI/8)/(Math::cos(Math::PI/8) + Math::sin(Math::PI/8)) # smaller RkdH = Math::cos(Math::PI/8)/(Math::cos(Math::PI/8) + Math::sin(Math::PI/8)) # bigger Mountain = [5, 2, 0.5, 1, 0.5, 2] Valley = [4, 2] Dotted = [1, 1.5] # Paper sizes for initialtion # # Add([DocumentColorSpace As AiDocumentColorSpace], [Width As Single], [Height As Single]) # # Creates a new document using optional parameters and returns a reference to the new A4 = Hash[:width, 595.28, :height, 841.89] B5 = Hash[:width, 515.91, :height, 728.50] def initialize(left=32, bottom = false, color_space = 2, size = A4) # 2 == AiEnum::AiDocumentCMYKColor: if AiEnum did not const_load then retry load in this initialize method bottom || bottom = left @left, @bottom = left, bottom begin illustrator = WIN32OLE.connect('Illustrator.Application') rescue WIN32OLERuntimeError => err puts err puts 'Retry (WIN32OLE.new)' begin illustrator = WIN32OLE.new('Illustrator.Application') rescue WIN32OLERuntimeError => err puts err puts 'Can not connect nor create Illustrator.Application. Exit!' exit 1 end # begin WIN32OLE.new end # begin WIN32OLE.connect WIN32OLE::const_load(illustrator, AiEnum) if AiEnum::ais==0 #@paper = illustrator::Documents.Add(color_space, A4[:width], A4[:height]) @paper = illustrator::Documents.Add(color_space, size[:width], size[:height]) @paper.DefaultFilled = false @paper.DefaultStroked = true # @paper.DefaultStrokeWidth = 0.1 @paper.DefaultStrokeWidth = 0.25 @paper.DefaultStrokeCap = AiButtEndCap @paper.DefaultStrokeJoin = AiMiterEndJoin @paper.DefaultStrokeMiterLimit = @paper.DefaultStrokeWidth / 2.0 @paper.DefaultStrokeDashes = [] color = @paper.DefaultStrokeColor case color.Color when AiColorCMYK color.CMYK.Black, color.CMYK.Cyan, color.CMYK.Magenta, color.CMYK.Yellow = 100, 0, 0, 0 else # The author do not write programs when the ColorSpace is not CMYK. # But must do so. end # case color.Color end # def initialize(left, bottom) def destroy @paper.Close(AiDoNotSaveChanges) end # def destroy def saveas(name = Time::now.strftime('%Y%m%d%H%M%S')) @paper.SaveAs(name) end # def saveas(name = Time::now.strftime('%Y%m%d%H%M%S')) def self.hs(sign) # Heaviside function return 1 if sign.to_f > 0 return 0 if sign.to_f < 0 return 1/2.0 end # def self.hs(sign) # Heaviside function def self.sh(heviside) heviside = heviside.to_f return +1 if heviside == 1 return -1 if heviside == 0 return 0 if heviside == 1/2.0 return +1 if heviside > 1/2.0 return -1 if heviside < 1/2.0 return 0 end def self.select(paths) paths.to_a.each{ |path| path.Selected = true } return paths end # def self.select(paths) def self.setcolor(c, cname = 'Black') case c.Color when AiColorCMYK case cname when /^b/i, 'Black' c.CMYK.Black, c.CMYK.Cyan, c.CMYK.Magenta, c.CMYK.Yellow = 100, 0, 0, 0 when /^c/i, 'Cyan' c.CMYK.Black, c.CMYK.Cyan, c.CMYK.Magenta, c.CMYK.Yellow = 0, 100, 0, 0 when /^w/i, 'White' c.CMYK.Black, c.CMYK.Cyan, c.CMYK.Magenta, c.CMYK.Yellow = 0, 0, 0, 0 else # 'Black' c.CMYK.Black, c.CMYK.Cyan, c.CMYK.Magenta, c.CMYK.Yellow = 100, 0, 0, 0 end # case cname when AiColorGray case cname when /^b/i, 'Black' c.Gray.Gray = 100 when /^c/i, 'Cyan' c.Gray.Gray = 40 when /^w/i, 'White' c.Gray.Gray = 0 else # 'Black' c.Gray.Gray = 100 end # case cname else # The author do not wright programs when the ColorSpace is not CMYK. end # case c.Color end # def self.setcolor(c, cname) def method_missing(*var) # $stderr.puts var[1..-1].type # $stderr.puts var[1..-1].size # $stderr.puts "[#{var[1..-1]}]" $stderr.puts "@paper.#{var[0]}(*[#{var[1..-1]}])" if $VERBOSE eval("@paper.#{var[0]}(*[#{var[1..-1]}])") # super end # def method_missing(name, args) # Visible Height and Width: not for Illustrator's Height, Width from Geometrics. # # # Document.Height: The height of the document., calculated from the GeometricBounds. # # Document.Width: The width of this document, calculated from the GeometricBounds. def vHeight visibles = self.paper.VisibleBounds return (visibles[3] - visibles[1]).abs end # def vHeight def vWidth visibles = self.paper.VisibleBounds return (visibles[2] - visibles[0]).abs end # def vWidth def newlayer(name = 'emanon'.reverse!) layr = self.paper.Layers.Add layr.Name = name return layr end # def newlayer(name) =begin def line(points = [], name = '', type = 'Solid', layr = self.paper.ActiveLayer) # points = Array of Array s of two Float s. # (MultiPoints) makes one open path. path = layr.PathItems.Add path.Name = name points.each do |p| point = path.PathPoints.Add point.Anchor = [ p[0]+@left, p[1]+@bottom ] point. LeftDirection = point.Anchor point.RightDirection = point.Anchor end # points.each do |p| case type when /^m/i, 'Mountain' path.StrokeDashes = Mountain when /^v/i, 'Valley' path.StrokeDashes = Valley else # 'Solid' path.StrokeDashes = [] end # case type return self, path end # def line(points = [[]], type = 'Solid', layr = self.paper.ActiveLayer) =end def line(points = [], name = '', type = 'Solid', layr = self.paper.ActiveLayer) # points = Array of Array s of two Float s. # (MultiPoints) makes many open paths of which each path has only two AnchorPoints. paths = [] # points.each_index do |i| (0 ... (points.size-1)).each do |i| j = (i+1) % points.size # if points.size == 1: ONE point case, j=i=0 . # The case does not occur in (0 ... (points.size-1)) . path = layr.PathItems.Add path.Name = ( (points.size<=2)? name : name+i.to_s ) point_i = path.PathPoints.Add point_i.Anchor = [ points[i][0]+@left, points[i][1]+@bottom ] point_i. LeftDirection = point_i.Anchor point_i.RightDirection = point_i.Anchor point_j = path.PathPoints.Add point_j.Anchor = [ points[j][0]+@left, points[j][1]+@bottom ] point_j. LeftDirection = point_j.Anchor point_j.RightDirection = point_j.Anchor case type when /^m/i, 'Mountain' path.StrokeDashes = Mountain when /^v/i, 'Valley' path.StrokeDashes = Valley when /^d/i, 'Dotted' path.StrokeDashes = Dotted when /^w/i, 'White' path.StrokeDashes = [] path.StrokeWidth = @paper.DefaultStrokeWidth*1.01 Illu::setcolor(path.StrokeColor, 'white') else # 'Solid' path.StrokeDashes = [] end # case type paths << path end # points.each_index do |i| paths = paths[0] if paths.size==1 return self, paths end # def line(points = [[]], type = 'Solid', layr = self.paper.ActiveLayer) def polygon(points = [], name = '', type = 'Solid', layr = self.paper.ActiveLayer) paths = [] points.each_index do |i| paths << self.line([points[i], points[(i+1) % points.size]], name+"_#{i}", type, layr)[1] end # points.each_index do |i| return self, paths end # def polygon(points = [[]], name = '', type = 'Solid', layr = self.paper.ActiveLayer) def square(size, name = '', lb = [0,0], type = 'Solid', layr = self.paper.ActiveLayer) return self.polygon( [ lb, [lb[0]+size, lb[1]], [lb[0]+size, lb[1]+size], [lb[0], lb[1]+size] ], name, type, layr) end # def square(size, lb = [0,0], name = '', type = 'Solid', layr = self.paper.ActiveLayer) ['line', 'polygon'].each do |lp| ['M', 'V', 'S', 'D', 'W'].each do |mvs| eval <<-HEAR def #{lp}#{mvs}(points = [], name = '', layr = self.paper.ActiveLayer) return #{lp}(points, name, '#{mvs}', layr) end HEAR end # ['M', 'V', 'S'].each do |mvs| end # ['line', 'polygon'].each do |lp| def ellipse(lt = [0,0], wh = [0,0], type = 'Solid', name='', layr = self.paper.ActiveLayer, reversed = true, inscribed = true) elli = layr.PathItems.Ellipse(lt[1]+@bottom,lt[0]+@left, wh[0],wh[1], reversed, inscribed) elli.Name = name case type when /^m/i, 'Mountain' elli.StrokeDashes = Mountain when /^v/i, 'Valley' elli.StrokeDashes = Valley when /^d/i, 'Dotted' elli.StrokeDashes = Dotted when /^w/i, 'White' elli.StrokeDashes = [] elli.StrokeWidth = @paper.DefaultStrokeWidth*1.01 Illu::setcolor(elli.StrokeColor, 'white') else # 'Solid' elli.StrokeDashes = [] end # case type return self, elli end # def ellipse(lt = [0,0], wh = [0,0], type = 'Solid', name='', layr = self.paper.ActiveLayer) def elli(c, rx, ry = rx, type = 'Solid', name='', layr = self.paper.ActiveLayer, reversed = true, inscribed = true) return self.ellipse([c[0]-rx, c[1]+ry], [rx*2.0, ry*2.0], type, name, layr, reversed, inscribed) end # def elli(c, rx, ry = rx, type = 'Solid', name='', layr = self.paper.ActiveLayer) ColorTamago = WIN32OLE.new('Illustrator.Color') cmyk = WIN32OLE.new('Illustrator.CMYKColor') cmyk.Cyan, cmyk.Magenta, cmyk.Yellow, cmyk.Black = 0,0,20,0 ColorTamago.CMYK = cmyk # def filled(points = [], type='Solid', name='', filledcolor = [0,0,20,0], layr=self.paper.ActiveLayer) def filled(points = [], type='Solid', name='', filledcolor = 'default', layr=self.paper.ActiveLayer) path = layr.PathItems.Add path.Name = name points.each do |pt| point = path.PathPoints.Add point.Anchor = [ pt[0]+@left, pt[1]+@bottom ] point. LeftDirection = point.Anchor point.RightDirection = point.Anchor end # points.each do |pt| path.Closed = true case type when /^m/i, 'Mountain' path.StrokeDashes = Mountain when /^v/i, 'Valley' path.StrokeDashes = Valley when /^d/i, 'Dotted' path.StrokeDashes = Dotted when /^w/i, 'White' path.StrokeDashes = [] path.StrokeWidth = @paper.DefaultStrokeWidth*1.01 Illu::setcolor(elli.StrokeColor, 'white') when /^h/i, 'Hidden' path.Stroked = false else # 'Solid' path.StrokeDashes = [] end # case type if filledcolor!='default' color = WIN32OLE.new('Illustrator.Color') cmyk = WIN32OLE.new('Illustrator.CMYKColor') cmyk.Cyan, cmyk.Magenta, cmyk.Yellow, cmyk.Black = filledcolor color.CMYK = cmyk path.FillColor = color else # if filledcolor!='default' path.FillColor = ColorTamago end # if filledcolor!='default' path.Filled = true return self, path end # def filled(anchors, type='Solid', name='', filledcolor = [0,0,20,0], layr=self.paper.ActiveLayer) def settext(str='', center = [0,0], direction = 0, scale = 0.5, layr = self.paper.ActiveLayer) # text = layr.TextArtItems.Add text_items = layr.TextArtItems text = text_items.Add text.Kind = AiPointText # text.Kind = AiPathText # text.Kind = AiAreaTextxt text.Contents = str text.Name = str text.Resize(100*scale, 100*scale) text.Rotate(direction) # text.Position visibles = text.VisibleBounds # vw = (visibles[2] - visibles[0]).abs # vh = (visibles[3] - visibles[1]).abs # vw = (visibles[2] - visibles[0]) # vh = (visibles[1] - visibles[3]) # こうしたらabsは要らない筈なんだが一応付けとく vw = (visibles[2] - visibles[0]).abs vh = (visibles[1] - visibles[3]).abs # text.Position = [ center[0] + @left - vw/2, center[1] + @bottom + vh ] # なんだか良くわからないけど、これだと配置高さの調整がうまくいく(2003/2/28) text.Position = [ center[0] + @left - vw/2, center[1] + @bottom + vh/2 ] # 此れが所要の筈なんだ、pointが左上なんで -vw +vh と符号がずれる(2003/3/16) # text.Position = [ center[0] + @left - vw/2, center[1] + @bottom ] # text.Position = [ center[0] + @left - vw/2, center[1] + @bottom - vh ] # text.Position = [ center[0] + @left - vw/2, center[1] + @bottom - vh/2 ] # text.Position = [ center[0] + @left - vw/2, center[1] -( @bottom - vh/2) ] return self, text, vw, vh, (vw+vh)/2 end # def settext(str, center, direction, scale, layr) def pathfindout layr = self.paper.ActiveLayer illu = layr.Application illu.DoScript('myPathFinder', 'myActions') # Beforehand we defiend the action 'myPathFinder' of 'myActions'. (myActions.aia) # # pathfinder-outline sleep 0.5 while illu.ActionIsRunning grp = layr.GroupItems pathItems = grp.item(grp.Count).PathItems paths = [] 1.upto(pathItems.Count) do |i| # path.Filled = @paper.DefaultFilled path = pathItems.item(i) #path.Stroked = @paper.DefaultStroked #path.StrokeWidth = @paper.DefaultStrokeWidth #path.StrokeCap = @paper.DefaultStrokeCap #path.StrokeJoin = @paper.DefaultStrokeJoin #path.StrokeMiterLimit = @paper.DefaultStrokeMiterLimit #path.StrokeDashes = @paper.DefaultStrokeDashes # default values are not good valuation path.Stroked = true path.StrokeWidth = 0.1 path.StrokeCap = AiButtEndCap path.StrokeJoin = AiMiterEndJoin path.StrokeMiterLimit = path.StrokeWidth/2 path.StrokeDashes = [] # path.StrokeColor.Color = AiColorCMYK Illu::setcolor(path.StrokeColor, 'cyan') paths << path end # 1.upto(pathItems.Count) do |path| return self, paths end # def pathfindout def measurement items = [] (64+2).times do |y| items << self.settext(y.to_s, [ 15*(y % 3), y/64.0*$size], 0, 1) items << self.settext(y.to_s, [ 50+ 20*(y % 3), y/64.0*$size], 0, 1.2) items << self.settext(y.to_s, [120+ 25*(y % 3), y/64.0*$size], 0, 1.5) items << self.settext(y.to_s, [200+ 30*(y % 3), y/64.0*$size], 0, 1.8) items << self.settext(y.to_s, [300+ 30*(y % 3), y/64.0*$size], 0, 2 ) end # (64+4).times do |y| return self, items end # def self.measurement end # class Illu #class Illustration < Illu # # alias Illustration Illu #end Illustration = Illu # alias AiEnumerations AiEnum AiEnumerations = AiEnum if $0 == __FILE__ p Illu::Mkw end # if $0 == __FILE__