void IWORKStyleContext::endOfElement()
{
  if (!m_parentIdent && !m_defaultParent.empty() && (!m_ident || (m_defaultParent != get(m_ident))))
    m_parentIdent = m_defaultParent;
  const IWORKStylePtr_t style(new IWORKStyle(m_props, m_ident, m_parentIdent));
  if (getId() && bool(m_styleMap))
    (*m_styleMap)[get(getId())] = style;
  if (m_ident && !m_nested)
    getState().m_stylesheet->m_styles[get(m_ident)] = style;
  if (isCollector())
    getCollector().collectStyle(style);
}
void IWORKStyleRefContext::endOfElement()
{
  if (getRef())
  {
    const IWORKStyleMap_t::const_iterator it = m_styleMap.find(get(getRef()));
    if (m_styleMap.end() != it)
    {
      const IWORKStylePtr_t &style = it->second;
      if (style->getIdent() && getState().m_stylesheet && !m_nested)
        getState().m_stylesheet->m_styles[get(style->getIdent())] = style;
      if (isCollector())
        getCollector().collectStyle(style);
    }
  }
}
void IWORKBrContext::endOfElement()
{
  if (isCollector())
    getCollector().collectLineBreak();
}
void IWORKLineElement::startOfElement()
{
  if (isCollector())
    getCollector().startLevel();
}
/*! Draw the statistics lines.
*/
void SimpleStatisticsForeground::draw(DrawEnv *pEnv, Viewport *pPort)
{
    if(getActive() == false)
        return;

    if(_face == 0)
        initText(getFamily(), getSize());

    if ((getCollector() == NULL) || 
        (!getCollector()->getNumOfElems() && !getMFElementIDs()->size()))
        return; // nothing to do

    Real32  pw = Real32(pPort->getPixelWidth ());
    Real32  ph = Real32(pPort->getPixelHeight());

    if(pw < 1 || ph < 1)
        return;

    glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT | GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_COLOR_MATERIAL);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    // Set viewport. We want to map one unit to one pixel on the
    // screen. Some sources in the internet say that we should
    // add an offset of -0.375 to prevent rounding errors. Don't
    // know if that is true, but it seems to work.
    glOrtho(0 - 0.375, pw - 0.375, 0 - 0.375, ph - 0.375, 0, 1);

    // retrieve text
    std::vector < std::string > stat;

    StatCollector *col = this->getCollector();
    StatElem      *el;

    if(getMFElementIDs()->size() != 0)
    {
        for(UInt32 i = 0; i < getMFElementIDs()->size(); ++i)
        {
            Int32 id(getElementIDs(i));
            el = ((id >= 0) ? col->getElem(id) : 0);

            stat.resize(stat.size() + 1);
            std::vector < std::string >::iterator str = stat.end() - 1;

            const char  *format = NULL;
            if(i < getMFFormats()->size() && getFormats(i).length())
            {
                format = getFormats(i).c_str();
            }

            if (el)
                el->putToString(*str, format);
            else
                *str = format;
        }
    }
    else    // fallback, show all elements
    {
        for(UInt32 i = 0; i < col->getNumOfElems(); ++i)
        {
            el = col->getElem(i, false);
            if(el)
            {
                std::string desc(el->getDesc()->getName()), eltext;

                el->putToString(eltext);
                desc = desc + " : " + eltext;

                stat.resize(stat.size() + 1);
                std::vector < std::string >::iterator str = stat.end() - 1;
                *str = desc;
            }
        }
    }

    TextLayoutParam layoutParam;
    layoutParam.spacing = 1.1f;
    layoutParam.majorAlignment = TextLayoutParam::ALIGN_BEGIN;
    layoutParam.minorAlignment = TextLayoutParam::ALIGN_BEGIN;

    TextLayoutResult layoutResult;
    _face->layout(stat, layoutParam, layoutResult);

    Real32 scale = 1 / _face->getScale();
    Real32 size = _face->getParam().size;
    Real32 textWidth = layoutResult.textBounds.x() * scale + size + getTextMargin().x() * 2.0f;
    Real32 textHeight = layoutResult.textBounds.y() * scale + size + getTextMargin().y() * 2.0f;

    // Let's do some simple form of layout management
    Real32 orthoX = 0, orthoY = ph;

    switch ( getHorizontalAlign() )
    {
        case Right:
            orthoX = pw - textWidth;
            break;
        case Middle:
            orthoX = (pw - textWidth) * 0.5;
            break;
        case Left:
        default:
            break;
    }

    switch ( getVerticalAlign() )
    {
        case Bottom:
            orthoY = textHeight;
            break;
        case Center:
            orthoY = (ph - textHeight) * 0.5 + textHeight;
            break;
        case Top:
        default:
            break;
    }

    glTranslatef(orthoX, orthoY, 0.0);

    // draw background
    glColor4fv(static_cast<const GLfloat *>(getBgColor().getValuesRGBA()));
    glBegin(GL_QUADS);
        glVertex2f(0, -textHeight);
        glVertex2f(textWidth, -textHeight);
        glVertex2f(textWidth, 0);
        glVertex2f(0, 0);
    glEnd();

    // draw border
    if(getBorderColor().alpha() >= 0.0f)
    {
        glColor4fv(
            static_cast<const GLfloat *>(getBorderColor().getValuesRGBA()));

        glBegin(GL_LINE_LOOP);
            glVertex2f(getBorderOffset().x(), 
                       -textHeight + 1 + getBorderOffset().y());
            glVertex2f(textWidth - 1 - getBorderOffset().x(), 
                       -textHeight + 1 + getBorderOffset().y());
            glVertex2f(textWidth - 1 - getBorderOffset().x(), 
                       -1 - getBorderOffset().y());
            glVertex2f(getBorderOffset().x(), -1 - getBorderOffset().y());
        glEnd();
    }

    glTranslatef( 0.5 * size + getTextMargin().x(), 
                 -0.5 * size - getTextMargin().y(), 
                  0.0);

    _texchunk   ->activate(pEnv);
    _texenvchunk->activate(pEnv);

    // draw text shadow
    glColor4fv(static_cast<const GLfloat *>(getShadowColor().getValuesRGBA()));
    glPushMatrix();
    glTranslatef(getShadowOffset().x(), getShadowOffset().y(), 0);
    glScalef(scale, scale, 1);
    _face->drawCharacters(layoutResult);

    // draw text
    glColor4fv(static_cast<const GLfloat *>(getColor().getValuesRGBA()));
    glPopMatrix();
    glScalef(scale, scale, 1);
    _face->drawCharacters(layoutResult);

    _texchunk   ->deactivate(pEnv);
    _texenvchunk->deactivate(pEnv);

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glPopAttrib();
}