mirror of
https://git.code.sf.net/p/fldigi/flrig
synced 2026-08-13 17:28:24 -04:00
fonts
* fix slow start caused by font fixed/proportional enumeration
- fixed point evaluator moved to separate thread during first
instantiation of Font_Browser class. Actual time to enumerate
2650 fonts on an i5 3.2 GHz system is approximately 25
seconds. Background process does not effect UI, but selection
of fixed fonts in font browser dialog may not show all of the
fixed fonts until the evaluator thread exits.
This commit is contained in:
parent
e95333b9bf
commit
c735fb253d
2 changed files with 384 additions and 267 deletions
|
|
@ -1,10 +1,16 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// based on similar widget by Mariwan Jalal, in FLTK source
|
||||
// Font_Browser.h v 0.0.1 2005-10-17
|
||||
//
|
||||
// for the Fast Light Tool Kit (FLTK) 1.1.x .
|
||||
//
|
||||
// David Freese, w1hkj@w1hkj.com
|
||||
// based on similar widget by Mariwan Jalal
|
||||
//
|
||||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014
|
||||
// Copyright (C) 2014-2020
|
||||
// David Freese, W1HKJ
|
||||
//
|
||||
// This file is part of flrig.
|
||||
// This file is part of flrig
|
||||
//
|
||||
// flrig is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -23,73 +29,101 @@
|
|||
#ifndef FONTBROWSER_H
|
||||
#define FONTBROWSER_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <FL/Enumerations.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <FL/Fl_Widget.H>
|
||||
#include <FL/Fl_Browser.H>
|
||||
#include <FL/Fl_Button.H>
|
||||
#include <FL/Fl_Return_Button.H>
|
||||
#include <FL/Fl_Check_Button.H>
|
||||
#include "flslider2.h"
|
||||
|
||||
// Preview box for showing font
|
||||
class Preview_Box : public Fl_Widget
|
||||
{
|
||||
private:
|
||||
int fontName;
|
||||
int fontSize;
|
||||
Fl_Color fontColor;
|
||||
int fontName;
|
||||
int fontSize;
|
||||
Fl_Color fontColor;
|
||||
|
||||
void draw();
|
||||
void draw();
|
||||
public:
|
||||
Preview_Box(int x, int y, int w, int h, const char* l);
|
||||
void SetFont( int fontname, int fontsize, Fl_Color c);
|
||||
Preview_Box(int x, int y, int w, int h, const char* l);
|
||||
void SetFont( int fontname, int fontsize, Fl_Color c);
|
||||
};
|
||||
|
||||
// Font browser widget
|
||||
class Font_Browser : public Fl_Window
|
||||
{
|
||||
friend void *find_fixed_fonts(void *);
|
||||
|
||||
public:
|
||||
enum filter_t { FIXED_WIDTH, VARIABLE_WIDTH, ALL_TYPES };
|
||||
struct font_pair {
|
||||
int nbr;
|
||||
std::string *name;
|
||||
font_pair() {
|
||||
nbr = 0;
|
||||
name = 0;
|
||||
}
|
||||
~font_pair() {
|
||||
if (name) delete name;
|
||||
}
|
||||
};
|
||||
|
||||
enum filter_t { FIXED_WIDTH, VARIABLE_WIDTH, ALL_TYPES };
|
||||
|
||||
// these are shared by all instances of Font_Browser
|
||||
// created for instance 1 and deleted for instance 0
|
||||
|
||||
static int *fixed;
|
||||
static font_pair *font_pairs;
|
||||
static int instance;
|
||||
static int numfonts;
|
||||
|
||||
private:
|
||||
int numfonts;
|
||||
Fl_Font fontnbr;
|
||||
int fontsize;
|
||||
Fl_Color fontcolor;
|
||||
filter_t filter;
|
||||
void *data_;
|
||||
|
||||
Fl_Browser *lst_Font;
|
||||
Fl_Browser *lst_Size;
|
||||
Fl_Value_Input2 *txt_Size;
|
||||
Fl_Return_Button *btn_OK;
|
||||
Fl_Button *btn_Cancel;
|
||||
Fl_Button *btn_Color;
|
||||
Preview_Box *box_Example;
|
||||
Fl_Font fontnbr;
|
||||
int fontsize;
|
||||
Fl_Color fontcolor;
|
||||
filter_t filter;
|
||||
void *data_;
|
||||
|
||||
void FontSort();
|
||||
Fl_Callback* callback_;
|
||||
Fl_Browser *lst_Font;
|
||||
Fl_Browser *lst_Size;
|
||||
Fl_Value_Input2 *txt_Size;
|
||||
Fl_Return_Button *btn_OK;
|
||||
Fl_Button *btn_Cancel;
|
||||
Fl_Button *btn_Color;
|
||||
Fl_Check_Button *btn_fixed;
|
||||
Preview_Box *box_Example;
|
||||
|
||||
Fl_Callback* callback_;
|
||||
|
||||
public:
|
||||
Font_Browser(int x = 100, int y = 100, int w = 400, int h = 225, const char *lbl = "Font Browser");
|
||||
void callback(Fl_Callback* cb, void *d = 0) { callback_ = cb; data_ = d; }
|
||||
static void fb_callback(Fl_Widget* w, void* arg);
|
||||
void FontNameSelect();
|
||||
void ColorSelect();
|
||||
Font_Browser(int x = 100, int y = 100, int w = 430, int h = 225, const char *lbl = "Font Browser");
|
||||
~Font_Browser();
|
||||
|
||||
int numFonts() { return numfonts; }
|
||||
void fontNumber(Fl_Font n);
|
||||
Fl_Font fontNumber() { return fontnbr; }
|
||||
void fontSize(int s);
|
||||
int fontSize() { return fontsize; }
|
||||
void fontColor(Fl_Color c);
|
||||
Fl_Color fontColor() { return fontcolor; };
|
||||
void callback(Fl_Callback* cb, void *d = 0) { callback_ = cb; data_ = d; }
|
||||
static void fb_callback(Fl_Widget* w, void* arg);
|
||||
void FontNameSelect();
|
||||
void ColorSelect();
|
||||
|
||||
const char *fontName() { return lst_Font->text(lst_Font->value()); }
|
||||
void fontName(const char* n);
|
||||
int numFonts() { return numfonts; }
|
||||
void fontNumber(Fl_Font n);
|
||||
Fl_Font fontNumber() { return fontnbr; }
|
||||
void fontSize(int s);
|
||||
int fontSize() { return fontsize; }
|
||||
void fontColor(Fl_Color c);
|
||||
Fl_Color fontColor() { return fontcolor; };
|
||||
|
||||
static bool fixed_width(Fl_Font f);
|
||||
void fontFilter(filter_t filter);
|
||||
const char *fontName() { return lst_Font->text(lst_Font->value()); }
|
||||
void fontName(const char* n);
|
||||
|
||||
static bool fixed_width(Fl_Font f);
|
||||
|
||||
void fontFilter(filter_t filter);
|
||||
};
|
||||
|
||||
extern Font_Browser* font_browser;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// Copyright (C) 2014
|
||||
// Copyright (C) 2014-2020
|
||||
// David Freese, W1HKJ
|
||||
//
|
||||
// based on similar widget by Mariwan Jalal and distributed with fltk
|
||||
//
|
||||
// This file is part of flrig.
|
||||
// This file is part of flrig
|
||||
//
|
||||
// flrig is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -26,7 +24,12 @@
|
|||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_Color_Chooser.H>
|
||||
|
|
@ -36,308 +39,388 @@
|
|||
#include "flslider2.h"
|
||||
#include "gettext.h"
|
||||
|
||||
#include "threads.h"
|
||||
#include "debug.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void find_fonts();
|
||||
|
||||
Font_Browser* font_browser;
|
||||
|
||||
int Font_Browser::instance = 0;
|
||||
int *Font_Browser::fixed = 0;
|
||||
int Font_Browser::numfonts = 0;
|
||||
|
||||
Font_Browser::font_pair *Font_Browser::font_pairs = 0;
|
||||
|
||||
|
||||
static int font_compare(const void *p1, const void *p2)
|
||||
{
|
||||
std::string s1 = *((const Font_Browser::font_pair *)p1)->name;
|
||||
std::string s2 = *((const Font_Browser::font_pair *)p2)->name;
|
||||
return strcasecmp( s1.c_str(), s2.c_str() );
|
||||
}
|
||||
|
||||
// Font Color selected
|
||||
|
||||
void Font_Browser::ColorSelect()
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
Fl::get_color(fontcolor, r, g, b);
|
||||
if (fl_color_chooser(_("Font color"), r, g, b) == 0)
|
||||
return;
|
||||
fontcolor = fl_rgb_color(r, g, b);
|
||||
btn_Color->color(fontcolor);
|
||||
unsigned char r, g, b;
|
||||
Fl::get_color(fontcolor, r, g, b);
|
||||
if (fl_color_chooser(_("Font color"), r, g, b) == 0)
|
||||
return;
|
||||
fontcolor = fl_rgb_color(r, g, b);
|
||||
btn_Color->color(fontcolor);
|
||||
btn_Color->labelcolor( fl_contrast(FL_BLACK, fontcolor));
|
||||
}
|
||||
|
||||
void Font_Browser::fb_callback(Fl_Widget* w, void* arg)
|
||||
{
|
||||
Font_Browser* fb = reinterpret_cast<Font_Browser*>(arg);
|
||||
Font_Browser* fb = reinterpret_cast<Font_Browser*>(arg);
|
||||
|
||||
if (w == fb->btn_Cancel)
|
||||
if (w == fb->btn_fixed) {
|
||||
if (fb->btn_fixed->value())
|
||||
fb->fontFilter(FIXED_WIDTH);
|
||||
else
|
||||
fb->fontFilter(ALL_TYPES);
|
||||
return;
|
||||
}
|
||||
|
||||
if (w == fb->btn_Cancel)
|
||||
fb->hide();
|
||||
else if (w == fb->btn_OK) {
|
||||
if (fb->callback_)
|
||||
(*fb->callback_)(fb, fb->data_);
|
||||
}
|
||||
else if (w == fb->btn_Color)
|
||||
fb->ColorSelect();
|
||||
else if (w == fb->lst_Font)
|
||||
fb->FontNameSelect();
|
||||
else {
|
||||
if (w == fb->lst_Size)
|
||||
fb->txt_Size->value(strtol(fb->lst_Size->text(fb->lst_Size->value()), NULL, 10));
|
||||
fb->fontsize = static_cast<int>(fb->txt_Size->value());
|
||||
}
|
||||
fb->box_Example->SetFont(fb->fontnbr, fb->fontsize, fb->fontcolor);
|
||||
}
|
||||
|
||||
// Sort the font list
|
||||
void Font_Browser::FontSort()
|
||||
{
|
||||
int size = lst_Font->size();
|
||||
for ( int t = 1; t <= size - 1; t++ )
|
||||
for ( int r = t+1; r <= size; r++ )
|
||||
if ( strcasecmp(lst_Font->text(t), lst_Font->text(r)) > 0 )
|
||||
lst_Font->swap(t,r);
|
||||
else if (w == fb->btn_OK) {
|
||||
if (fb->callback_)
|
||||
(*fb->callback_)(fb, fb->data_);
|
||||
}
|
||||
|
||||
else if (w == fb->btn_Color)
|
||||
fb->ColorSelect();
|
||||
|
||||
else if (w == fb->lst_Font)
|
||||
fb->FontNameSelect();
|
||||
|
||||
else {
|
||||
if (w == fb->lst_Size)
|
||||
fb->txt_Size->value(strtol(fb->lst_Size->text(fb->lst_Size->value()), NULL, 10));
|
||||
fb->fontsize = static_cast<int>(fb->txt_Size->value());
|
||||
}
|
||||
fb->box_Example->SetFont(fb->fontnbr, fb->fontsize, fb->fontcolor);
|
||||
}
|
||||
|
||||
// Font Name changed callback
|
||||
void Font_Browser::FontNameSelect()
|
||||
{
|
||||
int fn = lst_Font->value();
|
||||
if (!fn)
|
||||
return;
|
||||
int fn = lst_Font->value();
|
||||
if (!fn)
|
||||
return;
|
||||
|
||||
fontnbr = (Fl_Font)reinterpret_cast<intptr_t>(lst_Font->data(fn));
|
||||
fontnbr = (Fl_Font)reinterpret_cast<intptr_t>(lst_Font->data(fn));
|
||||
|
||||
// get sizes and fill browser; skip first element if it is zero
|
||||
lst_Size->clear();
|
||||
int nsizes, *sizes;
|
||||
char buf[4];
|
||||
nsizes = Fl::get_font_sizes(fontnbr, sizes);
|
||||
//
|
||||
for (int i = !*sizes; i < nsizes; i++)
|
||||
// get sizes and fill browser; skip first element if it is zero
|
||||
lst_Size->clear();
|
||||
int nsizes, *sizes;
|
||||
char buf[4];
|
||||
nsizes = Fl::get_font_sizes(fontnbr, sizes);
|
||||
//
|
||||
for (int i = !*sizes; i < nsizes; i++)
|
||||
if ((size_t)snprintf(buf, sizeof(buf), "%d", sizes[i]) < sizeof(buf))
|
||||
lst_Size->add(buf, reinterpret_cast<void*>(sizes[i]));
|
||||
lst_Size->add(buf, reinterpret_cast<void*>(sizes[i]));
|
||||
|
||||
// scalable font with no suggested sizes
|
||||
if (!lst_Size->size()) {
|
||||
// scalable font with no suggested sizes
|
||||
if (!lst_Size->size()) {
|
||||
for (int i = 1; i <= 48; i++) {
|
||||
snprintf(buf, sizeof(buf), "%d", i);
|
||||
lst_Size->add(buf, reinterpret_cast<void*>(i));
|
||||
snprintf(buf, sizeof(buf), "%d", i);
|
||||
lst_Size->add(buf, reinterpret_cast<void*>(i));
|
||||
}
|
||||
}
|
||||
fontSize(fontsize);
|
||||
}
|
||||
fontSize(fontsize);
|
||||
}
|
||||
|
||||
Font_Browser::Font_Browser(int x, int y, int w, int h, const char *lbl )
|
||||
: Fl_Window(x, y, w, h, lbl)
|
||||
: Fl_Window(x, y, w, h, lbl)
|
||||
{
|
||||
lst_Font = new Fl_Browser(5, 15, 280, 125, _("Font:"));
|
||||
lst_Font->align(FL_ALIGN_TOP_LEFT);
|
||||
lst_Font->type(FL_HOLD_BROWSER);
|
||||
lst_Font->callback(fb_callback, this);
|
||||
lst_Font = new Fl_Browser(5, 15, 280, 125, _("Font:"));
|
||||
lst_Font->align(FL_ALIGN_TOP_LEFT);
|
||||
lst_Font->type(FL_HOLD_BROWSER);
|
||||
lst_Font->callback(fb_callback, this);
|
||||
fixed = 0;
|
||||
|
||||
txt_Size = new Fl_Value_Input2(290, 15, 50, 22, _("Size:"));
|
||||
txt_Size->align(FL_ALIGN_TOP_LEFT);
|
||||
txt_Size->range(1.0, 48.0);
|
||||
txt_Size->step(1.0);
|
||||
txt_Size->callback(fb_callback, this);
|
||||
txt_Size = new Fl_Value_Input2(290, 15, 50, 22, _("Size:"));
|
||||
txt_Size->align(FL_ALIGN_TOP_LEFT);
|
||||
txt_Size->range(1.0, 48.0);
|
||||
txt_Size->step(1.0);
|
||||
txt_Size->callback(fb_callback, this);
|
||||
|
||||
lst_Size = new Fl_Browser(290, 40, 50, 100);
|
||||
lst_Size->type(FL_HOLD_BROWSER);
|
||||
lst_Size->callback(fb_callback, this);
|
||||
lst_Size = new Fl_Browser(290, 40, 50, 100);
|
||||
lst_Size->type(FL_HOLD_BROWSER);
|
||||
lst_Size->callback(fb_callback, this);
|
||||
|
||||
btn_OK = new Fl_Return_Button(345, 40, 50, 25, _("&OK"));
|
||||
btn_OK->shortcut(0x8006f);
|
||||
btn_OK->callback(fb_callback, this);
|
||||
btn_fixed = new Fl_Check_Button(345, 15, 18, 18, _("Fixed"));
|
||||
btn_fixed->callback(fb_callback, this);
|
||||
btn_fixed->value(0);
|
||||
|
||||
btn_Cancel = new Fl_Button(345, 70, 50, 25, _("Cancel"));
|
||||
btn_Cancel->labelsize(12);
|
||||
btn_Cancel->callback(fb_callback, this);
|
||||
btn_OK = new Fl_Return_Button(345, 40, 80, 25, _("&OK"));
|
||||
btn_OK->shortcut(0x8006f);
|
||||
btn_OK->callback(fb_callback, this);
|
||||
|
||||
btn_Color = new Fl_Button(345, 100, 50, 25, _("Color"));
|
||||
btn_Color->down_box(FL_BORDER_BOX);
|
||||
btn_Color->color(FL_FOREGROUND_COLOR);
|
||||
btn_Color->callback(fb_callback, this);
|
||||
btn_Cancel = new Fl_Button(345, 70, 80, 25, _("Cancel"));
|
||||
btn_Cancel->labelsize(12);
|
||||
btn_Cancel->callback(fb_callback, this);
|
||||
|
||||
box_Example = new Preview_Box(5, 145, 390, 75, _("That crazy fox jumped over the dog again!\n"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789\n"
|
||||
"!\"#$%&'()*+,-./:;<=>?@@[\\]^_`{|}~"));
|
||||
box_Example->box(FL_DOWN_BOX);
|
||||
box_Example->align(FL_ALIGN_WRAP|FL_ALIGN_CLIP|FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
|
||||
resizable(box_Example);
|
||||
btn_Color = new Fl_Button(345, 100, 80, 25, _("Color"));
|
||||
btn_Color->down_box(FL_BORDER_BOX);
|
||||
btn_Color->color(FL_FOREGROUND_COLOR);
|
||||
btn_Color->labelcolor( fl_contrast(FL_BLACK, FL_FOREGROUND_COLOR));
|
||||
btn_Color->callback(fb_callback, this);
|
||||
|
||||
set_modal();
|
||||
end();
|
||||
box_Example = new Preview_Box(5, 145, 420, 75,
|
||||
_("\
|
||||
abcdefghijklmnopqrstuvwxyz\n\
|
||||
ABCDEFGHIJKLMNOPQRSTUVWXYZ\n\
|
||||
0123456789"
|
||||
) );
|
||||
box_Example->box(FL_DOWN_BOX);
|
||||
box_Example->align(FL_ALIGN_WRAP|FL_ALIGN_CLIP|FL_ALIGN_CENTER|FL_ALIGN_INSIDE);
|
||||
resizable(box_Example);
|
||||
|
||||
// Initializations
|
||||
set_modal();
|
||||
end();
|
||||
|
||||
this->callback_ = 0; // Initialize Widgets callback
|
||||
this->data_ = 0; // And the data
|
||||
// Initializations
|
||||
|
||||
numfonts = Fl::set_fonts(0); // Nr of fonts available on the server
|
||||
this->callback_ = 0; // Initialize Widgets callback
|
||||
this->data_ = 0; // And the data
|
||||
|
||||
const char* name;
|
||||
for(int i = 0; i < numfonts; i++) {
|
||||
name = Fl::get_font_name((Fl_Font)i);
|
||||
if (isalpha(*name))
|
||||
lst_Font->add(name, reinterpret_cast<void*>(i));
|
||||
}
|
||||
FontSort();
|
||||
std::string fntname;
|
||||
bool ok = true;
|
||||
|
||||
fontnbr = FL_HELVETICA;;
|
||||
fontsize = FL_NORMAL_SIZE; // Font Size to be used
|
||||
fontcolor = FL_FOREGROUND_COLOR;
|
||||
filter = ALL_TYPES;
|
||||
if (instance == 0) {
|
||||
|
||||
lst_Font->value(1);
|
||||
FontNameSelect();
|
||||
++instance;
|
||||
|
||||
//! Fl::focus(lst_Font);
|
||||
numfonts = Fl::set_fonts(0); // Nr of fonts available on the server
|
||||
font_pairs = new font_pair[numfonts];
|
||||
fixed = new int[numfonts];
|
||||
|
||||
xclass(PACKAGE_NAME);
|
||||
int j = 0;
|
||||
for (int i = 0; i < numfonts; i++) {
|
||||
fntname = Fl::get_font_name((Fl_Font)i);
|
||||
ok = true;
|
||||
for (size_t k = 0; k < fntname.length(); k++) {
|
||||
if (fntname[k] < ' ' || fntname[k] > 'z' ||
|
||||
fntname[k] == '\\' || fntname[k] == '@') { // disallowed chars in browser widget
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fntname.empty()) ok = false;
|
||||
if (ok) {
|
||||
font_pairs[j].name = new std::string;
|
||||
*(font_pairs[j].name) = fntname;
|
||||
font_pairs[j].nbr = i;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
numfonts = j;
|
||||
|
||||
qsort(&font_pairs[0], numfonts, sizeof(font_pair), font_compare);
|
||||
|
||||
for (int i = 0; i < numfonts; i++) {
|
||||
lst_Font->add((*(font_pairs[i].name)).c_str(), reinterpret_cast<void *>(font_pairs[i].nbr));
|
||||
fixed[i] = 0;
|
||||
}
|
||||
find_fonts();
|
||||
} else {
|
||||
++instance;
|
||||
for (int i = 0; i < numfonts; i++) {
|
||||
lst_Font->add((*(font_pairs[i].name)).c_str(), reinterpret_cast<void *>(font_pairs[i].nbr));
|
||||
}
|
||||
}
|
||||
|
||||
fontnbr = FL_HELVETICA;;
|
||||
fontsize = FL_NORMAL_SIZE;
|
||||
fontcolor = FL_FOREGROUND_COLOR;
|
||||
filter = ALL_TYPES;
|
||||
|
||||
lst_Font->value(1);
|
||||
FontNameSelect();
|
||||
|
||||
xclass(PACKAGE_NAME);
|
||||
}
|
||||
|
||||
Font_Browser::~Font_Browser()
|
||||
{
|
||||
--instance;
|
||||
if (instance == 0) {
|
||||
delete [] fixed;
|
||||
fixed = 0;
|
||||
delete [] font_pairs;
|
||||
font_pairs = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Font_Browser::fontNumber(Fl_Font n)
|
||||
{
|
||||
fontnbr = n;
|
||||
lst_Font->value(1);
|
||||
int s = lst_Font->size();
|
||||
for (int i = 1; i < s; i++ ) {
|
||||
if ((Fl_Font)reinterpret_cast<intptr_t>(lst_Font->data(i)) == n) {
|
||||
lst_Font->value(i);
|
||||
FontNameSelect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
fontnbr = n;
|
||||
lst_Font->value(1);
|
||||
int s = lst_Font->size();
|
||||
for (int i = 1; i < s; i++ ) {
|
||||
if ((Fl_Font)reinterpret_cast<intptr_t>(lst_Font->data(i)) == n) {
|
||||
lst_Font->value(i);
|
||||
FontNameSelect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Font_Browser::fontSize(int s)
|
||||
{
|
||||
fontsize = s;
|
||||
int n = lst_Size->size();
|
||||
for (int i = 1; i < n; i++) {
|
||||
fontsize = s;
|
||||
int n = lst_Size->size();
|
||||
for (int i = 1; i < n; i++) {
|
||||
if ((intptr_t)lst_Size->data(i) == fontsize) {
|
||||
lst_Size->value(i);
|
||||
break;
|
||||
lst_Size->value(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
txt_Size->value(s);
|
||||
}
|
||||
txt_Size->value(s);
|
||||
}
|
||||
|
||||
void Font_Browser::fontColor(Fl_Color c)
|
||||
{
|
||||
btn_Color->color(fontcolor = c);
|
||||
box_Example->SetFont(fontnbr, fontsize, fontcolor);
|
||||
box_Example->redraw();
|
||||
btn_Color->color(fontcolor = c);
|
||||
box_Example->SetFont(fontnbr, fontsize, fontcolor);
|
||||
box_Example->redraw();
|
||||
}
|
||||
|
||||
void Font_Browser::fontName(const char* n)
|
||||
{
|
||||
int s = lst_Font->size();
|
||||
for (int i = 1; i < s; i++) {
|
||||
if (!strcmp(lst_Font->text(i), n)) {
|
||||
lst_Font->value(i);
|
||||
FontNameSelect();
|
||||
}
|
||||
}
|
||||
int s = lst_Font->size();
|
||||
for (int i = 1; i < s; i++) {
|
||||
if (!strcmp(lst_Font->text(i), n)) {
|
||||
lst_Font->value(i);
|
||||
FontNameSelect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Font_Browser::fontFilter(filter_t filter)
|
||||
{
|
||||
int s = lst_Font->size();
|
||||
|
||||
switch (filter) {
|
||||
case FIXED_WIDTH:
|
||||
for (int i = 0; i < s; i++) {
|
||||
if (fixed[i])
|
||||
lst_Font->show(i + 1);
|
||||
else
|
||||
lst_Font->hide(i + 1);
|
||||
}
|
||||
btn_fixed->value(1);
|
||||
break;
|
||||
case VARIABLE_WIDTH:
|
||||
for (int i = 0; i < s; i++) {
|
||||
if (!fixed[i])
|
||||
lst_Font->show(i + 1);
|
||||
else
|
||||
lst_Font->hide(i + 1);
|
||||
}
|
||||
btn_fixed->value(0);
|
||||
break;
|
||||
case ALL_TYPES:
|
||||
for (int i = 0; i < s; i++)
|
||||
lst_Font->show(i + 1);
|
||||
btn_fixed->value(0);
|
||||
break;
|
||||
}
|
||||
lst_Font->redraw();
|
||||
lst_Font->topline(lst_Font->value());
|
||||
}
|
||||
|
||||
// separate thread used to evaluate fixed / proportional fonts
|
||||
// friend of Font_Browser
|
||||
// launched by Font_Browser instance 1
|
||||
|
||||
static pthread_t find_font_thread;
|
||||
|
||||
//#define FBDEBUG 1
|
||||
|
||||
static int is_fixed;
|
||||
Fl_Font test_font;
|
||||
void font_test(void *)
|
||||
{
|
||||
fl_font(test_font, FL_NORMAL_SIZE);
|
||||
is_fixed = (fl_width(".") == fl_width("W"));
|
||||
}
|
||||
|
||||
void *find_fixed_fonts(void *)
|
||||
{
|
||||
#ifdef FBDEBUG
|
||||
FILE *sys_fonts = fopen("fonts.txt", "w");
|
||||
fprintf(sys_fonts, "Font #, Type, Name\n");
|
||||
#endif
|
||||
for (int i = 0; i < Font_Browser::numfonts; i++) {
|
||||
test_font = Font_Browser::font_pairs[i].nbr;
|
||||
is_fixed = -1;
|
||||
Fl::awake(font_test);
|
||||
while (is_fixed == -1) MilliSleep(10);
|
||||
Font_Browser::fixed[i] = is_fixed;
|
||||
#ifdef FBDEBUG
|
||||
fprintf(
|
||||
sys_fonts,
|
||||
"%d, %c, %s\n",
|
||||
Font_Browser::font_pairs[i].nbr,
|
||||
Font_Browser::fixed[i] ? 'F' : 'P',
|
||||
(*(Font_Browser::font_pairs[i].name)).c_str());
|
||||
#endif
|
||||
}
|
||||
#ifdef FBDEBUG
|
||||
fclose(sys_fonts);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void find_fonts()
|
||||
{
|
||||
if (pthread_create(&find_font_thread, NULL, find_fixed_fonts, NULL) < 0) {
|
||||
LOG_ERROR("%s", "pthread_create find_fixed_fonts failed");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool Font_Browser::fixed_width(Fl_Font f)
|
||||
{
|
||||
fl_font(f, FL_NORMAL_SIZE);
|
||||
return fl_width('X') == fl_width('i');
|
||||
return fl_width(".") == fl_width("W");
|
||||
}
|
||||
|
||||
#include <vector>
|
||||
#include <FL/Fl_Double_Window.H>
|
||||
#include <FL/Fl_Progress.H>
|
||||
|
||||
class Progress_Window : public Fl_Double_Window
|
||||
{
|
||||
public:
|
||||
Progress_Window(float min = 0.0f, float max = 100.0f, const char* l = 0)
|
||||
: Fl_Double_Window(200, 34), ps(5, 5, 190, 24, l)
|
||||
{
|
||||
end();
|
||||
|
||||
range(min, max);
|
||||
ps.align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE);
|
||||
ps.selection_color(FL_SELECTION_COLOR);
|
||||
set_modal();
|
||||
callback(nop);
|
||||
|
||||
if (l && *l) {
|
||||
fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
|
||||
int s = (int)(fl_width(l) + fl_width('W'));
|
||||
if (s > ps.w()) {
|
||||
ps.size(s, ps.h());
|
||||
size(ps.w() + 10, h());
|
||||
}
|
||||
}
|
||||
position(Fl::event_x_root() - w() / 2, Fl::event_y_root() - h());
|
||||
|
||||
xclass(PACKAGE_TARNAME);
|
||||
show();
|
||||
}
|
||||
void range(float min, float max) { ps.minimum(min); ps.maximum(max); }
|
||||
void value(float val) { ps.value(val); }
|
||||
static void nop(Fl_Widget*, void*) { }
|
||||
private:
|
||||
Fl_Progress ps;
|
||||
};
|
||||
|
||||
void Font_Browser::fontFilter(filter_t filter)
|
||||
{
|
||||
if (this->filter == filter)
|
||||
return;
|
||||
|
||||
int s = lst_Font->size();
|
||||
|
||||
static vector<bool> fixed;
|
||||
if (fixed.empty()) {
|
||||
Progress_Window pw(1, s, _("Reading fonts..."));
|
||||
fixed.resize(s);
|
||||
for (int i = 1; i < s; i++) {
|
||||
fixed[i] = fixed_width((Fl_Font)(intptr_t)(lst_Font->data(i)));
|
||||
pw.value(i);
|
||||
Fl::check();
|
||||
}
|
||||
}
|
||||
|
||||
switch (this->filter = filter) {
|
||||
case FIXED_WIDTH:
|
||||
for (int i = 1; i < s; i++) {
|
||||
if (fixed[i])
|
||||
lst_Font->show(i);
|
||||
else
|
||||
lst_Font->hide(i);
|
||||
}
|
||||
break;
|
||||
case VARIABLE_WIDTH:
|
||||
for (int i = 1; i < s; i++) {
|
||||
if (!fixed[i])
|
||||
lst_Font->show(i);
|
||||
else
|
||||
lst_Font->hide(i);
|
||||
}
|
||||
break;
|
||||
case ALL_TYPES:
|
||||
for (int i = 1; i < s; i++)
|
||||
lst_Font->show(i);
|
||||
break;
|
||||
}
|
||||
lst_Font->topline(lst_Font->value());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
Preview_Box::Preview_Box(int x, int y, int w, int h, const char* l)
|
||||
: Fl_Widget(x, y, w, h, l)
|
||||
{
|
||||
fontName = 1;
|
||||
fontSize = FL_NORMAL_SIZE;
|
||||
box(FL_DOWN_BOX);
|
||||
color(FL_BACKGROUND2_COLOR);
|
||||
fontColor = FL_FOREGROUND_COLOR;
|
||||
fontName = 1;
|
||||
fontSize = FL_NORMAL_SIZE;
|
||||
box(FL_DOWN_BOX);
|
||||
color(FL_BACKGROUND2_COLOR);
|
||||
fontColor = FL_FOREGROUND_COLOR;
|
||||
}
|
||||
|
||||
void Preview_Box::draw()
|
||||
{
|
||||
draw_box();
|
||||
fl_font((Fl_Font)fontName, fontSize);
|
||||
fl_color(fontColor);
|
||||
fl_draw(label(), x()+3, y()+3, w()-6, h()-6, align());
|
||||
draw_box();
|
||||
fl_font((Fl_Font)fontName, fontSize);
|
||||
fl_color(fontColor);
|
||||
fl_draw(label(), x()+3, y()+3, w()-6, h()-6, align());
|
||||
}
|
||||
|
||||
void Preview_Box::SetFont(int fontname, int fontsize, Fl_Color c)
|
||||
{
|
||||
fontName = fontname;
|
||||
fontSize = fontsize;
|
||||
fontColor = c;
|
||||
redraw();
|
||||
fontName = fontname;
|
||||
fontSize = fontsize;
|
||||
fontColor = c;
|
||||
redraw();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue