mirror of
https://github.com/fltk/fltk.git
synced 2026-05-31 22:04:26 +08:00
Fl_Cairo_Graphics_Driver: simpler way to construct the PangoLayout object.
This commit is contained in:
@@ -25,12 +25,13 @@
|
|||||||
#include <cairo/cairo.h>
|
#include <cairo/cairo.h>
|
||||||
|
|
||||||
typedef struct _PangoLayout PangoLayout;
|
typedef struct _PangoLayout PangoLayout;
|
||||||
|
typedef struct _PangoContext PangoContext;
|
||||||
typedef struct _PangoFontDescription PangoFontDescription;
|
typedef struct _PangoFontDescription PangoFontDescription;
|
||||||
|
|
||||||
|
|
||||||
class Fl_Cairo_Font_Descriptor : public Fl_Font_Descriptor {
|
class Fl_Cairo_Font_Descriptor : public Fl_Font_Descriptor {
|
||||||
public:
|
public:
|
||||||
Fl_Cairo_Font_Descriptor(const char* fontname, Fl_Fontsize size);
|
Fl_Cairo_Font_Descriptor(const char* fontname, Fl_Fontsize size, PangoContext *context);
|
||||||
FL_EXPORT ~Fl_Cairo_Font_Descriptor();
|
FL_EXPORT ~Fl_Cairo_Font_Descriptor();
|
||||||
PangoFontDescription *fontref;
|
PangoFontDescription *fontref;
|
||||||
int **width; // array of arrays of character widths
|
int **width; // array of arrays of character widths
|
||||||
@@ -42,12 +43,12 @@ class FL_EXPORT Fl_Cairo_Graphics_Driver : public Fl_Graphics_Driver {
|
|||||||
private:
|
private:
|
||||||
bool *needs_commit_tag_; // NULL or points to whether cairo surface was drawn to
|
bool *needs_commit_tag_; // NULL or points to whether cairo surface was drawn to
|
||||||
cairo_t *dummy_cairo_; // used to measure text width before showing a window
|
cairo_t *dummy_cairo_; // used to measure text width before showing a window
|
||||||
cairo_t *pango_layout_cairo_;
|
|
||||||
PangoLayout *pango_layout_;
|
|
||||||
int linestyle_;
|
int linestyle_;
|
||||||
int width_unscaled_(unsigned int c);
|
int width_unscaled_(unsigned int c);
|
||||||
protected:
|
protected:
|
||||||
cairo_t *cairo_;
|
cairo_t *cairo_;
|
||||||
|
PangoContext *pango_context_;
|
||||||
|
PangoLayout *pango_layout_;
|
||||||
public:
|
public:
|
||||||
Fl_Cairo_Graphics_Driver();
|
Fl_Cairo_Graphics_Driver();
|
||||||
virtual ~Fl_Cairo_Graphics_Driver();
|
virtual ~Fl_Cairo_Graphics_Driver();
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ static void draw_image_cb(void *data, int x, int y, int w, uchar *buf) {
|
|||||||
Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver() : Fl_Graphics_Driver() {
|
Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver() : Fl_Graphics_Driver() {
|
||||||
cairo_ = NULL;
|
cairo_ = NULL;
|
||||||
pango_layout_ = NULL;
|
pango_layout_ = NULL;
|
||||||
pango_layout_cairo_ = NULL;
|
pango_context_ = NULL;
|
||||||
dummy_cairo_ = NULL;
|
dummy_cairo_ = NULL;
|
||||||
linestyle_ = FL_SOLID;
|
linestyle_ = FL_SOLID;
|
||||||
clip_ = NULL;
|
clip_ = NULL;
|
||||||
@@ -81,6 +81,7 @@ Fl_Cairo_Graphics_Driver::Fl_Cairo_Graphics_Driver() : Fl_Graphics_Driver() {
|
|||||||
|
|
||||||
Fl_Cairo_Graphics_Driver::~Fl_Cairo_Graphics_Driver() {
|
Fl_Cairo_Graphics_Driver::~Fl_Cairo_Graphics_Driver() {
|
||||||
if (pango_layout_) g_object_unref(pango_layout_);
|
if (pango_layout_) g_object_unref(pango_layout_);
|
||||||
|
if (pango_context_) g_object_unref(pango_context_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const cairo_format_t Fl_Cairo_Graphics_Driver::cairo_format = CAIRO_FORMAT_ARGB32;
|
const cairo_format_t Fl_Cairo_Graphics_Driver::cairo_format = CAIRO_FORMAT_ARGB32;
|
||||||
@@ -88,8 +89,6 @@ const cairo_format_t Fl_Cairo_Graphics_Driver::cairo_format = CAIRO_FORMAT_ARGB3
|
|||||||
|
|
||||||
void Fl_Cairo_Graphics_Driver::set_cairo(cairo_t *cr, float s) {
|
void Fl_Cairo_Graphics_Driver::set_cairo(cairo_t *cr, float s) {
|
||||||
if (dummy_cairo_) {
|
if (dummy_cairo_) {
|
||||||
g_object_unref(pango_layout_);
|
|
||||||
pango_layout_ = NULL;
|
|
||||||
cairo_destroy(dummy_cairo_);
|
cairo_destroy(dummy_cairo_);
|
||||||
dummy_cairo_ = NULL;
|
dummy_cairo_ = NULL;
|
||||||
}
|
}
|
||||||
@@ -1070,22 +1069,20 @@ int Fl_Cairo_Graphics_Driver::get_font_sizes(Fl_Font fnum, int*& sizep) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Fl_Cairo_Font_Descriptor::Fl_Cairo_Font_Descriptor(const char* name, Fl_Fontsize size) : Fl_Font_Descriptor(name, size) {
|
Fl_Cairo_Font_Descriptor::Fl_Cairo_Font_Descriptor(const char* name, Fl_Fontsize size,
|
||||||
char string[70];
|
PangoContext *context) :
|
||||||
|
Fl_Font_Descriptor(name, size) {
|
||||||
|
char *string = new char[strlen(name) + 10];
|
||||||
strcpy(string, name);
|
strcpy(string, name);
|
||||||
// The factor of 0.75 below gives cairo-produced text the same size as
|
// The factor of 0.75 below gives cairo-produced text the same size as
|
||||||
// Xft-produced text for the same FLTK font size.
|
// Xft-produced text for the same FLTK font size.
|
||||||
sprintf(string + strlen(string), " %d", int(size * 0.75 + 0.5) );
|
sprintf(string + strlen(string), " %d", int(size * 0.75 + 0.5) );
|
||||||
//A PangoFontDescription describes a font in an implementation-independent manner.
|
//A PangoFontDescription describes a font in an implementation-independent manner.
|
||||||
fontref = pango_font_description_from_string(string);
|
fontref = pango_font_description_from_string(string);
|
||||||
|
delete[] string;
|
||||||
width = NULL;
|
width = NULL;
|
||||||
//A PangoFontMap represents the set of fonts available for a particular rendering system.
|
|
||||||
static PangoFontMap *def_font_map = pango_cairo_font_map_get_default(); // 1.10
|
|
||||||
//A PangoContext stores global information used to control the itemization process.
|
|
||||||
static PangoContext *pango_context = pango_font_map_create_context(def_font_map); // 1.22
|
|
||||||
static PangoLanguage *language = pango_language_get_default(); // 1.16
|
|
||||||
//A PangoFontset represents a set of PangoFont to use when rendering text.
|
//A PangoFontset represents a set of PangoFont to use when rendering text.
|
||||||
PangoFontset *fontset = pango_font_map_load_fontset(def_font_map, pango_context, fontref, language);
|
PangoFontset *fontset = pango_font_map_load_fontset(pango_cairo_font_map_get_default(), context, fontref, pango_language_get_default());
|
||||||
PangoFontMetrics *metrics = pango_fontset_get_metrics(fontset);
|
PangoFontMetrics *metrics = pango_fontset_get_metrics(fontset);
|
||||||
ascent = pango_font_metrics_get_ascent(metrics);
|
ascent = pango_font_metrics_get_ascent(metrics);
|
||||||
descent = pango_font_metrics_get_descent(metrics);
|
descent = pango_font_metrics_get_descent(metrics);
|
||||||
@@ -1109,13 +1106,13 @@ Fl_Cairo_Font_Descriptor::~Fl_Cairo_Font_Descriptor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
|
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size, PangoContext *context) {
|
||||||
Fl_Fontdesc* s = fl_fonts+fnum;
|
Fl_Fontdesc* s = fl_fonts+fnum;
|
||||||
if (!s->name) s = fl_fonts; // use 0 if fnum undefined
|
if (!s->name) s = fl_fonts; // use 0 if fnum undefined
|
||||||
Fl_Font_Descriptor* f;
|
Fl_Font_Descriptor* f;
|
||||||
for (f = s->first; f; f = f->next)
|
for (f = s->first; f; f = f->next)
|
||||||
if (f->size == size) return f;
|
if (f->size == size) return f;
|
||||||
f = new Fl_Cairo_Font_Descriptor(s->name, size);
|
f = new Fl_Cairo_Font_Descriptor(s->name, size, context);
|
||||||
f->next = s->first;
|
f->next = s->first;
|
||||||
s->first = f;
|
s->first = f;
|
||||||
return f;
|
return f;
|
||||||
@@ -1123,45 +1120,34 @@ static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
|
|||||||
|
|
||||||
|
|
||||||
/* Implementation note :
|
/* Implementation note :
|
||||||
* The pango_layout_ object is created relatively to the unscaled cairo context (scale() == 1).
|
* The pixel width of a drawn string equals the sum of the widths of its
|
||||||
* Therefore, the cairo context is unscaled before calling pango_cairo_create_layout(),
|
|
||||||
* pango_cairo_show_layout(), and pango_cairo_update_layout().
|
|
||||||
* This way, the pixel width of a drawn string equals the sum of the widths of its
|
|
||||||
* characters, except when kerning occurs.
|
* characters, except when kerning occurs.
|
||||||
*/
|
*/
|
||||||
void Fl_Cairo_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize s) {
|
void Fl_Cairo_Graphics_Driver::font(Fl_Font fnum, Fl_Fontsize s) {
|
||||||
if (!font_descriptor()) fl_open_display();
|
if (!font_descriptor()) fl_open_display();
|
||||||
if (!pango_layout_) {
|
if (!cairo_) {
|
||||||
bool needs_dummy = (cairo_ == NULL);
|
cairo_surface_t *surf = cairo_image_surface_create(Fl_Cairo_Graphics_Driver::cairo_format, 100, 100);
|
||||||
if (!cairo_) {
|
cairo_ = cairo_create(surf);
|
||||||
cairo_surface_t *surf = cairo_image_surface_create(Fl_Cairo_Graphics_Driver::cairo_format, 100, 100);
|
cairo_surface_destroy(surf);
|
||||||
cairo_ = cairo_create(surf);
|
dummy_cairo_ = cairo_;
|
||||||
cairo_surface_destroy(surf);
|
|
||||||
}
|
|
||||||
cairo_save(cairo_);
|
|
||||||
double f = scale(); cairo_scale(cairo_, 1/f, 1/f);
|
|
||||||
pango_layout_ = pango_cairo_create_layout(cairo_); // 1.10
|
|
||||||
cairo_restore(cairo_);
|
|
||||||
pango_layout_cairo_ = cairo_;
|
|
||||||
if (needs_dummy) {
|
|
||||||
dummy_cairo_ = cairo_;
|
|
||||||
}
|
|
||||||
} else if (pango_layout_cairo_ != cairo_) {
|
|
||||||
cairo_save(cairo_);
|
|
||||||
double f = scale(); cairo_scale(cairo_, 1/f, 1/f);
|
|
||||||
pango_cairo_update_layout(cairo_, pango_layout_);
|
|
||||||
cairo_restore(cairo_);
|
|
||||||
pango_layout_cairo_ = cairo_;
|
|
||||||
}
|
}
|
||||||
if (s == 0) return;
|
if (s == 0) return;
|
||||||
if (font() == fnum && size() == s) return;
|
|
||||||
if (fnum == -1) {
|
if (fnum == -1) {
|
||||||
Fl_Graphics_Driver::font(0, 0);
|
Fl_Graphics_Driver::font(0, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Fl_Graphics_Driver::font(fnum, s);
|
Fl_Graphics_Driver::font(fnum, s);
|
||||||
font_descriptor( find(fnum, int(s * scale() + 0.5)) );
|
if (!pango_context_) {
|
||||||
pango_layout_set_font_description(pango_layout_, ((Fl_Cairo_Font_Descriptor*)font_descriptor())->fontref);
|
//A PangoFontMap represents the set of fonts available for a particular rendering system.
|
||||||
|
PangoFontMap *def_font_map = pango_cairo_font_map_get_default(); // 1.10
|
||||||
|
//A PangoContext stores global information used to control the itemization process.
|
||||||
|
pango_context_ = pango_font_map_create_context(def_font_map); // 1.22
|
||||||
|
pango_layout_ = pango_layout_new(pango_context_);
|
||||||
|
}
|
||||||
|
font_descriptor( find(fnum, int(s * scale() + 0.5), pango_context_) );
|
||||||
|
//If no font description is set on the layout, the font description from the layout’s context is used.
|
||||||
|
pango_context_set_font_description(pango_context_,
|
||||||
|
((Fl_Cairo_Font_Descriptor*)font_descriptor())->fontref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1506,18 +1506,23 @@ int Fl_PostScript_Graphics_Driver::start_eps(int width, int height) {
|
|||||||
|
|
||||||
void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y) {
|
void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, double x, double y) {
|
||||||
if (!n) return;
|
if (!n) return;
|
||||||
|
if (!pango_context_) {
|
||||||
|
PangoFontMap *def_font_map = pango_cairo_font_map_get_default(); // 1.10
|
||||||
|
pango_context_ = pango_font_map_create_context(def_font_map); // 1.22
|
||||||
|
pango_layout_ = pango_layout_new(pango_context_);
|
||||||
|
}
|
||||||
PangoFontDescription *pfd = Fl_Graphics_Driver::default_driver().pango_font_description(font());
|
PangoFontDescription *pfd = Fl_Graphics_Driver::default_driver().pango_font_description(font());
|
||||||
pango_layout_set_font_description(pango_layout(), pfd);
|
pango_layout_set_font_description(pango_layout_, pfd);
|
||||||
int pwidth, pheight;
|
int pwidth, pheight;
|
||||||
cairo_save(cairo_);
|
cairo_save(cairo_);
|
||||||
pango_layout_set_text(pango_layout(), str, n);
|
pango_layout_set_text(pango_layout_, str, n);
|
||||||
pango_layout_get_size(pango_layout(), &pwidth, &pheight);
|
pango_layout_get_size(pango_layout_, &pwidth, &pheight);
|
||||||
if (pwidth > 0) {
|
if (pwidth > 0) {
|
||||||
double s = width(str, n);
|
double s = width(str, n);
|
||||||
cairo_translate(cairo_, x, y - height() + descent());
|
cairo_translate(cairo_, x, y - height() + descent());
|
||||||
s = (s/pwidth) * PANGO_SCALE;
|
s = (s/pwidth) * PANGO_SCALE;
|
||||||
cairo_scale(cairo_, s, s);
|
cairo_scale(cairo_, s, s);
|
||||||
pango_cairo_show_layout(cairo_, pango_layout());
|
pango_cairo_show_layout(cairo_, pango_layout_);
|
||||||
}
|
}
|
||||||
cairo_restore(cairo_);
|
cairo_restore(cairo_);
|
||||||
check_status();
|
check_status();
|
||||||
|
|||||||
Reference in New Issue
Block a user