Fresco/Berlin/modules/Fonts Font.cc,1.1,1.2 Glyph.cc,1.1,1.2 Glyph.hh,1.1,1.2

Nick Lewycky <[email protected]>
Newsgroups gmane.comp.video.fresco.cvs
Message-ID <[email protected]>
Update of /cvs/fresco/Fresco/Berlin/modules/Fonts
In directory purcel:/tmp/cvs-serv16493/Berlin/modules/Fonts

Modified Files:
	Font.cc Glyph.cc Glyph.hh 
Log Message:
Add some glyph handling with help from Freetype.


Index: Font.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/modules/Fonts/Font.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Font.cc	8 Jan 2003 01:42:31 -0000	1.1
+++ Font.cc	12 Jan 2003 02:54:09 -0000	1.2
@@ -31,21 +31,102 @@
            FT_Library library)
   : my_ftlib(library), my_size(size), my_xdpi(xdpi), my_ydpi(ydpi)
 {
-    FT_New_Face(my_ftlib, filename.c_str(), 0, &my_face);
-    FT_Set_Char_Size(my_face, 0, my_size*64, xdpi, ydpi);
+  FT_New_Face(my_ftlib, filename.c_str(), 0, &my_face);
+  FT_Set_Char_Size(my_face, 0, my_size*64, xdpi, ydpi);
 }
 
-} // namespace
-} // namespace
-
 Font::~Font() {}
 
 Glyph_ptr Font::glyph_char(Unichar c)
 {
-    return new Glyph(my_face, FT_Get_Char_Index(my_face, (FT_ULong)uc));
+  return new Glyph(my_face, FT_Get_Char_Index(my_face, (FT_ULong)uc));
 }
 
-Glyph::Glyph(FT_Face face, Foo char_index)
+bool Font::has_char(Unichar c)
 {
-    FT_Load_Glyph(my_face, char_index, FT_LOAD_DEFAULT);
+  return true;
 }
+
+bool Font::can_display(Unichar begin, Unichar end)
+{
+  return true;
+}
+
+Unistring Font::encoding()
+{
+  //
+}
+
+Unistring Font::font_family()
+{
+  return new Unistring(Unicode::to_CORBA(Babylon::String(my_face->family_name)));
+}
+
+Unistring Font::font_style()
+{
+  return new Unistring(Unicode::to_CORBA(Babylon::String(my_face->style_name)));
+}
+
+Unistring Font::fullname()
+{
+    // ??
+}
+
+void Font::font_metrics(FontMetrics &fm)
+{
+  fm.ascent = my_face->ascender;
+  fm.descent = my_face->descender;
+  fm.baseline = my_face->height;
+  fm.underline_offset = my_face->underline_position;
+  fm.underline_thickness = my_face->underline_width;
+}
+
+Coord height() const
+{
+  return my_size;
+}
+
+float angle()
+{
+  float angle = 0.;
+
+  void *htable = FT_Get_Sfnt_Table(my_face, ft_sfnt_hhea);
+  if (htable) {
+    TT_HoriHeader *header = *htable;
+    if (header->caret_Slope_Run != 0)
+      angle = header->caret_Slope_Rise / header->caret_Slope_Run;
+  }
+
+  void *vtable = FT_Get_Sfnt_Table(my_face, ft_sfnt_vhea);
+  if (vtable) {
+    TT_VertHeader *header = *vtable;
+    if (header->caret_Slope_Run != 0)
+      angle = header->caret_Slope_Rise / header->caret_Slope_Run;
+  }
+
+  return angle;
+}
+
+float caret_offset()
+{
+  float offset = 0.;
+
+  void *htable = FT_Get_Sfnt_Table(my_face, ft_sfnt_hhea);
+  if (htable) {
+    TT_HoriHeader *header = *htable;
+    if (header->caret_Offset != 0)
+      offset = header->caret_Offset;
+  }
+
+  void *vtable = FT_Get_Sfnt_Table(my_face, ft_sfnt_vhea);
+  if (vtable) {
+    TT_VertHeader *header = *vtable;
+    if (header->caret_Slope_Run != 0)
+      offset = header->caret_Offset;
+  }
+
+  return offset;
+}
+
+} // namespace
+} // namespace

Index: Glyph.cc
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/modules/Fonts/Glyph.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Glyph.cc	8 Jan 2003 01:42:31 -0000	1.1
+++ Glyph.cc	12 Jan 2003 02:54:09 -0000	1.2
@@ -20,27 +20,119 @@
  * MA 02139, USA.
  */
 
-#include <Berlin/Raster.hh>
+#include <Fresco/Raster.hh>
+#include <Berlin/RasterImpl.hh>
 #include "Glyph.hh"
 
-Glyph::Glyph(FT_Face face, Foo char_index)
+Glyph::Glyph(FT_Face face, FT_ULong char_index)
     : my_face(face)
 {
-    FT_Load_Glyph(my_face, char_index, FT_LOAD_DEFAULT);
+  FT_Load_Glyph(my_face, char_index, FT_LOAD_DEFAULT);
 }
 
 Raster_ptr Glyph::bitmap()
 {
+  RasterImpl *raster = new RasterImpl();
+  activate(raster);
+
+  FT_Set_Transform(my_face, &my_tr, 0);
+
+  FT_Glyph glyph;
+  FT_Get_Glyph(my_face->glyph, &glyph);
+  FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, &origin, 1);
+  FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)glyph;
+
+  Fresco::Raster::Data pixels;
+
+  switch (glyph_bitmap->bitmap.pixel_mode)
+    {
+    case FT_PIXEL_MODE_NONE:
+      // should never happen
+      std::cout << "WTF;FT_PIXEL_MODE_NONE" << std::endl;
+      break;
+    case FT_PIXEL_MODE_MONO: // MSB 1 bpp
+      internal_format = GL_ALPHA;
+      format = GL_ALPHA;
+      type = GL_UNSIGNED_BYTE;
+      for (int i = 0; i < height; i++)
+	for (int j = 0; j < width; j++)
+	  pixels[i*w + j] = (buffer[i*(width/8)+(j/8)] &
+			     (0x80 >> j%8)) ? 0xFF : 0;
+      break;
+    case FT_PIXEL_MODE_GRAY: // 8 bpp count of grey levels in num_bytes
+      internal_format = GL_ALPHA;
+      format = GL_ALPHA;
+      type = GL_UNSIGNED_BYTE;
+      for (int i = 0; i < height; i++)
+	for (int j = 0; j < width; j++)
+	  pixels[i*w+j] = buffer[i*width+j];
+      break;
+    case FT_PIXEL_MODE_GRAY2: // 2bpp (no known fonts)
+      std::cout << "FontKit NYI: FT_PIXEL_MODE_GRAY2" << std::endl;
+      break;
+    case FT_PIXEL_MODE_GRAY4: // 4bpp (no known fonts)
+      std::cout << "FontKit NYI: FT_PIXEL_MODE_GRAY4" << std::endl;
+      break;
+    case FT_PIXEL_MODE_LCD: // 8bpp RGB or BGR, width=3*glyph_width
+      std::cout << "FontKit NYI: FT_PIXEL_MODE_LCD" << std::endl;
+      break;
+    case FT_PIXEL_MODE_LCD_V: // 8bpp RGB or BGR, height=3*glyph_rows
+      std::cout << "FontKit NYI: FT_PIXEL_MODE_LCD_V" << std::endl;
+      break;
+    default:
+      std::cout << "FontKit unknown type : "
+		<< glyph_bitmap->bitmap.pixel_mode << std::endl;
+      break;
+    }
+  FT_Set_Transform(my_face, 0, 0);
+  FT_Done_Glyph(glyph);
+
+  activate(pixels);
+  raster->store_pixels(pixels);
+
+  return raster;
 }
 
 FontShape *Glyph::decompose()
 {
+  FT_Set_Transform(that->my_face, &my_tr, 0);
+  // use FT_Outline_Decompose
+  FT_Set_Transform(that->my_face, 0, 0);
 }
 
 void Glyph::char_info(GlyphMetrics *gm)
 {
+  double scale = 1.;
+  gm.size.x = static_cast<CORBA::Long>(my_face->glyph->metrics.width / scale);
+  gm.size.y = static_cast<CORBA::Long>(my_face->glyph->metrics.height / scale);
+  gm.hori_bearing.x = static_cast<CORBA::Long>(my_face->glyph->metrics.horiBearingX / scale);
+  gm.hori_bearing.y = static_cast<CORBA::Long>(my_face->glyph->metrics.horiBearingY /scale);
+  gm.hori_advance =  static_cast<CORBA::Long>(my_face->glyph->metrics.horiAdvance / scale);
+  gm.vert_bearing.x = static_cast<CORBA::Long>(my_face->glyph->metrics.vertBearingX / scale);
+  gm.vert_bearing.y = static_cast<CORBA::Long>(my_face->glyph->metrics.vertBearingY / scale);
+  gm.vert_advance = static_cast<CORBA::Long>(my_face->glyph->metrics.vertAdvance / scale);
+
+  gm.italic_correction = 0.;
+
+  void *table = FT_Get_Sfnt_Table(my_face, ft_sfnt_hhea);
+  if (table) {
+    TT_HoriHeader *header = *table;
+    gm.italic_correction = header->caret_Offset / 64.; // XXX MAYBE WRONG
+  }
 }
 
-void transform(Fresco::Transform_var tr)
+void Glyph::transform(Fresco::Transform_var tr)
 {
+  Fresco::Vertex  o = {0, 0, 0};
+  Fresco::Vertex e1 = {1, 0, 0};
+  Fresco::Vertex e2 = {0, 1, 0};
+
+  tr->transform_vertex(o);
+  tr->transform_vertex(e1);
+  tr->transform_vertex(e2);
+
+  my_tr.xx = (e1.x-o.x)*0x10000;
+  my_tr.xy = (e1.y-o.y)*0x10000;
+  my_tr.yx = (e2.x-o.x)*0x10000;
+  my_tr.yy = (e2.y-o.y)*0x10000;
 }

Index: Glyph.hh
===================================================================
RCS file: /cvs/fresco/Fresco/Berlin/modules/Fonts/Glyph.hh,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- Glyph.hh	8 Jan 2003 01:42:31 -0000	1.1
+++ Glyph.hh	12 Jan 2003 02:54:09 -0000	1.2
@@ -43,6 +43,7 @@
     void transformation(Fresco::Transform_var);
 private:
     FT_Face my_face;
+    FT_Matrix my_tr;
 };
 
 #endif // header guard
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.