Logo Search packages:      
Sourcecode: pango-graphite version File versions  Download package

FreetypeFont.cpp

/*--------------------------------------------------------------------*//*:Ignore this sentence.
Copyright (C) 1999, 2001, 2005 SIL International. All rights reserved.

Distributable under the terms of either the Common Public License or the
GNU Lesser General Public License, as specified in the LICENSING.txt file.

File: XftFont.cpp
Responsibility: Keith Stribley
Last reviewed: Not yet.

Description:
    A Font is an object that represents a font-family + bold + italic setting, that contains
  Graphite tables.
----------------------------------------------------------------------------------------------*/
#include <graphite/GrDebug.h>
#include <glib.h>

#include "FreetypeFont.h"

#include  FT_TRUETYPE_TABLES_H

// TBD do this properly
#define fix26_6(x) (x >> 6) + (x & 32 ? (x > 0 ? 1 : 0) : (x < 0 ? -1 : 0))
#define float26_6(x) (x / 32.)

namespace gr
{

00029 FreetypeFont::FreetypeFont(FT_Face face, int dpiX, int dpiY, 
      FT_Int32 load_flags)
  : Font(),
  m_ftFace(face),
  m_ft_load_flags(load_flags),
  m_clrFore(kclrBlack),
  m_clrBack(kclrTransparent),
  m_ascent(0),
  m_descent(0),
  m_emSquare(0),
  m_dpiX(dpiX),
  m_dpiY(dpiY)
{
  if (face)
  {
    setFace(face);
  }
}


00049 FreetypeFont::~FreetypeFont()
{
  // Make sure we delete all the buffers we've accumulated over the lifetime
  //  of this font.
  for (TableMap::iterator ti = m_tables.begin(); ti != m_tables.end(); ++ti)
    delete [] ti->second.first;
}
  

void FreetypeFont::UniqueCacheInfo(std::wstring & name, bool & bold, bool & italic)
{
      name   = m_faceName;
      bold   = m_fBold;
      italic = m_fItalic;
}


00066 Font * FreetypeFont::copyThis()
{
  return new FreetypeFont(*this);
}


00072 FreetypeFont::FreetypeFont(const FreetypeFont & font)
: Font(font),
  m_ftFace(font.m_ftFace),
  m_clrFore(font.m_clrFore),  // colors are not used
  m_clrBack(font.m_clrBack),  // colors are not used
  m_fBold(font.m_fBold),
  m_fItalic(font.m_fItalic),
  m_pixHeight(font.m_pixHeight),  
  m_ascent(font.m_ascent),
  m_descent(font.m_descent),
  m_emSquare(font.m_emSquare),
  m_dpiX(font.m_dpiX),
  m_dpiY(font.m_dpiY),
  m_faceName(font.m_faceName)
{
}

  //virtual FontErrorCode isValidForGraphite(int * pnVersion = NULL, int * pnSubVersion = NULL);

/*----------------------------------------------------------------------------------------------
  Read a table from the font.
----------------------------------------------------------------------------------------------*/  
const void * 
00095 FreetypeFont::getTable(fontTableId32 tableID, size_t * pcbSize)
{
  *pcbSize = 0;

  TableMap::const_iterator table_itr = m_tables.find(tableID);
  if (table_itr != m_tables.end())
  {
    // We have already loaded the table so use it.
    *pcbSize = table_itr->second.second;
    return table_itr->second.first;
  }
  else
  {
   // First find out how large the table is.
    FT_ULong tableBufferSz = 0;
    FT_Load_Sfnt_Table(m_ftFace, tableID, 0, 0, &tableBufferSz);
    if (tableBufferSz == 0)
      // We couldn't load the table for some reason so return 0;
      return 0;
    
    // Allocate a buffer and load the table.
    FT_Byte *pTable = new gr::byte[tableBufferSz];
    FT_Load_Sfnt_Table(m_ftFace, tableID, 0, pTable, 0);
    
    // record the table buffer and size into a record.  Note that we use the
    //  table ID as passed to this method, not the one passed to
    //  FT_Load_Sfnt_Table.
    m_tables[tableID] = std::make_pair(pTable, tableBufferSz);
    *pcbSize = tableBufferSz;
    return pTable;
  }
}


00129 void FreetypeFont::getFontMetrics(float * pAscent, float * pDescent,
    float * pEmSquare)
{
  if (pAscent) *pAscent = m_ascent; 
  if (pDescent) *pDescent = m_descent;
  if (pEmSquare) *pEmSquare = m_emSquare; 
}


00138 void FreetypeFont::getGlyphPoint(gid16 gid, unsigned int pointNum, gr::Point & xyReturn)
{
  // this isn't used very often, so don't bother caching
   ;

   FT_Load_Glyph(m_ftFace, gid, 0);
   const FT_Outline &outline = m_ftFace->glyph->outline;
   xyReturn.x = fix26_6(outline.points[pointNum].x);
   xyReturn.y = fix26_6(outline.points[pointNum].y);
}


00150 void FreetypeFont::getGlyphMetrics(gid16 glyphID, gr::Rect & boundingBox, gr::Point & advances)
{
  // used the cached metrics if available, otherwise load the glyph
  GlyphMetricMap::const_iterator gm_itr = m_glyphMetrics.find(glyphID);
  if (gm_itr != m_glyphMetrics.end())
  {
    // We've cahced the results from last time.
    boundingBox = gm_itr->second.first;
    advances    = gm_itr->second.second;
  }
  else
  {
    // We need to look up the glyph.
    FT_Load_Glyph(m_ftFace, glyphID, m_ft_load_flags);
    const FT_Glyph_Metrics &gm = m_ftFace->glyph->metrics;

    // Fill out the bounding box an advances.
    boundingBox.top = boundingBox.bottom = fix26_6(gm.horiBearingY);;
    boundingBox.bottom -= fix26_6(gm.height);
    boundingBox.left = boundingBox.right = fix26_6(gm.horiBearingX);
    boundingBox.right += fix26_6(gm.width);
    advances.x = fix26_6(gm.horiAdvance);
    advances.y = 0;
    
    // Now add an entry to our metrics map.
    m_glyphMetrics[glyphID] = std::make_pair(boundingBox, advances);
  }
}


00180 bool FreetypeFont::FontHasGraphiteTables(FT_Face face)
{
  assert(face);

  FT_ULong len = 0;
  // need Freetype 2.1.4 and up
  FT_Error error = FT_Load_Sfnt_Table(face, FT_MAKE_TAG('S','i','l','f'), 0, 0, &len);

  return (error == 0) && (len > 0);
}


00192 float FreetypeFont::ascent()
{
  float pixAscent;
  getFontMetrics(&pixAscent);
  return pixAscent;
}


00200 float FreetypeFont::descent()
{
  float pixDescent;
  getFontMetrics(NULL, &pixDescent);
  return pixDescent;
}


00208 float FreetypeFont::height()
{
  float pixAscent;
  float pixDescent;
  getFontMetrics(&pixAscent, &pixDescent);
  return (pixAscent + pixDescent);
}


00217 bool FreetypeFont::bold()
{
  return m_fBold;
}

00222 bool FreetypeFont::setBold(bool fbold)
{
  m_fBold = fbold;
  return m_fBold;
}

00228 bool FreetypeFont::italic()
{
  return m_fItalic;
}

00233 bool FreetypeFont::setItalic(bool fitalic)
{
  m_fItalic = fitalic;
  return m_fItalic;
}


00240 unsigned int FreetypeFont::getDPIx() 
{
  return m_dpiX;
}


00246 unsigned int FreetypeFont::getDPIy()
{
  return m_dpiY;
}

00251 FT_Face FreetypeFont::getFace()
{
  return m_ftFace;
}

00256 FT_Face FreetypeFont::setFace(FT_Face face)
{
  m_ftFace = face;

  if (face)
  {
    m_fBold   = (face->style_flags & FT_STYLE_FLAG_BOLD);
    m_fItalic = (face->style_flags & FT_STYLE_FLAG_ITALIC);
  
  m_faceName.resize(strlen(face->family_name));

  std::copy(face->family_name, 
      face->family_name + strlen(face->family_name),
      m_faceName.begin());

  assert(face->size);
  m_pixHeight = float26_6(face->size->metrics.height);
  m_emSquare = face->size->metrics.y_ppem;
  m_ascent = float26_6(face->size->metrics.ascender);
  m_descent = float26_6(face->size->metrics.descender);
  if (m_descent < 0) m_descent = -m_descent;

  assert(m_pixHeight > 0);
  }

  return m_ftFace;
}

} // namespace gr


Generated by  Doxygen 1.6.0   Back to index