Commit 1321585ef3c73386bfe9f26f93c3591647941011

Thomas de Grivel 2022-02-13T08:49:52

wip font

diff --git a/exterm.png b/exterm.png
new file mode 100644
index 0000000..f0f449c
Binary files /dev/null and b/exterm.png differ
diff --git a/lib/exterm.ex b/lib/exterm.ex
index e24d589..0968767 100644
--- a/lib/exterm.ex
+++ b/lib/exterm.ex
@@ -24,8 +24,8 @@ defmodule Exterm do
     IO.inspect({&Exterm.init/1, config})
     wx = :wx.new(config)
     frame = :wxFrame.new(wx, :wx_const.wx_id_any, @title, [{:size, @size}])
-    :wxWindow.connect(frame, :close_window)
-    :wxFrame.show(frame)
+    :ok = :wxWindow.connect(frame, :close_window)
+    true = :wxFrame.show(frame)
     Exterm.Font.init()
     font = Exterm.Font.load()
     opts = [{:size, @size}]
@@ -36,14 +36,18 @@ defmodule Exterm do
                                 :wx_const.wx_gl_min_blue, 8,
                                 :wx_const.wx_gl_depth_size, 24, 0]}]
     canvas = :wxGLCanvas.new(frame, opts ++ gl_attrib)
-    :wxGLCanvas.connect(canvas, :size)
+    :ok = :wxGLCanvas.connect(canvas, :size)
+    :ok = :wxGLCanvas.connect(canvas, :char)
     :wxWindow.reparent(canvas, frame)
     context = :wxGLContext.new(canvas)
     :wxGLCanvas.setCurrent(canvas, context)
     setup_gl(canvas)
     state = %{canvas: canvas,
               font: font,
-              lines: ['$ hello world !']}
+              lines: ['$>_hello_world_!  ',
+                      'plop',
+                      'hop',
+                      'toto toto']}
     :wx.batch(fn -> render(state) end)
     {frame, state}
   end
@@ -80,7 +84,8 @@ defmodule Exterm do
     {:stop, :normal, state}
   end
 
-  def handle_event({:wx, _, _, _, {:wxSize, :size, {width, height}, _}}, state) do
+  def handle_event(x = {:wx, _, _, _, {:wxSize, :size, {width, height}, _}}, state) do
+    IO.inspect(x)
     if width != 0 and height != 0 do
       resize_gl_scene(width, height)
       :wx.batch(fn -> render(state) end)
@@ -89,6 +94,19 @@ defmodule Exterm do
     {:noreply, state}
   end
 
+  def handle_event({:wx, _, _, _, {:wxKey, :char, _, _, code, _, _, _, _, _, _, _}}, state) do
+    IO.inspect([code])
+    lines = if [code] == '\r' do
+      [[] | state.lines]
+    else
+      first_line = hd(state.lines) ++ [code]
+      [first_line | tl(state.lines)]
+    end
+    state = %{state | lines: lines}
+    :wx.batch(fn -> render(state) end)
+    {:noreply, state}
+  end
+
   def handle_event(data, state) do
     IO.inspect({:handle_event, data, state})
     {:noreply, state}
@@ -112,10 +130,12 @@ defmodule Exterm do
 
   defp resize_gl_scene(width, height) do
     IO.inspect({:resize_gl_scene, width, height})
+    width = width * 2
+    height = height * 2
     :gl.viewport(0, 0, width, height)
     :gl.matrixMode(:gl_const.gl_projection)
     :gl.loadIdentity()
-    :gl.ortho(0.0, width + 0.0, height + 0.0, 0.0, -1.0, 1.0)
+    :gl.ortho(0.0, width + 0.0, 0.0, height + 0.0, -1.0, 1.0)
     :gl.matrixMode(:gl_const.gl_modelview)
     :gl.loadIdentity()
     :ok
@@ -125,12 +145,18 @@ defmodule Exterm do
     IO.inspect(:draw)
     :gl.clear(:gl_const.gl_color_buffer_bit)
     :gl.loadIdentity()
-    Enum.each(lines, fn line ->
-      Enum.each(line, fn c when is_integer(c) ->
-        Exterm.Font.render_glyph(font.regular, c)
+    lines
+    |> Enum.with_index()
+    |> Enum.each(fn {line, i} ->
+      :gl.pushMatrix()
+      line
+      |> Enum.map(fn c when is_integer(c) ->
+        Exterm.Font.load_glyph(font.regular, c)
       end)
+      |> :gl.callLists()
+      :gl.popMatrix()
+      :gl.translatef(0.0, 50.0, 0.0)
     end)
-    :gl.end()
   end
 
   defp render(%{canvas: canvas, font: font, lines: lines} = _state) do
diff --git a/lib/exterm/font.ex b/lib/exterm/font.ex
index 8d9420b..314dc1f 100644
--- a/lib/exterm/font.ex
+++ b/lib/exterm/font.ex
@@ -27,13 +27,13 @@ defmodule Exterm.Font do
 
   def load_glyph(font, codepoint) do
     id = glyph_index(font, codepoint)
-    if :gl.isList(id) do
-      :ok
+    if :gl.isList(id) == :gl_const.gl_true do
+      id
     else
-      :ok = :gl.newList(id, :gl_const.gl_compile_and_execute)
+      :ok = :gl.newList(id, :gl_const.gl_compile)
       :ok = render_glyph(font, codepoint)
       :ok = :gl.endList()
-      :ok
+      id
     end
   end
 
@@ -55,20 +55,19 @@ defmodule Exterm.Font do
     ttf = ttf(font.family)
     if glyph = TTF.glyph(ttf, codepoint) do
       :gl.pushMatrix()
-      :gl.translatef(0.0, 200.0, 0.0)
-      :gl.scalef(0.1, -0.1, 0.1)
+      :gl.translatef(0.0, 90.0, 0.0)
+      :gl.scalef(0.02, 0.02, 0.02)
       Enum.each(glyph.contours, fn contour ->
         :gl.begin(:gl_const.gl_line_loop)
         :gl.color3f(0.0, 0.0, 0.0)
         Enum.each(TTF.Glyph.contour_segments(contour), fn control_point ->
-          IO.inspect(control_point)
           :gl.vertex2f(control_point.a.x * 1.0, control_point.a.y * 1.0)
           :gl.vertex2f(control_point.c.x * 1.0, control_point.c.y * 1.0)
         end)
         :gl.end()
       end)
       :gl.popMatrix()
-      :gl.translatef(100.0, 0.0, 0.0)
+      :gl.translatef(20.0, 0.0, 0.0)
     end
   end
 
diff --git a/lib/ttf.ex b/lib/ttf.ex
index 3ce2185..16185be 100644
--- a/lib/ttf.ex
+++ b/lib/ttf.ex
@@ -29,7 +29,7 @@ defmodule TTF do
     |> parse_head()
     |> parse_loca()
     |> parse_glyphs()
-    |> IO.inspect()
+    #|> IO.inspect()
   end
 
   def parse_header(ttf = %__MODULE__{data: <<magic::unsigned-big-32, rest::binary>>, magic: nil}) do
@@ -183,16 +183,17 @@ defmodule TTF do
     nil
   end
   def codepoint_to_font_index(font, codepoint, i, _segment_count) do
-    start_code = elem(hd(font.cmap).start_codes, i)
-    end_code = elem(hd(font.cmap).end_codes, i)
+    cmap = hd(font.cmap)
+    start_code = elem(cmap.start_codes, i)
+    end_code = elem(cmap.end_codes, i)
     if start_code <= codepoint && codepoint <= end_code do
-      id_range_offset = elem(hd(font.cmap).id_range_offsets, i)
-      id_delta = elem(hd(font.cmap).id_deltas, i)
+      id_range_offset = elem(cmap.id_range_offsets, i)
+      id_delta = elem(cmap.id_deltas, i)
       if (id_range_offset == 0) do
         band(0xFFFF, (codepoint + id_delta))
       else
-        glyph_index_offset = i + bsr(id_range_offset, 1) + codepoint - start_code - hd(font.cmap).segment_count
-        glyph_index = elem(hd(font.cmap).glyph_indexes, glyph_index_offset)
+        glyph_index_offset = i + bsr(id_range_offset, 1) + codepoint - start_code - cmap.segment_count
+        glyph_index = elem(cmap.glyph_indexes, glyph_index_offset)
         band(0xFFFF, (glyph_index + id_delta))
       end
     else
@@ -217,9 +218,9 @@ defmodule TTF do
     glyf = table(ttf, "glyf")
     location = glyph_location(ttf, id)
     <<_::binary-size(location), contour_count::signed-big-16, xmin::signed-big-16, ymin::signed-big-16, xmax::signed-big-16, ymax::signed-big-16, rest::binary>> = glyf
-    IO.inspect([contour_count: contour_count, id: id, location: location])
+    #IO.inspect([contour_count: contour_count, id: id, location: location])
     glyph = %Glyph{bounding_box: {xmin, ymin, xmax, ymax}, codepoint: codepoint, contour_count: contour_count, ttf: ttf}
-    IO.inspect(glyph)
+    #IO.inspect(glyph)
     if (contour_count == -1) do
       glyph |> Glyph.CompoundContours.parse(rest)
     else
diff --git a/src/gl_const.erl b/src/gl_const.erl
index 4415535..130d093 100644
--- a/src/gl_const.erl
+++ b/src/gl_const.erl
@@ -18,3 +18,4 @@ gl_projection() -> ?GL_PROJECTION.
 gl_quad_strip() -> ?GL_QUAD_STRIP.
 gl_smooth() -> ?GL_SMOOTH.
 gl_triangles() -> ?GL_TRIANGLES.
+gl_true() -> ?GL_TRUE.