3 // Copyright (C) 2012-2020 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.
24 #include FT_FREETYPE_H
29 #include <ttfautohint.h>
32 // XXX Qt 4.8 bug: locale->quoteString("foo")
33 // inserts wrongly encoded quote characters
34 // into rich text QString
35 #if HAVE_QT_QUOTESTRING
36 # define QUOTE_STRING(x) locale->quoteString(x)
37 # define QUOTE_STRING_LITERAL(x) locale->quoteString(x)
39 # define QUOTE_STRING(x) "\"" + x + "\""
40 # define QUOTE_STRING_LITERAL(x) "\"" x "\""
44 // Shorthand for `tr' using a local `TRDOMAIN'.
45 #define Tr(text) QCoreApplication::translate(TRDOMAIN, text)
48 typedef struct Tag_Names_
51 const char* description
;
55 // the available script tags and its descriptions are directly extracted
56 // from `ttfautohint-scripts.h'
58 #define SCRIPT(s, S, d, h, H, ss) \
61 const Tag_Names script_names
[] =
63 #include <ttfautohint-scripts.h>
68 // the available feature tags and its descriptions are directly extracted
69 // from `ttfautohint-coverages.h'
71 #define COVERAGE(n, N, d, t, t1, t2, t3, t4) \
74 const Tag_Names feature_names
[] =
76 #include <ttfautohint-coverages.h>
82 // a: Add ttf&autohint Info
83 // b: Add TTFA info ta&ble
84 // c: x Height In&crease Limit / No x Height In&crease
86 // e: Control Instructions Fil&e
88 // g: Stem Width and Positionin&g Mode
91 // j: Ad&just Subglyphs
92 // k: Fallbac&k Script
93 // l: Hinting &Limit / No Hinting &Limit
94 // m: Hint Co&mposites
95 // n: Hint Set Range Mi&nimum
97 // p: Windows Com&patibility
100 // s: Fallback &Stem Width / Default Fallback &Stem Width
101 // t: x Height Snapping Excep&tions
102 // u: Defa&ult Script
104 // w: &Watch Input Files
105 // x: Hint Set Range Ma&ximum
107 // z: Blue &Zone Reference Font
108 // :: Family Suffix&:
110 Main_GUI::Main_GUI(bool horizontal_layout
,
118 const char* exceptions
,
127 const char* fallback
,
133 : hinting_range_min(range_min
),
134 hinting_range_max(range_max
),
135 hinting_limit(limit
),
136 gray_stem_width_mode(gray
),
137 gdi_cleartype_stem_width_mode(gdi
),
138 dw_cleartype_stem_width_mode(dw
),
139 increase_x_height(increase
),
140 x_height_snapping_exceptions_string(exceptions
),
141 fallback_stem_width(stem_width
),
142 ignore_restrictions(ignore
),
143 windows_compatibility(wincomp
),
144 adjust_subglyphs(adjust
),
145 hint_composites(composites
),
147 detailed_info(detailed
),
148 fallback_scaling(scaling
),
149 family_suffix(suffix
),
154 fallback_do_scale(1),
159 for (i
= 0; script_names
[i
].tag
; i
++)
161 if (!strcmp("latn", script_names
[i
].tag
))
163 if (!strcmp("none", script_names
[i
].tag
))
167 // map default script and fallback script tags to indices
168 for (i
= 0; script_names
[i
].tag
; i
++)
169 if (!strcmp(dflt
, script_names
[i
].tag
))
171 default_script_idx
= script_names
[i
].tag
? i
: latn_script_idx
;
173 for (i
= 0; script_names
[i
].tag
; i
++)
174 if (!strcmp(fallback
, script_names
[i
].tag
))
176 fallback_script_idx
= script_names
[i
].tag
? i
: none_script_idx
;
178 x_height_snapping_exceptions
= NULL
;
180 // if the current input files have been updated
181 // we wait a given time interval, then we reload the files
182 file_watcher
= new QFileSystemWatcher(this);
183 timer
= new QTimer(this);
184 timer
->setInterval(1000); // XXX make this configurable
185 timer
->setSingleShot(true);
186 fileinfo_input_file
.setCaching(false);
187 fileinfo_control_file
.setCaching(false);
188 fileinfo_reference_file
.setCaching(false);
190 // XXX register translations somewhere and loop over them
191 if (QLocale::system().name() == "en_US")
192 locale
= new QLocale
;
194 locale
= new QLocale(QLocale::C
);
196 // For real numbers (both parsing and displaying) we only use `.' as the
197 // decimal separator; similarly, we don't want localized formats like a
198 // thousands separator for any number.
199 setlocale(LC_NUMERIC
, "C");
201 create_layout(horizontal_layout
);
202 create_connections();
210 setUnifiedTitleAndToolBarOnMac(true);
214 Main_GUI::~Main_GUI()
216 number_set_free(x_height_snapping_exceptions
);
223 Main_GUI::closeEvent(QCloseEvent
* event
)
233 QMessageBox::about(this,
234 tr("About TTFautohint"),
235 tr("<p>This is <b>TTFautohint</b> version %1<br>"
236 " Copyright %2 2011-2020<br>"
237 " by Werner Lemberg <tt><wl@gnu.org></tt></p>"
239 "<p><b>TTFautohint</b> adds new auto-generated hints"
240 " to a TrueType font or TrueType collection.</p>"
243 " <a href='https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/FTL.TXT'>FreeType"
244 " License (FTL)</a> or"
245 " <a href='https://git.savannah.gnu.org/cgit/freetype/freetype2.git/tree/docs/GPLv2.TXT'>GNU"
253 Main_GUI::browse_input()
255 // XXX remember last directory
256 QString file
= QFileDialog::getOpenFileName(
258 tr("Open Input Font"),
263 input_line
->setText(QDir::toNativeSeparators(file
));
268 Main_GUI::browse_output()
270 // XXX remember last directory
271 QString file
= QFileDialog::getSaveFileName(
273 tr("Open Output Font"),
278 output_line
->setText(QDir::toNativeSeparators(file
));
283 Main_GUI::browse_control()
285 // XXX remember last directory
286 QString file
= QFileDialog::getOpenFileName(
288 tr("Open Control Instructions File"),
293 control_line
->setText(QDir::toNativeSeparators(file
));
298 Main_GUI::browse_reference()
300 // XXX remember last directory
301 QString file
= QFileDialog::getOpenFileName(
303 tr("Open Blue Zone Reference Font"),
308 reference_line
->setText(QDir::toNativeSeparators(file
));
313 Main_GUI::check_min()
315 int min
= min_box
->value();
316 int max
= max_box
->value();
317 int limit
= limit_box
->value();
319 max_box
->setValue(min
);
321 limit_box
->setValue(min
);
326 Main_GUI::check_max()
328 int min
= min_box
->value();
329 int max
= max_box
->value();
330 int limit
= limit_box
->value();
332 min_box
->setValue(max
);
334 limit_box
->setValue(max
);
339 Main_GUI::check_limit()
341 int min
= min_box
->value();
342 int max
= max_box
->value();
343 int limit
= limit_box
->value();
345 max_box
->setValue(limit
);
347 min_box
->setValue(limit
);
352 Main_GUI::check_dehint()
354 if (dehint_box
->isChecked())
356 control_label
->setEnabled(false);
357 control_line
->setEnabled(false);
358 control_button
->setEnabled(false);
360 reference_label
->setEnabled(false);
361 reference_line
->setEnabled(false);
362 reference_button
->setEnabled(false);
364 min_label
->setEnabled(false);
365 min_box
->setEnabled(false);
367 max_label
->setEnabled(false);
368 max_box
->setEnabled(false);
370 default_label
->setEnabled(false);
371 default_box
->setEnabled(false);
372 fallback_label
->setEnabled(false);
373 fallback_hint_or_scale_box
->setEnabled(false);
374 fallback_box
->setEnabled(false);
376 no_limit_box
->setEnabled(false);
377 limit_label
->setEnabled(false);
378 limit_box
->setEnabled(false);
380 no_x_increase_box
->setEnabled(false);
381 x_increase_label
->setEnabled(false);
382 x_increase_box
->setEnabled(false);
384 snapping_label
->setEnabled(false);
385 snapping_line
->setEnabled(false);
387 default_stem_width_box
->setEnabled(false);
388 stem_width_label
->setEnabled(false);
389 stem_width_box
->setEnabled(false);
391 wincomp_box
->setEnabled(false);
392 adjust_box
->setEnabled(false);
393 hint_box
->setEnabled(false);
394 symbol_box
->setEnabled(false);
396 ref_idx_label
->setEnabled(false);
397 ref_idx_box
->setEnabled(false);
399 stem_label
->setEnabled(false);
401 gray_label
->setEnabled(false);
402 gray_box
->setEnabled(false);
403 gdi_label
->setEnabled(false);
404 gdi_box
->setEnabled(false);
405 dw_label
->setEnabled(false);
406 dw_box
->setEnabled(false);
410 control_label
->setEnabled(true);
411 control_line
->setEnabled(true);
412 control_button
->setEnabled(true);
414 reference_label
->setEnabled(true);
415 reference_line
->setEnabled(true);
416 reference_button
->setEnabled(true);
418 min_label
->setEnabled(true);
419 min_box
->setEnabled(true);
421 max_label
->setEnabled(true);
422 max_box
->setEnabled(true);
424 default_label
->setEnabled(true);
425 default_box
->setEnabled(true);
426 fallback_label
->setEnabled(true);
427 fallback_hint_or_scale_box
->setEnabled(true);
428 fallback_box
->setEnabled(true);
430 no_limit_box
->setEnabled(true);
433 no_x_increase_box
->setEnabled(true);
434 check_no_x_increase();
436 snapping_label
->setEnabled(true);
437 snapping_line
->setEnabled(true);
439 default_stem_width_box
->setEnabled(true);
440 check_default_stem_width();
442 wincomp_box
->setEnabled(true);
443 adjust_box
->setEnabled(true);
444 hint_box
->setEnabled(true);
445 symbol_box
->setEnabled(true);
447 ref_idx_label
->setEnabled(true);
448 ref_idx_box
->setEnabled(true);
450 stem_label
->setEnabled(true);
452 gray_label
->setEnabled(true);
453 gray_box
->setEnabled(true);
454 gdi_label
->setEnabled(true);
455 gdi_box
->setEnabled(true);
456 dw_label
->setEnabled(true);
457 dw_box
->setEnabled(true);
463 Main_GUI::check_no_limit()
465 if (no_limit_box
->isChecked())
467 limit_label
->setEnabled(false);
468 limit_label
->setText(limit_label_text
);
469 limit_box
->setEnabled(false);
470 no_limit_box
->setText(no_limit_box_text_with_key
);
474 limit_label
->setEnabled(true);
475 limit_label
->setText(limit_label_text_with_key
);
476 limit_box
->setEnabled(true);
477 no_limit_box
->setText(no_limit_box_text
);
483 Main_GUI::check_no_x_increase()
485 if (no_x_increase_box
->isChecked())
487 x_increase_label
->setEnabled(false);
488 x_increase_label
->setText(x_increase_label_text
);
489 x_increase_box
->setEnabled(false);
490 no_x_increase_box
->setText(no_x_increase_box_text_with_key
);
494 x_increase_label
->setEnabled(true);
495 x_increase_label
->setText(x_increase_label_text_with_key
);
496 x_increase_box
->setEnabled(true);
497 no_x_increase_box
->setText(no_x_increase_box_text
);
503 Main_GUI::check_default_stem_width()
505 if (default_stem_width_box
->isChecked())
507 stem_width_label
->setEnabled(false);
508 stem_width_label
->setText(stem_width_label_text
);
509 stem_width_box
->setEnabled(false);
510 default_stem_width_box
->setText(default_stem_width_box_text_with_key
);
514 stem_width_label
->setEnabled(true);
515 stem_width_label
->setText(stem_width_label_text_with_key
);
516 stem_width_box
->setEnabled(true);
517 default_stem_width_box
->setText(default_stem_width_box_text
);
523 Main_GUI::check_run()
525 if (input_line
->text().isEmpty() || output_line
->text().isEmpty())
526 run_button
->setEnabled(false);
528 run_button
->setEnabled(true);
533 Main_GUI::absolute_input()
535 QString input_name
= QDir::fromNativeSeparators(input_line
->text());
536 if (!input_name
.isEmpty()
537 && QDir::isRelativePath(input_name
))
539 QDir
cur_path(QDir::currentPath() + "/" + input_name
);
540 input_line
->setText(QDir::toNativeSeparators(cur_path
.absolutePath()));
546 Main_GUI::absolute_output()
548 QString output_name
= QDir::fromNativeSeparators(output_line
->text());
549 if (!output_name
.isEmpty()
550 && QDir::isRelativePath(output_name
))
552 QDir
cur_path(QDir::currentPath() + "/" + output_name
);
553 output_line
->setText(QDir::toNativeSeparators(cur_path
.absolutePath()));
559 Main_GUI::absolute_control()
561 QString control_name
= QDir::fromNativeSeparators(control_line
->text());
562 if (!control_name
.isEmpty()
563 && QDir::isRelativePath(control_name
))
565 QDir
cur_path(QDir::currentPath() + "/" + control_name
);
566 control_line
->setText(QDir::toNativeSeparators(cur_path
.absolutePath()));
572 Main_GUI::absolute_reference()
574 QString reference_name
= QDir::fromNativeSeparators(reference_line
->text());
575 if (!reference_name
.isEmpty()
576 && QDir::isRelativePath(reference_name
))
578 QDir
cur_path(QDir::currentPath() + "/" + reference_name
);
579 reference_line
->setText(QDir::toNativeSeparators(cur_path
.absolutePath()));
585 Main_GUI::set_ref_idx_box_max()
587 QString reference_name
= QDir::fromNativeSeparators(reference_line
->text());
589 FT_Library library
= NULL
;
593 // we don't handle errors
594 // since `TTF_autohint' checks the reference font (and index) later on
595 error
= FT_Init_FreeType(&library
);
597 error
= FT_New_Face(library
, qPrintable(reference_name
), -1, &face
);
599 ref_idx_box
->setRange(0, error
? 100 : int(face
->num_faces
- 1));
602 FT_Done_FreeType(library
);
607 Main_GUI::check_number_set()
609 QString text
= snapping_line
->text();
612 // construct ASCII string from arbitrary Unicode data;
613 // the idea is to accept, say, CJK fullwidth digits also
614 for (int i
= 0; i
< text
.size(); i
++)
616 QChar c
= text
.at(i
);
618 int digit
= c
.digitValue();
620 qs
+= QString::number(digit
);
621 else if (c
.isSpace())
623 // U+30FC KATAGANA-HIRAGANA PROLONGED SOUND MARK is assigned
624 // to the `-' key in some Japanese input methods
625 else if (c
.category() == QChar::Punctuation_Dash
626 || c
== QChar(0x30FC))
628 // various Unicode COMMA characters,
629 // including representation forms
630 else if (c
== QChar(',')
631 || c
== QChar(0x055D)
632 || c
== QChar(0x060C)
633 || c
== QChar(0x07F8)
634 || c
== QChar(0x1363)
635 || c
== QChar(0x1802)
636 || c
== QChar(0x1808)
637 || c
== QChar(0x3001)
638 || c
== QChar(0xA4FE)
639 || c
== QChar(0xA60D)
640 || c
== QChar(0xA6F5)
641 || c
== QChar(0xFE10)
642 || c
== QChar(0xFE11)
643 || c
== QChar(0xFE50)
644 || c
== QChar(0xFE51)
645 || c
== QChar(0xFF0C)
646 || c
== QChar(0xFF64))
649 qs
+= c
; // we do error handling below
652 if (x_height_snapping_exceptions
)
653 number_set_free(x_height_snapping_exceptions
);
655 QByteArray str
= qs
.toLocal8Bit();
656 const char* s
= number_set_parse(str
.constData(),
657 &x_height_snapping_exceptions
,
661 statusBar()->setStyleSheet("color: red;");
662 if (x_height_snapping_exceptions
== NUMBERSET_ALLOCATION_ERROR
)
663 statusBar()->showMessage(
664 tr("allocation error"));
665 else if (x_height_snapping_exceptions
== NUMBERSET_INVALID_CHARACTER
)
666 statusBar()->showMessage(
667 tr("invalid character (use digits, dashes, commas, and spaces)"));
668 else if (x_height_snapping_exceptions
== NUMBERSET_OVERFLOW
)
669 statusBar()->showMessage(
671 else if (x_height_snapping_exceptions
== NUMBERSET_INVALID_RANGE
)
672 statusBar()->showMessage(
673 tr("invalid range (minimum is 6, maximum is 32767)"));
674 else if (x_height_snapping_exceptions
== NUMBERSET_OVERLAPPING_RANGES
)
675 statusBar()->showMessage(
676 tr("overlapping ranges"));
677 else if (x_height_snapping_exceptions
== NUMBERSET_NOT_ASCENDING
)
678 statusBar()->showMessage(
679 tr("values und ranges must be specified in ascending order"));
681 snapping_line
->setText(qs
);
682 snapping_line
->setFocus(Qt::OtherFocusReason
);
683 snapping_line
->setCursorPosition(int(s
- str
.constData()));
685 x_height_snapping_exceptions
= NULL
;
689 // normalize if there is no error
690 char* new_str
= number_set_show(x_height_snapping_exceptions
,
692 snapping_line
->setText(new_str
);
699 Main_GUI::check_family_suffix()
701 QByteArray text
= family_suffix_line
->text().toLocal8Bit();
702 const char* s
= text
.constData();
704 if (const char* pos
= ::check_family_suffix(s
))
706 statusBar()->setStyleSheet("color: red;");
707 statusBar()->showMessage(
708 tr("invalid character (use printable ASCII except %()/<>[]{})"));
709 family_suffix_line
->setFocus(Qt::OtherFocusReason
);
710 family_suffix_line
->setCursorPosition(int(pos
- s
));
716 Main_GUI::clear_status_bar()
718 statusBar()->clearMessage();
719 statusBar()->setStyleSheet("");
724 Main_GUI::check_filenames(const QString
& input_name
,
725 const QString
& output_name
,
726 const QString
& control_name
,
727 const QString
& reference_name
)
729 if (!QFile::exists(input_name
))
731 QMessageBox::warning(
734 tr("The file %1 cannot be found.")
735 .arg(QUOTE_STRING(QDir::toNativeSeparators(input_name
))),
741 if (input_name
== output_name
)
743 QMessageBox::warning(
746 tr("Input and output file names must be different."),
752 // silently overwrite if watching is active
753 if (QFile::exists(output_name
) && !watch_box
->isChecked())
755 int ret
= QMessageBox::warning(
758 tr("The file %1 already exists.\n"
760 .arg(QUOTE_STRING(QDir::toNativeSeparators(output_name
))),
761 QMessageBox::Yes
| QMessageBox::No
,
763 if (ret
== QMessageBox::No
)
767 if (!control_name
.isEmpty() && !QFile::exists(control_name
))
769 QMessageBox::warning(
772 tr("The file %1 cannot be found.")
773 .arg(QUOTE_STRING(QDir::toNativeSeparators(control_name
))),
779 if (!reference_name
.isEmpty() && !QFile::exists(reference_name
))
781 QMessageBox::warning(
784 tr("The file %1 cannot be found.")
785 .arg(QUOTE_STRING(QDir::toNativeSeparators(reference_name
))),
796 Main_GUI::open_files(const QString
& input_name
,
798 const QString
& output_name
,
800 const QString
& control_name
,
802 const QString
& reference_name
,
805 const int buf_len
= 1024;
808 *in
= fopen(qPrintable(input_name
), "rb");
811 strerror_r(errno
, buf
, buf_len
);
812 QMessageBox::warning(
815 tr("The following error occurred while opening input file %1:\n")
816 .arg(QUOTE_STRING(QDir::toNativeSeparators(input_name
)))
817 + QString::fromLocal8Bit(buf
),
823 *out
= fopen(qPrintable(output_name
), "wb");
826 strerror_r(errno
, buf
, buf_len
);
827 QMessageBox::warning(
830 tr("The following error occurred while opening output file %1:\n")
831 .arg(QUOTE_STRING(QDir::toNativeSeparators(output_name
)))
832 + QString::fromLocal8Bit(buf
),
838 if (!control_name
.isEmpty())
840 *control
= fopen(qPrintable(control_name
), "r");
843 strerror_r(errno
, buf
, buf_len
);
844 QMessageBox::warning(
847 tr("The following error occurred"
848 " while opening control instructions file %1:\n")
849 .arg(QUOTE_STRING(QDir::toNativeSeparators(control_name
)))
850 + QString::fromLocal8Bit(buf
),
859 if (!reference_name
.isEmpty())
861 *reference
= fopen(qPrintable(reference_name
), "rb");
864 strerror_r(errno
, buf
, buf_len
);
865 QMessageBox::warning(
868 tr("The following error occurred"
869 " while opening blue zone reference file %1:\n")
870 .arg(QUOTE_STRING(QDir::toNativeSeparators(reference_name
)))
871 + QString::fromLocal8Bit(buf
),
885 Main_GUI::check_watch()
887 if (watch_box
->isChecked())
889 // file watching gets started in the `run' function
898 Main_GUI::start_timer()
900 // we delay the file watching action, mainly to ensure
901 // that newly generated files have been completely written to disk
908 Main_GUI::stop_watching()
911 if (!fileinfo_input_file
.fileName().isEmpty())
912 file_watcher
->removePath(fileinfo_input_file
.fileName());
913 if (!fileinfo_control_file
.fileName().isEmpty())
914 file_watcher
->removePath(fileinfo_control_file
.fileName());
915 if (!fileinfo_reference_file
.fileName().isEmpty())
916 file_watcher
->removePath(fileinfo_reference_file
.fileName());
921 Main_GUI::watch_files()
923 if (fileinfo_input_file
.exists()
924 && fileinfo_input_file
.isReadable()
925 && (fileinfo_control_file
.fileName().isEmpty()
927 : (fileinfo_control_file
.exists()
928 && fileinfo_control_file
.isReadable()))
929 && (fileinfo_reference_file
.fileName().isEmpty()
931 : (fileinfo_reference_file
.exists()
932 && fileinfo_reference_file
.isReadable())))
934 QDateTime modified_input
= fileinfo_input_file
.lastModified();
935 QDateTime modified_control
= fileinfo_control_file
.lastModified();
936 QDateTime modified_reference
= fileinfo_reference_file
.lastModified();
937 // XXX make this configurable
938 if (datetime_input_file
.msecsTo(modified_input
) > 1000
939 || datetime_control_file
.msecsTo(modified_control
) > 1000
940 || datetime_reference_file
.msecsTo(modified_reference
) > 1000)
943 run(); // this function sets `datetime_XXX'
947 // restart timer for symlinks
948 if (watch_box
->isChecked())
950 if (fileinfo_input_file
.isSymLink()
951 || fileinfo_control_file
.isSymLink()
952 || fileinfo_reference_file
.isSymLink())
959 if (check
== DoCheck
)
961 else if (check
== CheckLater
)
964 run(); // let this routine handle all errors
971 struct GUI_Progress_Data
975 QProgressDialog
* dialog
;
980 #define TRDOMAIN "GuiProgress"
983 gui_progress(long curr_idx
,
989 GUI_Progress_Data
* data
= static_cast<GUI_Progress_Data
*>(user
);
991 if (num_sfnts
> 1 && curr_sfnt
!= data
->last_sfnt
)
993 data
->dialog
->setLabelText(Tr("Auto-hinting subfont %1 of %2"
994 " with %3 glyphs...")
999 if (curr_sfnt
+ 1 == num_sfnts
)
1001 data
->dialog
->setAutoReset(true);
1002 data
->dialog
->setAutoClose(true);
1006 data
->dialog
->setAutoReset(false);
1007 data
->dialog
->setAutoClose(false);
1010 data
->last_sfnt
= curr_sfnt
;
1017 data
->dialog
->setLabelText(Tr("Auto-hinting %1 glyphs...")
1019 data
->dialog
->setMaximum(int(num_glyphs
- 1));
1021 data
->begin
= false;
1024 data
->dialog
->setValue(int(curr_idx
));
1026 if (data
->dialog
->wasCanceled())
1033 struct GUI_Error_Data
1037 QString output_name
;
1038 QString control_name
;
1039 QString reference_name
;
1040 int* ignore_restrictions_p
;
1046 #define TRDOMAIN "GuiError"
1049 gui_error(TA_Error error
,
1050 const char* error_string
,
1051 unsigned int errlinenum
,
1052 const char* errline
,
1056 GUI_Error_Data
* data
= static_cast<GUI_Error_Data
*>(user
);
1057 QLocale
* locale
= data
->locale
; // for QUOTE_STRING_LITERAL
1062 if (error
== TA_Err_Canceled
)
1064 else if (error
== TA_Err_Invalid_FreeType_Version
)
1065 QMessageBox::critical(
1068 Tr("FreeType version 2.4.5 or higher is needed.\n"
1069 "Are you perhaps using a wrong FreeType DLL?"),
1072 else if (error
== TA_Err_Invalid_Font_Type
)
1073 QMessageBox::warning(
1076 Tr("This font is not a valid font"
1077 " in SFNT format with TrueType outlines.\n"
1078 "In particular, CFF outlines are not supported."),
1081 else if (error
== TA_Err_Already_Processed
)
1082 QMessageBox::warning(
1085 Tr("This font has already been processed by TTFautohint."),
1088 else if (error
== TA_Err_Missing_Legal_Permission
)
1090 int yesno
= QMessageBox::warning(
1093 Tr("Bit 1 in the %1 field of the %2 table is set:"
1094 " This font must not be modified"
1095 " without permission of the legal owner.\n"
1096 "Do you have such a permission?")
1097 .arg(QUOTE_STRING_LITERAL("fsType"))
1098 .arg(QUOTE_STRING_LITERAL("OS/2")),
1099 QMessageBox::Yes
| QMessageBox::No
,
1101 if (yesno
== QMessageBox::Yes
)
1103 *data
->ignore_restrictions_p
= true;
1107 else if (error
== TA_Err_Missing_Unicode_CMap
)
1108 QMessageBox::warning(
1111 Tr("The input font doesn't contain a Unicode character map.\n"
1112 "Maybe you haven't set the %1 checkbox?")
1113 .arg(QUOTE_STRING_LITERAL(Tr("Symbol Font"))),
1116 else if (error
== TA_Err_Missing_Symbol_CMap
)
1117 QMessageBox::warning(
1120 Tr("The input font does neither contain a symbol"
1121 " nor a character map."),
1124 else if (error
== TA_Err_Missing_Glyph
)
1125 QMessageBox::warning(
1128 Tr("No glyph for a standard character"
1129 " to derive standard width and height.\n"
1130 "Please check the documentation for a list of"
1131 " script-specific standard characters.\n"
1133 "Set the %1 checkbox if you want to circumvent this test.")
1134 .arg(QUOTE_STRING_LITERAL(Tr("Symbol Font"))),
1137 else if (error
>= 0x200 && error
< 0x300)
1138 QMessageBox::warning(
1141 QString::fromLocal8Bit("%1:%2:%3: %4 (0x%5)<br>"
1144 .arg(data
->control_name
)
1146 .arg(int(errpos
- errline
+ 1))
1148 .arg(error
, 2, 16, QLatin1Char('0'))
1150 .arg('^', int(errpos
- errline
+ 1))
1151 .replace(" ", " "),
1154 else if (error
>= 0x300 && error
< 0x400)
1155 QMessageBox::warning(
1158 Tr("Error code 0x%1 while loading blue zone reference file:\n")
1159 .arg(error
- 0x300, 2, 16, QLatin1Char('0'))
1160 + QString::fromLocal8Bit(error_string
),
1164 QMessageBox::warning(
1167 Tr("Error code 0x%1 while autohinting font:\n")
1168 .arg(error
, 2, 16, QLatin1Char('0'))
1169 + QString::fromLocal8Bit(error_string
),
1173 if (QFile::exists(data
->output_name
)
1174 && remove(qPrintable(data
->output_name
)))
1176 const int buf_len
= 1024;
1179 strerror_r(errno
, buf
, buf_len
);
1180 QMessageBox::warning(
1183 Tr("The following error occurred while removing output file %1:\n")
1184 .arg(QUOTE_STRING(QDir::toNativeSeparators(data
->output_name
)))
1185 + QString::fromLocal8Bit(buf
),
1199 if (check
== CheckLater
)
1205 QString input_name
= QDir::fromNativeSeparators(input_line
->text());
1206 QString output_name
= QDir::fromNativeSeparators(output_line
->text());
1207 QString control_name
= QDir::fromNativeSeparators(control_line
->text());
1208 QString reference_name
= QDir::fromNativeSeparators(reference_line
->text());
1209 if (!check_filenames(input_name
, output_name
, control_name
, reference_name
))
1215 // we need C file descriptors for communication with TTF_autohint
1222 if (!open_files(input_name
, &input
,
1223 output_name
, &output
,
1224 control_name
, &control
,
1225 reference_name
, &reference
))
1231 QProgressDialog dialog
;
1232 dialog
.setCancelButtonText(tr("Cancel"));
1233 dialog
.setMinimumDuration(1000);
1234 dialog
.setWindowModality(Qt::WindowModal
);
1236 TA_Info_Func info_func
= info
;
1237 TA_Info_Post_Func info_post_func
= info_post
;
1238 GUI_Progress_Data gui_progress_data
= {-1, true, &dialog
};
1239 GUI_Error_Data gui_error_data
= {this, locale
,
1240 output_name
, control_name
, reference_name
,
1241 &ignore_restrictions
, false};
1243 fileinfo_input_file
.setFile(input_name
);
1244 fileinfo_control_file
.setFile(control_name
);
1245 fileinfo_reference_file
.setFile(reference_name
);
1247 // prepare C strings
1248 QByteArray ctrl_name
= fileinfo_control_file
.fileName().toLocal8Bit();
1249 QByteArray ref_name
= fileinfo_reference_file
.fileName().toLocal8Bit();
1250 QByteArray except_str
= x_height_snapping_exceptions_string
.toLocal8Bit();
1251 QByteArray fam_suff
= family_suffix_line
->text().toLocal8Bit();
1253 Info_Data info_data
;
1255 info_data
.info_string
= NULL
; // must be deallocated after use
1256 info_data
.info_string_wide
= NULL
; // must be deallocated after use
1257 info_data
.info_string_len
= 0;
1258 info_data
.info_string_wide_len
= 0;
1260 info_data
.control_name
= ctrl_name
.isEmpty() ? NULL
1261 : ctrl_name
.constData();
1262 info_data
.reference_name
= ref_name
.isEmpty() ? NULL
1263 : ref_name
.constData();
1264 info_data
.reference_index
= ref_idx_box
->value();
1266 info_data
.hinting_range_min
= min_box
->value();
1267 info_data
.hinting_range_max
= max_box
->value();
1268 info_data
.hinting_limit
= no_limit_box
->isChecked()
1270 : limit_box
->value();
1272 // indices 0, 1, 2 are mapped to values -1, 0, 1
1273 info_data
.gray_stem_width_mode
= gray_box
->currentIndex() - 1;
1274 info_data
.gdi_cleartype_stem_width_mode
= gdi_box
->currentIndex() - 1;
1275 info_data
.dw_cleartype_stem_width_mode
= dw_box
->currentIndex() - 1;
1277 info_data
.increase_x_height
= no_x_increase_box
->isChecked()
1279 : x_increase_box
->value();
1280 info_data
.x_height_snapping_exceptions_string
= except_str
.constData();
1282 info_data
.family_suffix
= fam_suff
.constData();
1283 info_data
.family_data_head
= NULL
;
1285 info_data
.fallback_stem_width
= default_stem_width_box
->isChecked()
1287 : stem_width_box
->value();
1289 info_data
.windows_compatibility
= wincomp_box
->isChecked();
1290 info_data
.adjust_subglyphs
= adjust_box
->isChecked();
1291 info_data
.hint_composites
= hint_box
->isChecked();
1292 info_data
.symbol
= symbol_box
->isChecked();
1293 info_data
.fallback_scaling
= fallback_hint_or_scale_box
->currentIndex();
1294 info_data
.no_info
= info_box
->currentIndex() == 0;
1295 info_data
.detailed_info
= info_box
->currentIndex() == 2;
1296 info_data
.dehint
= dehint_box
->isChecked();
1297 info_data
.TTFA_info
= TTFA_box
->isChecked();
1299 strncpy(info_data
.default_script
,
1300 script_names
[default_box
->currentIndex()].tag
,
1301 sizeof (info_data
.default_script
));
1302 strncpy(info_data
.fallback_script
,
1303 script_names
[fallback_box
->currentIndex()].tag
,
1304 sizeof (info_data
.fallback_script
));
1306 if (info_box
->currentIndex())
1308 int ret
= build_version_string(&info_data
);
1310 QMessageBox::information(
1313 tr("Can't allocate memory for <b>TTFautohint</b> options string"
1314 " in <i>name</i> table."),
1318 QMessageBox::information(
1321 tr("<b>TTFautohint</b> options string"
1322 " in <i>name</i> table too long."),
1327 if (!*info_data
.family_suffix
)
1328 info_post_func
= NULL
;
1330 if (info_data
.symbol
1331 && info_data
.fallback_stem_width
1332 && info_data
.fallback_scaling
)
1333 QMessageBox::information(
1336 tr("Setting a fallback stem width for a symbol font"
1337 " with fallback scaling only has no effect."),
1341 datetime_input_file
= fileinfo_input_file
.lastModified();
1342 datetime_control_file
= fileinfo_control_file
.lastModified();
1343 datetime_reference_file
= fileinfo_reference_file
.lastModified();
1345 QByteArray snapping_string
= snapping_line
->text().toLocal8Bit();
1348 TTF_autohint("in-file, out-file, control-file, reference-file,"
1349 "reference-index, reference-name,"
1350 "hinting-range-min, hinting-range-max,"
1352 "gray-stem-width-mode,"
1353 "gdi-cleartype-stem-width-mode,"
1354 "dw-cleartype-stem-width-mode,"
1355 "progress-callback, progress-callback-data,"
1356 "error-callback, error-callback-data,"
1357 "info-callback, info-post-callback, info-callback-data,"
1358 "ignore-restrictions,"
1359 "windows-compatibility,"
1362 "increase-x-height,"
1363 "x-height-snapping-exceptions, fallback-stem-width,"
1365 "fallback-script, fallback-scaling,"
1366 "symbol, dehint, TTFA-info",
1367 input
, output
, control
, reference
,
1368 info_data
.reference_index
, info_data
.reference_name
,
1369 info_data
.hinting_range_min
, info_data
.hinting_range_max
,
1370 info_data
.hinting_limit
,
1371 info_data
.gray_stem_width_mode
,
1372 info_data
.gdi_cleartype_stem_width_mode
,
1373 info_data
.dw_cleartype_stem_width_mode
,
1374 gui_progress
, &gui_progress_data
,
1375 gui_error
, &gui_error_data
,
1376 info_func
, info_post_func
, &info_data
,
1377 ignore_restrictions
,
1378 info_data
.windows_compatibility
,
1379 info_data
.adjust_subglyphs
,
1380 info_data
.hint_composites
,
1381 info_data
.increase_x_height
,
1382 snapping_string
.constData(), info_data
.fallback_stem_width
,
1383 info_data
.default_script
,
1384 info_data
.fallback_script
, info_data
.fallback_scaling
,
1385 info_data
.symbol
, info_data
.dehint
, info_data
.TTFA_info
);
1387 if (info_box
->currentIndex())
1389 free(info_data
.info_string
);
1390 free(info_data
.info_string_wide
);
1402 // retry if there is a user request to do so (handled in `gui_error')
1403 if (gui_error_data
.retry
)
1410 statusBar()->showMessage(tr("Auto-hinting finished")
1412 + QDateTime::currentDateTime()
1413 .toString(Qt::TextDate
)
1416 // we have successfully processed a file;
1417 // start file watching now if requested
1418 if (watch_box
->isChecked())
1422 // Qt's file watcher doesn't handle symlinks;
1423 // we thus fall back to polling
1424 if (fileinfo_input_file
.isSymLink()
1425 || fileinfo_control_file
.isSymLink()
1426 || fileinfo_reference_file
.isSymLink())
1430 file_watcher
->addPath(input_name
);
1431 file_watcher
->addPath(control_name
);
1432 file_watcher
->addPath(reference_name
);
1439 // XXX distances are specified in pixels,
1440 // making the layout dependent on the output device resolution
1442 Main_GUI::create_layout(bool horizontal_layout
)
1447 QCompleter
* completer
= new QCompleter(this);
1448 QFileSystemModel
* model
= new QFileSystemModel(completer
);
1449 model
->setRootPath(QDir::rootPath());
1450 completer
->setModel(model
);
1452 input_label
= new QLabel(tr("&Input Font:"));
1453 input_line
= new Drag_Drop_Line_Edit(DRAG_DROP_TRUETYPE
);
1454 input_button
= new QPushButton(tr("Browse..."));
1455 input_label
->setBuddy(input_line
);
1456 // enforce rich text to get nice word wrapping
1457 input_label
->setToolTip(
1458 tr("<b></b>The input file, either a TrueType font (TTF),"
1459 " TrueType collection (TTC), or a TrueType-based OpenType font."));
1460 input_line
->setCompleter(completer
);
1462 output_label
= new QLabel(tr("&Output Font:"));
1463 output_line
= new Drag_Drop_Line_Edit(DRAG_DROP_TRUETYPE
);
1464 output_button
= new QPushButton(tr("Browse..."));
1465 output_label
->setBuddy(output_line
);
1466 output_label
->setToolTip(
1467 tr("<b></b>The output file, which will be essentially identical"
1468 " to the input font but will contain new, generated hints."));
1469 output_line
->setCompleter(completer
);
1471 control_label
= new QLabel(tr("Control Instructions Fil&e:"));
1472 control_line
= new Drag_Drop_Line_Edit(DRAG_DROP_ANY
);
1473 control_button
= new QPushButton(tr("Browse..."));
1474 control_label
->setBuddy(control_line
);
1475 // we use the non-breaking hyphen U+2011 (‑) where necessary
1476 QString tooltip_string
=
1477 tr("<p>An optional control instructions file to tweak hinting"
1478 " and to override glyph assignments to styles."
1479 " This text file contains entries"
1480 " of one of the following syntax forms"
1481 " (with brackets indicating optional elements).<br>"
1484 " [ <i>subfont‑idx</i> ]"
1485 " <i>script</i>"
1486 " <i>feature</i>"
1487 " <tt>@</tt> <i>glyph‑ids</i><br>"
1489 " [ <i>subfont‑idx</i> ]"
1490 " <i>script</i>"
1491 " <i>feature</i>"
1492 " <tt>width</tt> <i>stem‑widths</i><br>"
1494 " [ <i>subfont‑idx</i> ]"
1495 " <i>glyph‑id</i>"
1496 " <tt>left</tt> | <tt>right</tt> <i>points</i>"
1497 " [ <tt>(</tt><i>left‑offset</i><tt>,"
1498 "</tt><i>right‑offset</i><tt>)</tt> ]<br>"
1500 " [ <i>subfont‑idx</i> ]"
1501 " <i>glyph‑id</i>"
1502 " <tt>nodir</tt> <i>points</i><br>"
1504 " [ <i>subfont‑idx</i> ]"
1505 " <i>glyph‑id</i>"
1506 " <tt>touch</tt> | <tt>point</tt> <i>points</i>"
1507 " [ <tt>xshift</tt> <i>shift</i> ]"
1508 " [ <tt>yshift</tt> <i>shift</i> ]"
1509 " <tt>@</tt> <i>ppems</i><br>"
1512 "<i>subfont‑idx</i> gives the subfont index in a TTC,"
1513 " <i>glyph‑id</i> is a glyph name or index.<br>"
1516 "<i>script</i> and <i>feature</i> are four-letter tags"
1517 " (like <tt>cyrl</tt> for the Cyrillic script"
1518 " or <tt>subs</tt> for the subscript feature)"
1519 " that define a style the <i>glyph‑ids</i> are assigned to."
1520 " <i>glyph‑ids</i> is a comma-separated list of"
1521 " <i>glyph‑id</i> values and value ranges.<br>"
1524 "<i>stem‑widths</i> is a comma-separated list of integer"
1525 " stem widths (in font units); the first value sets the default stem"
1529 "<tt>left</tt> (<tt>right</tt>) creates one-point segments"
1530 " with direction left (right), possibly having a width (in font units)"
1531 " given by <i>left‑offset</i> and <i>right‑offset</i>"
1532 " relative to the corresponding points.<br>"
1535 "<tt>nodir</tt> removes points from horizontal segments,"
1536 " making them <i>weak</i> points.<br>"
1539 "<tt>touch </tt> (<tt>point</tt>) defines delta exceptions"
1540 " to be applied before (after) the final"
1541 " <tt>IUP</tt> bytecode instructions."
1542 " <tt>touch</tt> also touches points, making them <i>strong</i>."
1543 " In ClearType mode, <tt>point</tt> and <tt>xshift</tt>"
1544 " have no effect.<br>"
1547 "x and y <i>shift</i> values are in the range [-1;1],"
1548 " rounded to multiples of 1/8px.<br>"
1550 "<i>points</i> and <i>ppems</i> are ranges for point indices"
1551 " and ppem values as with x height snapping exceptions.<br>"
1553 "Keywords <tt>left</tt>, <tt>right</tt>, <tt>nodir</tt>,"
1554 " <tt>point</tt>, <tt>touch</tt>, <tt>width</tt>, <tt>xshift</tt>,"
1555 " and <tt>yshift</tt> can be abbreviated as <tt>l</tt>, <tt>r</tt>,"
1556 " <tt>n</tt>, <tt>p</tt>, <tt>t</tt>, <tt>w</tt>, <tt>x</tt>, and"
1557 " <tt>y</tt>, respectively.<br>"
1559 "Control instruction entries are separated"
1560 " by character <tt>;</tt> or by a newline.<br>"
1562 "A trailing character <tt>\\</tt> continues the current line"
1563 " on the next line.<br>"
1565 "<tt>#</tt> starts a line comment, which gets ignored."
1566 " Empty lines are ignored, too.</p>"
1569 " <tt>cyrl sups @ one.sups-nine.sups, zero.sups</tt><br>"
1570 " <tt>Q left 38 (-70,20)</tt><br>"
1571 " <tt>Adieresis touch 3-6 yshift 0.25 @ 13</tt>");
1573 control_label
->setToolTip(tooltip_string
);
1574 control_line
->setCompleter(completer
);
1576 reference_label
= new QLabel(tr("Blue &Zone Reference Font:"));
1577 reference_line
= new Drag_Drop_Line_Edit(DRAG_DROP_TRUETYPE
);
1578 reference_button
= new QPushButton(tr("Browse..."));
1579 reference_label
->setBuddy(reference_line
);
1580 reference_label
->setToolTip(
1581 tr("<b></b>A reference font file"
1582 " from which all blue zone values are taken."));
1583 reference_line
->setCompleter(completer
);
1585 ref_idx_label
= new QLabel(tr("Reference Face Index:"));
1586 ref_idx_box
= new QSpinBox
;
1587 ref_idx_label
->setBuddy(ref_idx_box
);
1588 ref_idx_label
->setToolTip(
1589 tr("The face index of the blue zone reference font to be used"
1590 " in case it is a TrueType Collection (<tt>.ttc</tt>)."));
1591 ref_idx_box
->setKeyboardTracking(false);
1592 // the range maximum gets updated interactively
1593 // after a (more or less) valid reference font has been selected
1594 ref_idx_box
->setRange(0, 100);
1599 min_label
= new QLabel(tr("Hint Set Range Mi&nimum:"));
1600 min_box
= new QSpinBox
;
1601 min_label
->setBuddy(min_box
);
1602 min_label
->setToolTip(
1603 tr("The minimum PPEM value of the range for which"
1604 " <b>TTFautohint</b> computes <i>hint sets</i>."
1605 " A hint set for a given PPEM value hints this size optimally."
1606 " The larger the range, the more hint sets are considered,"
1607 " usually increasing the size of the bytecode.<br>"
1608 "Note that changing this range doesn't influence"
1609 " the <i>gasp</i> table:"
1610 " Hinting is enabled for all sizes."));
1611 min_box
->setKeyboardTracking(false);
1612 min_box
->setRange(2, 10000);
1614 max_label
= new QLabel(tr("Hint Set Range Ma&ximum:"));
1615 max_box
= new QSpinBox
;
1616 max_label
->setBuddy(max_box
);
1617 max_label
->setToolTip(
1618 tr("The maximum PPEM value of the range for which"
1619 " <b>TTFautohint</b> computes <i>hint sets</i>."
1620 " A hint set for a given PPEM value hints this size optimally."
1621 " The larger the range, the more hint sets are considered,"
1622 " usually increasing the size of the bytecode.<br>"
1623 "Note that changing this range doesn't influence"
1624 " the <i>gasp</i> table:"
1625 " Hinting is enabled for all sizes."));
1626 max_box
->setKeyboardTracking(false);
1627 max_box
->setRange(2, 10000);
1630 // OpenType default script
1632 default_label
= new QLabel(tr("Defa&ult Script:"));
1633 default_box
= new QComboBox
;
1634 default_label
->setBuddy(default_box
);
1635 default_label
->setToolTip(
1636 tr("This sets the default script for OpenType features:"
1637 " After applying all features that are handled specially"
1638 " (for example small caps or superscript glyphs),"
1639 " <b>TTFautohint</b> uses this value for the remaining features."
1641 "<p>In most cases, you don't want to change this value.</p>"));
1642 for (int i
= 0; script_names
[i
].tag
; i
++)
1644 // XXX: how to provide translations?
1645 default_box
->insertItem(i
,
1647 .arg(script_names
[i
].tag
)
1648 .arg(script_names
[i
].description
));
1652 // hinting and fallback controls
1654 fallback_label
= new QLabel(tr("Fallbac&k Script"));
1655 fallback_hint_or_scale_box
= new QComboBox
;
1656 fallback_box
= new QComboBox
;
1657 fallback_label
->setBuddy(fallback_hint_or_scale_box
);
1658 fallback_label
->setToolTip(
1659 tr("This sets the fallback script for glyphs"
1660 " that <b>TTFautohint</b> can't map to a script automatically."
1661 " Either hinting with the script's blue zone values"
1662 " or simple scaling with the script's scaling value"
1663 " can be selected."));
1664 fallback_hint_or_scale_box
->insertItem(fallback_do_scale
, tr("Scaling:"));
1665 fallback_hint_or_scale_box
->insertItem(fallback_do_hint
, tr("Hinting:"));
1666 for (int i
= 0; script_names
[i
].tag
; i
++)
1668 // XXX: how to provide translations?
1669 fallback_box
->insertItem(i
,
1671 .arg(script_names
[i
].tag
)
1672 .arg(script_names
[i
].description
));
1678 limit_label_text_with_key
= tr("Hinting &Limit:");
1679 limit_label_text
= tr("Hinting Limit:");
1680 limit_label
= new QLabel(limit_label_text_with_key
);
1681 limit_box
= new QSpinBox
;
1682 limit_label
->setBuddy(limit_box
);
1683 limit_label
->setToolTip(
1684 tr("Switch off hinting for PPEM values exceeding this limit."
1685 " Changing this value does not influence the size of the bytecode.<br>"
1686 "Note that <b>TTFautohint</b> handles this feature"
1687 " in the output font's bytecode and not in the <i>gasp</i> table."));
1688 limit_box
->setKeyboardTracking(false);
1689 limit_box
->setRange(2, 10000);
1691 no_limit_box_text_with_key
= tr("No Hinting &Limit");
1692 no_limit_box_text
= tr("No Hinting Limit");
1693 no_limit_box
= new QCheckBox(no_limit_box_text
);
1694 no_limit_box
->setToolTip(
1695 tr("If switched on, <b>TTFautohint</b> adds no hinting limit"
1696 " to the bytecode.<br>"
1697 "For testing only."));
1700 // x height increase limit
1702 x_increase_label_text_with_key
= tr("x Height In&crease Limit:");
1703 x_increase_label_text
= tr("x Height Increase Limit:");
1704 x_increase_label
= new QLabel(x_increase_label_text_with_key
);
1705 x_increase_box
= new QSpinBox
;
1706 x_increase_label
->setBuddy(x_increase_box
);
1707 x_increase_label
->setToolTip(
1708 tr("For PPEM values in the range 6 ≤ PPEM ≤ <i>n</i>,"
1709 " where <i>n</i> is the value selected by this spin box,"
1710 " round up the font's x height much more often than normally.<br>"
1711 "Use this if holes in letters like <i>e</i> get filled,"
1713 x_increase_box
->setKeyboardTracking(false);
1714 x_increase_box
->setRange(6, 10000);
1716 no_x_increase_box_text_with_key
= tr("No x Height In&crease");
1717 no_x_increase_box_text
= tr("No x Height Increase");
1718 no_x_increase_box
= new QCheckBox(no_x_increase_box_text
);
1719 no_x_increase_box
->setToolTip(
1720 tr("If switched on,"
1721 " <b>TTFautohint</b> does not increase the x height."));
1724 // x height snapping exceptions
1726 snapping_label
= new QLabel(tr("x Height Snapping Excep&tions:"));
1727 snapping_line
= new Tooltip_Line_Edit
;
1728 snapping_label
->setBuddy(snapping_line
);
1729 snapping_label
->setToolTip(
1730 tr("<p>A list of comma separated PPEM values or value ranges"
1731 " at which no x height snapping shall be applied"
1732 " (x height snapping usually slightly increases"
1733 " the size of all glyphs).</p>"
1736 " <tt>2, 3-5, 12-17</tt><br>"
1737 " <tt>-20, 40-</tt>"
1738 " (meaning PPEM ≤ 20 or PPEM ≥ 40)<br>"
1739 " <tt>-</tt> (meaning all possible PPEM values)"));
1744 family_suffix_label
= new QLabel(tr("Family Suffix&:"));
1745 family_suffix_line
= new Tooltip_Line_Edit
;
1746 family_suffix_label
->setBuddy(family_suffix_line
);
1747 family_suffix_label
->setToolTip(
1748 tr("A string that gets appended to the family name entries"
1749 " (name IDs 1, 4, 6, 16, and 21)"
1750 " in the font's <i>name</i> table.<br>"
1751 "Mainly for testing purposes, enabling the operating system"
1752 " to display fonts simultaneously that are hinted"
1753 " with different <b>TTFautohint</b> parameters."));
1756 // fallback stem width
1758 stem_width_label_text_with_key
= tr("Fallback &Stem Width:");
1759 stem_width_label_text
= tr("Fallback Stem Width:");
1760 stem_width_label
= new QLabel(stem_width_label_text_with_key
);
1761 stem_width_box
= new QSpinBox
;
1762 stem_width_label
->setBuddy(stem_width_box
);
1763 stem_width_label
->setToolTip(
1764 tr("Set horizontal stem width (in font units) for all scripts"
1765 " that lack proper standard characters in the font.<br>"
1766 "If not set, <b>TTFautohint</b> uses a hard-coded default value."));
1767 stem_width_box
->setKeyboardTracking(false);
1768 stem_width_box
->setRange(1, 10000);
1770 default_stem_width_box_text_with_key
= tr("Default Fallback &Stem Width");
1771 default_stem_width_box_text
= tr("Default Fallback Stem Width");
1772 default_stem_width_box
= new QCheckBox(default_stem_width_box_text
);
1773 default_stem_width_box
->setToolTip(
1774 tr("If switched on, <b>TTFautohint</b> uses a default value"
1775 " for the fallback stem width (50 font units at 2048 UPEM)."));
1780 wincomp_box
= new QCheckBox(tr("Windows Com&patibility"));
1781 wincomp_box
->setToolTip(
1782 tr("If switched on, add two artificial blue zones positioned at the"
1783 " <tt>usWinAscent</tt> and <tt>usWinDescent</tt> values"
1784 " (from the font's <i>OS/2</i> table)."
1785 " This option, usually in combination"
1786 " with value <tt>-</tt> (a single dash)"
1787 " for the <i>x Height Snapping Exceptions</i> option,"
1788 " should be used if those two <i>OS/2</i> values are tight,"
1789 " and you are experiencing clipping during rendering."));
1791 adjust_box
= new QCheckBox(tr("Ad&just Subglyphs"));
1792 adjust_box
->setToolTip(
1793 tr("If switched on, the original bytecode of the input font"
1794 " gets applied (at EM size, usually 2048ppem)"
1795 " to derive the glyph outlines for <b>TTFautohint</b>.<br>"
1796 "Use this option only if subglyphs"
1797 " are incorrectly scaled and shifted.<br>"
1798 "Note that the original bytecode will always be discarded."));
1800 hint_box
= new QCheckBox(tr("Hint Co&mposites")
1801 + " "); // make label wider
1802 hint_box
->setToolTip(
1803 tr("If switched on, <b>TTFautohint</b> hints composite glyphs"
1804 " as a whole, including subglyphs."
1805 " Otherwise, glyph components get hinted separately.<br>"
1806 "Deactivating this flag reduces the bytecode size enormously,"
1807 " however, it might yield worse results."));
1809 symbol_box
= new QCheckBox(tr("S&ymbol Font"));
1810 symbol_box
->setToolTip(
1811 tr("If switched on, <b>TTFautohint</b> accepts fonts"
1812 " that don't contain a single standard character"
1813 " for any of the supported scripts.<br>"
1814 "Use this for symbol or dingbat fonts, for example."));
1816 dehint_box
= new QCheckBox(tr("&Dehint"));
1817 dehint_box
->setToolTip(
1818 tr("If set, remove all hints from the font.<br>"
1819 "For testing only."));
1821 info_label
= new QLabel(tr("ttf&autohint Info:"));
1822 info_box
= new QComboBox
;
1823 info_label
->setBuddy(info_box
);
1824 info_label
->setToolTip(
1825 tr("Specify which information about <b>TTFautohint</b>"
1826 " and its calling parameters gets added to the version string(s)"
1827 " (name ID 5) in the <i>name</i> table.<br>"
1828 "If you want to archive control instruction information,"
1829 " use a <i>TTFA</i> table."));
1830 info_box
->insertItem(0, tr("None"));
1831 info_box
->insertItem(1, tr("Version"));
1832 info_box
->insertItem(2, tr("Version and Parameters"));
1834 TTFA_box
= new QCheckBox(tr("Add TTFA Info Ta&ble"));
1835 TTFA_box
->setToolTip(
1836 tr("If switched on, an SFNT table called <i>TTFA</i>"
1837 " gets added to the output font,"
1838 " holding a dump of all parameters."
1839 " In particular, it lists all control instructions."));
1842 // stem width and positioning
1844 stem_label
= new QLabel(tr("Stem Width and Positionin&g Mode"));
1845 stem_label
->setToolTip(
1846 tr("<b>TTFautohint</b> provides three different hinting algorithms"
1847 " that can be selected for various hinting modes."
1850 " Position horizontal stems and snap stem widths"
1851 " to integer pixel values. While making the output look crisper,"
1852 " outlines become more distorted.</p>"
1854 "<p><i>quantized</i>:"
1855 " Use discrete values for horizontal stems and stem widths."
1856 " This only slightly increases the contrast"
1857 " but avoids larger outline distortion.</p>"
1859 "<p><i>natural</i>:"
1860 " Don't change horizontal stem widths"
1861 " but use discrete values for stem positioning."
1862 " This is what FreeType's"
1863 " ‘light’ hinting mode does.</p>"));
1865 QStringList mode_list
= QStringList() << "natural"
1869 gray_label
= new QLabel(tr("Grayscale:"));
1870 gray_box
= new QComboBox
;
1871 gray_box
->insertItems(0, mode_list
);
1872 gray_label
->setToolTip(
1873 tr("<b></b>Grayscale rendering, no ClearType activated."));
1875 // this must come after the creation of `gray_box'
1876 // (you get a bus error otherwise)
1877 stem_label
->setBuddy(gray_box
);
1879 gdi_label
= new QLabel(tr("GDI ClearType:"));
1880 gdi_box
= new QComboBox
;
1881 gdi_box
->insertItems(0, mode_list
);
1882 gdi_label
->setToolTip(
1883 tr("GDI ClearType rendering,"
1884 " introduced in 2000 for Windows XP.<br>"
1885 "The rasterizer version (as returned by the"
1886 " GETINFO bytecode instruction) is in the range"
1887 " 36 ≤ version < 38, and ClearType is enabled.<br>"
1888 "Along the vertical axis, this mode behaves like B/W rendering."));
1890 dw_label
= new QLabel(tr("DW ClearType:"));
1891 dw_box
= new QComboBox
;
1892 dw_box
->insertItems(0, mode_list
);
1893 dw_label
->setToolTip(
1894 tr("DirectWrite ClearType rendering,"
1895 " introduced in 2008 for Windows Vista.<br>"
1896 "The rasterizer version (as returned by the"
1897 " GETINFO bytecode instruction) is ≥ 38,"
1898 " ClearType is enabled, and subpixel positioning is enabled also.<br>"
1899 "Smooth rendering along the vertical axis."));
1904 watch_box
= new QCheckBox(tr("&Watch Input Files"));
1905 watch_box
->setToolTip(
1906 tr("If switched on, <b>TTFautohint</b> automatically re-runs"
1907 " the hinting process as soon as an input file"
1908 " (either the font, the reference font,"
1909 " or the control instructions file) is modified.<br>"
1910 "Pressing the %1 button starts watching.<br>"
1911 "If an error occurs, watching stops and must be restarted"
1912 " with the %1 button.")
1913 .arg(QUOTE_STRING_LITERAL(tr("Run"))));
1915 run_button
= new QPushButton(" "
1917 + " "); // make label wider
1919 if (horizontal_layout
)
1920 create_horizontal_layout();
1922 create_vertical_layout();
1926 // XXX distances are specified in pixels,
1927 // making the layout dependent on the output device resolution
1929 Main_GUI::create_vertical_layout()
1932 QGridLayout
* file_layout
= new QGridLayout
;
1934 file_layout
->addWidget(input_label
, 0, 0, Qt::AlignRight
);
1935 file_layout
->addWidget(input_line
, 0, 1);
1936 file_layout
->addWidget(input_button
, 0, 2);
1938 file_layout
->setRowStretch(1, 1);
1940 file_layout
->addWidget(output_label
, 2, 0, Qt::AlignRight
);
1941 file_layout
->addWidget(output_line
, 2, 1);
1942 file_layout
->addWidget(output_button
, 2, 2);
1944 file_layout
->setRowStretch(3, 1);
1946 file_layout
->addWidget(control_label
, 4, 0, Qt::AlignRight
);
1947 file_layout
->addWidget(control_line
, 4, 1);
1948 file_layout
->addWidget(control_button
, 4, 2);
1950 file_layout
->setRowStretch(5, 1);
1952 file_layout
->addWidget(reference_label
, 6, 0, Qt::AlignRight
);
1953 file_layout
->addWidget(reference_line
, 6, 1);
1954 file_layout
->addWidget(reference_button
, 6, 2);
1957 QGridLayout
* run_layout
= new QGridLayout
;
1959 run_layout
->addWidget(watch_box
, 0, 1);
1960 run_layout
->addWidget(run_button
, 0, 3, Qt::AlignRight
);
1961 run_layout
->setColumnStretch(0, 1);
1962 run_layout
->setColumnStretch(2, 2);
1967 QGridLayout
* gui_layout
= new QGridLayout
;
1968 QFrame
* hline
= new QFrame
;
1969 hline
->setFrameShape(QFrame::HLine
);
1970 int row
= 0; // this counter simplifies inserting new items
1972 gui_layout
->setRowMinimumHeight(row
, 10); // XXX urgh, pixels...
1973 gui_layout
->setRowStretch(row
++, 1);
1975 gui_layout
->addLayout(file_layout
, row
, 0, row
, -1);
1976 gui_layout
->setRowStretch(row
++, 1);
1978 gui_layout
->addWidget(hline
, row
, 0, row
, -1);
1979 gui_layout
->setRowStretch(row
++, 1);
1981 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
1982 gui_layout
->setRowStretch(row
++, 1);
1984 gui_layout
->addWidget(min_label
, row
, 0, Qt::AlignRight
);
1985 gui_layout
->addWidget(min_box
, row
++, 1, Qt::AlignLeft
);
1986 gui_layout
->addWidget(max_label
, row
, 0, Qt::AlignRight
);
1987 gui_layout
->addWidget(max_box
, row
++, 1, Qt::AlignLeft
);
1989 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
1990 gui_layout
->setRowStretch(row
++, 1);
1992 gui_layout
->addWidget(default_label
, row
, 0, Qt::AlignRight
);
1993 gui_layout
->addWidget(default_box
, row
++, 1, Qt::AlignLeft
);
1995 QGridLayout
* fallback_layout
= new QGridLayout
;
1996 fallback_layout
->addWidget(fallback_label
, 0, 0, Qt::AlignRight
);
1997 fallback_layout
->addWidget(fallback_hint_or_scale_box
, 0, 1, Qt::AlignLeft
);
1999 gui_layout
->addLayout(fallback_layout
, row
++, 0, Qt::AlignRight
);
2000 gui_layout
->addWidget(fallback_box
, row
++, 1, Qt::AlignLeft
);
2002 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
2003 gui_layout
->setRowStretch(row
++, 1);
2005 gui_layout
->addWidget(limit_label
, row
, 0, Qt::AlignRight
);
2006 gui_layout
->addWidget(limit_box
, row
++, 1, Qt::AlignLeft
);
2007 gui_layout
->addWidget(no_limit_box
, row
++, 1);
2009 gui_layout
->addWidget(x_increase_label
, row
, 0, Qt::AlignRight
);
2010 gui_layout
->addWidget(x_increase_box
, row
++, 1, Qt::AlignLeft
);
2011 gui_layout
->addWidget(no_x_increase_box
, row
++, 1);
2013 gui_layout
->addWidget(snapping_label
, row
, 0, Qt::AlignRight
);
2014 gui_layout
->addWidget(snapping_line
, row
++, 1, Qt::AlignLeft
);
2016 gui_layout
->addWidget(stem_width_label
, row
, 0, Qt::AlignRight
);
2017 gui_layout
->addWidget(stem_width_box
, row
++, 1, Qt::AlignLeft
);
2018 gui_layout
->addWidget(default_stem_width_box
, row
++, 1);
2020 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
2021 gui_layout
->setRowStretch(row
++, 1);
2023 gui_layout
->addWidget(wincomp_box
, row
++, 1);
2024 gui_layout
->addWidget(adjust_box
, row
++, 1);
2025 gui_layout
->addWidget(hint_box
, row
++, 1);
2026 gui_layout
->addWidget(symbol_box
, row
++, 1);
2027 gui_layout
->addWidget(dehint_box
, row
++, 1);
2029 gui_layout
->addWidget(info_label
, row
, 0, Qt::AlignRight
);
2030 gui_layout
->addWidget(info_box
, row
++, 1, Qt::AlignLeft
);
2031 gui_layout
->addWidget(TTFA_box
, row
++, 1);
2032 gui_layout
->addWidget(family_suffix_label
, row
, 0, Qt::AlignRight
);
2033 gui_layout
->addWidget(family_suffix_line
, row
++, 1, Qt::AlignLeft
);
2034 gui_layout
->addWidget(ref_idx_label
, row
, 0, Qt::AlignRight
);
2035 gui_layout
->addWidget(ref_idx_box
, row
++, 1, Qt::AlignLeft
);
2037 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
2038 gui_layout
->setRowStretch(row
++, 1);
2040 // this item spans two columns
2041 gui_layout
->addWidget(stem_label
, row
++, 0, 1, 2, Qt::AlignCenter
);
2043 gui_layout
->addWidget(gray_label
, row
, 0, Qt::AlignRight
);
2044 gui_layout
->addWidget(gray_box
, row
++, 1, Qt::AlignLeft
);
2045 gui_layout
->addWidget(gdi_label
, row
, 0, Qt::AlignRight
);
2046 gui_layout
->addWidget(gdi_box
, row
++, 1, Qt::AlignLeft
);
2047 gui_layout
->addWidget(dw_label
, row
, 0, Qt::AlignRight
);
2048 gui_layout
->addWidget(dw_box
, row
++, 1, Qt::AlignLeft
);
2050 gui_layout
->setRowMinimumHeight(row
, 30); // XXX urgh, pixels...
2051 gui_layout
->setRowStretch(row
++, 1);
2053 gui_layout
->addLayout(run_layout
, row
, 0, row
, -1);
2055 // create dummy widget to register layout
2056 QWidget
* main_widget
= new QWidget
;
2057 main_widget
->setLayout(gui_layout
);
2058 setCentralWidget(main_widget
);
2059 setWindowTitle("TTFautohint");
2063 // XXX distances are specified in pixels,
2064 // making the layout dependent on the output device resolution
2066 Main_GUI::create_horizontal_layout()
2069 QGridLayout
* file_layout
= new QGridLayout
;
2071 file_layout
->addWidget(input_label
, 0, 0, Qt::AlignRight
);
2072 file_layout
->addWidget(input_line
, 0, 1);
2073 file_layout
->addWidget(input_button
, 0, 2);
2075 file_layout
->setRowStretch(1, 1);
2077 file_layout
->addWidget(output_label
, 2, 0, Qt::AlignRight
);
2078 file_layout
->addWidget(output_line
, 2, 1);
2079 file_layout
->addWidget(output_button
, 2, 2);
2081 file_layout
->setRowStretch(3, 1);
2083 file_layout
->addWidget(control_label
, 4, 0, Qt::AlignRight
);
2084 file_layout
->addWidget(control_line
, 4, 1);
2085 file_layout
->addWidget(control_button
, 4, 2);
2087 file_layout
->setRowStretch(5, 1);
2089 file_layout
->addWidget(reference_label
, 6, 0, Qt::AlignRight
);
2090 file_layout
->addWidget(reference_line
, 6, 1);
2091 file_layout
->addWidget(reference_button
, 6, 2);
2094 QGridLayout
* run_layout
= new QGridLayout
;
2096 run_layout
->addWidget(watch_box
, 0, 1);
2097 run_layout
->addWidget(run_button
, 0, 3, Qt::AlignRight
);
2098 run_layout
->setColumnStretch(0, 2);
2099 run_layout
->setColumnStretch(2, 3);
2100 run_layout
->setColumnStretch(4, 1);
2105 QGridLayout
* gui_layout
= new QGridLayout
;
2106 QFrame
* hline
= new QFrame
;
2107 hline
->setFrameShape(QFrame::HLine
);
2108 int row
= 0; // this counter simplifies inserting new items
2111 gui_layout
->setColumnMinimumWidth(0, 10); // XXX urgh, pixels...
2112 gui_layout
->setColumnStretch(0, 1);
2115 gui_layout
->setRowMinimumHeight(row
, 10); // XXX urgh, pixels...
2116 gui_layout
->setRowStretch(row
++, 1);
2118 gui_layout
->addLayout(file_layout
, row
, 0, row
, -1);
2119 gui_layout
->setRowStretch(row
++, 1);
2121 gui_layout
->addWidget(hline
, row
, 0, row
, -1);
2122 gui_layout
->setRowStretch(row
++, 1);
2124 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
2125 gui_layout
->setRowStretch(row
++, 1);
2127 gui_layout
->addWidget(min_label
, row
, 1, Qt::AlignRight
);
2128 gui_layout
->addWidget(min_box
, row
++, 2, Qt::AlignLeft
);
2129 gui_layout
->addWidget(max_label
, row
, 1, Qt::AlignRight
);
2130 gui_layout
->addWidget(max_box
, row
++, 2, Qt::AlignLeft
);
2132 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
2133 gui_layout
->setRowStretch(row
++, 1);
2135 gui_layout
->addWidget(default_label
, row
, 1, Qt::AlignRight
);
2136 gui_layout
->addWidget(default_box
, row
++, 2, Qt::AlignLeft
);
2138 QGridLayout
* fallback_layout
= new QGridLayout
;
2139 fallback_layout
->addWidget(fallback_label
, 0, 0, Qt::AlignRight
);
2140 fallback_layout
->addWidget(fallback_hint_or_scale_box
, 0, 1, Qt::AlignLeft
);
2142 gui_layout
->addLayout(fallback_layout
, row
, 1, Qt::AlignRight
);
2143 gui_layout
->addWidget(fallback_box
, row
++, 2, Qt::AlignLeft
);
2145 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
2146 gui_layout
->setRowStretch(row
++, 1);
2148 gui_layout
->addWidget(limit_label
, row
, 1, Qt::AlignRight
);
2149 gui_layout
->addWidget(limit_box
, row
++, 2, Qt::AlignLeft
);
2150 gui_layout
->addWidget(no_limit_box
, row
++, 2);
2152 gui_layout
->addWidget(x_increase_label
, row
, 1, Qt::AlignRight
);
2153 gui_layout
->addWidget(x_increase_box
, row
++, 2, Qt::AlignLeft
);
2154 gui_layout
->addWidget(no_x_increase_box
, row
++, 2);
2156 gui_layout
->addWidget(snapping_label
, row
, 1, Qt::AlignRight
);
2157 gui_layout
->addWidget(snapping_line
, row
++, 2, Qt::AlignLeft
);
2159 gui_layout
->addWidget(stem_width_label
, row
, 1, Qt::AlignRight
);
2160 gui_layout
->addWidget(stem_width_box
, row
++, 2, Qt::AlignLeft
);
2161 gui_layout
->addWidget(default_stem_width_box
, row
++, 2);
2164 gui_layout
->setColumnMinimumWidth(3, 20); // XXX urgh, pixels...
2165 gui_layout
->setColumnStretch(3, 1);
2169 gui_layout
->addWidget(wincomp_box
, row
++, 4);
2170 gui_layout
->addWidget(adjust_box
, row
++, 4);
2171 gui_layout
->addWidget(hint_box
, row
++, 4);
2172 gui_layout
->addWidget(symbol_box
, row
++, 4);
2173 gui_layout
->addWidget(dehint_box
, row
++, 4);
2175 gui_layout
->addWidget(info_label
, row
, 3, Qt::AlignRight
);
2176 gui_layout
->addWidget(info_box
, row
++, 4, Qt::AlignLeft
);
2177 gui_layout
->addWidget(TTFA_box
, row
++, 4);
2178 gui_layout
->addWidget(family_suffix_label
, row
, 3, Qt::AlignRight
);
2179 gui_layout
->addWidget(family_suffix_line
, row
++, 4, Qt::AlignLeft
);
2180 gui_layout
->addWidget(ref_idx_label
, row
, 3, Qt::AlignRight
);
2181 gui_layout
->addWidget(ref_idx_box
, row
++, 4, Qt::AlignLeft
);
2183 gui_layout
->setRowMinimumHeight(row
, 20); // XXX urgh, pixels...
2184 gui_layout
->setRowStretch(row
++, 1);
2186 // this item spans two columns
2187 gui_layout
->addWidget(stem_label
, row
++, 3, 1, 2, Qt::AlignCenter
);
2189 gui_layout
->addWidget(gray_label
, row
, 3, Qt::AlignRight
);
2190 gui_layout
->addWidget(gray_box
, row
++, 4, Qt::AlignLeft
);
2191 gui_layout
->addWidget(gdi_label
, row
, 3, Qt::AlignRight
);
2192 gui_layout
->addWidget(gdi_box
, row
++, 4, Qt::AlignLeft
);
2193 gui_layout
->addWidget(dw_label
, row
, 3, Qt::AlignRight
);
2194 gui_layout
->addWidget(dw_box
, row
++, 4, Qt::AlignLeft
);
2196 gui_layout
->setRowMinimumHeight(row
, 30); // XXX urgh, pixels...
2197 gui_layout
->setRowStretch(row
++, 1);
2199 gui_layout
->addLayout(run_layout
, row
, 0, row
, -1);
2202 gui_layout
->setColumnMinimumWidth(5, 10); // XXX urgh, pixels...
2203 gui_layout
->setColumnStretch(5, 1);
2205 // create dummy widget to register layout
2206 QWidget
* main_widget
= new QWidget
;
2207 main_widget
->setLayout(gui_layout
);
2208 setCentralWidget(main_widget
);
2209 setWindowTitle("TTFautohint");
2214 Main_GUI::create_connections()
2216 connect(input_button
, SIGNAL(clicked()),
2217 SLOT(browse_input()));
2218 connect(output_button
, SIGNAL(clicked()),
2219 SLOT(browse_output()));
2220 connect(control_button
, SIGNAL(clicked()),
2221 SLOT(browse_control()));
2222 connect(reference_button
, SIGNAL(clicked()),
2223 SLOT(browse_reference()));
2225 connect(input_line
, SIGNAL(textChanged(QString
)),
2227 connect(output_line
, SIGNAL(textChanged(QString
)),
2230 connect(input_line
, SIGNAL(editingFinished()),
2231 SLOT(absolute_input()));
2232 connect(output_line
, SIGNAL(editingFinished()),
2233 SLOT(absolute_output()));
2234 connect(control_line
, SIGNAL(editingFinished()),
2235 SLOT(absolute_control()));
2236 connect(reference_line
, SIGNAL(editingFinished()),
2237 SLOT(absolute_reference()));
2239 connect(reference_line
, SIGNAL(editingFinished()),
2240 SLOT(set_ref_idx_box_max()));
2242 connect(min_box
, SIGNAL(valueChanged(int)),
2244 connect(max_box
, SIGNAL(valueChanged(int)),
2247 connect(limit_box
, SIGNAL(valueChanged(int)),
2248 SLOT(check_limit()));
2249 connect(no_limit_box
, SIGNAL(clicked()),
2250 SLOT(check_no_limit()));
2252 connect(no_x_increase_box
, SIGNAL(clicked()),
2253 SLOT(check_no_x_increase()));
2255 connect(snapping_line
, SIGNAL(editingFinished()),
2256 SLOT(check_number_set()));
2257 connect(snapping_line
, SIGNAL(textEdited(QString
)),
2258 SLOT(clear_status_bar()));
2260 connect(family_suffix_line
, SIGNAL(editingFinished()),
2261 SLOT(check_family_suffix()));
2262 connect(family_suffix_line
, SIGNAL(textEdited(QString
)),
2263 SLOT(clear_status_bar()));
2265 connect(default_stem_width_box
, SIGNAL(clicked()),
2266 SLOT(check_default_stem_width()));
2268 connect(dehint_box
, SIGNAL(clicked()),
2269 SLOT(check_dehint()));
2271 connect(file_watcher
, SIGNAL(fileChanged(const QString
&)),
2272 SLOT(start_timer()));
2273 connect(timer
, SIGNAL(timeout()),
2274 SLOT(watch_files()));
2276 connect(watch_box
, SIGNAL(clicked()),
2277 SLOT(check_watch()));
2279 connect(run_button
, SIGNAL(clicked()),
2285 Main_GUI::create_actions()
2287 exit_act
= new QAction(tr("E&xit"), this);
2288 exit_act
->setShortcuts(QKeySequence::Quit
);
2289 connect(exit_act
, SIGNAL(triggered()), SLOT(close()));
2291 about_act
= new QAction(tr("&About"), this);
2292 connect(about_act
, SIGNAL(triggered()), SLOT(about()));
2294 about_Qt_act
= new QAction(tr("About &Qt"), this);
2295 connect(about_Qt_act
, SIGNAL(triggered()), qApp
, SLOT(aboutQt()));
2300 Main_GUI::create_menus()
2302 file_menu
= menuBar()->addMenu(tr("&File"));
2303 file_menu
->addAction(exit_act
);
2305 help_menu
= menuBar()->addMenu(tr("&Help"));
2306 help_menu
->addAction(about_act
);
2307 help_menu
->addAction(about_Qt_act
);
2312 Main_GUI::create_status_bar()
2314 statusBar()->showMessage("");
2319 Main_GUI::set_defaults()
2321 min_box
->setValue(hinting_range_min
);
2322 max_box
->setValue(hinting_range_max
);
2324 default_box
->setCurrentIndex(default_script_idx
);
2325 fallback_hint_or_scale_box
->setCurrentIndex(fallback_scaling
);
2326 fallback_box
->setCurrentIndex(fallback_script_idx
);
2328 limit_box
->setValue(hinting_limit
? hinting_limit
: hinting_range_max
);
2329 // handle command line option `--hinting-limit=0'
2332 hinting_limit
= max_box
->value();
2333 no_limit_box
->setChecked(true);
2336 x_increase_box
->setValue(increase_x_height
? increase_x_height
2337 : TA_INCREASE_X_HEIGHT
);
2338 // handle command line option `--increase-x-height=0'
2339 if (!increase_x_height
)
2341 increase_x_height
= TA_INCREASE_X_HEIGHT
;
2342 no_x_increase_box
->setChecked(true);
2345 snapping_line
->setText(x_height_snapping_exceptions_string
);
2346 family_suffix_line
->setText(family_suffix
);
2348 if (fallback_stem_width
)
2349 stem_width_box
->setValue(fallback_stem_width
);
2352 stem_width_box
->setValue(50);
2353 default_stem_width_box
->setChecked(true);
2356 if (windows_compatibility
)
2357 wincomp_box
->setChecked(true);
2358 if (adjust_subglyphs
)
2359 adjust_box
->setChecked(true);
2360 if (hint_composites
)
2361 hint_box
->setChecked(true);
2363 symbol_box
->setChecked(true);
2365 dehint_box
->setChecked(true);
2367 info_box
->setCurrentIndex(0);
2368 else if (detailed_info
)
2369 info_box
->setCurrentIndex(2);
2371 info_box
->setCurrentIndex(1);
2373 TTFA_box
->setChecked(true);
2375 gray_box
->setCurrentIndex(gray_stem_width_mode
+ 1);
2376 gdi_box
->setCurrentIndex(gdi_cleartype_stem_width_mode
+ 1);
2377 dw_box
->setCurrentIndex(dw_cleartype_stem_width_mode
+ 1);
2379 run_button
->setEnabled(false);
2386 check_no_x_increase();
2391 // do this last since it disables almost everything
2397 Main_GUI::read_settings()
2400 // QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
2401 // QSize size = settings.value("size", QSize(400, 400)).toSize();
2408 Main_GUI::write_settings()
2411 // settings.setValue("pos", pos());
2412 // settings.setValue("size", size());
2415 // end of maingui.cpp