3 // Copyright (C) 2012 by Werner Lemberg.
5 // This file is part of the ttfautohint library, and may only be used,
6 // modified, and distributed under the terms given in `COPYING'. By
7 // continuing to use, modify, or distribute this file you indicate that you
8 // have read `COPYING' and understand and accept it fully.
10 // The file `COPYING' mentioned in the previous paragraph is distributed
11 // with the ttfautohint library.
25 #include <ttfautohint.h>
28 // XXX Qt 4.8 bug: locale->quoteString("foo")
29 // inserts wrongly encoded quote characters
30 // into rich text QString
31 #if HAVE_QT_QUOTESTRING
32 # define QUOTE_STRING(x) locale->quoteString(x)
33 # define QUOTE_STRING_LITERAL(x) locale->quoteString(x)
35 # define QUOTE_STRING(x) "\"" + x + "\""
36 # define QUOTE_STRING_LITERAL(x) "\"" x "\""
40 Main_GUI::Main_GUI(int range_min
,
54 : hinting_range_min(range_min
),
55 hinting_range_max(range_max
),
57 gray_strong_stem_width(gray
),
58 gdi_cleartype_strong_stem_width(gdi
),
59 dw_cleartype_strong_stem_width(dw
),
60 increase_x_height(increase
),
61 ignore_restrictions(ignore
),
62 windows_compatibility(wincomp
),
64 hint_with_components(components
),
66 latin_fallback(fallback
),
78 setUnifiedTitleAndToolBarOnMac(true);
80 // XXX register translations somewhere and loop over them
81 if (QLocale::system().name() == "en_US")
84 locale
= new QLocale(QLocale::C
);
91 Main_GUI::closeEvent(QCloseEvent
* event
)
101 QMessageBox::about(this,
102 tr("About TTFautohint"),
103 tr("<p>This is <b>TTFautohint</b> version %1<br>"
104 " Copyright %2 2011-2012<br>"
105 " by Werner Lemberg <tt><wl@gnu.org></tt></p>"
107 "<p><b>TTFautohint</b> adds new auto-generated hints"
108 " to a TrueType font or TrueType collection.</p>"
111 " <a href='http://www.freetype.org/FTL.TXT'>FreeType"
112 " License (FTL)</a> or"
113 " <a href='http://www.freetype.org/GPL.TXT'>GNU"
121 Main_GUI::browse_input()
123 // XXX remember last directory
124 QString file
= QFileDialog::getOpenFileName(
126 tr("Open Input File"),
130 input_line
->setText(QDir::toNativeSeparators(file
));
135 Main_GUI::browse_output()
137 // XXX remember last directory
138 QString file
= QFileDialog::getSaveFileName(
140 tr("Open Output File"),
145 output_line
->setText(QDir::toNativeSeparators(file
));
150 Main_GUI::check_min()
152 int min
= min_box
->value();
153 int max
= max_box
->value();
154 int limit
= limit_box
->value();
156 max_box
->setValue(min
);
158 limit_box
->setValue(min
);
163 Main_GUI::check_max()
165 int min
= min_box
->value();
166 int max
= max_box
->value();
167 int limit
= limit_box
->value();
169 min_box
->setValue(max
);
171 limit_box
->setValue(max
);
176 Main_GUI::check_limit()
178 int min
= min_box
->value();
179 int max
= max_box
->value();
180 int limit
= limit_box
->value();
182 max_box
->setValue(limit
);
184 min_box
->setValue(limit
);
189 Main_GUI::check_no_limit()
191 if (no_limit_box
->isChecked())
193 limit_label
->setEnabled(false);
194 limit_box
->setEnabled(false);
198 limit_label
->setEnabled(true);
199 limit_box
->setEnabled(true);
205 Main_GUI::check_no_increase()
207 if (no_increase_box
->isChecked())
209 increase_label
->setEnabled(false);
210 increase_box
->setEnabled(false);
214 increase_label
->setEnabled(true);
215 increase_box
->setEnabled(true);
221 Main_GUI::check_run()
223 if (input_line
->text().isEmpty() || output_line
->text().isEmpty())
224 run_button
->setEnabled(false);
226 run_button
->setEnabled(true);
231 Main_GUI::absolute_input()
233 QString input_name
= QDir::fromNativeSeparators(input_line
->text());
234 if (!input_name
.isEmpty()
235 && QDir::isRelativePath(input_name
))
237 QDir
cur_path(QDir::currentPath() + "/" + input_name
);
238 input_line
->setText(QDir::toNativeSeparators(cur_path
.absolutePath()));
244 Main_GUI::absolute_output()
246 QString output_name
= QDir::fromNativeSeparators(output_line
->text());
247 if (!output_name
.isEmpty()
248 && QDir::isRelativePath(output_name
))
250 QDir
cur_path(QDir::currentPath() + "/" + output_name
);
251 output_line
->setText(QDir::toNativeSeparators(cur_path
.absolutePath()));
257 Main_GUI::check_filenames(const QString
& input_name
,
258 const QString
& output_name
)
260 if (!QFile::exists(input_name
))
262 QMessageBox::warning(
265 tr("The file %1 cannot be found.")
266 .arg(QUOTE_STRING(QDir::toNativeSeparators(input_name
))),
272 if (input_name
== output_name
)
274 QMessageBox::warning(
277 tr("Input and output file names must be different."),
283 if (QFile::exists(output_name
))
285 int ret
= QMessageBox::warning(
288 tr("The file %1 already exists.\n"
290 .arg(QUOTE_STRING(QDir::toNativeSeparators(output_name
))),
291 QMessageBox::Yes
| QMessageBox::No
,
293 if (ret
== QMessageBox::No
)
302 Main_GUI::open_files(const QString
& input_name
,
304 const QString
& output_name
,
307 const int buf_len
= 1024;
310 *in
= fopen(qPrintable(input_name
), "rb");
313 strerror_r(errno
, buf
, buf_len
);
314 QMessageBox::warning(
317 tr("The following error occurred while opening input file %1:\n")
318 .arg(QUOTE_STRING(QDir::toNativeSeparators(input_name
)))
319 + QString::fromLocal8Bit(buf
),
325 *out
= fopen(qPrintable(output_name
), "wb");
328 strerror_r(errno
, buf
, buf_len
);
329 QMessageBox::warning(
332 tr("The following error occurred while opening output file %1:\n")
333 .arg(QUOTE_STRING(QDir::toNativeSeparators(output_name
)))
334 + QString::fromLocal8Bit(buf
),
346 struct GUI_Progress_Data
350 QProgressDialog
* dialog
;
355 gui_progress(long curr_idx
,
361 GUI_Progress_Data
* data
= (GUI_Progress_Data
*)user
;
363 if (num_sfnts
> 1 && curr_sfnt
!= data
->last_sfnt
)
365 data
->dialog
->setLabelText(QCoreApplication::translate(
367 "Auto-hinting subfont %1 of %2"
368 " with %3 glyphs...")
373 if (curr_sfnt
+ 1 == num_sfnts
)
375 data
->dialog
->setAutoReset(true);
376 data
->dialog
->setAutoClose(true);
380 data
->dialog
->setAutoReset(false);
381 data
->dialog
->setAutoClose(false);
384 data
->last_sfnt
= curr_sfnt
;
391 data
->dialog
->setLabelText(QCoreApplication::translate(
393 "Auto-hinting %1 glyphs...")
395 data
->dialog
->setMaximum(num_glyphs
- 1);
400 data
->dialog
->setValue(curr_idx
);
402 if (data
->dialog
->wasCanceled())
411 // return value 1 indicates a retry
414 Main_GUI::handle_error(TA_Error error
,
415 const unsigned char* error_string
,
420 if (error
== TA_Err_Canceled
)
422 else if (error
== TA_Err_Invalid_FreeType_Version
)
423 QMessageBox::critical(
426 tr("FreeType version 2.4.5 or higher is needed.\n"
427 "Are you perhaps using a wrong FreeType DLL?"),
430 else if (error
== TA_Err_Invalid_Font_Type
)
431 QMessageBox::warning(
434 tr("This font is not a valid font"
435 " in SFNT format with TrueType outlines.\n"
436 "In particular, CFF outlines are not supported."),
439 else if (error
== TA_Err_Already_Processed
)
440 QMessageBox::warning(
443 tr("This font has already been processed by TTFautohint."),
446 else if (error
== TA_Err_Missing_Legal_Permission
)
448 int yesno
= QMessageBox::warning(
451 tr("Bit 1 in the %1 field of the %2 table is set:"
452 " This font must not be modified"
453 " without permission of the legal owner.\n"
454 "Do you have such a permission?")
455 .arg(QUOTE_STRING_LITERAL("fsType"))
456 .arg(QUOTE_STRING_LITERAL("OS/2")),
457 QMessageBox::Yes
| QMessageBox::No
,
459 if (yesno
== QMessageBox::Yes
)
461 ignore_restrictions
= true;
465 else if (error
== TA_Err_Missing_Unicode_CMap
)
466 QMessageBox::warning(
469 tr("No Unicode character map."),
472 else if (error
== TA_Err_Missing_Symbol_CMap
)
473 QMessageBox::warning(
476 tr("No symbol character map."),
479 else if (error
== TA_Err_Missing_Glyph
)
480 QMessageBox::warning(
483 tr("No glyph for the key character"
484 " to derive standard stem width and height.\n"
485 "For the latin script, this key character is %1 (U+006F).\n"
487 "Set the %2 checkbox if you want to circumvent this test.")
488 .arg(QUOTE_STRING_LITERAL("o"))
489 .arg(QUOTE_STRING_LITERAL("symbol")),
493 QMessageBox::warning(
496 tr("Error code 0x%1 while autohinting font:\n")
497 .arg(error
, 2, 16, QLatin1Char('0'))
498 + QString::fromLocal8Bit((const char*)error_string
),
502 if (QFile::exists(output_name
) && remove(qPrintable(output_name
)))
504 const int buf_len
= 1024;
507 strerror_r(errno
, buf
, buf_len
);
508 QMessageBox::warning(
511 tr("The following error occurred while removing output file %1:\n")
512 .arg(QUOTE_STRING(QDir::toNativeSeparators(output_name
)))
513 + QString::fromLocal8Bit(buf
),
525 statusBar()->clearMessage();
527 QString input_name
= QDir::fromNativeSeparators(input_line
->text());
528 QString output_name
= QDir::fromNativeSeparators(output_line
->text());
529 if (!check_filenames(input_name
, output_name
))
532 // we need C file descriptors for communication with TTF_autohint
537 if (!open_files(input_name
, &input
, output_name
, &output
))
540 QProgressDialog dialog
;
541 dialog
.setCancelButtonText(tr("Cancel"));
542 dialog
.setMinimumDuration(1000);
543 dialog
.setWindowModality(Qt::WindowModal
);
545 const unsigned char* error_string
;
546 TA_Info_Func info_func
= info
;
547 GUI_Progress_Data gui_progress_data
= {-1, true, &dialog
};
550 info_data
.data
= NULL
; // must be deallocated after use
551 info_data
.data_wide
= NULL
; // must be deallocated after use
552 info_data
.data_len
= 0;
553 info_data
.data_wide_len
= 0;
555 info_data
.hinting_range_min
= min_box
->value();
556 info_data
.hinting_range_max
= max_box
->value();
557 info_data
.hinting_limit
= no_limit_box
->isChecked()
559 : limit_box
->value();
561 info_data
.gray_strong_stem_width
= gray_box
->isChecked();
562 info_data
.gdi_cleartype_strong_stem_width
= gdi_box
->isChecked();
563 info_data
.dw_cleartype_strong_stem_width
= dw_box
->isChecked();
565 info_data
.increase_x_height
= no_increase_box
->isChecked()
567 : increase_box
->value();
569 info_data
.windows_compatibility
= wincomp_box
->isChecked();
570 info_data
.pre_hinting
= pre_box
->isChecked();
571 info_data
.hint_with_components
= hint_box
->isChecked();
572 info_data
.latin_fallback
= fallback_box
->currentIndex();
573 info_data
.symbol
= symbol_box
->isChecked();
575 if (info_box
->isChecked())
577 int ret
= build_version_string(&info_data
);
579 QMessageBox::information(
582 tr("Can't allocate memory for <b>TTFautohint</b> options string"
583 " in <i>name</i> table."),
587 QMessageBox::information(
590 tr("<b>TTFautohint</b> options string"
591 " in <i>name</i> table too long."),
599 TTF_autohint("in-file, out-file,"
600 "hinting-range-min, hinting-range-max,"
602 "gray-strong-stem-width,"
603 "gdi-cleartype-strong-stem-width,"
604 "dw-cleartype-strong-stem-width,"
606 "progress-callback, progress-callback-data,"
607 "info-callback, info-callback-data,"
608 "ignore-restrictions,"
609 "windows-compatibility,"
611 "hint-with-components,"
613 "fallback-script, symbol",
615 info_data
.hinting_range_min
, info_data
.hinting_range_max
,
616 info_data
.hinting_limit
,
617 info_data
.gray_strong_stem_width
,
618 info_data
.gdi_cleartype_strong_stem_width
,
619 info_data
.dw_cleartype_strong_stem_width
,
621 gui_progress
, &gui_progress_data
,
622 info_func
, &info_data
,
624 info_data
.windows_compatibility
,
625 info_data
.pre_hinting
,
626 info_data
.hint_with_components
,
627 info_data
.increase_x_height
,
628 info_data
.latin_fallback
, info_data
.symbol
);
630 if (info_box
->isChecked())
632 free(info_data
.data
);
633 free(info_data
.data_wide
);
641 if (handle_error(error
, error_string
, output_name
))
645 statusBar()->showMessage(tr("Auto-hinting finished."));
649 // XXX distances are specified in pixels,
650 // making the layout dependent on the output device resolution
652 Main_GUI::create_layout()
657 QCompleter
* completer
= new QCompleter(this);
658 QFileSystemModel
* model
= new QFileSystemModel(completer
);
659 model
->setRootPath(QDir::rootPath());
660 completer
->setModel(model
);
662 QLabel
* input_label
= new QLabel(tr("&Input File:"));
663 input_line
= new Line_Edit
;
664 input_button
= new QPushButton(tr("Browse..."));
665 input_label
->setBuddy(input_line
);
666 // enforce rich text to get nice word wrapping
667 input_label
->setToolTip(
668 tr("<b></b>The input file, either a TrueType font (TTF),"
669 " TrueType collection (TTC), or a TrueType-based OpenType font."));
670 input_line
->setCompleter(completer
);
672 QLabel
* output_label
= new QLabel(tr("&Output File:"));
673 output_line
= new Line_Edit
;
674 output_button
= new QPushButton(tr("Browse..."));
675 output_label
->setBuddy(output_line
);
676 output_label
->setToolTip(
677 tr("<b></b>The output file, which will be essentially identical"
678 " to the input font but will contain new, generated hints."));
679 output_line
->setCompleter(completer
);
682 QGridLayout
* file_layout
= new QGridLayout
;
684 file_layout
->addWidget(input_label
, 0, 0, Qt::AlignRight
);
685 file_layout
->addWidget(input_line
, 0, 1);
686 file_layout
->addWidget(input_button
, 0, 2);
688 file_layout
->setRowStretch(1, 1);
690 file_layout
->addWidget(output_label
, 2, 0, Qt::AlignRight
);
691 file_layout
->addWidget(output_line
, 2, 1);
692 file_layout
->addWidget(output_button
, 2, 2);
697 QLabel
* min_label
= new QLabel(tr("Hint Set Range Mi&nimum:"));
698 min_box
= new QSpinBox
;
699 min_label
->setBuddy(min_box
);
700 min_label
->setToolTip(
701 tr("The minimum PPEM value of the range for which"
702 " <b>TTFautohint</b> computes <i>hint sets</i>."
703 " A hint set for a given PPEM value hints this size optimally."
704 " The larger the range, the more hint sets are considered,"
705 " usually increasing the size of the bytecode.<br>"
706 "Note that changing this range doesn't influence"
707 " the <i>gasp</i> table:"
708 " Hinting is enabled for all sizes."));
709 min_box
->setKeyboardTracking(false);
710 min_box
->setRange(2, 10000);
712 QLabel
* max_label
= new QLabel(tr("Hint Set Range Ma&ximum:"));
713 max_box
= new QSpinBox
;
714 max_label
->setBuddy(max_box
);
715 max_label
->setToolTip(
716 tr("The maximum PPEM value of the range for which"
717 " <b>TTFautohint</b> computes <i>hint sets</i>."
718 " A hint set for a given PPEM value hints this size optimally."
719 " The larger the range, the more hint sets are considered,"
720 " usually increasing the size of the bytecode.<br>"
721 "Note that changing this range doesn't influence"
722 " the <i>gasp</i> table:"
723 " Hinting is enabled for all sizes."));
724 max_box
->setKeyboardTracking(false);
725 max_box
->setRange(2, 10000);
728 // hinting and fallback controls
730 QLabel
* fallback_label
= new QLabel(tr("Fallback &Script:"));
731 fallback_box
= new QComboBox
;
732 fallback_label
->setBuddy(fallback_box
);
733 fallback_label
->setToolTip(
734 tr("This sets the fallback script module for glyphs"
735 " which <b>TTFautohint</b> can't map to a script automatically."));
736 fallback_box
->insertItem(0, tr("None"));
737 fallback_box
->insertItem(1, tr("Latin"));
742 limit_label
= new QLabel(tr("Hinting &Limit:"));
743 limit_box
= new QSpinBox
;
744 limit_label
->setBuddy(limit_box
);
745 limit_label
->setToolTip(
746 tr("Make <b>TTFautohint</b> add bytecode to the output font so that"
747 " sizes larger than this PPEM value are not hinted"
748 " (regardless of the values in the <i>gasp</i> table)."));
749 limit_box
->setKeyboardTracking(false);
750 limit_box
->setRange(2, 10000);
752 no_limit_box
= new QCheckBox(tr("No Hinting Limit"), this);
753 no_limit_box
->setToolTip(
754 tr("If switched on, <b>TTFautohint</b> adds no hinting limit"
755 " to the bytecode."));
758 // x height increase limit
760 increase_label
= new QLabel(tr("x Height In&crease Limit:"));
761 increase_box
= new QSpinBox
;
762 increase_label
->setBuddy(increase_box
);
763 increase_label
->setToolTip(
764 tr("For PPEM values in the range 5 < PPEM < <i>n</i>,"
765 " where <i>n</i> is the value selected by this spin box,"
766 " round up the font's x height much more often than normally.<br>"
767 "Use this if holes in letters like <i>e</i> get filled,"
769 increase_box
->setKeyboardTracking(false);
770 increase_box
->setRange(6, 10000);
772 no_increase_box
= new QCheckBox(tr("No x Height Increase"), this);
773 no_increase_box
->setToolTip(
775 " <b>TTFautohint</b> does not increase the x height."));
780 wincomp_box
= new QCheckBox(tr("Windows Com&patibility"), this);
781 wincomp_box
->setToolTip(
782 tr("If switched on, add two artificial blue zones positioned at the"
783 " <tt>usWinAscent</tt> and <tt>usWinDescent</tt> values"
784 " (from the font's <i>OS/2</i> table)."
785 " Use this if those values are tight,"
786 " and you are experiencing clipping during rendering."));
788 pre_box
= new QCheckBox(tr("Pr&e-hinting"), this);
790 tr("If switched on, the original bytecode of the input font"
791 " gets applied before <b>TTFautohint</b> starts processing"
792 " the outlines of the glyphs."));
794 hint_box
= new QCheckBox(tr("Hint With Co&mponents")
795 + " ", this); // make label wider
796 hint_box
->setToolTip(
797 tr("If switched on, <b>TTFautohint</b> hints composite glyphs"
798 " as a whole, including subglyphs."
799 " Otherwise, glyph components get hinted separately.<br>"
800 "Deactivating this flag reduces the bytecode size enormously,"
801 " however, it might yield worse results."));
803 symbol_box
= new QCheckBox(tr("S&ymbol Font"), this);
804 symbol_box
->setToolTip(
805 tr("If switched on, <b>TTFautohint</b> uses default values"
806 " for standard stem width and height"
807 " instead of deriving these values from the input font.<br>"
808 "Use this for fonts which don't contain glyphs"
809 " of a (supported) script."));
811 info_box
= new QCheckBox(tr("Add ttf&autohint Info"), this);
812 info_box
->setToolTip(
813 tr("If switched on, information about <b>TTFautohint</b>"
814 " and its calling parameters are added to the version string(s)"
815 " (name ID 5) in the <i>name</i> table."));
818 // stem width and positioning
820 QLabel
* stem_label
= new QLabel(tr("Strong Stem &Width and Positioning:"));
821 stem_label
->setToolTip(
822 tr("<b>TTFautohint</b> provides two different hinting algorithms"
823 " which can be selected for various hinting modes."
825 "<p><i>strong:</i> Position horizontal stems and snap stem widths"
826 " to integer pixel values. While making the output look crisper,"
827 " outlines become more distorted.</p>"
829 "<p><i>smooth:</i> Use discrete values for horizontal stems"
830 " and stem widths. This only slightly increases the contrast"
831 " but avoids larger outline distortion.</p>"));
833 gray_box
= new QCheckBox(tr("Grayscale"), this);
834 gray_box
->setToolTip(
835 tr("<b></b>Grayscale rendering, no ClearType activated."));
836 stem_label
->setBuddy(gray_box
);
838 gdi_box
= new QCheckBox(tr("GDI ClearType"), this);
840 tr("GDI ClearType rendering,"
841 " introduced in 2000 for Windows XP.<br>"
842 "The rasterizer version (as returned by the"
843 " GETINFO bytecode instruction) is in the range"
844 " 36 ≤ version < 38, and ClearType is enabled.<br>"
845 "Along the vertical axis, this mode behaves like B/W rendering."));
847 dw_box
= new QCheckBox(tr("DW ClearType"), this);
849 tr("DirectWrite ClearType rendering,"
850 " introduced in 2008 for Windows Vista.<br>"
851 "The rasterizer version (as returned by the"
852 " GETINFO bytecode instruction) is ≥ 38,"
853 " ClearType is enabled, and subpixel positioning is enabled also.<br>"
854 "Smooth rendering along the vertical axis."));
859 run_button
= new QPushButton(" "
861 + " "); // make label wider
866 QGridLayout
* gui_layout
= new QGridLayout
;
867 QFrame
* hline
= new QFrame
;
868 hline
->setFrameShape(QFrame::HLine
);
869 int row
= 0; // this counter simplifies inserting new items
871 gui_layout
->setRowMinimumHeight(row
, 10); // XXX urgh, pixels...
872 gui_layout
->setRowStretch(row
++, 1);
874 gui_layout
->addLayout(file_layout
, row
, 0, row
, -1);
875 gui_layout
->setRowStretch(row
++, 1);
877 gui_layout
->addWidget(hline
, row
, 0, row
, -1);
878 gui_layout
->setRowStretch(row
++, 1);
880 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
881 gui_layout
->setRowStretch(row
++, 1);
883 gui_layout
->addWidget(min_label
, row
, 0, Qt::AlignRight
);
884 gui_layout
->addWidget(min_box
, row
++, 1, Qt::AlignLeft
);
885 gui_layout
->addWidget(max_label
, row
, 0, Qt::AlignRight
);
886 gui_layout
->addWidget(max_box
, row
++, 1, Qt::AlignLeft
);
888 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
889 gui_layout
->setRowStretch(row
++, 1);
891 gui_layout
->addWidget(fallback_label
, row
, 0, Qt::AlignRight
);
892 gui_layout
->addWidget(fallback_box
, row
++, 1, Qt::AlignLeft
);
894 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
895 gui_layout
->setRowStretch(row
++, 1);
897 gui_layout
->addWidget(limit_label
, row
, 0, Qt::AlignRight
);
898 gui_layout
->addWidget(limit_box
, row
++, 1, Qt::AlignLeft
);
899 gui_layout
->addWidget(no_limit_box
, row
++, 1);
901 gui_layout
->addWidget(increase_label
, row
, 0, Qt::AlignRight
);
902 gui_layout
->addWidget(increase_box
, row
++, 1, Qt::AlignLeft
);
903 gui_layout
->addWidget(no_increase_box
, row
++, 1);
905 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
906 gui_layout
->setRowStretch(row
++, 1);
908 gui_layout
->addWidget(wincomp_box
, row
++, 1);
909 gui_layout
->addWidget(pre_box
, row
++, 1);
910 gui_layout
->addWidget(hint_box
, row
++, 1);
911 gui_layout
->addWidget(symbol_box
, row
++, 1);
912 gui_layout
->addWidget(info_box
, row
++, 1);
914 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
915 gui_layout
->setRowStretch(row
++, 1);
917 gui_layout
->addWidget(stem_label
, row
, 0, Qt::AlignRight
);
918 gui_layout
->addWidget(gray_box
, row
++, 1);
919 gui_layout
->addWidget(gdi_box
, row
++, 1);
920 gui_layout
->addWidget(dw_box
, row
++, 1);
922 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
923 gui_layout
->setRowStretch(row
++, 1);
925 gui_layout
->addWidget(run_button
, row
++, 1, Qt::AlignRight
);
927 // create dummy widget to register layout
928 QWidget
* main_widget
= new QWidget
;
929 main_widget
->setLayout(gui_layout
);
930 setCentralWidget(main_widget
);
931 setWindowTitle("TTFautohint");
936 Main_GUI::create_connections()
938 connect(input_button
, SIGNAL(clicked()), this,
939 SLOT(browse_input()));
940 connect(output_button
, SIGNAL(clicked()), this,
941 SLOT(browse_output()));
943 connect(input_line
, SIGNAL(textChanged(QString
)), this,
945 connect(output_line
, SIGNAL(textChanged(QString
)), this,
948 connect(input_line
, SIGNAL(editingFinished()), this,
949 SLOT(absolute_input()));
950 connect(output_line
, SIGNAL(editingFinished()), this,
951 SLOT(absolute_output()));
953 connect(min_box
, SIGNAL(valueChanged(int)), this,
955 connect(max_box
, SIGNAL(valueChanged(int)), this,
958 connect(limit_box
, SIGNAL(valueChanged(int)), this,
959 SLOT(check_limit()));
960 connect(no_limit_box
, SIGNAL(clicked()), this,
961 SLOT(check_no_limit()));
963 connect(no_increase_box
, SIGNAL(clicked()), this,
964 SLOT(check_no_increase()));
966 connect(run_button
, SIGNAL(clicked()), this,
972 Main_GUI::create_actions()
974 exit_act
= new QAction(tr("E&xit"), this);
975 exit_act
->setShortcuts(QKeySequence::Quit
);
976 connect(exit_act
, SIGNAL(triggered()), this, SLOT(close()));
978 about_act
= new QAction(tr("&About"), this);
979 connect(about_act
, SIGNAL(triggered()), this, SLOT(about()));
981 about_Qt_act
= new QAction(tr("About &Qt"), this);
982 connect(about_Qt_act
, SIGNAL(triggered()), qApp
, SLOT(aboutQt()));
987 Main_GUI::create_menus()
989 file_menu
= menuBar()->addMenu(tr("&File"));
990 file_menu
->addAction(exit_act
);
992 help_menu
= menuBar()->addMenu(tr("&Help"));
993 help_menu
->addAction(about_act
);
994 help_menu
->addAction(about_Qt_act
);
999 Main_GUI::create_status_bar()
1001 statusBar()->showMessage("");
1006 Main_GUI::set_defaults()
1008 min_box
->setValue(hinting_range_min
);
1009 max_box
->setValue(hinting_range_max
);
1011 fallback_box
->setCurrentIndex(latin_fallback
);
1013 limit_box
->setValue(hinting_limit
? hinting_limit
: hinting_range_max
);
1014 // handle command line option `--hinting-limit=0'
1017 hinting_limit
= max_box
->value();
1018 no_limit_box
->setChecked(true);
1021 increase_box
->setValue(increase_x_height
? increase_x_height
1022 : TA_INCREASE_X_HEIGHT
);
1023 // handle command line option `--increase-x-height=0'
1024 if (!increase_x_height
)
1026 increase_x_height
= TA_INCREASE_X_HEIGHT
;
1027 no_increase_box
->setChecked(true);
1030 if (windows_compatibility
)
1031 wincomp_box
->setChecked(true);
1033 pre_box
->setChecked(true);
1034 if (hint_with_components
)
1035 hint_box
->setChecked(true);
1037 symbol_box
->setChecked(true);
1039 info_box
->setChecked(true);
1041 if (gray_strong_stem_width
)
1042 gray_box
->setChecked(true);
1043 if (gdi_cleartype_strong_stem_width
)
1044 gdi_box
->setChecked(true);
1045 if (dw_cleartype_strong_stem_width
)
1046 dw_box
->setChecked(true);
1048 run_button
->setEnabled(false);
1055 check_no_increase();
1060 Main_GUI::read_settings()
1063 // QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
1064 // QSize size = settings.value("size", QSize(400, 400)).toSize();
1071 Main_GUI::write_settings()
1074 // settings.setValue("pos", pos());
1075 // settings.setValue("size", size());
1078 // end of maingui.cpp