Class: AAlib::Context

Inherits:
CPtr show all
Defined in:
lib/aalib.rb

Overview

A graphics context opened using a particular driver along with any keyboard and mouse drivers. Two buffers are maintained: the image buffer and the screen or text buffer. AAlib::Context#putpixel is the primary method to draw on the image buffer. AAlib::Context#render converts the image buffer to text, writing the result to the text buffer. Text may be written directly to the text buffer using AAlib::Context#puts and similar. Note that text written this way may be overwritten by AAlib::Context#render. Finally, AAlib::Context#flush writes the text buffer to the screen.

Constant Summary collapse

TYPE =

:nodoc:

'PPP' + HardwareParams::TYPE*2 + 'IIIIPPPPPPIIIIIIIPPPP'
NAMES =

:nodoc:

[:driver, :kbddriver, :mousedriver,  #:nodoc:
HardwareParams::NAMES.collect {|sym| ("hardware_params_" + sym.to_s).to_sym },
HardwareParams::NAMES.collect {|sym| ("driver_hardware_params_" + sym.to_s).to_sym },
:mulx, :muly, :imgwidth, :imgheight,
:imagebuffer, :textbuffer, :attrbuffer, :table,
:filltable, :parameters, :cursorx, :cursory, :cursorstate,
:mousex, :mousey, :buttons, :mousemode, :resizehandler,
:driverdata, :kbddriverdata, :mousedriverdata].flatten

Instance Method Summary collapse

Methods inherited from CPtr

#[], #[]=, #initialize, #inspect, new_ptr

Methods included from ArgumentChecks

included

Methods inherited from DL::PtrData

#string?

Constructor Details

This class inherits a constructor from AAlib::CPtr

Instance Method Details

#attrsObject

Returns the editable attr buffer as AAlib::CPtr (scrheight rows of scrwidth chars packed in a single string). Writes to this buffer will modify text attributes on screen after a #flush operation.



708
709
710
# File 'lib/aalib.rb', line 708

def attrs
  CPtr.new(Foreign.attrs(self)[0])
end

#autoinitkbd(release = false) ⇒ Object

Initializes the keyboard for capture of key press events. Release determines whether or not one is interested in key release events as well. Note that key releases are unavailable when using a text terminal (curses or slang drivers).



618
619
620
621
622
623
624
625
# File 'lib/aalib.rb', line 618

def autoinitkbd(release=false)
  mode = 0
  mode |= SENDRELEASE if release
  r,rs = Foreign.autoinitkbd(self, mode)
  unless r == 1
    raise Error.new("failed to initialize keyboard")
  end
end

#autoinitmouseObject



627
628
629
630
631
632
633
# File 'lib/aalib.rb', line 627

def autoinitmouse
  mode = 0
  r,rs = Foreign.autoinitmouse(self, mode)
  unless r == 1
    raise Error.new("failed to initialize mouse")
  end
end

#backconvert(x1 = 0, y1 = 0, x2 = scrwidth, y2 = scrheight) ⇒ Object

Text in the box bounded by x1, y1 and x2, y2 in screen coords is converted to an approximation of pixels on the image buffer to facilitate image based manipulation of text.

Note that a render operation must have been performed prior to calling this method; this method will not work unless the rendering tables have been calculated.

This is a hack based on the backconvert function used in BB, the AA-lib demo. This is the technique used by the pager at the end of BB that fades text in and out when paging. It may not work in different versions of AA-lib as it depends on some details not specified in the API.

See also #pixels_from_text



830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
# File 'lib/aalib.rb', line 830

def backconvert(x1=0, y1=0, x2=scrwidth, y2=scrheight)
  sw = scrwidth
  size = DL.sizeof('I'*5)
  parameters = self[:parameters]

  (y1...y2).each do |y| # "..." excludes last value; ".." includes it
    (x1...x2).each do |x|
      pos = x + y*sw
      # n a unique int representing a char + attributes (ascii values range
      # from 0-255; adding 256*a where a is 0,1,2,3,4 (no SPECIAL) makes 5
      # pixel value for each ascii char depending on the attribute) and we
      # somehow use that backwards in a lookup table
      attr = attrs[pos, 1][0]
      attr = Attr::REVERSE if attr == Attr::SPECIAL # Can't backconv SPECIAL
      n = text[pos, 1][0] + 256*attr

      p = parameters[n*size, size].unpack('I*')

      putpixel(x*2, y*2, p[1])
      putpixel(x*2+1, y*2, p[0])
      putpixel(x*2, y*2+1, p[3])
      putpixel(x*2+1, y*2+1, p[2])
    end
  end
  self
end

#closeObject

Closes the graphics context and resets the terminal if necessary. Also performs any keyboard and mouse uninitialization.



608
609
610
611
# File 'lib/aalib.rb', line 608

def close
  Foreign.close(self)
  nil
end

#copy_image_from(other) ⇒ Object

Copies the image buffer from other to the image buffer of self. Both image buffers should be the same size.



993
994
995
996
997
# File 'lib/aalib.rb', line 993

def copy_image_from(other)
  imgheight.times do |row|
    image[row*imgwidth] = other.image[other.imgwidth*row, imgwidth]
  end
end

#driver_hardware_paramsObject

Returns a HardwareParams object representing the context’s current hardware params as reported by the display driver.



645
646
647
# File 'lib/aalib.rb', line 645

def driver_hardware_params
  HardwareParams.new(self + DL.sizeof('PPP') + DL.sizeof(HardwareParams::TYPE))
end

#fastrender(x1 = 0, y1 = 0, x2 = scrwidth, y2 = scrheight) ⇒ Object

See #render. This method performs a faster render using the default rendering parameters. Screen coordinates (x1, y1) and (x2, y2) define the column and row of the top left and bottom right corners of the area to be rendered, respectively.



745
746
747
748
# File 'lib/aalib.rb', line 745

def fastrender(x1=0, y1=0, x2=scrwidth, y2=scrheight)
  Foreign.fastrender(self, x1, y1, x2, y2)
  self
end

#flushObject

Flushes the text buffer to the screen, making it visible. Note that the image buffer is transformed to ascii-art and written to the text buffer during #render.

When using the save driver, this method causes the file to be written out.



757
758
759
760
# File 'lib/aalib.rb', line 757

def flush
  Foreign.flush(self)
  self
end

#fontObject

Returns the current font.



714
715
716
# File 'lib/aalib.rb', line 714

def font
  Font.new(Foreign.font(self)[0])
end

#getevent(wait = true) ⇒ Object

Gets the next event. If wait is true, then #getevent will wait until an event occurs, otherwise it will return immediately.



927
928
929
930
931
932
# File 'lib/aalib.rb', line 927

def getevent(wait=true)
  check_kbd_init
  cwait = wait ? 1 : 0
  r,rs = Foreign.getevent(self, cwait)
  r
end

#getkey(wait = true) ⇒ Object

Gets the next key event. If wait is true, then #getevent will wait until an event occurs, otherwise it will return immediately.



937
938
939
940
941
942
# File 'lib/aalib.rb', line 937

def getkey(wait=true)
  check_kbd_init
  cwait = wait ? 1 : 0
  r,rs = Foreign.getkey(self, cwait)
  r
end

#getmouseObject

Returns an array of three values: the x,y location of the mouse in screen coords and the button mask of the mouse.



969
970
971
972
# File 'lib/aalib.rb', line 969

def getmouse
  Foreign.getmouse(self, x, y, b)
  self
end

#gotoxy(x, y) ⇒ Object

Moves the hardware cursor (if any) to position x, y in screen coords. To see the effect, #flush must be called.



947
948
949
950
# File 'lib/aalib.rb', line 947

def gotoxy(x, y)
  Foreign.gotoxy(self, x, y)
  self
end

#handle_resizeObject

Register a block to handle screen resize events. The block will be called with the Context when the screen size is changed and should perform any redrawing necessary.



916
917
918
919
920
921
922
# File 'lib/aalib.rb', line 916

def handle_resize
  handler = DL.callback('0P') do |ptr|
    resize
    yield self
  end
  Foreign.resize_handler(self, handler)
end

#hardware_paramsObject

Returns a HardwareParams object representing the context’s current requested hardware params.



638
639
640
# File 'lib/aalib.rb', line 638

def hardware_params
  HardwareParams.new(self + DL.sizeof('PPP'))
end

#hidecursorObject

Hides the hardware cursor (if any). Returns self.



954
955
956
957
# File 'lib/aalib.rb', line 954

def hidecursor
  Foreign.hidecursor(self)
  self
end

#hidemouseObject

Hides the mouse pointer (if any). Returns self.



976
977
978
979
# File 'lib/aalib.rb', line 976

def hidemouse
  Foreign.hidemouse(self)
  self
end

#imageObject

Returns the editable image buffer as AAlib::CPtr (imgheight rows of imgwidth chars packed into a single string)



692
693
694
# File 'lib/aalib.rb', line 692

def image
  CPtr.new(Foreign.image(self)[0])
end

#img2scr(imgx, imgy) ⇒ Object

Converts image buffer coordinates into text buffer coordinates.



720
721
722
# File 'lib/aalib.rb', line 720

def img2scr(imgx, imgy)
  [imgx/mulx, imgy/muly]
end

#imgheightObject

Height of the image buffer in pixels. Note pixels are non-square. Use mmwidth and mmheight to get the size of the screen in millimeters.



671
672
673
# File 'lib/aalib.rb', line 671

def imgheight
  Foreign.imgheight(self)[0]
end

#imgwidthObject

Width of the image buffer in pixels. Note pixels are non-square. Use mmwidth and mmheight to get the size of the screen in millimeters.



664
665
666
# File 'lib/aalib.rb', line 664

def imgwidth
  Foreign.imgwidth(self)[0]
end

#mmheightObject

Height of the screen in millimeters. Note this gives incorrect values on text terminals where AAlib cannot get screen size or font information.



685
686
687
# File 'lib/aalib.rb', line 685

def mmheight
  Foreign.mmheight(self)[0]
end

#mmwidthObject

Width of the screen in millimeters. Note this gives incorrect values on text terminals where AAlib cannot get screen size or font information.



678
679
680
# File 'lib/aalib.rb', line 678

def mmwidth
  Foreign.mmwidth(self)[0]
end

#mulxObject

Returns the ratio of the widths of the image and text buffers.



598
# File 'lib/aalib.rb', line 598

def mulx; end

#mulyObject

Returns the ratio of the heights of the image and text buffers.



601
# File 'lib/aalib.rb', line 601

def muly; end

#pixels(x, y, len) ⇒ Object

Returns pixels from the imagebuffer from x,y of length len in image coords and returns them as a String.



791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
# File 'lib/aalib.rb', line 791

def pixels(x, y, len)
  pos = x + y*imgwidth

  # Sanity check
  if pos > imgwidth*imgheight
    pos = imgwidth*imgheight
  elsif pos < 0
    pos = 0
  end
  if pos+len > imgwidth*imgheight
    len = imgwidth*imgheight - pos
  end

  image[pos, len]
end

#pixels_from_text(x, y, len) ⇒ Object

Returns two pixel-strings that, when drawn on the image buffer one above the other, will render to a rough approximation of the text of length len currently on the text buffer at x, y in screen coords. In other words, this converts text into pixels that may be painted and otherwise manipulated on the image buffer.

Note that a render operation must have been performed prior to calling this method; this method will not work unless the rendering tables have been calculated.

See also #backconvert



869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
# File 'lib/aalib.rb', line 869

def pixels_from_text(x, y, len)
  pos = x + y*scrwidth

  # Sanity check
  if pos > scrwidth*scrheight
    pos = scrwidth*scrheight
  elsif pos < 0
    pos = 0
  end
  if pos+len > scrwidth*scrheight
    len = scrwidth*scrheight - pos
  end

  sw = scrwidth
  size = DL.sizeof('I'*5)
  parameters = self[:parameters]
  
  bytes1 = " "*len*2
  bytes2 = " "*len*2

  len.times do |i|
    pos = i + x + y*sw
    # n is a unique int representing a char with attributes (ascii values range
    # from 0-255; adding 256*a where a is 0,1,2,3,4 (no SPECIAL) makes 5
    # pixel value for each ascii char, one for each possible attribute) and we
    # somehow use that backwards in a lookup table
    attr = attrs[pos, 1][0]
    attr = Attr::REVERSE if attr == Attr::SPECIAL # Can't backconv SPECIAL
    n = text[pos, 1][0] + 256*attr

    p = parameters[n*size, size].unpack('I*')
    
    # These indices make no sense I know, but that's how aalib has them. I
    # can't decipher the reason, but I'm sure it's a good one. 
    bytes1[i*2] = p[1]
    bytes1[i*2+1] = p[0]
    bytes2[i*2] = p[3]
    bytes2[i*2+1] = p[2]
  end
 
  [bytes1, bytes2]
end

#putpixel(x, y, color) ⇒ Object

Draw a pixel at x,y in image coords in the desired color (0-255).



764
765
766
767
# File 'lib/aalib.rb', line 764

def putpixel(x, y, color)
  Foreign.putpixel(self, x, y, color)
  self
end

#putpixels(x, y, str) ⇒ Object

Draw starting at x,y in image coords using the pixels from str.



771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
# File 'lib/aalib.rb', line 771

def putpixels(x, y, str)
  pos = x + y*imgwidth
 
  # Sanity check
  if pos > imgwidth*imgheight
    pos = imgwidth*imgheight
  elsif pos < 0
    pos = 0
  end
  if pos+str.length > imgwidth*imgheight
    str = str[0, imgwidth*imgheight - pos]
  end

  image[pos] = str
  self
end

#puts(x, y, attr, str) ⇒ Object

Writes string str at x,y in screen coords with attribute attr, a AAlib::Attr.



810
811
812
813
# File 'lib/aalib.rb', line 810

def puts(x, y, attr, str)
  Foreign.puts(self, x, y, attr, str)
  self
end

#render(render_params, x1 = 0, y1 = 0, x2 = scrwidth, y2 = scrheight) ⇒ Object

Converts the image buffer to ASCII on the text buffer. Renderparams should be a RenderParams specifying the parameters. Screen coordinates (x1, y1) and (x2, y2) define the column and row of the top left and bottom right corners of the area to be rendered, respectively.

Note that #flush must be called to flush to the screen.

The first call may take some time as the rendering tables are produced.



733
734
735
736
737
738
# File 'lib/aalib.rb', line 733

def render(render_params, x1=0, y1=0, x2=scrwidth, y2=scrheight)
  AAlib.check_render_params(render_params)

  Foreign.render(self, render_params, x1, y1, x2, y2)
  self
end

#resizeObject

Resizes the image and text buffers and performs any other necessary updates after a resize event. This is automaically called prior to running any resize handler.



985
986
987
988
# File 'lib/aalib.rb', line 985

def resize
  Foreign.resize(self)
  self
end

#scrheightObject

Height of the screen and text buffer in characters.



657
658
659
# File 'lib/aalib.rb', line 657

def scrheight
  Foreign.scrheight(self)[0]
end

#scrwidthObject

Width of the screen and text buffer in characters.



651
652
653
# File 'lib/aalib.rb', line 651

def scrwidth
  Foreign.scrwidth(self)[0]
end

#showcursorObject

Shoes the hardware cursor (if any). Returns self.



961
962
963
964
# File 'lib/aalib.rb', line 961

def showcursor
  Foreign.showcursor(self)
  self
end

#textObject

Returns the editable text buffer as AAlib::CPtr (scrheight rows of scrwidth characters packed in single string). Writes to this buffer will appear on screen after a #flush operation.



700
701
702
# File 'lib/aalib.rb', line 700

def text
  CPtr.new(Foreign.text(self)[0])
end