Главное > Программирование

Модифицирование Scan Tailor

(1/523) > >>

monday2000:
Я решил попробовать модифицировать Scan Tailor путём правки его исходных кодов.

Собрался СТ легко, в точном соответствии с инструкцией по сборке http://scantailor.git.sourceforge.net/git/gitweb.cgi?p=scantailor/scantailor;a=blob_plain;f=packaging/windows/readme.ru.txt

С помощью автора программы Tulon'а я сделал пока что такие исправления:

Оба исправления касаются ручного dewarping.
 
1. Когда в окне dewarping создаётся синяя сетка, то на её самой верхней и самой нижней синих горизонтальных линиях рисуется по 5 красных точек. Это неудобно - мне нужны лишь 2 - самая левая и самая правая, остальные 3 я всегда вручную убираю - прежде чем ставить свои красные точки. Вот код исправления:
 
C:\build\scantailor-0.9.11.1\filters\output\DewarpingView.cpp
 

--- Код: ---void
DewarpingView::initNewSpline(XSpline& spline, QPointF const& p1, QPointF const& p2)
{
    QLineF const line(p1, p2);
    spline.appendControlPoint(line.p1(), 0);
    //spline.appendControlPoint(line.pointAt(1.0/4.0), 1);
    //spline.appendControlPoint(line.pointAt(2.0/4.0), 1);
    //spline.appendControlPoint(line.pointAt(3.0/4.0), 1);
    spline.appendControlPoint(line.p2(), 0);
}
--- Конец кода ---

закомментировано создание 3 ненужных мне красных точек
 
2. Когда в режиме распрямления строк "Отключено" начинаешь вручную менять положение синих линий / красных точек - то режим распрямления строк не переключается при этом сам с "Отключено" на "Вручную". Приходится потом лезть в диалог и переключать самому - а это лишние телодвижения. Повторенные на десятках страниц, они начинают раздражать. В общем, вот код исправления:
 
C:\build\scantailor-0.9.11.1\filters\output\OptionsWidget.cpp
 

--- Код: ---void
OptionsWidget::distortionModelChanged(dewarping::DistortionModel const& model)
{
    m_ptrSettings->setDistortionModel(m_pageId, model);
   
    // Note that OFF remains OFF while AUTO becomes MANUAL.
    /*if (m_dewarpingMode == DewarpingMode::AUTO)*/ {
   
        m_ptrSettings->setDewarpingMode(m_pageId, DewarpingMode::MANUAL);
        m_dewarpingMode = DewarpingMode::MANUAL;
        updateDewarpingDisplay();
    }
}
--- Конец кода ---

Закомментировано мною - комментариями вида /* .... */

3. Перемещение всей самой верхней (нижней) синей горизонтальной линии за мышью за её крайнюю (левую или правую) красную точку. Работает это так: В окне dewarping, там, где синяя сетка, можно, нажав и удерживая Ctrl, двигать за крайнюю красную точку всю её горизонтальную синюю линию. Это даёт небольшое удобство при ручном dewarping.

Вот код исправления:


--- Код: ---C:\build\scantailor-0.9.11.1\interaction\DraggableObject.h
 
class DraggableObject
{
public:
.........
 
virtual void dragContinuation(QPointF const& mouse_pos) {   
        m_dragContinuationCallback(mouse_pos);
    }
// добавляем перегруженную функцию - с маской нажатого Ctrl
virtual void dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask) {}
.........
}
 
C:\build\scantailor-0.9.11.1\interaction\DraggablePoint.h
 
class DraggablePoint : public DraggableObject
{
public:
........
typedef boost::function<
    //void (QPointF const&)
    void (QPointF const&, Qt::KeyboardModifiers mask)
> MoveRequestCallback;
 
............
//virtual void dragContinuation(QPointF const& mouse_pos);
virtual void dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask);
...........
protected:
............
//virtual void pointMoveRequest(QPointF const& widget_pos) {
virtual void pointMoveRequest(QPointF const& widget_pos, Qt::KeyboardModifiers mask) {
    //m_moveRequestCallback(widget_pos);
    m_moveRequestCallback(widget_pos, mask);
}
..........
}
 
C:\build\scantailor-0.9.11.1\interaction\DraggablePoint.cpp
 
void
//DraggablePoint::dragContinuation(QPointF const& mouse_pos)
DraggablePoint::dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask)
{
    //pointMoveRequest(mouse_pos + m_pointRelativeToMouse);
    pointMoveRequest(mouse_pos + m_pointRelativeToMouse, mask);
}
 
C:\build\scantailor-0.9.11.1\interaction\ObjectDragHandler.cpp
 
void
ObjectDragHandler::onMouseMoveEvent(
    QMouseEvent* event, InteractionState& interaction)
{
    if (interaction.capturedBy(m_interaction)) {
        //m_pObj->dragContinuation(QPointF(0.5, 0.5) + event->pos());
        m_pObj->dragContinuation(QPointF(0.5, 0.5) + event->pos(), event->modifiers());
    }
}
 
C:\build\scantailor-0.9.11.1\interaction\InteractiveXSpline.h
 
class InteractiveXSpline : public InteractionHandler
{
...........
private:
...........
//void controlPointMoveRequest(int idx, QPointF const& pos);
void controlPointMoveRequest(int idx, QPointF const& pos, Qt::KeyboardModifiers mask);
...........
}
 
C:\build\scantailor-0.9.11.1\interaction\InteractiveXSpline.cpp
 
void
InteractiveXSpline::setSpline(XSpline const& spline)
{
..........
 
new_control_points[i].point.setMoveRequestCallback(
    //boost::bind(&InteractiveXSpline::controlPointMoveRequest, this, i, _1)
    boost::bind(&InteractiveXSpline::controlPointMoveRequest, this, i, _1, _2) // это самое сложное место - но мне его Tulon подсказал
..........
}
 
void
//InteractiveXSpline::controlPointMoveRequest(int idx, QPointF const& pos)
InteractiveXSpline::controlPointMoveRequest(int idx, QPointF const& pos, Qt::KeyboardModifiers mask)
{
........
 
(mc(mat, 2, 2)*mc(pt, 2, 1)).write(pt);   
//m_spline.moveControlPoint(i, pt + origin); // original line - now commented
//начало добавления
if (mask != Qt::ControlModifier) // default behavior
    m_spline.moveControlPoint(i, pt + origin);
else // Control key is currently pressed
{               
    Vec2d shift_y = storage_pt - old_pos;               
    QPointF new_position = m_spline.controlPointPosition(i) + shift_y;               
    new_position.setX(m_spline.controlPointPosition(i).x());               
    m_spline.moveControlPoint(i, new_position);
}
//конец добавления
}
} else {
.........
}
--- Конец кода ---

monday2000:
Я добавил в (свою копию) Scan Tailor генерацию разделённых субсканов - для "смешанных" (Mixed) сканов. Т.е. это то, для чего я сделал в своё время программу ST Split - которая теперь становится (наконец-таки) ненужной. Вот код исправления:

--- Код: ---C:\build\scantailor-0.9.11.1\ui\MainWindow.ui

<widget class="QMenu" name="menuDebug">
    <property name="title">
     <string>Tools</string>
    </property>
    <addaction name="actionFixDpi"/>
    <addaction name="actionRelinking"/>
    <addaction name="separator"/>
    <addaction name="actionDebug"/>
    <addaction name="separator"/>
    <addaction name="actionSettings"/>
    <addaction name="actionSplitMixed"/> // added
   </widget>
..........

<action name="actionDebug">
   <property name="checkable">
    <bool>true</bool>
   </property>
   <property name="checked">
    <bool>false</bool>
   </property>
   <property name="text">
    <string>Debug Mode</string>
   </property>
  </action>
  <action name="actionSplitMixed"> // the whole node "actionSplitMixed" is added
    <property name="checkable">
      <bool>true</bool>
    </property>
    <property name="checked">
      <bool>false</bool>
    </property>
    <property name="text">
      <string>Split mixed</string>
    </property>
  </action>

...............

Now compile the whole solution to make sure that in
C:\build\scantailor-build\ui_MainWindow.h
is automatically generated this:

class Ui_MainWindow
{
public:
    QAction *actionDebug;
    QAction *actionSplitMixed; // auto-generated from C:\build\scantailor-0.9.11.1\ui\MainWindow.ui
...............................

C:\build\scantailor-0.9.11.1\MainWindow.cpp

BackgroundTaskPtr
MainWindow::createCompositeTask(
PageInfo const& page, int const last_filter_idx, bool const batch, bool debug)
{
.................
if (last_filter_idx >= m_ptrStages->outputFilterIdx()) {
output_task = m_ptrStages->outputFilter()->createTask(
//page.id(), m_ptrThumbnailCache, m_outFileNameGen, batch, debug
page.id(), m_ptrThumbnailCache, m_outFileNameGen, batch, debug, actionSplitMixed->isChecked()
);
debug = false;
.................

C:\build\scantailor-0.9.11.1\filters\output\Filter.h

class Filter : public AbstractFilter
{
DECLARE_NON_COPYABLE(Filter)
public:
...........
IntrusivePtr<Task> createTask(
PageId const& page_id,
IntrusivePtr<ThumbnailPixmapCache> const& thumbnail_cache,
OutputFileNameGenerator const& out_file_name_gen,
//bool batch, bool debug);
bool batch, bool debug, bool split_mixed);
........................

C:\build\scantailor-0.9.11.1\filters\output\Filter.cpp

IntrusivePtr<Task>
Filter::createTask(
PageId const& page_id,
IntrusivePtr<ThumbnailPixmapCache> const& thumbnail_cache,
OutputFileNameGenerator const& out_file_name_gen,
//bool const batch, bool const debug)
bool const batch, bool const debug, bool split_mixed)
{
ImageViewTab lastTab(TAB_OUTPUT);
if (m_ptrOptionsWidget.get() != 0)
lastTab = m_ptrOptionsWidget->lastTab();
return IntrusivePtr<Task>(
new Task(
IntrusivePtr<Filter>(this), m_ptrSettings,
thumbnail_cache, page_id, out_file_name_gen,
//lastTab, batch, debug
lastTab, batch, debug, split_mixed
)
);
}
........................

C:\build\scantailor-0.9.11.1\filters\output\Task.h

class Task : public RefCountable
{
DECLARE_NON_COPYABLE(Task)
public:
Task(IntrusivePtr<Filter> const& filter,
IntrusivePtr<Settings> const& settings,
IntrusivePtr<ThumbnailPixmapCache> const& thumbnail_cache,
PageId const& page_id, OutputFileNameGenerator const& out_file_name_gen,
//ImageViewTab last_tab, bool batch, bool debug);
ImageViewTab last_tab, bool batch, bool debug, bool split_mixed);

virtual ~Task();

FilterResultPtr process(
TaskStatus const& status, FilterData const& data,
QPolygonF const& content_rect_phys);
bool m_split_mixed;//added
private:
........................

C:\build\scantailor-0.9.11.1\filters\output\Task.cpp

Task::Task(IntrusivePtr<Filter> const& filter,
IntrusivePtr<Settings> const& settings,
IntrusivePtr<ThumbnailPixmapCache> const& thumbnail_cache,
PageId const& page_id, OutputFileNameGenerator const& out_file_name_gen,
//ImageViewTab const last_tab, bool const batch, bool const debug)
ImageViewTab const last_tab, bool const batch, bool const debug, bool split_mixed)
: m_ptrFilter(filter),
m_ptrSettings(settings),
m_ptrThumbnailCache(thumbnail_cache),
m_pageId(page_id),
m_outFileNameGen(out_file_name_gen),
m_lastTab(last_tab),
m_batchProcessing(batch),
//m_debug(debug)
m_debug(debug),
m_split_mixed(split_mixed)//added
{
if (debug) {
m_ptrDbg.reset(new DebugImages);
}
}

....................................

// added by monday2000
template<typename MixedPixel>
void GenerateSubscans(QImage& source_img, QImage& subscan1, QImage& subscan2)
{
int const width = source_img.width();
int const height = source_img.height();

MixedPixel* source_line = reinterpret_cast<MixedPixel*>(source_img.bits());
int const source_stride = source_img.bytesPerLine() / sizeof(MixedPixel);

subscan1 = QImage(source_img.width(),source_img.height(),QImage::Format_Mono);
subscan2 = QImage(source_img.width(),source_img.height(),source_img.format());

subscan1.setDotsPerMeterX(source_img.dotsPerMeterX());
subscan1.setDotsPerMeterY(source_img.dotsPerMeterY());
subscan2.setDotsPerMeterX(source_img.dotsPerMeterX());
subscan2.setDotsPerMeterY(source_img.dotsPerMeterY());

QVector<QRgb> bw_palette(2);
bw_palette[0] = qRgb(0, 0, 0);
bw_palette[1] = qRgb(255, 255, 255);
subscan1.setColorTable(bw_palette);

if (subscan2.format() == QImage::Format_Indexed8)
{ //createGrayscalePalette() from C:\build\scantailor-0.9.11.1\imageproc\Grayscale.cpp
QVector<QRgb> palette(256);
for (int i = 0; i < 256; ++i) palette[i] = qRgb(i, i, i);
subscan2.setColorTable(palette);
}

uchar* subscan1_line = subscan1.bits();
int const subscan1_stride = subscan1.bytesPerLine();

MixedPixel* subscan2_line = reinterpret_cast<MixedPixel*>(subscan2.bits());
int const subscan2_stride = subscan2.bytesPerLine() / sizeof(MixedPixel);

uint32_t tmp_white_pixel = 0xffffffff;
MixedPixel mask = static_cast<MixedPixel>(0x00ffffff);

for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{ //this line of code was suggested by Tulon:
if ((source_line[x] & mask) == 0 || (source_line[x] & mask) == mask) // BW
{
uint8_t value1 = static_cast<uint8_t>(source_line[x]);
//BW SetPixel from http://djvu-soft.narod.ru/bookscanlib/023.htm
value1 ? subscan1_line[x >> 3] |= (0x80 >> (x & 0x7)) : subscan1_line[x >> 3] &= (0xFF7F >> (x & 0x7));
subscan2_line[x] = static_cast<MixedPixel>(tmp_white_pixel);
}
else // non-BW
{
uint8_t value = static_cast<uint8_t>(tmp_white_pixel);
//BW SetPixel from http://djvu-soft.narod.ru/bookscanlib/023.htm
value ? subscan1_line[x >> 3] |= (0x80 >> (x & 0x7)) : subscan1_line[x >> 3] &= (0xFF7F >> (x & 0x7));
subscan2_line[x] = source_line[x];
}
}
source_line += source_stride;
subscan1_line += subscan1_stride;
subscan2_line += subscan2_stride;
}
}
// end of added by monday2000

.......................

FilterResultPtr
Task::process(
TaskStatus const& status, FilterData const& data,
QPolygonF const& content_rect_phys)
{
.....................

if (!need_reprocess) {
..................

if (write_speckles_file && speckles_img.isNull()) {
// Even if despeckling didn't actually take place, we still need
// to write an empty speckles file.  Making it a special case
// is simply not worth it.
BinaryImage(out_img.size(), WHITE).swap(speckles_img);
}

bool invalidate_params = false;
// start of modification by monday2000
//if (!TiffWriter::writeImage(out_file_path, out_img)) {
// invalidate_params = true;  
//} else {
// deleteMutuallyExclusiveOutputFiles();
//}
// if Mixed Output and Split Mixed then
// if an output file has picture zones split it into 2 subscans.
QString const file_name(m_outFileNameGen.fileNameFor(m_pageId));
QString pic_dir = m_outFileNameGen.outDir() + "\\pic"; //folder for background subscans
QString subscan2_path = QDir(pic_dir).absoluteFilePath(file_name); //file of the background subscan

QImage subscan1;
QImage subscan2;

if (render_params.mixedOutput() && m_split_mixed)
{
if (out_img.format() == QImage::Format_Indexed8)
GenerateSubscans<uint8_t>(out_img, subscan1, subscan2);

else {
assert(out_img.format() == QImage::Format_RGB32
|| out_img.format() == QImage::Format_ARGB32);

GenerateSubscans<uint32_t>(out_img, subscan1, subscan2);
}

//if (!TiffWriter::writeImage(out_file_path, out_img)) {
if (!TiffWriter::writeImage(out_file_path, subscan1)) {
invalidate_params = true;
} else {
QDir().mkdir(pic_dir);
TiffWriter::writeImage(subscan2_path, subscan2);

deleteMutuallyExclusiveOutputFiles();
}
}
else
{
if (!TiffWriter::writeImage(out_file_path, out_img)) {
invalidate_params = true;  
} else {
deleteMutuallyExclusiveOutputFiles();
if (QFile().exists(subscan2_path))
QFile().remove(subscan2_path);
}
}
// end of added

if (write_automask) {
.....................

--- Конец кода ---

Работает это примерно так:

В (моей копии) Scan Tailor появился новый пункт в меню: Инструменты - Split mixed. Это - помечаемый пункт меню, т.е. на нём можно выставить галку (обозначающую как бы "включено").

Установленная галка означает, что режим вывода разделённых сканов включён, снятая - обычное поведение программы.

Разделение сканов осуществляется функцией GenerateSubscans, вызываемой (в случае, если стоит галка Split mixed) непосредственно перед записью готового обработанного скана в выходной TIF-файл. Т.е. другими словами, разделение субсканов происходит самой последней операцией - прямо перед записью в выходной файл. Передний субскан записывается вместо обычного скана - под тем же именем, только (естественно) в чёрно-белом режиме, в папке out создаётся папка "pic", и туда записываются соответствующие задние субсканы - одноимённые передним.

Всё это почти не тестировалось - так что глюки и падения не исключаются.

Вот собранный с этой фичей Scan Tailor:

http://rghost.ru/43030118 (4,51 МБ)

yuree:
Па-си-ба! Буду завтра тестить на работе, там у меня хрюша)

ПыСы. Потестил сейчас дома, на семёрке 32-й, идёт без лагов и вылетов.

$Shorox:
monday2000,
В вашей версии у меня частично не работает регулировка "Вручную" в "Полезная область".  Работает она только если цеплять мышью за уголок полезной области (т.е. если цепляешь мышью за углы). Если цеплять за стороны, то они не регулируются.
OS Windows 7x64

monday2000:
$Shorox
Спасибо, у меня такая же точно проблема. Посмотрел по исходникам и нашёл решение довольно быстро. Этот глюк возник из-за фичи "перемещение линии с Ctrl" - я добавил параметр маски в класс DraggableObject и в дочерний ему класс DraggablePoint (точнее, в виртуальную функцию класса DraggableObject), но я не учёл, что у класса DraggableObject есть ещё один дочерний ему класс - DraggableLineSegment. И его надо было тоже изменить аналогично изменениям в DraggablePoint. Вот эти изменения:

--- Код: ---C:\build\scantailor-0.9.11.1\interaction\DraggableLineSegment.h

class DraggableLineSegment : public DraggableObject
{
public:
..........
typedef boost::function<
//void (QLineF const& line)
void (QLineF const& line, Qt::KeyboardModifiers mask)
> MoveRequestCallback;
..........

//virtual void dragContinuation(QPointF const& mouse_pos);
virtual void dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask);
.............
protected:
..............
//virtual void lineSegmentMoveRequest(QLineF const& line) {
virtual void lineSegmentMoveRequest(QLineF const& line, Qt::KeyboardModifiers mask) {
//m_moveRequestCallback(line);
m_moveRequestCallback(line, mask);
}

C:\build\scantailor-0.9.11.1\interaction\DraggableLineSegment.cpp

void
//DraggableLineSegment::dragContinuation(QPointF const& mouse_pos)
DraggableLineSegment::dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask)
{
//lineSegmentMoveRequest(m_initialLinePos.translated(mouse_pos - m_initialMousePos));
lineSegmentMoveRequest(m_initialLinePos.translated(mouse_pos - m_initialMousePos), mask);
}
--- Конец кода ---
Да, ну и в DraggableObject я убрал добавленную мною перегруженную виртуальную функцию - и просто добавил в имеющуюся реквизит маски:

--- Код: ---C:\build\scantailor-0.9.11.1\interaction\DraggableObject.h

class DraggableObject
{
public:
.........

//virtual void dragContinuation(QPointF const& mouse_pos) {
virtual void dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask) {
m_dragContinuationCallback(mouse_pos);
}
.........
}
--- Конец кода ---

В общем, инструкция по фиче  "перемещение линии с Ctrl" обновлена, и  полностью она теперь выглядит так:

--- Код: ---C:\build\scantailor-0.9.11.1\interaction\DraggableObject.h

class DraggableObject
{
public:
.........

//virtual void dragContinuation(QPointF const& mouse_pos) {
virtual void dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask) {
m_dragContinuationCallback(mouse_pos);
}
.........
}

C:\build\scantailor-0.9.11.1\interaction\DraggablePoint.h

class DraggablePoint : public DraggableObject
{
public:
........
typedef boost::function<
//void (QPointF const&)
void (QPointF const&, Qt::KeyboardModifiers mask)
> MoveRequestCallback;

............
//virtual void dragContinuation(QPointF const& mouse_pos);
virtual void dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask);
...........
protected:
............
//virtual void pointMoveRequest(QPointF const& widget_pos) {
virtual void pointMoveRequest(QPointF const& widget_pos, Qt::KeyboardModifiers mask) {
//m_moveRequestCallback(widget_pos);
m_moveRequestCallback(widget_pos, mask);
}
..........
}

C:\build\scantailor-0.9.11.1\interaction\DraggablePoint.cpp

void
//DraggablePoint::dragContinuation(QPointF const& mouse_pos)
DraggablePoint::dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask)
{
//pointMoveRequest(mouse_pos + m_pointRelativeToMouse);
pointMoveRequest(mouse_pos + m_pointRelativeToMouse, mask);
}

C:\build\scantailor-0.9.11.1\interaction\ObjectDragHandler.cpp

void
ObjectDragHandler::onMouseMoveEvent(
QMouseEvent* event, InteractionState& interaction)
{
if (interaction.capturedBy(m_interaction)) {
//m_pObj->dragContinuation(QPointF(0.5, 0.5) + event->pos());
m_pObj->dragContinuation(QPointF(0.5, 0.5) + event->pos(), event->modifiers());
}
}

C:\build\scantailor-0.9.11.1\interaction\InteractiveXSpline.h

class InteractiveXSpline : public InteractionHandler
{
...........
private:
...........
//void controlPointMoveRequest(int idx, QPointF const& pos);
void controlPointMoveRequest(int idx, QPointF const& pos, Qt::KeyboardModifiers mask);
...........
}

C:\build\scantailor-0.9.11.1\interaction\InteractiveXSpline.cpp

void
InteractiveXSpline::setSpline(XSpline const& spline)
{
..........

new_control_points[i].point.setMoveRequestCallback(
//boost::bind(&InteractiveXSpline::controlPointMoveRequest, this, i, _1)
boost::bind(&InteractiveXSpline::controlPointMoveRequest, this, i, _1, _2)
..........
}

void
//InteractiveXSpline::controlPointMoveRequest(int idx, QPointF const& pos)
InteractiveXSpline::controlPointMoveRequest(int idx, QPointF const& pos, Qt::KeyboardModifiers mask)
{
........

(mc(mat, 2, 2)*mc(pt, 2, 1)).write(pt);
//m_spline.moveControlPoint(i, pt + origin); // original line - now commented
//начало добавления
if (mask != Qt::ControlModifier) // default behavior
m_spline.moveControlPoint(i, pt + origin);
else // Control key is currently pressed
{
Vec2d shift_y = storage_pt - old_pos;
QPointF new_position = m_spline.controlPointPosition(i) + shift_y;
new_position.setX(m_spline.controlPointPosition(i).x());
m_spline.moveControlPoint(i, new_position);
}
//конец добавления
}
} else {
.........
}

C:\build\scantailor-0.9.11.1\interaction\DraggableLineSegment.h

class DraggableLineSegment : public DraggableObject
{
public:
..........
typedef boost::function<
//void (QLineF const& line)
void (QLineF const& line, Qt::KeyboardModifiers mask)
> MoveRequestCallback;
..........

//virtual void dragContinuation(QPointF const& mouse_pos);
virtual void dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask);
.............
protected:
..............
//virtual void lineSegmentMoveRequest(QLineF const& line) {
virtual void lineSegmentMoveRequest(QLineF const& line, Qt::KeyboardModifiers mask) {
//m_moveRequestCallback(line);
m_moveRequestCallback(line, mask);
}

C:\build\scantailor-0.9.11.1\interaction\DraggableLineSegment.cpp

void
//DraggableLineSegment::dragContinuation(QPointF const& mouse_pos)
DraggableLineSegment::dragContinuation(QPointF const& mouse_pos, Qt::KeyboardModifiers mask)
{
//lineSegmentMoveRequest(m_initialLinePos.translated(mouse_pos - m_initialMousePos));
lineSegmentMoveRequest(m_initialLinePos.translated(mouse_pos - m_initialMousePos), mask);
}

--- Конец кода ---

Вот перекомпилированный ST - уже подправленный:
http://rghost.ru/43062070
Кстати, там не только полезная область не двигалась - но и резак тоже.
Что-то с переводом не то - он кое-где слетел в моей сборке СТ, и консольную версию я не собираю - а там тоже надо что-то подправить - под мои фичи новые (если собирать консольную версию). Ну и tif-библиотеки я брал обычные при сборке СТ - а не те из главы по сборке СТ "Патчим libtiff", да и кое-какие проекты я поотключал при сборке СТ - чтобы быстрее компилился.

Короче, моя сборка СТ - это больше как прототип пока, если делать её всерьёз - надо взять снова чистые исходники, всё как положено там сделать, накатить аккуратно все правки и т.п.

Навигация

[0] Главная страница сообщений

[#] Следующая страница

Перейти к полной версии