mirror of https://github.com/KLayout/klayout.git
Further reducing dependency on Qt, fixed tests
This commit is contained in:
parent
1edaf2b6b4
commit
29b3718b2d
|
|
@ -28,9 +28,8 @@
|
|||
#include "rba.h"
|
||||
#include "gsiDecl.h"
|
||||
|
||||
// On Windows, ruby.h is not compatible with windows.h which is included by utHead - at least not if
|
||||
// windows.h is included before ruby.h ...
|
||||
#include "tlUnitTest.h"
|
||||
#include "tlFileUtils.h"
|
||||
|
||||
void run_rubytest (tl::TestBase * /*_this*/, const std::string &fn)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2001,9 +2001,10 @@ MarkerBrowserPage::update_info_text ()
|
|||
|
||||
info += "</pre>";
|
||||
|
||||
if (item->image () != 0) {
|
||||
QImage image = item->image ();
|
||||
if (! image.isNull ()) {
|
||||
info += "<table border=\"1\" cellspacing=\"0\" cellpadding=\"5\" style=\"border-color:blue; border-style:solid\"><tr><td><p>Snapshot image<br/>(click to enlarge)</p><p><a href=\"show-snapshot\"><img src=\"item.overview-image\"/></a></p></td></tr></table>";
|
||||
info_text->set_image (*item->image ());
|
||||
info_text->set_image (image);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2802,7 +2803,7 @@ MarkerBrowserPage::remove_snapshot_button_clicked ()
|
|||
if (selected_item->column () == 0) {
|
||||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
mp_database->set_item_image (i, 0);
|
||||
mp_database->set_item_image (i, QImage ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2830,7 +2831,7 @@ MarkerBrowserPage::snapshot_button_clicked ()
|
|||
const rdb::Item *i = list_model->item (selected_item->row ());
|
||||
if (i) {
|
||||
|
||||
mp_database->set_item_image (i, new QImage (mp_view->get_screenshot ()));
|
||||
mp_database->set_item_image (i, QImage (mp_view->get_screenshot ()));
|
||||
markers_list->selectionModel ()->setCurrentIndex (*selected_item, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
|
||||
update_info_text ();
|
||||
|
||||
|
|
@ -3125,8 +3126,8 @@ MarkerBrowserPage::info_anchor_clicked (const QUrl &link)
|
|||
|
||||
QModelIndex current = markers_list->selectionModel ()->currentIndex ();
|
||||
const rdb::Item *i = list_model->item (current.row ());
|
||||
if (i && i->image () != 0) {
|
||||
MarkerBrowserSnapshotView *snapshot_view = new MarkerBrowserSnapshotView (this, *i->image ());
|
||||
if (i && i->has_image ()) {
|
||||
MarkerBrowserSnapshotView *snapshot_view = new MarkerBrowserSnapshotView (this, i->image ());
|
||||
snapshot_view->exec ();
|
||||
delete snapshot_view;
|
||||
#if QT_VERSION < 0x040300
|
||||
|
|
|
|||
|
|
@ -808,16 +808,19 @@ Class<rdb::Item> decl_RdbItem ("rdb", "RdbItem",
|
|||
"@brief Sets the tags from a string\n"
|
||||
"@param tags A comma-separated list of tags\n"
|
||||
) +
|
||||
#if defined(HAVE_QT)
|
||||
gsi::method ("image_str", &rdb::Item::image_str,
|
||||
gsi::method ("has_image?", &rdb::Item::has_image,
|
||||
"@brief Gets a value indicating that the item has an image attached\n"
|
||||
"See \\image_str how to obtain the image.\n\n"
|
||||
"This method has been introduced in version 0.28.\n"
|
||||
) +
|
||||
gsi::method ("image_str", &rdb::Item::image_str,
|
||||
"@brief Gets the image associated with this item as a string\n"
|
||||
"@return A base64-encoded image file (usually in PNG format)\n"
|
||||
"@return A base64-encoded image file (in PNG format)\n"
|
||||
) +
|
||||
gsi::method ("image_str=", &rdb::Item::set_image_str, gsi::arg ("image"),
|
||||
"@brief Sets the image from a string\n"
|
||||
"@param image A base64-encoded image file (preferably in PNG format)\n"
|
||||
) +
|
||||
#endif
|
||||
/* Not supported yet:
|
||||
gsi::method ("multiplicity", &rdb::Item::multiplicity,
|
||||
"@brief Gets the item's multiplicity\n"
|
||||
|
|
|
|||
|
|
@ -821,15 +821,7 @@ Item &Item::operator= (const Item &d)
|
|||
m_visited = d.m_visited;
|
||||
m_multiplicity = d.m_multiplicity;
|
||||
m_tag_ids = d.m_tag_ids;
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
if (mp_image.get ()) {
|
||||
mp_image.reset (0);
|
||||
}
|
||||
if (d.mp_image.get ()) {
|
||||
mp_image.reset (new QImage (*d.mp_image));
|
||||
}
|
||||
#endif
|
||||
m_image_str = d.m_image_str;
|
||||
}
|
||||
|
||||
return *this;
|
||||
|
|
@ -952,48 +944,60 @@ Item::set_tag_str (const std::string &tags)
|
|||
|
||||
#if defined(HAVE_QT)
|
||||
void
|
||||
Item::set_image (QImage *image)
|
||||
Item::set_image (const QImage &image)
|
||||
{
|
||||
mp_image.reset (image);
|
||||
}
|
||||
if (image.isNull ()) {
|
||||
|
||||
m_image_str.clear ();
|
||||
|
||||
std::string
|
||||
Item::image_str () const
|
||||
{
|
||||
if (! mp_image.get ()) {
|
||||
return std::string ();
|
||||
} else {
|
||||
|
||||
QByteArray img_data;
|
||||
QBuffer img_io_device (&img_data);
|
||||
mp_image->save (&img_io_device, "PNG");
|
||||
image.save (&img_io_device, "PNG");
|
||||
|
||||
return std::string (img_data.toBase64 ().constData ());
|
||||
m_image_str = std::string (img_data.toBase64 ().constData ());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Item::set_image_str (const std::string &s)
|
||||
const QImage
|
||||
Item::image () const
|
||||
{
|
||||
if (s.empty ()) {
|
||||
set_image (0);
|
||||
if (m_image_str.empty ()) {
|
||||
|
||||
return QImage ();
|
||||
|
||||
} else {
|
||||
|
||||
QByteArray img_data (QByteArray::fromBase64 (QByteArray::fromRawData (s.c_str (), int (s.size ()))));
|
||||
QByteArray img_data (QByteArray::fromBase64 (QByteArray::fromRawData (m_image_str.c_str (), int (m_image_str.size ()))));
|
||||
|
||||
QImage *image = new QImage ();
|
||||
if (image->loadFromData (img_data)) {
|
||||
set_image (image);
|
||||
} else {
|
||||
delete image;
|
||||
set_image (0);
|
||||
}
|
||||
QImage image;
|
||||
image.loadFromData (img_data);
|
||||
return image;
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
Item::has_image () const
|
||||
{
|
||||
return !m_image_str.empty ();
|
||||
}
|
||||
|
||||
std::string
|
||||
Item::image_str () const
|
||||
{
|
||||
return m_image_str;
|
||||
}
|
||||
|
||||
void
|
||||
Item::set_image_str (const std::string &s)
|
||||
{
|
||||
m_image_str = s;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Database implementation
|
||||
|
||||
|
|
@ -1324,13 +1328,20 @@ Database::remove_item_tag (const Item *item, id_type tag)
|
|||
|
||||
#if defined(HAVE_QT)
|
||||
void
|
||||
Database::set_item_image (const Item *item, QImage *image)
|
||||
Database::set_item_image (const Item *item, const QImage &image)
|
||||
{
|
||||
set_modified ();
|
||||
const_cast <Item *> (item)->set_image (image);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
Database::set_item_image_str (const Item *item, const std::string &image_str)
|
||||
{
|
||||
set_modified ();
|
||||
const_cast <Item *> (item)->set_image_str (image_str);
|
||||
}
|
||||
|
||||
void
|
||||
Database::set_item_multiplicity (const Item *item, size_t n)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -941,35 +941,37 @@ public:
|
|||
|
||||
#if defined(HAVE_QT)
|
||||
/**
|
||||
* @brief Get the image object attached to this item
|
||||
* @brief Gets the image object attached to this item
|
||||
*
|
||||
* @return The image object or 0 if no object is attached
|
||||
* @return The image object or an empty image if no image is attached
|
||||
*/
|
||||
const QImage *image () const
|
||||
{
|
||||
return mp_image.get ();
|
||||
}
|
||||
const QImage image () const;
|
||||
|
||||
/**
|
||||
* @brief Set an image for this item
|
||||
*
|
||||
* The image object will become owned by the item
|
||||
* @brief Set the image for this item
|
||||
*/
|
||||
void set_image (QImage *image);
|
||||
void set_image (const QImage &image);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get an image as a string (base64 coded)
|
||||
* @brief Gets a value indicating whether the item has an image
|
||||
*/
|
||||
bool has_image () const;
|
||||
|
||||
/**
|
||||
* @brief Gets the image as a string (PNG, base64 coded)
|
||||
*
|
||||
* Note: if neither PNG support for Qt are compiled in, this string will be empty
|
||||
*/
|
||||
std::string image_str () const;
|
||||
|
||||
/**
|
||||
* @brief Get an image from a string (base64 coded)
|
||||
* @brief Gets the image from a string (PNG, base64 coded)
|
||||
*
|
||||
* If the image string is empty, the image will be cleared.
|
||||
* If the image string is not valid, the image will also be cleared.
|
||||
*/
|
||||
void set_image_str (const std::string &s);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get the database reference
|
||||
|
|
@ -998,9 +1000,7 @@ private:
|
|||
bool m_visited;
|
||||
std::vector <bool> m_tag_ids;
|
||||
Database *mp_database;
|
||||
#if defined(HAVE_QT)
|
||||
std::unique_ptr<QImage> mp_image;
|
||||
#endif
|
||||
std::string m_image_str;
|
||||
|
||||
Item ();
|
||||
|
||||
|
|
@ -2226,9 +2226,14 @@ public:
|
|||
/**
|
||||
* @brief Set the image of an item
|
||||
*/
|
||||
void set_item_image (const Item *item, QImage *image);
|
||||
void set_item_image (const Item *item, const QImage &image);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Set the image string of an item
|
||||
*/
|
||||
void set_item_image_str (const Item *item, const std::string &image_str);
|
||||
|
||||
/**
|
||||
* @brief Set the multiplicity of an item
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -106,9 +106,7 @@ make_rdb_structure (rdb::Database *rdb)
|
|||
tl::make_member<std::string, rdb::Item> (&rdb::Item::cell_qname, &rdb::Item::set_cell_qname, "cell") +
|
||||
tl::make_member<bool, rdb::Item> (&rdb::Item::visited, &rdb::Item::set_visited, "visited") +
|
||||
tl::make_member<size_t, rdb::Item> (&rdb::Item::multiplicity, &rdb::Item::set_multiplicity, "multiplicity") +
|
||||
#if defined(HAVE_QT)
|
||||
tl::make_member<std::string, rdb::Item> (&rdb::Item::image_str, &rdb::Item::set_image_str, "image") +
|
||||
#endif
|
||||
tl::make_element<rdb::Values, rdb::Item> (&rdb::Item::values, &rdb::Item::set_values, "values",
|
||||
tl::make_member<rdb::ValueWrapper, rdb::Values::const_iterator, rdb::Values> (&rdb::Values::begin, &rdb::Values::end, &rdb::Values::add, "value", ValueConverter (rdb))
|
||||
)
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ tl::InputStream *get_resource (const char *name)
|
|||
} else {
|
||||
auto stream = new tl::InputStream (rr.first);
|
||||
if (rr.second) {
|
||||
stream->inflate ();
|
||||
stream->inflate_always ();
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,8 +81,8 @@ TL_PUBLIC std::pair<tl::InputStreamBase *, bool> get_resource_reader (const char
|
|||
/**
|
||||
* @brief Get resource names matching a glob pattern
|
||||
*
|
||||
* For example, find_resources("/group/*") will find resources below "group".
|
||||
* "*" also matches "/", so resources from subgroups will be listed too.
|
||||
* For example, find_resources("/group*") will find resources whose name start with "group".
|
||||
* "*" also matches "/"!
|
||||
*/
|
||||
TL_PUBLIC std::vector<std::string> find_resources (const std::string &pattern);
|
||||
|
||||
|
|
|
|||
|
|
@ -143,8 +143,39 @@ public:
|
|||
// ---------------------------------------------------------------
|
||||
// InputStream implementation
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* @brief A dummy delegate to provide for the case of raw data stashed inside the stream itself
|
||||
*/
|
||||
class RawDataDelegate
|
||||
: public InputStreamBase
|
||||
{
|
||||
public:
|
||||
RawDataDelegate (const std::string &source)
|
||||
: m_source (source)
|
||||
{ }
|
||||
|
||||
virtual size_t read (char *, size_t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void reset () { }
|
||||
virtual void close () { }
|
||||
|
||||
virtual std::string source () const { return m_source; }
|
||||
virtual std::string absolute_path () const { return m_source; }
|
||||
virtual std::string filename () const { return m_source; }
|
||||
|
||||
public:
|
||||
std::string m_source;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
InputStream::InputStream (InputStreamBase &delegate)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (&delegate), m_owns_delegate (false), mp_inflate (0)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (&delegate), m_owns_delegate (false), mp_inflate (0), m_inflate_always (false)
|
||||
{
|
||||
m_bcap = 4096; // initial buffer capacity
|
||||
m_blen = 0;
|
||||
|
|
@ -152,7 +183,7 @@ InputStream::InputStream (InputStreamBase &delegate)
|
|||
}
|
||||
|
||||
InputStream::InputStream (InputStreamBase *delegate)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (delegate), m_owns_delegate (true), mp_inflate (0)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (delegate), m_owns_delegate (true), mp_inflate (0), m_inflate_always (false)
|
||||
{
|
||||
m_bcap = 4096; // initial buffer capacity
|
||||
m_blen = 0;
|
||||
|
|
@ -160,7 +191,7 @@ InputStream::InputStream (InputStreamBase *delegate)
|
|||
}
|
||||
|
||||
InputStream::InputStream (const std::string &abstract_path)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (0), m_owns_delegate (false), mp_inflate (0)
|
||||
: m_pos (0), mp_bptr (0), mp_delegate (0), m_owns_delegate (false), mp_inflate (0), m_inflate_always (false)
|
||||
{
|
||||
m_bcap = 4096; // initial buffer capacity
|
||||
m_blen = 0;
|
||||
|
|
@ -175,28 +206,30 @@ InputStream::InputStream (const std::string &abstract_path)
|
|||
#if defined(HAVE_QT)
|
||||
|
||||
QResource res (tl::to_qstring (abstract_path));
|
||||
if (res.size () > 0) {
|
||||
|
||||
QByteArray data;
|
||||
#if QT_VERSION >= 0x60000
|
||||
if (res.compressionAlgorithm () == QResource::ZlibCompression) {
|
||||
#else
|
||||
if (res.isCompressed ()) {
|
||||
#endif
|
||||
data = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
|
||||
} else {
|
||||
data = QByteArray ((const char *)res.data (), (int)res.size ());
|
||||
}
|
||||
|
||||
mp_buffer = new char[data.size ()];
|
||||
memcpy (mp_buffer, data.constData (), data.size ());
|
||||
|
||||
mp_bptr = mp_buffer;
|
||||
m_bcap = data.size ();
|
||||
m_blen = m_bcap;
|
||||
|
||||
if (res.size () == 0) {
|
||||
throw tl::Exception (tl::to_string (tr ("Resource not found: ")) + abstract_path);
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
#if QT_VERSION >= 0x60000
|
||||
if (res.compressionAlgorithm () == QResource::ZlibCompression) {
|
||||
#else
|
||||
if (res.isCompressed ()) {
|
||||
#endif
|
||||
data = qUncompress ((const unsigned char *)res.data (), (int)res.size ());
|
||||
} else {
|
||||
data = QByteArray ((const char *)res.data (), (int)res.size ());
|
||||
}
|
||||
|
||||
mp_buffer = new char[data.size ()];
|
||||
memcpy (mp_buffer, data.constData (), data.size ());
|
||||
|
||||
mp_bptr = mp_buffer;
|
||||
m_bcap = data.size ();
|
||||
m_blen = m_bcap;
|
||||
|
||||
mp_delegate = new RawDataDelegate (abstract_path);
|
||||
|
||||
#else
|
||||
|
||||
std::pair<tl::InputStreamBase *, bool> rr = tl::get_resource_reader (ex.get ());
|
||||
|
|
@ -240,7 +273,7 @@ InputStream::InputStream (const std::string &abstract_path)
|
|||
m_owns_delegate = true;
|
||||
|
||||
if (needs_inflate) {
|
||||
inflate ();
|
||||
inflate_always ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -441,6 +474,13 @@ InputStream::inflate ()
|
|||
mp_inflate = new tl::InflateFilter (*this);
|
||||
}
|
||||
|
||||
void
|
||||
InputStream::inflate_always ()
|
||||
{
|
||||
m_inflate_always = true;
|
||||
reset ();
|
||||
}
|
||||
|
||||
void
|
||||
InputStream::close ()
|
||||
{
|
||||
|
|
@ -468,6 +508,8 @@ InputStream::reset ()
|
|||
|
||||
} else {
|
||||
|
||||
tl_assert (mp_delegate != 0);
|
||||
|
||||
mp_delegate->reset ();
|
||||
m_pos = 0;
|
||||
|
||||
|
|
@ -481,6 +523,10 @@ InputStream::reset ()
|
|||
mp_buffer = new char [m_bcap];
|
||||
|
||||
}
|
||||
|
||||
if (m_inflate_always) {
|
||||
inflate ();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -466,6 +466,15 @@ public:
|
|||
*/
|
||||
void inflate ();
|
||||
|
||||
/**
|
||||
* @brief Enables "inflate" right from the beginning
|
||||
*
|
||||
* Contrary to "inflate" (which is temporary), this version enables
|
||||
* decompression right from the beginning of the file. It does a "reset"
|
||||
* implicitly.
|
||||
*/
|
||||
void inflate_always ();
|
||||
|
||||
/**
|
||||
* @brief Obtain the current file position
|
||||
*/
|
||||
|
|
@ -557,6 +566,7 @@ private:
|
|||
|
||||
// inflate support
|
||||
InflateFilter *mp_inflate;
|
||||
bool m_inflate_always;
|
||||
|
||||
// No copying currently
|
||||
InputStream (const InputStream &);
|
||||
|
|
|
|||
|
|
@ -607,6 +607,14 @@ main_cont (int &argc, char **argv)
|
|||
tl::set_continue_flag (continue_flag);
|
||||
tl::set_debug_mode (debug_mode);
|
||||
|
||||
// set some global variables
|
||||
if (rba::RubyInterpreter::instance ()) {
|
||||
rba::RubyInterpreter::instance ()->define_variable ("ut_inst_path", tl::get_inst_path ());
|
||||
}
|
||||
if (pya::PythonInterpreter::instance ()) {
|
||||
pya::PythonInterpreter::instance ()->define_variable ("ut_inst_path", tl::get_inst_path ());
|
||||
}
|
||||
|
||||
FILE *output_file = 0;
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ load("test_prologue.rb")
|
|||
class Buddies_TestClass < TestBase
|
||||
|
||||
def buddy_bin(name)
|
||||
file = File.join(RBA::Application::instance.inst_path, name)
|
||||
file = File.join($ut_inst_path, name)
|
||||
return file
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ class DBGlyph_TestClass < TestBase
|
|||
tg.load_from_resource(":/fonts/does_not_exist.gds")
|
||||
assert_equal(false, true)
|
||||
rescue => ex
|
||||
assert_equal(ex.to_s, "Unable to load font resource from :/fonts/does_not_exist.gds in TextGenerator::load_from_resource")
|
||||
assert_equal(ex.to_s, "Resource not found: :/fonts/does_not_exist.gds in TextGenerator::load_from_resource")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue