Skip to content

Commit 8e7aed0

Browse files
xjl12da-liii
authored andcommitted
!426 [205_4] MuPDF:修复打开颜色选取时器崩溃
1 parent 53f835d commit 8e7aed0

File tree

6 files changed

+113
-18
lines changed

6 files changed

+113
-18
lines changed

devel/205_4.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# 205_4
2+
## 2025/07/16 MuPDF:修复打开颜色选取时器崩溃
3+
## What
4+
5+
`qt_glue_widget_rep::render()`使用MuPDF render重实现
6+
7+
## Why
8+
在启用MuPDF渲染器后,打开菜单栏上的颜色选取器,程序会崩溃
9+
崩溃原因是`qt_glue_widget_rep::render()`中使用qt_render_rep进行图像加载,与MuPDF冲突
10+
11+
## 如何测试
12+
配置xmake启用mupdf,并编译:
13+
```
14+
xmake f --mupdf=true
15+
xmake build stem
16+
xmake run stem
17+
```
18+
打开任意测试文档,单击菜单栏上的颜色选取器
19+

src/Plugins/MuPDF/mupdf_qt_simple_widget.cpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -142,24 +142,8 @@ qt_simple_widget_rep::repaint_invalid_regions () {
142142
canvas ()->surface ()->repaint (qrgn);
143143
}
144144

145-
static void
146-
mupdf_pixmap_cleanup_handler (void* info) {
147-
fz_pixmap* pix= (fz_pixmap*) info;
148-
if (pix) {
149-
fz_drop_pixmap (mupdf_context (), pix);
150-
}
151-
}
152-
153145
QImage
154146
qt_simple_widget_rep::get_backing_store () {
155-
fz_pixmap* pix = ((mupdf_picture_rep*) backing_store->get_handle ())->pix;
156-
uchar* samples= fz_pixmap_samples (mupdf_context (), pix);
157-
int w = fz_pixmap_width (mupdf_context (), pix);
158-
int h = fz_pixmap_height (mupdf_context (), pix);
159-
fz_keep_pixmap (mupdf_context (), pix);
160-
// we keep the samples since QImage will drop it later
161-
QImage im=
162-
QImage (samples, w, h, 4 * w, QImage::Format_RGBA8888_Premultiplied,
163-
mupdf_pixmap_cleanup_handler, pix);
164-
return im;
147+
fz_pixmap* pix= ((mupdf_picture_rep*) backing_store->get_handle ())->pix;
148+
return get_QImage_from_pixmap (pix);
165149
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/******************************************************************************
2+
* MODULE : mupdf_qt_ui_element.cpp
3+
* DESCRIPTION: Modified QT glue widget render process to adapt to MuPDF render
4+
* COPYRIGHT : (C) 2025 The Mogan Stem Authors
5+
*******************************************************************************
6+
* This software falls under the GNU general public license version 3 or later.
7+
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
8+
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
9+
******************************************************************************/
10+
11+
#include "MuPDF/mupdf_renderer.hpp"
12+
#include "qt_ui_element.hpp"
13+
14+
QTMPixmapOrImage
15+
qt_glue_widget_rep::render () {
16+
if (w > 128 || h > 128) {
17+
// Reduce pixmap width and height to improve performance
18+
SI factor= max (w, h) / 128;
19+
w/= factor;
20+
h/= factor;
21+
}
22+
fz_pixmap* pix= fz_new_pixmap (
23+
mupdf_context (), fz_device_rgb (mupdf_context ()), w, h, NULL, 1);
24+
mupdf_renderer_rep* ren= the_mupdf_renderer ();
25+
ren->begin (pix);
26+
rectangle r= rectangle (0, 0, w, h);
27+
ren->set_origin (0, 0);
28+
ren->encode (r->x1, r->y1);
29+
ren->encode (r->x2, r->y2);
30+
ren->set_clipping (r->x1, r->y2, r->x2, r->y1);
31+
if (col == "") {
32+
// do nothing
33+
}
34+
else {
35+
if (is_atomic (col)) {
36+
color c= named_color (col->label);
37+
ren->set_background (c);
38+
ren->set_pencil (c);
39+
ren->fill (r->x1, r->y2, r->x2, r->y1);
40+
}
41+
else {
42+
ren->set_shrinking_factor (std_shrinkf);
43+
brush old_b= ren->get_background ();
44+
ren->set_background (col);
45+
ren->clear_pattern (5 * r->x1, 5 * r->y2, 5 * r->x2, 5 * r->y1);
46+
ren->set_background (old_b);
47+
ren->set_shrinking_factor (1);
48+
}
49+
}
50+
ren->end ();
51+
52+
return get_QTMPixmapOrImage_from_pixmap (pix);
53+
}

src/Plugins/MuPDF/mupdf_renderer.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,3 +1316,35 @@ mupdf_renderer_rep::apply_shadow (SI x1, SI y1, SI x2, SI y2) {
13161316
static_cast<mupdf_renderer_rep*> (master)->encode (x2, y2);
13171317
master->put_shadow (this, x1, y1, x2, y2);
13181318
}
1319+
1320+
static void
1321+
mupdf_pixmap_cleanup_handler (void* info) {
1322+
fz_pixmap* pix= (fz_pixmap*) info;
1323+
if (pix) {
1324+
fz_drop_pixmap (mupdf_context (), pix);
1325+
}
1326+
}
1327+
1328+
QImage
1329+
get_QImage_from_pixmap (fz_pixmap* pix) {
1330+
uchar* samples= fz_pixmap_samples (mupdf_context (), pix);
1331+
int w = fz_pixmap_width (mupdf_context (), pix);
1332+
int h = fz_pixmap_height (mupdf_context (), pix);
1333+
fz_keep_pixmap (mupdf_context (), pix);
1334+
// we keep the samples since QImage will drop it later
1335+
QImage im=
1336+
QImage (samples, w, h, 4 * w, QImage::Format_RGBA8888_Premultiplied,
1337+
mupdf_pixmap_cleanup_handler, pix);
1338+
return im;
1339+
}
1340+
1341+
QTMPixmapOrImage
1342+
get_QTMPixmapOrImage_from_pixmap (fz_pixmap* pix) {
1343+
QImage qim= get_QImage_from_pixmap (pix);
1344+
if (headless_mode) {
1345+
return QTMPixmapOrImage (qim);
1346+
}
1347+
else {
1348+
return QTMPixmapOrImage (QPixmap::fromImage (qim));
1349+
}
1350+
}

src/Plugins/MuPDF/mupdf_renderer.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#ifndef MUPDF_RENDERER_HPP
1313
#define MUPDF_RENDERER_HPP
1414

15+
#include "QTMPixmapOrImage.hpp"
1516
#include "basic_renderer.hpp"
1617

1718
#include <mupdf/fitz.h>
@@ -123,4 +124,8 @@ class mupdf_renderer_rep : public basic_renderer_rep {
123124

124125
mupdf_renderer_rep* the_mupdf_renderer ();
125126

127+
// Convert fz_pixmap to QImage, QTMPixmapOrImage
128+
QImage get_QImage_from_pixmap (fz_pixmap* pix);
129+
QTMPixmapOrImage get_QTMPixmapOrImage_from_pixmap (fz_pixmap* pix);
130+
126131
#endif // defined MUPDF_RENDERER_HPP

src/Plugins/Qt/qt_ui_element.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ class qt_enum_command_rep : public command_rep {
8585
* glue widget
8686
******************************************************************************/
8787

88+
#ifndef USE_MUPDF_RENDERER
8889
QTMPixmapOrImage
8990
qt_glue_widget_rep::render () {
9091
QSize s= to_qsize (w, h);
@@ -126,6 +127,7 @@ qt_glue_widget_rep::render () {
126127

127128
return pxm;
128129
}
130+
#endif
129131

130132
QAction*
131133
qt_glue_widget_rep::as_qaction () {

0 commit comments

Comments
 (0)