Blame tests/test-user-font.cc

Packit Service e3b512
// vim: ts=2 sw=2 et
Packit Service e3b512
/*
Packit Service e3b512
 * These tests are of limited usefulness.  In fact, you might even say that
Packit Service e3b512
 * they're not really tests at all.  But I felt that it would be useful to have
Packit Service e3b512
 * some basic usage of most functions just to verify that things compile and
Packit Service e3b512
 * work generally
Packit Service e3b512
 */
Packit Service e3b512
Packit Service e3b512
#include <cfloat>
Packit Service e3b512
#include <stdexcept>
Packit Service e3b512
#include <boost/test/unit_test.hpp>
Packit Service e3b512
#include <boost/test/test_tools.hpp>
Packit Service e3b512
#include <boost/test/floating_point_comparison.hpp>
Packit Service e3b512
using namespace boost::unit_test;
Packit Service e3b512
#include <cairomm/fontface.h>
Packit Service e3b512
#include <cairomm/scaledfont.h>
Packit Service e3b512
#include <cairomm/surface.h>
Packit Service e3b512
#include <cairomm/context.h>
Packit Service e3b512
Packit Service e3b512
using namespace Cairo;
Packit Service e3b512
Packit Service e3b512
// little utility helper classes
Packit Service e3b512
struct TestSetup
Packit Service e3b512
{
Packit Service e3b512
  TestSetup()
Packit Service e3b512
  {
Packit Service e3b512
    surface = ImageSurface::create(Cairo::FORMAT_ARGB32, 100, 100);
Packit Service e3b512
    cr = Cairo::Context::create(surface);
Packit Service e3b512
  }
Packit Service e3b512
Packit Service e3b512
  RefPtr<Context> cr;
Packit Service e3b512
  RefPtr<Surface> surface;
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
// a no-op-render user font base class
Packit Service e3b512
class NullRenderUserFont : public UserFontFace
Packit Service e3b512
{
Packit Service e3b512
public:
Packit Service e3b512
  ErrorStatus
Packit Service e3b512
    render_glyph(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                 unsigned long /*glyph*/,
Packit Service e3b512
                 const RefPtr<Context>& /*cr*/,
Packit Service e3b512
                 TextExtents& /*metrics*/)
Packit Service e3b512
    { ++count_render_glyph; return CAIRO_STATUS_SUCCESS; }
Packit Service e3b512
Packit Service e3b512
  int count_render_glyph;
Packit Service e3b512
Packit Service e3b512
protected:
Packit Service e3b512
  NullRenderUserFont() : UserFontFace(), count_render_glyph(0) {}
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
/******************************
Packit Service e3b512
 * test_implement_text
Packit Service e3b512
 ******************************/
Packit Service e3b512
class ImplTextUserFont: public NullRenderUserFont
Packit Service e3b512
{
Packit Service e3b512
public:
Packit Service e3b512
  static RefPtr<ImplTextUserFont> create() { return RefPtr<ImplTextUserFont>(new ImplTextUserFont());};
Packit Service e3b512
  ErrorStatus text_to_glyphs(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                                     const std::string& /*utf8*/,
Packit Service e3b512
                                     std::vector<Glyph>& glyphs,
Packit Service e3b512
                                     std::vector<TextCluster>& /*clusters*/,
Packit Service e3b512
                                     TextClusterFlags& /*cluster_flags*/) override
Packit Service e3b512
  {
Packit Service e3b512
    ++count_text_to_glyphs;
Packit Service e3b512
    // return an arbitrary glyph
Packit Service e3b512
    Glyph g = {84, 0, 0};
Packit Service e3b512
    glyphs.push_back(g);
Packit Service e3b512
    return CAIRO_STATUS_SUCCESS;
Packit Service e3b512
  }
Packit Service e3b512
  int count_text_to_glyphs;
Packit Service e3b512
Packit Service e3b512
protected:
Packit Service e3b512
  ImplTextUserFont() : count_text_to_glyphs(0) {}
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
void test_implement_text()
Packit Service e3b512
{
Packit Service e3b512
  TestSetup setup;
Packit Service e3b512
  auto font = ImplTextUserFont::create();
Packit Service e3b512
  setup.cr->set_font_face(font);
Packit Service e3b512
  setup.cr->show_text("hello");
Packit Service e3b512
  BOOST_REQUIRE(font->count_text_to_glyphs > 0);
Packit Service e3b512
  BOOST_REQUIRE(font->count_render_glyph > 0);
Packit Service e3b512
}
Packit Service e3b512
Packit Service e3b512
/******************************
Packit Service e3b512
 * test_implement_unicode
Packit Service e3b512
 ******************************/
Packit Service e3b512
class ImplUnicodeUserFont: public NullRenderUserFont
Packit Service e3b512
{
Packit Service e3b512
public:
Packit Service e3b512
  static RefPtr<ImplUnicodeUserFont> create() { return RefPtr<ImplUnicodeUserFont>(new ImplUnicodeUserFont());};
Packit Service e3b512
  ErrorStatus unicode_to_glyph(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                                       unsigned long /*unicode*/,
Packit Service e3b512
                                       unsigned long& /*glyph*/) override
Packit Service e3b512
  { ++count_unicode_to_glyph;  return CAIRO_STATUS_SUCCESS;}
Packit Service e3b512
  int count_unicode_to_glyph;
Packit Service e3b512
Packit Service e3b512
protected:
Packit Service e3b512
  ImplUnicodeUserFont() : NullRenderUserFont(), count_unicode_to_glyph(0) {}
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
void test_implement_unicode()
Packit Service e3b512
{
Packit Service e3b512
  TestSetup setup;
Packit Service e3b512
  auto font = ImplTextUserFont::create();
Packit Service e3b512
  setup.cr->set_font_face(font);
Packit Service e3b512
  setup.cr->show_text("hello");
Packit Service e3b512
  BOOST_REQUIRE(font->count_text_to_glyphs > 0);
Packit Service e3b512
  BOOST_REQUIRE(font->count_render_glyph > 0);
Packit Service e3b512
}
Packit Service e3b512
Packit Service e3b512
/******************************
Packit Service e3b512
 * test_implement_both
Packit Service e3b512
 ******************************/
Packit Service e3b512
class ImplBothUserFont: public NullRenderUserFont
Packit Service e3b512
{
Packit Service e3b512
public:
Packit Service e3b512
  static RefPtr<ImplBothUserFont> create() { return RefPtr<ImplBothUserFont>(new ImplBothUserFont());};
Packit Service e3b512
  ErrorStatus unicode_to_glyph(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                                       unsigned long /*unicode*/,
Packit Service e3b512
                                       unsigned long& /*glyph*/) override
Packit Service e3b512
  { ++count_unicode_to_glyph;  return CAIRO_STATUS_SUCCESS;}
Packit Service e3b512
  int count_unicode_to_glyph;
Packit Service e3b512
Packit Service e3b512
  ErrorStatus text_to_glyphs(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                                     const std::string& /*utf8*/,
Packit Service e3b512
                                     std::vector<Glyph>& glyphs,
Packit Service e3b512
                                     std::vector<TextCluster>& /*clusters*/,
Packit Service e3b512
                                     TextClusterFlags& /*cluster_flags*/) override
Packit Service e3b512
  {
Packit Service e3b512
    ++count_text_to_glyphs;
Packit Service e3b512
    // return an arbitrary glyph
Packit Service e3b512
    Glyph g = {84, 0, 0};
Packit Service e3b512
    glyphs.push_back(g);
Packit Service e3b512
    return CAIRO_STATUS_SUCCESS;
Packit Service e3b512
  }
Packit Service e3b512
  int count_text_to_glyphs;
Packit Service e3b512
Packit Service e3b512
protected:
Packit Service e3b512
  ImplBothUserFont() : NullRenderUserFont(), count_unicode_to_glyph(0),
Packit Service e3b512
  count_text_to_glyphs(0) {}
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
void test_implement_both()
Packit Service e3b512
{
Packit Service e3b512
  TestSetup setup;
Packit Service e3b512
  auto font = ImplBothUserFont::create();
Packit Service e3b512
  setup.cr->set_font_face(font);
Packit Service e3b512
  setup.cr->show_text("hello");
Packit Service e3b512
  // text_to_glyphs should take precedence
Packit Service e3b512
  BOOST_REQUIRE(font->count_text_to_glyphs > 0);
Packit Service e3b512
  BOOST_REQUIRE(font->count_unicode_to_glyph == 0);
Packit Service e3b512
  BOOST_REQUIRE(font->count_render_glyph > 0);
Packit Service e3b512
}
Packit Service e3b512
Packit Service e3b512
/******************************
Packit Service e3b512
 * test_implement_neither
Packit Service e3b512
 ******************************/
Packit Service e3b512
class ImplNeitherUserFont: public NullRenderUserFont
Packit Service e3b512
{
Packit Service e3b512
public:
Packit Service e3b512
  static RefPtr<ImplNeitherUserFont> create() { return RefPtr<ImplNeitherUserFont>(new ImplNeitherUserFont());};
Packit Service e3b512
Packit Service e3b512
protected:
Packit Service e3b512
  ImplNeitherUserFont() : NullRenderUserFont() {}
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
void test_implement_neither()
Packit Service e3b512
{
Packit Service e3b512
  TestSetup setup;
Packit Service e3b512
  auto font = ImplNeitherUserFont::create();
Packit Service e3b512
  setup.cr->set_font_face(font);
Packit Service e3b512
  setup.cr->show_text("hello");
Packit Service e3b512
  BOOST_REQUIRE(font->count_render_glyph > 0);
Packit Service e3b512
}
Packit Service e3b512
Packit Service e3b512
/******************************
Packit Service e3b512
 * test_implement_init
Packit Service e3b512
 ******************************/
Packit Service e3b512
class ImplInitUserFont: public NullRenderUserFont
Packit Service e3b512
{
Packit Service e3b512
public:
Packit Service e3b512
  static RefPtr<ImplInitUserFont> create() { return RefPtr<ImplInitUserFont>(new ImplInitUserFont());};
Packit Service e3b512
  ErrorStatus init(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                           const RefPtr<Context>& /*cr*/,
Packit Service e3b512
                           FontExtents& /*extents*/) override
Packit Service e3b512
  {++count_init; return CAIRO_STATUS_SUCCESS;}
Packit Service e3b512
Packit Service e3b512
  int count_init;
Packit Service e3b512
Packit Service e3b512
protected:
Packit Service e3b512
  ImplInitUserFont() : NullRenderUserFont(), count_init(0) {}
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
void test_implement_init()
Packit Service e3b512
{
Packit Service e3b512
  TestSetup setup;
Packit Service e3b512
  auto font = ImplInitUserFont::create();
Packit Service e3b512
  setup.cr->set_font_face(font);
Packit Service e3b512
  setup.cr->show_text("hello");
Packit Service e3b512
  BOOST_REQUIRE(font->count_init > 0);
Packit Service e3b512
  BOOST_REQUIRE(font->count_render_glyph > 0);
Packit Service e3b512
}
Packit Service e3b512
Packit Service e3b512
class ExceptionUserFont : public UserFontFace
Packit Service e3b512
{
Packit Service e3b512
public:
Packit Service e3b512
  static RefPtr<ExceptionUserFont> create(int flags) { return RefPtr<ExceptionUserFont>(new ExceptionUserFont(flags));};
Packit Service e3b512
Packit Service e3b512
  ErrorStatus
Packit Service e3b512
  render_glyph(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
               unsigned long /*glyph*/,
Packit Service e3b512
               const RefPtr<Context>& /*cr*/,
Packit Service e3b512
               TextExtents& /*metrics*/)
Packit Service e3b512
  {
Packit Service e3b512
    count_render_glyph++;
Packit Service e3b512
    if (m_flags & FLAG_RENDER)
Packit Service e3b512
      throw std::logic_error("render-glyph exception");
Packit Service e3b512
    return CAIRO_STATUS_SUCCESS;
Packit Service e3b512
  }
Packit Service e3b512
Packit Service e3b512
  ErrorStatus
Packit Service e3b512
  unicode_to_glyph(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                                       unsigned long unicode,
Packit Service e3b512
                                       unsigned long& glyph)
Packit Service e3b512
  {
Packit Service e3b512
    count_unicode_to_glyph++;
Packit Service e3b512
    if (m_flags & FLAG_UNICODE)
Packit Service e3b512
      throw std::logic_error("unicode-to-glyph exception");
Packit Service e3b512
Packit Service e3b512
    glyph = unicode;
Packit Service e3b512
    return CAIRO_STATUS_SUCCESS;
Packit Service e3b512
  }
Packit Service e3b512
Packit Service e3b512
  ErrorStatus
Packit Service e3b512
  init(const RefPtr<ScaledFont>& /*scaled_font*/,
Packit Service e3b512
                         const RefPtr<Context>& /*cr*/,
Packit Service e3b512
                         FontExtents& /*extents*/) override
Packit Service e3b512
  {
Packit Service e3b512
    count_init++;
Packit Service e3b512
    if (m_flags & FLAG_INIT)
Packit Service e3b512
      throw std::logic_error("init exception");
Packit Service e3b512
    return CAIRO_STATUS_SUCCESS;
Packit Service e3b512
  }
Packit Service e3b512
Packit Service e3b512
  int count_render_glyph;
Packit Service e3b512
  int count_text_to_glyphs;
Packit Service e3b512
  int count_unicode_to_glyph;
Packit Service e3b512
  int count_init;
Packit Service e3b512
  int m_flags;
Packit Service e3b512
Packit Service e3b512
  static const int FLAG_INIT = 1 << 0;
Packit Service e3b512
  static const int FLAG_UNICODE = 1 << 1;
Packit Service e3b512
  static const int FLAG_RENDER = 1 << 2;
Packit Service e3b512
Packit Service e3b512
protected:
Packit Service e3b512
  ExceptionUserFont(int flags) : UserFontFace(), count_render_glyph(0),
Packit Service e3b512
  count_text_to_glyphs(0), count_unicode_to_glyph(0), count_init(0),
Packit Service e3b512
  m_flags(flags) {}
Packit Service e3b512
};
Packit Service e3b512
Packit Service e3b512
void test_user_font_exception()
Packit Service e3b512
{
Packit Service e3b512
  auto font =
Packit Service e3b512
    ExceptionUserFont::create(ExceptionUserFont::FLAG_INIT);
Packit Service e3b512
  BOOST_CHECK(font);
Packit Service e3b512
Packit Service e3b512
  // the init() callback will throw an exception, if this isn't handled in the
Packit Service e3b512
  // callback wrapper, the program will abort since an exception can't unwind
Packit Service e3b512
  // through C code.  However, due to the exception being thrown, the create()
Packit Service e3b512
  // function will fail and throw a new exception.  So if the executable doesn't
Packit Service e3b512
  // abort, we should get an exception here.
Packit Service e3b512
  Cairo::RefPtr<Cairo::ScaledFont> scaled_font;
Packit Service e3b512
  BOOST_CHECK_THROW (scaled_font = Cairo::ScaledFont::create(font,
Packit Service e3b512
                                                             Cairo::scaling_matrix(10, 10),
Packit Service e3b512
                                                             Cairo::identity_matrix(),
Packit Service e3b512
                                                             Cairo::FontOptions()),
Packit Service e3b512
                     Cairo::logic_error);
Packit Service e3b512
  BOOST_CHECK (font->count_init > 0);
Packit Service e3b512
Packit Service e3b512
  // now test when an exception is thrown in unicode_to_glyph
Packit Service e3b512
  font = ExceptionUserFont::create(ExceptionUserFont::FLAG_UNICODE);
Packit Service e3b512
  BOOST_CHECK_NO_THROW (scaled_font = Cairo::ScaledFont::create(font,
Packit Service e3b512
                                                                Cairo::scaling_matrix(10, 10),
Packit Service e3b512
                                                                Cairo::identity_matrix(),
Packit Service e3b512
                                                                Cairo::FontOptions()));
Packit Service e3b512
  TestSetup setup;
Packit Service e3b512
  setup.cr->set_font_face(font);
Packit Service e3b512
  // this call should throw an exception since the callback wrapper will return
Packit Service e3b512
  // an error status (that will be translated into an exception) but the test
Packit Service e3b512
  // shouldn't abort since the callback exceptions are handled by the callback
Packit Service e3b512
  // wrapper
Packit Service e3b512
  BOOST_REQUIRE_EQUAL (CAIRO_STATUS_SUCCESS, font->get_status());
Packit Service e3b512
  BOOST_CHECK_THROW(setup.cr->show_text("Hello, world"), Cairo::logic_error);
Packit Service e3b512
  BOOST_CHECK(font->count_unicode_to_glyph > 0);
Packit Service e3b512
  BOOST_CHECK_EQUAL(font->count_render_glyph, 0);
Packit Service e3b512
Packit Service e3b512
  // now test when an exception is thrown in render_glyph
Packit Service e3b512
  font = ExceptionUserFont::create(ExceptionUserFont::FLAG_RENDER);
Packit Service e3b512
  BOOST_CHECK_NO_THROW (scaled_font = Cairo::ScaledFont::create(font,
Packit Service e3b512
                                                                Cairo::scaling_matrix(10, 10),
Packit Service e3b512
                                                                Cairo::identity_matrix(),
Packit Service e3b512
                                                                Cairo::FontOptions()));
Packit Service e3b512
  // need a new setup since the old cr is now in an error state, so attemtping
Packit Service e3b512
  // to use it will throw an exception
Packit Service e3b512
  TestSetup setup2;
Packit Service e3b512
  BOOST_CHECK_NO_THROW(setup2.cr->set_font_face(font));
Packit Service e3b512
  BOOST_REQUIRE_EQUAL (CAIRO_STATUS_SUCCESS, font->get_status());
Packit Service e3b512
  BOOST_CHECK_THROW(setup2.cr->show_text("Hello, world"), Cairo::logic_error);
Packit Service e3b512
  BOOST_CHECK (font->count_unicode_to_glyph > 0);
Packit Service e3b512
  BOOST_CHECK (font->count_render_glyph > 0);
Packit Service e3b512
}
Packit Service e3b512
Packit Service e3b512
Packit Service e3b512
test_suite*
Packit Service e3b512
init_unit_test_suite(int argc, char* argv[])
Packit Service e3b512
{
Packit Service e3b512
  // compile even with -Werror
Packit Service e3b512
  if (argc && argv) {}
Packit Service e3b512
Packit Service e3b512
  test_suite* test= BOOST_TEST_SUITE( "Cairo::UserFontFace Tests" );
Packit Service e3b512
Packit Service e3b512
  test->add (BOOST_TEST_CASE (&test_implement_text));
Packit Service e3b512
  test->add (BOOST_TEST_CASE (&test_implement_unicode));
Packit Service e3b512
  test->add (BOOST_TEST_CASE (&test_implement_both));
Packit Service e3b512
  test->add (BOOST_TEST_CASE (&test_implement_neither));
Packit Service e3b512
  test->add (BOOST_TEST_CASE (&test_implement_init));
Packit Service e3b512
  test->add (BOOST_TEST_CASE (&test_user_font_exception));
Packit Service e3b512
Packit Service e3b512
  return test;
Packit Service e3b512
}