view libinterp/corefcn/txt-eng-ft.h @ 17272:8ce6cdd272eb

Support TeX elements in FreeType renderer. * libinterp/corefcn/txt-eng.cc: New file. Contains mapping from symbol name to character code, in Unicode and MS symbol. * libinterp/corefcn/modules.mk (COREFCN_SRC): Add txt-eng.cc. * libinterp/corefcn/oct-tex-lexer.ll: Add "\n" to rules applicable to ".", as the latter does not include new line characters. * libinterp/corefcn/oct-tex-parser.yy: Remove debug statements. * libinterp/corefcn/txt-eng.ft.cc (gripe_missing_glyph, gripe_glyph_render): Change signature from char to FT_ULong. (ft_render::ft_render): Adapt to new/removed members. (ft_render::~ft_render): Remove use of fonts member. (ft_render::set_font): Likewise. Use font instead. (ft_render::push_new_line): Likewise. Change meaning of yoffset and initialize line_yoffset. (ft_render::update_line_bbox): New method. (ft_render::set_mode): Change meaning of yoffset and initialize line_yoffset. (ft_render::process_character): New method. (ft_render::visit(text_element_string)): Use it. (ft_render::visit(text_element_list), ft_render::visit(text_element_subscript), ft_render::visit(text_element_superscript), ft_render::visit(text_element_color), ft_render::visit(text_element_fontsize), ft_render::visit(text_element_fontname), ft_render::visit(text_element_fontstyle), ft_render::visit(text_element_symbol)): New methods. (ft_render::set_color): Use color member instead of red/green/blue. * libinterp/corefcn/txt-eng-ft.h (ft_render::visit(text_element_list), ft_render::visit(text_element_subscript), ft_render::visit(text_element_superscript), ft_render::visit(text_element_color), ft_render::visit(text_element_fontsize), ft_render::visit(text_element_fontname), ft_render::visit(text_element_fontstyle), ft_render::visit(text_element_symbol)): New methods. (ft_render::update_line_bbox, ft_render::process_character): New methods. (ft_render::current_face): Removed method.i (ft_render::font): New member, replaces obsolete ft_render::fonts. (ft_render::line_yoffset): New member. (ft_render::color): New member, replaces obsolete red, green and blue. (ft_render::ft_font::ft_font()): Implement default constructor. (ft_render::ft_font::operator=): Fix incorrect use of FT_Reference_Face return value. (ft_render::ft_font::is_valid): New method. * libinterp/corefcn/txt-eng.h (class text_element_symbol, class text_element_fontname, class text_element_fontsize, class text_element_fontname, class text_element_fontstyle, class text_element_color): Add forward definition. (text_element_symbol::invalid_code): New enum. (text_element_symbol::code): New member. (text_element_symbol::text_element_symbol): Initialize it. (text_element_symbol::get_symbol_code): New method. (text_element_fontstyle::get_fontstyle): New method. (text_element_fontname::get_fontname): Renamed from fontname. (text_element_fontsize::get_fontsize): Renamed from fontsize.
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 18 Aug 2013 16:36:46 -0400
parents cb7233cfbf43
children 0a09d4b40767
line wrap: on
line source

/*

Copyright (C) 2009-2012 Michael Goffioul

This file is part of Octave.

Octave is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

Octave 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 General Public License
for more details.

You should have received a copy of the GNU General Public License
along with Octave; see the file COPYING.  If not, see
<http://www.gnu.org/licenses/>.

*/

#if ! defined (txt_eng_ft_h)
#define txt_eng_ft_h 1

#if HAVE_FREETYPE

#include <list>
#include <vector>

#include <ft2build.h>
#include FT_FREETYPE_H

#include <dMatrix.h>
#include <uint8NDArray.h>
#include "txt-eng.h"

class
OCTINTERP_API
ft_render : public text_processor
{
public:
  enum {
      MODE_BBOX   = 0,
      MODE_RENDER = 1
  };

  enum {
      ROTATION_0   = 0,
      ROTATION_90  = 1,
      ROTATION_180 = 2,
      ROTATION_270 = 3
  };

public:
  ft_render (void);

  ~ft_render (void);

  void visit (text_element_string& e);

  void visit (text_element_list& e);

  void visit (text_element_subscript& e);

  void visit (text_element_superscript& e);

  void visit (text_element_color& e);

  void visit (text_element_fontsize& e);

  void visit (text_element_fontname& e);

  void visit (text_element_fontstyle& e);

  void visit (text_element_symbol& e);

  void reset (void);

  uint8NDArray get_pixels (void) const { return pixels; }

  Matrix get_boundingbox (void) const { return bbox; }

  uint8NDArray render (text_element* elt, Matrix& box,
                       int rotation = ROTATION_0);

  Matrix get_extent (text_element *elt, double rotation = 0.0);
  Matrix get_extent (const std::string& txt, double rotation = 0.0,
                     const caseless_str& interpreter = "tex");

  void set_font (const std::string& name, const std::string& weight,
                 const std::string& angle, double size);

  void set_color (Matrix c);

  void set_mode (int m);

  void text_to_pixels (const std::string& txt,
                       uint8NDArray& pixels_, Matrix& bbox,
                       int halign, int valign, double rotation,
                       const caseless_str& interpreter = "tex");

private:
  int rotation_to_mode (double rotation) const;

  // No copying!

  ft_render (const ft_render&);

  ft_render& operator = (const ft_render&);

  // Class to hold information about fonts and a strong
  // reference to the font objects loaded by freetype.
  class ft_font
    {
    public:
      std::string name;
      std::string weight;
      std::string angle;
      double size;
      FT_Face face;

      ft_font (void)
        : name (), weight (), angle (), size (0), face (0) { }

      ft_font (const std::string& nm, const std::string& wt,
               const std::string& ang, double sz, FT_Face f)
        : name (nm), weight (wt), angle (ang), size (sz), face (f) { }

      ft_font (const ft_font& ft)
        : name (ft.name), weight (ft.weight), angle (ft.angle),
          size (ft.size), face (0)
        {
          if (FT_Reference_Face (ft.face) == 0)
            face = ft.face;
        }

      ~ft_font (void)
        {
          if (face)
            FT_Done_Face (face);
        }

      ft_font& operator = (const ft_font& ft)
        {
          if (&ft != this)
            {
              name = ft.name;
              weight = ft.weight;
              angle = ft.angle;
              size = ft.size;
              FT_Done_Face (face);
              if (FT_Reference_Face (ft.face) == 0)
                face = ft.face;
              else
                face = 0;
            }

          return *this;
        }

      bool is_valid (void) const { return face; }
    };

  void push_new_line (void);

  void update_line_bbox (void);

  void compute_bbox (void);

  int compute_line_xoffset (const Matrix& lb) const;

  FT_UInt process_character (FT_ULong code, FT_UInt previous = 0);

private:
  // The current font used by the renderer.
  ft_font font;

  // Used to stored the bounding box corresponding to the rendered text.
  // The bounding box has the form [x, y, w, h] where x and y represent the
  // coordinates of the bottom left corner relative to the anchor point of
  // the text (== start of text on the baseline). Due to font descent or
  // multiple lines, the value y is usually negative.
  Matrix bbox;

  // Used to stored the rendered text. It's a 3D matrix with size MxNx4
  // where M and N are the width and height of the bounding box.
  uint8NDArray pixels;

  // Used to store the bounding box of each line. This is used to layout
  // multiline text properly.
  std::list<Matrix> line_bbox;

  // The current horizontal alignment. This is used to align multi-line text.
  int halign;

  // The X offset for the next glyph.
  int xoffset;

  // The Y offset of the baseline for the current line.
  int line_yoffset;

  // The Y offset of the baseline for the next glyph. The offset is relative
  // to line_yoffset. The total Y offset is computed with:
  // line_yoffset + yoffset.
  int yoffset;

  // The current mode of the rendering process (box computing or rendering).
  int mode;

  // The base color of the rendered text.
  uint8NDArray color;
};

#endif // HAVE_FREETYPE

#endif