yagf-0.9.2.1/0000775000175000017500000000000012250673416013337 5ustar parallelsparallelsyagf-0.9.2.1/README0000664000175000017500000000046612247205425014222 0ustar parallelsparallelsFor more information and system requirements see DESCRIPTION file. This is a beta version so many things are not yet implemented as they are supposed to. The main things to do are - adding more image prepocessing features - adding packet recognition Contributors are welcome. Contact me via anb@symmetrica.net.yagf-0.9.2.1/src/0000775000175000017500000000000012250673434014126 5ustar parallelsparallelsyagf-0.9.2.1/src/spellchecker.cpp0000664000175000017500000002063612250140707017275 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include #include #include #include #include #include #include #include "spellchecker.h" SpellChecker::SpellChecker(QTextEdit *textEdit): m_textEdit(textEdit) { m_regExp = new QRegExp("[^\\s]*"); //m_cursor= new QTextCursor(m_textEdit->document()); spell_config1 = new_aspell_config(); spell_config2 = new_aspell_config(); aspell_config_replace(spell_config1, "lang", m_lang1.toAscii()); aspell_config_replace(spell_config2, "lang", m_lang2.toAscii()); aspell_config_replace(spell_config1, "encoding", "utf-8"); aspell_config_replace(spell_config2, "encoding", "utf-8"); m_map = new StringMap(); m_map->insert("ruseng", "ru"); m_map->insert("rus", "ru"); m_map->insert("bul", "bg"); m_map->insert("cze", "cs"); m_map->insert("dan", "da"); m_map->insert("dut", "nl"); m_map->insert("ell", "el"); m_map->insert("eng", "en"); m_map->insert("est", "et"); m_map->insert("fin", "fi"); m_map->insert("fra", "fr"); m_map->insert("ger", "de"); m_map->insert("gerf", "de-alt"); m_map->insert("heb", "he"); m_map->insert("hrv", "hr"); m_map->insert("hun", "hu"); m_map->insert("ita", "it"); m_map->insert("lav", "lv"); m_map->insert("lit", "lt"); m_map->insert("nor", "no"); m_map->insert("pol", "pl"); m_map->insert("por", "pt_PT"); m_map->insert("rum", "ro"); m_map->insert("slo", "sl"); m_map->insert("slk", "sk"); m_map->insert("spa", "es"); m_map->insert("srp", "sr"); m_map->insert("swe", "sv"); m_map->insert("swef", "sv"); m_map->insert("tur", "tr"); m_map->insert("ukr", "uk"); spell_checker1 = 0; spell_checker2 = 0; setLanguage("ruseng"); dictList = new QStringList(); } void SpellChecker::enumerateDicts() { AspellConfig *config; AspellDictInfoList *dlist; AspellDictInfoEnumeration *dels; const AspellDictInfo *entry; config = new_aspell_config(); /* the returned pointer should _not_ need to be deleted */ dlist = get_aspell_dict_info_list(config); /* config is no longer needed */ delete_aspell_config(config); dels = aspell_dict_info_list_elements(dlist); while ((entry = aspell_dict_info_enumeration_next(dels)) != 0) { dictList->append(entry->code); } delete_aspell_dict_info_enumeration(dels); } bool SpellChecker::hasDict(const QString &shname) { return dictList->contains(m_map->value(shname)); } SpellChecker::~SpellChecker() { delete m_regExp; delete m_map; delete_aspell_speller(spell_checker1); delete_aspell_speller(spell_checker2); delete_aspell_config(spell_config1); delete_aspell_config(spell_config2); delete dictList; } void SpellChecker::setLanguage(const QString &lang) { delete_aspell_speller(spell_checker1); delete_aspell_speller(spell_checker2); bad_language.clear(); m_lang2 = "en"; m_lang1 = m_map->value(lang, QString("en")); if (lang == "rus_fra") { m_lang1 = "ru"; m_lang2 = "fr"; } else if (lang == "rus_ger") { m_lang1 = "ru"; m_lang2 = "de"; } else if (lang == "rus_spa") { m_lang1 = "ru"; m_lang2 = "es"; } aspell_config_replace(spell_config1, "lang", m_lang1.toAscii()); aspell_config_replace(spell_config2, "lang", m_lang2.toAscii()); AspellCanHaveError *possible_err = new_aspell_speller(spell_config1); spell_checker1 = 0; if (aspell_error_number(possible_err) == 0) spell_checker1 = to_aspell_speller(possible_err); else delete_aspell_can_have_error(possible_err); possible_err = new_aspell_speller(spell_config2); spell_checker2 = 0; if (aspell_error_number(possible_err) == 0) spell_checker2 = to_aspell_speller(possible_err); else delete_aspell_can_have_error(possible_err); // Check absent dictionary if (spell_checker1 == 0) bad_language = m_lang1; if (spell_checker2 == 0) bad_language = m_lang2; } bool SpellChecker::spellCheck() { if ((spell_checker1 == 0) || (spell_checker2 == 0)) { QPixmap icon; icon.load(":/warning.png"); QMessageBox messageBox(QMessageBox::NoIcon, "YAGF", QObject::trUtf8("Required spelling dictionary (%1) is not found.\nSpell-checking is disabled.\nTry to install an appropriate aspell dictionary.").arg(bad_language), QMessageBox::Ok, 0); messageBox.setIconPixmap(icon); messageBox.exec(); return false; } QTextCursor cursor(m_textEdit->document()); while (!cursor.isNull() && !cursor.atEnd()) { _checkWord(&cursor); QTextCursor oldc = cursor; if (!cursor.movePosition(QTextCursor::NextWord, QTextCursor::MoveAnchor)) break; //cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::MoveAnchor); //cursor = m_textEdit->document()->find(*m_regExp, cursor); int oldpos = oldc.position(); int newpos = cursor.position(); if (abs(newpos - oldpos) < 3) cursor.setPosition(newpos + 1); } if (!cursor.isNull()) _checkWord(&cursor); return true; } void SpellChecker::unSpellCheck() { QTextCursor cursor(m_textEdit->document()); QTextCharFormat fmt = cursor.charFormat(); fmt.setUnderlineStyle(QTextCharFormat::NoUnderline); cursor.select(QTextCursor::Document); cursor.setCharFormat(fmt); cursor.clearSelection(); } void SpellChecker::_checkWord(QTextCursor *cursor) { cursor->select(QTextCursor::WordUnderCursor); QString selText = cursor->selectedText(); static const QRegExp nonDigits("\\D"); if (!selText.contains(nonDigits)) return; selText = selText.remove(QString::fromUtf8("«")); selText = selText.remove(QString::fromUtf8("»")); //selText = selText.remove("\""); //selText = selText.remove("("); //selText = selText.remove(")"); QByteArray ba = selText.toUtf8(); if ((aspell_speller_check(spell_checker1, ba.data(), ba.size()) == 0) && (aspell_speller_check(spell_checker2, ba.data(), ba.size()) == 0)) { QTextCharFormat fmt = cursor->charFormat(); fmt.setUnderlineColor(QColor(Qt::red)); fmt.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline); cursor->setCharFormat(fmt); } else { QTextCharFormat fmt = cursor->charFormat(); fmt.setUnderlineStyle(QTextCharFormat::NoUnderline); cursor->setCharFormat(fmt); } cursor->clearSelection(); } void SpellChecker::checkWord() { if ((spell_checker1 == 0) || (spell_checker2 == 0)) return; QTextCursor cursor = m_textEdit->textCursor(); _checkWord(&cursor); } QStringList SpellChecker::suggestions() { QStringList sl; if ((spell_checker1 == 0) || (spell_checker2 == 0)) return sl; QTextCursor cursor = m_textEdit->textCursor(); cursor.select(QTextCursor::WordUnderCursor); QString word = cursor.selectedText(); QByteArray ba = word.toUtf8(); if ((aspell_speller_check(spell_checker2, ba.data(), ba.size()) != 0)||(aspell_speller_check(spell_checker1, ba.data(), ba.size()) != 0)) return sl; const struct AspellWordList * awl = aspell_speller_suggest(spell_checker1, ba.data(), ba.size()); if(aspell_word_list_size(awl) > 0) { struct AspellStringEnumeration * ase = aspell_word_list_elements(awl); int i = 0; while ((!aspell_string_enumeration_at_end(ase))&&(i < 10)) { const char * text = aspell_string_enumeration_next(ase); sl << QString::fromUtf8(text); i++; } delete_aspell_string_enumeration(ase); } return sl; } yagf-0.9.2.1/src/popplerdialog.ui0000664000175000017500000001564112247205425017332 0ustar parallelsparallels PopplerDialog 0 0 320 252 Import from PDF :/images/application_pdf.png:/images/application_pdf.png File Name 1 0 Select... Pages 2 From spinBox 1 1 1 999 12 2 4 2 To spinBox_2 0 0 1 999 Qt::Horizontal 40 20 0 1 Entire Document Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox rejected() PopplerDialog reject() 316 260 286 274 buttonBox accepted() PopplerDialog accept() 248 254 157 274 yagf-0.9.2.1/src/tpagecollection.cpp0000664000175000017500000001763612250140707020013 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "tpagecollection.h" #include "qsnippet.h" #ifdef TIFF_IO #include "qxttiffiohandler.h" #endif #include "settings.h" #include #include #include PageCollection * PageCollection::m_instance = NULL; PageCollection::PageCollection(QObject *parent) : QObject(parent) { index = -1; pid = 0; } PageCollection::PageCollection(const PageCollection &) { } PageCollection::~PageCollection() { clear(); } bool PageCollection::appendPage(const QString &fileName) { #ifdef TIFF_IO if (fileName.endsWith(".tif", Qt::CaseInsensitive) || fileName.endsWith(".tiff", Qt::CaseInsensitive)) { QXtTiffIOHandler * toh = new QXtTiffIOHandler(); QFile f(fileName); f.open(QIODevice::ReadOnly); toh->setDevice(&f); if (toh->canRead()) { if (toh->imageCount() == 1) { delete toh; appendPage(fileName); return true; } else { for (int i = 0; i < toh->imageCount(); i++) { QImage img; toh->jumpToImage(i); toh->read(&img); QString nfn = Settings::instance()->workingDir() + QString("tiff-page-%1.jpg").arg(i+1); img.save(nfn, "JPEG"); appendPage(nfn); QApplication::processEvents(); } delete toh; return true; } } else return false; } else #endif // TIFF_IO { Page * p = new Page(++pid); connect(p,SIGNAL(refreshView()), this, SIGNAL(loadPage())); if (p->loadFile(fileName)) { pages.append(p); index = pages.count() - 1; emit addSnippet(index); return true; } else return false; } } int PageCollection::count() { return pages.count(); } bool PageCollection::makePageCurrent(int index) { this->index = index; return index < pages.count(); } bool PageCollection::makePageCurrentByID(int id) { return makePageCurrent(id2Index(id)) >= 0; } void PageCollection::setBeforeFirst() { index = -1; } bool PageCollection::makeNextPageCurrent() { index++; if (index < count()) return true; index = -1; return false; } QSnippet *PageCollection::snippet() { if (!cp()) return NULL; QSnippet * s = new QSnippet(); s->setPage(cp()->pageID(), cp()->fileName(), cp()->thumbnail()); return s; } QPixmap PageCollection::pixmap() { if (!cp()) return QPixmap(); return cp()->displayPixmap(); } void PageCollection::savePageForRecognition(const QString &fileName) { if (!cp()) return; cp()->savePageForRecognition(fileName); } void PageCollection::saveRawBlockForRecognition(QRect r, const QString &fileName) { if (!cp()) return; cp()->saveRawBlockForRecognition(r, fileName); } void PageCollection::saveBlockForRecognition(QRect r, const QString &fileName, const QString &format) { if (!cp()) return; cp()->saveBlockForRecognition(r, fileName, format); } void PageCollection::saveBlockForRecognition(int index, const QString &fileName) { if (!cp()) return; if (index == 0) cp()->sortBlocksInternal(); cp()->saveBlockForRecognition(index, fileName); } int PageCollection::blockCount() { if (!cp()) return 0; return cp()->blockCount(); } Block PageCollection::getBlock(const QRect &r) { Block block(0,0,0,0); if (!cp()) return block; return cp()->getBlock(r); } Block PageCollection::getBlock(int index) { Block block(0,0,0,0); if (!cp()) return block; return cp()->getBlock(index); } void PageCollection::selectBlock(const QRect &r) { if (!cp()) return; cp()->selectBlock(r); } Block PageCollection::getSelectedBlock() { Block block(0,0,0,0); if (!cp()) return block; return cp()->getSelectedBlock(); } bool PageCollection::pageValid() { return cp() != 0; } QString PageCollection::fileName() { if (!cp()) return ""; return cp()->fileName(); } bool PageCollection::savePageAsImage(const QString &fileName, const QString &format) { if (!cp()) return false; return cp()->savePageAsImage(fileName, format); } bool PageCollection::isDeskewed() { if (cp()) return cp()->isDeskewed(); return false; } bool PageCollection::isPreprocessed() { if (cp()) return cp()->isPreprocessed(); return false; } qreal PageCollection::getRotation() { if (cp()) return cp()->getRotation(); return 0; } void PageCollection::setRotation(const qreal value) { if (cp()) cp()->rotate(value); } void PageCollection::setDeskewed(const bool value) { if (cp()) cp()->setDeskewed(value); } void PageCollection::setPreprocessed(const bool value) { if (cp()) cp()->setPreprocessed(value); } void PageCollection::reloadPage() { emit loadPage(); } void PageCollection::makeLarger() { if (!cp()) return; cp()->makeLarger(); emit loadPage(); } void PageCollection::makeSmaller() { if (!cp()) return; cp()->makeSmaller(); emit loadPage(); } void PageCollection::rotate90CW() { if (!cp()) return; cp()->rotate90CW(); emit loadPage(); } void PageCollection::rotate90CCW() { if (!cp()) return; cp()->rotate90CCW(); emit loadPage(); } void PageCollection::rotate180() { if (!cp()) return; cp()->rotate180(); emit loadPage(); } void PageCollection::deskew() { if (!cp()) return; cp()->deskew(); emit loadPage(); } void PageCollection::blockAllText() { if (!cp()) return; cp()->blockAllText(); emit loadPage(); } bool PageCollection::splitPage(bool preprocess) { if (!cp()) return false; bool res = cp()->splitPage(preprocess); emit loadPage(); return res; } void PageCollection::addBlock(const QRect &rect) { if (!cp()) return; Block block(rect.x(), rect.y(), rect.width(), rect.height()); cp()->addBlock(block); } void PageCollection::deleteBlock(const QRect &rect) { if (!cp()) return; cp()->deleteBlock(rect); } void PageCollection::clearBlocks() { if (!cp()) return; cp()->clearBlocks(); } void PageCollection::clear() { foreach (Page * p, pages) { delete p; } pages.clear(); emit cleared(); index = -1; pid = 0; } Page *PageCollection::cp() { if ((index < 0)|| (index >= count())) return (Page*) 0; return pages.at(index); } int PageCollection::id2Index(int id) { foreach (Page *p, pages) { if (p->pageID() == id) return pages.indexOf(p); } return -1; } void PageCollection::pageSelected(int id) { makePageCurrent(id2Index(id)); emit loadPage(); } void PageCollection::pageRemoved(int id) { int index = id2Index(id); if (index >= 0) { delete pages.at(index); pages.remove(index); } if (index >= pages.count()) index = pages.count() - 1; makePageCurrent(index); emit loadPage(); } PageCollection *PageCollection::instance() { if (!m_instance) m_instance = new PageCollection(); return m_instance; } void PageCollection::clearCollection() { if (m_instance) m_instance->clear(); } yagf-0.9.2.1/src/pdfextractor.cpp0000664000175000017500000001146112247205425017337 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "pdfextractor.h" #include #include #include #include #include #include #include class PDFThread : public QThread { public: explicit PDFThread(PDFExtractor * parent) : QThread() { mparent = parent; } virtual void run() { QProcess process; // connect(this, SIGNAL(finished()), mparent, SIGNAL(finished()), Qt::QueuedConnection); // connect(this, SIGNAL(terminated()), mparent, SIGNAL(finished()), Qt::QueuedConnection); connect(mparent, SIGNAL(terminate()), this, SLOT(terminate())); connect (mparent, SIGNAL(killProcess()), &process, SLOT(kill()), Qt::QueuedConnection); connect (mparent, SIGNAL(terminateProcess()), &process, SLOT(terminate()), Qt::QueuedConnection); process.start(command, arguments); process.waitForFinished(1600000); } void setProcess(const QString &cmd, const QStringList &args) { command = cmd; arguments.clear(); arguments.append(args); } private: QString command; QStringList arguments; PDFExtractor * mparent; }; PDFExtractor::PDFExtractor(QObject *parent) : QObject(parent) { } void PDFExtractor::setCommandStringPaged(const QString &cmdStr) { commandStringPaged = cmdStr; } void PDFExtractor::setCommandStringEntire(const QString &cmdStr) { commandStringEntire = cmdStr; } void PDFExtractor::setOutputDir(const QString &value) { outputDir = value; } QString PDFExtractor::getOutputDir() { return outputDir; } void PDFExtractor::setOutputExtension(const QString &value) { outputExtension = value; } QString PDFExtractor::getOutputExtension() { return outputExtension; } void PDFExtractor::setOutputPrefix(const QString &value) { outputPrefix = value; } QString PDFExtractor::getOutputPrefix() { return outputPrefix; } void PDFExtractor::setResolution(const QString &value) { resolution = value; } QString PDFExtractor::getResolution() { return resolution; } void PDFExtractor::setSourcePDF(const QString &value) { sourcePDF = value; } QString PDFExtractor::getSourcePDF() { return sourcePDF; } void PDFExtractor::setStartPage(const QString &value) { startPage = value; } QString PDFExtractor::getStartPage() { return startPage; } void PDFExtractor::setStopPage(const QString &value) { stopPage = value; } QString PDFExtractor::getStopPage() { return stopPage; } void PDFExtractor::cancel() { emit killProcess(); emit terminateProcess(); emit terminate(); } void PDFExtractor::execInternal(const QString &command, const QStringList &arguments) { canceled = false; filters.clear(); filters << QString("page*.%1").arg(getOutputExtension()); PDFThread thread(this); thread.setProcess(command, arguments); thread.start(); lastPage = 0; while (!thread.isFinished()) { QDir dir; dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setSorting(QDir::Size | QDir::Reversed); dir.setSorting(QDir::Name); dir.setPath(outputDir); QFileInfoList fil; fil = dir.entryInfoList(filters, QDir::Files, QDir::Name); int lastI = 0; for (int i =lastPage; i < fil.count() - 1; i++) { emit addPage(fil.at(i).absoluteFilePath()); lastI = i; QApplication::processEvents(); } lastPage = lastI; } QDir dir; dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks); dir.setSorting(QDir::Size | QDir::Reversed); dir.setSorting(QDir::Name); dir.cd(outputDir); QFileInfoList fil; fil = dir.entryInfoList(filters, QDir::Files, QDir::Name); for (int i = 0; i < fil.count(); i++) { emit addPage(fil.at(i).absoluteFilePath()); QApplication::processEvents(); } emit finished(); } yagf-0.9.2.1/src/forcelocaledialog.cpp0000600000175000017500000000414712250171445020257 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "forcelocaledialog.h" #include "ui_forcelocaledialog.h" ForceLocaleDialog::ForceLocaleDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ForceLocaleDialog) { ui->setupUi(this); this->setWindowTitle("Choose UI Language"); ui->groupBox->setTitle("Choose Language"); ui->radioButton->setText("English"); ui->radioButton_2->setText("Russian"); ui->radioButton_3->setText("Defined by locale"); ui->label->setText("Restart the program for the changes to take effect"); ui->buttonBox->buttons()[1]->setText("&Cancel"); ui->buttonBox->buttons()[0]->setText("&OK"); } ForceLocaleDialog::~ForceLocaleDialog() { delete ui; } void ForceLocaleDialog::setOption(Locales option) { switch(option) { case ForceLocaleDialog::NoLocale: ui->radioButton->setChecked(true); break; case ForceLocaleDialog::RussianLocale: ui->radioButton_2->setChecked(true); break; case ForceLocaleDialog::DefaultLocale: ui->radioButton_3->setChecked(true); break; default: break; } } ForceLocaleDialog::Locales ForceLocaleDialog::getOption() { if (ui->radioButton->isChecked()) return ForceLocaleDialog::NoLocale; if (ui->radioButton_2->isChecked()) return ForceLocaleDialog::RussianLocale; return ForceLocaleDialog::DefaultLocale; } yagf-0.9.2.1/src/qsnippet.cpp0000664000175000017500000000247112247205425016476 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "qsnippet.h" QSnippet::QSnippet(QListWidget *parent) : QListWidgetItem(parent) { } bool QSnippet::setPage(int id, const QString &name, const QImage &image) { if (image.isNull()) { QImage img(name); if (img.isNull()) return false; setIcon(QPixmap::fromImage(img)); } else setIcon(QPixmap::fromImage(image)); this->name = name; setToolTip(name); pid = id; return true; } QString QSnippet::getName() { return name; } int QSnippet::pageID() { return pid; } yagf-0.9.2.1/src/CCAnalysis.cpp0000664000175000017500000001414112247205425016621 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "CCAnalysis.h" #include #include RotationCropper::RotationCropper(QImage * image, QRgb color, int dtr) { this->image = image; darksCount = 0; lightsCount = 0; minval = 0; maxval = 0; //clAltCount = 0; darktr = dtr; whitetr = 650; clBrighttoWidthtr = 0.1; //QRgb * line = (QRgb *) image->scanLine(0); whitePixel = color; //replaceColor = color; } RotationCropper::~RotationCropper() {} QRect RotationCropper::crop() { y1 = 0; int tolerance = 3; recolor(); for (int y = 0; y < image->height(); y ++) { if (checkHorzLine(y)) { tolerance--; if (tolerance == 0) { y1 = y; break; } } else tolerance = 3; } y2 = image->height()-1; tolerance = 3; for (int y = y2; y >= 0; y--) { if (checkHorzLine(y)) { tolerance--; if (tolerance == 0) { y2 = y; break; } } else tolerance = 3; } x1 = 0; tolerance = 3; for (int x = x1; x < image->width(); x++) { if (checkVertLine(x)) { tolerance--; if (tolerance == 0) { x1 = x; break; } } else tolerance = 3; } x2 = image->width()-1; tolerance = 3; for (int x = x2; x >= 0; x--) { if (checkVertLine(x)) { tolerance--; if (tolerance == 0) { x2 = x; break; } } else tolerance = 3; } return QRect(x1, y1, x2-x1, y2-y1); } void RotationCropper::recolor() { QColor repColor(1,2,3); for (int y = 0; y < image->height(); y++) { QRgb * line = (QRgb *) image->scanLine(y); for (int x = 0; x < image->width(); x++) { if (line[x] == whitePixel ) line[x] = repColor.rgb(); else break; } for (int x = image->width() - 1; x >= 0; x--) { if (line[x] == whitePixel ) line[x] = repColor.rgb(); else break; } } } bool RotationCropper::checkHorzLine(int y) { int skipCount = 0; darksCount = 0; lightsCount = 0; minval = 800; maxval = 0; whitesCount = 0; //clAltCount = 0; whiteAlt = 0; //int maxlstripe = 0; //int currentlstripe = 0; QRgb * line = (QRgb *) image->scanLine(y); for (int i = 0; i < image->width(); i++) { if ((qRed(line[i]) == 1) && (qGreen(line[i]) == 2) && (qBlue(line[i]) == 3)) { skipCount++; continue; } int pixel = qRed(line[i]) + qGreen(line[i]) + qBlue(line[i]); if (pixel <= darktr) { darksCount++; // if (currentlstripe > maxlstripe) maxlstripe = currentlstripe; // currentlstripe = 0; } else { lightsCount++; // currentlstripe++; if (pixel >= whitetr) { whitesCount++; if (whiteAlt == 0) { whiteAlt = 1; clWhiteCount++; } } else whiteAlt = 0; } minval = pixel < minval ? pixel : minval; maxval = pixel > maxval ? pixel : maxval; } qreal d = image->width() - skipCount; if (d == 0) return false; clBrighttoWidth = (qreal)lightsCount/d; if (clBrighttoWidth <= clBrighttoWidthtr) return false; if (maxval - minval < 40) return false; //if (clAltCount < 10) // return false; //if (maxlstripe < 10) // return false; // if ((clWhiteCount > 0)&&(clWhiteCount < 3)) // return false; return true; } bool RotationCropper::checkVertLine(int x) { int skipCount = 0; darksCount = 0; lightsCount = 0; minval = 800; maxval = 0; whitesCount = 0; //clAltCount = 0; whiteAlt = 0; //int curline =0; for (int y = 0; y < image->height(); y++) { QRgb * line = (QRgb *) image->scanLine(y); if ((qRed(line[x]) == 1) && (qGreen(line[x]) == 2) && (qBlue(line[x]) == 3)) { skipCount++; continue; } int pixel = qRed(line[x]) + qGreen(line[x]) + qBlue(line[x]); if (pixel <= darktr) { darksCount++; // if (curline) { // clAltCount++; // curline = 0; // } } else { lightsCount++; // if (!curline) { // clAltCount++; // curline = 1; // } if (pixel >= whitetr) { whitesCount++; if (whiteAlt == 0) { whiteAlt = 1; clWhiteCount++; } } else whiteAlt = 0; } minval = pixel < minval ? pixel : minval; maxval = pixel > maxval ? pixel : maxval; } qreal d = image->height() - skipCount; if (d == 0) return false; clBrighttoWidth = (qreal)lightsCount/d; if (clBrighttoWidth <= clBrighttoWidthtr) return false; if (maxval - minval < 40) return false; // if (clAltCount < 10) // return false; if ((clWhiteCount > 0)&&(clWhiteCount < 3)) return false; return true; } yagf-0.9.2.1/src/ycommon.h0000664000175000017500000000213112247205425015752 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef YCOMMMON_H #define YCOMMMON_H #include #include #include #include typedef QList QPointList; inline QRect QRectF2Rect(const QRectF &rf) { QRect r; r.setX(rf.x()); r.setY(rf.y()); r.setWidth(rf.width()); r.setHeight(rf.height()); return r; } #endif yagf-0.9.2.1/src/main.cpp0000775000175000017500000000514112250171073015552 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include #include #include #include #include #include "mainform.h" #include "settings.h" void parseCmdLine(const QStringList &args) { foreach (const QString &arg, args){ if (arg == "-h" || arg == "--help") { printf("Using:\n" " yagf\n" " yagf \n" " yagf [file name [file name]...]\n" "YAGF is a graphical interface for cuneiform and tesseract.\n" "\n" "Keys:\n" " -h, --help\t Show this message and exit\n" " -V, --version\t Show version string and exit\n"); exit(0); } else if (arg == "-V" || arg == "--version") { printf("YAGF version: %s\n", version.toUtf8().constData()); exit(0); } } } int main(int argc, char *argv[]) { QApplication app(argc, argv); parseCmdLine(app.arguments()); Settings * settings = Settings::instance(); settings->readSettings(settings->workingDir()); settings->writeSettings(); QTranslator translator; QString qmName = "yagf_" + QLocale::system().name(); if (settings->useRussianLocale()) qmName = "yagf_ru"; if (!settings->useNoLocale()) { translator.load(qmName, QString(QML_INSTALL_PATH)); app.installTranslator(&translator); settings->makeLanguageMaps(); } QTranslator translator2; if (settings->useRussianLocale()) translator2.load("qt_ru_RU", QLibraryInfo::location(QLibraryInfo::TranslationsPath)); else translator2.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)); if (!settings->useNoLocale()) app.installTranslator(&translator2); MainForm window; window.show(); return app.exec(); } yagf-0.9.2.1/src/tblock.cpp0000664000175000017500000000300012250140707016071 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "tblock.h" Block::Block(int x, int y, int width, int height) : QRect(x, y, width, height) { number = -1; language = "default"; } Block::Block(const QRect &r) : QRect(r.x(), r.y(), r.width(), r.height()) { number = -1; } int Block::blockNumber() { return number; } void Block::setBlockNumber(const int value) { number = value; } void Block::setLanguage(const QString &lang) { language = lang; } QString Block::getLanguage() { return language; } bool rectLessThan(const QRect &r1, const QRect &r2) { if (r1.y() < r2.y()) return true; if (r1.x() < r2.x()) return true; return false; } void sortBlocks(TBlocks &blocks) { qSort(blocks.begin(), blocks.end(), rectLessThan); } yagf-0.9.2.1/src/advancedconfigdialog.h0000664000175000017500000000225212250140707020403 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef ADVANCEDCONFIGDIALOG_H #define ADVANCEDCONFIGDIALOG_H #include namespace Ui { class AdvancedConfigDialog; } class AdvancedConfigDialog : public QDialog { Q_OBJECT public: explicit AdvancedConfigDialog(QWidget *parent = 0); ~AdvancedConfigDialog(); bool doCrop1(); void setCrop1(const bool value); private: Ui::AdvancedConfigDialog *ui; }; #endif // ADVANCEDCONFIGDIALOG_H yagf-0.9.2.1/src/ghostscr.cpp0000664000175000017500000000320212247205425016460 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "ghostscr.h" #include #include GhostScr::GhostScr() : PDFExtractor() { } void GhostScr::exec() { QString command = "gs"; QStringList args; args << "-SDEVICE=jpeg" << "-r1200x1200" << "-sPAPERSIZE=letter" << "-dNOPAUSE" << "-dBATCH"; if ((!getStopPage().isEmpty()) || (getStopPage().toInt() > 0)) { if (getStartPage().toInt() == 0) this->setStartPage("1"); args << QString("-dFirstPage=").append(getStartPage()) << QString("-dLastPage=").append(getStopPage()); } if (!getOutputDir().endsWith("/")) setOutputDir(getOutputDir().append('/')); setOutputPrefix(getOutputDir().append("page")); args << QString("-sOutputFile=").append(getOutputPrefix()).append("_%04d.jpg"); args << "--" << this->getSourcePDF(); setOutputExtension("jpg"); execInternal(command, args); } yagf-0.9.2.1/src/configdialog.h0000664000175000017500000000234212247205425016722 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef CONFIGDIALOG_H #define CONFIGDIALOG_H #include namespace Ui { class ConfigDialog; } class ConfigDialog : public QDialog { Q_OBJECT public: explicit ConfigDialog(QWidget *parent = 0); ~ConfigDialog(); void setSelectedEngine(int value); int selectedEngine(); void setTessDataPath(const QString &value); //"" - find yourself QString tessdataPath(); private: Ui::ConfigDialog *ui; }; #endif // CONFIGDIALOG_H yagf-0.9.2.1/src/utils.h0000664000175000017500000000214112247205425015432 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef UTILS_H #define UTILS_H class QString; QString extractFileName(const QString &path); QString extractFilePath(const QString &path); QString extractDigits(const QString &fn); bool findProgram(const QString &name); inline bool _contains(qreal x1, qreal x2, qreal xc) { return ((xc >= x1) && (xc <= x2)) || ((xc <= x1) && (xc >= x2)); } #endif yagf-0.9.2.1/src/yagf.qrc0000775000175000017500000000424112247701361015564 0ustar parallelsparallels images/rcw.png images/rccw.png images/revert.png images/select.png images/smaller.png images/larger.png images/singlecolumn.png images/yagf.png images/back.png images/document_open.png images/document_save_as.png images/editcopy.png images/filefind.png images/fileopen.png images/filesaveas.png images/forward.png images/scanner.png images/warning.png images/critical.png images/info.png images/resize.png images/resize_block.png images/save_all.png images/editclear.png images/batch.png images/remove.png images/align.png images/undo.png images/scanner_s2.png images/recblocks.png images/trashcan1s.png images/trashcan2-s.png images/check_spelling.png images/savpicas.png images/saveblock.png images/deskew2.png images/stock_new_html.png images/application_pdf.png images/trashcan_full.png images/clearblocks.png images/selecttext.png images/edit_paste.png images/scanner48.png images/selectmulti.png images/tools_wizard.png images/tools_wizard_small.png yagf-0.9.2.1/src/analysis.h0000664000175000017500000000557012247205425016126 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef ANALYSIS_H #define ANALYSIS_H #include "ccbuilder.h" #include //#include #include #include #include #include typedef struct _Rect { qint32 x1, x2, y1, y2; int dotCount; } Rect; bool operator==(Rect r1, Rect r2); typedef QHash ComponentParameters; typedef QList Strings; typedef QList StringsBoxes; typedef QMultiHash GlyphField; typedef struct ginfo { ginfo(int a1, int a2, int a3); int h; int x; int y; } GlyphInfo; bool operator==(GlyphInfo g1, GlyphInfo g2); typedef QList TextLine; typedef QMultiHash LineField; typedef QList Lines; typedef QList Bars; const int BarRatio = 24; class CCAnalysis : public QObject { public: CCAnalysis(CCBuilder * builder); ~CCAnalysis(); bool analize(bool extractBars = false); Bars addBars(); TextLine extractLine(); int getGlyphCount(); QList getGlyphs(); int getMediumGlyphHeight(); int getMediumGlyphWidth(); int getMediumLetterSpace(); int getMediumWordSpace(); int getStringsCount(); int getGlyphBoxCount(); Rect getGlyphBox(int index); QRect getStringBox(const int index) const; Lines getLines(); qreal getK(); void rotateLines(qreal phi, const QPoint &c = QPoint(0,0)); private: bool extractComponents(bool extractBars = false); void classifyGlyphs(); int findAdjacent(Rect &r); void normalizeLines(); void rotatePhi(qreal phi, const QPoint &c, QPoint &p); void addBarsHorizontal(int hoffset = 0, int height = -1, int woffset = 0, int width = -1); void addBarsHorisontalAfterVertical(); void addBarsVertical(); private: CCBuilder * builder; ComponentParameters components; Strings strings; StringsBoxes boxes; GlyphField glyphField; Lines lines; int glyphCount; int mediumGlyphHeight; int mediumGlyphWidth; int mediumLetterSpace; int mediumWordSpace; int stringsCount; qreal k; Bars bars; QVector verts; }; #endif yagf-0.9.2.1/src/configdialog.ui0000664000175000017500000000715612247205425017120 0ustar parallelsparallels ConfigDialog 0 0 344 237 OCR Settings :/yagf.png:/yagf.png OCR Engine 12 cuneiform tesseract Tesseract Setup Location of the tessdata directory: Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() ConfigDialog accept() 248 254 157 274 buttonBox rejected() ConfigDialog reject() 316 260 286 274 yagf-0.9.2.1/src/forcelocaledialog.h0000600000175000017500000000237512250171445017725 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef FORCELOCALEDIALOG_H #define FORCELOCALEDIALOG_H #include namespace Ui { class ForceLocaleDialog; } class ForceLocaleDialog : public QDialog { Q_OBJECT public: explicit ForceLocaleDialog(QWidget *parent = 0); ~ForceLocaleDialog(); enum Locales { NoLocale, RussianLocale, DefaultLocale } ; void setOption(Locales option); Locales getOption(); private: Ui::ForceLocaleDialog *ui; }; #endif // FORCELOCALEDIALOG_H yagf-0.9.2.1/src/qxttiffiohandler.cpp0000664000175000017500000001160312247205425020203 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2012 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "qxttiffiohandler.h" #include #include #include #include #include #include #include QXtTiffIOHandler::QXtTiffIOHandler() : QImageIOHandler() { dirnum = 0; dircount = 0; tif = NULL; } QXtTiffIOHandler::~QXtTiffIOHandler() { if (tif) TIFFClose(tif); } static tsize_t readProc(thandle_t handle, tdata_t data, tsize_t size) { QIODevice * device = (QIODevice *) handle; quint32 res = device->read((char *) data, size); return res; } static tsize_t writeProc(thandle_t handle, tdata_t data, tsize_t size) { QIODevice * device = (QIODevice *) handle; quint32 res = device->write((char *) data, size); return res; } static toff_t seekProc(thandle_t handle, toff_t offset, int whence) { QIODevice * device = (QIODevice *) handle; quint64 pos = device->pos(); switch(whence) { case SEEK_CUR: pos = pos + offset; break; case SEEK_SET : pos = offset; break; case SEEK_END : pos = device->size() + offset; break; default: break; } if (device->seek(pos)) return pos; return device->pos(); } static int closeProc(thandle_t handle) { QIODevice * device = (QIODevice *) handle; device->close(); return 0; } static toff_t sizeProc(thandle_t handle) { QIODevice * device = (QIODevice *) handle; return device->size(); } bool QXtTiffIOHandler::canRead() const { if (device()) if (device()->isReadable()) { TIFF * t = TIFFClientOpen("dummy", "r", device(), readProc, writeProc, seekProc, closeProc, sizeProc, NULL, NULL); if (t) { /*dircount = 0; do { dircount++; } while (TIFFReadDirectory(t));*/ device()->reset(); return true; } } return false; } bool QXtTiffIOHandler::read(QImage *image) { quint32 w; quint32 h; char * raster; tif = TIFFClientOpen("dummy", "r", device(), readProc, writeProc, seekProc, closeProc, sizeProc, NULL, NULL); TIFFSetDirectory(tif, dirnum); TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); raster = (char*) _TIFFmalloc(w * h * sizeof (uint32)); QBuffer buff; if (raster != NULL) { if (TIFFReadRGBAImage(tif, w, h, (uint32 *)raster, 0)) { QImage tmp(w, h, QImage::Format_ARGB32); for (uint32 row = 0; row < h; row++) { //strncpy((char*)tmp.scanLine(h - row - 1), &raster[4*w*row], 4*w); quint32 * p = (quint32 *) tmp.scanLine(h - row - 1); for (quint32 i = 0; i < w; i++) p[i] = ((quint32 *) raster)[w*row + i]; } _TIFFfree(raster); tmp.save(&buff, "JPG"); } device()->reset(); //TIFFClose(tif); return image->loadFromData(buff.buffer(), "JPG"); } return false; } QVariant QXtTiffIOHandler::option(QImageIOHandler::ImageOption option) const { return QImageIOHandler::option(option); } int QXtTiffIOHandler::loopCount() const { return 0; } int QXtTiffIOHandler::imageCount() //const { //device()->open(QIODevice::ReadOnly); //if (canRead()) { tif = TIFFClientOpen("dummy", "r", device(), readProc, writeProc, seekProc, closeProc, sizeProc, NULL, NULL); dircount = 0; do { dircount++; } while (TIFFReadDirectory(tif)); device()->reset(); //TIFFClose(tif); return dircount; } return dircount; } bool QXtTiffIOHandler::jumpToImage(int imageNumber) { if (imageNumber < imageCount()) { dirnum = imageNumber; return true; } return false; } bool QXtTiffIOHandler::supportsOption(QImageIOHandler::ImageOption option) const { if (option == QImageIOHandler::Animation) return true; return QImageIOHandler::supportsOption(option); } void QXtTiffIOHandler::setOption(QImageIOHandler::ImageOption option, const QVariant &value) { QImageIOHandler::setOption(option, value); } yagf-0.9.2.1/src/pdf2ppt.h0000664000175000017500000000174012247205425015655 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef PDF2PPT_H #define PDF2PPT_H #include "pdfextractor.h" class PDF2PPT : public PDFExtractor { public: PDF2PPT(); virtual void exec(); }; #endif // PDF2PPT_H yagf-0.9.2.1/src/qgraphicsinput.h0000664000175000017500000000667512247205425017353 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef QGRAPHICSINPUT_H #define QGRAPHICSINPUT_H #include "sidebar.h" #include #include #include #include #include #include typedef QList ActionList; class Block; class QGraphicsPixmapItem; class QGraphicsRectItem; class QPixmap; class QCursor; class QRectF; class QCursor; class QToolBar; class QActions; enum SelectStates { NoSelect = 0, StartSelect, Selecting }; class QGraphicsInput : public QGraphicsScene { Q_OBJECT public: explicit QGraphicsInput(const QRectF &sceneRect, QGraphicsView *view = 0); ~QGraphicsInput(); void setView(QGraphicsView *view); QRect getActiveBlock(); QRect getCurrentBlock(); void deleteBlock(int index); void deleteCurrentBlock(); void clearBlocks(); bool addBlock(const QRectF &rect, bool removeObstacles = true); void addBlockColliding(Block block); void drawLine(int x1, int y1, int x2, int y2); void imageOrigin(QPoint &p); QPixmap getCurrentImage(); void cropWhiteFrame(); void setMagnifierCursor(QCursor *cursor); void addToolBarAction(QAction * action); void addToolBarSeparator(); void setToolBarVisible(); QGraphicsRectItem *newBlock(const QRectF &rect); bool loadImage(const QPixmap &pixmap); //setMagnifierCursor(QCursor * cursor = ); protected: virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent); virtual void wheelEvent(QGraphicsSceneWheelEvent *wheelEvent); virtual void keyReleaseEvent(QKeyEvent *keyEvent); virtual void keyPressEvent(QKeyEvent *keyEvent); signals: void leftMouseClicked(int x, int y, bool blockSelected); void rightMouseClicked(int x, int y, bool inTheBlock); void keyPressed(int key); void increaseMe(); void decreaseMe(); void blockCreated(QRect rect); void deleteBlock(QRect rect); private slots: private: void leftMouseRelease(qreal x, qreal y); void rightMouseRelease(qreal x, qreal y); int nearActiveBorder(qreal x, qreal y); void clearTransform(); void addToolBar(); void deleteBlockRect(QGraphicsRectItem *item); QGraphicsView *m_view; QGraphicsPixmapItem *m_image; QGraphicsRectItem *m_CurrentBlockRect; QGraphicsRectItem *m_LastSelected; SelectStates selecting; QRectF blockRect; QRectF selBlockRect; bool hasImage; Qt::MouseButton buttonPressed; QCursor *magnifierCursor; int near_res; QPointer toolbar; ActionList actionList; QRect redRect; bool xred; }; #endif // QGRAPHICSINPUT_H yagf-0.9.2.1/src/scanner.cpp0000664000175000017500000000633312250140707016260 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "scanner.h" #include "utils.h" #include class XSaneScannerFE : public ScannerBase { public: XSaneScannerFE(const QString &PLL, QObject *parent = 0) : ScannerBase(parent) { addParameter("-s"); addParameter("-n"); addParameter("-N"); setProgramName("XSane"); setPreloadLibrary(PLL); addEnvironmentVar("LD_PRELOAD=" + PLL); } void exec() { waitFor(); execInternal("xsane"); } }; ScannerBase::ScannerBase(QObject *parent) : QObject(parent), scanProcess(this) { environment.append(QProcess::systemEnvironment()); } ScannerBase::~ScannerBase() { waitFor(); } void ScannerBase::addParameter(const QString &s) { parameters.append(s); } void ScannerBase::addEnvironmentVar(const QString &s) { environment.append(s); } void ScannerBase::setOutputFile(const QString &s) { outputFile = s; } QString ScannerBase::programName() { return pName; } void ScannerBase::waitFor() { scanProcess.terminate(); scanProcess.waitForFinished(10000); } void ScannerBase::execInternal(const QString &s) { scanProcess.setEnvironment(environment); QStringList sl; sl.append(parameters); sl.append(outputFile); connect(&scanProcess, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(finished(int,QProcess::ExitStatus))); scanProcess.start(s, sl); } void ScannerBase::setProgramName(const QString &s) { pName = s; } void ScannerBase::setPreloadLibrary(const QString &s) { preloadLibrary = s; } QString ScannerFactory::findPreloadLibrary() { QFileInfo lib; lib.setFile("/usr/local/lib/yagf/libxspreload.so"); if (!lib.exists()) { lib.setFile("/usr/lib/yagf/libxspreload.so"); if (!lib.exists()) { lib.setFile("/usr/lib64/yagf/libxspreload.so"); if (!lib.exists()) lib.setFile("/usr/local/lib64/yagf/libxspreload.so"); } } if (lib.exists()) return lib.filePath(); else return ""; } void ScannerFactory::findFEs() { if (findProgram("xsane")) fes << "xsane"; } ScannerFactory::ScannerFactory() { preloadPath = findPreloadLibrary(); findFEs(); } ScannerBase *ScannerFactory::createScannerFE(const QString &name) { if (fes.contains(name)) return new XSaneScannerFE(preloadPath); return NULL; } void ScannerBase::finished(int, QProcess::ExitStatus) { emit processFinished(); } yagf-0.9.2.1/src/PageAnalysis.h0000664000175000017500000000307612247205425016662 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef PAGEANALYSIS_H #define PAGEANALYSIS_H #include #include #include #include #include #include "ycommon.h" #include "analysis.h" class QPixmap; class QImage; class QRect; class BlockSplitter { public: void setImage(const QImage &image, qreal rotation, qreal scale); QRect getRootBlock(const QImage &image); Bars getBars(); // call after something calls blockAllText(); void splitBlocks(); QRect getRotationCropRect(const QImage &image); QList getBlocks(); private: QRect blockAllText(); void splitVertical(); void splitHorisontal(); bool isBlockRecogniseable(const Rect &block); private: QImage img; qreal m_rotate; qreal m_scale; int generalBr; Bars bars; Lines lines; QList blocks; }; #endif yagf-0.9.2.1/src/mainform.cpp0000775000175000017500000010621712250140750016442 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "sidebar.h" #include "droplabel.h" #include "popplerdialog.h" #include "pdfextractor.h" #include "pdf2ppt.h" #include "ghostscr.h" #include "configdialog.h" #include "advancedconfigdialog.h" #include "mainform.h" #include "tpagecollection.h" #include "scanner.h" #include "projectmanager.h" #include "forcelocaledialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "qgraphicsinput.h" #include "utils.h" #include "qxtunixsignalcatcher.h" #include "PageAnalysis.h" #include #include #include #include #include const QString outputBase = "output"; const QString outputExt = ".txt"; const QString inputFile = "input.bmp"; const QString outputFile = "output.txt"; const QString scanOutputFile = "input.png"; MainForm::MainForm(QWidget *parent): QMainWindow(parent) { setupUi(this); pages = PageCollection::instance(); setWindowTitle("YAGF"); //spellChecker = new SpellChecker(textEdit); textEdit->enumerateDicts(); frame->show(); //toolBar->addWidget(label1); //toolBar->addWidget(selectLangsBox); graphicsInput = new QGraphicsInput(QRectF(0, 0, 2000, 2000), graphicsView) ; graphicsInput->addToolBarAction(actionHideShowTolbar); graphicsInput->addToolBarAction(this->actionTBLV); graphicsInput->addToolBarAction(this->actionSmaller_view); graphicsInput->addToolBarSeparator(); graphicsInput->addToolBarAction(actionRotate_90_CCW); graphicsInput->addToolBarAction(actionRotate_180); graphicsInput->addToolBarAction(actionRotate_90_CW); graphicsInput->addToolBarAction(actionPrepare_Page); graphicsInput->addToolBarAction(actionDeskew); graphicsInput->addToolBarSeparator(); graphicsInput->addToolBarAction(actionSelect_Text_Area); graphicsInput->addToolBarAction(actionSelect_multiple_blocks); graphicsInput->addToolBarAction(ActionClearAllBlocks); label->setListWidget(sideBar); connect(sideBar, SIGNAL(pageSelected(int)), pages, SLOT(pageSelected(int))); connect(label, SIGNAL(pageRemoved(int)), pages, SLOT(pageRemoved(int))); statusBar()->show(); useXSane = TRUE; scanner = NULL; //rotation = 0; m_menu = new QMenu(graphicsView); ifCounter = 0; connect(actionOpen, SIGNAL(triggered()), this, SLOT(loadImage())); connect(actionQuit, SIGNAL(triggered()), this, SLOT(close())); connect(this, SIGNAL(windowShown()), this, SLOT(onShowWindow()), Qt::QueuedConnection); connect(actionScan, SIGNAL(triggered()), this, SLOT(scanImage())); connect(actionPreviousPage, SIGNAL(triggered()), this, SLOT(loadPreviousPage())); connect(actionNextPage, SIGNAL(triggered()), this, SLOT(loadNextPage())); connect(actionRecognize, SIGNAL(triggered()), this, SLOT(recognize())); connect(action_Save, SIGNAL(triggered()), textEdit, SLOT(saveText())); connect(actionAbout, SIGNAL(triggered()), this, SLOT(showAboutDlg())); connect(actionOnlineHelp, SIGNAL(triggered()), this, SLOT(showHelp())); connect(actionCopyToClipboard, SIGNAL(triggered()),textEdit, SLOT(copyClipboard())); connect(graphicsInput, SIGNAL(rightMouseClicked(int, int, bool)), this, SLOT(rightMouseClicked(int, int, bool))); connect(actionSelect_HTML_format, SIGNAL(triggered()), this, SLOT(selectHTMLformat())); connect(graphicsInput, SIGNAL(increaseMe()), this, SLOT(enlargeButtonClicked())); connect(graphicsInput, SIGNAL(decreaseMe()), this, SLOT(decreaseButtonClicked())); connect(sideBar, SIGNAL(filesDropped(QStringList)), SLOT(loadFiles(QStringList))); connect(pages, SIGNAL(loadPage()), this, SLOT(loadPage())); connect(graphicsInput, SIGNAL(blockCreated(QRect)), pages, SLOT(addBlock(QRect))); connect(graphicsInput, SIGNAL(deleteBlock(QRect)), pages, SLOT(deleteBlock(QRect))); connect(sideBar, SIGNAL(fileRemoved(int)), pages, SLOT(pageRemoved(int))); connect (pages, SIGNAL(addSnippet(int)), this, SLOT(addSnippet(int))); selectLangsBox = new QComboBox(); selectLangsBox->setToolTip(trUtf8("Recognition language")); toolBar->insertWidget(actionRecognize, selectLangsBox); // connect(selectLangsBox->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(LangTextChanged(QString))); initSettings(); engineLabel = new QLabel(); statusBar()->addPermanentWidget(engineLabel, 0); if (settings->getSelectedEngine() == UseCuneiform) { //fillLanguagesBoxCuneiform(); engineLabel->setText(trUtf8("Using Cuneiform")); } if (settings->getSelectedEngine() == UseTesseract) { //fillLanguagesBoxTesseract(); engineLabel->setText(trUtf8("Using Tesseract")); } fillLangBox(); delTmpFiles(); QXtUnixSignalCatcher::connectUnixSignal(SIGUSR2); ba = new QByteArray(); connect(QXtUnixSignalCatcher::catcher(), SIGNAL(unixSignal(int)), this, SLOT(readyRead(int))); QPixmap l_cursor; l_cursor.load(":/resize.png"); resizeCursor = new QCursor(l_cursor); graphicsInput->setMagnifierCursor(resizeCursor); l_cursor.load(":/resize_block.png"); resizeBlockCursor = new QCursor(l_cursor); // textEdit->setContextMenuPolicy(Qt::ActionsContextMenu); this->sideBar->show(); //connect(sideBar, SIGNAL(fileSelected(const QString &)), this, SLOT(fileSelected(const QString &))); connect(actionRecognize_All_Pages, SIGNAL(triggered()), this, SLOT(recognizeAll())); QPixmap pm; pm.load(":/align.png"); //alignButton->setIcon(pm); pm.load(":/undo.png"); //unalignButton->setIcon(pm); //connect(unalignButton, SIGNAL(clicked()), this, SLOT(unalignButtonClicked())); //clearBlocksButton->setDefaultAction(ActionClearAllBlocks); loadFromCommandLine(); emit windowShown(); pdfx = NULL; if (findProgram("pdftoppm")) { pdfx = new PDF2PPT(); } else if (findProgram("gs")) { pdfx = new GhostScr(); } if (pdfx) { connect(pdfx, SIGNAL(addPage(QString)), this, SLOT(addPDFPage(QString)), Qt::QueuedConnection); connect (pdfx, SIGNAL(finished()), this, SLOT(finishedPDF())); } pdfPD.setWindowTitle("YAGF"); pdfPD.setLabelText(trUtf8("Importing pages from the PDF document...")); pdfPD.setCancelButtonText(trUtf8("Cancel")); pdfPD.setMinimum(-1); pdfPD.setMaximum(-1); pdfPD.setWindowIcon(QIcon(":/yagf.png")); if (pdfx) connect(&pdfPD, SIGNAL(canceled()), pdfx, SLOT(cancel())); menu_Settings->addAction("UI Language", this, SLOT(setUILanguage())); } void MainForm::onShowWindow() { // actionCheck_spelling->setCheckable(true); connect(selectLangsBox, SIGNAL(currentIndexChanged(int)), this, SLOT(newLanguageSelected(int))); selectLangsBox->setCurrentIndex(selectLangsBox->findData(QVariant(settings->getLanguage()))); //spellChecker->setLanguage(language); //actionCheck_spelling->setEnabled(spellChecker->spellCheck()); } void MainForm::loadFromCommandLine() { QStringList sl = QApplication::arguments(); if (sl.count() > 1) { if (QFile::exists(sl.at(1))) loadFile(sl.at(1)); for (int i = 2; i < sl.count(); i++) { QApplication::processEvents(); if (QFile::exists(sl.at(i))) loadFile(sl.at(i)); } sideBar->select(sl.at(1)); } } void MainForm::loadFiles(QStringList files) { for (int i = 0; i < files.count(); i++) if (QFile::exists(files.at(i))) loadFile(files.at(i)); } void MainForm::LangTextChanged(const QString &text) { if (selectLangsBox->findText(text, Qt::MatchStartsWith) < 0) selectLangsBox->lineEdit()->setText(""); } void MainForm::showConfigDlg() { ConfigDialog dialog(this); SelectedEngine ose = settings->getSelectedEngine(); if (settings->getSelectedEngine() == UseCuneiform) dialog.setSelectedEngine(0); else dialog.setSelectedEngine(1); dialog.setTessDataPath(settings->getTessdataPath()); if (dialog.exec()) { settings->setSelectedEngine(dialog.selectedEngine() == 0 ? UseCuneiform : UseTesseract); settings->setTessdataPath(dialog.tessdataPath()); if (settings->getSelectedEngine() != ose) { QString oldLang = selectLangsBox->currentText(); selectLangsBox->clear(); if (settings->getSelectedEngine() == UseCuneiform) { engineLabel->setText(trUtf8("Using Cuneiform")); } if (settings->getSelectedEngine() == UseTesseract) { engineLabel->setText(trUtf8("Using Tesseract")); } fillLangBox(); int newIndex = selectLangsBox->findText(oldLang); if (newIndex >= 0) { selectLangsBox->setCurrentIndex(newIndex); settings->setLanguage(selectLangsBox->itemData(newIndex).toString()); } else { settings->setLanguage("eng"); for (int i = 0; i < selectLangsBox->count(); i++) { QString s = selectLangsBox->itemData(i).toString(); if (s == "eng") { newLanguageSelected(i); selectLangsBox->setCurrentIndex(i); break; } } } } } } void MainForm::importPDF() { if (!pdfx) { QMessageBox::critical(this, trUtf8("No PDF converter installed"), trUtf8("No compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required).")); return; } PopplerDialog dialog(this); if (dialog.exec()) { pdfx->setSourcePDF(dialog.getPDFFile()); if (pdfx->getSourcePDF().isEmpty()) { QMessageBox::information(this, trUtf8("Error"), trUtf8("PDF file name may not be empty")); return; } pdfx->setStartPage(dialog.getStartPage()); pdfx->setStopPage(dialog.getStopPage()); bool doit = true; QString outputDir; while (doit) { outputDir = QFileDialog::getExistingDirectory(this, trUtf8("Select an existing directory for output or create some new one")); //, QString(""), QString(), (QString*) NULL, QFileDialog::ShowDirsOnly); if (outputDir.isEmpty()) return; QDir dir(outputDir); if (dir.count() > 2) QMessageBox::warning(this, trUtf8("Selecting Directory"), trUtf8("The selected directory is not empty")); else doit = false; } pdfx->setOutputDir(outputDir); QApplication::processEvents(); pdfPD.setWindowFlags(Qt::Dialog|Qt::WindowStaysOnTopHint); pdfPD.show(); pdfPD.setMinimum(0); pdfPD.setMaximum(100); QApplication::processEvents(); pdfx->exec(); } } void MainForm::addPDFPage(QString pageName) { pages->appendPage(pageName); pdfPD.setValue(pdfPD.value()+1); } void MainForm::finishedPDF() { pdfPD.hide(); } void MainForm::loadImage() { QFileDialog dialog(this, trUtf8("Open Image"), settings->getLastDir(), trUtf8("Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm)")); dialog.setFileMode(QFileDialog::ExistingFiles); if (dialog.exec()) { QStringList fileNames; fileNames = dialog.selectedFiles(); settings->setLastDir(dialog.directory().path()); if (fileNames.count() > 0) loadFile(fileNames.at(0), true); if (!pages->pageValid()) return; for (int i = 1; i < fileNames.count(); i++) { loadFile(fileNames.at(i), false); } // if (fileNames.count() > 0) // pages->makePageCurrent(0); } } void MainForm::singleColumnButtonClicked() { //singleColumn = singleColumnButton->isChecked(); } void MainForm::closeEvent(QCloseEvent *event) { if (!textEdit->textSaved()) { QPixmap icon; icon.load(":/info.png"); QMessageBox messageBox(QMessageBox::NoIcon, "YAGF", trUtf8("There is an unsaved text in the editor window. Do you want to save it?"), QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel, this); messageBox.setIconPixmap(icon); int result = messageBox.exec(); if (result == QMessageBox::Save) textEdit->saveText(); else if (result == QMessageBox::Cancel) { event->ignore(); return; } } if (scanner) { delete scanner; scanner = NULL; } settings->setSize(size()); settings->setPosition(pos()); settings->setFullScreen(isFullScreen()); settings->writeSettings(); delTmpFiles(); event->accept(); QXtUnixSignalCatcher::catcher()->disconnectUnixSugnals(); pages->clear(); } void MainForm::rotateCWButtonClicked() { QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); pages->rotate90CW(); setCursor(oldCursor); } void MainForm::rotateCCWButtonClicked() { QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); pages->rotate90CCW(); setCursor(oldCursor); } void MainForm::rotate180ButtonClicked() { QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); pages->rotate180(); setCursor(oldCursor); } void MainForm::enlargeButtonClicked() { pages->makeLarger(); } void MainForm::decreaseButtonClicked() { pages->makeSmaller(); } void MainForm::initSettings() { settings = Settings::instance(); if (settings->getFullScreen()) showFullScreen(); else { move(settings->getPosition()); resize(settings->getSize()); } actionCheck_spelling->setChecked(settings->getCheckSpelling()); actionSelect_HTML_format->setChecked(settings->getOutputFormat() != "text"); QList li; li.append(1); li.append(1); splitter->setSizes(li); toolBar->setIconSize(settings->getIconSize()); } void MainForm::newLanguageSelected(int index) { settings->setLanguage(selectLangsBox->itemData(index).toString()); actionCheck_spelling->setEnabled(textEdit->hasDict(settings->getLanguage())); if (settings->getCheckSpelling()) { settings->setCheckSpelling(textEdit->spellCheck(settings->getLanguage())); //actionCheck_spelling->setEnabled(checkSpelling); actionCheck_spelling->setChecked(settings->getCheckSpelling()); } } void MainForm::scanImage() { if (useXSane) { if (scanner) { delete scanner; } ScannerFactory * sf = new ScannerFactory(); scanner = sf->createScannerFE("xsane"); if (scanner == NULL) { QMessageBox::warning(this, trUtf8("Scanning is impossible"), trUtf8("No scanning front-end is found. Please install XSane in order to perform scanning.")); return; } scanner->setOutputFile(settings->workingDir() + scanOutputFile); delete sf; scanner->exec(); } } void MainForm::loadFile(const QString &fn, bool loadIntoView) { QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); if (pages->appendPage(fn)) { if (loadIntoView) { pages->makePageCurrent(pages->count()-1); loadPage(); sideBar->item(sideBar->count()-1)->setSelected(true); } } else { QMessageBox::warning(this, trUtf8("Failed to Load Image"), fn); } setCursor(oldCursor); } void MainForm::delTmpFiles() { QDir dir(settings->workingDir()); dir.setFilter(QDir::Files | QDir::NoSymLinks); for (uint i = 0; i < dir.count(); i++) { if (dir[i].endsWith("jpg") || dir[i].endsWith("bmp") || dir[i].endsWith("png") || dir[i].endsWith("txt")) dir.remove(dir[i]); } delTmpDir(); } void MainForm::loadNextPage() { } void MainForm::loadPreviousPage() { } // TODO: think on blocks/page recognition bool MainForm::useTesseract(const QString &inputFile) { QProcess proc; proc.setWorkingDirectory(settings->workingDir()); QStringList sl; sl.append(inputFile); sl.append(outputBase); sl.append("-l"); sl.append(settings->getLanguage()); QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); env.insert("TESSDATA_PREFIX", settings->getTessdataPath()); proc.setProcessEnvironment(env); proc.start("tesseract", sl); proc.waitForFinished(-1); if (proc.exitCode()) { QByteArray stdout = proc.readAllStandardOutput(); QByteArray stderr = proc.readAllStandardError(); QString output = QString(stdout) + QString(stderr); QMessageBox::critical(this, trUtf8("Starting tesseract failed"), trUtf8("The system said: ") + (output != "" ? output : trUtf8("program not found"))); return false; } return true; } bool MainForm::useCuneiform(const QString &inputFile, const QString &outputFile) { QProcess proc; proc.setWorkingDirectory(settings->workingDir()); QStringList sl; sl.append("-l"); sl.append(settings->getLanguage()); sl.append("-f"); if (settings->getOutputFormat() == "text") sl.append("text"); else sl.append("html"); sl.append("-o"); sl.append(settings->workingDir() + outputFile); sl.append(settings->workingDir() + inputFile); proc.start("cuneiform", sl); proc.waitForFinished(-1); if (proc.exitCode()) { QByteArray stdout = proc.readAllStandardOutput(); QByteArray stderr = proc.readAllStandardError(); QString output = QString(stdout) + QString(stderr); QMessageBox::critical(this, trUtf8("Starting cuneiform failed"), trUtf8("The system said: ") + (output != "" ? output : trUtf8("program not found"))); return false; } return true; } void MainForm::recognizeInternal() { if (settings->getSelectedEngine() == UseCuneiform) { if (!useCuneiform(inputFile, outputFile)) return; } if (settings->getSelectedEngine() == UseTesseract) { if (!useTesseract(inputFile)) return; } QFile textFile(settings->workingDir() + outputFile); textFile.open(QIODevice::ReadOnly); QByteArray text = textFile.readAll(); textFile.close(); QString textData; QTextCodec *codec = QTextCodec::codecForName("UTF-8"); textData = codec->toUnicode(text); //QString::fromUtf8(text.data()); if (settings->getOutputFormat() == "text") textData.prepend(""); textData.replace("", "\"--"); textData.replace(".bmp>", ""); // textData.replace("-

", ""); // textData.replace("-
", ""); textEdit->append(textData); textEdit->append(QString(" ")); if (settings->getCheckSpelling()) { actionCheck_spelling->setChecked(textEdit->spellCheck(settings->getLanguage())); } } void MainForm::recognize() { QFile::remove(settings->workingDir() + "input*.bmp"); if (!pages->pageValid()) { QMessageBox::critical(this, trUtf8("Error"), trUtf8("No image loaded")); return; } if (!findEngine()) return; if (pages->blockCount() > 0) { for (int i = 0; i < pages->blockCount(); i++) { prepareBlockForRecognition(i); recognizeInternal(); } } else { preparePageForRecognition(); recognizeInternal(); } } void MainForm::showAboutDlg() { QPixmap icon; icon.load(":/yagf.png"); QMessageBox aboutBox(QMessageBox::NoIcon, trUtf8("About YAGF"), trUtf8("

YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines

Version %1

Ⓒ 2009-2013 Andrei Borovsky

This is a free software distributed under GPL v3. Visit http://symmetrica.net/cuneiform-linux/yagf-en.html for more details.").arg(version), QMessageBox::Ok); aboutBox.setIconPixmap(icon); QList labels = aboutBox.findChildren(); for (int i = 0; i < labels.count(); i++) { QLabel *lab = labels.at(i); lab->setTextInteractionFlags(Qt::TextBrowserInteraction); } aboutBox.setTextFormat(Qt::RichText); aboutBox.exec(); } void MainForm::showHelp() { QDesktopServices::openUrl(QUrl(trUtf8("http://symmetrica.net/cuneiform-linux/yagf-en.html"))); } void MainForm::readyRead(int sig) { QFile f(settings->workingDir() + scanOutputFile); QString newName = QString(settings->workingDir() + "scan-input-%1.png").arg(ifCounter); ifCounter++; QFileInfo fi(newName); if (fi.exists()) { QFile f2(newName); f2.remove(); } f.rename(newName); loadFile(newName); } void MainForm::delTmpDir() { QDir dir; dir.setPath(settings->workingDir() + "output_files"); dir.setFilter(QDir::Files | QDir::NoSymLinks); for (uint i = 0; i < dir.count(); i++) { if (dir[i].endsWith("jpg") || dir[i].endsWith("bmp")) dir.remove(dir[i]); } dir.rmdir(settings->workingDir() + "output_files"); } void MainForm::clearTmpFiles() { QFile::remove(settings->workingDir() + "tmp*.bmp"); QFile f(settings->workingDir()+inputFile); f.remove(); f.setFileName(settings->workingDir()+outputFile); f.remove(); } void MainForm::fillLangBox() { settings->startLangPair(); QString full; QString abbr; selectLangsBox->clear(); while(settings->getLangPair(full, abbr)) selectLangsBox->addItem(full, QVariant(abbr)); } void MainForm::preparePageForRecognition() { clearTmpFiles(); pages->savePageForRecognition(settings->workingDir() + inputFile); } void MainForm::prepareBlockForRecognition(const QRect &r) { clearTmpFiles(); pages->saveBlockForRecognition(r, settings->workingDir() + inputFile); } void MainForm::prepareBlockForRecognition(int index) { clearTmpFiles(); pages->saveBlockForRecognition(index, settings->workingDir() + inputFile); } void MainForm::setResizingCusor() { //scrollArea->widget()->setCursor(*resizeBlockCursor); } void MainForm::setUnresizingCusor() { //scrollArea->widget()->setCursor(QCursor(Qt::ArrowCursor)); } void MainForm::loadPage() { //graphicsInput->clearBlocks(); graphicsInput->loadImage(pages->pixmap()); QApplication::processEvents(); for (int i = 0; i < pages->blockCount(); i++) graphicsInput->addBlockColliding(pages->getBlock(i)); QFileInfo fi(pages->fileName()); setWindowTitle(QString("YAGF - %1").arg(fi.fileName()) ); } void MainForm::recognizeAll() { if (pages->count() == 0) return; QProgressDialog progress(trUtf8("Recognizing pages..."), trUtf8("Abort"), 0, pages->count(), this); progress.setWindowTitle("YAGF"); progress.show(); progress.setValue(0); pages->makePageCurrent(-1); for (int i = 0; i < pages->count(); i++) { progress.setValue(i); if (progress.wasCanceled()) break; pages->makeNextPageCurrent(); recognize(); } } void MainForm::unalignButtonClicked() { /*if (((QSelectionLabel *) scrollArea->widget())->pixmap()->isNull()) return; int rot = ((FileToolBar *) m_toolBar)->getRotation(); int rrot = ((rot + 45)/90); rrot *=90; rotateImage(rrot - rot); rotation = rrot;*/ } void MainForm::hideToolBar() { graphicsInput->setToolBarVisible(); } void MainForm::on_ActionClearAllBlocks_activated() { pages->clearBlocks(); loadPage(); } void MainForm::rightMouseClicked(int x, int y, bool inTheBlock) { m_menu->clear(); m_menu->addAction(ActionClearAllBlocks); if (inTheBlock) { m_menu->addAction(ActionDeleteBlock); m_menu->addAction(actionRecognize_block); m_menu->addAction(actionSave_block); m_menu->addAction(actionDeskew_by_Block); } else { m_menu->addAction(actionSelect_Text_Area); m_menu->addAction(actionSelect_multiple_blocks); } QPoint p = graphicsView->mapToGlobal(QPoint(x, y)); m_menu->move(p); m_menu->show(); } void MainForm::on_ActionDeleteBlock_activated() { QRect r = graphicsInput->getCurrentBlock(); graphicsInput->deleteCurrentBlock(); pages->deleteBlock(r); } bool MainForm::findEngine() { if (settings->getSelectedEngine() == UseCuneiform) { if (!findProgram("cuneiform")) { if (findProgram("tesseract")) { QMessageBox::warning(this, trUtf8("Warning"), trUtf8("cuneiform not found, switching to tesseract")); settings->setSelectedEngine(UseTesseract); } else { QMessageBox::warning(this, trUtf8("Warning"), trUtf8("No recognition engine found.\nPlease install either cuneiform or tesseract")); return false; } } } if (settings->getSelectedEngine() == UseTesseract) { if (!findProgram("tesseract")) { if (findProgram("cuneiform")) { QMessageBox::warning(this, trUtf8("Warning"), trUtf8("tesseract not found, switching to cuneiform")); settings->setSelectedEngine(UseCuneiform); } else { QMessageBox::warning(this, trUtf8("Warning"), trUtf8("No recognition engine found.\nPlease install either cuneiform or tesseract")); return false; } } } return true; } void MainForm::on_actionRecognize_block_activated() { if (!findEngine()) return; if (graphicsInput->getCurrentBlock().isNull()) return; clearTmpFiles(); pages->saveRawBlockForRecognition(graphicsInput->getCurrentBlock(), settings->workingDir() + inputFile); recognizeInternal(); } /*void MainForm::on_actionRecognize_activated() { }*/ void MainForm::on_actionCheck_spelling_triggered() { settings->setCheckSpelling(actionCheck_spelling->isChecked()); } void MainForm::on_actionSave_current_image_activated() { QCursor oc = cursor(); setCursor(Qt::WaitCursor); QString format; QString fn = getFileNameToSaveImage(format); if (!fn.isEmpty()) { if (!(pages->savePageAsImage(fn, format))) QMessageBox::warning(this, QObject::trUtf8("Warning"), QObject::trUtf8("Failed to save the image")); } setCursor(oc); } QString MainForm::getFileNameToSaveImage(QString &format) { QString jpegFilter = QObject::trUtf8("JPEG Files (*.jpg)"); QString pngFilter = QObject::trUtf8("PNG Files (*.png)"); QStringList filters; format = "JPEG"; filters << jpegFilter << pngFilter; QFileDialog dialog(this, trUtf8("Save Image"), settings->getLastOutputDir()); dialog.setFilters(filters); dialog.setAcceptMode(QFileDialog::AcceptSave); dialog.setDefaultSuffix("jpg"); if (dialog.exec()) { if (dialog.selectedNameFilter() == jpegFilter) { format = "JPEG"; dialog.setDefaultSuffix("jpg"); } else if (dialog.selectedNameFilter() == pngFilter) { format = "PNG"; dialog.setDefaultSuffix("png"); } QStringList fileNames; fileNames = dialog.selectedFiles(); settings->setLastOutputDir(dialog.directory().path()); return fileNames.at(0); } return ""; } MainForm::~MainForm() { delete resizeBlockCursor; delete resizeCursor; //delete fileChannel; delete graphicsInput; delete ba; delete pdfx; } void MainForm::on_actionSave_block_activated() { QString format; QString fn = getFileNameToSaveImage(format); if (!fn.isEmpty()) pages->saveBlockForRecognition(graphicsInput->getCurrentBlock(), fn, format); } void MainForm::on_actionCheck_spelling_activated() { settings->setCheckSpelling(actionCheck_spelling->isChecked()); if (settings->getCheckSpelling()) { actionCheck_spelling->setChecked(textEdit->spellCheck(settings->getLanguage())); } else textEdit->unSpellCheck(); } /*void MainForm::on_alignButton_clicked() { this->AnalizePage(); }*/ void MainForm::on_actionDeskew_activated() { QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); pages->deskew(); setCursor(oldCursor); } void MainForm::on_actionSelect_HTML_format_activated() { if (actionSelect_HTML_format->isChecked()) settings->setOutputFormat("html"); else settings->setOutputFormat("text"); } void MainForm::pasteimage() { QClipboard *clipboard = QApplication::clipboard(); QPixmap pm = clipboard->pixmap(); if (pm.isNull()) return; QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); QString tmpFile = "input-01.png"; QFileInfo fi(settings->workingDir() + tmpFile); while (fi.exists()) { QString digits = extractDigits(tmpFile); bool result; int d = digits.toInt(&result); if (!result) return; d++; if (d < 0) d = 0; QString newDigits = QString::number(d); while (newDigits.size() < digits.size()) newDigits = '0' + newDigits; tmpFile = tmpFile.replace(digits, newDigits); fi.setFile(settings->workingDir(), tmpFile); } pm.save(fi.absoluteFilePath(), "PNG"); loadFile(fi.absoluteFilePath()); setCursor(oldCursor); } void MainForm::deskewByBlock() { /*QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); graphicsInput->update(); QApplication::processEvents(); if (!graphicsInput->getCurrentBlock().isNull()) { QImage img = graphicsInput->getCurrentBlock();*/ pages->deskew(); //} ///setCursor(oldCursor); } void MainForm::selectTextArea() { pages->blockAllText(); } void MainForm::showAdvancedSettings() { AdvancedConfigDialog dlg; dlg.setCrop1(settings->getCropLoaded()); if (dlg.exec()) { settings->setCropLoaded(dlg.doCrop1()); } } void MainForm::addSnippet(int index) { sideBar->addItem((QListWidgetItem *) pages->snippet()); } void MainForm::preprocessPage() { QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); if (!pages->splitPage(true)) QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to detect text areas on this page.\nThe page possibly lacks contrast. Try to select blocks manually.")); setCursor(oldCursor); } void MainForm::saveProject() { if (settings->getProjectDir().isEmpty()) { QString dir = QFileDialog::getExistingDirectory(this, QObject::trUtf8("Select Project Directory"), ""); if (dir.isEmpty()) return; QCursor oldCursor = cursor(); QDir dinfo(dir); if (dinfo.entryList().count() > 2) { QMessageBox::warning(this, trUtf8("Warning"), trUtf8("The selected directoy is not empty. Please select or create another one.")); } else { ProjectSaver ps; if (!ps.save(dir)) QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to save the project.")); else settings->setProjectDir(dir); } setCursor(oldCursor); } else { QCursor oldCursor = cursor(); ProjectSaver ps; if (!ps.save(settings->getProjectDir())) QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to save the project.")); setCursor(oldCursor); } } void MainForm::loadProject() { pages->clear(); QString dir = QFileDialog::getExistingDirectory(this, QObject::trUtf8("Select Project Directory"), ""); if (dir.isEmpty()) return; QCursor oldCursor = cursor(); ProjectLoader pl; if (!pl.load(dir)) QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to load project.")); else settings->setProjectDir(dir); setCursor(oldCursor); } void MainForm::selectBlocks() { QCursor oldCursor = cursor(); setCursor(Qt::WaitCursor); if (!pages->splitPage(false)) QMessageBox::warning(this, trUtf8("Warning"), trUtf8("Failed to detect text areas on this page.\nThe page possibly lacks contrast. Try to select blocks manually.")); setCursor(oldCursor); } void MainForm::setSmallIcons() { QSize s = toolBar->iconSize(); if (s.height() > 32) { s.setHeight(32); s.setWidth(32); } else { s.setHeight(48); s.setWidth(48); } toolBar->setIconSize(s); settings->setIconSize(s); } void MainForm::selectHTMLformat() { if (actionSelect_HTML_format->isChecked()) settings->setOutputFormat("html"); else settings->setOutputFormat("text"); } void MainForm::setUILanguage() { ForceLocaleDialog fld(this); if (settings->useNoLocale()) fld.setOption(ForceLocaleDialog::NoLocale); else { if (settings->useRussianLocale()) fld.setOption(ForceLocaleDialog::RussianLocale); else { fld.setOption(ForceLocaleDialog::DefaultLocale); } } if (fld.exec() == QDialog::Accepted) { settings->setNoLocale(false); settings->setRussianLocale(false); if (fld.getOption() == ForceLocaleDialog::NoLocale) settings->setNoLocale(true); else { if (fld.getOption() == ForceLocaleDialog::RussianLocale) settings->setRussianLocale(true); } } } yagf-0.9.2.1/src/PageAnalysis.cpp0000664000175000017500000001645112247205425017216 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "PageAnalysis.h" #include "CCAnalysis.h" #include "ccbuilder.h" #include "analysis.h" #include "utils.h" #include #include #include #include #include void BlockSplitter::setImage(const QImage &image, qreal rotation, qreal scale) { img = image; m_rotate = rotation; m_scale = scale; } QRect BlockSplitter::getRootBlock(const QImage &image) { if (image.isNull()) return QRect(0,0,0,0); QImage img1 = image; QRect result = blockAllText(); RotationCropper rc(&img1, QColor("white").rgb(), generalBr); CCBuilder cb(img1); //img1.save("/home/anre/pictures/ttt.png"); QRect r = cb.crop();//rc.crop(); QRect r1(result.x() + r.x(), result.y() + r.y(), result.width(), result.height()); result = r1; foreach (Rect rc, bars) { bars.removeOne(rc); rc.x1 += r.x(); rc.x2 += r.x(); rc.y1 += r.y(); rc.y2 += r.y(); bars.append(rc); } return result; } Bars BlockSplitter::getBars() { return bars; } QRect BlockSplitter::blockAllText() { //img = img.transformed(QTransform().translate(-x, -y).rotate(m_rotate).translate(x, y), Qt::SmoothTransformation); if (!img.isNull()) { CCBuilder * cb = new CCBuilder(img); cb->setGeneralBrightness(360); cb->setMaximumColorComponent(100); cb->labelCCs(); CCAnalysis * an = new CCAnalysis(cb); an->analize(); lines = an->getLines(); foreach(TextLine l, lines) if (l.count() < 3) lines.removeOne(l); int minX = 100000; int minY = 100000; int maxX = 0; int maxY = 0; for (int i =0; i < lines.count(); i++) { int x1 = lines.at(i).at(0).x; int y1 = lines.at(i).at(0).y; int x2 = lines.at(i).at(lines.at(i).count()-1).x; int y2 = lines.at(i).at(lines.at(i).count()-1).y; //graphicsInput->drawLine(x1,y1,x2,y2); if (x1 > x2) { int t = x2; x2 = x1; x1 = t; } minX = minX < x1 ? minX : x1; maxX = maxX > x2 ? maxX : x2; if (y1 > y2) { int t = y2; y2 = y1; y1 = t; } minY = minY < y1 ? minY : y1; maxY = maxY > y2 ? maxY : y2; } minX = minX - 2*an->getMediumGlyphWidth(); maxX =maxX + 2*an->getMediumGlyphWidth(); minY = minY - 2*an->getMediumGlyphHeight(); maxY = maxY + 2*an->getMediumGlyphHeight(); //graphicsInput->clearBlocks(); //graphicsInput->addBlock(QRectF(ox + minX*2*sideBar->getScale(), oy + minY*2*sideBar->getScale(), (maxX-minX)*2*sideBar->getScale(), (maxY-minY)*2*sideBar->getScale())); bars = an->addBars(); delete an; generalBr = cb->getGB(); delete cb; minX = minX <= 0 ? 1 :minX; minY = minY <= 0 ? 1 :minY; return QRect(minX*2*m_scale, minY*2*m_scale, (maxX-minX)*2*m_scale, (maxY-minY)*2*m_scale); } return QRect(0, 0, 0, 0); } void BlockSplitter::splitVertical() { bool didSplit = true; while(didSplit) { didSplit = false; for (int i = blocks.count() - 1; i >=0; i--) { Rect block = blocks.at(i); foreach(Rect bar, bars) { if (abs(bar.x2 - bar.x1) > (bar.y2-bar.y1)) continue; int xmid = (bar.x1 + bar.x2)/2; if ((block.x1 < (xmid - 5)) &&(block.x2 > (xmid + 5))) { Rect block1 = block; block1.x2 = xmid -2; Rect block2 = block; block2.x1 = xmid + 2; blocks.removeAll(block); blocks.append(block1); blocks.append(block2); didSplit = true; break; } } } } } void BlockSplitter::splitBlocks() { QRect r = getRootBlock(img); Rect b; b.x1 = r.x(); b.y1 = r.y(); b.x2 = b.x1 + r.width(); b.y2 = b.y1 + r.height(); blocks.clear(); blocks.append(b); splitVertical(); splitHorisontal(); // qSort(blocks.begin(), blocks.end(), rectLessThan); for (int i = blocks.count() -1; i >=0; i--) { Rect r = blocks.at(i); if (!isBlockRecogniseable(r)) blocks.removeAll(r); } } QList BlockSplitter::getBlocks() { return blocks; } QRect BlockSplitter::getRotationCropRect(const QImage &image) { const QImage * img = ℑ QImage * img2 = const_cast(img); RotationCropper rc(img2, QColor("white").rgb(), generalBr); return rc.crop(); } void BlockSplitter::splitHorisontal() { bool didSplit = true; while(didSplit) { didSplit = false; for (int i = blocks.count() - 1; i >=0; i--) { Rect block = blocks.at(i); foreach(Rect bar, bars) { if (abs(bar.y2 - bar.y1) > (bar.x2-bar.x1)) continue; int ymid = (bar.y1 + bar.y2)/2; if ((block.y1 < (ymid - 5)) &&(block.y2 > (ymid + 5))) if (_contains(bar.x1, bar.x2, block.x1)||_contains(bar.x1, bar.x2, block.x2)||_contains(block.x1, block.x2, bar.x1)||_contains(block.x1, block.x2, bar.x2)) { Rect block1 = block; block1.y2 = ymid -2; Rect block2 = block; block2.y1 = ymid + 2; blocks.removeAll(block); blocks.append(block1); blocks.append(block2); didSplit = true; break; } } } } } inline bool between(int a, int b, int c) { return (c > a) && (c < b); } bool BlockSplitter::isBlockRecogniseable(const Rect &block) { int contains = 0; int maxl = 0; foreach(TextLine l, lines) { if (!between(block.x1, block.x2, l.first().x)) continue; if (!between(block.x1, block.x2, l.last().x)) continue; if (!between(block.y1, block.y2, l.first().y)) continue; if (!between(block.y1, block.y2, l.last().y)) continue; contains++; if (l.count() > maxl) maxl = l.count(); } if ((maxl > 3)) return true; return false; } yagf-0.9.2.1/src/texteditor.cpp0000664000175000017500000001755012250140707017025 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "texteditor.h" #include "settings.h" #include "ycommon.h" #include "utils.h" #include #include #include #include #include #include #include #include TextEditor::TextEditor(QWidget *parent) : QTextEdit(parent), spellChecker(this) { hasCopy = false; mTextSaved = true; setContextMenuPolicy(Qt::CustomContextMenu); connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequested(QPoint))); connect(document(), SIGNAL(cursorPositionChanged(const QTextCursor &)), this, SLOT(updateSP())); connect(this, SIGNAL(copyAvailable(bool)), this, SLOT(copyAvailable(bool))); connect(this, SIGNAL(textChanged()), this, SLOT(textChanged())); } TextEditor::~TextEditor() { } bool TextEditor::textSaved() { return mTextSaved; } bool TextEditor::spellCheck(const QString &lang) { spellChecker.setLanguage(lang); return spellChecker.spellCheck(); } void TextEditor::unSpellCheck() { spellChecker.unSpellCheck(); } void TextEditor::enumerateDicts() { spellChecker.enumerateDicts(); } bool TextEditor::hasDict(const QString &shname) { return spellChecker.hasDict(shname); } void TextEditor::saveText() { Settings * settings = Settings::instance(); QString filter; if (settings->getOutputFormat() == "text") filter = trUtf8("Text Files (*.txt)"); else filter = trUtf8("HTML Files (*.html)"); QFileDialog dialog(this, trUtf8("Save Text"), settings->getLastOutputDir(), filter); if (settings->getOutputFormat() == "text") dialog.setDefaultSuffix("txt"); else dialog.setDefaultSuffix("html"); dialog.setAcceptMode(QFileDialog::AcceptSave); if (dialog.exec()) { QStringList fileNames; fileNames = dialog.selectedFiles(); settings->setLastOutputDir(dialog.directory().path()); QFile textFile(fileNames.at(0)); textFile.open(QIODevice::ReadWrite | QIODevice::Truncate); if (settings->getOutputFormat() == "text") textFile.write(toPlainText().toUtf8()); else saveHtml(&textFile); textFile.close(); mTextSaved = true; } } void TextEditor::keyPressEvent(QKeyEvent *e) { if (e->modifiers() & Qt::ControlModifier) { if ((e->key() == Qt::Key_Plus) || (e->key() == Qt::Key_Equal)) { enlargeFont(); e->accept(); return; } else if (e->key() == Qt::Key_Minus) { decreaseFont(); e->accept(); return; } } QTextEdit::keyPressEvent(e); } void TextEditor::wheelEvent(QWheelEvent *e) { if (e->modifiers() & Qt::ControlModifier) { if (e->delta() > 0) enlargeFont(); else decreaseFont(); e->accept(); return; } QTextEdit::wheelEvent(e); } void TextEditor::replaceWord() { QAction * action = (QAction *) sender(); QTextCursor cursor = textCursor(); cursor.select(QTextCursor::WordUnderCursor); cursor.removeSelectedText(); cursor.insertText(action->text()); } void TextEditor::copyAvailable(bool yes) { hasCopy = yes; } void TextEditor::textChanged() { mTextSaved = !(toPlainText().count()); Settings * settings = Settings::instance(); QFont f(font()); f.setPointSize(settings->getFontSize()); setFont(f); } void TextEditor::copyClipboard() { if (!hasCopy) { QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(toPlainText(), QClipboard::Clipboard); } else copy(); } void TextEditor::saveHtml(QFile *file) { QString text = document()->toHtml().toUtf8(); QString newDir = extractFilePath(file->fileName()) + extractFileName(file->fileName()) + ".files"; text.replace("", ""); /*text.replace(workingDir + "output_files", newDir); text.replace("[img src=", ""); text.replace(".bmp]", ".bmp>"); QDir dir(workingDir+"output_files"); dir.rename(workingDir+"output_files", newDir);*/ file->write(text.toAscii()); } void TextEditor::contextMenuRequested(const QPoint &point) { QAction *action; QMenu * menu = new QMenu(this); QStringList sl = spellChecker.suggestions(); //if (sl.count() == 0) { action = new QAction(trUtf8("Undo\tCtrl+Z"), this); action->setShortcut(QKeySequence("Ctrl+Z")); connect(action, SIGNAL(triggered()), this, SLOT(undo())); menu->addAction(action); action = new QAction(trUtf8("Redo\tCtrl+Shift+Z"), this); action->setShortcut(QKeySequence("Ctrl+Shift+Z")); connect(action, SIGNAL(triggered()), this, SLOT(redo())); menu->addAction(action); action = new QAction("separator", this); action->setText(""); action->setSeparator(true); menu->addAction(action); action = new QAction(trUtf8("Select All\tCtrl+A"), this); action->setShortcut(QKeySequence("Ctrl+A")); connect(action, SIGNAL(triggered()), this, SLOT(selectAll())); menu->addAction(action); action = new QAction(trUtf8("Cut\tCtrl+X"), this); action->setShortcut(QKeySequence("Ctrl+X")); connect(action, SIGNAL(triggered()), this, SLOT(cut())); menu->addAction(action); action = new QAction(trUtf8("Copy\tCtrl+C"), this); action->setShortcut(QKeySequence("Ctrl+C")); connect(action, SIGNAL(triggered()), this, SLOT(copyClipboard())); menu->addAction(action); action = new QAction(trUtf8("Paste\tCtrl+V"), this); action->setShortcut(QKeySequence("Ctrl+V")); connect(action, SIGNAL(triggered()), this, SLOT(paste())); menu->addAction(action); action = new QAction("separator", this); action->setText(""); action->setSeparator(true); menu->addAction(action); action = new QAction(trUtf8("Larger Font\tCtrl++"), this); connect(action, SIGNAL(triggered()), this, SLOT(enlargeFont())); menu->addAction(action); action = new QAction(trUtf8("Smaller Font\tCtrl+-"), this); connect(action, SIGNAL(triggered()), this, SLOT(decreaseFont())); menu->addAction(action); //} if (sl.count() > 0) menu->addSeparator(); foreach(QString str, sl) { QAction * action = menu->addAction(str); connect(action, SIGNAL(triggered()), this, SLOT(replaceWord())); } menu->exec(mapToGlobal(point)); delete menu; } void TextEditor::enlargeFont() { Settings * settings = Settings::instance(); int fontSize = font().pointSize(); fontSize++; QFont f(font()); f.setPointSize(fontSize); setFont(f); settings->setFontSize(fontSize); } void TextEditor::decreaseFont() { Settings * settings = Settings::instance(); int fontSize = font().pointSize(); if (fontSize > 1) fontSize--; QFont f(font()); f.setPointSize(fontSize); setFont(f); settings->setFontSize(fontSize); } void TextEditor::updateSP() { Settings * settings = Settings::instance(); if (settings->getCheckSpelling()) spellChecker.checkWord(); } yagf-0.9.2.1/src/CCAnalysis.h0000664000175000017500000000270512250140707016264 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef CCANALYSIS_H #define CCANALYSIS_H #include #include #include "ycommon.h" class QImage; class RotationCropper { public: RotationCropper(QImage * image, QRgb color, int dtr); ~RotationCropper(); QRect crop(); private: void recolor(); bool checkHorzLine(int y); bool checkVertLine(int x); private: QImage * image; QRgb whitePixel; QRgb replaceColor; int darksCount; int lightsCount; int minval; int maxval; //int clAltCount; int whitesCount; int darktr; int whitetr; int whiteAlt; qreal clBrighttoWidth; qreal clBrighttoWidthtr; int clWhiteCount; int y1, y2, x1, x2; }; #endif yagf-0.9.2.1/src/settings.cpp0000664000175000017500000003267412250171073016476 0ustar parallelsparallels/* This program 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. This program 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. */ #include "settings.h" #include "utils.h" #include #include #include #include Settings * Settings::m_instance = NULL; Settings::Settings() { //makeLanguageMaps(); } Settings::Settings(const Settings &) { } Settings::~Settings() { } Settings *Settings::instance() { if (!m_instance) m_instance = new Settings(); return m_instance; } void Settings::readSettings(const QString &path) { mPath = path; mPath = mPath.append("yagf.ini"); settings = new QSettings(mPath, QSettings::IniFormat); lastDir = settings->value("mainwindow/lastDir").toString(); lastOutputDir = settings->value("mainwindow/lastOutputDir").toString(); QString defEngine; if (findProgram("tesseract")&&(!findProgram("cuneiform"))) defEngine = "tesseract"; else defEngine = "cuneiform"; QString engine = settings->value("ocr/engine", QVariant(defEngine)).toString(); if (engine == "cuneiform") selectedEngine = UseCuneiform; else selectedEngine = UseTesseract; language = settings->value("ocr/language", selectDefaultLanguageName()).toString(); //selectLangsBox->setCurrentIndex(selectLangsBox->findData(QVariant(language))); outputFormat = settings->value("ocr/outputFormat", QString("text")).toString(); if (outputFormat == "") outputFormat = "text"; checkSpelling = settings->value("mainWindow/checkSpelling", bool(true)).toBool(); bool ok; fontSize = settings->value("mainwindow/fontSize", int(12)).toInt(&ok); noLocale = settings->value("mainwindow/nolocale", QVariant(false)).toBool(); RussianLocale = settings->value("mainwindow/rulocale", QVariant(false)).toBool(); findTessDataPath(); tessdataPath = settings->value("ocr/tessData", QVariant(tessdataPath)).toString(); if (tessdataPath.isEmpty()) findTessDataPath(); cropLoaded = settings->value("processing/crop1", QVariant(true)).toBool(); size = settings->value("mainwindow/size", QSize(800, 600)).toSize(); iconSize = settings->value("mainwindow/iconSize", QSize(48, 48)).toSize(); position = settings->value("mainwindow/pos", QPoint(0, 0)).toPoint(); fullScreen = settings->value("mainwindow/fullScreen", QVariant(false)).toBool(); } void Settings::writeSettings() { settings->setValue("mainwindow/size", size); settings->setValue("mainwindow/iconSize", iconSize); settings->setValue("mainwindow/pos", position); settings->setValue("mainwindow/fullScreen", fullScreen); settings->setValue("mainwindow/lastDir", lastDir); settings->setValue("mainWindow/checkSpelling", checkSpelling); settings->setValue("mainwindow/lastOutputDir", lastOutputDir); settings->setValue("mainwindow/fontSize", fontSize); settings->setValue("mainwindow/nolocale", noLocale); settings->setValue("mainwindow/rulocale", RussianLocale); settings->setValue("ocr/language", language); //settings->setValue("ocr/singleColumn", singleColumn); settings->setValue("ocr/outputFormat", outputFormat); QString engine = selectedEngine == UseCuneiform ? QString("cuneiform") : QString("tesseract"); settings->setValue("ocr/engine", engine); settings->setValue("ocr/tessData", tessdataPath); settings->setValue("processing/crop1", cropLoaded); settings->sync(); } QString Settings::getLanguage() { return language; } QString Settings::getOutputFormat() { return outputFormat; } QString Settings::getLastDir() { return lastDir; } QString Settings::getLastOutputDir() { return lastOutputDir; } bool Settings::getCheckSpelling() { return checkSpelling; } QString Settings::getTessdataPath() { if (!tessdataPath.endsWith("/")) tessdataPath = tessdataPath.append("/"); return tessdataPath; } SelectedEngine Settings::getSelectedEngine() { return selectedEngine; } QSize Settings::getSize() { return size; } QPoint Settings::getPosition() { return position; } bool Settings::getFullScreen() { return fullScreen; } int Settings::getFontSize() { return fontSize; } bool Settings::getCropLoaded() { return cropLoaded; } void Settings::setLanguage(const QString &value) { language = value; } void Settings::setOutputFormat(const QString &value) { outputFormat = value; } void Settings::setLastDir(const QString &value) { lastDir = value; } void Settings::setLastOutputDir(const QString &value) { lastOutputDir = value; } void Settings::setCheckSpelling(const bool value) { checkSpelling = value; } void Settings::setTessdataPath(const QString &value) { tessdataPath = value; } void Settings::setSelectedEngine(const SelectedEngine value) { selectedEngine = value; } void Settings::setSize(const QSize &value) { size = value; } void Settings::setPosition(const QPoint &value) { position = value; } void Settings::setFullScreen(const bool value) { fullScreen = value; } void Settings::setFontSize(const int &value) { fontSize = value; } void Settings::setCropLoaded(const bool value) { cropLoaded = value; } QString Settings::workingDir() { QString wDir = QDir::homePath(); if (!wDir.endsWith("/")) wDir += '/'; QDir d(wDir + ".config"); if (d.exists()) wDir += ".config/"; QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); wDir = env.value("XDG_CONFIG_HOME", wDir); if (!wDir.endsWith("/")) wDir += '/'; wDir += "yagf/"; QDir dir(wDir); if (!dir.exists()) dir.mkdir(wDir); return wDir; } void Settings::startLangPair() { lpi = 0; } bool Settings::getLangPair(QString &full, QString &abbr) { QMap * map; if (selectedEngine == UseCuneiform) map = &cuMap; if (selectedEngine == UseTesseract) map = &tesMap; full = map->keys().at(lpi); abbr = map->value(full); lpi++; if (lpi < map->count()) return true; return false; } void Settings::setProjectDir(const QString &dir) { projectDir = dir; } QString Settings::getProjectDir() { return projectDir; } void Settings::makeLanguageMaps() { cuMap.insert(QObject::trUtf8("Bulgarian"), "bul"); cuMap.insert(QObject::trUtf8("Czech"), "cze"); cuMap.insert(QObject::trUtf8("Danish"), "dan"); cuMap.insert(QObject::trUtf8("Dutch"), "dut"); cuMap.insert(QObject::trUtf8("English"), "eng"); cuMap.insert(QObject::trUtf8("French"), "fra"); cuMap.insert(QObject::trUtf8("German"), "ger"); cuMap.insert(QObject::trUtf8("Hungarian"), "hun"); cuMap.insert(QObject::trUtf8("Italian"), "ita"); cuMap.insert(QObject::trUtf8("Latvian"), "lav"); cuMap.insert(QObject::trUtf8("Lithuanian"), "lit"); cuMap.insert(QObject::trUtf8("Polish"), "pol"); cuMap.insert(QObject::trUtf8("Portuguese"), "por"); cuMap.insert(QObject::trUtf8("Romanian"), "rum"); cuMap.insert(QObject::trUtf8("Russian"), "rus"); cuMap.insert(QObject::trUtf8("Russian-English"), "ruseng"); cuMap.insert(QObject::trUtf8("Spanish"), "spa"); cuMap.insert(QObject::trUtf8("Serbian"), "srp"); cuMap.insert(QObject::trUtf8("Slovenian"), "slo"); cuMap.insert(QObject::trUtf8("Swedish"), "swe"); cuMap.insert(QObject::trUtf8("Ukrainian"), "ukr"); tesMap.insert(QObject::trUtf8("Bulgarian"), "bul"); tesMap.insert(QObject::trUtf8("Czech"), "ces"); tesMap.insert(QObject::trUtf8("Danish"), "dan"); tesMap.insert(QObject::trUtf8("Dutch"), "nld"); tesMap.insert(QObject::trUtf8("English"), "eng"); tesMap.insert(QObject::trUtf8("Finnish"), "fin"); tesMap.insert(QObject::trUtf8("French"), "fra"); tesMap.insert(QObject::trUtf8("German"), "deu"); tesMap.insert(QObject::trUtf8("German Gothic"), "gerf"); tesMap.insert(QObject::trUtf8("Greek"), "ell"); tesMap.insert(QObject::trUtf8("Hebrew"), "heb"); tesMap.insert(QObject::trUtf8("Hungarian"), "hun"); tesMap.insert(QObject::trUtf8("Italian"), "ita"); tesMap.insert(QObject::trUtf8("Latvian"), "lav"); tesMap.insert(QObject::trUtf8("Lithuanian"), "lit"); tesMap.insert(QObject::trUtf8("Norwegian"), "nor"); tesMap.insert(QObject::trUtf8("Polish"), "pol"); tesMap.insert(QObject::trUtf8("Portuguese"), "por"); tesMap.insert(QObject::trUtf8("Romanian"), "ron"); tesMap.insert(QObject::trUtf8("Russian"), "rus"); tesMap.insert(QObject::trUtf8("Serbian"), "srp"); tesMap.insert(QObject::trUtf8("Slovenian"), "slv"); tesMap.insert(QObject::trUtf8("Slovak"), "slk"); tesMap.insert(QObject::trUtf8("Spanish"), "spa"); tesMap.insert(QObject::trUtf8("Swedish"), "swe"); tesMap.insert(QObject::trUtf8("Swedish Gothic"), "swef"); tesMap.insert(QObject::trUtf8("Turkish"), "tur"); tesMap.insert(QObject::trUtf8("Ukrainian"), "ukr"); } void Settings::findTessDataPath() { QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); if (env.contains("TESSDATA_PREFIX")) { tessdataPath = env.value("TESSDATA_PREFIX"); return; } QDir dir; dir.setPath("/usr/share/tessdata"); if (dir.exists()) { tessdataPath = "/usr/share/"; return; } dir.setPath("/usr/local/share/tessdata"); if (dir.exists()) { tessdataPath = "/usr/local/share/"; return; } dir.setPath("/usr/local/share/tesseract-ocr/tessdata"); if (dir.exists()) { tessdataPath = "/usr/local/share/tesseract-ocr/"; return; } dir.setPath("/usr/share/tesseract-ocr/tessdata"); if (dir.exists()) { tessdataPath = "/usr/share/tesseract-ocr/"; return; } tessdataPath.clear(); return; } QString Settings::selectDefaultLanguageName() { QLocale loc = QLocale::system(); QString name = ""; QMap * map; if (selectedEngine == UseCuneiform) map = &cuMap; if (selectedEngine == UseTesseract) map = &tesMap; switch (loc.language()) { case QLocale::Bulgarian: name = map->value("Bulgarian"); break; case QLocale::Czech: name = map->value("Czech"); break; case QLocale::Danish: name = map->value("Danish"); break; case QLocale::German: name = map->value("German"); break; case QLocale::Dutch: name = map->value("Dutch"); break; case QLocale::Russian: name = map->value("Russian"); break; case QLocale::English: name = "eng"; break; case QLocale::Spanish: name = map->value("Spanish"); break; case QLocale::French: name = map->value("French"); break; case QLocale::Hungarian: name = map->value("Hungarian"); break; case QLocale::Italian: name = map->value("Italian"); break; case QLocale::Latvian: name = map->value("Latvian"); break; case QLocale::Lithuanian: name = map->value("Lithuanian"); break; case QLocale::Polish: name = map->value("Polish"); break; case QLocale::Portuguese: name = map->value("Portuguese"); break; case QLocale::Romanian: name = map->value("Romanian"); break; case QLocale::Swedish: name = map->value("Swedish"); break; case QLocale::Serbian: name = map->value("Serbian"); break; case QLocale::Slovenian: name = map->value("Slovenian"); break; case QLocale::Slovak: name = map->value("Slovak", "eng"); break; case QLocale::Ukrainian: name = map->value("Ukrainian"); break; case QLocale::Finnish: name = map->value("Finnish", "eng"); break; case QLocale::Greek: name = map->value("Greek", "eng"); break; case QLocale::Hebrew: name = map->value("Hebrew", "eng"); break; case QLocale::Norwegian: name = map->value("Norwegian", "eng"); break; case QLocale::Turkish: name = map->value("Turkish", "eng"); break; default: break; } if (name == "") name = "eng"; return name; } QSize Settings::getIconSize() { return iconSize; } void Settings::setIconSize(const QSize &value) { iconSize = value; } bool Settings::useNoLocale() { return noLocale; } bool Settings::useRussianLocale() { return RussianLocale; } void Settings::setNoLocale(bool value) { noLocale = value; } void Settings::setRussianLocale(bool value) { RussianLocale = value; } yagf-0.9.2.1/src/qgraphicsinput.cpp0000664000175000017500000004154412247205425017700 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "qgraphicsinput.h" #include "qxtgraphicsview.h" #include "qxtgraphicsproxywidget.h" #include "ccbuilder.h" #include "analysis.h" #include "PageAnalysis.h" #include "math.h" #include "ycommon.h" #include "tblock.h" #include #include #include #include #include #include #include #include #include QGraphicsInput::QGraphicsInput(const QRectF &sceneRect, QGraphicsView *view) : QGraphicsScene(sceneRect) { setView(view); m_image = 0; selecting = NoSelect; hasImage = false; m_LastSelected = 0; buttonPressed = Qt::NoButton; near_res = 0; magnifierCursor = new QCursor(Qt::SizeAllCursor); toolbar = 0; redRect.setX(0); redRect.setY(0); redRect.setWidth(0); redRect.setHeight(0); xred = false; } QGraphicsInput::~QGraphicsInput() { delete magnifierCursor; } void QGraphicsInput::addToolBar() { toolbar = new QToolBar(m_view); toolbar->setMouseTracking(false); toolbar->setMovable(false); toolbar->setWindowOpacity(0.75); toolbar->move(0,0); toolbar->setIconSize(QSize(24,24)); toolbar->setMinimumHeight(32); //toolbar->setCursor(); actionList.at(0)->setText(QString::fromUtf8(">>")); setToolBarVisible(); //QXtGraphicsProxyWidget * pw = new QXtGraphicsProxyWidget(); //pw->setWidget(toolbar); //pw->setZValue(100); //this->addItem(pw); //pw->setView((QXtGraphicsView *) views().at(0)); //toolbar->setParent(0); toolbar->show(); foreach (QAction * action, actionList) { toolbar->addAction(action); } ((QXtGraphicsView *) views().at(0))->sendScrollSignal(); } bool QGraphicsInput::loadImage(const QPixmap &pixmap) { clear(); m_LastSelected = 0; m_CurrentBlockRect = 0; // clearBlocks(); m_image = addPixmap(pixmap); setSceneRect(pixmap.rect()); m_image->setZValue(-1); QApplication::processEvents(); //m_realImage->setData(1, "image"); //m_realImage->hide(); this->setFocus(); m_image->setFocus(); m_image->setAcceptedMouseButtons(Qt::LeftButton | Qt::RightButton | Qt::MidButton); m_image->setAcceptHoverEvents(true); m_image->setData(1, "image"); addToolBar(); if (m_view) { m_view->centerOn(0, 0); m_view->show(); update(); hasImage = true; return true; } else return false; } void QGraphicsInput::setView(QGraphicsView *view) { m_view = view; if (m_view) m_view->setScene(this); } void QGraphicsInput::mousePressEvent(QGraphicsSceneMouseEvent *event) { QGraphicsScene::mousePressEvent(event); // QMessageBox::critical(0, "MOUS111", "MOUSE"); if (!hasImage) return; if (event->buttons() == Qt::LeftButton) { buttonPressed = Qt::LeftButton; if (selecting == NoSelect) { if ((near_res = nearActiveBorder(event->scenePos().x(), event->scenePos().y())) != 0) { m_CurrentBlockRect = m_LastSelected; selecting = Selecting; blockRect = m_CurrentBlockRect->rect(); } else { selecting = StartSelect; blockRect.setLeft(event->lastScenePos().x()); blockRect.setTop(event->lastScenePos().y()); blockRect.setWidth(10); blockRect.setHeight(10); } } else { //TODO!!! } } else buttonPressed = Qt::RightButton; } void QGraphicsInput::deleteBlockRect(QGraphicsRectItem *item) { if (item == 0) return; if (item == m_CurrentBlockRect) m_CurrentBlockRect = 0; if (item == m_LastSelected) m_LastSelected = 0; removeItem(item); } void QGraphicsInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { QGraphicsScene::mouseReleaseEvent(mouseEvent); if (buttonPressed == Qt::LeftButton) { if (selecting == Selecting) { selecting = NoSelect; if ((blockRect.width() < 12) || (blockRect.height() < 12)) { if (m_CurrentBlockRect == m_LastSelected) m_LastSelected = 0; deleteBlockRect(m_CurrentBlockRect); //clik!!! leftMouseRelease(mouseEvent->scenePos().x(), mouseEvent->scenePos().y()); } else emit blockCreated(QRectF2Rect(m_CurrentBlockRect->rect())); if (xred) emit deleteBlock(redRect); xred = false; m_CurrentBlockRect = 0; } if (selecting == StartSelect) { selecting = NoSelect; m_CurrentBlockRect = 0; leftMouseRelease(mouseEvent->scenePos().x(), mouseEvent->scenePos().y()); } } if (buttonPressed == Qt::RightButton) { this->rightMouseRelease(mouseEvent->scenePos().x(), mouseEvent->scenePos().y()); } buttonPressed = Qt::NoButton; } QGraphicsRectItem *QGraphicsInput::newBlock(const QRectF &rect) { QPen p(Qt::SolidLine); QBrush b(Qt::SolidPattern); b.setColor(QColor(0, 0, 127, 127)); p.setWidth(2); p.setColor(QColor(0, 0, 255)); QGraphicsRectItem *res; res = this->addRect(rect, p, b); res->setAcceptHoverEvents(true); res->setZValue(1); res->setData(1, "block"); res->setData(2, "no"); return res; } bool QGraphicsInput::addBlock(const QRectF &rect, bool removeObstacles) { QGraphicsRectItem *block = newBlock(rect); if (!removeObstacles) { if (block->collidingItems().size() > 0) { deleteBlockRect(block); return false; } } else { for (int i = block->collidingItems().size() - 1; i >= 0; i--) { if (block->collidingItems().at(i)->data(1) == "block") deleteBlockRect((QGraphicsRectItem *) block->collidingItems().at(i)); } } m_CurrentBlockRect = block; return true; } void QGraphicsInput::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { QGraphicsScene::mouseMoveEvent(mouseEvent); if (selecting == StartSelect) { selecting = Selecting; m_CurrentBlockRect = newBlock(blockRect); } if ((mouseEvent->modifiers() & Qt::ControlModifier) == 0) if (mouseEvent->buttons() == Qt::NoButton) { near_res = nearActiveBorder(mouseEvent->scenePos().x(), mouseEvent->scenePos().y()); switch (near_res) { case 0: m_view->viewport()->setCursor(Qt::ArrowCursor); break; case 1: m_view->viewport()->setCursor(Qt::SplitHCursor); break; case 2: m_view->viewport()->setCursor(Qt::SplitVCursor); break; case 3: m_view->viewport()->setCursor(Qt::SplitHCursor); break; case 4: m_view->viewport()->setCursor(Qt::SplitVCursor); break; default: break; } } QRectF newRect; if (near_res && (mouseEvent->buttons()&Qt::LeftButton)) { if (!xred) redRect = QRectF2Rect(m_LastSelected->rect()); xred = true; QRectF newRect = m_LastSelected->mapRectToScene(m_LastSelected->rect()); switch (near_res) { case 1: newRect.setLeft(mouseEvent->lastScenePos().x()); break; case 2: newRect.setTop(mouseEvent->lastScenePos().y()); break; case 3: newRect.setRight(mouseEvent->lastScenePos().x()); break; case 4: newRect.setBottom(mouseEvent->lastScenePos().y()); break; default: break; } m_CurrentBlockRect = m_LastSelected; m_CurrentBlockRect->setRect(m_LastSelected->mapRectFromScene(newRect)); for (int i = 0; i < m_CurrentBlockRect->collidingItems().size(); ++i) if (m_CurrentBlockRect->collidingItems().at(i)->data(1) == "block") { m_CurrentBlockRect->setRect(m_LastSelected->mapRectFromScene(selBlockRect)); return; } selBlockRect = newRect; return; } if (selecting == Selecting) { newRect = blockRect; if (newRect.left() < mouseEvent->lastScenePos().x()) newRect.setRight(mouseEvent->lastScenePos().x()); else newRect.setLeft(mouseEvent->lastScenePos().x()); if (newRect.top() < mouseEvent->lastScenePos().y()) newRect.setBottom(mouseEvent->lastScenePos().y()); else newRect.setTop(mouseEvent->lastScenePos().y()); m_CurrentBlockRect->setRect(newRect); for (int i = 0; i < m_CurrentBlockRect->collidingItems().size(); ++i) if (m_CurrentBlockRect->collidingItems().at(i)->data(1) == "block") { m_CurrentBlockRect->setRect(blockRect); return; } blockRect = newRect; return; } if (!toolbar.isNull()) { // if (mouseEvent->pos().y() < toolbar->height()) // toolbar->setFocus(); } } void QGraphicsInput::leftMouseRelease(qreal x, qreal y) { QGraphicsItem *it = this->itemAt(x, y); if (it) { if (it->data(1).toString() == "block") { QGraphicsRectItem *r = (QGraphicsRectItem *) it; QPen p(Qt::SolidLine); QBrush b(Qt::SolidPattern); b.setColor(QColor(0, 0, 127, 127)); p.setColor(QColor(0, 0, 255)); p.setWidth(2); if (r->data(2).toString() == "no") { //select block!!!! if (m_LastSelected) { m_LastSelected->setPen(p); m_LastSelected->setBrush(b); m_LastSelected->setData(2, "no"); } b.setColor(QColor(127, 0, 0, 127)); p.setColor(QColor(255, 0, 0)); r->setData(2, "yes"); m_LastSelected = r; selBlockRect = m_LastSelected->rect(); redRect = QRectF2Rect(selBlockRect); // ATT // emit addBlock(QRectF2Rect(selBlockRect)); } else { m_LastSelected = 0; r->setData(2, "no"); } r->setPen(p); r->setBrush(b); // m_CurrentBlockRect = r; } } else m_CurrentBlockRect = 0; emit leftMouseClicked(m_view->mapFromScene(x, y).x(), m_view->mapFromScene(x, y).y(), m_CurrentBlockRect != 0); } void QGraphicsInput::rightMouseRelease(qreal x, qreal y) { QGraphicsItem *it = this->itemAt(x, y); if (it) { if (it->data(1).toString() == "block") { m_CurrentBlockRect = (QGraphicsRectItem *) it; } } else m_CurrentBlockRect = 0; emit rightMouseClicked(m_view->mapFromScene(x, y).x(), m_view->mapFromScene(x, y).y(), m_CurrentBlockRect != 0); } int QGraphicsInput::nearActiveBorder(qreal x, qreal y) { if (m_LastSelected == 0) return 0; x = m_LastSelected->mapFromScene(x, y).x(); y = m_LastSelected->mapFromScene(x, y).y(); qreal xcenter = m_LastSelected->rect().center().x(); qreal ycenter = m_LastSelected->rect().center().y(); qreal xcd = abs(m_LastSelected->rect().right() - xcenter) + 8; qreal ycd = abs(m_LastSelected->rect().bottom() - ycenter) + 8; if ((abs(x - m_LastSelected->rect().left()) <= 4)) { if (abs(y - ycenter) < ycd) return 1; else return 0; } if ((abs(m_LastSelected->rect().top() - y) <= 4)) { if (abs(x - xcenter) < xcd) return 2; else return 0; } if ((abs(x - m_LastSelected->rect().right()) <= 4)) { if (abs(y - ycenter) < ycd) return 3; else return 0; } if ((abs(m_LastSelected->rect().bottom() - y) <= 4)) { if (abs(x - xcenter) < xcd) return 4; else return 0; } return 0; } QRect QGraphicsInput::getActiveBlock() { return QRectF2Rect(m_LastSelected->rect()); } QRect QGraphicsInput::getCurrentBlock() { return QRectF2Rect(m_CurrentBlockRect->rect()); } void QGraphicsInput::deleteCurrentBlock() { if (m_CurrentBlockRect != 0) deleteBlockRect(m_CurrentBlockRect); } void QGraphicsInput::deleteBlock(int index) { int count = 0; for (int i = 0; i < items().count(); i++) { if (items().at(i)->data(1) == "block") { if (index == count) { deleteBlockRect((QGraphicsRectItem *)items().at(i)); return; } count++; } } } void QGraphicsInput::clearBlocks() // KEEP { for (int i = items().count() - 1; i >= 0; i--) { if (items().at(i)->data(1) == "block") { deleteBlockRect((QGraphicsRectItem *)items().at(i)); } } } void QGraphicsInput::setMagnifierCursor(QCursor *cursor) { delete magnifierCursor; magnifierCursor = new QCursor(cursor->pixmap()); } void QGraphicsInput::addToolBarAction(QAction *action) { actionList.append(action); } void QGraphicsInput::addToolBarSeparator() { QAction * action = new QAction(" | ", 0); action->setEnabled(false); actionList.append(action); } void QGraphicsInput::setToolBarVisible() { if (toolbar.isNull()) return; if (actionList.at(0)->text() == QString::fromUtf8("<<")) { for (int i = 1; i < actionList.count(); i++) actionList.at(i)->setVisible(false); toolbar->setMaximumWidth(32); toolbar->setMinimumWidth(32); actionList.at(0)->setText(QString::fromUtf8(">>")); } else { for (int i = 1; i < actionList.count(); i++) actionList.at(i)->setVisible(true); toolbar->setMaximumWidth(480); toolbar->setMinimumWidth(480); actionList.at(0)->setText(QString::fromUtf8("<<")); } } void QGraphicsInput::wheelEvent(QGraphicsSceneWheelEvent *wheelEvent) { if (wheelEvent->modifiers() == Qt::ControlModifier) { int delta = wheelEvent->delta(); qreal coeff = delta < 0 ? 1 / (1 - delta / (360.)) : 1 + delta / (240.); if (coeff >= 1) emit increaseMe(); else emit decreaseMe(); wheelEvent->accept(); m_view->viewport()->setCursor(*magnifierCursor); } else QGraphicsScene::wheelEvent(wheelEvent); } void QGraphicsInput::keyReleaseEvent(QKeyEvent *keyEvent) { if (keyEvent->key() == Qt::Key_Control) m_view->viewport()->setCursor(Qt::ArrowCursor); if (keyEvent->modifiers() & Qt::ControlModifier) { if ((keyEvent->key() == Qt::Key_Plus) || (keyEvent->key() == Qt::Key_Equal)) { emit increaseMe(); return; } if ((keyEvent->key() == Qt::Key_Minus) || (keyEvent->key() == Qt::Key_Underscore)) { emit decreaseMe(); return; } } if (keyEvent->key() > Qt::Key_F1) { emit keyPressed((int)keyEvent->key()); } } void QGraphicsInput::clearTransform() { if (m_view) { QTransform tr = m_view->transform(); tr.reset(); m_view->setTransform(tr); } } void QGraphicsInput::keyPressEvent(QKeyEvent *keyEvent) { if (keyEvent->key() == Qt::Key_Control) { m_view->viewport()->setCursor(*magnifierCursor); //QApplication:: } } void QGraphicsInput::drawLine(int x1, int y1, int x2, int y2) { QPen pen(QColor("red")); pen.setWidth(2); this->addLine(x1, y1, x2, y2, pen); } void QGraphicsInput::imageOrigin(QPoint &p) { p.setX(m_image->mapToScene(0,0).x()); p.setY(m_image->mapToScene(0,0).y()); } QPixmap QGraphicsInput::getCurrentImage() { return (m_image->pixmap()); } void QGraphicsInput::addBlockColliding(Block block) { QGraphicsRectItem *gi = newBlock(block); m_CurrentBlockRect = gi; QGraphicsTextItem * gte = new QGraphicsTextItem(QString::number(block.blockNumber()), gi); gte->setFont(QFont("Arial", 16)); gte->setDefaultTextColor(QColor("white")); gte->moveBy(block.x(), block.y()); } yagf-0.9.2.1/src/popplerdialog.h0000664000175000017500000000236712247205425017145 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef POPPLERDIALOG_H #define POPPLERDIALOG_H #include namespace Ui { class PopplerDialog; } class PopplerDialog : public QDialog { Q_OBJECT public: explicit PopplerDialog(QWidget *parent = 0); ~PopplerDialog(); QString getPDFFile(); QString getStartPage(); QString getStopPage(); private slots: void on_checkBox_toggled(bool checked); void on_pushButton_clicked(); private: Ui::PopplerDialog *ui; }; #endif // POPPLERDIALOG_H yagf-0.9.2.1/src/tpage.cpp0000664000175000017500000003217612250140707015733 0ustar parallelsparallels /* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "tpage.h" #include "imagebooster.h" #include "settings.h" #include "ccbuilder.h" #include "CCAnalysis.h" #include "PageAnalysis.h" #include "analysis.h" #include #include #include #include #include #include #include Page::Page(const int pid, QObject *parent) : QObject(parent), selectedBlock(0,0,0,0) { imageLoaded = false; loadedBefore = false; ccbuilder = NULL; rotation = 0; deskewed = false; preprocessed = false; mFileName.clear(); this->pid = pid; } Page::~Page() { delete ccbuilder; } bool Page::loadFile(QString fileName, bool loadIntoView) { // TODO: перенести в TPages. /*if ((fileName != "") && (sideBar->getFileNames().contains(fileName))) { sideBar->select(fileName); sideBar->clearBlocks(); for (int i = 0; i < graphicsInput->blocksCount(); i++) sideBar->addBlock(graphicsInput->getBlockRectByIndex(i).toRect()); }*/ if (fileName == "") { if(mFileName.isEmpty()) return false; fileName = mFileName; } rotation = 0; crop1.setX(0); crop1.setY(0); crop1.setWidth(0); crop1.setHeight(0); scale = 0.5; QImageReader ir(fileName); ir.setScaledSize(QSize(ir.size().width()/2, ir.size().height()/2)); img2 = ir.read(); imageLoaded = !img2.isNull(); if (!imageLoaded) return false; if (ccbuilder){ delete ccbuilder; ccbuilder = 0; } if (!loadedBefore) { settings = Settings::instance(); if (settings->getCropLoaded()) { ccbuilder = new CCBuilder(img2); ccbuilder->setGeneralBrightness(360); ccbuilder->setMaximumColorComponent(100); QRect r = ccbuilder->crop(); crop1 = r; img2 = img2.copy(crop1); delete ccbuilder; ccbuilder = 0; // ccbuilder = new CCBuilder(img2); } //ccbuilder->labelCCs(); //mGeneralBrightness = ccbuilder->getGB(); } else { if (settings->getCropLoaded()) img2 = img2.copy(crop1); } rotateImageInternal(img2, rotation); scaleImages(); mFileName = fileName; loadedBefore = true; return true; } QPixmap Page::displayPixmap() { return QPixmap::fromImage(currentImage()); } QImage Page::thumbnail() { return img16; } bool Page::makeLarger() { if (scale >= 0.5) return false; if (scale < 0.2) { scale = 0.2; return true; } if (scale < 0.25) { scale = 0.25; return true; } if (scale < 0.5) scale = 0.5; return true; } bool Page::makeSmaller() { if (scale <= 0.125) { return false; } if (scale > 0.25) { scale = 0.25; return true; } if (scale > 0.2) { scale = 0.2; return true; } if (scale > 0.125) scale = 0.125; return true; } void Page::rotate(qreal angle) { rotateImageInternal(img2, angle); rotation += angle; scaleImages(); clearBlocks(); } void Page::unload() { if (ccbuilder){ delete ccbuilder; ccbuilder = 0; } img2 = QImage(0,0,QImage::Format_ARGB32); img4 = QImage(0,0,QImage::Format_ARGB32); img6 = QImage(0,0,QImage::Format_ARGB32); img8 = QImage(0,0,QImage::Format_ARGB32); img16 = QImage(0,0,QImage::Format_ARGB32); imageLoaded = false; } inline bool qrects_equal(QRect &r1, QRect &r2) { if (abs(r1.x() - r2.x()) > 2) return false; if (abs(r1.y() - r2.y()) > 2) return false; if (abs(r1.width() - r2.width()) > 2) return false; if (abs(r1.height() - r2.height()) > 2) return false; return true; } void Page::addBlock(Block block) { QRect r = block; normalizeRect(r); bool add = true; foreach (Block b, blocks) { QRect r1 = b; if (r == r1) { add = false; break; } } if (add) { block.setRect(r.x(), r.y(), r.width(), r.height()); blocks.append(block); } sortBlocksInternal(); renumberBlocks(); } void Page::deleteBlock(const Block &b) { blocks.removeOne(b); sortBlocksInternal(); renumberBlocks(); } void Page::deleteBlock(const QRect &r) { QRect rx = r; normalizeRect(rx); foreach (Block b, blocks) { QRect r1 = b; if (qrects_equal(rx, r1)) { blocks.removeAll(b); break; } } sortBlocksInternal(); renumberBlocks(); } Block Page::getBlock(const QRect &r) { QRect rn =r; normalizeRect(rn); foreach (Block b, blocks) { QRect r1 = b; if (qrects_equal(rn,r1)) { scaleRect(b); return b; } } return Block(0,0,0,0); } Block Page::getBlock(int index) { Block b = blocks.at(index); scaleRect(b); return b; } int Page::blockCount() { return blocks.count(); } void Page::clearBlocks() { blocks.clear(); } void Page::savePageForRecognition(const QString &fileName) { QImageReader ir(mFileName); QImage image = ir.read(); applyTransforms(image, 1); image.save(fileName, "BMP"); } bool Page::savePageAsImage(const QString &fileName, const QString &format) { QImageReader ir(mFileName); QImage image = ir.read(); //applyTransforms(image, 1); return image.save(fileName, format.toAscii().data()); } void Page::saveRawBlockForRecognition(QRect r, const QString &fileName) { normalizeRect(r); saveBlockForRecognition(r, fileName, "BMP"); } void Page::saveBlockForRecognition(QRect r, const QString &fileName, const QString &format) { int oldw = r.width(); int oldh = r.height(); r.setX(r.x()*2); r.setY(r.y()*2); r.setWidth(oldw*2); r.setHeight(oldh*2); QImageReader ir(mFileName); QImage image = ir.read(); applyTransforms(image, 1); image.copy(r).save(fileName, format.toAscii().data()); } void Page::saveBlockForRecognition(int index, const QString &fileName) { saveBlockForRecognition(blocks.at(index), fileName, "BMP"); } void Page::selectBlock(const QRect &r) { QRect rn =r; normalizeRect(rn); foreach (Block b, blocks) { QRect r1 = b; if (rn == r1) { selectedBlock = b; break; } } } Block Page::getSelectedBlock() { return selectedBlock; } void Page::deskew(bool recreateCB) { if (deskewed) return; if (imageLoaded) { prepareCCBuilder(); CCAnalysis * an = new CCAnalysis(ccbuilder); if (an->analize()) { QImage timg = tryRotate(img2, -atan(an->getK())*360/6.283); CCBuilder * cb2 = new CCBuilder(timg); cb2->setGeneralBrightness(360); cb2->setMaximumColorComponent(100); cb2->labelCCs(); CCAnalysis * an2 = new CCAnalysis(cb2); an2->analize(); qreal angle = -atan(an2->getK())*360/6.283; delete an2; delete cb2; if (abs(angle*10) >= abs(5)) angle += (-atan(an->getK())*360/6.283); else angle = -atan(an->getK())*360/6.283; rotate(angle); deskewed = true; delete ccbuilder; ccbuilder = 0; if (recreateCB) prepareCCBuilder(); } delete an; } } void Page::rotate90CW() { rotate(90); } void Page::rotate90CCW() { rotate(-90); } void Page::rotate180() { rotate(180); } void Page::blockAllText() { prepareCCBuilder(); clearBlocks(); BlockSplitter bs; bs.setImage(img2, rotation, scale); QRect r = bs.getRootBlock(currentImage()); addBlock(r); } QList Page::splitInternal() { clearBlocks(); BlockSplitter bs; //rotation = 0; bs.setImage(img2, 0, 0.5);// sideBar->getScale()); bs.splitBlocks(); return bs.getBlocks(); } void Page::prepareCCBuilder() { if (!ccbuilder) { ccbuilder = new CCBuilder(img2); ccbuilder->setGeneralBrightness(360); ccbuilder->setMaximumColorComponent(100); ccbuilder->labelCCs(); } } bool Page::splitPage(bool preprocess) { QList blocks; prepareCCBuilder(); if (preprocess) { QString fn =Settings::instance()->workingDir() + QString::fromUtf8("tmp-%1.bmp").arg((quint64)img2.data_ptr()); saveTmpPage(fn, !preprocessed, !preprocessed, false); loadedBefore = false; loadFile(fn); blocks = splitInternal(); /*if (blocks.count() == 0) { deskew(); fn =Settings::instance()->workingDir() + QString::fromUtf8("tmp-%1.bmp").arg((quint64)img2.data_ptr()); saveTmpPage(fn, true, false); loadedBefore = false; loadFile(fn); blocks = splitInternal(); }*/ if (!preprocessed) { fn =Settings::instance()->workingDir() + QString::fromUtf8("tmp-%1.bmp").arg((quint64)img2.data_ptr()); if (blocks.count() == 0) { saveTmpPage(fn, false, false, true, 2); } else { saveTmpPage(fn, false, false, false, 7, 5); } loadedBefore = false; loadFile(fn); blocks = splitInternal(); } preprocessed = true; } else { deskew(); blocks = splitInternal(); } qreal sf = 2.0*scale; foreach (Rect block, blocks) { QRect r; block.x1 *=sf; block.y1 *=sf; block.x2 *= sf; block.y2 *=sf; r.setX(block.x1); r.setY(block.y1); r.setWidth(block.x2 - block.x1); r.setHeight(block.y2 - block.y1); addBlock(r); } return blocks.count() != 0; } QString Page::fileName() { return mFileName; } int Page::pageID() { return pid; } void Page::sortBlocksInternal() { sortBlocks(blocks); } bool Page::isDeskewed() { return deskewed; } bool Page::isPreprocessed() { return preprocessed; } qreal Page::getRotation() { return rotation; } void Page::setDeskewed(bool value) { deskewed = value; } void Page::setPreprocessed(bool value) { preprocessed = value; } void Page::applyTransforms(QImage &image, qreal scale) { scale = scale*2; QRect crop; crop.setX(crop1.x()*scale); crop.setY(crop1.y()*scale); crop.setWidth(crop1.width()*scale); crop.setHeight(crop1.height()*scale); image = image.copy(crop); rotateImageInternal(image, rotation); } void Page::rotateImageInternal(QImage &image, qreal angle) { qreal x = image.width() / 2; qreal y = image.height() / 2; image = image.transformed(QTransform().translate(-x, -y).rotate(angle).translate(x, y), Qt::SmoothTransformation); } void Page::scaleImages() { img4 = img2.scaledToWidth(img2.width() / 2); img6 = img2.scaledToWidth(img2.width() / 2.5); img8 = img4.scaledToWidth(img4.width() / 2); img16 = img8.scaledToWidth(img8.width() / 2); } void Page::normalizeRect(QRect &rect) { qreal oldw = rect.width(); qreal oldh = rect.height(); rect.setX(rect.x()*0.5/scale); rect.setY(rect.y()*0.5/scale); rect.setWidth(oldw*0.5/scale); rect.setHeight(oldh*0.5/scale); } void Page::scaleRect(QRect &rect) { qreal oldw = rect.width(); qreal oldh = rect.height(); rect.setX(rect.x()/0.5*scale); rect.setY(rect.y()/0.5*scale); rect.setWidth(oldw/0.5*scale); rect.setHeight(oldh/0.5*scale); } QImage Page::tryRotate(QImage image, qreal angle) { qreal x = image.width() / 2; qreal y = image.height() / 2; return image.transformed(QTransform().translate(-x, -y).rotate(angle).translate(x, y), Qt::SmoothTransformation); } QImage Page::currentImage() { if (scale <= 0.125) return img8; if (scale <= 0.2) return img6; if (scale <= 0.25) return img4; return img2; } void Page::saveTmpPage(const QString &fileName, bool cc, bool boost, bool brighten, int p, int q) { QImageReader ir(mFileName); QImage image = ir.read().convertToFormat(QImage::Format_ARGB32); if (image.isNull()) return; ImageBooster booster; if (boost) booster.boost(&image); if (brighten) booster.brighten(&image,p,q); if (cc) { deskewed = false; deskew(false); } // booster.flatten(&image); applyTransforms(image, 1); image.save(fileName, "BMP"); } void Page::renumberBlocks() { for (int i = 0; i < blocks.count(); i++) { blocks[i].setBlockNumber(i+1); } } yagf-0.9.2.1/src/spellchecker.h0000664000175000017500000000333512250140707016737 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef SPELLCHECKER_H #define SPELLCHECKER_H #include #include #include typedef QMap StringMap; class QTextEdit; class QRegExp; class QTextCursor; class QStringList; class SpellChecker { public: SpellChecker(QTextEdit *textEdit); ~SpellChecker(); void unSpellCheck(); void setLanguage(const QString &lang); bool spellCheck(); //Returns false only if the dictionary not found. Otherwise always true. void checkWord(); void enumerateDicts(); bool hasDict(const QString &shname); QStringList suggestions(); private: void _checkWord(QTextCursor *cursor); QTextEdit *m_textEdit; QRegExp *m_regExp; QString m_lang1; QString m_lang2; StringMap *m_map; AspellConfig *spell_config1; AspellConfig *spell_config2; AspellSpeller *spell_checker1; AspellSpeller *spell_checker2; QStringList *dictList; QString bad_language; }; #endif // SPELLCHECKER_H yagf-0.9.2.1/src/ccbuilder.h0000664000175000017500000000552212247205425016234 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef CCBUILDER_H #define CCBUILDER_H #include #include #include #include #include //#define DEBUG_CC typedef QList IntList; /* This class builds a 2-dimensional array for an image in which the connected pixels are labeled with the same numbers. The elements of the resulting array may be accesed using the label() method. */ class CCBuilder : public QObject { Q_OBJECT public: /* pixmap is the image to be analysed */ explicit CCBuilder(const QImage &img, QObject *parent = 0); ~CCBuilder(); /* This method sets the threshold for the basckround. If pixel r+g+b value is greater than this value the pixel is considered as the (white) background. Otherwise it is considered as the foregraound to be analyzed. */ void setGeneralBrightness(int value); void setMaximumColorComponent(int value); /* This method resets CCs labels so that they occupy a continuos range of numbers */ void compactLabels(); /* This method returns the label value for original image's x and y. */ quint32 label(int x, int y); /* This method performs the actual connected component's labeling */ int labelCCs(); /* Returns image width */ int width(); /* Returns image height */ int height(); QRect crop(); int getGB(); signals: public slots: private: void initialScan(); void backwardScan(); void forwardScan(); int labelChecked(int x, int y); void setLabel(int x, int y, int newValue); void relabelLineLR(int y); void relabelLineRL(int y); bool isForeground(QRgb value); void scanFirstLineLR(); void scanLineLR(int y); void labelLeftmostPoint(int y); void labelRightmostPoint(int y); int generalBrightness; int maximumComponentBrightness; QImage image; quint32 * labels; bool * flags; bool skipNext; IntList recolor; quint32 maxlabel; bool didRecolor; int w, h; QRect cropRect; #ifdef DEBUG_CC int dcounter; int gcounter; #endif friend class Cropper; }; #endif // CCBUILDER_H yagf-0.9.2.1/src/scanner.h0000664000175000017500000000360512250140707015724 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef SCANNER_H #define SCANNER_H #include #include #include class ScannerBase : public QObject { Q_OBJECT public: explicit ScannerBase(QObject *parent = 0); ~ScannerBase(); void addParameter(const QString &s); void addEnvironmentVar(const QString &s); void setOutputFile(const QString &s); QString programName(); virtual void exec() = 0; signals: void processFinished(); public slots: private slots: void finished( int, QProcess::ExitStatus ); protected: void waitFor(); void execInternal(const QString &s); void setProgramName(const QString &s); void setPreloadLibrary(const QString &s); private: QProcess scanProcess; QStringList parameters; QStringList environment; QString outputFile; QString pName; QString preloadLibrary; }; class ScannerFactory { public: ScannerFactory(); QStringList frontEnds(); ScannerBase * createScannerFE(const QString &name); private: QString findPreloadLibrary(); void findFEs(); private: QString preloadPath; QStringList fes; }; #endif // SCANNERBASE_H yagf-0.9.2.1/src/advancedconfigdialog.ui0000664000175000017500000000416512247205425020603 0ustar parallelsparallels AdvancedConfigDialog 0 0 400 115 Advanced Settings Crop Image When Loaded true Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() AdvancedConfigDialog accept() 248 254 157 274 buttonBox rejected() AdvancedConfigDialog reject() 316 260 286 274 yagf-0.9.2.1/src/sidebar.cpp0000664000175000017500000001076212247205425016246 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "sidebar.h" #include "qsnippet.h" #include #include #include #include #include #include #include SideBar::SideBar(QWidget *parent) : QListWidget(parent) { //setDragDropOverwriteMode(true); current = 0; setMaximumWidth(120); setMinimumWidth(120); connect(this, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(itemActive(QListWidgetItem*,QListWidgetItem*))); setToolTip(trUtf8("Drop files here")); setAcceptDrops(true); setDropIndicatorShown(true); lock = false; } void SideBar::itemActive(QListWidgetItem *item, QListWidgetItem *item2) { if (lock) return; lock = true; if (item) { emit pageSelected(((QSnippet *)item)->pageID()); current = ((QSnippet *)item); } else current = 0; lock = false; } /*void SideBar::dragEnterEvent(QDragEnterEvent *event) { if (!event->mimeData()->hasUrls()) { setCursor(Qt::ForbiddenCursor); event->ignore(); // >mimeData()->setData("application/x-qabstractitemmodeldatalist", QByteArray()); } else { setCursor(Qt::DragCopyCursor); event->accept(); } QListWidget::dragEnterEvent(event); }*/ QStringList SideBar::mimeTypes() const { QStringList qstrList; qstrList.append("text/uri-list"); return qstrList; } Qt::DropActions SideBar::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction; } bool SideBar::dropMimeData(int index, const QMimeData *data, Qt::DropAction action) { // if (action == Qt::MoveAction) // return false; QList urlList; urlList = data->urls(); // retrieve list of urls QStringList files; foreach(QUrl url, urlList) // iterate over list { files.append(url.toLocalFile()); ++index; // increment index to preserve drop order } emit filesDropped(files); return true; } void SideBar::startDrag(Qt::DropActions supportedActions) { supportedActions |= Qt::MoveAction; QDrag * drag = new QDrag(this); QMimeData *mimeData = new QMimeData(); QList urlList; QStringList sl; foreach(QListWidgetItem * lwi, selectedItems()) { QString s = QString::number(((QSnippet *)lwi)->pageID()); sl << s; } mimeData->setUrls(urlList); drag->setMimeData(mimeData); if (drag->exec(supportedActions,Qt::CopyAction) == Qt::CopyAction) { foreach(QListWidgetItem * lwi, selectedItems()) { emit fileRemoved(((QSnippet *) lwi)->pageID()); model()->removeRow(row(lwi)); } } current = 0; } QSnippet * SideBar::getItemByName(const QString &name) { for (int i = 0; i < count(); i++) { if (((QSnippet *)item(i))->getName() == name) return ((QSnippet *)item(i)); } return NULL; } void SideBar::select(const QString &name) { current = getItemByName(name); if (current) current->setSelected(true); } void SideBar::selectFirstFile() { if (count() == 0) { current = NULL; return; } current = (QSnippet *) item(0); } /*void SideBar::dragLeaveEvent(QDragLeaveEvent *event) { setCursor(Qt::ArrowCursor); event->accept(); //QListWidget::dragLeaveEvent(event); } void SideBar::dropEvent(QDropEvent *event) { if (event->mimeData()->hasUrls()) { QList ul = event->mimeData()->urls(); QList::Iterator i; for (i = ul.begin(); i != ul.end(); i++) { QUrl url = *i; this->addFile(url.toLocalFile()); } } setCursor(Qt::ArrowCursor); event->accept(); //QListWidget::dropEvent(event); }*/ yagf-0.9.2.1/src/BlockAnalysis.cpp0000664000175000017500000003034112247205425017366 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "BlockAnalysis.h" #include #include #include #include #include //#define DEBUG BlockAnalysis::BlockAnalysis(QPixmap *pixmap) { m_image = new QImage((pixmap->toImage().convertToFormat(QImage::Format_RGB32))); badImage = m_image->isNull(); this->m_coords = new QRect(m_image->rect()); m_blockMap = NULL; } BlockAnalysis::~BlockAnalysis() { deleteBlock(); delete m_image; } void BlockAnalysis::newBlock() { /*deleteBlock(); m_blockMap = new char * [m_coords->height() - m_coords->top()]; for (int i = 0; i < m_coords->height() - m_coords->top(); i++) m_blockMap[i] = new char[m_coords->width() - m_coords->left()]; for (int i = m_coords->top(); i < m_coords->height(); i++) { QRgb * line = (QRgb *) m_image->scanLine(i); for (int j = m_coords->left(); j < m_coords->width(); j++) { if ((qRed(line[j]) + qGreen(line[j]) + qBlue(line[j])) < treshold) m_blockMap[i-m_coords->top()][j-m_coords->left()] = 0; else m_blockMap[i-m_coords->top()][j-m_coords->left()] = 128; } }*/ } void BlockAnalysis::deleteBlock() { if (m_blockMap != NULL) { for (int i = 0; i < m_coords->height() - m_coords->top(); i++) delete m_blockMap[i]; delete m_blockMap; m_blockMap = NULL; } } void BlockAnalysis::countLinesInImg(int factor, int d) { int ftmp = factor; if (m_image->isNull()) return; for (int i = m_coords->top(); i < m_coords->height(); i++) { int l = i; linesInfo[i] = 0; ftmp = factor; for (int j = m_coords->left(); j < m_coords->width(); j++) { int k = qRed(lines[l][j]) + qGreen(lines[l][j]) + qBlue(lines[l][j]); if (k >= mtreshold - 1) { linesInfo[i]++; #ifdef DEBUG if (d != 0) m_image->setPixel(j, l, (1 << 32) + 1); #endif } else break; ftmp--; if (ftmp == 0) { ftmp = factor; l -= d; if ((l < m_coords->top()) || (l == m_coords->height())) break; } } } longestLine[2] = longestLine[1]; longestLine[1] = longestLine[0]; longestLine[0] = linesInfo[0]; for (int i = m_coords->top(); i < m_coords->height() ; i++) if (linesInfo[i] > longestLine[0]) longestLine[0] = linesInfo[i]; longestCount[2] = longestCount[1]; longestCount[1] = longestCount[0]; longestCount[0] = 0; for (int i = m_coords->top(); i < m_coords->height(); i++) { if (longestLine[0] - linesInfo[i] < 5) longestCount[0]++; } #ifdef DEBUG QImage im = m_image->copy(*m_coords); im.save("/home/andrei/ttt.jpg", "JPEG"); #endif } void BlockAnalysis::countLinesInImg(QImage *_image) { mtreshold = 0; linesInfo = new quint16[_image->rect().height() + _image->rect().top()]; for (int i = 0; i < _image->rect().height() + _image->rect().top(); i++) linesInfo[i] = 0; lines = new QRgb * [_image->rect().height() + _image->rect().top()]; for (int i = _image->rect().top() + _image->rect().height() / 8; i < _image->rect().height() - _image->rect().height() / 8; i++) { QRgb *line = (QRgb *)(m_image->scanLine(i)); lines[i] = line; for (int j = _image->rect().left() + _image->rect().width() / 8; j < _image->rect().width() - _image->rect().width() / 8; j++) { mtreshold = mtreshold + qRed(line[j]) + qGreen(line[j]) + qBlue(line[j]); } } int div = (_image->rect().height() - _image->rect().top()) * (_image->rect().width() - _image->rect().left()); mtreshold = mtreshold / div; if (_image->isNull()) return; for (int i = _image->rect().top() + _image->rect().height() / 8; i < _image->rect().height() - _image->rect().height() / 8; i++) { for (int j = _image->rect().left() + _image->rect().width() / 8; j < _image->rect().width() - _image->rect().width() / 8; j++) { int k = qRed(lines[i][j]) + qGreen(lines[i][j]) + qBlue(lines[i][j]); if (k >= mtreshold - 1) { linesInfo[i]++; #ifdef DEBUG if (d != 0) m_image->setPixel(j, l, (1 << 32) + 1); #endif } else break; } } longestLine[2] = longestLine[1]; longestLine[1] = longestLine[0]; longestLine[0] = linesInfo[0]; for (int i = _image->rect().top(); i < _image->rect().height() ; i++) if (linesInfo[i] > longestLine[0]) longestLine[0] = linesInfo[i]; longestCount[2] = longestCount[1]; longestCount[1] = longestCount[0]; longestCount[0] = 0; for (int i = _image->rect().top(); i < _image->rect().height(); i++) { if (longestLine[0] - linesInfo[i] < 5) longestCount[0]++; } #ifdef DEBUG QImage im = m_image->copy(*m_coords); im.save("/home/andrei/ttt.jpg", "JPEG"); #endif delete lines; delete linesInfo; } int BlockAnalysis::getSkew2() { int ll[7], lc[7]; for (int i = 0; i < 7; i++) { QMatrix m; m.rotate((i - 3) * 2); QImage img = m_image->transformed(m, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGB32); img = img.copy(img.rect()); countLinesInImg(&img); ll[i] = longestLine[0]; lc[i] = longestCount[0]; } int imax = 0; for (int i = 0; i < 7; i++) { if ((ll[i] > ll[imax]) && (lc[i] > lc[imax])) { imax = i; } } int result = (imax - 3) * 2; return result; } int BlockAnalysis::getSkew1() { createLinesInfo(); preScan1(); int ll, lc; int ll1, lc1, div1, dir1; int ll2, lc2, div2, dir2; if (m_coords->width() > 1024) m_coords->setWidth(1024); if (m_coords->height() > m_coords->width() / 2) m_coords->setHeight(m_coords->width() / 2); countLinesInImg(m_coords->width(), 0); ll = longestLine[0]; lc = longestCount[0]; int div = 2; int direction = 1; countLinesInImg(m_coords->width() / div, direction); int safe = 0; while ((longestLine[0] >= longestLine[1]) && (longestCount[0] >= longestCount[1]) && (safe < 512)) { div++; countLinesInImg(m_coords->width() / div, direction); safe++; } ll1 = longestLine[0]; lc1 = longestCount[0]; div1 = div; dir1 = direction; longestLine[0] = ll; longestCount[0] = lc; div = 2; direction = - direction; countLinesInImg(m_coords->width() / div, direction); safe = 0; while ((longestLine[0] >= longestLine[1]) && (longestCount[0] >= longestCount[1]) && (safe < 512)) { div++; countLinesInImg(m_coords->width() / div, direction); safe++; } ll2 = longestLine[0]; lc2 = longestCount[0]; div2 = div; dir2 = direction; int rdir; int rdiv; if ((ll1 > ll2) && (lc1 > lc2)) { rdir = dir1; rdiv = div1; } else { rdir = dir2; rdiv = div2; } float result = atan(((float)(rdiv - 1)) / ((float)m_coords->width()) * rdir) / M_2_PI * 360; QMatrix m; m.rotate(result); QImage *tmp = m_image; m_image = new QImage(tmp->transformed(m, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGB32)); delete tmp; tmp = m_image; m_image = new QImage(tmp->scaled(QSize(tmp->width(), tmp->height()) * 1.1).convertToFormat(QImage::Format_RGB32)); delete tmp; *m_coords = m_image->rect(); delete linesInfo; delete lines; createLinesInfo(); preScan1(); countLinesInImg(m_coords->width(), 0); if ((ll > longestLine[0]) && (lc > longestCount[0])) { result = 0; } // if (((float)longestLine[0])/((float)m_coords->width()) < 0.8) // result = 0; delete linesInfo; delete lines; return result; } int BlockAnalysis::getSkew() { createLinesInfo(); preScan1(); int ll, lc; if (m_coords->width() > 1536) m_coords->setWidth(1536); if (m_coords->height() > m_coords->width() / 2) m_coords->setHeight(m_coords->width() / 2); countLinesInImg(m_coords->width(), 0); ll = longestLine[0]; lc = longestCount[0]; countLinesInImg(m_coords->width() / 4, -1); countLinesInImg(m_coords->width() / 4, 1); int maxRes = 0; if ((longestLine[1] >= longestLine[maxRes]) && (longestCount[1] > longestCount[maxRes])) maxRes = 1; if ((longestLine[2] >= longestLine[maxRes]) && (longestCount[2] > longestCount[maxRes])) maxRes = 2; int direction = 0; if (maxRes == 0) direction = 1; else if (maxRes == 1) direction = -1; else return 0; int div = 4; countLinesInImg(m_coords->width() / div, direction); int safe = 0; while ((longestLine[0] >= longestLine[1]) && (longestCount[0] >= longestCount[1]) && (safe < 512)) { div++; countLinesInImg(m_coords->width() / div, direction); direction = - direction; safe++; } float result = atan(((float)(div - 1)) / ((float)m_coords->width()) * (direction)) / M_2_PI * 360; QMatrix m; m.rotate(result); QImage *tmp = m_image; m_image = new QImage(tmp->transformed(m, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGB32)); *m_coords = m_image->rect(); delete linesInfo; delete lines; delete tmp; createLinesInfo(); preScan1(); countLinesInImg(m_coords->width(), 0); if ((ll > longestLine[0]) && (lc > longestCount[0])) result = 0; if (((float)longestLine[0]) / ((float)m_coords->width()) < 0.8) result = 0; delete linesInfo; delete lines; return result; } void BlockAnalysis::preScan1() { mtreshold = 0; for (int i = m_coords->top(); i < m_coords->height(); i++) { QRgb *line = (QRgb *)(m_image->scanLine(i)); lines[i] = line; for (int j = m_coords->left(); j < m_coords->width(); j++) { mtreshold = mtreshold + qRed(line[j]) + qGreen(line[j]) + qBlue(line[j]); } } int div = (m_coords->height() - m_coords->top()) * (m_coords->width() - m_coords->left()); mtreshold = mtreshold / div; for (int i = m_coords->top(); i < m_coords->height(); i++) { //qint16 pixel1 = qRed(lines[i][m_coords->left()]) + qGreen(lines[i][m_coords->left()]) + qBlue(lines[i][m_coords->left()]); //qint16 pixel2 = qRed(lines[i][m_coords->left() + 1]) + qGreen(lines[i][m_coords->left() + 1]) + qBlue(lines[i][m_coords->left() + 1]); for (int j = m_coords->left() + 2; j < m_coords->width(); j++) { qint16 pixel3 = qRed(lines[i][j]) + qGreen(lines[i][j]) + qBlue(lines[i][j]); if (pixel3 >= mtreshold) { lines[i][j-1] = lines[i][j]; lines[i][j-2] = lines[i][j]; } //pixel1 = pixel2; //pixel2 = pixel3; } lines[i][m_coords->width()-1] = lines[i][m_coords->width()-2]; } for (int i = m_coords->height() - 1; i >= 0; i--) { if (longestLine[0] - linesInfo[i] > 2) { m_coords->setHeight(i + 1); break; } } for (int i = m_coords->top(); i < m_coords->height(); i++) { if (longestLine[0] - linesInfo[i] > 2) { m_coords->setTop(i); break; } } } void BlockAnalysis::createLinesInfo() { linesInfo = new quint16[m_coords->height() + m_coords->top()]; for (int i = 0; i < m_coords->height() + m_coords->top(); i++) linesInfo[i] = 0; lines = new QRgb * [m_coords->height() + m_coords->top()]; } yagf-0.9.2.1/src/forcelocaledialog.ui0000600000175000017500000000543312250076477020122 0ustar parallelsparallels ForceLocaleDialog 0 0 400 203 Dialog GroupBox RadioButton RadioButton RadioButton TextLabel Qt::Vertical 20 40 Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() ForceLocaleDialog accept() 248 254 157 274 buttonBox rejected() ForceLocaleDialog reject() 316 260 286 274 yagf-0.9.2.1/src/droplabel.cpp0000664000175000017500000000354012247205425016575 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "droplabel.h" #include #include #include #include #include #include #include #include DropLabel::DropLabel(QWidget *parent, Qt::WindowFlags f) : QLabel(parent, f) { setAcceptDrops(true); } void DropLabel::dragEnterEvent(QDragEnterEvent *event) { //event->setDropAction(Qt::IgnoreAction); const QMimeData * md = event->mimeData(); QStringList sl = md->formats(); if (!md->formats().contains("text/uri-list")) { setCursor(Qt::ForbiddenCursor); } else { event->setDropAction(Qt::MoveAction); event->accept(); //QCursor cur(lw->selectedItems().at(0)->icon().pixmap(96, 128)); //setCursor(cur); } } void DropLabel::dragLeaveEvent(QDragLeaveEvent *event) { setCursor(Qt::ArrowCursor); event->accept(); } void DropLabel::dropEvent(QDropEvent *event) { if (event->dropAction() == Qt::MoveAction) event->ignore(); else event->accept(); } void DropLabel::setListWidget(QListWidget *w) { lw = 0; } yagf-0.9.2.1/src/translations/0000775000175000017500000000000012250673454016651 5ustar parallelsparallelsyagf-0.9.2.1/src/translations/ts_update.sh0000775000175000017500000000037112247205425021174 0ustar parallelsparallels#!/bin/sh lupdate -noobsolete ../mainform.cpp ../mainform.ui ../popplerdialog.ui ../configdialog.ui ../advancedconfigdialog.ui ../main.cpp ../spellchecker.cpp ../sidebar.cpp ../settings.cpp -ts yagf_ru.ts yagf_lt.ts yagf_de.ts yagf_pl.ts yagf_uk.ts yagf-0.9.2.1/src/translations/yagf_lt.ts0000664000175000017500000005437112247205425020653 0ustar parallelsparallels AdvancedConfigDialog Advanced Settings Sudėtingesni nustatymai Crop Image When Loaded Apkarpyti įkeltą paveikslėlį ConfigDialog OCR Settings OCR nustatymai OCR Engine OCR variklis cuneiform cuneiform tesseract tesseract Tesseract Setup Tesseract nustatymai Location of the tessdata directory: Tesseract direktorijos vieta: MainForm Recognition language Atpažinimo kalba Open Image Atverti failą Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) Grafiniai failai (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) There is an unsaved text in the editor window. Do you want to save it? Rengyklės lange yra neišsaugotas tekstas. Išsaugoti? Warning Perspėjimas Error Klaida No image loaded Grafinio failo įkelti nepavyko Starting cuneiform failed Nepavyko paleisti „Cuneiform“ programos The system said: Sistemos atsakymas: program not found programos rasti nepavyko About YAGF Apie YAGF http://symmetrica.net/cuneiform-linux/yagf-en.html http://symmetrica.net/cuneiform-linux/yagf-en.html Recognizing pages... Atpažįstami puslapiai... Abort Nutraukti Save Image Įrašyti paveikslėlį Importing pages from the PDF document... Importuojami puslapiai iš PDF dokumento... Cancel Atšaukti No compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required). Nerasta tinkama PDF konvertavimo priemonė. Prašome įdiegti „pdftoppm“ įrankį arba „GrostScript“ programų paketą (iš jo bus reikalinga programa „gs“). PDF file name may not be empty PDF failo vardas negali būti tuščias Select an existing directory for output or create some new one Pasirinkite egzistuojantį aplanką sukuriamiems failams arba sukurkite naują Selecting Directory Pasirenkamas aplankas The selected directory is not empty Pasirinktas aplankas netuščias Starting tesseract failed Nepavyko paleisti tesseract cuneiform not found, switching to tesseract Nepavyko rasti cuneiform, perjungiama į tesseract No recognition engine found. Please install either cuneiform or tesseract Nepavyko rasti jokio atpažinimo variklio. Prašome įdiegti cuneiform arba tesseract. tesseract not found, switching to cuneiform Tesseract nerastas, perjungiama į cuneiform No PDF converter installed Neįdiegtas PDF konvertuoklis <p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details. GPL v3. Jei norite sužinoti plačiau, aplankykite <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> svetainę. Using Cuneiform Using Tesseract Scanning is impossible No scanning front-end is found. Please install XSane in order to perform scanning. Failed to Load Image Failed to detect text areas on this page. The page possibly lacks contrast. Try to select blocks manually. The selected directoy is not empty. Please select or create another one. Failed to save the project. Failed to load project. MainWindow S&can... S&kenuoti... Scanning images using XSane... Puslapis skenuojamas naudojant „XSane“... &Save text... &Įrašyti tekstą &Open Image... &Atverti grafinį failą... Open Image Atverti grafinį failą &Recognize &Atpažinti tesktą Recognizing text... Atpažįstamas tekstas... Choose &Language &Parinkti kalbą Quit Išeiti Previous page Ankstesnis puslapis Move to previous image Eiti prie ankstesnio puslapio Next page Kitas puslapis Move to next image Eiti prie tolimesnio puslapio Online Help Pagalba internete About... Apie programą... Recognize &All Pages Atpažinti &visus puslapius Recognize All Pages Atpažinti visus puslapius Ctrl+A Vald+A Clear all blocks Išvalyti visus pažymėjimus Delete the current block Ištrinti šį pažymėjimą Recognize block Atpažinti pažymėjimą Recognize this block Atpažinti šį pažymėjimą Clear numbers Išvalyti skaičius Crear block numbering Išvalyti pažymėjimų numeravimą Check spelling Tikrinti rašybą Save current image... Įrašyti šį paveikslėlį... Save currently opened image in its real size Išsaugoti šiuo metu atvertą paveikslėlį realiu dydžiu Save block Išsaugoti pažymėjimą Save the current block to the image file Įrašyti dabartinį pažymėjimą į paveikslėlio failą Select HTML format Pasirinkti HTML formatą Select HTML format as recognition output Pasirinkti HTML formatą kaip atpažinimo išvestį Larger view Padidinti Smaller view Sumažinti Rotate 90 CCW Pasukti 90 laipsnių prieš laikr. rodyklę Rotate 180 Pasukti 180 laipsnių Rotate 90 CW Pasukti 90 laipsnių pagal laikr. rodyklę &File &Failas &Help &Pagalba Copy To Clipboard Kopijuoti į atmintinę Copy recognized text to clipboard Kopijuoti tekstą į atmintinę MainWindow PagrindinisLangas toolBar įrankiųJuosta Ctrl+N Vald+N Ctrl+S Vald+S Ctrl+O Vald+O Ctrl+R Vald+R Ctrl+Q Vald+Q &Settings &Nustatymai << << Hide/Show Toolbar Slėpti/Rodyti įrankių juostą Import from PDF... Importuoti iš PDF... Import pages from PDF documents Importuoti puslapius iš PDF dokumento OCR Settings OCR nustatymai Set up the OCR parameters Nustatykite OCR parametrus Paste Image Įterpti paveikslėlį Paste image from clipboard Įterpti paveikslėlį iš iškarpinės Select Text Area Pažymėkite teksto sritį Deskew Block Ištiesinti pažymėjimą Deskew the current block Ištiesinti dabartinį pažymėjimą Deskew Ištiesinti Correct the page skew Pataisyti puslapio kreivumą Advanced Settings Sudėtingesni nustatymai The settings you should probably never change Nustatymai, kurių ko gero geriau niekada nekeisti select multiple blocks Splits text into several blocks Toggle Large/Small Icons toolBar_2 Select Recognition Language Prepare Page Save Project... Load Project... Prepare the page for recognition PopplerDialog Import from PDF Importuoti iš PDF File Name Failo pavadinimas Select... Pažymėti... Pages Puslapiai From Nuo To Iki Entire Document Visą dokumentą QObject JPEG Files (*.jpg) JPEG failai (*.jpg) PNG Files (*.png) PNG failai (*.png) Failed to save the image Nepavyko įrašyti paveikslėlio Required spelling dictionary (%1) is not found. Spell-checking is disabled. Try to install an appropriate aspell dictionary. Reikiamo rašybos tikrinimo žodyno (%1) rasti nepavyko Rašybos tikrinimas išjungtas. Prašome įdiegti reikiamą aspell žodyną. Warning Perspėjimas Select Project Directory Bulgarian Czech Danish Dutch English French German Hungarian Italian Latvian Lithuanian Polish Portuguese Romanian Russian Russian-English Spanish Serbian Slovenian Swedish Ukrainian Finnish German Gothic Greek Hebrew Norwegian Slovak Swedish Gothic Turkish SideBar Drop files here Meskite failus čia yagf-0.9.2.1/src/translations/yagf_pl.ts0000664000175000017500000005245112247205425020644 0ustar parallelsparallels AdvancedConfigDialog Advanced Settings Crop Image When Loaded ConfigDialog OCR Settings OCR Engine cuneiform tesseract Tesseract Setup Location of the tessdata directory: MainForm Recognition language Język rozpoznawania Open Image Otwórz plik graficzny Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) Pliki graficzne (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) There is an unsaved text in the editor window. Do you want to save it? W oknie edytora jest niezapisany tekst. Zapisać? Warning Ostrzeżenie Error Błąd No image loaded Brak załadowanego obrazka Starting cuneiform failed Nie udało się uruchomić cuneiform The system said: Odpowiedź systemu: program not found nie znaleziono programu About YAGF О programie http://symmetrica.net/cuneiform-linux/yagf-en.html http://symmetrica.net/cuneiform-linux/yagf-pl.html Save Image Recognizing pages... Rozpoznaję strony... Abort Przerwij Importing pages from the PDF document... Cancel No compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required). PDF file name may not be empty Select an existing directory for output or create some new one Selecting Directory The selected directory is not empty Starting tesseract failed cuneiform not found, switching to tesseract No recognition engine found. Please install either cuneiform or tesseract tesseract not found, switching to cuneiform No PDF converter installed <p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details. Using Cuneiform Using Tesseract Scanning is impossible No scanning front-end is found. Please install XSane in order to perform scanning. Failed to Load Image Failed to detect text areas on this page. The page possibly lacks contrast. Try to select blocks manually. The selected directoy is not empty. Please select or create another one. Failed to save the project. Failed to load project. MainWindow S&can... S&kanuj... Scanning images using XSane... Skanuję strony używając XSane... &Save text... &Zapisz tekst... &Open Image... &Otwórz plik graficzny... Open Image Otwórz plik graficzny &Recognize &Распознать Recognizing text... Rozpoznaj tekst... Choose &Language &Wybierz język Quit Zakończ Previous page Poprzednia strona Move to previous image Przejdź do poprzedniej grafiki Next page Następna strona Move to next image Przejdź do następnej grafiki Online Help Pomoc online About... O programie... Clear all blocks Oczyść wszystkie bloki Delete the current block Usuń bieżący blok Recognize block Rozpoznaj blok Recognize this block Rozpoznaj ten blok Clear numbers Crear block numbering Check spelling Sprawdzanie pisowni Save current image... Save currently opened image in its real size Save block Save the current block to the image file Select HTML format Select HTML format as recognition output Larger view Powiększ widok Smaller view Zmniejsz widok Rotate 90 CCW Obróć o 90 stopni w lewo Rotate 180 Obróć o 180 stopni Rotate 90 CW Obróć o 90 stopni w lewo &File &Plik &Help &Pomoc Copy To Clipboard Kopiuj do schowka Copy recognized text to clipboard Skopiuj rozpoznany tekst do schowka MainWindow toolBar Ctrl+N Ctrl+S Ctrl+O Ctrl+R Ctrl+Q Recognize &All Pages Rozpoznaj &wszystkie strony Recognize All Pages Rozpoznaj wszystkie strony Ctrl+A &Settings << Hide/Show Toolbar Import from PDF... Import pages from PDF documents OCR Settings Set up the OCR parameters Paste Image Paste image from clipboard Select Text Area Deskew Block Deskew the current block Deskew Correct the page skew Advanced Settings The settings you should probably never change select multiple blocks Splits text into several blocks Toggle Large/Small Icons toolBar_2 Select Recognition Language Prepare Page Save Project... Load Project... Prepare the page for recognition PopplerDialog Import from PDF File Name Select... Pages From To Entire Document QObject JPEG Files (*.jpg) PNG Files (*.png) Failed to save the image Required spelling dictionary (%1) is not found. Spell-checking is disabled. Try to install an appropriate aspell dictionary. Warning Ostrzeżenie Select Project Directory Bulgarian Czech Danish Dutch English French German Hungarian Italian Latvian Lithuanian Polish Portuguese Romanian Russian Russian-English Spanish Serbian Slovenian Swedish Ukrainian Finnish German Gothic Greek Hebrew Norwegian Slovak Swedish Gothic Turkish SideBar Drop files here yagf-0.9.2.1/src/translations/yagf_de.ts0000664000175000017500000005512212247205425020617 0ustar parallelsparallels AdvancedConfigDialog Advanced Settings Erweiterte Einstellungen Crop Image When Loaded Bild nach dem Laden beschneiden ConfigDialog OCR Settings OCR Einstellungen OCR Engine cuneiform tesseract Tesseract Setup Tesseract Einstellungen Location of the tessdata directory: Ort des tessdata Verzeichnisses: MainForm Recognition language Erkennungs-Sprache Open Image Bild öffnen Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) Bilddateien (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) There is an unsaved text in the editor window. Do you want to save it? Nicht gespeicherter Text im Bearbeitungsfenster. Jetzt speichern? Warning Warnung Error Fehler Starting cuneiform failed Der Start von "Cuneiform" schlug fehl The system said: Das System sagt: program not found Programm nicht gefunden No image loaded Kein Bild geöffnet About YAGF Über YAGF http://symmetrica.net/cuneiform-linux/yagf-en.html http://symmetrica.net/cuneiform-linux/yagf-en.html Recognizing pages... Erkenne Seiten... Abort Abbruch Save Image Bild speichern Importing pages from the PDF document... Seiten aus dem PDF Dokument importieren... Cancel Abbrechen No compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required). Es konnte keine kompatible PDF Konvertierungssoftware gefunden werden. Bitte installieren Sie entweder pdftoppm aus dem Paket poppler oder das GhostScript Paket (aus diese wird der "gs" Befehl gebraucht). PDF file name may not be empty PDF Dateiname darf nicht leer sein Select an existing directory for output or create some new one Wählen Sie ein bestehendes Verzeichnis für die Ausgabe oder erstellen sie ein neues Selecting Directory Verzeichnis auswählen The selected directory is not empty Das ausgewählte Verzeichnis ist nicht leer Starting tesseract failed tesseract startete nicht cuneiform not found, switching to tesseract cuneiform nicht gefunden, wechsle zu tesseract No recognition engine found. Please install either cuneiform or tesseract Keine Erkennungs Engine gefunden. Bitte cuneiform und/oder tesseract installieren tesseract not found, switching to cuneiform tesseract nicht gefunden, wechsel zu cuneiform No PDF converter installed Kein PDF Konvertierer installiert <p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details. <p align="center"><b>YAGF - Yet Another Graphical Front-end (Noch ein weiteres grafisches Frontend) fürr cuneiform und tesseract OCR (Optical Character Recognition = Optische Zeichen Erkennung) engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> Dies ist freie Softwater die unter der GPL v3 verbreitet wird. Besuchen Sie <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> für weitere Informationen. {2009-2012?} Using Cuneiform Using Tesseract Scanning is impossible No scanning front-end is found. Please install XSane in order to perform scanning. Failed to Load Image Failed to detect text areas on this page. The page possibly lacks contrast. Try to select blocks manually. The selected directoy is not empty. Please select or create another one. Failed to save the project. Failed to load project. MainWindow MainWindow Hauptfenster Larger view Ansicht vergrößern Smaller view Ansicht verkleinern Rotate 90 CCW Um 90° gegen den UZS drehen Rotate 180 Um 180° drehen Rotate 90 CW Um 90° im UZS drehen &File &Datei &Help &Hilfe toolBar Werkzeugleiste S&can... Bild ei&nlesen... Scanning images using XSane... Bilder mit «XSane» einlesen... Ctrl+N Ctrl+N &Save text... Text &speichern... Ctrl+S Ctrl+S &Open Image... Bild &öffnen... Open Image Bild öffnen Ctrl+O Ctrl+O &Recognize Texte&rkennung: aktuelle Seite Recognizing text... Texterkennung... Ctrl+R Ctrl+R Choose &Language &Wählen Sie eine Sprache Quit B&eenden Ctrl+Q Ctrl+Q Previous page Vorherige Seite Move to previous image Zum vorherigen Bild wechseln Next page Nächste Seite Move to next image Zum nächsten Bild wechseln Online Help Online-&Hilfe About... Ü&ber... Copy To Clipboard In die Zwischenablage kopieren Copy recognized text to clipboard Text in die Zwischenablage kopieren Recognize &All Pages Texterkennung: &alle Seiten Recognize All Pages Texterkennung: alle Seiten Ctrl+A Ctrl+A Clear all blocks Alle Markierungen entfernen Delete the current block Aktuelle Markierung entfernen Recognize block Texterkennung: aktuelle Markierung Recognize this block Diese Markierung erkennen Clear numbers Nummern löschen Crear block numbering Markierungsnummerierung löschen Check spelling Rechtschreibprüfung Save current image... Aktuelles Bild speichern... Save currently opened image in its real size Aktuelles Bild mit wirklicher Auflösung speichern Save block Block speichern Save the current block to the image file Aktuellen Block in die Bilddatei speichern Select HTML format HTML Format auswählen Select HTML format as recognition output HTML Format als Ausgabe der Erkennung wählen &Settings Ein&stellungen << Hide/Show Toolbar Werkzeugleiste anzeigen/verbergen Import from PDF... Aus PDF importieren ... Import pages from PDF documents Seiten aus PDF Dokumenten importieren OCR Settings OCR Einstellungen Set up the OCR parameters OCR Parameter einstellen Paste Image Bild einfügen Paste image from clipboard Bild der Zwischenablage einfügen Select Text Area Textbereich auwählen Deskew Block Block entzerren Deskew the current block Aktuellen Block entzerren Deskew Entzerren Correct the page skew Seitenverzerrung korrigieren Advanced Settings Erweiterte Einstellungen The settings you should probably never change Einstellungen die sie wahrscheinlich nie ändern sollten select multiple blocks Mehrere Blöcke auswählen Splits text into several blocks Teilt Text in mehrere Blöcke Toggle Large/Small Icons Große/kleine Icons toolBar_2 Select Recognition Language Prepare Page Save Project... Load Project... Prepare the page for recognition PopplerDialog Import from PDF Aus PDF importieren File Name Dateiname Select... Auswählen... Pages Seiten From Von To bis Entire Document Ganzes Dokument QObject JPEG Files (*.jpg) JPEG Dateien (*.jpg) PNG Files (*.png) PNG Dateien (*.png) Failed to save the image Speichern des Bilds schlug fehl Required spelling dictionary (%1) is not found. Spell-checking is disabled. Try to install an appropriate aspell dictionary. Erforderliches (%1) Wörterbuch nicht gefunden. Rechtschreibprüfung ist deaktiviert. Bitte entsprechendes aspell Wörterbuch installieren. Warning Warnung Select Project Directory Bulgarian Czech Danish Dutch English French German Hungarian Italian Latvian Lithuanian Polish Portuguese Romanian Russian Russian-English Spanish Serbian Slovenian Swedish Ukrainian Finnish German Gothic Greek Hebrew Norwegian Slovak Swedish Gothic Turkish SideBar Drop files here Dateien hier ablegen yagf-0.9.2.1/src/translations/yagf_uk.ts0000664000175000017500000006140112247205425020643 0ustar parallelsparallels AdvancedConfigDialog Advanced Settings Розширені налаштування Crop Image When Loaded Обрізати зображення після завантаження ConfigDialog OCR Settings Налаштування розпізнавання OCR Engine Рушій розпізнавання cuneiform Cuneiform tesseract Tesseract Tesseract Setup Налаштування Tesseract Location of the tessdata directory: Розташування теки tessdata MainForm Recognition language Мова розпізнавання Open Image Відкрити зображення Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) Файли зображення (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) There is an unsaved text in the editor window. Do you want to save it? У вікні редактора незбережений текст. Зберегти? Warning Попередження Error Помилка No image loaded Нема завантажених зображень Starting cuneiform failed Не вдалось запустити cuneiform The system said: Система пише: program not found програму не знайдено About YAGF Про програму http://symmetrica.net/cuneiform-linux/yagf-en.html http://symmetrica.net/cuneiform-linux/yagf-en.html Save Image Зберегти зображення Recognizing pages... Розпізнавання сторінки… Abort Скасувати Importing pages from the PDF document... Імпорт сторінок з PDF-документа Cancel Скасувати No compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required). Не знайдено перетворювач PDF-документів. Пропонуємо встановити або програму pdftoppm, або покет GhostScript (достатньо виконуваного файла gs). PDF file name may not be empty Назва PDF-файла не може бути порожньою Select an existing directory for output or create some new one Виберіть існуючу теку для виводу результату або створіть нову Selecting Directory Вибрати теку The selected directory is not empty Вибрана тека непорожня Starting tesseract failed Невдалий запуск tesseract cuneiform not found, switching to tesseract Не знайдено cuneiform, перемикаємось у tesseract No recognition engine found. Please install either cuneiform or tesseract Не знайдено жодного рушія з розпізнавання. Просимо встановити або cuneiform, або tesseract tesseract not found, switching to cuneiform tesseract не знайдено, перкмикаємось у cuneiform No PDF converter installed Не встановлено PDF-конвертера <p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details. <p align="center"><b>YAGF - Ще один графічний фронт-енд (Yet Another Graphical Front-end) для рушіїв з розпізнавання cuneiform та tesseract</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> Це вільне програмне забезпечення, яке поширюється піл ліцензією GPL v3. Відвідайте <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> , щоб отримати більше інформації. Using Cuneiform Using Tesseract Scanning is impossible No scanning front-end is found. Please install XSane in order to perform scanning. Failed to Load Image Failed to detect text areas on this page. The page possibly lacks contrast. Try to select blocks manually. The selected directoy is not empty. Please select or create another one. Failed to save the project. Failed to load project. MainWindow S&can... Зі&сканувати… Scanning images using XSane... Сканування зображень, використовуючи XSane… &Save text... &Зберегти текст… &Open Image... &Відкрити зображення… Open Image Відкрити зображення &Recognize &Розпізнати Recognizing text... Розпізнавання тексту… Choose &Language Вибрати &мову Quit Вийти Previous page Попередня сторінка Move to previous image Перейти до попереднього зображення Next page Наступна сторінка Move to next image Перейти до наступного зображення Online Help Довідка в інтернеті About... Про програму… Clear all blocks Очистити всі блоки Delete the current block Вилучити теперішній блок Recognize block Розпізнати блок Recognize this block Розпізнати цей блок Clear numbers Очистити номери Crear block numbering Очистити блок нумерації Check spelling Перевірити орфографію Save current image... Зберегти теперішнє зображення… Save currently opened image in its real size Зберегти теперішнє відкрите зображення в справжньому розмірі Save block Зберегти блок Save the current block to the image file Зберегти цей блок як зображення Select HTML format Виділити формат HTML Select HTML format as recognition output Виділити формат HTML як результат розпізнавання Larger view Збільшити Smaller view Зменшити Rotate 90 CCW Перевернути на 90 градусів проти часової стрілки Rotate 180 Перевернути на 180 градусів Rotate 90 CW Перевернути на 90 градусів за часовою стрілкою &File &Файл &Help &Довідка Copy To Clipboard Скопіювати до кишені Copy recognized text to clipboard Скопіювати розпізнаний текст у кишеню MainWindow Головне вікно toolBar Панель інструментів Ctrl+N Ctrl+N Ctrl+S Ctrl+S Ctrl+O Ctrl+O Ctrl+R Ctrl+R Ctrl+Q Ctrl+Q Recognize &All Pages Розпізнати &всі сторінки Recognize All Pages Розпізнати всі сторінки Ctrl+A Ctrl+A &Settings &Налаштування << << Hide/Show Toolbar Сховати/відобразити панель інструментів Import from PDF... Імпортувати з PDF Import pages from PDF documents Імпортувати сторінки з PDF-документів OCR Settings Налаштування розпізнавання Set up the OCR parameters Конфігурування параметрів розпізнавання Paste Image Вставити зображення Paste image from clipboard Вставити зображення з буферу обміну Select Text Area Вибрати текстовий блок Deskew Block Вирівняти блок Deskew the current block Вирівняти поточний блок Deskew Вирівняти Advanced Settings Роширені налаштування The settings you should probably never change Налаштування, які ви скоріш за все ніколи не змінюватимете select multiple blocks вибрати кілька блоків Splits text into several blocks Розділити текст на декілька окремих блоків Toggle Large/Small Icons Перемикнути великі/маленькі піктограми toolBar_2 Correct the page skew Select Recognition Language Prepare Page Save Project... Load Project... Prepare the page for recognition PopplerDialog Import from PDF Імпортувати з PDF File Name Назва файла Select... Виберіть... Pages Сторінки From Від To Адресат Entire Document Документ повністю QObject JPEG Files (*.jpg) Файли JPEG (*.jpg) PNG Files (*.png) Файли PNG (*.png) Failed to save the image Не вдалось зберегти зображення Required spelling dictionary (%1) is not found. Spell-checking is disabled. Try to install an appropriate aspell dictionary. Потрібні словники орфографії (%1) не знайдено. Перевірку орфографії вимкнено. Спробуйте встановити відповідний словник aspell. Warning Попередження Select Project Directory Bulgarian Czech Danish Dutch English French German Hungarian Italian Latvian Lithuanian Polish Portuguese Romanian Russian Russian-English Spanish Serbian Slovenian Swedish Ukrainian Finnish German Gothic Greek Hebrew Norwegian Slovak Swedish Gothic Turkish SideBar Drop files here Пересуньте файли сюди yagf-0.9.2.1/src/translations/yagf_ru.ts0000664000175000017500000006322112247205425020654 0ustar parallelsparallels AdvancedConfigDialog Advanced Settings Дополнительные настройки Crop Image When Loaded Обрезать изображение при загрузке ConfigDialog OCR Settings Настройки программ распознавания OCR Engine Программа распознавания cuneiform cuneiform tesseract tesseract Tesseract Setup Настройка tesseract Location of the tessdata directory: Расположение директории tessdata: MainForm Recognition language Язык распознавания Open Image Открыть файл Image Files (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) Графические файлы (*.png *.jpg *.jpeg *.bmp *.tiff *.tif *.gif *.pnm *.pgm *.pbm *.ppm) There is an unsaved text in the editor window. Do you want to save it? В окне редактора несохраненный текст. Сохранить? Warning Предупреждение Error Ошибка No image loaded Изображение не загружено Starting cuneiform failed Не удалось запустить cuneiform The system said: Ответ системы: program not found программа не найдена About YAGF О программе http://symmetrica.net/cuneiform-linux/yagf-en.html http://symmetrica.net/cuneiform-linux/yagf-ru.html Save Image Сохранить изображение Recognizing pages... Распознаем страницы... Abort Прервать Importing pages from the PDF document... Импорт страниц из документа PDF... Cancel Отменить No compatible PDF converter software could be found. Please install either the pdftoppm utility or the GhostScript package (from this the gs command will be required). Не найдены подходящие конверторы PDF. Установите, пожалуйста, утилиту pdftoppm или пакет GhostScript (из которого требуется программа gs). PDF file name may not be empty Необходимо указать имя файла PDF Select an existing directory for output or create some new one Выберите существующую директорию для вывода или создайте новую Selecting Directory Выбор директории The selected directory is not empty Выбранная директория - не пустая Starting tesseract failed Не удалось запустить tesseract cuneiform not found, switching to tesseract Программа cuneiform не найдена, переключаемся на tesseract No recognition engine found. Please install either cuneiform or tesseract Программа распознавания не найдена. Установите, пожалуйста, cuneiform или tesseract tesseract not found, switching to cuneiform Программа tesseract не найдена, переключаемся на cuneiform No PDF converter installed Конвертер PDF не установлен <p align="center"><b>YAGF - Yet Another Graphical Front-end for cuneiform and tesseract OCR engines</b></p><p align="center">Version %1</p> <p align="center">Ⓒ 2009-2012 Andrei Borovsky</p> This is a free software distributed under GPL v3. Visit <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-en.html</a> for more details. <p align="center"><b>YAGF - Графическая оболочка для программ распознавания текста cuneiform и tesseract</b></p><p align="center">Версия %1</p> <p align="center">Ⓒ 2009-2012 Андрей Боровский</p> YAGF - открытое программное обеспечение, которое распространяется на условиях лицензии GPL v3. Вы найдете подробности на странице <a href="http://symmetrica.net/cuneiform-linux/yagf-en.html">http://symmetrica.net/cuneiform-linux/yagf-ru.html</a>. Using Cuneiform Используется Cuneiform Using Tesseract Используется Tesseract Scanning is impossible Сканирование невозможно No scanning front-end is found. Please install XSane in order to perform scanning. Программа сканирования не найдена. Необходимо установить XSane. Failed to Load Image Невозможно загруить выбранное изобажение Failed to detect text areas on this page. The page possibly lacks contrast. Try to select blocks manually. Не удалось найти ткстовые области на странице. Возможно, изображение отсканировано со слишком низким контрастом. Попробуйт выделить блоки вручную. The selected directoy is not empty. Please select or create another one. Выбранный каталог содержит файлы. Выберите пустой каталог или создайте новый. Failed to save the project. Ошибка при сохранении проекта. Failed to load project. Невозможно открыть проект. MainWindow S&can... С&канировать... Scanning images using XSane... Сканируем страницу с помощью XSane... &Save text... &Сохранить текст... &Open Image... &Открыть графический файл... Open Image Открыть графический файл &Recognize &Распознать Recognizing text... Распознать текст... Choose &Language &Выбрать язык Quit Выйти Previous page Предыдущее изображение Move to previous image Перейти к предыдущему изображению Next page Следующее изображение Move to next image Перейти к следующему изображению Online Help Справка онлайн About... О програме... Clear all blocks Очистить все блоки Delete the current block Удалить этот блок Recognize block Распознать блок Recognize this block Распознать этот блок Clear numbers Crear block numbering Check spelling Проверить орфографию Save current image... Сохранить изображение... Save currently opened image in its real size Сохраняет полученное изображение в реальном размере Save block Сохранить блок Save the current block to the image file Сохранить этот блок в графическом файле Select HTML format Выбрать формат HTML Select HTML format as recognition output Выбрать HTML в качестве формата вывода распознанного текста Larger view Увеличить Smaller view Уменьшить Rotate 90 CCW Повернуть на 90 градусов против часовой стрелки Rotate 180 Повернуть на 180 градусов Rotate 90 CW Повернуть на 90 градусов по часовой стрелке &File &Файл &Help &Справка Copy To Clipboard Копировать текст в буфер обмена Copy recognized text to clipboard Копировать текст в буфер обмена MainWindow toolBar Ctrl+N Ctrl+S Ctrl+O Ctrl+R Ctrl+Q Recognize &All Pages Распознать &всё Recognize All Pages Распознать все страницы Ctrl+A &Settings &Настройки << Hide/Show Toolbar Показать/убрать панель Import from PDF... Импорт из документа PDF... Import pages from PDF documents Импорт страниц из документа PDF OCR Settings Настройки программ распознавания Set up the OCR parameters Установить параметры программ распознавания Paste Image Вставить изображение Paste image from clipboard Вставить страницу из буфера обмена Select Text Area Автоматически выделить текстовую область Deskew Block Выровнять блок Deskew the current block Выровнять выделенный блок Deskew Выровнять Correct the page skew Исправить наклон страницы Advanced Settings Дополнительные настройки The settings you should probably never change Настройки, которые вам, скорее всего, менять не нужно select multiple blocks Разделить текст на блоки Splits text into several blocks Разбить текст на блоки Toggle Large/Small Icons Большие/маленькие иконки toolBar_2 Select Recognition Language Выбор языка распознавания Prepare Page Save Project... Сохранить проект... Load Project... Загрузить проект... Prepare the page for recognition Подготовить страницу для распознавания PopplerDialog Import from PDF Импорт из документа PDF File Name Имя файла PDF Select... Выбрать... Pages Страницы From С To по Entire Document Весь документ QObject JPEG Files (*.jpg) Файлы JPEG (*.jpg) PNG Files (*.png) Файлы PNG (*.png) Failed to save the image Не удалось сохранить файл Required spelling dictionary (%1) is not found. Spell-checking is disabled. Try to install an appropriate aspell dictionary. Требуемый орфографический словарь (%1) не найден. Проверка орфографии будет отключена. Попробуйте установить соответствующий словарь aspell. Warning Предупреждение Select Project Directory Выбор директории проекта Bulgarian Болгарский Czech Чешский Danish Датский Dutch Голландский English Английский French Французский German Немецкий Hungarian Венгерский Italian Итальянский Latvian Латышский Lithuanian Литовский Polish Польский Portuguese Португальский Romanian Румынский Russian Русский Russian-English Русский-английский Spanish Испанский Serbian Сербский Slovenian Словенский Swedish Шведский Ukrainian Украинский Finnish Финский German Gothic Немецкий готический Greek Греческий Hebrew Иврит Norwegian Норевежский Slovak Словацкий Swedish Gothic Шведский готический Turkish Турецкий SideBar Drop files here Перетащите файлы сюда yagf-0.9.2.1/src/qxtunixsignalcatcher.cpp0000664000175000017500000000505112247205425021100 0ustar parallelsparallels/* This program 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. This program 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. */ #include "qxtunixsignalcatcher.h" #include "qxtunixscinternal.h" #include #include #include QXtUnixSignalCatcher * QXtUnixSignalCatcher::sc = NULL; QMutex * QXtUnixSignalCatcher::mutex = NULL; QXtUnixSignalCatcher::QXtUnixSignalCatcher(QObject *parent) : QObject(parent) { mutex = new QMutex(); sci = new QXtUnixSignalCatcherInternal(0); connect(sci, SIGNAL(unixSignalInternal(int)), this, SLOT(doEmit(int)), Qt::QueuedConnection); sigset_t newset; sigemptyset(&newset); sigaddset(&newset, SIGHUP); sigaddset(&newset, SIGTERM); sigaddset(&newset, SIGINT); sigaddset(&newset, SIGUSR1); sigaddset(&newset, SIGUSR2); sigprocmask(SIG_UNBLOCK, &newset, 0); } QXtUnixSignalCatcher::QXtUnixSignalCatcher() : QObject(0) { } QXtUnixSignalCatcher::QXtUnixSignalCatcher(QXtUnixSignalCatcher &) : QObject(0) { } QXtUnixSignalCatcher::~QXtUnixSignalCatcher() { } void QXtUnixSignalCatcher::signalHandler(int sig_num) { mutex->lock(); sc->emitSignal(sig_num); mutex->unlock(); } void QXtUnixSignalCatcher::emitSignal(int sig_num) { sci->emitSignal(sig_num); } bool QXtUnixSignalCatcher::connectUnixSignalInternal(int sig_num) { struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_handler = signalHandler; return (sigaction(sig_num, &sa, 0) == 0); } bool QXtUnixSignalCatcher::connectUnixSignal(int sig_num) { catcher(); return sc->connectUnixSignalInternal(sig_num); } void QXtUnixSignalCatcher::disconnectUnixSugnals() { sigset_t newset; sigemptyset(&newset); sigaddset(&newset, SIGHUP); sigaddset(&newset, SIGTERM); sigaddset(&newset, SIGINT); sigaddset(&newset, SIGUSR1); sigaddset(&newset, SIGUSR2); sigprocmask(SIG_BLOCK, &newset, 0); delete sci; sci = NULL; delete mutex; mutex = NULL; } void QXtUnixSignalCatcher::doEmit(int sig_num) { emit unixSignal(sig_num); } QXtUnixSignalCatcher *QXtUnixSignalCatcher::catcher() { if (!sc) sc = new QXtUnixSignalCatcher(0); return sc; } yagf-0.9.2.1/src/qxtunixsignalcatcher.h0000664000175000017500000000253712247205425020553 0ustar parallelsparallels/* This program 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. This program 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. */ #ifndef QXTUNIXSIGNALCTACHER_H #define QXTUNIXSIGNALCTACHER_H #include class QMutex; class QXtUnixSignalCatcherInternal; class QXtUnixSignalCatcher : public QObject { Q_OBJECT public: static QXtUnixSignalCatcher * catcher(); static bool connectUnixSignal(int sig_num); void disconnectUnixSugnals(); signals: void unixSignal(int sig_num); private slots: void doEmit(int sig_num); private: QXtUnixSignalCatcher(QObject *parent = 0); QXtUnixSignalCatcher(); QXtUnixSignalCatcher(QXtUnixSignalCatcher&); ~QXtUnixSignalCatcher(); static void signalHandler(int sig_num); void emitSignal(int sig_num); bool connectUnixSignalInternal(int sig_num); private: static QXtUnixSignalCatcher * sc; static QMutex * mutex; QXtUnixSignalCatcherInternal * sci; }; #endif // QXTUNIXSIGNALCTACHER_H yagf-0.9.2.1/src/mainform.h0000775000175000017500000001056412250140750016106 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "settings.h" #include #include #include "ui_mainform.h" #include #include //#include "ui_popplerdialog.h" class QComboBox; class QCheckBox; class QLabel; class QCloseEvent; class QPixmap; class QProcess; class QByteArray; class QFile; class SpellChecker; class QCursor; class QGraphicsInput; class QMenu; class PDFExtractor; class ccbuilder; class QLabel; const QString version = "0.9.2.1"; class PageCollection; class ScannerBase; class MainForm : public QMainWindow, public Ui::MainWindow { Q_OBJECT public: MainForm(QWidget *parent = 0); ~MainForm(); signals: void windowShown(); private slots: //void on_actionRecognize_activated(); void on_actionSelect_HTML_format_activated(); void on_actionDeskew_activated(); //void on_alignButton_clicked(); void on_actionCheck_spelling_activated(); void on_actionSave_block_activated(); void on_actionSave_current_image_activated(); void on_actionCheck_spelling_triggered(); void on_actionRecognize_block_activated(); void on_ActionDeleteBlock_activated(); void on_ActionClearAllBlocks_activated(); void loadImage(); void rotateCWButtonClicked(); void rotateCCWButtonClicked(); void rotate180ButtonClicked(); void enlargeButtonClicked(); void decreaseButtonClicked(); void singleColumnButtonClicked(); void newLanguageSelected(int index); void scanImage(); void loadNextPage(); void loadPreviousPage(); void recognize(); void recognizeAll(); void showAboutDlg(); void showHelp(); void unalignButtonClicked(); void hideToolBar(); void importPDF(); void showConfigDlg(); void addPDFPage(QString pageName); void finishedPDF(); void pasteimage(); void deskewByBlock(); void selectTextArea(); void selectBlocks(); void setSmallIcons(); void selectHTMLformat(); void loadFiles(QStringList files); void LangTextChanged(const QString &text); private: virtual void closeEvent(QCloseEvent *event); void initSettings(); void loadFile(const QString &fn, bool loadIntoView = true); //void loadFileWithPixmap(const QString &fn, const QPixmap &pixmap); void delTmpFiles(); void delTmpDir(); void preparePageForRecognition(); void prepareBlockForRecognition(const QRect &r); void prepareBlockForRecognition(int index); void recognizeInternal(); bool useCuneiform(const QString &inputFile, const QString &outputFile); bool useTesseract(const QString &inputFile); QString getFileNameToSaveImage(QString &format); void loadFromCommandLine(); void clearTmpFiles(); void fillLangBox(); private: QComboBox *selectLangsBox; QGraphicsInput *graphicsInput; QString fileName; QCursor *resizeCursor; QCursor *resizeBlockCursor; bool useXSane; ScannerBase * scanner; QByteArray *ba; //SpellChecker *spellChecker; QMenu *m_menu; PDFExtractor * pdfx; QProgressDialog pdfPD; int ifCounter; Settings * settings; PageCollection * pages; QLabel * engineLabel; private slots: bool findEngine(); void readyRead(int sig); void setResizingCusor(); void setUnresizingCusor(); void loadPage(); void rightMouseClicked(int x, int y, bool inTheBlock); void onShowWindow(); void showAdvancedSettings(); void addSnippet(int index); void preprocessPage(); void saveProject(); void loadProject(); void setUILanguage(); }; yagf-0.9.2.1/src/tpage.h0000664000175000017500000000642412250140707015375 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef TPAGE_H #define TPAGE_H #include "tblock.h" #include "analysis.h" #include #include #include #include class CCBuilder; class Settings; class Page : public QObject { Q_OBJECT public: explicit Page(const int pid, QObject *parent = 0); ~Page(); bool loadFile(QString fileName, bool loadIntoView = true); QPixmap displayPixmap(); QImage thumbnail(); bool makeLarger(); bool makeSmaller(); void rotate(qreal angle); void unload(); void addBlock(Block block); void deleteBlock(const Block &b); void deleteBlock(const QRect &r); Block getBlock(const QRect &r); Block getBlock(int index); int blockCount(); void clearBlocks(); void savePageForRecognition(const QString &fileName); bool savePageAsImage(const QString &fileName, const QString &format); void saveRawBlockForRecognition(QRect r, const QString &fileName); void saveBlockForRecognition(QRect r, const QString &fileName, const QString &format); void saveBlockForRecognition(int index, const QString &fileName); void selectBlock(const QRect &r); Block getSelectedBlock(); void deskew(bool recreateCB = true); void rotate90CW(); void rotate90CCW(); void rotate180(); void blockAllText(); bool splitPage(bool preprocess); QString fileName(); int pageID(); void sortBlocksInternal(); bool isDeskewed(); bool isPreprocessed(); qreal getRotation(); void setDeskewed(bool value); void setPreprocessed(bool value); signals: void refreshView(); public slots: private: void renumberBlocks(); void applyTransforms(QImage &image, qreal scale); void rotateImageInternal(QImage &image, qreal angle); void scaleImages(); void normalizeRect(QRect &rect); void scaleRect(QRect &rect); QImage tryRotate(QImage image, qreal angle); QImage currentImage(); void saveTmpPage(const QString &fileName, bool cc,bool boost, bool brighten, int p = 1, int q =1); QList splitInternal(); void prepareCCBuilder(); private: qreal scale; qreal rotation; int mGeneralBrightness; QRect crop1; QRect crop2; bool deskewed; QImage img; QImage img2; QImage img4; QImage img6; QImage img8; QImage img16; TBlocks blocks; bool imageLoaded; bool loadedBefore; bool preprocessed; QString mFileName; CCBuilder * ccbuilder; Settings * settings; int blockPointer; int pid; Block selectedBlock; }; #endif // TPAGE_H yagf-0.9.2.1/src/tblock.h0000664000175000017500000000237112250140707015550 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef TBLOCK_H #define TBLOCK_H #include #include #include class Block : public QRect { public: explicit Block( int x, int y, int width, int height ); Block(const QRect &r); int blockNumber(); void setBlockNumber(const int value); void setLanguage(const QString &lang); QString getLanguage(); private: int number; QString language; }; typedef QList TBlocks; void sortBlocks(TBlocks &blocks); #endif // TBLOCK_H yagf-0.9.2.1/src/configdialog.cpp0000664000175000017500000000274512247205425017264 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "configdialog.h" #include "ui_configdialog.h" #include #include ConfigDialog::ConfigDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ConfigDialog) { ui->setupUi(this); } ConfigDialog::~ConfigDialog() { delete ui; } void ConfigDialog::setSelectedEngine(int value) { if (!value) ui->radioButton->setChecked(true); else ui->radioButton_2->setChecked(true); } int ConfigDialog::selectedEngine() { if (ui->radioButton->isChecked()) return 0; return 1; } void ConfigDialog::setTessDataPath(const QString &value) { ui->lineEdit->setText(value); } QString ConfigDialog::tessdataPath() { return ui->lineEdit->text(); } yagf-0.9.2.1/src/tpagecollection.h0000664000175000017500000000564512250140707017455 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef TPAGECOLLECTION_H #define TPAGECOLLECTION_H #include "tpage.h" #include #include #include class QSnippet; class PageCollection : public QObject { Q_OBJECT public: static PageCollection * instance(); static void clearCollection(); bool appendPage(const QString &fileName); int count(); bool makePageCurrent(int index); bool makePageCurrentByID(int id); void setBeforeFirst(); // the page pointer is set before the first page bool makeNextPageCurrent(); QSnippet * snippet(); QPixmap pixmap(); void savePageForRecognition(const QString &fileName); void saveRawBlockForRecognition(QRect r, const QString &fileName); void saveBlockForRecognition(QRect r, const QString &fileName, const QString &format = "BMP"); void saveBlockForRecognition(int index, const QString &fileName); int blockCount(); Block getBlock(const QRect &r); Block getBlock(int index); void selectBlock(const QRect &r); Block getSelectedBlock(); bool pageValid(); QString fileName(); bool savePageAsImage(const QString &fileName, const QString &format); bool isDeskewed(); bool isPreprocessed(); qreal getRotation(); void setRotation(const qreal value); void setDeskewed(const bool value); void setPreprocessed(const bool value); void reloadPage(); public slots: void makeLarger(); void makeSmaller(); void rotate90CW(); void rotate90CCW(); void rotate180(); void deskew(); void blockAllText(); bool splitPage(bool preprocess); void addBlock(const QRect & rect); void deleteBlock(const QRect & rect); void clearBlocks(); void clear(); signals: void loadPage(); // The page is already current void addSnippet(int index); void cleared(); private slots: void pageSelected(int id); void pageRemoved(int id); private: PageCollection(QObject *parent = 0); PageCollection(const PageCollection &); ~PageCollection(); Page * cp(); int id2Index(int id); private: QVector pages; int index; int pid; static PageCollection * m_instance; }; #endif // TPAGECOLLECTION_H yagf-0.9.2.1/src/pdf2ppt.cpp0000664000175000017500000000303412247205425016206 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "pdf2ppt.h" #include #include PDF2PPT::PDF2PPT() : PDFExtractor() { } void PDF2PPT::exec() { QString command = "pdftoppm"; QStringList args; args << "-jpeg"; if ((!getStopPage().isEmpty()) || (getStopPage().toInt() > 0)) { if (getStartPage().toInt() == 0) this->setStartPage("1"); args << "-f" << getStartPage() << "-l" << getStopPage(); } args << "-rx" << "600" << "-ry" << "600" << this->getSourcePDF(); if (!getOutputDir().endsWith("/")) setOutputDir(getOutputDir().append('/')); setOutputPrefix(getOutputDir().append("page")); args << getOutputPrefix(); setOutputExtension("jpg"); execInternal(command, args); } yagf-0.9.2.1/src/analysis.cpp0000664000175000017500000003245712247205425016465 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "analysis.h" #include "utils.h" #include bool operator==(Rect r1, Rect r2) { if (r1.x1 != r2.x1) return false; if (r1.y1 != r2.y1) return false; if (r1.x2 != r2.x2) return false; if (r1.y2 != r2.y2) return false; return true; } bool operator==(GlyphInfo g1, GlyphInfo g2) { if (g1.x != g2.x) return false; if (g1.y != g2.y) return false; if (g1.h != g2.h) return false; return true; } CCAnalysis::CCAnalysis(CCBuilder * builder) { this->builder = builder; glyphCount = 0; mediumGlyphHeight = 0; mediumGlyphWidth = 0; mediumLetterSpace = 0; mediumWordSpace = 0; stringsCount = 0; } CCAnalysis::~CCAnalysis() { } bool CCAnalysis::analize(bool extractBars) { if (extractComponents(extractBars)) { classifyGlyphs(); normalizeLines(); return true; } return false; } Bars CCAnalysis::addBars() { extractComponents(true); addBarsHorizontal(); addBarsVertical(); addBarsHorisontalAfterVertical(); return bars; } bool CCAnalysis::extractComponents(bool extractBars) { components.clear(); for (int y = 0; y < builder->height(); y++) { for (int x = 0; x < builder->width(); x++) { quint32 label = builder->label(x,y); if (label) { Rect r; r.dotCount = 0; r.x1 = builder->width(); r.x2 = 0; r.y1 = builder->height(); r.y2 = 0; if (!components.contains(label)) components.insert(label, r); r = components.value(label); r.dotCount++; if (x < r.x1) r.x1 = x; if (x > r.x2) r.x2=x; if (y r.y2) r.y2 = y; components.remove(label); components.insert(label,r); } } } quint32 wacc, hacc, count; wacc = 0; hacc= 0; count = 0; foreach(Rect r, components.values()) { wacc += (r.x2 - r.x1); hacc +=(r.y2 - r.y1); count++; } quint32 wmed; quint32 hmed; if (count != 0) { wmed = wacc/count; hmed = hacc/count; } else return false; if (extractBars) { foreach(quint32 k, components.keys()) { Rect r = components.value(k); int deltaX = abs(r.x2 - r.x1); // TODO: remove abs() if not needed int deltaY = abs(r.y2 - r.y1); // TODO: remove abs() if not needed if ((deltaX > 10)&&(deltaY > 10)) continue; if (deltaX != 0) { if (deltaY/deltaX >= BarRatio) { components.remove(k); bars.append(r); continue; } } else { if (deltaY >= BarRatio) { components.remove(k); bars.append(r); continue; } } if (deltaY != 0) { if (deltaX/deltaY >= BarRatio) { components.remove(k); bars.append(r); continue; } } else { if (deltaX >= BarRatio) { components.remove(k); bars.append(r); continue; } } } } foreach(quint32 k, components.keys()) { Rect r = components.value(k); if ((r.x2 - r.x1) > 6*wmed) components.remove(k); else { int s = (r.y2 - r.y1)*(r.x2 - r.x1); if (( s < 30) || ((r.y2 - r.y1) > 4*hmed)) components.remove(k); else { if (s == 0) components.remove(k); else if (((double)r.dotCount/(double)s) < 0.1) components.remove(k); } } } wacc = 0; hacc= 0; count = 0; foreach(Rect r, components.values()) { wacc += (r.x2 - r.x1); hacc +=(r.y2 - r.y1); count++; } if (count == 0) return false; wmed = wacc/count; hmed = hacc/count; mediumGlyphWidth = wmed; mediumGlyphHeight = hmed; glyphCount = count; return true; } int CCAnalysis::getGlyphBoxCount() { return components.count(); } Rect CCAnalysis::getGlyphBox(int index) { return components.values().at(index); } void CCAnalysis::classifyGlyphs() { foreach (Rect r, components) { glyphField.insert(r.x1, r); } } TextLine CCAnalysis::extractLine() { Rect first; //QPoint firstpt; TextLine line; for (int x =0; x < builder->width(); x++) { if (glyphField.values(x).count()) { first = glyphField.values(x).at(0); glyphField.remove(x, first); line.append(ginfo((first.x1+first.x2)/2, (first.y1+first.y2)/2, abs(first.y1-first.y2))); break; } } if (line.count()) { Rect temp = first; while (findAdjacent(temp) >= 0) { line.append(ginfo((temp.x1+temp.x2)/2, (temp.y1+temp.y2)/2, abs(temp.y1-temp.y2))); } } return line; } int CCAnalysis::findAdjacent(Rect &r) { int startx = (r.x1+r.x2)/2; int xspan = (r.x2 - r.x1)*4; int ymid = (r.y1+r.y2)/2; int endx = startx + xspan; for (int x=startx; x = r1.y1) && (ymid <= r1.y2)) { r = r1; glyphField.remove(x, r1); return x; } } } return -1; } void CCAnalysis::normalizeLines() { k = 0; int count = 0; TextLine l = extractLine(); while (l.count()) { lines.append(l); if (l.count() > 4) { if (abs (l.last().h - l.first().h) < 3) { qreal d = l.last().x - l.first().x; if (d != 0) { k = k + ((qreal)(l.last().y - l.first().y))/d; count++; } } else { int lastX = l.at(l.count()-1).x; int lastY = l.at(l.count()-1).y; int lastH = l.at(l.count()-1).h; int firstX = l.at(1).x; int firstY = l.at(1).y; int firstH = l.at(1).h; if (abs (lastH - firstH) < 3) { qreal d = lastX - firstX; if (d != 0) { k = k + ((qreal)(lastY - firstY))/d; count++; } } } } //graphicsInput->drawLine(l.at(0).x()*2, l.at(0).y()*2, l.at(l.count()-1).x()*2,l.at(l.count()-1).y()*2); l = extractLine(); } if (count) k = k/count; } Lines CCAnalysis::getLines() { return lines; } qreal CCAnalysis::getK() { return k; } void CCAnalysis::rotatePhi(qreal phi, const QPoint &c, QPoint &p) { int x = p.x() - c.x(); int y = p.y() - c.y(); int x1 = x*cos(phi) - y*sin(phi); int y1 = x*sin(phi) + y*cos(phi); p.setX(x1+c.x()); p.setY(y1+c.y()); } void CCAnalysis::addBarsHorizontal(int hoffset, int height, int woffset, int width) { bool * li = new bool[builder->height()]; if (height < 0) height = builder->height(); if (width < 0) width = builder->width(); for (int i = hoffset; i < height; i++) li[i] = false; foreach (TextLine tl, lines) { if (tl.count() == 1) continue; foreach(GlyphInfo gi, tl) // OPTIMIZE if (_contains(woffset, width, gi.x)) { for (int i = gi.y - gi.h/2; i < gi.y + gi.h/2; i++) li[i] = true; } } int him = 0; int hlm = 0; int lcount = 0; int icount = 0; int chl = 0; int chi = 0; for (int i= hoffset; i < height; i++) { if (!li[i]) { // empty space if (chl > 0) { hlm += chl; lcount++; chl = 0; } chi++; } else { if (chi > 0) { if (icount > 0) him += chi; icount++; chi = 0; } chl++; } } if ((icount < 3)||(lcount == 0)) { delete[] li; return; } him -= chi; him = him/(icount-2); hlm /= lcount; int ilcount = 0; int llcount = 0; for (int i = hoffset; i < height; i++) { if (!li[i]) { ilcount++; } else { if (ilcount >= 5*him) { Rect r; r.x1 = woffset; r.x2 = width-1; r.y1 = 0; for (int j = i - 3*him; j < i; j++) { if ((!li[j-1]) && (!li[j]) && (!li[j+1])) { r.y1 = j; break; } } if (r.y1 > 0) { r.y2 = r.y1; bars.append(r); } } ilcount = 0; llcount++; } } delete[] li; } void CCAnalysis::addBarsHorisontalAfterVertical() { Rect r; r.y1 = 0; r.y2 = builder->height(); r.x1 = builder->width(); r.x2 = r.x1; verts.append(r); for (int i = 1; i < verts.count(); i++) { addBarsHorizontal(0, -1, verts[i-1].x2, verts[i].x1); } } /*void CCAnalysis::addBarsHorizontal() { bool * li = new bool[builder->height()]; for (int i = 0; i < builder->height(); i++) li[i] = false; int hlm = 0; foreach (TextLine tl, lines) hlm += tl.first().h; hlm /= lines.count(); foreach (TextLine tl, lines) { if (tl.count() < 3) if (tl.first().x > lines.first().first().x + 64) continue; for (int i = (tl.first().y - hlm < 0 ? 0 : tl.first().y - hlm); i < (tl.last().y + hlm > builder->height() ? builder->height() : tl.last().y + hlm); i++) li[i] = true; //for (int i = (tl.last().y - tl.last().h < 0 ? 0 : tl.last().y - tl.last().h); i < (tl.last().y + tl.last().h > builder->height() ? builder->height() : tl.last().y + tl.last().h); i++) // li[i] = true; } int fcount = 0; for (int i = 0; i < builder->height(); i++) { if (!li[i]) fcount++; else { if (fcount >= hlm*1.5) { Rect r; r.x1 = 0; r.x2 = builder->width()-1; r.y1 = i - hlm/2; r.y2 = r.y1; bars.append(r); fcount = 0; } } } delete[] li; }*/ void CCAnalysis::addBarsVertical() { int * li = new int[builder->width()]; for (int i = 0; i < builder->width(); i++) li[i] = 0; foreach(Rect c, components.values()) { for (int j = c.x1; j <= c.x2; j++) li[j]++; } int liprev = 1000; for (int i = 0; i < builder->width(); i++) { if (li[i] < 3) { if (liprev >= 3) { Rect r; r.x1 = i < builder->width() -5 ? i + 5 : i; r.x2 = r.x1; r.y1 = 0; r.y2 = builder->height()-1; bars.append(r); verts.append(r); } } else if (liprev < 3) { Rect r; r.x1 = i > 3 ? i - 3 : i-1; r.x2 = r.x1; r.y1 = 0; r.y2 = builder->height()-1; bars.append(r); verts.append(r); } liprev = li[i]; } delete[] li; } void CCAnalysis::rotateLines(qreal phi, const QPoint &c) { for (int i = 0; i < lines.count(); i++) { TextLine l = lines.at(i); for (int j =0; j < l.count(); j++) { QPoint p = QPoint(l.at(j).x, l.at(j).y); rotatePhi(phi, c, p); ginfo g = l.at(j); g.x = p.x(); g.y = p.y(); l.replace(j, g); } lines.replace(i, l); } } int CCAnalysis::getMediumGlyphWidth() { return mediumGlyphWidth; } int CCAnalysis::getMediumGlyphHeight() { return mediumGlyphHeight; } ginfo::ginfo(int a1, int a2, int a3) { x = a1; y = a2; h = a3; } int CCAnalysis::getGlyphCount() { return glyphCount; } QList CCAnalysis::getGlyphs() { return components.values(); } yagf-0.9.2.1/src/pdfextractor.h0000664000175000017500000000446212247205425017007 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef PDFEXTRACTOR_H #define PDFEXTRACTOR_H #include #include class PDFExtractor : public QObject { Q_OBJECT public: explicit PDFExtractor(QObject *parent = 0); void setCommandStringPaged(const QString &cmdStr); void setCommandStringEntire(const QString &cmdStr); void setSourcePDF(const QString &value); QString getSourcePDF(); void setOutputDir(const QString &value); QString getOutputDir(); void setStartPage(const QString &value); QString getStartPage(); void setStopPage(const QString &value); QString getStopPage(); void setResolution(const QString &value); QString getResolution(); void setOutputPrefix(const QString &value); QString getOutputPrefix(); void setOutputExtension(const QString &value); QString getOutputExtension(); void virtual exec() = 0; static bool findProgram(); signals: void terminate(); void killProcess(); void terminateProcess(); void addPage(QString pageName); void finished(); public slots: void cancel(); protected: void execInternal(const QString &command, const QStringList &arguments); private: QString commandStringPaged; QString commandStringEntire; QString sourcePDF; QString outputDir; QString startPage; QString stopPage; QString resolution; QString outputPrefix; QString outputExtension; int lastPage; QStringList filters; bool canceled; }; #endif // PDFEXTRACTOR_H yagf-0.9.2.1/src/qxtgraphicsview.h0000664000175000017500000000261612247205425017531 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef QXTGRAPHICSVIEW_H #define QXTGRAPHICSVIEW_H #include #include class QXtGraphicsView : public QGraphicsView { Q_OBJECT public: QXtGraphicsView(QWidget * parent = 0):QGraphicsView(parent) { connect(this, SIGNAL(scrolledDeferred()), this, SIGNAL(scrolled()), Qt::QueuedConnection); } void sendScrollSignal() { emit scrolledDeferred(); } signals: void scrolled(); void scrolledDeferred(); protected: void scrollContentsBy (int dx, int dy) { QGraphicsView::scrollContentsBy(dx, dy); emit scrolled(); } }; #endif // QXTGRAPHICSVIEW_H yagf-0.9.2.1/src/advancedconfigdialog.cpp0000664000175000017500000000241312250140707020735 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "advancedconfigdialog.h" #include "ui_advancedconfigdialog.h" AdvancedConfigDialog::AdvancedConfigDialog(QWidget *parent) : QDialog(parent), ui(new Ui::AdvancedConfigDialog) { ui->setupUi(this); } AdvancedConfigDialog::~AdvancedConfigDialog() { delete ui; } bool AdvancedConfigDialog::doCrop1() { return ui->checkBox->checkState() == Qt::Checked; } void AdvancedConfigDialog::setCrop1(const bool value) { ui->checkBox->setCheckState((value == true ? Qt::Checked : Qt::Unchecked)) ; } yagf-0.9.2.1/src/droplabel.h0000664000175000017500000000236012247205425016241 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef DROPLABEL_H #define DROPLABEL_H #include class QListWidget; class DropLabel : public QLabel { Q_OBJECT public: DropLabel(QWidget * parent = 0, Qt::WindowFlags f = 0); void setListWidget(QListWidget * w); signals: void pageRemoved(int id); protected: void dragEnterEvent(QDragEnterEvent *event); void dragLeaveEvent(QDragLeaveEvent *event); void dropEvent(QDropEvent *event); private: QListWidget * lw; }; #endif // DROPLABEL_H yagf-0.9.2.1/src/mainform.ui0000775000175000017500000011324012247205425016276 0ustar parallelsparallels MainWindow 0 0 1920 1138 Qt::CustomContextMenu MainWindow :/yagf.png:/yagf.png 2 2 QFrame::StyledPanel QFrame::Raised 128 0 128 16777215 94 94 94 94 94 94 255 255 255 1 Qt::ScrollBarAlwaysOff true 100 128 Qt::ElideNone QListView::LeftToRight 4 QListView::IconMode 128 80 128 80 76 76 76 94 94 94 94 94 94 60 60 60 94 94 94 76 76 76 94 94 94 94 94 94 94 94 94 94 94 94 76 76 76 94 94 94 94 94 94 60 60 60 94 94 94 76 76 76 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 94 :/images/trashcan_full.png Qt::AlignCenter 1 0 Qt::Horizontal Qt::NoContextMenu Times New Roman 0 0 1920 25 &File &Help &Settings 0 0 0 0 toolBar 48 48 TopToolBarArea false toolBar_2 TopToolBarArea false :/images/scanner48.png:/images/scanner48.png S&can... Scanning images using XSane... Ctrl+N :/images/document_save_as.png:/images/document_save_as.png &Save text... Ctrl+S :/images/document_open.png:/images/document_open.png &Open Image... Open Image Ctrl+O :/images/filefind.png:/images/filefind.png &Recognize Recognizing text... Ctrl+R Choose &Language Quit Ctrl+Q :/images/back.png:/images/back.png Previous page Move to previous image :/images/forward.png:/images/forward.png Next page Move to next image Online Help About... Online Help :/images/editcopy.png:/images/editcopy.png Copy To Clipboard Copy recognized text to clipboard :/batch.png:/batch.png Recognize &All Pages Recognize All Pages Ctrl+A :/images/clearblocks.png:/images/clearblocks.png Clear all blocks Clear all blocks :/images/trashcan2-s.png:/images/trashcan2-s.png Delete the current block Delete the current block :/images/recblocks.png:/images/recblocks.png Recognize block Recognize this block Clear numbers Crear block numbering true :/images/check_spelling.png:/images/check_spelling.png Check spelling :/images/savpicas.png:/images/savpicas.png Save current image... Save currently opened image in its real size :/images/saveblock.png:/images/saveblock.png Save block Save the current block to the image file :/images/deskew2.png:/images/deskew2.png Deskew Correct the page skew true :/images/stock_new_html.png:/images/stock_new_html.png Select HTML format Select HTML format as recognition output :/images/larger.png:/images/larger.png Larger view Larger view :/images/smaller.png:/images/smaller.png Smaller view Smaller view :/images/rccw.png:/images/rccw.png Rotate 90 CCW Rotate 90 CCW :/images/revert.png:/images/revert.png Rotate 180 Rotate 180 :/images/rcw.png:/images/rcw.png Rotate 90 CW Rotate 90 CW << Hide/Show Toolbar :/images/application_pdf.png:/images/application_pdf.png Import from PDF... Import pages from PDF documents OCR Settings Set up the OCR parameters :/images/edit_paste.png:/images/edit_paste.png Paste Image Paste image from clipboard :/images/selecttext.png:/images/selecttext.png Select Text Area Select Text Area Deskew Block Deskew the current block Advanced Settings The settings you should probably never change :/images/selectmulti.png:/images/selectmulti.png select multiple blocks Splits text into several blocks Toggle Large/Small Icons :/images/system_config_language.png:/images/system_config_language.png Select Recognition Language Select Recognition Language :/images/tools_wizard_small.png:/images/tools_wizard_small.png Prepare Page Prepare the page for recognition Save Project... Load Project... QXtGraphicsView QGraphicsView
qxtgraphicsview.h
SideBar QListWidget
sidebar.h
DropLabel QLabel
droplabel.h
TextEditor QTextEdit
texteditor.h
actionTBLV triggered() MainWindow enlargeButtonClicked() -1 -1 959 568 actionSmaller_view triggered() MainWindow decreaseButtonClicked() -1 -1 959 568 actionRotate_90_CCW triggered() MainWindow rotateCCWButtonClicked() -1 -1 959 568 actionRotate_180 triggered() MainWindow rotate180ButtonClicked() -1 -1 959 568 actionRotate_90_CW triggered() MainWindow rotateCWButtonClicked() -1 -1 959 568 actionHideShowTolbar triggered() MainWindow hideToolBar() -1 -1 959 568 actionImport_from_PDF triggered() MainWindow importPDF() -1 -1 959 568 actionOCR_Settings triggered() MainWindow showConfigDlg() -1 -1 959 568 actionPaste_Image triggered() MainWindow pasteimage() -1 -1 959 568 actionSelect_Text_Area triggered() MainWindow selectTextArea() -1 -1 959 568 actionDeskew_by_Block triggered() MainWindow deskewByBlock() -1 -1 959 568 actionAdvanced_Settings triggered() MainWindow showAdvancedSettings() -1 -1 959 568 actionSelect_multiple_blocks triggered() MainWindow selectBlocks() -1 -1 959 568 actionToggle_Large_Small_Icons triggered() MainWindow setSmallIcons() -1 -1 959 568 actionPrepare_Page triggered() MainWindow preprocessPage() -1 -1 959 568 actionSave_Project triggered() MainWindow saveProject() -1 -1 959 568 actionLoad_Project triggered() MainWindow loadProject() -1 -1 959 568 rotateCWButtonClicked() rotateCCWButtonClicked() rotate180ButtonClicked() enlargeButtonClicked() decreaseButtonClicked() hideToolBar() importPDF() showConfigDlg() pasteimage() blockAllText() deskewByBlock() showAdvancedSettings() selectTextArea() selectBlocks() setSmallIcons() preprocessPage() saveProject() loadProject()
yagf-0.9.2.1/src/qxtunixscinternal.h0000664000175000017500000000163612247205425020105 0ustar parallelsparallels/* This program 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. This program 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. */ #ifndef QXTUNIXSCINTERNAL_H #define QXTUNIXSCINTERNAL_H #include class QXtUnixSignalCatcherInternal : public QObject { Q_OBJECT public: QXtUnixSignalCatcherInternal(QObject *parent = 0) : QObject(parent) {} void emitSignal(int sig_num) { emit unixSignalInternal(sig_num); } signals: void unixSignalInternal(int sig_num); }; #endif // QXTUNIXSCINTERNAL_H yagf-0.9.2.1/src/qxtgraphicsproxywidget.cpp0000664000175000017500000000330612247205425021474 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "qxtgraphicsproxywidget.h" #include "qxtgraphicsview.h" #include #include #include QXtGraphicsProxyWidget::QXtGraphicsProxyWidget(QGraphicsItem * parent, Qt::WindowFlags wFlags) : QGraphicsProxyWidget(parent, wFlags) { setFlag(QGraphicsItem::ItemSendsGeometryChanges, true); } void QXtGraphicsProxyWidget::setView(QXtGraphicsView * view) { mview = view; QPointF p = mview->mapToScene(0,0); setPos(p.x(), p.y()); //setPos(0,0); connect(mview, SIGNAL(scrolled()), this, SLOT(viewScrolled())); } void QXtGraphicsProxyWidget::viewScrolled() { QPointF p = mview->mapToScene(0,0); setPos(p.x(), p.y()); } QVariant QXtGraphicsProxyWidget::itemChange(GraphicsItemChange change, const QVariant & value) { QVariant v; matrix().reset(); if (change == QGraphicsItem::ItemTransformChange) { v = QVariant(matrix()); return v; } return value; } yagf-0.9.2.1/src/images/0000775000175000017500000000000012250673444015374 5ustar parallelsparallelsyagf-0.9.2.1/src/images/application_pdf.png0000664000175000017500000002024612247205425021236 0ustar parallelsparallelsPNG  IHDR>atIME #3I~$bKGD HIDATx tǫXE+"PPQHbrCmjUb= V+nmhʎ"&[YBCIH'aw 7maB@޼{ofW+l)ʣQKj:Ւf5ZB83F%XpIpi-8H<: (vױcha:qDܿF>ݘ/2y46"K!X؉PEEbMEPRM%ʨLU9 iV0UTY&|GG>P~WYU*j[Uo&?Єc7j_uAiw .mi?FW<,HK%x)@@nG7>~Kp!)a}$@=xs z {Pn #MD BӒhFOT g$x[ ۋGc[`P o(7֌EO>IӧS0+Kַq#m=fkG3/87QKt OT Ȳw@!ק>422,C=TMK9jݚFU.CWqv^B,kGM܎eU?-xU!>K{O[8*{-AE&}qVe@1# Њ?!|JF_k-ؑ^pXx5KW%7Tep#<.!@B>uxG?"^oV1^J${qa[mB!@GOMoUdμZީ[Je={l7kUiʣ5c~s._^uہW31ch@M7>=vQ @l0Q*s1Cɻߟ|*qoUWpݿKie˴Ўk ^I޴q!b{nl Ћ ߈lD;ޛq7Y;8pz} `zfom(/)9Y8%H3{.-Coy7^o,'LoRu{9cM a> FÇm|hY/XY~V{YF-eX*ްA7_*BXE-d~@,^۴`ڕ|>Sqݻr6o6sH^qp̼oFj<9KL֕כ 6AB'#bųaF>2 3#GՔ dϮÀ>Z;87p=i%@jvߍ `3Fidջql>#j#.eg =gэ7Wּ$ʛ=-6sP2@ |NdZ  Y&zA76hF#@$ɞSm$0 ,oK4,̙5:`°J@7 @+ÑCD;ەw~K|Z|;W_yŶ6QA jj&BDES43vGkw!gK. 94oѴYBvp2iW#c;*tMI|5˙>= >Z-e#/Zޞ֫f[*|Q 2}I0tOKm>< :|.r'L/oҺtfxy;&1c;jkuF)yO@c__cX:i>et kcF1c5|2oAh?|oψ ݻm%nrwqc$LBٴG ^7y'U{c|QTtc ?"5-gupuub9p_|Ex,7Gsg Ν6qi# Fct" l. 7f 6"2csn%s@#I^(#_{mC,ۗsrGtVĉQW%+K!h 9b!l2ƂoAʞn_}  m3nCpwn%/ 4'L2G I,{9]|r[8hFlhN-Cѣio;kSü!"h&e oLx2+kҩv^teNMu ^t fk4px<_j_VeqG8|.be8G>N*(hɲI@ {Ikݬ=]G[BW=R5T~IyWR6N\-ʺc)m[Kr0*r&/&j7Jaa>!)|els>W \qUTgҨ18&+fFwyBf;B\BwI8I ~7>j80I_c7+ {L׏v﵀gXAVG&'',Kn=J8j :zoQG ߦW0poM5cP |3_H*abhmM<8X9S`:˽8wӿWK{C~ĉzX?x1r`D5Ph }ÄICp#o@~kp-x_=cFXbW>KK//~?C+WFI2Qtc1 * >|xYvhj*aCq_(T}{L @EM_* 5k7`W}{GA. 2|wk1mZ5:|$|mslRWNESvT T &pLơSqߤ |-eNmB%n ?⊡Whyy"LgN|7,9Y1Z~wT⚀?nԉO:x  6'־4I_șQޖRM-*q#)|P0ѣr\G= >TXu|$:[[Aǵ TEQSh( NCqO|Do_׵;˘uceݵK3D'Ryٶ-A٧HC%ܣ]裮7fl8ʞ||o|h"Ґ!thݺ܆HXCE]ݽjtLҨ1%nT6t(.& <3\Eq>&i_WY={ڵrUREρ.Yy]GoMud2|86@,a܏>=8k^==wj/RW/?9O(ӟpZŽ Nb3tby2G _+. Yֱg/WD;Ncc< [ڭ(K;H?Ёczu6)Yukw(9ޗXg]q9"T4ho \w&|5FBu{R /hkgx~V{*_;'>T& ۱2S#x&#_~v|(C .K`*{ԧs+z%nbƍ޽M(XSuPtnK/ F o,r9U{:t#|-ʽ>a N2~u.'?¯ݳBL&ۗs8RUZI~6QP@ESRRWDZ0iRBu,zW>Q=,[FE>><yQ bP7 mBA>?zBSOo [qԲ2hƏ›njX[<'eV^l,Kdϴ]{>NP޿9vɟi.ȑߩew/Ǥ{)̓եn$  8%\eX#6rVF[ch Sg!fpU]峇 7+}r"'ܹGS(/lTyVv{p_o.Z~o J?'4mE4Ñ'Ϸ`J n[Ԥ _nj []nj_j_4 pbtnΕWR,K9rF92z~(㴄l׎)ȸq 9?(_ttD#.&GxU@{5.|^*\ܓ=݀taRmw=6./ޏY>VV>{< >%\yT[z+f<2SG?!|5gh`!hooߞ/L>_X o^]Kp U&a_2-+=fΤ}&j/:YjhR+p#rZxNA|饨A%}MZA^hl^GH$*d^BEEŚo(UG֝4 lsϞ=iǬKX精J ¿VwG3b.y0&d*87/c}.**`0H~.)B*(i ~ X{i(y7|OA7Sksry8e%`'u/Kҳ%lXw/7Sݴ{o Ν;i +>Y%384\.8:}M*|p _%pxWA޵kرm޼6qFi3=}3~;efeibذasߍu)E.Uox@8xΝ}v4oذ[Zj5Ҋ+is%Кki#$;;2224֭^{|޻ڲ~$BY9c7p0t(U1+ܲMS~< ܖ-[4kf C^L7}/^L_s2o|3g}5{6fK[n04nܸI|ίeg\ [ 7F~a>b/X~c>><ʓS4Yfї_~I_|}4u'LOwǎZO>}+DD@ZycPòYDL_ïL9~#|  >:&OB9W?~<;>#9Νc6t`F$c[?o޼mڴwGmXc3(57RkoVۛNC _333qß4i6M0>3-_ArF*|*%Kѣ](2*b6x{?A>-'QOfxٸ/ 2udVi^.dFja{?ll Q+ /+2LWF/}(rd}m>ʕ+@K![o>=XO .%?q3Ν+uqDX¢΃&x%~f?@¢7~hl߾> ァAVf7r>=׈F^D5|B:<@ؒ,m}ӦпUI7eѽCW_q? 0Υ |*'/iZ?._ǟ g }DUbJ0őeBz9TCNhrca9K=fzs;x8d"m@1/Z>|C;X‡>JE#|NWjS=] 5 _?jZ9`W}&?'xk+xE2ۅv _s?^_l͚5{o5 5ؒʢ" ` zW i031o,J ͞3G~ɓ'ayO SCaǎ;II< ?!>{zؑsط[r׳ɻl&~N?l˖-9\ K׮]; :}Owot: _ F3j~w\F,X!7|9±7|skń/ i^N ,PLȒܬJ@/J:,{- ~jj{iq.4q7Rv)>\̱]Ɵ _4H_+HO@dd#/𓓓ˇ q9Sjr,ϱ0P? :^|٭\dvciĐ#B~߾}yumRnDJx'O֞azgQ^NCqq@=} …[w~Nb%Ŕn'Mo\QwU(fq$ t2dXŃ5||&))FqNaW2''1Nrm}f͢[n<\qTJ\)ۼNItPG@+7wʔ)tn{oQ< 7$z>R'Sŷ[ rpxi`a@\ׇyƌwmS#1 DkYCY$FA3{שg H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME "7)"IDAThYoW}띵7$A'I(/HR%R> !TE @G}A O!TH( ">I*Ƶ;;x8̜ݍw73svgwbf<̛C= x.fJǦwA @ qf3#v{:Woffx) οWnxObaaa<+%+Okx\(W0sLz%e+-<8}ts71y{iګ:4#$I iE CʄfF{R AC 8| [o;rucd/R 23R$P\Au-?P 53#Bxol\}֭;;]:q Ҹ""!;YD  }LA !9A!yP]^^g̃m0Z̠tmnI$1S t^WfV . !@ٴYP=D}$%°BJ1B/MpQDw'L,u1UF0 "z}OHz)7Ue :g2?X?AnqVh+*E(rd߰3 %} f1 & RR7AGփ/=Ƃ  Y7PL0]@\ن'D9$ C48s&|{PyTReS|5B)d:{0)v {})poWR'MYBۥǎ;, }—^AJ7T<5ٳOϞwT*Bf򺰷 o+_I IK~Eҧ-wVe֔Y3{S&n(0s(ڣ wRxD `@ {8)߬D ylm5L0 nW@0,@ Z_qPa6k7qccCO?4O՗4R<D7qJ&ŋyǹTb-ߺy/.[*=s8 ~(6#)\0Mi-ʤؖZ?AHhԯAl ~_7uh{ԫnI=z؝C!ޑEԭCgx*'X0gvDHݜt*Y~? nJ֢;fy ԭ t-7 ٬6;,2J/ )bl0$Z R:Ii 7U*nqEŸ,*o)j0/RK]E<ޑSpv#g7'xQgK}*>eì[J(P9R$umVXdZ+f>DYmq%a#3_uҀh[>5 q֧lNF!k h @R@kK&tg>q߱'::-RYIENDB`yagf-0.9.2.1/src/images/edit_paste.png0000664000175000017500000001133412247205425020221 0ustar parallelsparallelsPNG  IHDR``w8 pHYsHHFk>bKGDNIDATx][lWz ,ɑ|QlY,n1$.n o }KQh_苁h mbo:1"YwYw(g3 *s9y-ml+`{ij'$rW_}ai\.={lt׮]MOl%G\'O.B(1uر_pxhbpҥ?;MӺ[[[AUU@%ͻ!;vxܹVI(֍H--- {l$w)Iy<7 A_|yr7AANOOܹaޮpsO'''wmnnNx㍧r>iZ@Kg(7oη>FhA ;ST!322AE|G? AG}իW/a2<nDPP p֭8xϏ9A Jlx9AFR*$[믿 zARmc MI Ii|ePaiaʓ‰D'|rjc#1GЁmqXǏ׭oOKѣɀMB8F;poM֖ n"Xxokk_F?̵k ~5 w(JKX-l f(*(٦8LFC|3 |?3g\9q:SKު)!z |?v_v4h )#5FtR+9eЕNZjc݂h4 [EyTXȼp*'7n|oKovҭ\+ÍPsEG€[vp\)䘗t&O.VY B^ˢ$k(fV^P`OۏR_={vÍ\+A ;:{0o(%S[A,*dg Z Ai88xXway0C"G"@E.m̍: tn{?!b(}Fa8p=̠g O^F,ӈEUľ]5/ a O+/ CZm3y饗`7dQh ## xݾ}wzzq(dy;Tvuxw/y ,+2{r!A^xqj4Jڃ~O91pAye[*XNm000wޅ%܌/ ;v ::: a6 nsQB8ǨEM…h`C<˺BCN>LJy P[4 &+ZxѼ6 9QYp~*~߭]MD vm/ 9ˣu4Љ Z[[2IIxm~0T@ϢGpJ~X}!QcTHZ3 ʻH[%B.)re"oj_$>KqfDXa4ʪ_:u¯8 M1WDH|DwDŽ@0B;-ȸScn؇'⢞Z >+Rje<ѡ{C byk`@Oh&VjAtY=|V; 'lj +Ct\:)>+]jₚњh`Dʨhf{B檔hjdF\Ov؇"sB>{+P.!5X ^(^+)Ѝ<YD}Szc2$ZfŨj$ a c[H^߄$J]l~1U*L=-WVʯE+$XDQ&X[M1|h!yMȓN*Jir&edds a8? +c_Bk LaRkbS`) '\an:N 1d˶;OўN.- }a6?Bwђ֕CM+T@ϞiݑpV7eٵ ska>#OFݡvttypa#Gү?W]3Vm$`PCg-,44˭6&0?sΕSN)_>>UEmׂp07,B&&SD:%Յhtu1N0((憆q 1Ou2[("ws O.M cό'o6(dE9O8tl^3dvvVC/h#H`<|3)Dޅ{~xl֎w (e#%yJAIJ?݊-UD b]*-TT[Dh&pI6Rӄy8vbgl̝;s̝<{wUm{{Ϲ~߹PTBEE)ih*"EmGB3!oWc;@HP0Ϗ!T-.t +mADSH#/!AD8%uOD@rZTiLB TH -ɤ6PU퀝D~@|*jӟ@WWuEŸ:!9U\i#‘Ԟ_?%oWaG:Pd]/@WW߼+'|Rk휌׮VLEQp]:l?Qs~((J V}^f%iʧMk/i18% #DfLr"/L.m!DB8p&J^`EQ %Gs”&+P39.(EQ*Rrt:͛oO (#R֮UKƳ /Q$8eW˲ʕ+į^% (JES_}J)Bt%|)eB{FʫgU/@n𫱀(5R%m4f% #|LxضM6U׀@,e 數IN8$xP(Dk[vݺ fkСC D m۶QWWWd2'|iR__]wŽދUz"B2DFbLOO3<=ʣ>JKK /_ѣl߾[*iºujB"!E"\pضhnn.<ロ5kPt__} G4-w]i%m9kOMMsyt]/LNQ+-4IDн:Xh44dT*E24Mfggb u4uEޮѱ1lV8۷ogͬ]9^z%4M#H r1&''1 ̵`288333466233_|:8'XF/.u!`޽qnfiokzk+;, TUEu4MCuTU%\|kJVBr`ypܴa7tcfA@ Tk׮5k~z u%s*‘#Gd2%J׫J;s p!^~e2 @JK6?߿;wK[[X6z{{9u;w#8ߏaAD"ylٲ[oټy3?06lh4(DQ裏O?Ixy'bJ&@@< pvs;v[9H0;;BcDcc#ض,TX,HQ:Z[[ijj*!۶ҥK$IQDhmm-=pчzH) S_ E$-kVxw8"Ԁ,_@qR_B#߃H-Rr̵}ű}U+\Rc (.TMꋋLp ajp])eEK)qv¶@>/ZՒZ ]׭<.mcv8^\P dj&8UBml6eYA:mbYYl03;;_/T ! :6m&`WYZZ"NXӺ˳۶8|Dىs Щfٳgth4J; B>swZ28_Zšm+ ܧE,*eYd28f&6RJR$gFFܧ~.] 0K e^NBcE, n)GW GҶ R~3jj/t#"L0 ώ;#30 d??Bλr%`lۡk?>޷A lFQJ0|ocƹ _ 릔^UUwպVU}0W~ngsK|xhP>͡_O ruN7x㱦HD\,".U_J̬Յ (p $}rY11|h +4 @)e@.1ӡӁB!4(FHHIl64U! C46~am7DIXED Ëa*hFPHob:*SA|TUEtD(r엲,: R#zxt_v~ 04! fXDU%c8,""HM5OWW,",LXR 5iv~%Iպwq(8dd@̊"’0CKVP G텉W8Q U!/{mR*J \~!""+g:圻r哾0 ;O .@^YvRkf_Ɲ{~P,zF0bOD0cS+*50,%)@?h?<~:_(@0A Yl: (m. 7dz*Gʇ*6$ im$Qk,=zB{X,.-/?y`_akn ",u+~#Ms,B%h,&˵[6...&{+.- c|l[UoX}GC$هi##[[a CmnWxɒl` uۘHرフj_ЕrLnoۍLQ]#N;< CHUz+lW:1Y2/*rv"O?rZdX,QT4UYQDDQFchvU~[vBD$0DD@ Qh'ʥұc==z}~c} EkqH僙EXDYT3UXR5ѽ!2"':Yg<5R@Zn'wܹ $Lz]ÆvzBjEw[X@@DT0wbǏx9fkgs~lZ^;HxB1!8N***䭾**""J%##'_{n Ç66 YLӍM9NTTPRK/P}OMNݜqRo;wW}}UcL7o:꒪톏=QnV>_ PDjO4RV08;7?8-"QNCbYD@U<\PU/~~d7G*ީɩZɕ+ea᳹ \9V\>~ԳHڝLUN֙Թ'ON{|V+׮]̆!)0}(=I{VvUD8rT#w.SDET֞9szK3pO>b9mfǂĩ:N|wE3U}2!U 3/42tܫoOO߸ycC=奥ϟ?W^[L:ZM^~ZO ºqLhoM :֛o>G=|X,ʥoΙk's.}5t׮Bs̳!AGjAΞ:9vjZOé564Bv yQQj` 5 `}~gv^|[CSS|G/WŢt%%<L=&*"CaJ\f"j_d0uahhԩOvO?`չ_^^*(9NA@;.scBD#'>9[/^ǎU{.Lff/gZׯ_U(q3|۩F`\ ggK,qfJj l-ٱo\(*?_OVɘͫ I3;iZJk߾:6G(CƜ:5"PD°$.n5٥J=66f9O~0Ri@bkkˇk5wcC F ~VzzџAiݾx/1jfJsݶ(_>ZiT;A(}0\~Za0 {,Hҵs.IowlZ-FS.//<]_qF6Au0 =e8y4($ɖZ;ϡl1zP,f{OY++.u3)+ukP$JIENDB`yagf-0.9.2.1/src/images/scanner_s2.png0000664000175000017500000000572112247205425020140 0ustar parallelsparallelsPNG  IHDR00WsRGB pHYs  tIME ;B> cIDATh}L\?敡3SB ѪDwR)]n5i1jLpѮѺ\hZjCKZN Ey)aP+Üs㞙"Pl޻pH$|w.s'qETY ϐ#| rJB03g$ \x׳{n9s gesIEv+,VMee%:<~xc``h4JQQ=?\#F2G^Bp [l9q.IEEv@ @SS|twws) PÇ3::$f3&B. kCaZCwxKK\.g3{&nߏ$IaX8x !9sP(D0s42ˣkײqFYfM31ѣGٷoǏ… v˖-#L2<yPVVF(PTTd"N2?Gl tuuOi&EYLb\t^8@?a6LMMF_^[ە;>tKKɚ4M#344DUUf!}}}tuuqww^~eebBp~94HD<󌏏qݔֆiڵˡ䐧?7|oy)))Eww7%%%\.~?>yپ};N3˴ tttv$Ibzz.]`N9||z=NYb211lK V_,v1 !2\.8###̐O~~>vݞ7288-WZZZعs iGO/[ YI$ Q\\fCQFGG رm۶155E[[_|HJaa!vUUD"xfdsKFdGrܹ={ /lՀ4)Jڶmχ(!$Q^^t:MOOdZ,l6,IӸn|8,ccch$Ih(q u=[3ivK/7sMHa+7O>v$I" (..bٚ'!I+VgfZX,L&dYnX gL|QUYܼ|.Ѐ6_"\_~7|SZT*1|>B0}}}D"fggɬBN3v"  D"qB!gjjRغurlsbB_8 {j( &p8L4dO<'Dx"XX,=?,TnRQQ7ވe4440jLsABQ(|:߰ݹsȩS(..Fuٰ9KD"$hd2 DlHx~W\9qŢp&K`moQ7i&ARX Mp8$DYqݘL&JJJi͚5{}}}WIIb 9B?$ P<@n޿/AQ?ٳgeEQPٌ(( 7t?uͣ ,7?+LIQ(+v!ڵk!l^Wr-b׮]:MjnhsZFl@~ 6n܈를W G4~-)|x8bbFwmx&afMwUƫ&%,)5rjUZLJ1ׯKY@KvbK[aBj!"Z9C9=WV a຿YX֜DQhF IENDB`yagf-0.9.2.1/src/images/editclear.png0000664000175000017500000000764112247205425020042 0ustar parallelsparallelsPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<IDAThyT՝ǿ޷UںzoziH츠EELDCt4z8q!hFs%Q䘓#HT4 vfkꮮիz۝? ƭ99u>W羺pmԳO2|ԩowb΃%ߖ֍/&룑=ȥEuwg eNzz|V"pߒ[癆vCq% V"%C=sj.#y>5XC.0wΌkt}q0\DQ0MY_!x?vhW>í{1&L@TՋcsT@XoP.kŦ1dW:NvF'`(a/!24. bckϐ 0¯ꇑ=CgHFqB8E_> =T2AdIޕ/\rM͟_!$f' _}m(g!89?E T[De8 v!_6B.s'Mr-EzB~zΠ 閕`o ̼fpJ*җXw>P!?̛ t¼D ^;AˉZGp(@b#<anT4][n^{Ġ>=нk^a.q.[A)qz7LPTP;?Ï99;wuÅɿqxh]G8_6h+nr $C$qf$PxY<{TT=,Ku >;`)!+JG >;ZOygLŶV_v"aP8Ú/c!ON$lzB3ێ@'`YD"6a7m;^z("4Ǿ'pq 5?n.Wi]Gxmٗhŭ=8"+^co\eh`yT;g ޾.d)~o$[.Z< +s|$P$mk=ì⊱ +ýP[9?v;ι7k_У)-|+ nskȠ^UF"rL@{~qa\ґУOK%pWx.σMMO=pcK߬x\x;@z[ZL|} G4WOr(s ~Ep҅Uuϡ5,׳+//wQcͫ̐Liցqm8(Û,䓁p snLȦOK1@Tw7z5_K`\e.EK, rA!Ƙ r}xd!orPVY&" J$J 0H'\o5 ,˖%r|sBAR) zD^e!%, Tgos~'!e 9tG3T.hs~?[l%iP!ALPǶ`d0MRosNG |]>`X!o,p 'S8֭Xq`[lBf` Țx+`e`XoBmHC>`i7.lg" s$G OTU~]{BCwZBB3aiH 88s rM*Pb&X.JP DbR"3J\EX;0c48V`@s]7/LFEl:8 YPYZ=AoLIP"zy @b t QUo[ 0J@ @9#ٿoK&솚+/];/3Jatq'!"i!A9GΏ뮻={1ǔOdM|͍02IĒ0 j@(LÂ[D c(/ زڤF' pJ7)nYcvPY-޻o:&Ao䬽Q1x7Ϣu76e˖Bգ;x陸ʯp)}mhb.1סRj@FW4 ѱ v%͢3Np$L;LYjKV R6bq*fM2}yUe9'JYxXN4osmh.8.vRu->poڴrr'ɵe;ŃD&bYѸ D 9A?I~ [FO0ݭ5S&#w8(+;e{8OppyLCg|ޞj/Kx.0qpdž$R"$RPYB% T::ao$OD/߹j:2iͪ-~:4vGw8OJTNٺ; F֏׵pd˥ݶW Զ-ɶP^Ɣ1y9/]=ԢHet0%f`3I"@(A,(-a m:1:S-{Sg"94 Za3D(-@(R:cz2a@8lsG(q(L~rycsBiii!ehT72s mN v ۆqiL5#rt$IGN.ۖ,]LF-&G &”\%yȬ_o䆇+[slܯٔUd9}Hi^Ҍ(\< ~ƠD{S,^ h>C~u<IENDB`yagf-0.9.2.1/src/images/singlecolumn.png0000775000175000017500000000566012247205425020607 0ustar parallelsparallelsPNG  IHDR "L pHYs4: MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_FIDATx얽 07|G"J(aP?*El6_U8jRDweYFgeeZ'IB*%"4Myo#"<[kam)oy0/>_9zZo_.(R3D4E"1MDb=E9R\cʲiﺮ(WEG5dIENDB`yagf-0.9.2.1/src/images/info.png0000664000175000017500000000735412247205425017042 0ustar parallelsparallelsPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<iIDATh՚{lTW~?{g3/!)@h6Z4JVۖ QRZu[UP#RKԮVZ.dMZ%Ym-8cl3f<}?I6IZGؾ{wFh|bB _6 (5YB@(@:=@-u*PjZk3}% h`CX; l>fvj:_.R:>>>{رo)`RkT@?7bɓ'(J7tp[Zy]tжmkZRtɓog}'@`]Çv !88C<({|N葑3ӟO>! lr=z={<`8m/pAGGZkɓ~*ʫZk3B{m'N<߿Q)8s9~+ 4P$*dر)O̲w `ttt011qi߾}{Z7?5?x.ǥ8}*\Bl6êLڒXR`{ZIe)ξ΍i*NEZ-?/?~E?>m fc;v,JiBD__5plY˦tqߦ1*g>ͺKiƥS|x:krI޻iHXEOOZ;~ ۙӊݲm۶^koo;)%Bƿ#sS/w'ȥ-ϱ{K>zGF/]M4.Or_?H0RJ6l@^/?Ϟ?Eཕ[F3]\'NAJlg7E7o[OX\d [&!dljSg.!#)WcHIlWa: ?m3&)LBIJ2 8zzr|! SxZSmxF]*wueZSl/%P(5R)Jf"-F S ]ػkEZ.#xJALWA)E^gڵk? |}q}eBXm4JGaCi0 㶣hndJZbܤTڏhINR"˅cw9ҀքaOJɕRK3s =H6S\kаaYЙ5a>QXl ϏD-Gqڢ\i eLPJ8k+=pC ly_.M[ *}|C !8P{T7*p?SZT-RP(dK5Yq"@[R 7/TRnp@ A”$-ɗv[7X 62|h@2=W{G> l68N>o6HDd ))nKiM/xJG7/>L5#? t<$Dۊ gwFO$M3x5,/Q4</hG!4h/. [_BvhZ] 566F^>\+4Aߦ .?}yse2qO܍X^fu^zswK|0[Gc~P4W.~lXN2JKH,:q~z dř7\BJXߑo*amvadH&GIJ#&!5==LVTx0 l6K:F)?s#!ZT** Qr;edHӤR)|1k znnN߸qCJm;|u80jVl'U@ڂRrMׁ9`p@ nlC𵄈@`C D |=$kϊ@zľd@M k.mwX4.ݸ]@ | RIENDB`yagf-0.9.2.1/src/images/batch.png0000664000175000017500000001111412247205425017155 0ustar parallelsparallelsPNG  IHDR00WsRGBbKGD pHYsu85tIME$/y*@tEXtCommentCreated with GIMPWIDAThՙYuomfzf44F$b(@%U*RYx N qB.yp*/%rb"Fv(Kт$iF3=K/_۽7Ӛrnu9,?_bk;>엻3֭rXq'cI\ðv񓃃5#: A >~200 VzQDh֢&N5M&>yUq]ҏ>ם~衇|*GۉJ]G1uBH:YGrV&KΞ9b>*'.i4|3Çe8fȩEYJ)jcPSEfl{N k ׬򏮹w>*͛~>S6lp繙xX^s奙+;-WZJ!RBI |~Q}G\={N24:y׮]ٝ9 lFD`߾}˖-[E1!+(!S8J"DIR cI!N4IFLLVBJ%9|ϡgr>no@;5/{WXyU+TG8NS)%QJ"@[K\א'Iqb\cl>"B# cb+@rpݷt8I$qg=^0;vz/햛2I7iZ7#_ukVҖBs;È'OfDJoYϼ.@>u]^y!9gg:rx麍s\Qy(uk X"̃O>Śg>Y V igZ +'q=q=k7A9NB7x_m,iwRm[Ny/w Byonmo޽oB@qQHzVcLݣG W_kF&ǵ!lYw֤HHӔ(IFa_F$+YkI__R{%N9s J%yE@6֚9U,UT=jZTӻUc,Q,(rIZBJ1X!Z$ BJ4Mi9H)Ic mmmc.k=WZ&'>ymLQ3Ňjh< ~cA3e¬Mfs!HSKKuM{[mAzH)b_gs79]yBiZS(\AWZHb"M[iQjhB[AYH)BؖCJ5'R" B;v8.]<V-^#-y)Affi3-f)Ć % QjFHJKd1{ARb03>}Ki͹9RmjTmjM-ij_cM=ܵQ! MֱN~t6$')vf ap$yZ+._.^z &&{zuhcq _$.jh'}׾o>AOG5H( aF1$)q !ARaLHi)Ra&Fln왌3u]Rx ̺uwam( Xd1|ϥP9 B< .epd3%f}m~Sסvr, 1x^x: Cvؾmqgp:0hk]A=֭F"mgiƹAkNiRmBU)1wA+p݃t<%+%aj~٤$IR9y.PgS:Ʋl%d2atttVabmjMd~`ַu}K.U'Od=k: n3()"KR%"4($"FΏ1a=X)i{ +6󊤣\.a~(B)EVcll 8^؅ Q,J\.Ǟ_N1+gYyԂAT+eN0$ CjZ:"* %.[J' 344ӧ[o>rÄaHRZC#<Җ֚'OǾS.82u;YAc܁5` dO{[q]+pRJnvy2Z8ի) nxxn::: <-[i&8qccctu}Zyzܨ祤q)o,sGP(+ c 3>>Ntww/w7n8+&5zjV^JB:X}⬆dekײw^rmmme;Yx12 j8Y|1m.1+I$!MS,===\r%_~}}Yd1bU L|u+hO<ӧjA% ^u&u(l 3w^#lm,OߟyиdϞ=g?}ֲd,YBP 8Μ93< -oݺVF`N"t$iL4C`۶mܹwyVqV(JT*VX<7+ٳBӂM #h57ƴPJYBcZ̷6mD&cͬ]ǏsܹֈeѢEXks2ccciֺR2VM3S uь^.b%l6O?M79rϟo!ۋ5W][lL[.Z0 /0$MV5-̑x^*( DQR|c -ݻwϲeˈ8qy(]v[n󢳳+O#32>>ZְRTU) -J, p9֭VTj yڵkKH}Wq^|Ň:)k4ehh1r\qL&Q,RV f2jRJ}4VAVCO>QJq!;> ڶ޽b Js I^{5"tvvfq]頟I###,^x.?;q}]> ^8??zw\/MD+@qzV1gĴB}~zx Y|9+w1 IENDB`yagf-0.9.2.1/src/images/trashcan2-s.png0000664000175000017500000000432112247205425020223 0ustar parallelsparallelsPNG  IHDR00` sRGBPLTEk,^UV_OZ^5xe޽?(j~GbGsF:yhgGn B!ymmͤȯjY qD:kgO:^.k~LMKfrƸؼam蝈_g 6ܗv5ݪ<pd`PF:1xbM L&q* ))'MJIeR}IwKAAE51 `0I@uH.+h__o ~{t@"uu0'''$20c6`P"Pp_EjY!108>p\971ˢ'_蠄ZL D\MB<Ư,1?+&$Uur^&Do:ŽS-iPju:x^[[I ;)qG>5,E8Dej6f/N<~3<"Wuv2X#8=k@ӎ;:LzV3c\,g6挎MhA@ 1,ޱ318,cZ^;2(cÑυR&~߲;3[z=4rf9s8A1O/,`2bp +bby+YRXljkkfP`. qOk_Sk~ېhJp6 "èU} nODF[k…7݇n{ihlJ )3 g&2fЃdsﺭNw~swIun0 ]FB2gFXFΛs9YukIa467ew?ƴ|;;>|oZ/=> i=w)t6*[7S[Vn`Ɵt-4T@N!΄?7'ןֶ+w{'Tvz]28wTZi 36>ýd0dH8C2\|^E)t1}|N\(Θ7k.Cd!w\L" <㯣};ObG㎞yhumowB' 4UH <.oz/~8z̗J{uoOZvQ4EěJVĸb#m]gL'l~artn@x užLY?={߾z{kgg x GygDpw:q_]Q5NTxĀ7(oƘ :lyn#`k׻ 2~ X=z7۟E_P1?oI1 x{_Z_cKbn$S" 2KJ ӟJo~s"7Q{vuLhOÆ3߈^XӷgiG18qn>p\bTp4Y`IENDB`yagf-0.9.2.1/src/images/scanner_s.png0000664000175000017500000000570312247205425020056 0ustar parallelsparallelsPNG  IHDR00WsRGB pHYs  tIME ('{9 UIDAThklTkfMisZ'ENiQzBV PDlI?Q4ƈ5&z&%~㇓cR%B/2Notڹt:]|kLk[*=z뮻2sݻyp\B!N>L__QvQ y{L&V+,t:X,~, v˅j\2@*8vPk׮i&8@ww7ϟ,lh1.fxBUUt]硇o}d(i===l޼^y^~en6;wh4(7Ib6nHuu59q^/;wn>(0eOGn޽{s\.*++q8B!gD"8qyEB[,f3EEEy455Q[[Kyy9@OO>Ǐfm۶U^mZ #NիW $6V+ǎ!PDôse(sмʎ;eyY3?H055Eoo/GMӰX,$I&''㌌G^{?N%LO?Timm=S[[iDQ\Buu5!}}}tuuqwpa<21z !㧟~czz9$I"LrUFGGI&x<JKKikkC4^}U^xCt>#wzғO>)JJJzn)))v  tttPSSo}p\8XUUh4J8nq8 I 055dݺu( 'NX-5SEÑ7288-WZ[[ٿb}]>O>vNMM m۶sϱw^&''ikk/$a(**p( ذav [2KR}Qt]Lp^|^hBE&`50ch4@$HbV+yyy ݝy$QVVF0n#26 Պld2e D" avv6[dpp!ZZZV- K[okגNB022@ @A4X,\6y^p:\,333$I0X[D ??IJKKilldϞ=mڴsm}1'6 %ڹ_}f!2fh4J<e7Lljb\vD"A"KEEETVVr-{?hll< .HX* F)]'Ϟ=Kqq1#ȆL/HRqR0;; }>uuu477) 5kƯ[.lL F_coY7G4f3it:QU fff0Lx<f3%%%֯_O]]d9 D o669o駟z꒗^z)R[[ .\d2!2,cX+2k׮{cEEҒ0.-hCΝ; n1f3a0Wp#'4# #VϾ;qoߎRQQqZ3d_ @,0pGˆ@J[#G:3Z]:HoJB1.\nBK*AE e)*WNl1Xr4T!ĴL=w9sPV(<93~u#+m&?ntXX6çwfr1 3iIENDB`yagf-0.9.2.1/src/images/selecttext.png0000664000175000017500000001151412247205425020264 0ustar parallelsparallelsPNG  IHDR00W OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs  tIME 7v~IDAThՙo\gw|In6!M D !HE%(H V(|6,tĂPUH - " "@*TL|7홱gaq93EQq%3oB_tpu6waMs!AR5cn~0N~b)Unـ .L!kA&3W)0+WKr FbmyLNNF'Nj[ωzBi銙+zk̙㑧_ΠB*KK-e0|j) >z_ӱUH˒dNMFqMLNE)˗aqq z=jgΜG+o\Z^dP*C՘TMZ [4%uyJ(Ez* ܹMfy*Kgvvc7>KcR|j;a>dPS r[kZp8SZ-;kw"d, [/w>HJo1g>nڡVd׫`< 8 ;QƈŁyK޶%AV4st(Jn Y'FB9ZwiT"٘299g0B|9<h;a:%0}揀_hN7㻍0Q"@"PH݁Vh ,+" *11UƦPT&J"P,cM3LOϤ WR`v:MxZzZ9)*)(,q9"9b<#&m FCш$.I2K? -8P`|odBKu: L)_ hOTU3JeȈP7Z(0$*2i@B8 T& (CBF0CB%0I լ7-ap*cJZ듩*}j IST|B/!A3NQ<03}$>樔9XpRqhcH9--jjt]G)Y";Їv0 VN24GKeUo|gӲ"6B h^wA+Ņ,p?mDǠzbJƕةPr;!cW8TZ^_ o~ۃ x__3i^0"1~` h$*Z䳿'gޔbUT*{@ 0#"kXYY*LF`߹XF:_ڵߋ05ƫ޺}}zǴT膮 kz=7_{]xy첶h4a9jTKrSӲn] vpAg@@`bKGDIDATx[ \U_[^ldB  F@DGef̌0a< QF1E @֡ӝZz՝Nҝ43u}|o+ra  $I+vd'|J SKS[[+_jW_I'@s:Aș_~~H$ᣟxHDAz"sc. .]zٓp֨t&3x1Duv7:(x{vjdznRpo:b޹eepժUSFVlvk mPWW7e'' ?} \+6pKMwBxUyy5?v{{[i#g;Z^u R%WQP:Xb5)x<;hN -tPЁͤ)Kɡ0ۇ<džo,^a.$ /61m#ްWUΞ= k֬la-x< lwBK =4.CLIc|NE4@fNH{; XzTIV~b8J>o67-B 2 fpss;V=|-p@#h 8]="Yp|:^::JKHEcH0-LwTF~;>.6L`qvlKKAFV=7'̓!uɴ4|ow DG#"`^t19Rb5arKЉNO["0l.*,56XM;RNgbPҡ#PQ0H%|CrrOfZ5h{Dʐ(Cƞ ;TTqR*:,q^hϷ0d8.>ݕqlϧ`*+j\\|aF8PӀNFg>PdGRYP8σENb>tro^Q$ n(:_⹨|&i]8rdMPP( "%TA%xq  \i9yMDki:F#9EVҬ*;q)Fsf& \jff2Ӊ_&1@D*hw1Db&w/gVK"#A\Hzɣd2GR`8n.f35daqv Yv2|f^Z!!IZWnBfZ!:|hhD3RY TKW5^W Tb"ufx Rp}xF\9ڴ v ޫ'@X'XgdP / 頋 ;\ŌLʤjrG$˴**Z-}E P !4a"CC$XN(6CדvV]dg;47 !Ue`H6@/pIÙĈk(t{g. @͒5BU,OVI[ `2JEƘ1\!K)D(Q2őx+1yR1LY3g `8B( nT!?(NOf4p\H5,_\pQ响m͞KES 8LC4wmC!$CB")a-Yj sDJv(DSB"P_otW@$F.J[ $HбTaȃ0tP'iMq>_ppdyNQA4II% 9`rGuFQvC20MAMB/B"G{$1t)_?uk -Q "=XrT_Eא%}`b30e}`!K 통1m3" H6,4c PiP4 #o'(9o8/;ng vqwnЬs> p7\mn sP ;0U+Ѱ1/Ew_x\ G;͵> u?0'tB*w}h1-& U6hU7o\>ud9N@ȔEاwHs;YM/2,_-RGFC.G*tb)nZm]: Ouo:uX&98Qh5" _LXZ3cR{8ݡHct>C*mfӺDKjGFNT[M%]WO| wFIv*Bv>H DC jaN@u}JZvMܱeyڿT%#(ɖU6g G`c58u'oU+|w0BlfV9j(*i; T쑼sx<̰KECߒx{M~lV_d&`XA+nfI`3UJa'~tvl] ^*`=P40,G$b.ckO]+~@I /Ry|2l[ s&W{+k! fksi~:}Nx}>q޲TwUjcNH0mDØ~O&r $h5epGH LԛP HQ@ʩWĮըWw0{?c;s*6,.R#j41MT(Gn!'%@5 "BAN 5PQi;AI KtgGTsQiPf@($(RS“+Qx+!@qeKɄȏ7NT$ zoth04TW,IO 4^huNUms!eL+/GU02|^t\'р|u>;k,M|?K>$-XPy}_X}l&CWV{ X,>o%z-YP+%(uU1wTj%u99 :PRGȞ zܔP%&kx"IJ{ {!!2zBUR bIY[I * D'-h7~2, 6;f-kc!qk{aZ9$M@V ?CQ`|AOG ePSS͎ x&f=MhIҠ*4P<d endPj WnDBk o?h`[@2,vWF0#;ZF`Ȗʧ#}RonZ7ت.2+>۰t8q80RJLb^G* G`bb{Q_Pn“_>JA30ckèP쏦ai􏅁iYJĢTxz>s,$ 8`R8'/߿CڶvaX6QQ'GGƑ ΨH3$8L$x&dD0OƊL% w`Y uu'˷zΔ/Owyk}Dz:ub$KF L "YYU}$t"4rUIJ{C̐hĐF"Z(d`XlJz9Z 9יXD[2Ë::2ڑ{1O+JM'%sdp \93-t$I 1  w&}J{QhZMks疲]S UTgf#Ӝ%d(pS=l]^V8L,nwHz Tc_d5аGR`f_,~$\4'Ф$Jnq-Zشr>C'ckӏ0;I$?LLoW%^S9^Rdrт;O)G֝- lq~/$LrwUrd}ﶞ=wI_7\4GCD2=UB4&sGd rJ{I'&E>3S#x`\uvx4n /7W{wl/ [ [1~irPdR=]z3pͽ=}M8y.-ٶsOIfi;]5,jt cҩ{9ꃧ~=s,2txZ^|QVշu/hNw/kGq3ArooYQ]spJ$/Y-rX|l{2EP7쇗wό%ވ3[&Otei鮯0=mGrۚFcjVZLa6]QU3L׌  Rcn8:z{ϑWYw>R.2аtm¥tp` u(|n̲lB"V9VZUFEuY 1գ*Ъg ž MxP|dR|n.W1閦7˝re屠[iR㫴PRWŨ  A&W\g 3 )6@H%+rNg^vގzLseq&q tlZ2ڋtϲ8oX%/f! yFV{F8g7i MU`>Q'T x8}혅fm" !'΅(If:{B+ lJpAGs-;'ȳu(Xu>.6*D=`! FJB>\Nj*}W({ A"N%*ʃ>۶}N!}:DR%Hr,,$7ŠͬKT*\.#!/кtbX[__¹o,2^\|X77NI@8Am_=qCO .^bm(|*B ]]]=ԋ}/:yL&3`! &|VtBXPomm@~qy/`Νo|gcH !dYl߿XrYM&r[ %H$Bf}wywTJH@6ŁOVJΥKy~%Ƈ>~&G^?̷7< `uu ر?ʵB{r @\#Ay$\v~/~t?U-WIij- U>sxϧzr(cUYֽJHD:sg_k=Gπ;922Z4?=P]nߚ0Mx"! MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3bKGD pHYs4:tIME !劍EIDATXVK0)Kx 6&츔'RHpWA AR?-y3Lg 0^1 H>\6mS4<c46}?H_|!B!;!;; @2$iR/Z$'_ aTZ$^yݾZ@Z$r/ϑr |eyBYwdqh?FZS*ڨ 6$2Pu۳lt5ֳwDo8uOSsD7\xC2_y7IENDB`yagf-0.9.2.1/src/images/scanner48.png0000664000175000017500000001251512247205425017707 0ustar parallelsparallelsPNG  IHDR00WIDATigyuElI06X6NfiYI&30-mL62]!M;ͤ)6mbƒm, -H9:ۻ=sW%$aH'fdacs?}x(Y5Е&LH߰sҵLʀ% 1X2lM :U/s 2Q-j}8>fft:^3 ޽offscv˷[-DALȒI!d00 #$f@30LdDQ~(=ަ,/E}WRn eĹ_{gpȞ]p\%Hю$MNɘ3*fbR9%f afMEʙhl:O={w,/U_Bv$'xkkvH$#Y24 $ɨ`,fཐPh/ 3^2Y]]eyiG-|?޻ ^yv.-jsTjrFp{%  >F,B <`4 DMA uepYtj» 4\6A3/j0޺&3SmH` i\.N+L3dEP$@2pHVrZi#̰4G$#ٓ1, Mc4"eLU<DiM" ڔ7uG&=~Y]Y|c1׌s̜KJJ>2`Mv\s=ނ .%.=_(#Ə\6m|Uf)?{fU` Ni='e_+ /aÙ?O%Z%PWZtbiB\*t v +3x00@Db}w_;_, d#|D]L1q>*b@dr`hjG,5ЌQsqz?Q ~6,q'CMŅك7gTˉG?Ǿ">$12QVڌ=UmrUL H4zFJαf,\g\Am&"iq9B&&oþ[N8zxkaǞMȩĕ  Rv͜4NO2Vc3f0bՄyloPh VO o+>mc1/qprWwM<+Q.Ddc` xrΠ&  s )cN2f5D 3 a{oeK,gD%YRݾc].V* Ǔ4MՉfD]ZTbmHY2˩+$M]c|i}'NE!d mX-UI0"U H`5uonEk/P9ڼ7ͷ{,7qϏKDm3;Bf tZKP7b{ƨY(5KAi@tᝢNPfs:pfROCT6vҺ&N=8ߙ6KEy.l\ŋ(/}=yM:ð^[s;07垻J,A;dQ!RpO@O 1ϑEݫ_}ɓ1Rtj)ZKr`E%[X( )@h iE؜4/a㊺=%Zy*E(?);~}RGsnwR\; E, "[E+ReIV*i%i[' ➿~poɁ"MwC88h\"ezn YaС{n硯?ƻ~.#@DB"zbDъ"Z-\ro϶8n.&X b0.apHlp>Ggy7'G<1EP,p+0*p`n9m1?s 閈<5em;8ȑgxu81!DG">8Z'zG">8S@E),EpD'8~7Cnտu{-W/_8}|y V#xAG#gE;De=꜉'FG e)2zbpӊ2zFοp]_zNs)N<ʼnw냯ÒjڋvhCayC\&O|[q@Liݭz?BZ|ӟmZp} zE(STTfs; USsfu [-G;?s4%AN@"esL'sN9õwPՉhģ>z; #rjQ%lҀdLٌ3ٌ@Qt? 9,Ez>NKC,!)Qo3%DQUDZ>kٿ 8E,\ɓCQ%[)s~u]D*(>xT=j9rY]ػk/u]a8rsau@Pe-bB rSc@6rʀ3.j ݝv"b:.M<ߦp!"x9eyy^tBK$1EtPrɼϦgjDsk9u]SUU#sc/<*yk138p\7"rc2qΡPUe8qkO$&: nnl6c:SNSgLƈ(9' cﳹt:' Z{D@U>Or7%o{_PvAQUT a`&kn1-.`}c5" &Sw,h !wWW03De@\ڜ3WpΡ"*(8zdccٳ;{)5XuEY()'̌lҎ%nf99&"EDS\*"Bj "*9D.0v?Ēb z!&FFNLU՘ ++k_Ye8QS= 咢(PPpgΜj.u)K;D9SDS3se!;d8' %0:13,9ǧ4̫xLӢHӡ벴%+++x@'y:|̦3r6DA!j8UTQ 8daj YFM)B3@șy!!DNsB1y[̑&}_*O< \&8ܺoOq{ÑGi=5[x[o{|c~2pD@6{[ٵgG~1DqKٌO#|ay.z!</p`*`|ID~T5,,>~&*Dep4` tz#.NVġ4jIŴ2VW.p~E66irMJKDp4`9Wc.RpѨC=neY9*)²Ŝ)kΙ+0...3..2QޅZMմ6sRSŃnht}ԋfZXDΚ#uUlwQ We(N +PWJ53of ɒIb`ffTrFT́Nd漢 H@ENʹnj^mUUu!挈1 :X}3ey}}}1Μsgcvz`n\mw:B+ćwfg*Y$H"$3L l@k0rSͫjZWt:lN&͍͍|>[gkkk0of\iuE]˲]le`0(:njE)1.wwլ`fhrJ ͼթYU׳d:otccc^5|6'[[Fכh pHYs4: MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_F!IDATx֡JQߌ[4 (dg0Xf/h۠]EdE ,.Ü?߽n3l43Kpw>G >M)3oXNK$vRLp~y{EY\K=P( ׆T^fvz},v|BB19NS0+ډ, %@zhD|&nD8ۀN0%Xs)Ǫ!kw8Bca~DIENDB`yagf-0.9.2.1/src/images/document_save_as.png0000664000175000017500000000732012247205425021417 0ustar parallelsparallelsPNG  IHDR00W pHYs a aJ%tIME  &7'[umbKGD]IDATxZkTյΣ=33<`0APh-CEE+KG55Ws&qhDKDFR1!ϣ'?}ZZ{wWlm3M`Ukut, ]n۳u:~sPdDp|2>{m;/p=ò16ǻB TUf͚2o\d"8[ZQ {5p DhtDgExLOv~vlX\ŭ/{jeYh&BAnhhɲ4LO? #؆H\| \[?#`?hY%W4`0hcY-xsL&uZ%,2 tTD@#{l')^`wT 8LN4Ea]DXeI%qɒ*cw#jԦ0IϛR㯥D6Yߎ@0a/@#Ϩ .\ L Xk,O9K15m+}y`MӡiCD냸3:ȈGOx}xv#e>sDesgQ(y(`hIiP1a,G.ǒKUBAH~S#A2RAQ,WcdYy\]tLlh uJ'Z#i(@uEeKD^X2Jd N`͟b2գ-ʄuGPg D#zו9}[ Vu^-KDزJt+G@HDZo5鳠aZv{.t_Wmb @ȏ׏0C,!13SOb6|_߂ >6W67>ɳU)'+1E*Щލ򊕠$yjLD+ħn޾ܔ̗ƙs [NJ\ir2mSi6b[`:¡H^ȲpҜ3&X9'Kb^#׏xQt^!^y*k Bm7ZL#cHhx[̼+>DfsP< Ti2ar7L^A8ƶ;U% +ؐXnJ|l,*V!4$T5qO`p`Ets$|/+E$=sVU A:(Y])WJ2,@PNat?Eog(td".S `wK0]Ks@@ܭ}΄VNBl)ڷořu{qŅUZ\ -L}SJã߲av;PaL%۹P(ރ@ɶʍX8@8ن|n^O=έN  fv 5IZDD30I:" ̼k P_ڎSZ aQCi{?[%{5 ;۞f?RbRo^FR1!pc#9 ߜǜ#*FCge[Lˊ"q͏e4Ńh:R:>chhEڲkqy LqӍ̨yeg 8J({}gPk۹w>}GdqDP qpO9 \6 q>>c=kGgLEkmD{j&-bݺ/WX`ɗqA޷[],|ݟ3%dRT⺶H2**LTT1纻p;r~87Wxj5k_`s o}}"R경L9D4'ܪ-17|/I"2:u.&|m3O4`^45/0֍'YǰihG۝et qNL'ZԼI7ʊ ؎eJ4 [Ɖl[ZPzjȏWse|cޖř-lnkIBa<{&pvq8C}y%D>aHrO0 <^㾥8 Vǰ8'" )dNާ%0ұ4z}Wɦp<{7ăbH_.m4Š#)^.K, _g/{R)6; %}wqgcZf5WDuB^ŤzvQTUq>pD,Pz+&aQFxtӻ6m17bbX'DM&(^cGGGVb AN䵱{:tRk>|̇}g=Z'?GUe?&1AlHqdc[GtV<(qL?XzW(&5ѕfq^9,4I0 [BQ >v=p9gܥKH|6Dz(g.G%пB $,+?3ꖣ>W9-K77k/bk5wö&b#'|If X7/yèsn„R5ÿw? z iRש}\nD%EmcPKE&6g: "vbtxװ&%+Æk1y zoCj}f:zT $volmkͱ偹[uAngϯw3\~Sc{<`t/|#QРjh-K뉤BHƶ̟AEL΍ŹUTA\չrxO6~ziʡ&/N2JR!qBi;̈́Bm'62`YGRzŧСVήE% &]$ Qp1Pjټ 5Ri2c;8Dp4 B&FlՓXkI8yIDyl>=3 CR!Fj+F<Ϟ; =,t󮷟AOr=[vq |bG9Dfez4ڻyxDr,^<}r_| JH`WJMr[^EXoo\1eΗ?#GvV BC)V 5Rj>Q9XkGc\yJ$i{oB#clVcFˊ2|g tWw4 <'c>zn_ PaG>xMTB<uk?[SB+1~0 8z&t7kt r"ٰ6vm9fo r;_Fe+yIaa[sժUTy9}\i֝cZ<;1G@j }5H6~G f?MJ\Pst;~r<"Q> vH)v$In/xژg_V{sO?ȍ~:ʳ/% x}(Js믿>JB+3΂YxYŏ[n;,4ir兓B, GD*ّr{nRvc:1ErѪ9h3ma|6lzOꗾme_^?d|8o~yŻ_tSHwFnh$I'ZJKm{_uw:* Ω?_|u H#wT1.zj|S..?'.̨R>>5yhiWǥRV?ٲnȲ$IZlQYWlZRFYt`{JaOII\St_&T+MwhnXUj[3diF٤hl6I,:۠,#s$,+m<79;J_J$i}?dDeC wnYjʢEK!rLdY1vGpSjYᘆ\Ҳ0'c Z(VQTh43ty2NR?HZ%m"K&+s`z%Wݲ~ԤZ-k׮ecHӴvvj/p(:~mcVCٜIdWgs]`o,Mydk?E#׃֚(}枞ppNx1!Y+nD -Z(Rʂt=tރ⺯·qJcz_mOɾfqt 2Җ=y^31si,vw>&2qCV3aV)8fͣnù~v]u{W,;֫RhfY!5cjG$p9 ؘlF05=mf}w|+-,,#cj*Yfs,4S4_^B`\ZǮZ3'j^[VׄRPKo k)AI)Z ,N>ͻ":gfdΝccnG@Hb4˳{Eka X4JO>9Z|yZ0 U2J)!BVJ)yNa!"B,Zg[n޲eKOJ 6A~KPm[#WT\RqA B8! )R:RZkOZ;c},Fٳرcsн5FNIENDB`yagf-0.9.2.1/src/images/select.png0000775000175000017500000000501112247205425017355 0ustar parallelsparallelsPNG  IHDR@c+QFsBIT|d pHYs[[tEXtSoftwarewww.inkscape.org< IDATxl_+Mi+ ZX"8(aK„6$tq5@(H* 0ťVfeEZhm1&#HSz;mw;y^'w< r΅I@!ܓιk W"'1'$e'6%e9pY3 _2K,Y]~ܹs9uىJ/ˎ?>hiD$q8s}衇%K? //V3|IzǼ|M 6~[K$Oj{gxZ[2⟚?-^|Ev oI9K?1+WoZSx%'N`08Z-x$ `Μ9ttt{'Z{Zүc_`ʔ)tuu cqIL/y0vXN>mgΜi%5JZҠbq >-4h455 `oݻwqF咎H *~3Qmڴݻw#Z*)/TTUUԤ@ 0=2\X(.-ZDKK̼/3gQFXkOI*Oww;/9~I$o&ب+V_R9P0ưk.jkkq-3w( 6g$D!F%"JIIW(;X`&++ 2f̜9N;f̘lcLRI&e%T0zhͣ>j}sHʢYK,Ux0 98pjjI! @۷og֭1IʊϐڵkٷoƘ9vIcѣJKK+0MUPZZJ[[az$q3{' 3eM*鰤? &^9r$'O4%%%kɱcǴl2ZI$ Yf I%$FR:m@TWk"Kwr]`ҥ&==}rd}wMNNNt߹VϿƍ cޗfϽ+?N;}􀤦;ߵ}қ; Gˡow=w޻w/ׯC}lŽ;~yqI&_Mqq1_|E/@ `oܸ񈤎,^ 6?~y;~nܸB|zzz\^^^s?[ZOA{9=Aw@MM\0 }b\~燌1ݱwz ֯_K/pի&xJMMe6?|[xsDb֞/** zk+WÇ$5I544xs 63V^1|4a„P(憌1-K \}}'9+D`a9[PP~'׮]5!۹s'9W__킅IuAȑ#CW^  AP:Os7ވvI9Fꫯ<nԩj n͞8;킪Vfffʕ+!̚5u(xxyp }g=XZ{P^|$I՞| /K.yPVV欵&~mUUgΝP@@ >gO=3\$#Ƙk\pW@˒Ν aʕdk)//aJE7;$ kג>}sk2\ #bsn?LLq)IENDB`yagf-0.9.2.1/src/images/check_spelling.png0000664000175000017500000000720512247205425021054 0ustar parallelsparallelsPNG  IHDR00WsRGBbKGD pHYs  tIME2KDIDATh՚yp]}?{{Z*/d#` 6lK.mixZ&iLIf2鴝N4a&ЦJ@la#c`Yk}[9= 5 4Ùs޽w~g|>z{{9}o\h Va"2X,.ڰaCo3kEdW\}""&N(#e'"A*q܌y]S,6m{^zC/bѺ:.]ʎ;ijjb477GommեKrvyq0W}ucď0< v]vyyӹF+#+#:-yW>6*-ȹ x@Ӂ /O^^{_w-G`]|#U}ٗzF{W+sT`C5\O:}@ {w>lw@%.gw)~X?5| ;otFI4HjYog89Î&#y^B(^'O:]u6 SdEzҔ%&!=m9YD<~`݁7{6໮'])9/n9w|N0LEUv$aܝ*,$#beQ3|{w!prz&@Q T`]VKޖGrPBi᧪L`h5aIMggTrgOqt'{D~8rif!I:s3j^-U:}s=zgb<{ϴ*F&._ ZJ0ÃT̾T1);{4#\8b_LѹMs=UdvK؎yxrFR{+*g~;TVšZsARsTW3}O_jz>2E-ّiXUMu_z{`egx}V@voESUKE3z٧$IФ`zEQ塃~+-xe S62Sn-^M=G'2m9o®YQ9oFxdf\;EJEL/ P,_RJ,H<.ծd.hWLݞq%Z[$uI!r/Uܶ5+ry';+}0||^5Trv[*ZZ1IZܶe㏞]>o;IS4au\P3Z&3YcGH7nR[v߽:h>'~ C Tį'b47kQU0O|5F/H7'Wکq76$%LWE1bOxq5a߼bG۠@LoE憏+k@P k/ =u $S: $RyZ>{8Ry\zb`#leT\qbPB a >*:jGn^`@0 /^S3R? O$lathlb)-/B^ɦo|{^ssBp>A8zlE!"~j րI0vNm$FI>~V )miwsT" tu@!YZ<|Xj-敍RkO)}ϔ{okݲۢ1s< Sx~#&ٽ{-u ֪(I$]`PP{uW-Z/_M/?巆*o; mpxUꅡA@$`$,7I0*lH(wE<@Xkyux\s޻Od =Mʪ=EEKw jHƟ6= 'R#ƀ) MCB^u"v5ww0ew^٠v KLmABD}5ES1ȩ` ^t0x"Ivl^+~>{wսks ï kWxfӳ(I("YGZD xn;}NvC>$)!lF؆b߮D}D;b!+?4gT2,I*BR1ň a!t6Qȣ9th "x".Y3FJBbHe 4UPU=oiR.{r̚(6]L)PSJ:+eea(!t+ݮƑX?$,Γv,D!L!a(!mݻrWt.{Fଜɮf5, PHIEHfծ7W/#ec.4Z&5n L(a$D^۳GdټoΐZw LǒW*4k[џ'y_ S :x׏?']^a9ng:X<}-yyvIENDB`yagf-0.9.2.1/src/images/save_all.png0000664000175000017500000000500112247205425017660 0ustar parallelsparallelsPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< ~IDAThZKG{fzfM|mc;G$L7@DbCVRXbD,YŠ   #,;{3w^]uaQ]Տ_ %Q5]w_k%"վڋ#Է#Ԅ) &p8=9y^DZ!so~ , Mvvʇ JT21Vakxp _{%\y3F,G1qU@q'1j`Lb}iY3z'ź@>޲(λOx,HHV+WklW\D+$na[+4`oY*׺[jILӐ,V.QVbQхB$ٝER b V *Sa[(M*c,>fiO,EHB|@=ǹ}D}?# vWSwr|$O BY{%+|7q3cE9"ܾ}8BY-1E) ŃfŢ5IlՖa`&xbHeLLY5"{{Yk ,kpp*QRAbq = mEܟRWk>L%2xns_{?<__((Xi6" c` 9ֺeu̡YIqDUYŒ!|~ց$ Ly8=;s1IkLvϾ^q0(dׇ JJ#(˲ӵ29zݲajan1b"%3E${Ͽxg/OUwSXkg~z'I8T"{$%QfyaUMlEGBHo=zS&eG}?6N8?Aւm6,#]MbCQ_z^7ߜyTM@M(ATxiE ӝ+t+K+Z,ONO?c^3|lnݺu^A>YM4MGY$%I2Z 031sIDTƘb\n޽;w[Vs ǚo IENDB`yagf-0.9.2.1/src/images/trashcan1s.png0000664000175000017500000000433112247205425020146 0ustar parallelsparallelsPNG  IHDR00` sRGBPLTEk(b 24a ;s:>DG G#Gp+GjN QQTW=PeZ:QpW3U2T;T [$Z>YmbNY\c#a2_;[2^XYafP[sJ[3d+jLb4gZciaaj\bpoEfnrGg0m.p[jdbjqx1-m?}^x-y9b50%۷[W`lyB.ȗ@kY[{r k{S^x1 b =#ccKptj=}ǡΪQ-+'ol2FﰴDg{ ޟ{\ACSUaQM[m74g$9޼ONbP"  ܾൻ}v=(Q qXwCVjV0m jŻӓݾ}竴ר+a?<!eKDmUHtucccmN.ĉp?_8l7.l6()lDDO(__H*:Vw"F HGGG'''_>l ˍ#6f`0[['zW[Mm.#'C++FUӿyB,W끢J=!UſD"2 qQXfAAk}JKPRch+u7^&;3&5޳#E D4\Dz]mjv%? 0aRH"3ݔ72IObAY0j%4K}}tJC)555s`6bdnrh/RI`,fc:+ ګ$^un$1-TޘRd;4xH*( ޿kw Xi̴P ϻ_eB4=Kk4e^x>!!89d.5}gWDH={6fߖwt:~Tzm3m}bdfwgŧe!SR^|%S\_ H&]!qX8 fhh~dbb ^ d´H??(48@BكVm>Se:^K ^Ko000SvO155ťUeş C!njŞ=Z Nü;wgؙCݨ@/K s"##17M֙۹:k,olv2,=騫2u0"B! W7`M2Q>8[X@vvvI, wWS[ʔnP(tjSXu[,8QA>x.E2 i} PyIENDB`yagf-0.9.2.1/src/images/larger.png0000775000175000017500000000611712247205425017362 0ustar parallelsparallelsPNG  IHDR "> MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3bKGD pHYs4:tIME / HIDATXWNA9Ĩ@ I@ʋ4VTVeSU|ﻙLsT% H,G( $#I!,N `$$o,S6K↬oit2!袰 4im{\+nx}O$|JcA 2 `^c#(;hvjf߂M 'WSf\ &5 n=eeXNkQˆVb y#}`m$2;Kx@Ʊ):],Qm81^ߗvŶd!TC37Mk{ܹ) ;CSI;_ ,iK_yoIENDB`yagf-0.9.2.1/src/images/fileopen.png0000664000175000017500000000362112247205425017701 0ustar parallelsparallelsPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<IDATh՚ϫdG?T7! J`fEtnEN2HFpDp 2BDtV2+31/3o|?׽UŽ}w{:)hnߺu>0(9)YZ(.ׯ? (-H"ݸqmo@eu'_|0iV|}N5fUz)%)-o^Ͱeߗ7Km2ED^ŰӶfe2sߛVN s t On_{w)g7u@~cB_> rA`x lX#Qz?hx`AYD6:4j!̌"٠!"BBGo m _|>sK}wrK ~Ʒ>~ `5Cj|Zi@4#%u1d~'3Ξ}/޽ث7[⁙bl)tY?'OxҒEâ6P𛀷1(IK,Xb5 `?`Ut [)b- (J|Y`FQؔ'~Z$xn|67KAsm`0<̦u0Dxƅ[0@ d=b {|3@Jjs ӭQ?C%W^c:i1y| &P~Dܩ,?MQT%rƛ;woM`F9g#nⳆLG sZ!:S{{֭Ҩd\X"o& *PawyLGLw;482!Y`YB%ߌy~of!xLNHDܡBŬf(0Bl6 mgs63nQ8|:?/!UED4~g1jS6Qj. ݬNl [cZeL)M S) hܞfnw0DY(/ffB^U_s,S˽}H)Rp^A]w_#8S4@! t^J}61\cyQ-1Aw9]T# fԎ"INx93+IYu,sX2@z!,i*wJ']N^&I[!,::Ł< 28_A0Frם wn,wQN&/'!2-b15r]A?GtCfMPAFyi@t߻2-u3!՗EBn$ xS1`f8', 2 ;w]dAD[hjV\kx(( 9|W]Н>P%p4^?:bcfF$URD4x _K" GmV9DqޥڠSHh'^̍SBLK*D}L1z3$%1T[-7N̚%Z?U;ʀg.܍G\~2(0ʀK;3"|  ];7_{᫯GsIYD󃛿}g/O<*. O  _!c3ja([9-+IENDB`yagf-0.9.2.1/src/images/revert.png0000775000175000017500000000637112247205425017417 0ustar parallelsparallelsPNG  IHDR "> pHYs4: MiCCPPhotoshop ICC profilexڝSwX>eVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_FIDATxϫLar'! J Xa#eH66Rba#%UHFVBJ)Kdž{3;Lg̼sΙ=>{ށ&*Sha~[s /,dY[YOqzep?$X nֈ<^P ġ"U+ |LZvcǨު'LUiha0z` E2*PCc I@a.[1A GؘkӍ+"=lSOD)%0j-gX3W1a ,B -bعۏ3]X /p!B@lŷϲ|fs+'}c~I4ae>W_0;n.W iҨ>;yeU6)15X>P*o׻3IENDB`yagf-0.9.2.1/src/images/clearblocks.png0000664000175000017500000000637612247205425020376 0ustar parallelsparallelsPNG  IHDR00WsRGBbKGD pHYs  tIME +& ~IDAThZ{p\Wy}{JJÒ-Ƕ$$nIu24LӤ0qBhB8BIad:Ӗ!C# CccK⇞lٲݻq+b;^63ovv3Oy /zajt卍BҖݶ`jh(uW:t?9ޏ FH6 ( AHfq) ZkYde(x!S-=fӲnZpyy١⺭w]8IyO.y-. lh];tuO_z}kbk+ pDF_ ڭDЎ }y!06ŀdl'A$H{б(vgD(y5@Tx-״KW,v/woS~8w: zǢuŋ'O4p qp<$@>Wߘ|ȿWCGpm+v/VpQݻWEM@(8s籯o"qabei()Hـm$@* NLbYQWPwXïUϤ9![^SSiyK(zpcܳ'z/}n(ܳKk篹 ) Ivlţ@䍔l@d7ͯFc8o޿sY hw_pߎPmxd֦UcF͉30u,)OCh8NlK\blkSٜ36]wuZoV:i`5Ռ*z⋙FBfr0LjrD_'o>"(V)XO3* V wVLҿ8ݨ# ׶ssG~;'WC θib`e@3CiFL3}ޕYI&y飼iN[cfDx#O6tD@tD(c Ĥ;Wbhf0[HGHmÚ4>4]XYD H1 sY֬ue13%$đ{Z=Vߑ;S pLNNE$Hɶh]A`x ^`AP AJ%!G ,XeJ :m :NZ]Y\wj{ߺeMs5Yge b/A)SfH@Eh1qNisc@$@Yw迥yֆ _^န/>% @)Kkr2Y dA\,x`J:eWJib+5:~cZH) BX[ #w/BNς5i-RH"]$N=SνVWII`E(ϕXQNUe/ 8 o/L\A!{Nd{^ 'Z1=@( J`eAz`] KV6j kHA X#$>>̋}Wo2G"XAI f_*1FJ x-q"t.YexKG~1%gXk_E (}o]c oueJ-INCe* ]Î+p4cI=s"NfOE_qJ$) $,EaxOԼ|zcQ~{=,Ih-VM߽w!>O~Y6" @g2 !@۶*W8F}h T{\z\GȌ0,%ӚW훆'yx ÿ[yy鈥4@K.\HԳp>FH@J)$ 1j^ǫFu5ًu*\034x9!Xy9  ȠaGښ ś\B%xkUͷƦ?YT[; Ki Ag0;1lCfGH )ؑ>*%3́uDtcSAXP418Ǚk:柈7Qۇ /vލF HtҎ͍׮6T o,u\qc%+ǀYw%NO"%nX 0Þ_aw420Z3YZ!v[ l]rVt@{tbjKNĹ˵%ߛrAǟ \:/IENDB`yagf-0.9.2.1/src/images/saveblock.png0000664000175000017500000000272312247205425020053 0ustar parallelsparallelsPNG  IHDR szz pHYs  IDATXOƿWU]=6^IcrABB)|!E#E$Q ;ho\$B{uٙzqAfo)i4~ݿUWf\}}'%ə^-DNFyy 2O ,zwPhY[z//nll0|ٗ`"+G,?X'3aprWw+8o[Y"[WO".? ZkpWؼ c W"y3S,W]988<}Nw|zQts+E`l$YZF2(5Ƃxj0 rA^):S@P޽H#uKMsdy {x<$G "Z\$I= $˯D *AU,@Uo"Xk"C*vQU(U[ X!"Pp0OUH9BP#9BY1(HdD)6T0M藷*=YȀТ4,ⷯ+^\ﻡ64U +t38ƦFW d&&4XJ0F 12$] @pk8z*CSHAny?kP̈́T ,)G(pGt ~1;!ӫH^~){,N5LeF\Wc/U$@I ,)|'.R)0EV ,?1&*Ps7z?ydɜ&Oq /40EYCdT`U$]E[2.MFbX8ׂE< S 6qJP"MwH|HRhi> #-C CHf^xTֿRLk wʢPB@u큒(3dY7g`s{!uiB{6ƭ[|xa~`?\'`;DX!wxaCdU7vȠ&5B`ږm{kSk mZ~k[[W_NiniUSŞxÞbfE!XKCƐ5ge50Za9Eč Y_dq b/CWqզ <~߹|o-ĥ߱qIaD^⤗(jǻ >L^&Uvo:7~+z۶kT}r5yRP]/ ]ѽPĂ-&12GrBp2Qfb!\m4<7~iV/ `[fi_擽QB{&BZ5=#`(<^+xWttx)FntOwl۲X2[ڋw(v}2fd#~@ubޛ{G [W0ydOek;۲[2{:P% ~u^==o;sGW/cSGS"-^w;k钋Q/\?)W9W_vz{> mZ/-#QP~eV\fnmz㢫N/}͢_AtAL+yA9tILB}zٻZ(Os z* **BOӘ694&W+h=#xĥKx3;^@yedhw^81xA!REU}܍ՁԇFkS<_8N( 0}Jat_k31BR(GwѝwSE*!h} )N_ACpR/i.K[?8aoҜaT?"e!(3hp+ XE&sˑJtLCwIlȓ~:6]IfbvJ]{h;WV獁gȜS H.{-?cz@$g2:΂Z=ZjɱEq;%i_ZՓ x6O߾#["hQ< m 4S׎P݁FGc%s[oGa޳RsWg7 nʹp^މD m+6>;!²66=}4V.x(.)Hmf3ѸW͘؆0“m\uMGNgk6lsHHKHzݝOp`jGp V!xBpk5__Ē8a`x6<;M廬w]ݦYNVn4g;w i7,槄*#΋G<"Id:k$c)Ģ ‘u#g̅!4!lb\e9{y2uA*4"NZc3B5sU?;5 P?`>怈?9fOٝhB[Dp|:/GC ЈLKpx^׽OJ6>QkT>~qYͫm a5)j^g(!"=5_2)RN *ݭAZݭ2YmZ1Yc4O$O V}-9ID5&z[y䰏na#ϼ(6kBIT$6$y>'M}U#hF+NADe  ZSŚ*"5` U2뻆J7e `ZƴtO|ۯӈD^u$)B-:֤15oBTzR lU7XQk ESsѩO|o^u+v|7v֩OSo cMԱք3Y Yóo5:.(Fct)`^ {זޗG)F!1IQiwŌH5"x/PEZF4~8C_Glj7cTQqiviJRؤ`7/BH'(\m$GB*(m)X&F!=(:08[;96\XƫԴHkE:[0dC}j !%Acm\H/|uגxth0mW|CEiD1|+]Z)X+8 V1\#UE(Ţ/Fڽ3vxhحX O>_i3NQiB;mZAcE@U#A,Ac !!->}# G]wʙkY%t.C`-XfAQ6`WkƤX՘cr5cLF2iTJw +}n;mw-s;{칤z3l#!-!^p{ =~iCv#ߩ,! M9P B N~6~1iu3W:o^$`l\bt87NtR!6K32S,tBoܘv@{ ĊBIl,ԇ@-? {fm%n%8$mIˇE]A}X zf^,ZA[yQB^.~/hqIENDB`yagf-0.9.2.1/src/images/scanner.png0000664000175000017500000001251512247205425017533 0ustar parallelsparallelsPNG  IHDR00WIDATigyuElI06X6NfiYI&30-mL62]!M;ͤ)6mbƒm, -H9:ۻ=sW%$aH'fdacs?}x(Y5Е&LH߰sҵLʀ% 1X2lM :U/s 2Q-j}8>fft:^3 ޽offscv˷[-DALȒI!d00 #$f@30LdDQ~(=ަ,/E}WRn eĹ_{gpȞ]p\%Hю$MNɘ3*fbR9%f afMEʙhl:O={w,/U_Bv$'xkkvH$#Y24 $ɨ`,fཐPh/ 3^2Y]]eyiG-|?޻ ^yv.-jsTjrFp{%  >F,B <`4 DMA uepYtj» 4\6A3/j0޺&3SmH` i\.N+L3dEP$@2pHVrZi#̰4G$#ٓ1, Mc4"eLU<DiM" ڔ7uG&=~Y]Y|c1׌s̜KJJ>2`Mv\s=ނ .%.=_(#Ə\6m|Uf)?{fU` Ni='e_+ /aÙ?O%Z%PWZtbiB\*t v +3x00@Db}w_;_, d#|D]L1q>*b@dr`hjG,5ЌQsqz?Q ~6,q'CMŅك7gTˉG?Ǿ">$12QVڌ=UmrUL H4zFJαf,\g\Am&"iq9B&&oþ[N8zxkaǞMȩĕ  Rv͜4NO2Vc3f0bՄyloPh VO o+>mc1/qprWwM<+Q.Ddc` xrΠ&  s )cN2f5D 3 a{oeK,gD%YRݾc].V* Ǔ4MՉfD]ZTbmHY2˩+$M]c|i}'NE!d mX-UI0"U H`5uonEk/P9ڼ7ͷ{,7qϏKDm3;Bf tZKP7b{ƨY(5KAi@tᝢNPfs:pfROCT6vҺ&N=8ߙ6KEy.l\ŋ(/}=yM:ð^[s;07垻J,A;dQ!RpO@O 1ϑEݫ_}ɓ1Rtj)ZKr`E%[X( )@h iE؜4/a㊺=%Zy*E(?);~}RGsnwR\; E, "[E+ReIV*i%i[' ➿~poɁ"MwC88h\"ezn YaС{n硯?ƻ~.#@DB"zbDъ"Z-\ro϶8n.&X b0.apHlp>Ggy7'G<1EP,p+0*p`n9m1?s 閈<5em;8ȑgxu81!DG">8Z'zG">8S@E),EpD'8~7Cnտu{-W/_8}|y V#xAG#gE;De=꜉'FG e)2zbpӊ2zFοp]_zNs)N<ʼnw냯ÒjڋvhCayC\&O|[q@Liݭz?BZ|ӟmZp} zE(STTfs; USsfu [-G;?s4%AN@"esL'sN9õwPՉhģ>z; #rjQ%lҀdLٌ3ٌ@Qt? 9,Ez>NKC,!)Qo3%DQUDZ>kٿ 8E,\ɓCQ%[)s~u]D*(>xT=j9rY]ػk/u]a8rsau@Pe-bB rSc@6rʀ3.j ݝv"b:.M<ߦp!"x9eyy^tBK$1EtPrɼϦgjDsk9u]SUU#sc/<*yk138p\7"rc2qΡPUe8qkO$&: nnl6c:SNSgLƈ(9' cﳹt:' Z{D@U>Or7%o{_PvAQUT a`&kn1-.`}c5" &Sw,h !wWW03De@\ڜ3WpΡ"*(8zdccٳ;{)5XuEY()'̌lҎ%nf99&"EDS\*"Bj "*9D.0v?Ēb z!&FFNLU՘ ++k_Ye8QS= 咢(PPpgΜj.u)K;D9SDS3se!;d8' %0:13,9ǧ4̫xLӢHӡ벴%+++x@'y:|̦3r6DA!j8UTQ 8daj YFM)B3@șy!!DNsB1y[̑&}_*O< \&8ܺoOq{ÑGi=5[x[o{|c~2pD@6{[ٵgG~1DqKٌO#|ay.z!</p`*`|ID~T5,,>~&*Dep4` tz#.NVġ4jIŴ2VW.p~E66irMJKDp4`9Wc.RpѨC=neY9*)²Ŝ)kΙ+0...3..2QޅZMմ6sRSŃnht}ԋfZXDΚ#uUlwQ We(N +PWJ53of ɒIb`ffTrFT́Nd漢 H@ENʹnj^mUUu!挈1 :X}3ey}}}1Μsgcvz`n\mw:B+ćwfg*Y$H"$3L l@k0rSͫjZWt:lN&͍͍|>[gkkk0of\iuE]˲]le`0(:njE)1.wwլ`fhrJ ͼթYU׳d:otccc^5|6'[[FכheVBl"#Ya@Ņ VHUĂ H(gAZU\8ܧ}zy&j9R<:OHɽH gyx~t?op.$P&W " R.TSd ly|B" I>ةآ(G$@`UR,@".Y2GvX@`B, 8C L0ҿ_pH˕͗K3w!lBa)f "#HL 8?flŢko">!N_puk[Vh]3 Z zy8@P< %b0>3o~@zq@qanvRB1n#Dž)4\,XP"MyRD!ɕ2 w ONl~Xv@~- g42y@+͗\LD*A aD@ $<B AT:18 \p` Aa!:b""aH4 Q"rBj]H#-r9\@ 2G1Qu@Ơst4]k=Kut}c1fa\E`X&cX5V5cX7va$^lGXLXC%#W 1'"O%zxb:XF&!!%^'_H$ɒN !%2I IkHH-S>iL&m O:ňL $RJ5e?2BQͩ:ZImvP/S4u%͛Cˤ-Кigih/t ݃EЗkw Hb(k{/LӗT02goUX**|:V~TUsU?y TU^V}FUP թU6RwRPQ__c FHTc!2eXBrV,kMb[Lvv/{LSCsfffqƱ9ٜJ! {--?-jf~7zھbrup@,:m:u 6Qu>cy Gm7046l18c̐ckihhI'&g5x>fob4ekVyVV׬I\,mWlPW :˶vm))Sn1 9a%m;t;|rtuvlp4éĩWggs5KvSmnz˕ҵܭm=}M.]=AXq㝧/^v^Y^O&0m[{`:>=e>>z"=#~~~;yN`k5/ >B Yroc3g,Z0&L~oL̶Gli})*2.QStqt,֬Yg񏩌;jrvgjlRlc웸xEt$ =sl3Ttcܢ˞w|/%ҟ3gAMA|Q cHRMz%u0`:o_FIDATx;hSaGOҔPEV"E[ p,E N./A :(*((7Eqȵyw5 ͑^/P:3vs\JЗ@ˮ4^tq jѩdtu 0qeTH`R ^z)!B PЇB } Iae[v{苀žsٲK9AW$pU#޺7@).{6[q@^nn[d;VZ>*{Y=⍭.zGaޚ_T] R"}jG ^V(zg@Nf;d3 T~FJ'-i1>5Q/xwWwhQxxxkGxGk5] ^hkkGk5]k3]k3Q?};O'{U_:AE`84;>v~6Oc>􉳹tE~kUe / *w11$>׀~ X!dܘ9ǣ4=CZ#)NIENDB`yagf-0.9.2.1/src/images/critical.png0000664000175000017500000000565512247205425017703 0ustar parallelsparallelsPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< *IDATh՚klUU{{$-0t24NLPQDa"0@ | ИIa),Bg?9pdg9kkg_a\bWBq 7x@UhW\!`0 Jn >K8.c/}b,F@>ކ& Jtvvjoo?vy/"!D)0OߔR(Zc{!LL&q}lll)1buΜ9M̲rc l)e8X@h__H&9D"A*Yx;---љ'0zUVVV~#IX\ÇT*S[[rGG;Ƙs,~0 y5Zq]7uݰ?j@|ŮJ)N!y0:ި[w"z{W!^ %v&B*%Z)Tj dPJJK5כk"`Nf\8sm0J1v֬Ր86 ytn΀#Mvܮ]h#OAnEgzzIl݊f<GEIIΝ6?LM&Gy @9x&NADs嫕+Q,ϝj53gDC|߾ۋ6 rM(!P ~}˖f)YB0s3uyw7sb6D,v)hBN~GAkGHj*X2hίVAǶl֭a".u/Aӗ I ̦ VrJX_۴ps\Wqh4"( X #ū/w]C7rt˖K"r-pn9(Vo6 VDvodvf cr/˖1hJnoY-X#K{^>u*٬l6|c’%92ld.۷C-#LQ qrva\8nx=gzIݑE(]֨tN㔔&Y1 Hիj͚$j̡zl[Tr\1 [pq߱Yb$R*~ (/_{׭ ‚ᗇ(si][# (t\q]⥥c=3fjvFD8|a4~ATB0vBRYuP4Unt*M+fofDWJZLhQxk۸`,ʅd6KyCK$\(DYo|ioitiN^uPRe2N‰ŸLٳsض[%]xܱti#stÆlBORS)[wC)ř;99_d&)Bvhd k9n]gل,hK"6`@Q߷ox< G#Yk#9xp 3#KT'LGMl̘0/'sЇ֋W1; >.RS.-d\ggd2 ߟͻjP7L| \ץT&Jη$z\j,f'/ߖ/YcA~̃1Fvgȑ:t('"UϟOSO:r/([z.9x0$,%%b[[Q%< 8g-={,]]]T~\߯y>PlHqw`=:ظ#JTTT0bĈANW.k.TqD]RWGGǧ/~ǒ7n@Nf!_pR|ǬZAPnEn[5B7} ~trAa7?qpD}OUGuf3T,[sͯqPnn> *ҟ.iX k"ՍN޾G@VQb*w4MZ^]IENDB`yagf-0.9.2.1/src/images/tools_wizard.png0000664000175000017500000000715012247205425020621 0ustar parallelsparallelsPNG  IHDR00WsBIT|dIDAThYTW~ #e UD@D`E, UWMP,`b1bb)4ĸb( APP"efqW5݈=e߻w crk׮ Rz700xEq<{rIwI.99]U']?R Zrۇ> ###§~+QȥgS^h8YIoVmSS鴫E?,=Z[3E__ߑ, OS`$N~2O:t^'\H+\F+F+trnm#uWʌI(;HMQ(݆uPUU桢">p[u777pvvn {нdT:Ich9U|=:GZ/Nq)y dGD] _a/@ASZfc-y%g̙jǏpU3 ɛ :ebTdnnV(//iii˞x/J!K;G__IS.}E&=?.zP*2m P/""HDx<K]eرJ>yySǑ.$+51}4oѣ߿p]vI(oC"Lb4DǢ^vj2QݚM͇n?Џ{>S>ZK񒻭0%%E srrZ ƍt޽.M/i%De2m~?Rn%nmYAj 99qdmqF *BH$^p***$ȑ#4>KH'ft}nogB>"F-ʤ4ȵT%{"_z!^[_YYGǜ;K'NAAWW qqqH&*?I݅m}|"$gbsfWk t ٲ GT)xL#j]J ?j-#X}ƁZ&4[ N-Tr yuO)ھ7`#ׯ_wݱcGД)SX'[nh_̅Bm4Ȅq>{Ϩ]e("uń6_ G֑gu𔙪v)=kEii=3RuWR }%^+aDMco?y$ USNuL"u5SBAGGgo9^)QNbr" 6'IrRQ]c%; %@onLS=;wlW8iKFKYfyz߿Օ?{l~XX3FlRn"3Q?L^v!!!lL JmHp_b͵4 )wW""rp^S~ʖbB>oU8@P)bC0]0>l͊Ĉ 6𭭭?022RMID .RC0,%4@>̌ vœ$FJS/~-/:CiœoW꯼@ U~u@wwD-7o&hL80l۫3.8`ܹs⽵J\np,WhG?Vخt;nuq>^i7ӖsT_(M9Ui/4)8Ϩ3aL͝A"+j<%%%^HH!XYY񃃃]-MVlt֌q"-Kd+Z+Xi⎝&~7w/QULR( gP<2͐>Mō\m3Bj7Z.jѴն6O ˎ2Dp{H- a.ݘlA^(.QsӚz S%w<.`е:w[C' Jе:vSÏ'uUM) w;:,N`޼yh"@O))X⬯!u} [OhM͝\'?^NAc7 -W84QF+S,xxxH&6K%M)tcˬb٘秏Y 뀇ET(wI=>>:x{%:}e[,xYz`CL  [<=2?GOHCBi03tuu@ pfLl \"Ð6  P _jfRc \9DTUUzYM@3Fʘp+qݡZn ;oZFE5!҉mͻ7-ld-׸~(Yaq^a,,1ƞ Mv03Y bnlp#C`l$uD:-C ,`e4 /3U+?F`{@u!$jJmGEh667ڐ>>hgKUTTdQX*gh& 0T'1.O7K3Z Fl ͆"k*3ViV%W` D3R?<+^%XE8;Ϛ5k^xxohѸIENDB`yagf-0.9.2.1/src/images/tools_wizard_small.png0000664000175000017500000000137312247205425022012 0ustar parallelsparallelsPNG  IHDRasBIT|dIDAT8_HSqonrsϜsJ:4,LPWBPaHc!! =(U6f3WuSۼ;%Qt8|`lC& ^3ghBji.IIIqz'1-sks zznƳ{[Nz/.A-e/s]!Y(Iz1focxt9j:}W9棲qVK/h5J<e}]`S1ݵ'xjff&|Fε*L_ _l5@Ҏ>өSPZi!T'# z Kb%S(G3#C$7\>\.J%&ܻ/>A폅󻀩a}U 颳U82 +YN!?UFV<ӛAU^x8Bq܅  cY֨m<ϗQBdÉNPAmMR(ZF~FbV *2`p6$IrG"oK 2 Hf! z f(ð)eg|C^W,Zvb]kVXd~{IENDB`yagf-0.9.2.1/src/images/recblocks.png0000664000175000017500000000266212247205425020053 0ustar parallelsparallelsPNG  IHDR*ԠsRGB pHYs  tIME /BgiTXtCommentCreated with GIMPd.eIDATHmKl\988SۃIEU!)YQJ)e RXfS)^h,Ґ.BD\SZc{I3qؾ{9,N2"|ҧ{wJ x}.C6> 䁷9+$ow)N(RБJp?gfvrt`|k][HobvJyJߒlke^'u- T*3BGɌ`d(CiED ces%7;K~~GOb` q(>ADn4^O5pG|9P? ,J ZX%5Mvx P) 83=#bUTXI@BkAcG Wtw?39&tBDPcn[Mwwbq`g]Vٴ1u ?5ІuCG-L6/y\""L]bCTҧŧ%kRK-5Z啀XvmM57π$;R)t$=WkGh֍hXnH,-БJl+`_OO/R-Zkiכ5RH} 2==prd8KyVF#DAt=_+6'(32p`擶r3Jxj{:.\՝ghkmap0[M&ؕIT1?(7"(7Ngl/?$СCdd+d+mC)0NI_۠ݒ\~S3fbvrquJ kb<}{+/%^x9>&:yɧO=T* ZvXk  VWWH&oyk?rSgzAw_zCRTp}fu1DQ$QEѰ1ZdMaa+ιRz> ;vlgvw^RTrMcjQZFa(rabq AsD"Zk^y%v|~{9>di}})>dP9Zki*U5`% ƘF48I),..x?QVy"2闥KIENDB`yagf-0.9.2.1/src/images/resize.png0000664000175000017500000000130712247205425017400 0ustar parallelsparallelsPNG  IHDRngAMA abKGD̿ pHYsaa0UtIME#2HIDAT(ύ_HSq޻߽sM6D҇0ODEYAFXRY+!H`cCe L%SktWszIiy9p>{8[*^oq^ ]ޞaЖkO)L&ϯvxEzq [ Θ!Ɩd4>_n1;>YM`^f! 3M-W<0sПt5/Ho'3cq4aac8*gaLHIMѥ֫1JEKDXGbua "9qkr %ɐ[Cbnݠ*2U.1T9ַ+'4+oIAi ADwt::D]:&Jh?ەvI6h 9¢|m֓qGIyH-?\OeyXRNlκ.gF;iSGzjY,KuEimP>3;3%/+=Je|sƽ:\Zp(v "p-J*>{9'":0TIENDB`yagf-0.9.2.1/src/images/warning.png0000664000175000017500000000526512247205425017553 0ustar parallelsparallelsPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org< 2IDAThZ[lΙbM8e.:Fun$ƐD!OQE`P7+C>!E*(XIJD m$!AXrVP0 `^_a;sٹ>ewצQGuz97ݨe`,B<ZA0`1ZEжq+#<nii +Wb7?~˟SVa؊ @ǣsss 4e2N1hMXWGEQȲfffX<g,q6112 E1}<+m] ?t/9y1j>4v͛aV>]!*zՂ R BSf' xf=b.IRX@!pH&j߷oN뭺JQj";U[[$*J_2`rdv9~BfcRpާ`PU<Y!@evy@i@klo`HU՜/lL0 {@)kqvee%Lb*~KQa X ߿px}02.iYza~A@ ܿ3¥PM`-]׮]U(ju~ Ԑ}q0jEˑJƚT(FB~SSSu }\hiK_9dYF(j,Ub((ojjry_3)22ş>7tG `tkAQԙˑL&KRa)3::H$ 7Y,r6d|sEqFk? y~%*,Evԩ{^.0̋VHTf>̹O Iit LM~4(zv.M$ïOc.@ 򢏪( i_2!Q {oާ4Msa\{ ;.e!2dYeIMcP b'zw*EpD"9w\g4|#swӡ 7M| -= ]A܆,y\Jkh`'CBQB<] lӭ===O*7 aSL.OC\Cwō7'bi0]t54X}}}Q ɤgpp0{(w{-iЂ(++[>-~ lpV! (ĉSSSm/S,;1i||W&dl6a h KӞ/2smuuu ,& ;q ge(8ǁŃ:q  UUV9>x@ АdrKEC~( vus⻛;CB4_~AIK .omZ"mm_>%ES/6o`$itͺԮiJk03D;::Z @+lj[8h!~V_ٲeKbW [WzC0z=[fY_ypAi.X0oYEU&RYWTUUٓ/0!dȑ#_=sO֒[nRЈFN1uΰ1$! ?_ơtɓ'`1!>4777%IV4@ZkjjTU17xIߏ 65bϭ~L٫:MԃVU*4%:}@u L~?-۫}.)*Ip?'SWr_ڛᆴ^{m[GGG>R ۻp[|(61?z,SBhcIENDB`yagf-0.9.2.1/src/images/yagf.png0000664000175000017500000000646212247205425017034 0ustar parallelsparallelsPNG  IHDR00WsRGBbKGD pHYs  tIME'D4tEXtCommentCreated with GIMPW IDAThi\u{zM}$Il,f1fS0d &8,1 e0c0Ae0Hifzfz~o1H@+{UwyuyFeQFel^Ϧi Ï_=&QxǘןaTHz%Ȼ-6o Xy㝿k%\s?ሂ`A&d[*aVb(Oe?)s`!9.rN$_q5*Vέ hScdLe *Pvwdoz`58;^[=D t A>FOԷp>Wۼf5+z]a 3RI0 #ѦD 3}lkLዹ+)1y8:.b6 ZŒiV@jt< Z؇ wW[s`pp_uIn51&XB m@J TĬd*%k³/ ͙ǣǝU˿Hne %E'NZNj$p85!,MS)SHL3phrOoZ/$8/SgSFoL-|BecD)FK#bTcanKWGOWrY:Mӧ N:=P\;FVf-|a# &O#5ԺwEQ`FxS 1yj8Dh)܆TeX`v^6g~?-gyi<?eѯep" QAD!-_C8g&An¨rd&SI腋QJaB ?N5K \@ OQLdd F|uVz M LD0' 5Ye(D 4ēW6%MUY "I 1Gˬ]v%mE! `IU`w#B.m8uNKXCMoN_8 Y.>:&0Z Wr*ѠJy!hH%ǣT q3@FmhakMM혅h!tJ%4n'StkN 0M9Er(MMTT^3A&7Q:is?gɢE,=u@9 *_In6fL#P $>~P&sJr9fM: 0i:# VDŽ]4g?XB u6g©Fصi,1bq̶̥ѩmSr3 iT*ؓ`{!C±X瞁?zbM[D1;=@N昡МB#eH$By&Wsu-rE6}q!$V,GzU\^{vm,RU=@>]qhF.֟^/ ; 3m 5 P(#!Qcm|SqVD";l8 F ^b)  Hdvv"`'luϡ:;ja1u&bqf:hL? u4rVj/'Ν׾‘EF:l96Pe,(ARbY_f.J6ZLHn^Ax{PiZ&QvR0@5``*Ğ2NO&֒IeͨZR  TsQB ~ [-Bq ]eVq,J.MLĘ9d@J[Vc"RiN,uvoO;= he([KXj<EiTۖ^vCG-ş}}f#YC/Ow  iڎ!DX#T:׳ QXTv)f)Ն!n a2YBU!JfxȞNLQnJՂh>r9KMNP !0 9Ra} y ~blnb=W"s0$5=[`Fb4xA ,\-AdzPP<|#'qM3Z8$9HŰIBЦ¨0C_JG!_% isDv!/˖ӷlP:D-LQ& A}V!A$S%:pJ+,%ӎ+=aL[ƪ ''aY_a2YۅljH1o @J$>[Jd$I(M/q[ۇ jZwnUAYph#gh|  +~Sbl݈Ձxa=4J9 sOZ.'Ni3GF -B#0 | BLeBN;0vv oh߾sH5z><0kr;/S 9`[&2ԇs+olD졖RcWR?V?>F#Vf1223d*qrW^ޅޅ(ޮfgw;?@w:n@W ,[`^hmVdОFTea0dɬzUngհW=:luȑTX8+Wr} gUG _B<mͼd6-=N O/ Aʃ>?1g\m7K*1uBQ՚^e\>rԙS>8{oG M4>Eˤ1JS-~c^~}BWp䇟a-Vl'+ll<"=6|r׽6w?/t+4_ hb\Hvh=sh?X}]Q{>gO~hrQFeQF?M9ftIENDB`yagf-0.9.2.1/src/images/filefind.png0000664000175000017500000001101012247205425017647 0ustar parallelsparallelsPNG  IHDR00WsRGBbKGD.Ni pHYsu85tIME1`tEXtCommentCreated with GIMPWcIDAThՙfUy?s}^g3 Pc,#P@gP,J411&jdFI Ta1U a`hfmm]zp{XV{>gC2?r]R _{8x( giJecpa!B[:bݏ ;89kg(rr[j&ͬ| !tZUBDq .x|>844p,84uB/DryddyRrm6۩?2AJˣeᬥ|7n7}_Rv $o`졇!<^L_t~itO-hFJ! OJXܸTԸSf}%.~Phm[:y>K;O_~Sf,%lXO+4'4B 'RIy Z.kC1q$ #ky%)Ug{pѧ=tb$pѦ`}^}p?:|}Xew=?70vqfD '"ܽ\q˹BKƽ9Gy8r$1kU sOOV{ڝ߿ڡW^}-ʫD|0$0@yɝp$'vX8paO} !&xjԗjw3 h0Ʋ yM!~$w" H,R s7ճu`vWXEpgڢe?IԼ~|ww*__޷/km/ ]RwA $sAjZ8NΑ~rqwa#NRrmJ9\3'_C0/`_gii{ ?2ӟ254Pd9NҶ}'=ph[,=4ڀ@u s!%Zc!%֚jBJIXkXkl $1$I+PyLR$JD'` ;)R^5)R!ZPAuyŽTk.90222B3#={1oۘXڙvs;\ 6E7c]`-~Yz> ӳyjOt ‚i2'f֙V@UX_W0:H"(Y9(2+tkE82ciRJ֫3ê,dyR4,Οjn<[xiD+ưzଵuE-H,:rB@JoV(Ҕr|,d)ki[Cs+{S2,J(bE4Ylf|G4 -E1fk-ks$iJec vI&)%KKKhc癙)1`1P `3˓F3}GOZS ՛_0eYFexv2]XQ c,Ie(50gԚex^As,//y^/u:ey9Gt6ߗzot98h%j%XRT5 OA VvLdžz XG ?'wbxn.~CV[\+%ztdhO u=#SC:(qB;0N`xH!`^AJI@fwDvRt\> vmcu{26iټ^^?4!%SPiQ׉(,G("xR6BRB c¯AfwI!GaRzXDQi3TC5I ' ;U>+3g<~zW(hEK.nmã~p^83aSU GH!('KԪ0$}R)+?)J(OR.8S~׮S>}}}T*UYt?gu](r$vۭ׏ nh,Τ$8G EtFq-(Rg≣\}:+\@x+/zݱc|ߟ81~ %5Aj%Bfq"#9߸;9ϠXd:*J)Ft<cLy^wȑ#My^ˎ(N[;vp ~xRVEhGmp4MҔٓhY<#R1ΛXWST'IGxGf~~%,;ÅoٳnjR#z=$)vmyN$(0Ʋ@$Iq޽{hPThZq{ݭGizg8۷/ݻwM7[Ivɏ{uc#lX7Z"'<녹O(TW & 02P^Rg||d~~(h,//jpp<,|.,BJԱ=(aٰvzr)|EZ"=jGdڏgcPcb|Ap099 Q155ŦMzZVJ1zjJ=8Ws3Bؿ?Zay饗 ZK,..fxxܭŷ:1(ؼy37o9G$"8a!rU9غu+{RPi4LNN2>>ZJV,gdYv*="썮+[k{tV<\qrI9B]"s;y)P~J=[p7SVyǹkgzz),cڵcT*!8tBYt]w/:txT*<\{lڴG2==Me@J%ޑ wt3J&s)J<\wulݺ^{'NZ,k֬9x~~5Ƙ=}JR *{1J +\~eq 7m6^yNJF"H|%p 0>bAcUV^a sgՋI$ثMS_kb͢va)%R@$֎Y 0.f WTTxOųHD" 8Q{Y =,+ۼjΰB2 #4o,U9i2ƽ3xu"1hF~"Yj.D$%3˜td´**jN'<ݵgҜ\( Oe'ij"[YfYb!QߖBS r[rH#gV\hqFG}G9BNN7--M X{I PG^c:l @CáuZەwEC&P_|>/8˦K -1KGoVsF}D)q @G ,*"|ғ⥻ɽRqdDS> 5kSўY&7Z9 #?euL -6@^b6?_-- IENDB`yagf-0.9.2.1/src/images/document_open.png0000664000175000017500000000312012247205425020731 0ustar parallelsparallelsPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<IDATxZ=lE~^l.JJAAhHT((t))?IDrKˠHN|s;x;w{s,w)>|w}Y gCG SPe "]z ) @Y?q:tŷ/_|m$(H\beeׯ ;R%zjR1~I<>r/Mu,Ɋ'N3 Y:?^Q a#<(̌@k` ÀkE W/c؝K#ڕZy/ނ^R@ p9J;n}ea<ٽɯF;PLU3sn`@C,s@pj\0&a7pX`& V43psFX`BXK4YUBBZPsU9)…B H{ VbX$T2b p>N?e7g9J8Zcl2 qSeHY Dts6qƛaDeL I(91f!hP%Žw Vu\r5:i\|^WMdDx)le5sgN,1o3Av.gs}퍗_M@H"ϔ'dx.нv%o@zsomFgC& V|Ĥ/d `=Psus&/ @ i1|B@ģD<GG6Ձ\ ՟-S!bl"lIt7tMmT@Ffeȱ}}tjПêZ:T^: y?K1TEHb%rPKhB–ne+p~,'ט+Sfq  HyEA""%д0㔑1(h.DuO"NWT$܅ָ4qNΛK'zk=hMNHB1@+@\Yd\91JsIi G>MZ"[;]U!!@_є>< y,N)E:3 m!aHb9 :E>L#&{G\)`T]4AQ!)jH=n =%7j<~7l>d]=9^-"yzU5rYJ+0"\Rn#kiZDr@ݱgE")&4_۶ހ`AcVSI(g_xwۏ:̋Z~?~"?%<%I ]uatIME #5bKGD.IDATxye]9{{W־uu[Kb0h9Ƃ fBt 4"Lƒ5&<<̀ #H@4n-VW/teU{97s߽****^ĭw-޻-r5}Szus[I 0Z!PxL}KnpoVM2 y['>^90\m`*(:noj D9`& DrKظce]N`LDw\w(~z0Lȿ cV$FaEQP);c掃ooLt^_ ak'xAb UJzAz}}a$QtrdǚdUV~#Kyn?>max뮠. R#Fa Aj~pZiBDڊ,S(%h-(Fu@690J5K S/W;xe`7bR;^}8~|;váp<l;/Pzp>ҡVZm ՞%Iti!g@%DGIwj4,Og>ðe-krx=3g2Zxqv{TϷb?RԨjDM Fڠ߇R?BJnϛ? BJ&MrZG~<(cr[ Z},=Spp 'a&lD+ʾWA#xptDBfZZՐ/[qK4*BYtZAX;ڏhwR&f'iLg#c=m\o#[ {f vhD՞Dz/4r+#[]9[=$:u)EC)ѐdsv &[J&f;t'&;|:sUd_!|mŞ)3'` i}WEm:h[IX}F7}-s)p^>`4Ab $Yid,DgCkORnvxibOWuh0߁6eq0OH:0*}J{<|=bcd ⊷eW♛;oN4 ( b RHj!Kj!)d'N?4UXߙ)vMl'PS t:4{a PFAB>.aPH ԑ$e: &A@_P4 Dje MD͔hMhMI:m~W^]pE_&K"M,]k*~DU9uؘi* ~I\+!H-zPHMxٷeaف1+7lZguIze1>ʮ@<)SQWd9|*IT1~*T 񳍏@`+q"5Q3>[l 3L&`bmS%Pap3.bE - ,t-XmyYE1TR3 hb~VgajVi`V` AɉIld2\(/or ?*qY|d D%BPE\EMP&Q-WiߊR3}j%pƄnVI`f2p3mD\*LdJ&]tu ԉaeO/~$6?v:LOe *K'#]sv OE 5}mg6M֤P^ L&5V A#DQTO"6|RVcu)l!K &[P~ (dT9 BBJ+ 0,]x}BqHႇ>?TBܖsQ_iVceb>Q#6AhI`Z$K; hqß/Pu}̬&hep)6|N2pdN jD!{7, B3<U3Ht}8\FLJVF *bҷ>XA[ Yڠ (UXB@|nbY &_A֌5q2 *'ս`2I O 7p_SNn CQux6Z4NBu/ M 0 Fiܘ҄aw&Z ߋ]Ht  GצW}EAKMMWfj uN;~I ti+n&  Wwp|\ bcf-8'x+8K8٨ppO+X g:=_?)d TFKM#WuTZinee&ѩԿZ`k+EzBH6Bh oU J+B4n޺M)&284lZ&bёjŕ \2(VmQ^SW}⺸p 1>5VSB5$/:_/|]sk.dCqwAjD PrQFst~ )uy>=IjE% ugͽe#I#b @2,|žY2_wqInjXfkrYhBVŗR8xaɣУ'|mbhBH-;BT쭦k#y8ԁ*PvΠۺx bԈ^E*FTE B"BBoů*Uu熹ԢS8=z/X-|/݇Ϝ=n*cCV_]>3‰9{Ae=tшcDXjޕ+P0Nea8\%8|ĂhAk.JS:VjRku9Y N/ uwy@i~4j  ݇p}:cj\| *ǻʳ*Y=vA܅e90?Q< t%*ݺ4e BZ3,+UK_y(^sn ;yDڠ0$IdL64ZTEr':v(5rETC!DՓA$_?->wa8G=wVLOkFJ _VfR./#Om]  -^i5T&ĔfpQm ΅] ٪2: sы|[*nŞe()N/_| :x횓gƗN -\*A6JӽJ|*" ߭]ybz;U财z [QxA· 'O^\ud\\S@\ O>H Ͻ$.K̪FO"Gя`? e0gA#ò(ea~V#R"" eUX+Eu] | &ZO1'f!,2 k3XϝyI$ Jw}XZKNA rGhzdvgLox .E oA!_!VpILNξHXucBN`V۷f7;'^ K2) ؾQ>]t+S| /{Y.(5Jc8F(XrؖC&(ŷ)qAx;"IBQBQ(ZR#bqHeUn?PtlEto3Ae9S|yBF$iÊW}/_v).PP@ EO~#KŋE\J EP<`*3AT=Y yb~E!ʮFc6hdYNA:l.f [+O4h>@!fxH+"RٕrmM^A8׾s/%h 8Ǘ1*΅+PI fV t󪘴G 輸UdETe|]k7}NȢS + aP Iӆ)2aKG{!SvoQ-Y/`y82 (ob*&y6J22{ªxzϲmEgN AC5M /f &'Be;,wO5qcw˧J@8yvJSZJᕄQjm,^5e*W\ďUf@x>*KQtauҢ *%/VԞ)=p-yR7Dly.`#1<-/ВT`L1%rus*<'Qh}]tQ۪ IFv6)(aE? ;Bbc-˰t&[LN$xg)J``wynNӾ FeWع1D}% G4!^ޠ qjAFo*&c)XU^+O@H'M--Yz"겲j q&`۰w2mO}w^'(u`iHXUBz/49n{j}=.:YmiL \hU&`΀9n +f*dyde2:n? 5LoEpxuѻw{RQE!cW ?o8\HbU&VR;5*Eoo8/*Ǩ_Csj| xhmK69]EI[dYY)-5AEF^w}m^(t1mP͘43?'̽IP:G_ZK:+_W|G<165B=ES[3,VJ/ZJ=ˁ= Mv- dH?JLdu &ާF[FB(/ڼ*9hv"X:{:M 305ȋ^R…%+]weމU`vEltW#3|xXIeB^oOcO7`wOh·BFǮZ+;WO 8{_Wf5PL`fg?5eI[paB8..[nسofKî['Z\~ c'=-U9UT@U}_URu 0#xj&&֖% sN9uBR3CXk8`#~MnC|? /Ԇ0 (U7M, *]/([GJ+V>-`*~U%,n~(  Μ+8u˅咽 O\VV7SW[t?@W6dGh1`C(81⾁>FNL"4͝^NaH3`P,-Z^Y9}+K2 YR +>4ԇ}/Y5U<;dx)\⃽Od M?.`%h&#V_yCTtJبR%K.9{칒K^uQu>pr/g -i%#zBS|#M$&$`Đu?ʿ]o|j-_@PZ4@/(s˩AɋWJ.+XX(8s48mD\.\GuZLs>Ə̋|㙼.$5.;\O UZך=PtMz3؄Kh%:+h-ynY9-/ %˧J.\,X\d ?=3xD>ck5r`##@.HGQOV 0A8ro.!s 3E[0/.j}| 'b +}K+ ˰kI^Y^ttKg~8~D㼏hߌ 4[z2h)5v4+??|?\,ιPHj$7xbSCf i$:8  l۶TUL`@_:uL-ˎ~rq`Y)-Ⴅ7,{g33EX nˁ/\ĪGNrAhbr;K6/!d<}4 X_-bZDv8`M D f6 `Gh(%(qC"qpǕNފee%^߂f}aԞԄaWHc6R*W=TJ ЩO9!)Y_ѵMFbcm~w`/>)J'hoQ DzT4 :tI E4(%(&d4VSP|~pG b;=ph,w9Ïk#$uBeV$>Fx_Bk5"0 8ʃ>~lt_b4Ą,Zw{,3< OPDcE&:hxP ya8S `4_: t.xdѱFbZ9|ypCRa11P%KKKt]}>/E(v JB2* 1B(4>Qp@{~(/.O>( "qk\k i!B9 "D[=ϰ GY*;|IjO=Z;k]Qh;s{Zi$!4I Iz}?G$T w>oOS1'ILAKf(ln?;|OyE.,ڠF[ [h03 [#YSH*Nh@)=yd)YGmx=pDZ0 dFH'UDYEâ[E]?8"~tBCdYF&^ .K\~Tk J2 q8t5X;ų/ Wx>g^㬠A틊5cUQӈ?$vnqS{mao $JH#š( e9戔x_">lH[k"xG$j~fSyS=`X; 5j҄N*KRjHH{j;a' _Kr^>p.׷( FiҖ&K bϞ8|=ol3=Q"6-Qa%Zxĕ_)A[q -ι`ǖdȑ#^?%Dسk*jw-(UiW7d*ިҹ)|׷NubDtT1HE"oC7 +^p(hAF + z }2+gχ89rcn#Iq~'~g#w\f; ^ Dbёͪ^=RNBaPȩV.cR &$mj+_k|=(R`0{8[b0;;޽8z@DVqV}T[8oʁx,pή+5o B?>oYIЎrs97c=l A3ITWl;+ˑ71ѹ,#?4½铝+X֊Qj}dI5EF^r+cY?1Se׏&SjA"[=Ux,xk?;;ڿ/B/~~>;j_2hI9|j߰׏ _ 5%z.2y!ٷom)xG?~S- n trelHqEVuI##'1Y#AIޭӕo,@8Çn[_WP[$+Pȗp uiIn$Wi8~TFB-(q8V}Ej8tι%O~=yϯv;tvS4|HtK)V++E$5@Yx9pJ+<9q|i;zřkU ̞رc&/~eY.e^ƟX=kԸ|Gpo_Ǐk'Nu J͘WzoP 4]~ӟzϮ0_>V ֚,˘͆Mǯ|ᇿUӻ:ob֚Uqqįʯ?=CpvD\6>?2ypVϿZ[_r_in˿'?oU<%?p9>>hZJJ~ٟ٩hwʿ:l50k#8t曌2~w&X%>טcZ>ګDM<4oZpfM_+%2fA^Z~=Af5`L%熶QmIENDB`yagf-0.9.2.1/src/images/resize_block.png0000664000175000017500000000202312247205425020546 0ustar parallelsparallelsPNG  IHDRĴl;gAMA abKGD pHYstt~!gtIME/-IDAT8˥U_LSg}^%T-Z̥Pt&p &V>4:%Ie[̩pO˞->h42 D J g띍 rON;}P1+6XEXZz-[,h`y~w*"Y0[L-&{ƿI iN-ұU*ʤp$)_x<~맱@-8眯Z;8+o5i_+ҧ'OE(Ȳ YyE\n+GkfЎDߚ]ަT"j B9|Ϲ:IUUhhXxӹ)A<=!<0t{i.\({4Fv@]`s?lOM {fRj J&\W1•k?bf>zK+[ @@{Z/:|4Md2uCutC9*++EQ!\lWc6 EBYDp fנ5!DCs &m ~OGP]n\n.'JVk8rE߄@\\O_Z?N/RG `xͺe(b$q (0Ӂ=')j.=XK?;ENXB$Iz+-oэA@]`=ǰ}],mMZY($j|>̲i" T6ρ"Z;IjK9"`IENDB`yagf-0.9.2.1/src/images/forward.png0000664000175000017500000000457112247205425017551 0ustar parallelsparallelsPNG  IHDR00WbKGD pHYs^tIME  eP IDATxY{.XkFkRikMc6REJGZ"*Ea ]]w;3L?Ι;sﮡ IY~~;s~NI;6[]Q&\!ĉ#`LGWឳNy^eJ:cQ+׽qg8VM^K~}So^<?d-;*(ong?:\|V]z=MAqĆq\Z7l($_D n٣,~p&u-T_7G;\\/4e865f20xGa%@2Z@B>@g~H,^4 ~̺PzAMs;2B!/y. ]? Y1"6Ma! P΀ (Ɵֈ;okzG*!ܮ>?0Lz-c#0rٴLa+{rQPz{zK.Oȓ %$>̱zF!^r=.>egQĦNW@D&"JE^#B!3g1)6n=q/9(s1D.&("H*AM) , Y (SlUpKͦ;UfB&!Mf^X BQ;>MFPSHa8e[%{0:?O.Qh#ϸ05bK-Dۊ <_`6i#> b[$S.y#nJ!>o&\4@nVBCzsã#FBJǜ"*YP"@H(@RUO&S Jf;HV{U;Q͏̔0PO/GY@7fslLtNʁcgD:AweComr_U Xt@:ع(~*U\7 aŽ”Qm,Ky\GT@qMX*􄰒_qPPB`U?ۑ4q .c[f[ $"FRUP"+1@}} ){KR{; Ǽ@h^[5eğ0eSM*>NC:B@{8zWo\5jCKBeX$"m8QTg@BNɛ*U#=+_m|oКSƌ2D,:S"p!H>ui62o;;m`W`z)}1=-b&N9]L(ۙ%L30'!F+U+}Ń(@# /̀,@MĹbDt.!lٴ}6DvD<鸮[^'t@?H>c>wλHOR晬,S7ڶw[ T3rA;*'8!ǁoGj-W,3AT&7J/T!@f9ݝ֍=eDv=jcڷ(N4:JFjQ9Ԃw׼,_}So˲.|sp&@!׈x[^.(R)Y`[samY@;> )ݠ@lӱ f![_܊*;^ZPMPe4V^Kx|K%Ў-[XDȏ9=xuR1O%fBkЖ%?`7xV]o| cG|uú6K[`iz ڰd1nXtbe ʚv"l:y2/l^ z:)#ܠuX `|h57>uWO>uu]tQ8i'ıcĠ=:IENDB`yagf-0.9.2.1/src/preload.c0000664000175000017500000000403012247205425015712 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include #include #include #include #include #include #include #define _GNU_SOURCE #define __USE_GNU #include //static int fd = 0; static FILE * f; /*int open(const char *pathname, int flags) { printf("called %s\n", pathname); }*/ FILE* fopen(const char* path, const char* mode) { printf("called %s\n", path); FILE* (*real_fopen)(const char*, const char*) = dlsym(RTLD_NEXT, "fopen"); if (strstr(path, "input.png")== NULL) return real_fopen(path, mode); if (strstr(mode, "r")) return 0; //if (fd <= 0) //fd = open("/var/tmp/yagf.fifo", O_WRONLY); f = real_fopen(path, mode); return f; } /*size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) { FILE* (*real_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream) = dlsym(RTLD_NEXT, "fwrite"); if (stream == f) write(fd, ptr, size*nmemb); return real_fwrite(ptr, size, nmemb, stream); }*/ int fclose(FILE *fp) { int (* real_fclose)(FILE *fp) = dlsym(RTLD_NEXT, "fclose"); if (f == fp) { // write(fd, endmark, 6); int ppid = getppid(); kill(ppid, SIGUSR2); } return real_fclose(fp); } yagf-0.9.2.1/src/make_style.sh0000775000175000017500000000023212247205425016614 0ustar parallelsparallels#!/bin/sh astyle --style=k\&r -l --convert-tabs --pad=oper --pad-header --indent-switches --unpad=paren --align-pointer=name --indent=spaces=4 *.cpp *.h yagf-0.9.2.1/src/projectmanager.h0000664000175000017500000000313212247205425017274 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include class QXmlStreamWriter; class QXmlStreamReader; class ProjectSaver : public QObject { Q_OBJECT public: explicit ProjectSaver(QObject *parent = 0); bool save(const QString &dir); signals: public slots: private: void writePages(); void writeBlocks(); void writeSettings(); QString copyFile(const QString &source); private: QXmlStreamWriter * stream; QString directory; }; class ProjectLoader : public QObject { Q_OBJECT public: explicit ProjectLoader(QObject *parent = 0); bool load(const QString &dir); signals: void languageChanged(); void engineChanged(); public slots: private: bool readPages(); bool readBlocks(); bool readSettings(); void loadPage(); bool readNextElement(); private: QXmlStreamReader * stream; QString directory; }; yagf-0.9.2.1/src/projectmanager.cpp0000664000175000017500000001656112247205425017641 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "projectmanager.h" #include "tpagecollection.h" #include "settings.h" #include #include #include #include #include #include const QString URI = "symmetrica.net/yagf"; const QString VERSION = "0.9.2"; inline QString boolToString(bool value) { return value ? "true" : "false"; } ProjectSaver::ProjectSaver(QObject *parent) : QObject(parent) { } bool ProjectSaver::save(const QString &dir) { directory = dir; if (!directory.endsWith("/")) directory = directory + "/"; QString fileName = directory+"yagf_project.xml"; QFile f(fileName); if (!f.open(QIODevice::WriteOnly|QIODevice::Truncate)) return false; stream = new QXmlStreamWriter(&f); stream->setAutoFormatting(true); stream->writeStartDocument(); stream->writeStartElement(URI, "yagf"); stream->writeAttribute(URI, "version", VERSION); writeSettings(); writePages(); stream->writeEndDocument(); f.flush(); delete stream; f.close(); return true; } void ProjectSaver::writePages() { PageCollection * pc = PageCollection::instance(); for (int i =0; i < pc->count(); i++) { stream->writeStartElement(URI, "page"); pc->makePageCurrent(i); stream->writeAttribute(URI, "image", copyFile(pc->fileName())); stream->writeAttribute(URI, "deskewed", boolToString(pc->isDeskewed())); stream->writeAttribute(URI, "rotation", QString::number(pc->getRotation())); stream->writeAttribute(URI, "preprocessed", boolToString(pc->isPreprocessed())); writeBlocks(); stream->writeEndElement(); } } void ProjectSaver::writeBlocks() { PageCollection * pc = PageCollection::instance(); for (int i = 0; i < pc->blockCount(); i++) { stream->writeStartElement(URI, "block"); Block b =pc->getBlock(i); stream->writeAttribute(URI, "left", QString::number(b.left())); stream->writeAttribute(URI, "top", QString::number(b.top())); stream->writeAttribute(URI, "width", QString::number(b.width())); stream->writeAttribute(URI, "height", QString::number(b.height())); // stream->writeAttribute(URI, "language", "eng"); stream->writeEndElement(); } } void ProjectSaver::writeSettings() { stream->writeStartElement(URI, "settings"); Settings * settings = Settings::instance(); QString engine; if (settings->getSelectedEngine() == UseCuneiform) engine = "cuneiform"; if (settings->getSelectedEngine() == UseTesseract) engine = "tesseract"; stream->writeAttribute(URI, "engine", engine); stream->writeAttribute(URI, "defaultlanguage", settings->getLanguage()); stream->writeEndElement(); } QString ProjectSaver::copyFile(const QString &source) { QFileInfo fi(source); QString dir = fi.absolutePath(); if (!dir.endsWith("/")) dir = dir + "/"; QString base = fi.baseName(); QString fileName = base+".png"; if (dir == directory) return fileName; QString newName = directory + fileName; if (source.endsWith(".png", Qt::CaseInsensitive)) { if (QFile::copy(source, newName)) return fileName; else return ""; } else { QImage image(source); if (image.save(newName)) return fileName; else return ""; } return ""; } ProjectLoader::ProjectLoader(QObject *parent): QObject(parent) { } bool ProjectLoader::load(const QString &dir) { directory = dir; if (!directory.endsWith("/")) directory = directory + "/"; QString fileName = directory+"yagf_project.xml"; QFile f(fileName); if (!f.open(QIODevice::ReadOnly)) return false; stream = new QXmlStreamReader(&f); stream->setNamespaceProcessing(true); if (!readSettings()) return false; if (!readPages()) return false; f.close(); return true; } bool ProjectLoader::readSettings() { Settings * settings = Settings::instance(); if (!readNextElement()) return false; QStringRef n; while ((n = stream->name()) != "settings") if (!readNextElement()) return false; QStringRef engine = stream->attributes().value(URI, "engine"); if (engine == "tesseract") settings->setSelectedEngine(UseTesseract); if (engine == "cuneiform") settings->setSelectedEngine(UseCuneiform); emit engineChanged(); QString language = stream->attributes().value(URI, "defaultlanguage").toString(); if (!language.isEmpty()) settings->setLanguage(language); emit languageChanged(); return true; } void ProjectLoader::loadPage() { QString image = stream->attributes().value(URI, "image").toString(); QString fn = directory + image; bool oldcl = Settings::instance()->getCropLoaded(); Settings::instance()->setCropLoaded(false); PageCollection * pc = PageCollection::instance(); Settings::instance()->setCropLoaded(oldcl); pc->appendPage(fn); QString value = stream->attributes().value(URI, "rotation").toString(); if (!value.isEmpty()) { pc->setRotation(value.toDouble()); } value = stream->attributes().value(URI, "deskewed").toString(); if (!value.isEmpty()) { pc->setDeskewed(value.endsWith("true", Qt::CaseInsensitive) ? true : false); } value = stream->attributes().value(URI, "preprocessed").toString(); if (!value.isEmpty()) { pc->setPreprocessed(value.endsWith("true", Qt::CaseInsensitive) ? true : false); } } bool ProjectLoader::readPages() { if (!readNextElement()) return false; QString name; if ((name = stream->name().toString()) != "page") return false; while(stream->name() == "page") { loadPage(); if (!readBlocks()) break; } PageCollection::instance()->reloadPage(); return true; } bool ProjectLoader::readBlocks() { if (!readNextElement()) return false; while (stream->name() == "block") { int top = stream->attributes().value(URI, "top").toString().toInt(); int left = stream->attributes().value(URI, "left").toString().toInt(); int width = stream->attributes().value(URI, "width").toString().toInt(); int height = stream->attributes().value(URI, "height").toString().toInt(); PageCollection::instance()->addBlock(QRect(left, top, width, height)); if (!readNextElement()) return false; } return true; } bool ProjectLoader::readNextElement() { while (!stream->readNextStartElement()) if (stream->atEnd()) return false; return true; } yagf-0.9.2.1/src/qxtgraphicsproxywidget.h0000664000175000017500000000244012247205425021137 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef QXTGRAPHICSPROXYWIDGET_H #define QXTGRAPHICSPROXYWIDGET_H #include class QXtGraphicsView; class QXtGraphicsProxyWidget : public QGraphicsProxyWidget { Q_OBJECT public: QXtGraphicsProxyWidget(QGraphicsItem * parent = 0, Qt::WindowFlags wFlags = 0); void setView(QXtGraphicsView * view); public slots: void viewScrolled(); protected: QVariant itemChange(GraphicsItemChange change, const QVariant & value); private: QXtGraphicsView * mview; }; #endif // QXTGRAPHICSPROXYWIDGET_H yagf-0.9.2.1/src/qsnippet.h0000664000175000017500000000232312247205425016137 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef QSNIPPET_H #define QSNIPPET_H #include #include #include #include #include class QSnippet : public QListWidgetItem { public: explicit QSnippet(QListWidget *parent = 0); bool setPage(int id, const QString &name, const QImage &image = QImage()); QString getName(); int pageID(); signals: public slots: private: QString name; int pid; }; #endif // QSNIPPET_H yagf-0.9.2.1/src/popplerdialog.cpp0000664000175000017500000000332112247205425017467 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "popplerdialog.h" #include "ui_popplerdialog.h" #include PopplerDialog::PopplerDialog(QWidget *parent) : QDialog(parent), ui(new Ui::PopplerDialog) { ui->setupUi(this); } PopplerDialog::~PopplerDialog() { delete ui; } void PopplerDialog::on_checkBox_toggled(bool checked) { ui->spinBox->setEnabled(!checked); ui->spinBox_2->setEnabled(!checked); } void PopplerDialog::on_pushButton_clicked() { QString fileName = QFileDialog::getOpenFileName(this, trUtf8("Open PDF File"), "", trUtf8("PDF Files (*.pdf)")); if (!fileName.isEmpty()) ui->lineEdit->setText(fileName); } QString PopplerDialog::getPDFFile() { return ui->lineEdit->text(); } QString PopplerDialog::getStartPage() { return QString::number(ui->spinBox->value()); } QString PopplerDialog::getStopPage() { if (ui->checkBox->isChecked()) return "-1"; return QString::number(ui->spinBox_2->value()); } yagf-0.9.2.1/src/settings.h0000664000175000017500000000520512250171073016131 0ustar parallelsparallels/* This program 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. This program 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. */ #ifndef _SETTINGS_H_ #define _SETTINGS_H_ #include #include #include #include #include #include enum SelectedEngine { UseCuneiform, UseTesseract }; class Settings { public: static Settings * instance(); void readSettings(const QString &path); void writeSettings(); QString getLanguage(); bool useNoLocale(); bool useRussianLocale(); void setNoLocale(bool value); void setRussianLocale(bool value); QString getOutputFormat(); QString getLastDir(); QString getLastOutputDir(); bool getCheckSpelling(); QString getTessdataPath(); SelectedEngine getSelectedEngine(); QSize getSize(); QSize getIconSize(); QPoint getPosition(); bool getFullScreen(); int getFontSize(); bool getCropLoaded(); void setLanguage(const QString &value); void setOutputFormat(const QString &value); void setLastDir(const QString &value); void setLastOutputDir(const QString &value); void setCheckSpelling(const bool value); void setTessdataPath(const QString &value); void setSelectedEngine(const SelectedEngine value); void setSize(const QSize &value); void setIconSize(const QSize &value); void setPosition(const QPoint &value); void setFullScreen(const bool value); void setFontSize(const int &value); void setCropLoaded(const bool value); QString workingDir(); void startLangPair(); bool getLangPair(QString &full, QString &abbr); void setProjectDir(const QString &dir); QString getProjectDir(); void makeLanguageMaps(); private: void findTessDataPath(); QString selectDefaultLanguageName(); Settings(); Settings(const Settings &); ~Settings(); private: QString language; QString outputFormat; QString lastDir; QString lastOutputDir; QString projectDir; bool checkSpelling; QString tessdataPath; SelectedEngine selectedEngine; QSize size; QSize iconSize; QPoint position; bool fullScreen; int fontSize; bool cropLoaded; QMap cuMap; QMap tesMap; int lpi; bool noLocale; bool RussianLocale; QString mPath; QSettings * settings; static Settings * m_instance; }; #endif yagf-0.9.2.1/src/BlockAnalysis.h0000664000175000017500000000277412247205425017044 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef BLOCKANALYSIS_H #define BLOCKANALYSIS_H #include #include class QPixmap; class QImage; class QRect; class BlockAnalysis { public: BlockAnalysis(QPixmap *pixmap); ~BlockAnalysis(); int getSkew(); int getSkew1(); int getSkew2(); QRect getCoords(); QPixmap getPixmap(); private: QImage *m_image; char **m_blockMap; int longestLine[3]; int longestCount[3]; QRect *m_coords; qint64 mtreshold; quint16 *linesInfo; QRgb * * lines; void newBlock(); void deleteBlock(); void countLinesInImg(int factor, int d); void countLinesInImg(QImage *_image); void preScan1(); void deleteLines(); bool badImage; void createLinesInfo(); }; #endif // BLOCKANALYSIS_H yagf-0.9.2.1/src/SkewAnalysis.h0000664000175000017500000000236112247205425016713 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef SKEWANALYSIS_H #define SKEWANALYSIS_H #include "ycommon.h" class QPixmap; class SkewAnalysis { public: SkewAnalysis(QPointList *pointList, int width, int height); ~SkewAnalysis(); signed int getSkew(); double getPhi(); QPixmap drawTriangle(QPixmap &pm); private: //int bin[360][2000]; double getRightPhi(); double getLeftPhi(); QPointList *pointList; int m_height; int m_width; double phi; QPoint * p1; QPoint * p2; }; #endif yagf-0.9.2.1/src/ghostscr.h0000664000175000017500000000170412247205425016132 0ustar parallelsparallels /* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef GHOSTSCR_H #define GHOSTSCR_H #include "pdfextractor.h" class GhostScr : public PDFExtractor { public: GhostScr(); virtual void exec(); }; #endif // PDF2PPT_H yagf-0.9.2.1/src/sidebar.h0000664000175000017500000000310312247205425015702 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2010 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef SIDEBAR_H #define SIDEBAR_H #include class QSnippet; class SideBar : public QListWidget { Q_OBJECT public: explicit SideBar(QWidget *parent = 0); void clearBlocks(); void select(const QString &name); void selectFirstFile(); signals: void pageSelected(int id); void filesDropped(QStringList); void fileRemoved(int id); private slots: void itemActive( QListWidgetItem * item, QListWidgetItem *item2 ); protected: QStringList mimeTypes () const; Qt::DropActions supportedDropActions () const; bool dropMimeData(int index, const QMimeData *data, Qt::DropAction action); void startDrag(Qt::DropActions supportedActions); private: QSnippet * getItemByName(const QString &name); QSnippet * current; bool lock; }; #endif // SIDEBAR_H yagf-0.9.2.1/src/imagebooster.h0000664000175000017500000000265212250140707016754 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef IMAGEBOOSTER_H #define IMAGEBOOSTER_H #include #include class ImageBooster : public QObject { Q_OBJECT public: explicit ImageBooster(QObject *parent = 0); ~ImageBooster(); void boost(QImage * image); void brighten(QImage * image, int p, int q); void flatten(QImage * image); void sharpen(QImage * image); signals: public slots: private: void buildProfile(QImage *image); void sharpenEdges(quint32 * r, quint32 * g, quint32 * b, quint32 * br, int w); void analyseStripe(QRgb *line, int i, int w, qreal &med, qreal &med1, int &start); private: quint32 * profile; }; #endif // IMAGEBOOSTER_H yagf-0.9.2.1/src/imagebooster.cpp0000664000175000017500000002042012250140707017300 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-ends Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "imagebooster.h" #include ImageBooster::ImageBooster(QObject *parent) : QObject(parent) { profile = new quint32[16]; for (int i =0; i < 16; i++) profile[i] = 0; } ImageBooster::~ImageBooster() { delete[] profile; } void ImageBooster::boost(QImage *image) { if (!image) return; int h = image->height(); int w = image->width(); if (h*w == 0) return; buildProfile(image); int imax = 0; quint32 pmax = 0; for (int i = 0; i < 16; i++) { if (profile[i] > pmax) { imax = i; pmax = profile[i]; } } // quint32 * rl = new quint32[w]; // quint32 * gl = new quint32[w]; // quint32 * bl = new quint32[w]; // quint32 * brl = new quint32[w]; if (imax > 10) { for(int i = 0; i < h; i++) { QRgb * line = (QRgb *) image->scanLine(i); for (int j = 0; j < w; j++) { int r = qRed(line[j]); int g = qGreen(line[j]); int b = qBlue(line[j]); r = r*8/10; g = g*8/10; b = b*8/10; r = r*r/160; g = g*g/160; b = b*b/160; //r = r*10/7; if (r > 255) r = 255; //g = g*10/7; if (g > 255) g = 255; //b = b*10/7; if (b > 255) b = 255; // rl[j] = r; // gl[j] = g; // bl[j] = b; // brl[j] = r+ g+ b; line[j] = ((255 & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } //sharpenEdges(rl, gl, bl, brl, w); } } else { for(int i = 0; i < h; i++) { QRgb * line = (QRgb *) image->scanLine(i); for (int j = 0; j < w; j++) { int r = qRed(line[j]); int g = qGreen(line[j]); int b = qBlue(line[j]); r = r*r/160; g = g*g/160; b = b*b/160; r = r*10/9; if (r > 255) r = 255; g = g*10/9; if (g > 255) g = 255; b = b*10/9; if (b > 255) b = 255; //rl[j] = r; //gl[j] = g; // bl[j] = b; // brl[j] = r+ g+ b; line[j] = ((255 & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } //sharpenEdges(rl, gl, bl, brl, w); } } //delete [] gl; //delete[] rl; //delete[] bl; //delete[] brl; } void ImageBooster::brighten(QImage *image, int p, int q) { if (!image) return; int h = image->height(); int w = image->width(); if (h*w == 0) return; for(int i = 0; i < h; i++) { QRgb * line = (QRgb *) image->scanLine(i); for (int j = 0; j < w; j++) { int r = qRed(line[j]); int g = qGreen(line[j]); int b = qBlue(line[j]); r = r*p/q; g = g*p/q; b = b*p/q; if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; line[j] = ((255 & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } } } void ImageBooster::flatten(QImage *image) { if (!image) return; int h = image->height(); int w = image->width(); if (h*w == 0) return; for (int i = 0; i < h; i++) { QRgb * line = (QRgb *) image->scanLine(i); int start = 300; qreal med1 = 0; qreal med = 0; analyseStripe(line, i, w, med, med1, start); while (start < w) { for (int j = start; j < 300; j++) { int r = qRed(line[j]); int g = qGreen(line[j]); int b = qBlue(line[j]); r = r*10/5; g = g*10/5; b = b*10/5; if (r > 255) r = 255; if (g > 255) g = 255; if (b > 255) b = 255; line[j] = ((255 & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); } med1 = med; start+=300; analyseStripe(line, i, w, med, med1, start); } } } void ImageBooster::sharpen(QImage * image) { QImage * newImage = new QImage(* image); int k [3][3]= {{0,-1,0}, {-1,5,-1}, {0,-1,0}}; int ks = 3; int sumKernel = 1; int r,g,b; int bpl = image->bytesPerLine(); QColor color; for(int x=ks/2; xwidth()-(ks/2); x++) { for(int y=ks/2; yheight()-(ks/2); y++) { r = 0; g = 0; b = 0; for(int i = -ks/2; i<= ks/2; i++) { for(int j = -ks/2; j<= ks/2; j++) { color = QColor(image->pixel(x+i, y+j)); r += color.red()*k[ks/2+i][ks/2+j]; g += color.green()*k[ks/2+i][ks/2+j]; b += color.blue()*k[ks/2+i][ks/2+j]; } } r = qBound(0, r/sumKernel, 255); g = qBound(0, g/sumKernel, 255); b = qBound(0, b/sumKernel, 255); newImage->setPixel(x,y, qRgb(r,g,b)); } } for (int i = 0; i < image->height(); i++) { uchar * dest = image->scanLine(i); uchar * src = newImage->scanLine(i); strncpy((char*)dest, (char*)src, bpl); } delete newImage; } void ImageBooster::buildProfile(QImage * image) { int h = image->height(); int w = image->width(); if (h*w == 0) return; for(int i = 0; i < h; i++) { QRgb * line = (QRgb *) image->scanLine(i); for (int j = 0; j < w; j++) { int brightness = qRed(line[j])+qGreen(line[j])+qBlue(line[j]); brightness /= 48; profile[brightness]++; } } } void ImageBooster::sharpenEdges(quint32 *r, quint32 *g, quint32 *b, quint32 *br, int w) { quint32 sp[4]; quint32 mDelta = 0; quint32 counter = 0; quint32 * deltas = new quint32[w]; for (int i = 3; i < w; i++) { sp[0] = br[i-3]; sp[1] = br[i-2]; sp[2] = br[i-1]; sp[3] = br[i]; if ( ( (sp[0]-sp[1])*(sp[1]-sp[2]) > 0)&&((sp[1]-sp[2])*(sp[2]-sp[3]) > 0)) { mDelta += abs(sp[0]-sp[3]); counter++; deltas[i] = mDelta; } else deltas[i] = 0; } if (counter) mDelta /= counter; else { delete[] deltas; return; } int i = 3; while (i < w) { if (deltas[i] > mDelta) { if (br[i-3] < br[i]) { r[i-2] = r[i-3]; g[i-2] = g[i-3]; b[i-2] = b[i-3]; } else { r[i-1] = r[i]; g[i-1] = g[i]; b[i-1] = b[i]; } i++; } i++; } delete[] deltas; } void ImageBooster::analyseStripe(QRgb * line, int i, int w, qreal &med, qreal &med1, int &start) { if (start < 300) start = 300; for (int j = start; j < w - 600; j+=300) { int sum = 0; for (int k = j; k < j+300; k++) { sum += (qRed(line[k]) + qGreen(line[k]) + qBlue(line[k])); } med = sum/300; if ((sum - med1 < 100)&&(sum - med1 > 10)) { med = sum; start = j; return; } if ((sum - med1 > -100)&&(sum - med1 < -10)) { med = sum; start = j-300; return; } med1 = sum; } start = w; } yagf-0.9.2.1/src/qxttiffiohandler.h0000664000175000017500000000270612247205425017654 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2012 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef QXTTIFFIOHANDLER_H #define QXTTIFFIOHANDLER_H #include #include #include #include #include "tiffio.h" class QXtTiffIOHandler : public QImageIOHandler { public: explicit QXtTiffIOHandler(); ~QXtTiffIOHandler(); bool canRead() const; bool read(QImage *image); QVariant option(ImageOption option) const; void setOption(ImageOption option, const QVariant &value); bool supportsOption(ImageOption option) const; int imageCount (); //const; bool jumpToImage( int imageNumber ); int loopCount () const; private: quint16 dirnum; quint16 dircount; TIFF * tif; }; #endif // QXTTIFFIOHANDLER_H yagf-0.9.2.1/src/SkewAnalysis.cpp0000664000175000017500000001432212247205425017246 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "SkewAnalysis.h" #include #include #include #include #include #include #include SkewAnalysis::SkewAnalysis(QPointList *pointList, int width, int height) { /* for (int i = 0; i < 360; i++) for (int j = 0; j < 2000; j++) bin[i][j] = 0; for (int i = 0; i < 360; i++) { for (int j = 0; j < pointList->count(); j+=2) { long int r = pointList->at(j).x()*cos(i/360*M_2_PI) + pointList->at(j).y()*cos(i/360*M_2_PI); r = r/4; bin[i][r]++; } } long int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0; int phi1 = 0, phi2 = 0, phi3 = 0, phi4 = 0; long int tmpsum = 0; //for (int i = 0; i < 360; i++) // for (int j = 0; j < 2000; j++) // if (bin[i][j] < 9) bin[i][j] = 0; for (int i = 0; i < 360; i++) { for (int j = 0; j < 2000; j++) // tmpsum += bin[i][j]; if (tmpsum < bin[i][j]) tmpsum = bin[i][j]; if ((tmpsum > sum4) || (tmpsum > sum3) || (tmpsum > sum2 || (tmpsum > sum1))) { if (sum1 < sum2) {sum1 = sum2; phi1 = phi2;} if (sum2 < sum3) {sum2 = sum3; phi2 = phi3;} if (sum3 < sum4) {sum3 = sum4; phi3 = phi4;} sum4 = tmpsum; phi4 = i; tmpsum =0; } } FILE * f = fopen("/home/andrei/hough.txt", "w"); for (int i = 0; i < 360; i++) { for (int j = 0; j < 1000; j++) fprintf(f, "%i:, %i, ", i, bin[i][j]); fprintf(f, "\n"); } fclose(f);*/ this->pointList = pointList; m_width = width; m_height = height; p1 = new QPoint(); p2 = new QPoint(); } SkewAnalysis::~SkewAnalysis() { delete p1; delete p2; } signed int SkewAnalysis::getSkew() { int minLeftDist = 10000; int minRightDist = 0; for (int i = 0; i < pointList->count(); i++) { if (!(i%2)) { if (minLeftDist > pointList->at(i).x()) minLeftDist = pointList->at(i).x(); } else { if (minRightDist < pointList->at(i).x()) minRightDist = pointList->at(i).x(); } } minRightDist = m_width - minRightDist; signed int res; if (minRightDist > minLeftDist) { phi = getRightPhi(); } else { phi = getLeftPhi(); } res = (phi/(2*M_PI))*360+1; if (res > 45) return 90 - res; if (res < 45) return -(90 + res); return -res; } double SkewAnalysis::getPhi() { return getSkew()*2*M_PI/(double)360; //if (phi > 0.7854) return M_PI_2 - phi; //if (phi < 0.7854) return -(M_PI_2 + phi); } double SkewAnalysis::getRightPhi() { double phi = 0; int maxx = 0, maxy = 0, minx = 10000, miny = 10000; for (int i = 1; i < pointList->count(); i +=2) { if(maxx< pointList->at(i).x()) { maxx = pointList->at(i).x(); maxy = pointList->at(i).y(); } if(miny > pointList->at(i).y()) { minx = pointList->at(i).x(); miny = pointList->at(i).y(); } } phi = 0; if (maxy-miny < m_height - maxy) { miny = 0; for (int i = 1; i < pointList->count(); i +=2) if(miny < pointList->at(i).y()) { minx = pointList->at(i).x(); miny = pointList->at(i).y(); } } else { miny = 10000; for (int i = 1; i < pointList->count(); i +=2) if(miny > pointList->at(i).y()) { minx = pointList->at(i).x(); miny = pointList->at(i).y(); } } if (maxx-minx == 0) return 0; if (m_height/abs(maxx-minx) >=100 ) return 0; // if (maxy > miny) p1->setX(maxx); p1->setY(maxy); p2->setX(minx); p2->setY(miny); phi = atan((double)(maxy-miny)/(double)(maxx-minx)); //else //phi = atan((double)(miny - maxy)/(double)(maxx-minx)); // phi = - (M_PI_2 -phi); return phi; } double SkewAnalysis::getLeftPhi() { double phi = 0; int maxx = 0, maxy = 0, minx = 10000, miny = 10000; for (int i = 0; i < pointList->count(); i +=2) { if(minx > pointList->at(i).x()) { minx = pointList->at(i).x(); miny = pointList->at(i).y(); } if(maxy > pointList->at(i).y()) { maxx = pointList->at(i).x(); maxy = pointList->at(i).y(); } } phi = 0; if (miny < m_height - miny) { maxy = 0; for (int i = 0; i < pointList->count(); i +=2) if((maxy < pointList->at(i).y()) && (pointList->at(i).y() < 0.9*m_height)) { maxx = pointList->at(i).x(); maxy = pointList->at(i).y(); } } else { maxy = 10000; for (int i = 0; i < pointList->count(); i +=2) if((maxy > pointList->at(i).y()) && (pointList->at(i).y() < 0.9*m_height)) { maxx = pointList->at(i).x(); maxy = pointList->at(i).y(); } } p1->setX(maxx); p1->setY(maxy); p2->setX(minx); p2->setY(miny); if (maxx-minx == 0) return 0; if (m_height/abs(maxx-minx) >=100 ) return 0; phi = atan((double)(maxy-miny)/(double)(maxx-minx)); return phi; } QPixmap SkewAnalysis::drawTriangle(QPixmap &pm) { QImage img = pm.toImage(); QPainter p(&img); QPen pen; pen.setColor(QColor(255, 0, 0)); p.setPen(pen); p.drawLine(*p1, *p2); // p. return QPixmap::fromImage(img); } yagf-0.9.2.1/src/ccbuilder.cpp0000664000175000017500000004053012247205425016565 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009-2011 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include "ccbuilder.h" #include "settings.h" #include #include #define XDEBUG #ifdef XDEBUG #include #endif class Cropper { public: Cropper(CCBuilder * builder) { this->builder = builder; darksCount = 0; lightsCount = 0; minval = 0; maxval = 0; //clAltCount = 0; darktr = builder->generalBrightness; whitetr = 650; clBrighttoWidthtr = 0.1; } ~Cropper() {} QRect crop() { y1 = 0; int tolerance = 3; for (int y = 0; y < builder->h; y ++) { if (checkHorzLine(y)) { tolerance--; if (tolerance == 0) { y1 = y; break; } } else tolerance = 3; } y2 = builder->h-1; tolerance = 3; for (int y = y2; y >= 0; y--) { if (checkHorzLine(y)) { tolerance--; if (tolerance == 0) { y2 = y; break; } } else tolerance = 3; } x1 = 0; tolerance = 3; for (int x = x1; x < builder->w; x++) { if (checkVertLine(x)) { tolerance--; if (tolerance == 0) { x1 = x; break; } } else tolerance = 3; } x2 = builder->w-1; tolerance = 3; for (int x = x2; x >= 0; x--) { if (checkVertLine(x)) { tolerance--; if (tolerance == 0) { x2 = x; break; } } else tolerance = 3; } return QRect(x1, y1, x2-x1, y2-y1); } bool checkHorzLine(int y) { darksCount = 0; lightsCount = 0; minval = 800; maxval = 0; whitesCount = 0; //clAltCount = 0; whiteAlt = 0; //int maxlstripe = 0; //int currentlstripe = 0; QRgb * line = (QRgb *) builder->image.scanLine(y); //int curline =0; for (int i = 0; i < builder->w; i++) { int pixel = qRed(line[i]) + qGreen(line[i]) + qBlue(line[i]); if (pixel <= darktr) { darksCount++; // if (currentlstripe > maxlstripe) maxlstripe = currentlstripe; // currentlstripe = 0; } else { lightsCount++; // currentlstripe++; if (pixel >= whitetr) { whitesCount++; if (whiteAlt == 0) { whiteAlt = 1; clWhiteCount++; } } else whiteAlt = 0; } minval = pixel < minval ? pixel : minval; maxval = pixel > maxval ? pixel : maxval; } clBrighttoWidth = (qreal)lightsCount/builder->w; if (clBrighttoWidth <= clBrighttoWidthtr) return false; if (maxval - minval < 40) return false; //if (clAltCount < 10) // return false; //if (maxlstripe < 10) // return false; // if ((clWhiteCount > 0)&&(clWhiteCount < 3)) // return false; return true; } bool checkVertLine(int x) { darksCount = 0; lightsCount = 0; minval = 800; maxval = 0; whitesCount = 0; //clAltCount = 0; whiteAlt = 0; //int curline =0; for (int y = 0; y < builder->h; y++) { QRgb * line = (QRgb *) builder->image.scanLine(y); int pixel = qRed(line[x]) + qGreen(line[x]) + qBlue(line[x]); if (pixel <= darktr) { darksCount++; // if (curline) { // clAltCount++; // curline = 0; // } } else { lightsCount++; // if (!curline) { // clAltCount++; // curline = 1; // } if (pixel >= whitetr) { whitesCount++; if (whiteAlt == 0) { whiteAlt = 1; clWhiteCount++; } } else whiteAlt = 0; } minval = pixel < minval ? pixel : minval; maxval = pixel > maxval ? pixel : maxval; } clBrighttoWidth = (qreal)lightsCount/builder->h; if (clBrighttoWidth <= clBrighttoWidthtr) return false; if (maxval - minval < 40) return false; // if (clAltCount < 10) // return false; if ((clWhiteCount > 0)&&(clWhiteCount < 3)) return false; return true; } private: CCBuilder * builder; int darksCount; int lightsCount; int minval; int maxval; //int clAltCount; int whitesCount; int darktr; int whitetr; int whiteAlt; qreal clBrighttoWidth; qreal clBrighttoWidthtr; int clWhiteCount; int y1, y2, x1, x2; }; CCBuilder::CCBuilder(const QImage &img, QObject *parent) : QObject(parent) { if (img.isNull()) { w = h = 0; return; } image = img; image.convertToFormat(QImage::Format_RGB32); labels = NULL; //new quint32 [image.height()*image.width()]; flags = NULL; //new bool[image.height()]; //memset(flags, 0, sizeof(bool)*image.height()); skipNext = false; maxlabel = 1; w = image.width(); h = image.height(); } CCBuilder::~CCBuilder() { delete [] labels; delete [] flags; } int CCBuilder::width() { return w; } int CCBuilder::height() { return h; } void CCBuilder::compactLabels() { QList l; l.append(0); for( int i = 0; i < w; i++) for( int j = 0; j < h; j++) if (!l.contains(label(i,j))) l.append(label(i,j)); for( int i = 0; i < w; i++) for( int j = 0; j < h; j++) setLabel(i, j, l.indexOf(label(i,j))); } void CCBuilder::setGeneralBrightness(int value) { generalBrightness = value; } quint32 CCBuilder::label(int x, int y) { int index = y*w+x; if (index < w*h) return labels[index]; return 0; } int CCBuilder::labelChecked(int x, int y) { if ((x<0)||(y<0)) return 0; if ((x>=w)||(y>=h)) return 0; return labels[y*w+x]; } void CCBuilder::setLabel(int x, int y, int newValue) { recolor.replace(label(x, y), newValue); labels[y*w+x] = newValue; didRecolor = true; } void CCBuilder::relabelLineLR(int y) { for (int x = 0; x < w; x++) { if (labelChecked(x, y)) { int oc = labelChecked(x, y); if (recolor.at(labelChecked(x-1, y))) { int nc = recolor.at(labelChecked(x-1, y)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } if (recolor.at(labelChecked(x+1, y-1))) { int nc = recolor.at(labelChecked(x+1, y-1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } } else { if (recolor.at(labelChecked(x, y-1))) { int nc = recolor.at(labelChecked(x, y-1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } if (recolor.at(labelChecked(x-1, y-1))) { int nc = recolor.at(labelChecked(x-1, y-1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } if (recolor.at(labelChecked(x+1, y-1))) { int nc = recolor.at(labelChecked(x+1, y-1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } } } } } void CCBuilder::relabelLineRL(int y) { for (int x = w-1; x >= 0; x--) { if (labelChecked(x, y)) { int oc = labelChecked(x, y); if (recolor.at(labelChecked(x+1, y))) { int nc = recolor.at(labelChecked(x+1, y)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } if (recolor.at(labelChecked(x-1, y+1))) { int nc = recolor.at(labelChecked(x-1, y+1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } } else { if (recolor.at(labelChecked(x, y+1))) { int nc = recolor.at(labelChecked(x, y+1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } if (recolor.at(labelChecked(x+1, y+1))) { int nc = recolor.at(labelChecked(x+1, y+1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } if (recolor.at(labelChecked(x-1, y+1))) { int nc = recolor.at(labelChecked(x-1, y+1)); if (nc < oc) { setLabel(x, y, nc); oc = nc; } } } } } } bool CCBuilder::isForeground(QRgb value) { int b = qRed(value) + qGreen(value) + qBlue(value); int maxc = qRed(value) > qGreen(value) ? qRed(value) : qGreen(value); if (maxc < qBlue(value)) maxc = qBlue(value); //generalBrightness = (generalBrightness+b)/2; if ((b >= generalBrightness))// || (maxc >= maximumComponentBrightness)) return false; return true; } void CCBuilder::setMaximumColorComponent(int value) { maximumComponentBrightness = value; } void CCBuilder::initialScan() { recolor.clear(); recolor.append(0); scanFirstLineLR(); for (int j = 1; j < h; j++) { labelLeftmostPoint(j); scanLineLR(j); labelRightmostPoint(j); } } void CCBuilder::backwardScan() { bool rdid = false; didRecolor = false; relabelLineLR(h-1); rdid = rdid|didRecolor; skipNext = flags[h-1]; flags[h-1] = !didRecolor; skipNext = skipNext&flags[h-1]; for (int j = h-2; j >= 0; j--) { didRecolor = false; skipNext = skipNext&flags[j]; if (!skipNext) { relabelLineRL(j); rdid = rdid|didRecolor; } #ifdef DEBUG_CC else dcounter++; gcounter++; #endif skipNext = flags[j]; flags[j] = !didRecolor; skipNext = skipNext&flags[j]; } didRecolor = rdid; } void CCBuilder::forwardScan() { bool rdid = false; didRecolor = false; relabelLineLR(0); rdid = rdid|didRecolor; skipNext = flags[0]; flags[0] = !didRecolor; skipNext = skipNext&flags[0]; for (int j = 1; j < h; j++) { didRecolor = false; skipNext = skipNext&flags[j]; if (!skipNext) { relabelLineLR(j); rdid = rdid|didRecolor; } #ifdef DEBUG_CC else dcounter++; gcounter++; #endif skipNext = flags[j]; flags[j] = !didRecolor; skipNext = skipNext&flags[j]; } didRecolor = rdid; } int CCBuilder::labelCCs() { if (w*h == 0) return 0; Cropper cr(this); cropRect = cr.crop(); QImage tmp = image.copy(cropRect); image = tmp; w = image.width(); h = image.height(); if (w*h == 0) return 0; labels = new quint32 [image.height()*image.width()]; flags = new bool[image.height()]; memset(flags, 0, sizeof(bool)*image.height()); quint64 acc =0; for (int y =0; y < h; y++) { QRgb * line = (QRgb *) image.scanLine(y); for (int x = 0; x < w; x++) { int b = qRed(line[x]) + qGreen(line[x]) + qBlue(line[x]); acc += b; } } acc =acc/(h*w); /* ADHOC */ // if (acc < 200) // acc +=80; #ifdef DEBUG_CC dcounter = 0; gcounter = 0; #endif setGeneralBrightness(acc); int count = 0; initialScan(); didRecolor = true; int turn = 1; while (didRecolor) { didRecolor = false; if (turn) backwardScan(); else forwardScan(); turn = 1 - turn; count++; } #ifdef DEBUG_CC qDebug() << dcounter << gcounter; #endif return count; } void CCBuilder::scanFirstLineLR() { if (!(h*w)) return; QRgb * line = (QRgb *) image.scanLine(0); if (isForeground(line[0])) { labels[0] = maxlabel; recolor.append(maxlabel); maxlabel++; } else labels[0] = 0; for (int i = 1; i < w; i++) { if (isForeground(line[i])) { if (labels[i-1]) labels[i] = labels[i-1]; else { labels[i] = maxlabel; recolor.append(maxlabel); maxlabel++; } } else labels[i] = 0; } } void CCBuilder::labelLeftmostPoint(int y) { QRgb * line = (QRgb *) image.scanLine(y); if (isForeground(line[0])) { int prlabel = labels[w*(y-1)]; if (prlabel) labels[w*y] = prlabel; else { if ((w > 1) && (labels[w*(y-1) + 1] > 0)) { labels[w*y] = labels[w*(y-1) + 1]; } else { labels[w*y] = maxlabel; recolor.append(maxlabel); maxlabel++; } } } else labels[w*y] = 0; } void CCBuilder::labelRightmostPoint(int y) { if (w < 2) return; QRgb * line = (QRgb *) image.scanLine(y); if (isForeground(line[w-1])) { if (labels[w*y-1]) labels[w*(y+1) - 1] = labels[w*y-1]; else { if (labels[w*y-2]) { labels[w*(y+1) - 1] = labels[w*y-2]; } else if (labels[w*(y+1)-2]) { labels[w*(y+1) - 1] = labels[w*(y+1)-2]; } else { labels[w*(y+1) - 1] = maxlabel; recolor.append(maxlabel); maxlabel++; } } } else labels[w*(y+1) - 1] = 0; } void CCBuilder::scanLineLR(int y) { QRgb * line = (QRgb *) image.scanLine(y); for (int i = 1; i < w-1; i++) { labels[w*y + i] = 0; int nc; int oc; oc = maxlabel; if (isForeground(line[i])) { nc = labels[w*(y - 1) + i]; if (nc) { labels[w*y + i] = nc; oc = nc; } nc = labels[w*(y - 1) + i - 1]; if ((nc) && (nc <= oc)) { labels[w*y + i] = nc; oc = nc; } nc = labels[w*(y - 1) + i + 1]; if ((nc) && (nc <= oc)) { labels[w*y + i] = nc; oc = nc; } nc = labels[w*y + i - 1]; if ((nc) && (nc <= oc)) { labels[w*y + i] = nc; oc = nc; } if (!labels[w*y + i]) { labels[w*y + i] = maxlabel; recolor.append(maxlabel); maxlabel++; } } } } QRect CCBuilder::crop() { Cropper cropper(this); return cropper.crop(); } int CCBuilder::getGB() { return generalBrightness; } yagf-0.9.2.1/src/texteditor.h0000664000175000017500000000324512250140707016466 0ustar parallelsparallels/* YAGF - cuneiform and tesseract OCR graphical front-end Copyright (C) 2009-2013 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #ifndef TEXTEDITOR_H #define TEXTEDITOR_H #include #include #include "spellchecker.h" class TextEditor : public QTextEdit { Q_OBJECT public: explicit TextEditor(QWidget *parent = 0); ~TextEditor(); bool textSaved(); bool spellCheck(const QString &lang); void unSpellCheck(); void enumerateDicts(); bool hasDict(const QString &shname); public slots: void saveText(); protected: void keyPressEvent ( QKeyEvent * e ); void wheelEvent ( QWheelEvent * e ); private slots: void contextMenuRequested(const QPoint& point); void enlargeFont(); void decreaseFont(); void updateSP(); void replaceWord(); void copyAvailable(bool yes); void textChanged(); void copyClipboard(); private: void saveHtml(QFile *file); private: SpellChecker spellChecker; bool hasCopy; bool mTextSaved; }; #endif // TEXTEDITOR_H yagf-0.9.2.1/src/utils.cpp0000664000175000017500000000336412247205425015775 0ustar parallelsparallels/* YAGF - cuneiform OCR graphical front-end Copyright (C) 2009 Andrei Borovsky This program 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. This program 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 this program. If not, see . */ #include #include #include #include #include #include #include "utils.h" QString extractFileName(const QString &path) { QFileInfo fi(path); return fi.fileName(); } QString extractFilePath(const QString &path) { QFileInfo fi(path); QString s = fi.dir().path(); if (!s.endsWith("/")) s += '/'; return s; } QString extractDigits(const QString &fn) { bool extracting = FALSE; QString result = ""; for (int i = 0; i < fn.size(); i++) if ((fn.at(i) >= '0') && (fn.at(i) <= '9')) { extracting = TRUE; result += fn.at(i); } else { if (extracting) break; } return result; } bool findProgram(const QString &name) { QStringList sl = QString(getenv("PATH")).split(":"); QFileInfo fi; for (int i = 0; i < sl.count(); i++) { fi.setFile(sl.at(i), name); if (fi.exists()) return true; } return false; } yagf-0.9.2.1/ChangeLog0000664000175000017500000000771712250140054015110 0ustar parallelsparallels* Tue Dec 5 2013 Andrei Borovsky - 0.9.2.1 - Added interface language switcher * Mon Sep 3 2012 Andrei Borovsky - 0.9.2 - Workspace may now be saved as a project - Prepare for recognition button - Small bug fixes and improvements * Fri Apr 20 2012 Andrei Borovsky - 0.9.1 - Some minor bug fixes and improvements * Sun Apr 15 2012 Andrei Borovsky - 0.9.1 - Toolbar icons size togling options is added - YAGF now stores its private data in according with freedesktop.org standard for configuration files * Mon Apr 09 2012 Andrei Borovsky - 0.9.1 - Text-splitting capability for splitting text into blocks automatically is added * Tue Feb 28 2012 Andrei Borovsky - 0.9 - Genral program restructure. Images are loaded and processed much faster. * Mon Feb 27 2012 Andrei Borovsky - 0.9 - Hebrew support added - corrected word suggestion added to the text editor context menu. * Sun Feb 26 2012 Andrei Borovsky - 0.9 - Automatic cropping of the loaded images added * Sun Dec 22 2011 Stefan Grthe - 0.9 - German Gothic and Swedish Gothic recognition is added (requires tesseract 3+) * Sun Dec 22 2011 Andrei Borovsky - 0.9 - Hebrew recognition support added (requires tesseract 3.0.1+) * Fri Dec 16 2011 Andrei Borovsky - 0.8.9 - Deskewing images improved - Pasting i,ages from clipboard added - Automatic text selection added (experimental) - Some minor bug fixes and improvements * Sun Aug 28 2011 Andrei Borovsky - 0.8.7 - Tesseract support added - PDF import added - Dictionary selection bug fixed * Sun Feb 20 2011 Andrei Borovsky - 0.8.6 - Some bugs fixed - The default recognition language is now set according to the user's locale - Spellchecker buton now indicates if the dictioanry for the selected language is available - Skew correction feature (beta stage) is added * Tue Jan 25 2011 Andrei Borovsky - 0.8.5 - Many bug fixes thanks to Skip - Spellchecker improved - Bulgarian language added (at last!;) - Blocks and entire image may be saved to a file * Sat Jan 08 2011 Andrei Borovsky - 0.8.4 - Serbian, Croatian, and Slovenian languages are added (at last!) - Ability to open several files at ones is added - Ability to drag and drop files on the sidebar is added - Sidebar now remembers blocks selected on all the pages * Sun Dec 26 2010 Andrei Borovsky - 0.8.2 - multiple blocks in image are now supported * Sun Aug 16 2009 Andrei Borovsky - 0.8.1 - batch recognition added * Wed Aug 5 2009 Andrei Borovsky - 0.8.0 - text selection blocks are now resizable - images management bar is added * Wed Aug 5 2009 Andrei Borovsky - 0.8.0 - text selection blocks are now resizable - images management bar is added * Sat Jul 25 2009 Andrei Borovsky - 0.7.1 - scaling and rotation is kept between images in the series - images and text may be scaled by Ctrl + mouse wheel or by Ctrl + [+]/[-] keys. * Sun Jul 19 2009 Andrei Borovsky - 0.7.0 - spell-checking is added - saving to html with images is added * Fri Jul 17 2009 Andrei Borovsky - 0.6.2 - merged the patches with the appropriate files - removed unnessesary ldconfig call * Wed Jul 15 2009 Kyrill Detinov - 0.6.1 - update to 0.6.1 - fixed build in x86-64 - corrected build requires * Sat Jun 20 2009 Kyrill Detinov - 0.5.0 - change compiling outside of the source tree * Mon Jun 15 2009 Kyrill Detinov - 0.5.0 - fix requires Qt version * Mon Jun 08 2009 Kyrill Detinov - 0.5.0 - correct build requires: libqt4-devel <= 4.4.3, cmake >= 2.6 * Fri Jun 05 2009 Kyrill Detinov - 0.5.0 - initial package created yagf-0.9.2.1/YAGF.desktop0000664000175000017500000000153212247205425015456 0ustar parallelsparallels[Desktop Entry] Type=Application Categories=Qt;Office;OCR; Exec=yagf %F Icon=yagf Terminal=false StartupNotify=true MimeType=image/png;image/jpeg;image/bmp;image/tiff;image/gif;image/x-portable-pixmap;image/x-portable-graymap;image/x-portable-bitmap; Name=YAGF Name[ru]=YAGF Name[lt]=YAGF Name[pl]=YAGF Name[de]=YAGF GenericName=OCR text recognition GenericName[ru]=Распознавание текста GenericName[lt]=ENTER YOUR TRANSLATION HERE GenericName[pl]=ENTER YOUR TRANSLATION HERE GenericName[de]=OCR Texterkennung Comment=Graphical frontend for Cuneiform and Tesseract Comment[ru]=Графическая оболочка для Cuneiform и Tesseract Comment[lt]=Grafinė teksto atpažinimo programos Cuneiform sąsaja Comment[pl]=Grafinė teksto atpažinimo programos Cuneiform sąsaja Comment[de]=Graphische Benutzeroberfläche zu Cuneiform yagf-0.9.2.1/COPYING0000664000175000017500000010451312247205425014373 0ustar parallelsparallels GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program 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. This program 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 this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . yagf-0.9.2.1/DESCRIPTION0000664000175000017500000000162712247205425015050 0ustar parallelsparallelsYAGF is a graphical front-end for cuneiform and tesseract OCR tools. With YAGF you can open already scanned image files or obtain new images via XSane (scanning results are automatically passed to YAGF). Once you have a scanned image you can prepare it for recognition, select particular image areas for recognition, set the recognition language and so no. Recognized text is displayed in a editor window where it can be corrected, saved to disk or copied to clipboard. YAGF also provides some facilities for a multi-page recognition (see the online help for more details). Building YAGF requires: qt4 development tools version > 4.5 libaspell development package Running YAGF requires: Qt 4.5 or later, aspell Of course it is desirable to have xsane installed. PDFimport is done using either pdftoppm or gs utilities. Make sure at least one of these is installed if you are going to recognize text from PDFs. yagf-0.9.2.1/INSTALL0000664000175000017500000000174712247205425014376 0ustar parallelsparallelsThese are generic installation instructions. You will need CMake to build YAGF from sources. There are two modes for building YAGF with CMake: in-source and out-source. The out-source mode is preferred. To build YAGF in this mode follow these instructions: make a directory for your build (for example yagf-build). Assuming your yagf-build directory is in the same directory as the yagf directory you can command: cd yagf-build cmake ../yagf make sudo make install You can now remove the yagf-build directory. In order to perform an in-source build you should issue this simple set of commands: cd yagf cmake ./ make sudo make install While YAGF may be built to support multi-image TIFFs, I have found that it conflicts with JPEG input libraries. This may be reso;ved in the future. If you want to build the program with multi-image TIFF support, open CMakeLists.txt file and change the line set(MPTIFF_SUPPORT false) to set(MPTIFF_SUPPORT true) and then build the program as descried above. yagf-0.9.2.1/AUTHORS0000664000175000017500000000116412247205425014406 0ustar parallelsparallelsDevelopers: Andrei Borovsky Icon designers: YAGF theme: Andrei Borovsky Crystal Project theme: Everaldo Coelho Oxygen theme: Oxygen Team Human-O2 theme: Schollidesign Translators: German: Stefan Garthe Lithuanian: Donatas Glodenis Polish: Andrzej Januszkiewicz Russian: Andrei Borovsky Ukrainian: Olexa Stasevych yagf-0.9.2.1/CMakeLists.txt0000664000175000017500000001345512250076445016106 0ustar parallelsparallelsproject(yagf C CXX) cmake_minimum_required(VERSION 2.6.0) # Setting MPTIFF_SUPPORT to true turns on the multi-image tiffs support. In this case YAGF requires various libtiff development files # that may are incompatible with the Qt's JPEG reader on some systems. So Qt (and YAGF) may lose the ability to read jpegs. # You have been warned! set(MPTIFF_SUPPORT false) if(MPTIFF_SUPPORT) set(TIFFIO_SRC src/qxttiffiohandler.cpp) endif(MPTIFF_SUPPORT) if (NOT DEFINED ${CMAKE_INSTALL_PREFIX}) set(CPACK_INSTALL_PREFIX /usr/) set (CMAKE_INSTALL_PREFIX /usr/) endif() # following 2 lines define where interface translations will be installed set(QML_DESTINATION share/yagf/translations/) set(QML_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}) add_definitions( -DQML_INSTALL_PATH="${QML_INSTALL_PREFIX}${QML_DESTINATION}") set(SOURCES src/main.cpp src/mainform.cpp src/qgraphicsinput.cpp src/utils.cpp src/qxtunixsignalcatcher.cpp src/spellchecker.cpp src/BlockAnalysis.cpp src/PageAnalysis.cpp src/SkewAnalysis.cpp src/CCAnalysis.cpp src/qxtgraphicsproxywidget.cpp src/popplerdialog.cpp src/pdfextractor.cpp src/pdf2ppt.cpp src/ghostscr.cpp src/configdialog.cpp src/advancedconfigdialog.cpp src/ccbuilder.cpp src/analysis.cpp src/qsnippet.cpp src/sidebar.cpp src/droplabel.cpp src/projectmanager.cpp src/settings.cpp src/texteditor.cpp src/tblock.cpp src/tpage.cpp src/tpagecollection.cpp ${TIFFIO_SRC} src/scanner.cpp src/imagebooster.cpp src/forcelocaledialog.cpp) set(HEADERS src/settings.h) set(INT_SOURCES src/preload.c) set(UIS src/mainform.ui src/popplerdialog.ui src/configdialog.ui src/advancedconfigdialog.ui src/forcelocaledialog.ui) set(MOC_HEADERS src/mainform.h src/qxtunixsignalcatcher.h src/qxtunixscinternal.h src/qgraphicsinput.h src/qxtgraphicsproxywidget.h src/qxtgraphicsview.h src/popplerdialog.h src/pdfextractor.h src/pdf2ppt.h src/configdialog.h src/advancedconfigdialog.h src/ccbuilder.h src/qsnippet.h src/sidebar.h src/droplabel.h src/projectmanager.h src/texteditor.h src/tblock.h src/tpage.h src/tpagecollection.h src/scanner.h src/imagebooster.h src/forcelocaledialog.h) set (yagf_RCCS src/yagf.qrc) set(QM_FILES ${CMAKE_BINARY_DIR}/yagf_ru.qm ${CMAKE_BINARY_DIR}/yagf_lt.qm ${CMAKE_BINARY_DIR}/yagf_de.qm ${CMAKE_BINARY_DIR}/yagf_pl.qm ${CMAKE_BINARY_DIR}/yagf_uk.qm) set (LIB_PATH_SUFFIX ) add_definitions(-Wall -g) find_package(Qt4 4.6 REQUIRED) find_package(ASPELL REQUIRED) if(MPTIFF_SUPPORT) add_definitions(-DTIFF_IO) find_package(TIFF REQUIRED) endif(MPTIFF_SUPPORT) include(${QT_USE_FILE}) qt4_wrap_ui(UI_HEADERS ${UIS}) qt4_wrap_cpp(MOC_SRCS ${MOC_HEADERS}) qt4_add_resources(yagf_RCC_SRCS ${yagf_RCCS}) include_directories( ${CMAKE_BINARY_DIR} ${PROJECT_SOURCE_DIR}/src) add_executable(yagf ${SOURCES} ${UI_HEADERS} ${MOC_SRCS} ${yagf_RCC_SRCS} ${QM_FILES}) add_library(xspreload SHARED ${INT_SOURCES}) target_link_libraries(xspreload dl) target_link_libraries(yagf ${QT_LIBRARIES} ${ASPELL_LIBRARIES} ${TIFF_LIBRARIES}) add_custom_target(translations DEPENDS ${QM_FILES}) qt4_add_translation(${CMAKE_BINARY_DIR}/yagf_ru.qm ${PROJECT_SOURCE_DIR}/src/mainform.cpp ${PROJECT_SOURCE_DIR}/src/popplerdialog.cpp ${MOC_SRCS} ${UI_HEADERS} ${PROJECT_SOURCE_DIR}/src/translations/yagf_ru.ts) qt4_add_translation(${CMAKE_BINARY_DIR}/yagf_lt.qm ${PROJECT_SOURCE_DIR}/src/mainform.cpp ${PROJECT_SOURCE_DIR}/src/popplerdialog.cpp ${MOC_SRCS} ${UI_HEADERS} ${PROJECT_SOURCE_DIR}/src/translations/yagf_lt.ts) qt4_add_translation(${CMAKE_BINARY_DIR}/yagf_de.qm ${PROJECT_SOURCE_DIR}/src/mainform.cpp ${PROJECT_SOURCE_DIR}/src/popplerdialog.cpp ${MOC_SRCS} ${UI_HEADERS} ${PROJECT_SOURCE_DIR}/src/translations/yagf_de.ts) qt4_add_translation(${CMAKE_BINARY_DIR}/yagf_pl.qm ${PROJECT_SOURCE_DIR}/src/mainform.cpp ${PROJECT_SOURCE_DIR}/src/popplerdialog.cpp ${MOC_SRCS} ${UI_HEADERS} ${PROJECT_SOURCE_DIR}/src/translations/yagf_pl.ts) qt4_add_translation(${CMAKE_BINARY_DIR}/yagf_uk.qm ${PROJECT_SOURCE_DIR}/src/mainform.cpp ${PROJECT_SOURCE_DIR}/src/popplerdialog.cpp ${MOC_SRCS} ${UI_HEADERS} ${PROJECT_SOURCE_DIR}/src/translations/yagf_uk.ts) #QT4_CREATE_TRANSLATION(yagf_ru.qm src/mainform.cpp ${MOC_SRCS} ${UI_HEADERS} src/yagf_ru.ts) #set(CMAKE_INSTALL_PREFIX /usr/) install_targets(/bin/ yagf) if (CMAKE_SIZEOF_VOID_P EQUAL 8) set (LIB_PATH_SUFFIX 64) set_property (GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) endif(CMAKE_SIZEOF_VOID_P EQUAL 8) install_targets(/lib${LIB_PATH_SUFFIX}/yagf xspreload) install(FILES ${QM_FILES} DESTINATION ${QML_DESTINATION}) #install(FILES COPYING DESCRIPTION README AUTHORS ChangeLog DESTINATION share/yagf/) install(FILES yagf.png DESTINATION share/pixmaps/) install(FILES yagf.png DESTINATION share/icons/hicolor/96x96/apps/) install(FILES YAGF.desktop DESTINATION share/applications/) #set(CPACK_PACKAGE_FILE_NAME yagf) set(CPACK_PACKAGE_VENDOR "Andrei Borovsky, anb@symmetrica.net") set(CPACK_PACKAGE_CONTACT ${CPACK_PACKAGE_VENDOR}) set(CPACK_SYSTEM_NAME "i586") set(CPACK_BINARY_DEB ON) set(CPACK_BINARY_RPM ON) set(CPACK_BINARY_STGZ ON) set(CPACK_BINARY_TGZ OFF) set(CPACK_BINARY_TZ OFF) set(CPACK_BINARY_TBZ2 OFF) set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Graphical front-end for cuneiform and tesseract OCR tools") set(CPACK_PACKAGE_VERSION 0.9.1) set(CPACK_PACKAGE_VERSION_MAJOR "0") set(CPACK_PACKAGE_VERSION_MINOR "9") set(CPACK_PACKAGE_VERSION_PATCH "1") set(CPACK_STRIP_FILES bin/yagf bin/libyagfpreload) set(CPACK_SOURCE_TBZ2 "OFF") set(CPACK_SOURCE_TGZ "ON") set(CPACK_SOURCE_TZ "OFF") set(CPACK_SOURCE_INSTALLED_DIRECTORIES "${CMAKE_SOURCE_DIR}/yagf-${CPACK_PACKAGE_VERSION}/;/") set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/COPYING) set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/DESCRIPTION) set(CPACK_RESOURCE_FILE_README ${CMAKE_SOURCE_DIR}/README) set(DEBIAN_PACKAGE_SECTION "text processing") set(CPACK_RPM_PACKAGE_LICENSE "GPL v.3.0") set (CPACK_RPM_PACKAGE_REQUIRES "libqt > 4.5") include(CPack) yagf-0.9.2.1/yagf.png0000664000175000017500000002345212247205425014776 0ustar parallelsparallelsPNG  IHDR``w8 pHYs ^ IDATxyW}9oouERkkIH10,fMbL '3)LI&m'!)K6#@j}Ι?n#[R5>U[w=l6l6l6l6l6l6l6l6l?/׾Ї1da{l y9̱˱w'_-">1Tc5RFmyr_d,*.;O>?L d?9Xk;Jt(rFH` 9qRΏile@[g!?d^ ȑ\p\U)>< I 6O֍{ot{֡9;ļ*گΎR\~v.p}C`=Xc @JCP98|l^ordwW<~Wg )Õ6_@}P5% /(_<{ݝt_^nƺ1* سم\ tRq!!Ak[AE ]rxW:eC7cl>z\Zy } >I JCA;0> vzG6š3|#~c{YGyK?kOz"+w$@)੧`rJExT*Ѝac(o&%_WYW?L!){M8_1c8pq(oχ\=4:pbN@]EWMU2Lֹ5|$ H3aUE8 հ7}c%0}(x ͇sPgfFaj<[-X ScXv;oc$y 'fywck0Q v37\ ;n;3jup4V1ȝ5Jq(nVV1ks^[SX\g{QGr 5_>AiӰk B.;0 "1{`|C26IP.*vjkbc53 Ig.@:WpmuMp.o\#_ m@Շ;]05Wp5F&Ó[͓W**M" 2AF@ 07 /KAQR1yaїK fznn?Մ2w@م=;0&FH:yXƌM8uھVX%;|rUTH^~`0&5utn \.B?M|fW#ann{& 1$fd aJ$P.B.@9qrS$G>9Լ:ݬI8rۭo09 W|u;ǪP# A,  pMJ,b  %In-uL01@&8)oz-|oWGwAX 9e̶"rp9 ,ANsx,!yX"-1$ %E# HYCIcd}x\^ŐCNo}o:sI7b(; #ꙚYe K.2`Szw]Ȩ mD]F. EER*#Q"'r,i rZ]9WF!+P-f)(9ᑕFȼmVCB#1@"5ktwΣ>1+5Y2*,EI%ܴ44,U v'ɰfDLxuh:q l(A';'!vaTHzQ\Q:(6,ȕjs~Iw OOYViH[\.ZJ/`MX4$ kmD@/uf@*({*D06=ݳlP UC=&X لݣSVÈlt=<)I(n.IpJ4G F|@/ Ila•~;Nkaik9=(D.^zf|@ >:ЮO(p 5EM:Hm/uZd !.(bYdH%@` H.H|4>497wN!t a2IXJPNTaңj R{h۠$AK__9k+~>?(#p=gRDmjs (-*ItQql;WAz N_ʣd;i!*x@b-dM t0H)e|2JB|$CڋFeza ݤʣg!š[*G-^(TpgO":)L&t`üp $5|=DKO>O>{AÝ0HC%0uU;|?׿;}qw"`l7|OGx W?{tW|@o fG c6X`,,#Tc]Fk[=P><8>ZR6RoY$8yqdՅ<| IOKBu8]<z _b4,ysbi {.x '١2^N8uc$mQHg3x<{ _(rk 6l!^|.6A\4>[ lo7bxI/HZ[73f{|IL,7/,.dI&3bXU1Ok3KJCq5!js8XB>/8vbx*Rc?Q4J E?8~'Ufޑ6OIps5'gٱLR Do . Sɏ6p /cN8} U )52D%"X7o- xˈblv;уW0fW|>9r>v^}05Up.%*GJĉ'  NXkLwFC;CɧϽ#8# _č3<.d9RU8P)a ?_I_{FFhcOƒ0\C cmtFי*Qہv%LMG  8yj:O@ TbKE|/zR4d KXs8Ƣ$Q+םѭs0]X_CS;H/PQu=靖o~t!Br\ߋ}[~;b4 IĠQ Kg$yYsPa]IZN^q\\ a Cκot$eoB"x62I4ܝFP@ Co߈P ysb' dTuHw1q;llv{6}/w~+!r@`ةpn\clq'@NLyG9 Po~_llE(#9,@A4rɒ\d6Gt8'ÅUơ}.9!;y]+A-v5ln@)Ih1w`HqD;~WQWF(7ACZ8I2d$EU;VYB8N ^D)153za!0/jfRcUHt0:`@W,IgcмT1($waD\'WfkM]!(`΢ ty[!l[+sdw~YrPPߙ:vʀA2@SHtJiZ(ͳhT `47ɺ> ڈ;dVA[ %bbFZeX߀Rޏ} 3|\*:#laY@!PBr{Ld8~f2\%&- dH7SW'yq2]㐤 Yo,d,Rqtt:EVc a^`C_<_qŰCW!i"'+@D! !bT/ (%=2Rۤ#I#JEk ҈+-:|KT]~O{)%$avb#XY<<"yXڂ Uwf$}'~[ 4E*| X]^1C)h -b8iM LGxʂآYyL|>OW_L/%َY| Ն6 YDw ui{&CcqQp./m$$:?rS%B0:D&4BcD_h10m+8Bd+ tbC;~H+M T2J!ֱNܧ*lZ&yLMN<[MNÌ`fn$AmsKCbrRR rVa=͙_GV{j2څc1"`q>ȕ9xrG &aqXI8FU3 :Êj-p+("6%~\لNZw~jtPE)*дe@KxdN@^A>RnG!֦RIoRY_B? 'A :R<`uJg|FX!4r^\v)A@k$` 8h`"9 ^G8kx` 1:EX]YA b"qXo ~TFϓU%:[a:."P@ZtɥP1) I&8򲋭 Az$Q\Tc VKȧO!6 xGGsq@a߉;f1[/sCF&P .k$F h2cpƈZHbh9&%.MQ $+1QXA}D4 3|zfW'Z?<p j#7Zac#&2OQ[O;cQRaGamPIDAT+=JJ"1H2lp@C5Tȳqgm xYf NX]h> +z1nLa{1rIk=IR36M1Jppb&_B?4B;ǖҰb$_ݵʳooY>Qdu̞ÎujctK9@gǠ4 YA`ܴ]=[ wBI@"< Ϝ+P.BQ{|-/5^>c-4zd2цXQ-%C"R9Jscqv5XZacxzqE>O#|NQRv|}s[xQc#oOMPN# ҈{~ fE]*b#pazɰ,YhxO~H\Bn-='i0(1v]c+S0Ve{ΝD_{%LB.^b(]@lt`YDsN-B;N[0QҭM>9~e,wynEl5Zlի|n°l|r [ An."+B+`y wҺ `8t˿Ʒ:m`-o..rkNr{kPtYlBBy'ar;Rf܍vIz,n 0S g?~VfKOhA'bfqcx 1̌ w0h5"AݳZg,$u{7vY"]O=|rw~~t+wy(rTL_&b0޿ޅ"̔a#ƎV ۃႷcE01U&[?;:9׮mZmn[o0qa fQaYh{|z9 (0(acT?Gz$WnlE~>0{}# Cx hhy.ߘ/ΞV?WUףo5JWojq(agHrE(CpkKN?2Wc=Z?=e:Yѯ1WFDmǟe>es|6H=Fw{r'9 O7CO^;z2M0K? {\ p64~㽨s)Ա KKd܃-,;GZ?(p>fmfmfmfmfmfmfmfmfm v՝(IENDB`