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

graphitecache.cpp

/* Pango
 * graphitecache.cpp: Graphite caching for pango
 *
 * Copyright (C) 2005-2006 SIL International
 * Author: Daniel Glassey <wdg@debian.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.      See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "graphitecache.h"

static GList *segment_cache = NULL;
static int segment_cache_length = 0;

static GList *glyphstring_cache = NULL;
static int glyphstring_cache_length = 0;

static GList *logattr_cache = NULL;
static int logattr_cache_length = 0;

namespace gr
{

class SegmentCache
{
private:
    PangoTextSrc *m_text;
    RangeSegment *m_grseg;
    PangoGrFont  *m_font;
    bool m_temp;
      
public:
      SegmentCache(PangoTextSrc *text, RangeSegment *pgrseg, PangoGrFont *pfont, bool temp) :
      m_text(text), m_grseg(pgrseg), m_font(pfont), m_temp(temp) {};
      ~SegmentCache()
      {
            if (!m_temp) {
            delete m_grseg;
            delete m_font;
            delete m_text;
            }
      }
      
    RangeSegment*       segment()   {return m_grseg;};
    const char*   text()            {return m_text->getText();};
    int               length()      {return m_text->getLength();}
    PangoGrFont*        font()            {return m_font;};
    PangoTextSrc*       textsource()      {return m_text;};
};

class GlyphStringCache
{
private:
    PangoTextSrc *m_text;
    PangoGlyphString *m_glyphs;
    PangoGrFont  *m_font;
    bool m_temp;
      
public:
      GlyphStringCache(PangoTextSrc *text, PangoGlyphString *pglyphs, PangoGrFont *pfont, bool temp) :
      m_text(text), m_glyphs(pglyphs), m_font(pfont), m_temp(temp) {};
      ~GlyphStringCache()
      {
            if (!m_temp) {
            pango_glyph_string_free(m_glyphs);
            delete m_font;
            delete m_text;
            }
      }
      
    PangoGlyphString*   glyphstring()     {return m_glyphs;};
    const char*   text()            {return m_text->getText();};
    int           length()    {return m_text->getLength();}
    PangoGrFont*        font()            {return m_font;};
    PangoTextSrc*       textsource()      {return m_text;};
};

class LogAttrCache
{
private:
    PangoTextSrc *m_text;
    PangoLogAttr *m_attrs;
    PangoGrFont  *m_font;
    int m_len;
      
public:
      LogAttrCache(PangoTextSrc *text, PangoLogAttr *pattrs, PangoGrFont *pfont, int attr_len) :
      m_text(text), m_attrs(pattrs), m_font(pfont), m_len(attr_len) {};
      ~LogAttrCache()
      {
            if (m_len) {
            g_free(m_attrs);
            delete m_font;
            delete m_text;
            }
      }
      
    PangoLogAttr*       logattr()   {return m_attrs;};
    const char*  text()    {return (m_text) ? m_text->getText() : NULL;};
    int    length()  {return (m_text) ? m_text->getLength() : 0 ;}
    PangoGrFont*        font()            {return m_font;};
    PangoTextSrc*       textsource()      {return m_text;};
    int         attr_len()      {return m_len;};
};


}; //namespace gr

using gr::RangeSegment;
using gr::PangoGrFont;
using gr::PangoTextSrc;

using gr::SegmentCache;

gint segment_compare (gconstpointer a, gconstpointer b)
{
      SegmentCache* acache = (SegmentCache*) a;
      SegmentCache* bcache = (SegmentCache*) b;
    if (*(acache->font()) != *(bcache->font()))
        return (acache - bcache);     // any ordering will do here so long as it is consistent
      else if (acache->length() != bcache->length())
         return (acache->length() - bcache->length());
    else
         return strcmp(acache->text(), bcache->text());
}

RangeSegment *graphite_GetSegment(PangoTextSrc *text, PangoGrFont *pFont)
{
      GList *found;
      RangeSegment *pgrseg = NULL;
      SegmentCache *cachecomp = new SegmentCache(text, NULL, pFont, true);
      found = g_list_find_custom(segment_cache, cachecomp, &segment_compare);
      delete cachecomp;
      if (found)
      {
            SegmentCache *foundcache = (SegmentCache*) found->data;
            
            pgrseg = foundcache->segment();
      }
      return pgrseg;
}

/*
      Cache takes control of the text, font and glyphstring memory
      returns a new text and font
*/
void graphite_CacheSegment(PangoTextSrc * & text, PangoGrFont * & pfont, 
      RangeSegment *pgrseg)
{
      SegmentCache *cache = new SegmentCache(text, pgrseg, pfont, false);
      PangoTextSrc *new_text = new PangoTextSrc(*text);
      PangoGrFont *new_pfont = new PangoGrFont(*pfont);
      text = new_text;
      pfont = new_pfont;
      segment_cache = g_list_append(segment_cache, cache);
    if (++segment_cache_length > MAX_CACHE)
    {
        GList *tSeg = g_list_first(segment_cache);
   if (tSeg)
   {
     SegmentCache * old_cache =
       reinterpret_cast<SegmentCache*>(tSeg->data);
     delete old_cache;
   }
        segment_cache = g_list_delete_link(segment_cache, tSeg);
        --segment_cache_length;
    }
}

using gr::GlyphStringCache;
gint glyphstring_compare (gconstpointer a, gconstpointer b)
{
      GlyphStringCache* acache = (GlyphStringCache*) a;
      GlyphStringCache* bcache = (GlyphStringCache*) b;
    if (*(acache->font()) != *(bcache->font()))
        return (acache - bcache);     // any ordering will do here so long as it is consistent
      else if (acache->length() != bcache->length())
         return (acache->length() - bcache->length());
    else
         return strcmp(acache->text(), bcache->text());
}

PangoGlyphString *graphite_GetGlyphString(PangoTextSrc *text, PangoGrFont *pFont)
{
      GList *found;
      PangoGlyphString *pglyphs = NULL;
      GlyphStringCache *cachecomp = new GlyphStringCache(text, NULL, pFont, true);
      found = g_list_find_custom(glyphstring_cache, cachecomp, &glyphstring_compare);
      delete cachecomp;
      if (found)
      {
            GlyphStringCache *foundcache = (GlyphStringCache*) found->data;
            
            pglyphs = foundcache->glyphstring();
      }
      return pglyphs;
}

/*
      Cache takes control of the text, font and glyphstring memory
*/
void graphite_CacheGlyphString(PangoTextSrc * & text, PangoGrFont * & pfont,
      PangoGlyphString *pglyphs)
{
    PangoGlyphString *new_string = pango_glyph_string_copy(pglyphs);
    if (new_string)
    {
        GlyphStringCache *cache = new GlyphStringCache(text, new_string,
                                                    pfont, false);
        glyphstring_cache = g_list_append(glyphstring_cache, cache);
        if (++glyphstring_cache_length > MAX_CACHE)
        {
            GList *tString = g_list_first(glyphstring_cache);
     if (tString)
     {
       GlyphStringCache * oldCache = 
         reinterpret_cast<GlyphStringCache*>(tString->data);
       delete oldCache;
     }
            glyphstring_cache = g_list_delete_link(glyphstring_cache, tString);
            --glyphstring_cache_length;
        }
    }
}

using gr::LogAttrCache;
gint logattr_compare (gconstpointer a, gconstpointer b)
{
      LogAttrCache* acache = (LogAttrCache*) a;
      LogAttrCache* bcache = (LogAttrCache*) b;
    if (*(acache->font()) != *(bcache->font()))
        return (acache - bcache);     // any ordering will do here so long as it is consistent
      else if (acache->length() != bcache->length())
            return (acache->length() - bcache->length());
    else
         return strcmp(acache->text(), bcache->text());
}

PangoLogAttr *graphite_GetLogAttr(PangoTextSrc *text, PangoGrFont *pFont)
{
      GList *found;
      PangoLogAttr *pattrs = NULL;
      LogAttrCache *cachecomp = new LogAttrCache(text, NULL, pFont, 0);
      found = g_list_find_custom(logattr_cache, cachecomp, &logattr_compare);
      delete cachecomp;
      if (found)
      {
            LogAttrCache *foundcache = (LogAttrCache*) found->data;
            
            pattrs = foundcache->logattr();
      }
      return pattrs;
}

/*
      Cache takes control of the text, font and attrs memory
*/
void graphite_CacheLogAttr(PangoTextSrc * & text, PangoGrFont * & pfont,
      int attr_len, PangoLogAttr *pattrs)
{
    PangoLogAttr *new_attrs = g_new (PangoLogAttr, attr_len);
      std::copy(pattrs, pattrs + attr_len, new_attrs);
    LogAttrCache *cache = new LogAttrCache(text, new_attrs,
                                                pfont, attr_len);
    logattr_cache = g_list_append(logattr_cache, cache);
    if (++logattr_cache_length > MAX_CACHE)
    {
        GList *tLog = g_list_first(logattr_cache);
   if (tLog)
   {
     LogAttrCache * oldCache = 
       reinterpret_cast<LogAttrCache*>(tLog->data);
     delete oldCache;
   }
        logattr_cache = g_list_delete_link(logattr_cache, tLog);
        --logattr_cache_length;
    }
}


Generated by  Doxygen 1.6.0   Back to index