with ada.unchecked_Deallocation; package body openGL.Glyph.Container is --------- --- Forge -- function to_glyph_Container (parent_Face : in freetype.Face.view) return openGL.glyph.Container.item is Self : openGL.glyph.Container.item; begin Self.Face := parent_Face; Self.Err := 0; Self.charMap := new freetype.charMap.Item' (freetype.charMap.to_charMap (Self.Face)); return Self; end to_glyph_Container; procedure destruct (Self : in out Item) is use Glyph_Vectors; procedure deallocate is new ada.unchecked_Deallocation (openGL.Glyph.item'Class, Glyph_view); procedure deallocate is new ada.unchecked_Deallocation (freetype.charMap.item'Class, charMap_view); Cursor : Glyph_Vectors.Cursor := Self.Glyphs.First; the_Glyph : Glyph_view; begin while has_Element (Cursor) loop the_Glyph := Element (Cursor); deallocate (the_Glyph); next (Cursor); end loop; Self.Glyphs .clear; Self.charMap.destruct; deallocate (Self.charMap); end destruct; -------------- -- Attributes -- function CharMap (Self : access Item; Encoding : in freeType_c.FT_Encoding) return Boolean is Result : constant Boolean := Self.charMap.CharMap (Encoding); begin Self.Err := Self.charMap.Error; return Result; end CharMap; function FontIndex (Self : in Item; Character : in freetype.charMap.characterCode) return Natural is begin return Natural (Self.charMap.FontIndex (Character)); end FontIndex; procedure add (Self : in out Item; Glyph : in Glyph_view; Character : in freetype.charMap.characterCode) is begin Self.glyphs.append (Glyph); Self.charMap.insertIndex (Character, Self.Glyphs.Length); end add; function Glyph (Self : in Item; Character : in freetype.charMap.characterCode) return Glyph_view is use type freetype.charMap.glyphIndex; Index : constant freetype.charMap.glyphIndex := Self.charMap.GlyphListIndex (Character); begin if Index = -1 then return null; else return Self.Glyphs.Element (Integer (Index)); end if; end Glyph; function BBox (Self : in Item; Character : in freetype.charMap.characterCode) return Bounds is begin return Self.Glyph (Character).BBox; end BBox; function Advance (Self : in Item; Character : in freetype.charMap.characterCode; nextCharacterCode : in freetype.charMap.characterCode) return Real is Left : constant freetype.charMap.glyphIndex := Self.charMap.FontIndex (Character); Right : constant freetype.charMap.glyphIndex := Self.charMap.FontIndex (nextCharacterCode); begin return Real (Self.Face.KernAdvance (Integer (Left), Integer (Right)) (1) + Float (Self.Glyph (Character).Advance)); end Advance; function Error (Self : in Item) return freetype_c.FT_Error is begin return Self.Err; end Error; -------------- -- Operations -- function render (Self : access Item; Character : in freetype.charMap.characterCode; nextCharacterCode : in freetype.charMap.characterCode; penPosition : in Vector_3; renderMode : in Integer) return Vector_3 is use type freetype_c.FT_Error, freetype.charMap.glyphIndex; Left : constant freetype.charMap.glyphIndex := Self.charMap.FontIndex (Character) - 0; Right : constant freetype.charMap.glyphIndex := Self.charMap.FontIndex (nextCharacterCode) - 0; ft_kernAdvance : constant freetype.Vector_3 := Self.Face.KernAdvance (Integer (Left), Integer (Right)); kernAdvance : Vector_3 := [ft_kernAdvance (1), ft_kernAdvance (2), ft_kernAdvance (3)]; Index : freetype.charMap.glyphIndex; begin if Self.Face.Error = 0 then Index := Self.charMap.GlyphListIndex (Character); kernAdvance := kernAdvance + Self.Glyphs.Element (Integer (Index)).Render (penPosition, renderMode); else raise openGL.Error with "Unable to render character '" & Character'Image & "'"; end if; return kernAdvance; end Render; end openGL.Glyph.Container;