Beispiel #1
0
void StaffText::layout()
      {
      if (autoplace())
            setUserOff(QPointF());
      QPointF p(textStyle().offset(spatium()));
      if (placement() == Element::Placement::BELOW)
            p.ry() =  - p.ry() + lineHeight();
      setPos(p);
      Text::layout1();
      if (!parent()) // palette & clone trick
          return;

      if (autoplace() && segment()) {
            qreal minDistance = score()->styleP(StyleIdx::dynamicsMinDistance);  // TODO
            Shape s1          = segment()->staffShape(staffIdx()).translated(segment()->pos());
            Shape s2          = shape().translated(segment()->pos());

            if (placement() == Element::Placement::ABOVE) {
                  qreal d = s2.minVerticalDistance(s1);
                  if (d > -minDistance)
                        rUserYoffset() = -d - minDistance;
                  }
            else {
                  qreal d = s1.minVerticalDistance(s2);
                  if (d > -minDistance)
                        rUserYoffset() = d + minDistance;
                  }
            }
      adjustReadPos();
      }
short RenderListMarker::baselinePosition(bool, bool) const
{
    if (!isImage()) {
        const Font& font = style()->font();
        return font.ascent() + (lineHeight(false) - font.height())/2;
    }
    return height();
}
Beispiel #3
0
void SimpleText::layout()
      {
      int n = _text.size();
      if (!n) {
            setPos(QPointF());
            setbbox(QRectF());
            return;
            }

      QFontMetricsF fm(_textStyle.fontPx(spatium()));
      QPointF o(_textStyle.offset(spatium()));

      QRectF bb;
      qreal lh = lineHeight();
      qreal ly = .0;
      for (int i = 0; i < n; ++i) {
            TLine* t = &_text[i];

            QRectF r(fm.tightBoundingRect(t->text));

            t->pos.ry() = ly;
            if (align() & ALIGN_BOTTOM)
                  t->pos.ry() += -r.bottom();
            else if (align() & ALIGN_VCENTER)
                  t->pos.ry() +=  -(r.top() + r.bottom()) * .5;
            else if (align() & ALIGN_BASELINE)
                  ;
            else  // ALIGN_TOP
                  t->pos.ry() += -r.top();

            if (align() & ALIGN_RIGHT)
                  t->pos.rx() = -r.right();
            else if (align() & ALIGN_HCENTER)
                  t->pos.rx() = -(r.left() + r.right()) * .5;
            else  // ALIGN_LEFT
                  t->pos.rx() = -r.left();
            bb |= r.translated(t->pos);
            ly += lh;
            }
      setPos(o);
      setbbox(bb);
      }
LayoutRect RenderBoxModelObject::localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset)
{
    ASSERT(!slowFirstChild());

    // FIXME: This does not take into account either :first-line or :first-letter
    // However, as soon as some content is entered, the line boxes will be
    // constructed and this kludge is not called any more. So only the caret size
    // of an empty :first-line'd block is wrong. I think we can live with that.
    RenderStyle* currentStyle = firstLineStyle();

    enum CaretAlignment { alignLeft, alignRight, alignCenter };

    CaretAlignment alignment = alignLeft;

    switch (currentStyle->textAlign()) {
    case LEFT:
    case WEBKIT_LEFT:
        break;
    case CENTER:
    case WEBKIT_CENTER:
        alignment = alignCenter;
        break;
    case RIGHT:
    case WEBKIT_RIGHT:
        alignment = alignRight;
        break;
    case JUSTIFY:
    case TASTART:
        if (!currentStyle->isLeftToRightDirection())
            alignment = alignRight;
        break;
    case TAEND:
        if (currentStyle->isLeftToRightDirection())
            alignment = alignRight;
        break;
    }

    LayoutUnit x = borderLeft() + paddingLeft();
    LayoutUnit maxX = width - borderRight() - paddingRight();

    switch (alignment) {
    case alignLeft:
        if (currentStyle->isLeftToRightDirection())
            x += textIndentOffset;
        break;
    case alignCenter:
        x = (x + maxX) / 2;
        if (currentStyle->isLeftToRightDirection())
            x += textIndentOffset / 2;
        else
            x -= textIndentOffset / 2;
        break;
    case alignRight:
        x = maxX - caretWidth;
        if (!currentStyle->isLeftToRightDirection())
            x -= textIndentOffset;
        break;
    }
    x = std::min(x, std::max<LayoutUnit>(maxX - caretWidth, 0));

    LayoutUnit height = style()->fontMetrics().height();
    LayoutUnit verticalSpace = lineHeight(true, currentStyle->isHorizontalWritingMode() ? HorizontalLine : VerticalLine,  PositionOfInteriorLineBoxes) - height;
    LayoutUnit y = paddingTop() + borderTop() + (verticalSpace / 2);
    return currentStyle->isHorizontalWritingMode() ? LayoutRect(x, y, caretWidth, height) : LayoutRect(y, x, height, caretWidth);
}
Beispiel #5
0
int QDeclarativeText::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
    _id = QDeclarativeImplicitSizeItem::qt_metacall(_c, _id, _a);
    if (_id < 0)
        return _id;
    if (_c == QMetaObject::InvokeMetaMethod) {
        if (_id < 17)
            qt_static_metacall(this, _c, _id, _a);
        _id -= 17;
    }
#ifndef QT_NO_PROPERTIES
      else if (_c == QMetaObject::ReadProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: *reinterpret_cast< QString*>(_v) = text(); break;
        case 1: *reinterpret_cast< QFont*>(_v) = font(); break;
        case 2: *reinterpret_cast< QColor*>(_v) = color(); break;
        case 3: *reinterpret_cast< TextStyle*>(_v) = style(); break;
        case 4: *reinterpret_cast< QColor*>(_v) = styleColor(); break;
        case 5: *reinterpret_cast< HAlignment*>(_v) = hAlign(); break;
        case 6: *reinterpret_cast< VAlignment*>(_v) = vAlign(); break;
        case 7: *reinterpret_cast< WrapMode*>(_v) = wrapMode(); break;
        case 8: *reinterpret_cast< int*>(_v) = lineCount(); break;
        case 9: *reinterpret_cast< bool*>(_v) = truncated(); break;
        case 10: *reinterpret_cast< int*>(_v) = maximumLineCount(); break;
        case 11: *reinterpret_cast< TextFormat*>(_v) = textFormat(); break;
        case 12: *reinterpret_cast< TextElideMode*>(_v) = elideMode(); break;
        case 13: *reinterpret_cast< qreal*>(_v) = paintedWidth(); break;
        case 14: *reinterpret_cast< qreal*>(_v) = paintedHeight(); break;
        case 15: *reinterpret_cast< qreal*>(_v) = lineHeight(); break;
        case 16: *reinterpret_cast< LineHeightMode*>(_v) = lineHeightMode(); break;
        }
        _id -= 17;
    } else if (_c == QMetaObject::WriteProperty) {
        void *_v = _a[0];
        switch (_id) {
        case 0: setText(*reinterpret_cast< QString*>(_v)); break;
        case 1: setFont(*reinterpret_cast< QFont*>(_v)); break;
        case 2: setColor(*reinterpret_cast< QColor*>(_v)); break;
        case 3: setStyle(*reinterpret_cast< TextStyle*>(_v)); break;
        case 4: setStyleColor(*reinterpret_cast< QColor*>(_v)); break;
        case 5: setHAlign(*reinterpret_cast< HAlignment*>(_v)); break;
        case 6: setVAlign(*reinterpret_cast< VAlignment*>(_v)); break;
        case 7: setWrapMode(*reinterpret_cast< WrapMode*>(_v)); break;
        case 10: setMaximumLineCount(*reinterpret_cast< int*>(_v)); break;
        case 11: setTextFormat(*reinterpret_cast< TextFormat*>(_v)); break;
        case 12: setElideMode(*reinterpret_cast< TextElideMode*>(_v)); break;
        case 15: setLineHeight(*reinterpret_cast< qreal*>(_v)); break;
        case 16: setLineHeightMode(*reinterpret_cast< LineHeightMode*>(_v)); break;
        }
        _id -= 17;
    } else if (_c == QMetaObject::ResetProperty) {
        switch (_id) {
        case 5: resetHAlign(); break;
        case 10: resetMaximumLineCount(); break;
        }
        _id -= 17;
    } else if (_c == QMetaObject::QueryPropertyDesignable) {
        _id -= 17;
    } else if (_c == QMetaObject::QueryPropertyScriptable) {
        _id -= 17;
    } else if (_c == QMetaObject::QueryPropertyStored) {
        _id -= 17;
    } else if (_c == QMetaObject::QueryPropertyEditable) {
        _id -= 17;
    } else if (_c == QMetaObject::QueryPropertyUser) {
        _id -= 17;
    }
#endif // QT_NO_PROPERTIES
    return _id;
}
Beispiel #6
0
/*
The ultimate line painting function.
Currently missing features:
- draw indent lines
*/
void KateRenderer::paintTextLine(QPainter& paint, KateLineLayoutPtr range, int xStart, int xEnd, const KTextEditor::Cursor* cursor)
{
  Q_ASSERT(range->isValid());

//   kDebug( 13033 )<<"KateRenderer::paintTextLine";

  // font data
  const QFontMetricsF &fm = config()->fontMetrics();

  int currentViewLine = -1;
  if (cursor && cursor->line() == range->line())
    currentViewLine = range->viewLineForColumn(cursor->column());

  paintTextLineBackground(paint, range, currentViewLine, xStart, xEnd);

  if (range->layout()) {
    bool drawSelection = m_view->selection() && showSelections() && m_view->selectionRange().overlapsLine(range->line());
    // Draw selection in block selecton mode. We need 2 kinds of selections that QTextLayout::draw can't render:
    //   - past-end-of-line selection and
    //   - 0-column-wide selection (used to indicate where text will be typed)
    if (drawSelection && m_view->blockSelection()) {
      int selectionStartColumn = m_doc->fromVirtualColumn(range->line(), m_doc->toVirtualColumn(m_view->selectionRange().start()));
      int selectionEndColumn   = m_doc->fromVirtualColumn(range->line(), m_doc->toVirtualColumn(m_view->selectionRange().end()));
      QBrush selectionBrush = config()->selectionColor();
      if (selectionStartColumn != selectionEndColumn) {
        KateTextLayout lastLine = range->viewLine(range->viewLineCount() - 1);
        if (selectionEndColumn > lastLine.startCol()) {
          int selectionStartX = (selectionStartColumn > lastLine.startCol()) ? cursorToX(lastLine, selectionStartColumn, true) : 0;
          int selectionEndX = cursorToX(lastLine, selectionEndColumn, true);
          paint.fillRect(QRect(selectionStartX - xStart, (int)lastLine.lineLayout().y(), selectionEndX - selectionStartX, lineHeight()), selectionBrush);
        }
      } else {
        const int selectStickWidth = 2;
        KateTextLayout selectionLine = range->viewLine(range->viewLineForColumn(selectionStartColumn));
        int selectionX = cursorToX(selectionLine, selectionStartColumn, true);
        paint.fillRect(QRect(selectionX - xStart, (int)selectionLine.lineLayout().y(), selectStickWidth, lineHeight()), selectionBrush);
      }
    }

    QVector<QTextLayout::FormatRange> additionalFormats;
    if (range->length() > 0) {
      // We may have changed the pen, be absolutely sure it gets set back to
      // normal foreground color before drawing text for text that does not
      // set the pen color
      paint.setPen(attribute(KTextEditor::HighlightInterface::dsNormal)->foreground().color());
      // Draw the text :)
      if (drawSelection) {
        // FIXME toVector() may be a performance issue
        additionalFormats = decorationsForLine(range->textLine(), range->line(), true).toVector();
        range->layout()->draw(&paint, QPoint(-xStart,0), additionalFormats);

      } else {
        range->layout()->draw(&paint, QPoint(-xStart,0));
      }
    }

    QBrush backgroundBrush;
    bool backgroundBrushSet = false;

    // Loop each individual line for additional text decoration etc.
    QListIterator<QTextLayout::FormatRange> it = range->layout()->additionalFormats();
    QVectorIterator<QTextLayout::FormatRange> it2 = additionalFormats;
    for (int i = 0; i < range->viewLineCount(); ++i) {
      KateTextLayout line = range->viewLine(i);

      // Determine the background to use, if any, for the end of this view line
      backgroundBrushSet = false;
      while (it2.hasNext()) {
        const QTextLayout::FormatRange& fr = it2.peekNext();
        if (fr.start > line.endCol())
          break;

        if (fr.start + fr.length > line.endCol()) {
          if (fr.format.hasProperty(QTextFormat::BackgroundBrush)) {
            backgroundBrushSet = true;
            backgroundBrush = fr.format.background();
          }

          goto backgroundDetermined;
        }

        it2.next();
      }

      while (it.hasNext()) {
        const QTextLayout::FormatRange& fr = it.peekNext();
        if (fr.start > line.endCol())
          break;

        if (fr.start + fr.length > line.endCol()) {
          if (fr.format.hasProperty(QTextFormat::BackgroundBrush)) {
            backgroundBrushSet = true;
            backgroundBrush = fr.format.background();
          }

          break;
        }

        it.next();
      }

      backgroundDetermined:

      // Draw selection or background color outside of areas where text is rendered
      if (!m_printerFriendly ) {
        bool draw = false;
        QBrush drawBrush;
        if (m_view->selection() && !m_view->blockSelection() && m_view->lineEndSelected(line.end(true))) {
          draw = true;
          drawBrush = config()->selectionColor();
        } else if (backgroundBrushSet && !m_view->blockSelection()) {
          draw = true;
          drawBrush = backgroundBrush;
        }

        if (draw) {
          int fillStartX = line.endX() - line.startX() + line.xOffset() - xStart;
          int fillStartY = lineHeight() * i;
          int width= xEnd - xStart - fillStartX;
          int height= lineHeight();

          // reverse X for right-aligned lines
          if (range->layout()->textOption().alignment() == Qt::AlignRight)
            fillStartX = 0;

          if (width > 0) {
            QRect area(fillStartX, fillStartY, width, height);
            paint.fillRect(area, drawBrush);
          }
        }
      }
      // Draw indent lines
      if (showIndentLines() && i == 0)
      {
        const qreal w = spaceWidth();
        const int lastIndentColumn = range->textLine()->indentDepth(m_tabWidth);

        for (int x = m_indentWidth; x < lastIndentColumn; x += m_indentWidth)
        {
          paintIndentMarker(paint, x * w + 1 - xStart, range->line());
        }
      }

      // draw an open box to mark non-breaking spaces
      const QString& text = range->textLine()->string();
      int y = lineHeight() * i + fm.ascent() - fm.strikeOutPos();
      int nbSpaceIndex = text.indexOf(nbSpaceChar, line.lineLayout().xToCursor(xStart));

      while (nbSpaceIndex != -1 && nbSpaceIndex < line.endCol()) {
        int x = line.lineLayout().cursorToX(nbSpaceIndex);
        if (x > xEnd)
          break;
        paintNonBreakSpace(paint, x - xStart, y);
        nbSpaceIndex = text.indexOf(nbSpaceChar, nbSpaceIndex + 1);
      }

      // draw tab stop indicators
      if (showTabs()) {
        int tabIndex = text.indexOf(tabChar, line.lineLayout().xToCursor(xStart));
        while (tabIndex != -1 && tabIndex < line.endCol()) {
          int x = line.lineLayout().cursorToX(tabIndex);
          if (x > xEnd)
            break;
          paintTabstop(paint, x - xStart + spaceWidth()/2.0, y);
          tabIndex = text.indexOf(tabChar, tabIndex + 1);
        }
      }

      // draw trailing spaces
      if (showTrailingSpaces()) {
        int spaceIndex = line.endCol() - 1;
        int trailingPos = range->textLine()->lastChar();
        if (trailingPos < 0)
          trailingPos = 0;
        if (spaceIndex >= trailingPos) {
          while (spaceIndex >= line.startCol() && text.at(spaceIndex).isSpace()) {
            if (text.at(spaceIndex) != '\t' || !showTabs())
              paintTrailingSpace(paint, line.lineLayout().cursorToX(spaceIndex) - xStart + spaceWidth()/2.0, y);
            --spaceIndex;
          }
        }
      }
    }

    // draw word-wrap-honor-indent filling
    if ( (range->viewLineCount() > 1)  && range->shiftX() && (range->shiftX() > xStart) )
    {
      if (backgroundBrushSet)
        paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1),
          backgroundBrush);
      paint.fillRect(0, lineHeight(), range->shiftX() - xStart, lineHeight() * (range->viewLineCount() - 1),
        QBrush(config()->wordWrapMarkerColor(), Qt::Dense4Pattern));
    }

    // Draw caret
    if (drawCaret() && cursor && range->includesCursor(*cursor)) {
      int caretWidth, lineWidth = 2;
      QColor color;
      QTextLine line = range->layout()->lineForTextPosition(qMin(cursor->column(), range->length()));

      // Determine the caret's style
      caretStyles style = caretStyle();

      // Make the caret the desired width
      if (style == Line) {
        caretWidth = lineWidth;
      } else if (line.isValid() && cursor->column() < range->length()) {
        caretWidth = int(line.cursorToX(cursor->column() + 1) - line.cursorToX(cursor->column()));
        if (caretWidth < 0) {
          caretWidth = -caretWidth;
        }
      } else {
        caretWidth = spaceWidth();
      }

      // Determine the color
      if (m_caretOverrideColor.isValid()) {
        // Could actually use the real highlighting system for this...
        // would be slower, but more accurate for corner cases
        color = m_caretOverrideColor;
      } else {
        // search for the FormatRange that includes the cursor
        foreach (const QTextLayout::FormatRange &r, range->layout()->additionalFormats()) {
          if ((r.start <= cursor->column() ) && ( (r.start + r.length)  > cursor->column())) {
            // check for Qt::NoBrush, as the returned color is black() and no invalid QColor
            QBrush foregroundBrush = r.format.foreground();
            if (foregroundBrush != Qt::NoBrush) {
              color = r.format.foreground().color();
            }
            break;
          }
        }
        // still no color found, fall back to default style
        if (!color.isValid())
          color = attribute(KTextEditor::HighlightInterface::dsNormal)->foreground().color();
      }

      // Clip the caret - Qt's caret has a habit of intruding onto other lines.
      paint.save();
      paint.setClipRect(0, line.lineNumber() * lineHeight(), xEnd - xStart, lineHeight());
      switch(style) {
      case Line :
        paint.setPen(QPen(color, caretWidth));
        break;
      case Block :
        // use a gray caret so it's possible to see the character
        color.setAlpha(128);
        paint.setPen(QPen(color, caretWidth));
        break;
      case Underline :
        paint.setClipRect(0, lineHeight() - lineWidth, xEnd - xStart, lineWidth);
        break;
      case Half :
        color.setAlpha(128);
        paint.setPen(QPen(color, caretWidth));
        paint.setClipRect(0, lineHeight() / 2, xEnd - xStart, lineHeight() / 2);
        break;
      }

      if (cursor->column() <= range->length()) {
        range->layout()->drawCursor(&paint, QPoint(-xStart,0), cursor->column(), caretWidth);
      } else {
        // Off the end of the line... must be block mode. Draw the caret ourselves.
        const KateTextLayout& lastLine = range->viewLine(range->viewLineCount() - 1);
        int x = cursorToX(lastLine, KTextEditor::Cursor(range->line(), cursor->column()), true);
        if ((x >= xStart) && (x <= xEnd)) {
          paint.fillRect(x - xStart, (int)lastLine.lineLayout().y(), caretWidth, lineHeight(), color);
        }
      }

      paint.restore();
    }
Beispiel #7
0
void KateRenderer::paintTextLineBackground(QPainter& paint, KateLineLayoutPtr layout, int currentViewLine, int xStart, int xEnd)
{
  if (isPrinterFriendly())
    return;

  // Normal background color
  QColor backgroundColor( config()->backgroundColor() );

  // paint the current line background if we're on the current line
  QColor currentLineColor = config()->highlightedLineColor();

  // Check for mark background
  int markRed = 0, markGreen = 0, markBlue = 0, markCount = 0;

  // Retrieve marks for this line
  uint mrk = m_doc->mark( layout->line() );
  if (mrk)
  {
    for (uint bit = 0; bit < 32; bit++)
    {
      KTextEditor::MarkInterface::MarkTypes markType = (KTextEditor::MarkInterface::MarkTypes)(1<<bit);
      if (mrk & markType)
      {
        QColor markColor = config()->lineMarkerColor(markType);

        if (markColor.isValid()) {
          markCount++;
          markRed += markColor.red();
          markGreen += markColor.green();
          markBlue += markColor.blue();
        }
      }
    } // for
  } // Marks

  if (markCount) {
    markRed /= markCount;
    markGreen /= markCount;
    markBlue /= markCount;
    backgroundColor.setRgb(
      int((backgroundColor.red() * 0.9) + (markRed * 0.1)),
      int((backgroundColor.green() * 0.9) + (markGreen * 0.1)),
      int((backgroundColor.blue() * 0.9) + (markBlue * 0.1))
    );
  }

  // Draw line background
  paint.fillRect(0, 0, xEnd - xStart, lineHeight() * layout->viewLineCount(), backgroundColor);

  // paint the current line background if we're on the current line
  if (currentViewLine != -1) {
    if (markCount) {
      markRed /= markCount;
      markGreen /= markCount;
      markBlue /= markCount;
      currentLineColor.setRgb(
        int((currentLineColor.red() * 0.9) + (markRed * 0.1)),
        int((currentLineColor.green() * 0.9) + (markGreen * 0.1)),
        int((currentLineColor.blue() * 0.9) + (markBlue * 0.1))
      );
    }

    paint.fillRect(0, lineHeight() * currentViewLine, xEnd - xStart, lineHeight(), currentLineColor);
  }
}
int RenderLineBreak::baselinePosition(FontBaseline baselineType, bool firstLine, LineDirectionMode direction, LinePositionMode linePositionMode) const
{
    const RenderStyle& style = firstLine ? firstLineStyle() : this->style();
    const FontMetrics& fontMetrics = style.fontMetrics();
    return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
}
Beispiel #9
0
 /**
  * @brief Calculates preferable editor height for specified number of lines
  */
 int ScriptWidget::editorHeight(int lines)
 {
     return lines * lineHeight() + 8;
 }
Beispiel #10
0
static void drawChar(unsigned char ch, int posX, int posY, font_t* font,
    int alignFlags, short /*textFlags*/)
{
    float x = (float) posX, y = (float) posY;
    Point2Raw coords[4];
    RectRaw geometry;

    if(alignFlags & ALIGN_RIGHT)
        x -= Fonts_CharWidth(font, ch);
    else if(!(alignFlags & ALIGN_LEFT))
        x -= Fonts_CharWidth(font, ch) / 2;

    if(alignFlags & ALIGN_BOTTOM)
        y -= topToAscent(font) + lineHeight(font, ch);
    else if(!(alignFlags & ALIGN_TOP))
        y -= (topToAscent(font) + lineHeight(font, ch))/2;

    glMatrixMode(GL_MODELVIEW);
    glTranslatef(x, y, 0);

    switch(Font_Type(font))
    {
    case FT_BITMAP:
        /// @todo Filtering should be determined at a higher level.
        /// @todo We should not need to re-bind this texture here.
        GL_BindTextureUnmanaged(BitmapFont_GLTextureName(font), GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE,
                                filterUI? GL_LINEAR : GL_NEAREST);

        std::memcpy(&geometry, BitmapFont_CharGeometry(font, ch), sizeof(geometry));
        BitmapFont_CharCoords(font, ch, coords);
        break;

    case FT_BITMAPCOMPOSITE: {
        uint8_t const border = BitmapCompositeFont_CharBorder(font, ch);

        GL_BindTexture(BitmapCompositeFont_CharTexture(font, ch));

        std::memcpy(&geometry, BitmapCompositeFont_CharGeometry(font, ch), sizeof(geometry));
        if(border)
        {
            geometry.origin.x -= border;
            geometry.origin.y -= border;
            geometry.size.width += border*2;
            geometry.size.height += border*2;
        }
        BitmapCompositeFont_CharCoords(font, ch, coords);
        break; }

    default:
        Con_Error("FR_DrawChar: Invalid font type %i.", (int) Font_Type(font));
        exit(1); // Unreachable.
    }

    if(font->_marginWidth)
    {
        geometry.origin.x -= font->_marginWidth;
        geometry.size.width += font->_marginWidth*2;
    }
    if(font->_marginHeight)
    {
        geometry.origin.y -= font->_marginHeight;
        geometry.size.height += font->_marginHeight*2;
    }

    GL_DrawRectWithCoords(&geometry, coords);

    if(Font_Type(font) == FT_BITMAPCOMPOSITE)
    {
        GL_SetNoTexture();
    }

    glMatrixMode(GL_MODELVIEW);
    glTranslatef(-x, -y, 0);
}