Skip to content

Commit 9999bb8

Browse files
committed
Fixes for HiDPI screens.
1 parent 3927cd9 commit 9999bb8

File tree

5 files changed

+131
-76
lines changed

5 files changed

+131
-76
lines changed

frontend/common/TeXEngine.cc

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ TeXEngine::~TeXEngine()
180180
}
181181

182182
TeXEngine::TeXEngine()
183-
: horizontal_pixels_(0), font_size_(12), scale_(1.0)
183+
: horizontal_pixels_(0), font_size_(12), total_scale_(1.0), device_scale_(1.0)
184184
{
185185
// latex_packages.push_back("breqn");
186186
latex_packages.push_back("hyperref");
@@ -221,17 +221,23 @@ void TeXEngine::set_font_size(int fontsize)
221221
font_size_=fontsize;
222222
}
223223

224-
void TeXEngine::set_scale(double scale)
224+
void TeXEngine::set_scale(double total_scale, double device_scale)
225225
{
226-
if(scale_!=scale) {
226+
if(total_scale_!=total_scale && device_scale_!=device_scale) {
227227
// flag all requests as requiring an update
228228
std::set<std::shared_ptr<TeXRequest> >::iterator reqit=requests.begin();
229229
while(reqit!=requests.end()) {
230230
(*reqit)->needs_generating=true;
231231
++reqit;
232232
}
233233
}
234-
scale_=scale;
234+
total_scale_=total_scale;
235+
device_scale_=device_scale;
236+
}
237+
238+
double TeXEngine::get_scale() const
239+
{
240+
return total_scale_;
235241
}
236242

237243
TeXEngine::TeXRequest::TeXRequest()
@@ -354,7 +360,7 @@ void TeXEngine::convert_set(std::set<std::shared_ptr<TeXRequest> >& reqs)
354360
// Note: the number here has no effect on the size in pixels of the generated
355361
// PDF. That is set with the -D parameter of dvipng.
356362

357-
const double horizontal_mm=horizontal_pixels_*(12.0/font_size_)/3.94/scale_;
363+
const double horizontal_mm=horizontal_pixels_*(12.0/font_size_)/3.94/(total_scale_/device_scale_);
358364
//#ifdef DEBUG
359365
// std::cerr << "tex_it: font_size " << font_size << std::endl
360366
// << " pixels " << horizontal_pixels_ << std::endl
@@ -498,7 +504,7 @@ void TeXEngine::convert_set(std::set<std::shared_ptr<TeXRequest> >& reqs)
498504
// Convert the entire dvi file to png files.
499505
//
500506
std::ostringstream resspec;
501-
resspec << horizontal_pixels_/(1.0*horizontal_mm)*millimeter_per_inch;
507+
resspec << horizontal_pixels_/(1.0*horizontal_mm)*millimeter_per_inch*device_scale_;
502508

503509
std::string dvipng_stdout, dvipng_stderr;
504510
tpl::Process dvipng_proc("dvipng -T tight -bg transparent -D "+resspec.str()+" "+tmppath+".dvi", "",

frontend/common/TeXEngine.hh

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,14 @@ namespace cadabra {
5252

5353
// Set the width and font size for all images to be generated.
5454
void set_geometry(int horizontal_pixels);
55-
void set_scale(double);
55+
56+
// Set the scale factor for generating bitmaps. The total scale is
57+
// the product of HiDPI scale and any text-scaling factor on top of
58+
// that, so that it represents the total scale at which text renders.
59+
// The device_scale is just the HiDPI factor; we need to generate
60+
// bitmaps at the width times this size.
61+
void set_scale(double total_scale, double device_scale);
62+
double get_scale() const;
5663
void set_font_size(int font_size);
5764
std::vector<std::string> latex_packages;
5865

@@ -92,7 +99,7 @@ namespace cadabra {
9299
std::string preamble_string;
93100
int horizontal_pixels_;
94101
int font_size_;
95-
double scale_;
102+
double total_scale_, device_scale_;
96103

97104
void erase_file(const std::string&) const;
98105
void convert_one(std::shared_ptr<TeXRequest>);

frontend/gtkmm/NotebookWindow.cc

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,20 @@ NotebookWindow::NotebookWindow(Cadabra *c, bool ro)
4141

4242
// Query high-dpi settings. For now only for cinnamon.
4343
scale = 1.0;
44+
auto screen = Gdk::Screen::get_default();
4445
#ifndef __APPLE__
4546
const char *ds = std::getenv("DESKTOP_SESSION");
4647
if(ds) {
4748
settings = Gio::Settings::create((strcmp(ds, "cinnamon") == 0) ? "org.cinnamon.desktop.interface" : "org.gnome.desktop.interface");
48-
scale = settings->get_double("text-scaling-factor");
49+
scale = settings->get_double("text-scaling-factor")*screen->get_monitor_scale_factor(0);
50+
// scale = screen->get_monitor_scale_factor(0);
4951
}
5052
#else
51-
auto screen = Gdk::Screen::get_default();
5253
scale = screen->get_monitor_scale_factor(0);
5354
std::cerr << "cadabra-client: scale = " << scale << std::endl;
5455
#endif
5556
// std::cerr << "monitor scale factor " << Gdk::Monitor::get_scale_factor() << std::endl;
56-
engine.set_scale(scale);
57+
engine.set_scale(scale, screen->get_monitor_scale_factor(0));
5758

5859
#ifndef __APPLE__
5960
if(ds) {
@@ -73,7 +74,7 @@ NotebookWindow::NotebookWindow(Cadabra *c, bool ro)
7374
if(prefs.highlight) load_css("black");
7475
else load_css("blue");
7576

76-
auto screen = Gdk::Screen::get_default();
77+
// auto screen = Gdk::Screen::get_default();
7778
// std::cerr << "cadabra-client: scale = " << screen->get_monitor_scale_factor(0) << std::endl;
7879
Gtk::StyleContext::add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
7980

@@ -1693,10 +1694,13 @@ void NotebookWindow::on_help_register()
16931694

16941695
void NotebookWindow::on_text_scaling_factor_changed(const std::string& key)
16951696
{
1696-
if(key=="text-scaling-factor") {
1697-
scale = settings->get_double("text-scaling-factor");
1698-
std::cout << "cadabra-client: text-scaling-factor = " << scale << std::endl;
1699-
engine.set_scale(scale);
1697+
std::cerr << key << std::endl;
1698+
if(key=="text-scaling-factor" || key=="scaling-factor") {
1699+
auto screen = Gdk::Screen::get_default();
1700+
scale = settings->get_double("text-scaling-factor");
1701+
scale *= screen->get_monitor_scale_factor(0);
1702+
std::cout << "cadabra-client: total scaling-factor = " << scale << std::endl;
1703+
engine.set_scale(scale, screen->get_monitor_scale_factor(0));
17001704
engine.invalidate_all();
17011705
engine.convert_all();
17021706

frontend/gtkmm/TeXView.cc

Lines changed: 75 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,40 @@
11

2-
#include "TeXView.hh"
3-
#include <iostream>
2+
#include "TeXView.hh"
3+
#include <iostream>
4+
#include <cairo/cairo.h>
5+
#include <cairomm/context.h>
6+
#include <giomm/resource.h>
7+
#include <gdkmm/general.h> // set_source_pixbuf()
48

5-
using namespace cadabra;
9+
using namespace cadabra;
610

7-
TeXView::TeXView(TeXEngine& eng, DTree::iterator it, int hmargin)
8-
: content(0), datacell(it), vbox(false, 10), hbox(false, hmargin), engine(eng)
9-
{
10-
content = engine.checkin(datacell->textbuf, "", "");
11+
TeXView::TeXView(TeXEngine& eng, DTree::iterator it, int hmargin)
12+
: content(0), datacell(it), vbox(false, 10), hbox(false, hmargin), engine(eng)
13+
{
14+
content = engine.checkin(datacell->textbuf, "", "");
1115

1216
#if GTKMM_MINOR_VERSION>=10
13-
add(rbox);
14-
rbox.add(vbox);
15-
rbox.set_reveal_child(false);
16-
rbox.set_transition_duration(1000);
17-
rbox.set_transition_type(Gtk::REVEALER_TRANSITION_TYPE_CROSSFADE); //SLIDE_DOWN);
17+
add(rbox);
18+
rbox.add(vbox);
19+
rbox.set_reveal_child(false);
20+
rbox.set_transition_duration(1000);
21+
rbox.set_transition_type(Gtk::REVEALER_TRANSITION_TYPE_CROSSFADE); //SLIDE_DOWN);
1822
#else
19-
add(vbox);
23+
add(vbox);
2024
#endif
21-
vbox.set_margin_top(10);
22-
vbox.set_margin_bottom(0);
23-
vbox.pack_start(hbox, Gtk::PACK_SHRINK, 0);
24-
hbox.pack_start(image, Gtk::PACK_SHRINK, hmargin);
25+
vbox.set_margin_top(10);
26+
vbox.set_margin_bottom(0);
27+
vbox.pack_start(hbox, Gtk::PACK_SHRINK, 0);
28+
hbox.pack_start(image, Gtk::PACK_SHRINK, hmargin);
2529
// add(image);
26-
override_background_color(Gdk::RGBA("white"));
27-
add_events( Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK );
28-
}
30+
override_background_color(Gdk::RGBA("white"));
31+
add_events( Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK );
32+
}
2933

30-
TeXView::~TeXView()
31-
{
32-
engine.checkout(content);
33-
}
34+
TeXView::~TeXView()
35+
{
36+
engine.checkout(content);
37+
}
3438

3539
void TeXView::on_show()
3640
{
@@ -60,14 +64,7 @@ void TeXView::convert()
6064

6165
if(content->image().data()!=0) {
6266
//std::cerr << "SHOULD NOT HAPPEN" << std::endl;
63-
Glib::RefPtr<Gdk::Pixbuf> pixbuf =
64-
Gdk::Pixbuf::create_from_data(content->image().data(), Gdk::COLORSPACE_RGB,
65-
true,
66-
8,
67-
content->width(), content->height(),
68-
4*content->width());
69-
70-
image.set(pixbuf);
67+
image.update_image(content, engine.get_scale());
7168
}
7269
}
7370
catch(TeXEngine::TeXException& ex) {
@@ -77,27 +74,58 @@ void TeXView::convert()
7774

7875

7976
void TeXView::dim(bool d)
80-
{
81-
if(d) image.set_opacity(0.3);
82-
else image.set_opacity(1.0);
83-
}
84-
85-
bool TeXView::on_button_release_event(GdkEventButton *ev)
86-
{
87-
show_hide_requested.emit(datacell);
88-
return true;
89-
}
90-
91-
void TeXView::update_image()
92-
{
93-
Glib::RefPtr<Gdk::Pixbuf> pixbuf =
77+
{
78+
if(d) image.set_opacity(0.3);
79+
else image.set_opacity(1.0);
80+
}
81+
82+
bool TeXView::on_button_release_event(GdkEventButton *ev)
83+
{
84+
show_hide_requested.emit(datacell);
85+
return true;
86+
}
87+
88+
void TeXView::update_image()
89+
{
90+
image.update_image(content, engine.get_scale());
91+
}
92+
93+
void TeXView::TeXArea::update_image(std::shared_ptr<TeXEngine::TeXRequest> content, double scale)
94+
{
95+
pixbuf =
9496
Gdk::Pixbuf::create_from_data(content->image().data(), Gdk::COLORSPACE_RGB,
9597
true,
9698
8,
9799
content->width(), content->height(),
98100
4*content->width());
99101

100-
image.set(pixbuf);
102+
set_size_request(pixbuf->get_width(), pixbuf->get_height());
103+
// update=true;
104+
scale_=scale;
105+
// HERE
106+
// image.set(pixbuf);
101107
}
102108

103109

110+
bool TeXView::TeXArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
111+
{
112+
if(!pixbuf) return false;
113+
114+
// Gtk::Allocation allocation = get_allocation();
115+
// const int width = allocation.get_width();
116+
// const int height = allocation.get_height();
117+
auto surface = cr->get_target();
118+
auto csurface = surface->cobj();
119+
// cairo_surface_set_device_scale(csurface, 1.0, 1.0);
120+
// cairo_surface_mark_dirty(csurface);
121+
double device_scale_x, device_scale_y;
122+
cairo_surface_get_device_scale(csurface, &device_scale_x, &device_scale_y);
123+
// std::cerr << device_scale_x << std::endl;
124+
set_size_request(pixbuf->get_width()/device_scale_x, pixbuf->get_height()/device_scale_y);
125+
cr->scale(1.0/device_scale_x, 1.0/device_scale_y);
126+
Gdk::Cairo::set_source_pixbuf(cr, pixbuf, 0, 0);
127+
cr->paint();
128+
cr->scale(1.0, 1.0);
129+
130+
return true;
131+
}

frontend/gtkmm/TeXView.hh

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
#include <gtkmm/eventbox.h>
55
#include <gtkmm/box.h>
6-
#include <gtkmm/image.h>
6+
#include <gtkmm/drawingarea.h>
77
#if GTKMM_MINOR_VERSION>=10
88
#include <gtkmm/revealer.h>
99
#endif
@@ -31,20 +31,30 @@ namespace cadabra {
3131
#endif
3232
Gtk::VBox vbox;
3333
Gtk::HBox hbox;
34-
Gtk::Image image;
35-
36-
/// The actual image is stored in the image referenced by pixbuf.
37-
/// FIXME: This pointer is not yet shared among instances which show the
38-
/// same content.
39-
40-
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
41-
42-
/// Update the visible image from the pixbuf. Call this in order to propagate
43-
/// changes to the pixbuf (e.g. from re-running the TeXRequest) to the
44-
/// visible widget itself.
4534

35+
class TeXArea : public Gtk::DrawingArea {
36+
public:
37+
virtual bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override;
38+
39+
/// Update the visible image from the pixbuf. Call this in order to propagate
40+
/// changes to the pixbuf (e.g. from re-running the TeXRequest) to the
41+
/// visible widget itself.
42+
43+
void update_image(std::shared_ptr<TeXEngine::TeXRequest>, double scale);
44+
45+
/// The actual image is stored in the image referenced by pixbuf.
46+
/// FIXME: This pointer is not yet shared among instances which show the
47+
/// same content.
48+
49+
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
50+
double scale_;
51+
};
52+
53+
TeXArea image;
54+
55+
/// Update the TeX image.
4656
void update_image();
47-
57+
4858
/// Dim the output to indicate that the result is no longer guaranteed to
4959
/// be correlated with the input cell from which it was derived.
5060

0 commit comments

Comments
 (0)