Главное > Программирование
Модифицирование Scan Tailor
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", да и кое-какие проекты я поотключал при сборке СТ - чтобы быстрее компилился.
Короче, моя сборка СТ - это больше как прототип пока, если делать её всерьёз - надо взять снова чистые исходники, всё как положено там сделать, накатить аккуратно все правки и т.п.
Навигация
Перейти к полной версии