Introducing font resolution

With the subresolution mode, the "Default" fonts get very small.
Hence, a separate font resolution is provided which
applies to "Default" font rendering only.
This commit is contained in:
Matthias Koefferlein 2024-08-03 21:10:25 +02:00
parent a802cd0e91
commit 3290d0ab21
24 changed files with 210 additions and 107 deletions

View File

@ -33,13 +33,15 @@ Bitmap::Bitmap ()
{
init (0, 0);
m_resolution = 1.0;
m_font_resolution = 1.0;
}
Bitmap::Bitmap (unsigned int w, unsigned int h, double r)
Bitmap::Bitmap (unsigned int w, unsigned int h, double r, double rf)
: m_empty_scanline (0)
{
init (w, h);
m_resolution = r;
m_font_resolution = rf;
}
Bitmap::Bitmap (const Bitmap &d)
@ -60,6 +62,7 @@ Bitmap::operator= (const Bitmap &d)
}
m_resolution = d.m_resolution;
m_font_resolution = d.m_font_resolution;
for (unsigned int i = 0; i < m_height; ++i) {
if (! d.m_scanlines.empty () && d.m_scanlines [i] != 0) {
@ -796,7 +799,7 @@ Bitmap::render_text (const lay::RenderText &text)
{
if (text.font == db::DefaultFont) {
const lay::FixedFont &ff = lay::FixedFont::get_font (m_resolution);
const lay::FixedFont &ff = lay::FixedFont::get_font (m_font_resolution);
// count the lines and max. characters per line
@ -877,7 +880,7 @@ Bitmap::render_text (const lay::RenderText &text)
} else {
// Create a sub-renderer so we do not need to clear *this
lay::BitmapRenderer hr (m_width, m_height, m_resolution);
lay::BitmapRenderer hr (m_width, m_height, m_resolution, m_font_resolution);
db::DHershey ht (text.text, text.font);
hr.reserve_edges (ht.count_edges ());

View File

@ -157,8 +157,9 @@ public:
* @param w The width of the bitmap
* @param h The height of the bitmap
* @param r The resolution of the bitmap
* @param rf The font resolution of the bitmap
*/
Bitmap (unsigned int w, unsigned int h, double r);
Bitmap (unsigned int w, unsigned int h, double r, double rf);
/**
* @brief Copy constructor
@ -218,6 +219,11 @@ public:
*/
double resolution () const;
/**
* @brief Get the font resolution of the bitmap (applies to "Default" font)
*/
double font_resolution () const;
/**
* @brief Get the width of the bitmap
*/
@ -311,7 +317,7 @@ public:
private:
unsigned int m_width;
unsigned int m_height;
double m_resolution;
double m_resolution, m_font_resolution;
std::vector<uint32_t *> m_scanlines;
std::vector<uint32_t *> m_free;
uint32_t *m_empty_scanline;
@ -357,6 +363,12 @@ Bitmap::resolution () const
return m_resolution;
}
inline double
Bitmap::font_resolution () const
{
return m_font_resolution;
}
inline unsigned int
Bitmap::width () const
{

View File

@ -30,8 +30,8 @@ namespace lay
// ----------------------------------------------------------------------------------------------
// BitmapRenderer implementation
BitmapRenderer::BitmapRenderer (unsigned int width, unsigned int height, double resolution)
: Renderer (width, height, resolution),
BitmapRenderer::BitmapRenderer (unsigned int width, unsigned int height, double resolution, double font_resolution)
: Renderer (width, height, resolution, font_resolution),
m_xmin (0.0), m_xmax (0.0), m_ymin (0.0), m_ymax (0.0),
m_ortho (true)
{

View File

@ -53,7 +53,7 @@ public:
/**
* @brief The default ctor
*/
BitmapRenderer (unsigned int width, unsigned int height, double resolution);
BitmapRenderer (unsigned int width, unsigned int height, double resolution, double font_resolution);
/**
* @brief Reserve space for n edges

View File

@ -449,7 +449,7 @@ static void create_precursor_bitmaps (const std::vector<lay::ViewOp> &view_ops_i
mutex->lock ();
}
lay::Bitmap &bp = precursors.insert (std::make_pair (bm_index, lay::Bitmap (width, height, 1.0))).first->second;
lay::Bitmap &bp = precursors.insert (std::make_pair (bm_index, lay::Bitmap (width, height, 1.0, 1.0))).first->second;
const LineStyleInfo &ls_info = ls.style (op.line_style_index ()).scaled (op.width ());
for (unsigned int y = 0; y < height; y++) {
@ -961,7 +961,7 @@ bitmap_to_bitmap (const lay::ViewOp &view_op, const lay::Bitmap &bitmap,
lay::Bitmap precursor;
if (ls_info.width () > 0) {
precursor = lay::Bitmap (width, height, 1.0);
precursor = lay::Bitmap (width, height, 1.0, 1.0);
LineStyleInfo lsi = ls_info;

View File

@ -205,6 +205,14 @@ LayoutCanvas::resolution () const
return (m_srm ? 1.0 : 1.0 / m_oversampling) * (m_hrm ? 1.0 : 1.0 / dpr ());
}
double
LayoutCanvas::font_resolution () const
{
// NOTE: for font resolution we do not include the subresolution mode - otherwise
// the labels will become very hard to read.
return (1.0 / m_oversampling) * (m_hrm ? 1.0 : 1.0 / dpr ());
}
#if defined(HAVE_QT)
void
LayoutCanvas::init_ui (QWidget *parent)
@ -370,7 +378,7 @@ LayoutCanvas::prepare_drawing ()
{
if (m_need_redraw) {
BitmapViewObjectCanvas::set_size (m_viewport_l.width (), m_viewport_l.height (), resolution ());
BitmapViewObjectCanvas::set_size (m_viewport_l.width (), m_viewport_l.height (), resolution (), font_resolution ());
if (! mp_image ||
(unsigned int) mp_image->width () != m_viewport_l.width () ||
@ -406,7 +414,7 @@ LayoutCanvas::prepare_drawing ()
++c;
}
mp_redraw_thread->commit (m_layers, m_viewport_l, resolution ());
mp_redraw_thread->commit (m_layers, m_viewport_l, resolution (), font_resolution ());
if (tl::verbosity () >= 20) {
tl::info << "Restored image from cache";
@ -456,7 +464,7 @@ LayoutCanvas::prepare_drawing ()
}
if (m_redraw_clearing) {
mp_redraw_thread->start (mp_view->synchronous () ? 0 : mp_view->drawing_workers (), m_layers, m_viewport_l, resolution (), m_redraw_force_update);
mp_redraw_thread->start (mp_view->synchronous () ? 0 : mp_view->drawing_workers (), m_layers, m_viewport_l, resolution (), font_resolution (), m_redraw_force_update);
} else {
mp_redraw_thread->restart (m_need_redraw_layer);
}
@ -642,8 +650,8 @@ class DetachedViewObjectCanvas
: public BitmapViewObjectCanvas
{
public:
DetachedViewObjectCanvas (tl::Color bg, tl::Color fg, tl::Color ac, unsigned int width_l, unsigned int height_l, double resolution, tl::PixelBuffer *img)
: BitmapViewObjectCanvas (width_l, height_l, resolution),
DetachedViewObjectCanvas (tl::Color bg, tl::Color fg, tl::Color ac, unsigned int width_l, unsigned int height_l, double resolution, double font_resolution, tl::PixelBuffer *img)
: BitmapViewObjectCanvas (width_l, height_l, resolution, font_resolution),
m_bg (bg), m_fg (fg), m_ac (ac), mp_image (img)
{
// TODO: Good choice?
@ -728,7 +736,7 @@ class DetachedViewObjectCanvasMono
{
public:
DetachedViewObjectCanvasMono (bool bg, bool fg, bool ac, unsigned int width, unsigned int height)
: BitmapViewObjectCanvas (width, height, 1.0),
: BitmapViewObjectCanvas (width, height, 1.0, 1.0),
m_bg (bg), m_fg (fg), m_ac (ac)
{
// .. nothing yet ..
@ -798,7 +806,7 @@ LayoutCanvas::image_with_options (unsigned int width, unsigned int height, int l
// provide canvas objects for the layout bitmaps and the foreground/background objects
BitmapRedrawThreadCanvas rd_canvas;
DetachedViewObjectCanvas vo_canvas (background, foreground, active, width * oversampling, height * oversampling, resolution, &img);
DetachedViewObjectCanvas vo_canvas (background, foreground, active, width * oversampling, height * oversampling, resolution, resolution, &img);
// compute the new viewport
db::DBox tb (target_box);
@ -811,7 +819,7 @@ LayoutCanvas::image_with_options (unsigned int width, unsigned int height, int l
lay::RedrawThread redraw_thread (&rd_canvas, mp_view);
// render the layout
redraw_thread.start (0 /*synchronous*/, m_layers, vp, resolution, true);
redraw_thread.start (0 /*synchronous*/, m_layers, vp, resolution, resolution, true);
redraw_thread.stop (); // safety
// paint the background objects. It uses "img" to paint on.
@ -859,7 +867,7 @@ LayoutCanvas::image_with_options_mono (unsigned int width, unsigned int height,
lay::RedrawThread redraw_thread (&rd_canvas, mp_view);
// render the layout
redraw_thread.start (0 /*synchronous*/, m_layers, vp, 1.0, true);
redraw_thread.start (0 /*synchronous*/, m_layers, vp, 1.0, 1.0, true);
redraw_thread.stop (); // safety
tl::BitmapBuffer img (width, height);
@ -879,7 +887,7 @@ LayoutCanvas::screenshot ()
tl::PixelBuffer img (m_viewport.width (), m_viewport.height ());
img.fill (m_background);
DetachedViewObjectCanvas vo_canvas (background_color (), foreground_color (), active_color (), m_viewport_l.width (), m_viewport_l.height (), resolution (), &img);
DetachedViewObjectCanvas vo_canvas (background_color (), foreground_color (), active_color (), m_viewport_l.width (), m_viewport_l.height (), resolution (), font_resolution (), &img);
// and paint the background objects. It uses "img" to paint on.
do_render_bg (m_viewport_l, vo_canvas);

View File

@ -334,10 +334,15 @@ public:
}
/**
* @brief Reimplementation of ViewObjectCanvas: Resolution
* @brief Reimplementation of ViewObjectCanvas interface
*/
double resolution () const;
/**
* @brief Reimplementation of ViewObjectCanvas interface
*/
double font_resolution () const;
/**
* @brief Gets the gamma value
*/

View File

@ -1598,10 +1598,10 @@ LayoutViewBase::icon_for_layer (const LayerPropertiesConstIterator &iter, unsign
*sl0++ = 0;
}
lay::Bitmap fill (w, h, 1.0);
lay::Bitmap frame (w, h, 1.0);
lay::Bitmap text (w, h, 1.0);
lay::Bitmap vertex (w, h, 1.0);
lay::Bitmap fill (w, h, 1.0, 1.0);
lay::Bitmap frame (w, h, 1.0, 1.0);
lay::Bitmap text (w, h, 1.0, 1.0);
lay::Bitmap vertex (w, h, 1.0, 1.0);
unsigned int wp = w - 1;

View File

@ -24,13 +24,14 @@
#include "layFixedFont.h"
#include "tlPixelBuffer.h"
#include "dbVector.h"
namespace lay
{
PixelBufferPainter::PixelBufferPainter (tl::PixelBuffer &img, unsigned int width, unsigned int height, double resolution)
PixelBufferPainter::PixelBufferPainter (tl::PixelBuffer &img, unsigned int width, unsigned int height, double resolution, double font_resolution)
: mp_img (&img),
m_resolution (resolution), m_width (width), m_height (height)
m_resolution (resolution), m_font_resolution (font_resolution), m_width (width), m_height (height)
{
// .. nothing yet ..
}
@ -38,13 +39,29 @@ PixelBufferPainter::PixelBufferPainter (tl::PixelBuffer &img, unsigned int width
void
PixelBufferPainter::set (const db::Point &p, tl::Color c)
{
if (p.x () >= 0 && p.x () < m_width && p.y () >= 0 && p.y () < m_height) {
if (m_resolution < 1.0 - 1e-10) {
fill_rect (p, p, c);
} else if (p.x () >= 0 && p.x () < m_width && p.y () >= 0 && p.y () < m_height) {
((unsigned int *) mp_img->scan_line (p.y ())) [p.x ()] = c.rgb ();
}
}
void
PixelBufferPainter::draw_line (const db::Point &p1, const db::Point &p2, tl::Color c)
{
if (m_resolution < 1.0 - 1e-10) {
if (p1.x () == p2.x () || p1.y () == p2.y ()) {
fill_rect (p1, p2, c);
} else {
// TODO: not implemented yet.
}
} else {
draw_line_int (p1, p2, c);
}
}
void
PixelBufferPainter::draw_line_int (const db::Point &p1, const db::Point &p2, tl::Color c)
{
if (p1.x () == p2.x ()) {
@ -80,11 +97,22 @@ PixelBufferPainter::draw_line (const db::Point &p1, const db::Point &p2, tl::Col
void
PixelBufferPainter::fill_rect (const db::Point &p1, const db::Point &p2, tl::Color c)
{
unsigned int f = (unsigned int) (1.0 / m_resolution + 1e-10);
if (f == 1) {
fill_rect_int (p1, p2, c);
} else {
fill_rect_int (p1 - db::Vector (db::Coord (f / 2), db::Coord (f / 2)), p2 + db::Vector (db::Coord (f - f / 2 - 1), db::Coord (f - f / 2 - 1)), c);
}
}
void
PixelBufferPainter::fill_rect_int (const db::Point &p1, const db::Point &p2, tl::Color c)
{
int y1 = std::min (p1.y (), p2.y ());
int y2 = std::max (p1.y (), p2.y ());
for (int y = y1; y <= y2; ++y) {
draw_line (db::Point (p1.x (), y), db::Point (p2.x (), y), c);
draw_line_int (db::Point (p1.x (), y), db::Point (p2.x (), y), c);
}
}
@ -104,7 +132,7 @@ PixelBufferPainter::draw_rect (const db::Point &p1, const db::Point &p2, tl::Col
void
PixelBufferPainter::draw_text (const char *t, const db::Point &p, tl::Color c, int halign, int valign)
{
const lay::FixedFont &ff = lay::FixedFont::get_font (m_resolution);
const lay::FixedFont &ff = lay::FixedFont::get_font (m_font_resolution);
int x = p.x (), y = p.y ();
if (halign < 0) {

View File

@ -44,7 +44,7 @@ namespace lay {
class LAYBASIC_PUBLIC PixelBufferPainter
{
public:
PixelBufferPainter (tl::PixelBuffer &img, unsigned int width, unsigned int height, double resolution);
PixelBufferPainter (tl::PixelBuffer &img, unsigned int width, unsigned int height, double resolution, double font_resolution);
void set (const db::Point &p, tl::Color c);
void draw_line (const db::Point &p1, const db::Point &p2, tl::Color c);
@ -54,8 +54,11 @@ public:
private:
tl::PixelBuffer *mp_img;
double m_resolution;
double m_resolution, m_font_resolution;
int m_width, m_height;
void fill_rect_int (const db::Point &p1, const db::Point &p2, tl::Color c);
void draw_line_int (const db::Point &p1, const db::Point &p2, tl::Color c);
};
}

View File

@ -46,6 +46,7 @@ RedrawThread::RedrawThread (lay::RedrawThreadCanvas *canvas, LayoutViewBase *vie
m_width = 0;
m_height = 0;
m_resolution = 1.0;
m_font_resolution = 1.0;
m_boxes_already_drawn = false;
m_custom_already_drawn = false;
m_nlayers = 0;
@ -106,12 +107,13 @@ subtract_box (const db::DBox &subject, const db::DBox &with)
}
void
RedrawThread::commit (const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution)
RedrawThread::commit (const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution, double font_resolution)
{
m_vp_trans = vp.trans ();
m_width = vp.width ();
m_height = vp.height ();
m_resolution = resolution;
m_font_resolution = font_resolution;
m_layers = layers;
m_nlayers = int (m_layers.size ());
@ -131,12 +133,13 @@ RedrawThread::commit (const std::vector <lay::RedrawLayerInfo> &layers, const la
}
void
RedrawThread::start (int workers, const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution, bool force_redraw)
RedrawThread::start (int workers, const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution, double font_resolution, bool force_redraw)
{
m_vp_trans = vp.trans ();
m_width = vp.width ();
m_height = vp.height ();
m_resolution = resolution;
m_font_resolution = font_resolution;
db::DBox new_region = m_vp_trans.inverted () * db::DBox (db::DPoint (0, 0), db::DPoint (m_width, m_height));
double epsilon = m_vp_trans.inverted ().ctrans (1e-3);
@ -261,7 +264,7 @@ RedrawThread::do_start (bool clear, const db::Vector *shift_vector, const std::v
if (clear) {
mp_canvas->prepare (m_nlayers * planes_per_layer + special_planes_before + special_planes_after, m_width, m_height, m_resolution, shift_vector, 0, mp_view->drawings ());
mp_canvas->prepare (m_nlayers * planes_per_layer + special_planes_before + special_planes_after, m_width, m_height, m_resolution, m_font_resolution, shift_vector, 0, mp_view->drawings ());
m_boxes_already_drawn = false;
m_custom_already_drawn = false;
@ -281,7 +284,7 @@ RedrawThread::do_start (bool clear, const db::Vector *shift_vector, const std::v
}
}
mp_canvas->prepare (m_nlayers * planes_per_layer + special_planes_before + special_planes_after, m_width, m_height, m_resolution, shift_vector, &planes_to_init, mp_view->drawings ());
mp_canvas->prepare (m_nlayers * planes_per_layer + special_planes_before + special_planes_after, m_width, m_height, m_resolution, m_font_resolution, shift_vector, &planes_to_init, mp_view->drawings ());
for (std::vector<int>::const_iterator l = restart.begin (); l != restart.end (); ++l) {
if (*l >= 0 && *l < int (m_layers.size ())) {
@ -315,7 +318,7 @@ RedrawThread::do_start (bool clear, const db::Vector *shift_vector, const std::v
}
} else {
mp_canvas->prepare (1, m_width, m_height, m_resolution, 0, 0, mp_view->drawings ());
mp_canvas->prepare (1, m_width, m_height, m_resolution, m_font_resolution, 0, 0, mp_view->drawings ());
}
}

View File

@ -55,8 +55,8 @@ public:
RedrawThread (lay::RedrawThreadCanvas *canvas, lay::LayoutViewBase *view);
virtual ~RedrawThread ();
void commit (const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution);
void start (int workers, const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution, bool force_redraw);
void commit (const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution, double font_resolution);
void start (int workers, const std::vector <lay::RedrawLayerInfo> &layers, const lay::Viewport &vp, double resolution, double font_resolution, bool force_redraw);
void restart (const std::vector<int> &restart);
void wakeup_checked ();
void wakeup ();
@ -107,6 +107,7 @@ private:
db::DCplxTrans m_vp_trans;
int m_width, m_height;
double m_resolution;
double m_font_resolution;
std::vector<db::Box> m_redraw_regions;
db::DBox m_stored_region, m_valid_region;
db::DPoint m_last_center;

View File

@ -242,9 +242,9 @@ shift_bitmap (const lay::Bitmap *from, lay::Bitmap *to, int dx, int dy)
}
void
BitmapRedrawThreadCanvas::prepare (unsigned int nlayers, unsigned int width, unsigned int height, double resolution, const db::Vector *shift_vector, const std::vector<int> *planes, const lay::Drawings *drawings)
BitmapRedrawThreadCanvas::prepare (unsigned int nlayers, unsigned int width, unsigned int height, double resolution, double font_resolution, const db::Vector *shift_vector, const std::vector<int> *planes, const lay::Drawings *drawings)
{
RedrawThreadCanvas::prepare (nlayers, width, height, resolution, shift_vector, planes, drawings);
RedrawThreadCanvas::prepare (nlayers, width, height, resolution, font_resolution, shift_vector, planes, drawings);
lock ();
@ -256,7 +256,7 @@ BitmapRedrawThreadCanvas::prepare (unsigned int nlayers, unsigned int width, uns
for (size_t i = 0; i < mp_plane_buffers.size (); ++i) {
lay::Bitmap *from = mp_plane_buffers [i];
lay::Bitmap *to = mp_plane_buffers [i] = new lay::Bitmap (width, height, resolution);
lay::Bitmap *to = mp_plane_buffers [i] = new lay::Bitmap (width, height, resolution, font_resolution);
shift_bitmap (from, to, shift_vector->x (), shift_vector->y ());
delete from;
}
@ -265,7 +265,7 @@ BitmapRedrawThreadCanvas::prepare (unsigned int nlayers, unsigned int width, uns
for (lay::Drawings::const_iterator d = drawings->begin (); d != drawings->end (); ++d, ++di) {
for (unsigned int i = 0; i < d->num_planes (); ++i) {
lay::Bitmap *from = mp_drawing_plane_buffers[di][i];
lay::Bitmap *to = mp_drawing_plane_buffers[di][i] = new lay::Bitmap (width, height, resolution);
lay::Bitmap *to = mp_drawing_plane_buffers[di][i] = new lay::Bitmap (width, height, resolution, font_resolution);
shift_bitmap (from, to, shift_vector->x (), shift_vector->y ());
delete from;
}
@ -305,13 +305,13 @@ BitmapRedrawThreadCanvas::prepare (unsigned int nlayers, unsigned int width, uns
clear_planes ();
for (unsigned int i = 0; i < nlayers; ++i) {
mp_plane_buffers.push_back (new lay::Bitmap (width, height, resolution));
mp_plane_buffers.push_back (new lay::Bitmap (width, height, resolution, font_resolution));
}
for (lay::Drawings::const_iterator d = drawings->begin (); d != drawings->end (); ++d) {
mp_drawing_plane_buffers.push_back (std::vector <lay::Bitmap *> ());
for (unsigned int i = 0; i < d->num_planes (); ++i) {
mp_drawing_plane_buffers.back ().push_back (new lay::Bitmap (width, height, resolution));
mp_drawing_plane_buffers.back ().push_back (new lay::Bitmap (width, height, resolution, font_resolution));
}
}
@ -364,7 +364,7 @@ BitmapRedrawThreadCanvas::clear_planes ()
lay::CanvasPlane *
BitmapRedrawThreadCanvas::create_drawing_plane ()
{
return new lay::Bitmap(m_width, m_height, resolution ());
return new lay::Bitmap(m_width, m_height, resolution (), font_resolution ());
}
void

View File

@ -49,7 +49,7 @@ public:
* @brief Constructor
*/
RedrawThreadCanvas ()
: m_resolution (1.0), m_width (0), m_height (0)
: m_resolution (1.0), m_font_resolution (1.0), m_width (0), m_height (0)
{ }
/**
@ -91,11 +91,13 @@ public:
* @param shifting The shift vector by which the original image should be shifted to form the background or 0 if no shifting is required
* @param layers The set of plane indexes to initialize (if null, all planes are initialized). A negative value initializes the drawing planes.
* @param resolution The resolution in which the image is drawn
* @param font_resolution The resolution in which the "Default" font is drawn
* @param drawings The custom drawing interface which is responsible to draw user objects
*/
virtual void prepare (unsigned int /*nlayers*/, unsigned int width, unsigned int height, double resolution, const db::Vector * /*shift_vector*/, const std::vector<int> * /*planes*/, const lay::Drawings * /*drawings*/)
virtual void prepare (unsigned int /*nlayers*/, unsigned int width, unsigned int height, double resolution, double font_resolution, const db::Vector * /*shift_vector*/, const std::vector<int> * /*planes*/, const lay::Drawings * /*drawings*/)
{
m_resolution = resolution;
m_resolution = font_resolution;
m_width = width;
m_height = height;
}
@ -162,6 +164,14 @@ public:
return m_resolution;
}
/**
* @brief Get the font resolution value
*/
double font_resolution () const
{
return m_font_resolution;
}
/**
* @brief Get the canvas width
*/
@ -186,6 +196,7 @@ public:
private:
tl::Mutex m_mutex;
double m_resolution;
double m_font_resolution;
unsigned int m_width, m_height;
};
@ -271,7 +282,7 @@ public:
* This method is called from RedrawThread::start (), not from the
* redraw thread.
*/
virtual void prepare (unsigned int nlayers, unsigned int width, unsigned int height, double resolution, const db::Vector *shift_vector, const std::vector<int> *planes, const lay::Drawings *drawings);
virtual void prepare (unsigned int nlayers, unsigned int width, unsigned int height, double resolution, double font_resolution, const db::Vector *shift_vector, const std::vector<int> *planes, const lay::Drawings *drawings);
/**
* @brief Test a plane with the given index for emptiness
@ -313,7 +324,7 @@ public:
*/
virtual lay::Renderer *create_renderer ()
{
return new lay::BitmapRenderer (m_width, m_height, resolution ());
return new lay::BitmapRenderer (m_width, m_height, resolution (), font_resolution ());
}
/**

View File

@ -1284,7 +1284,7 @@ RedrawThreadWorker::draw_text_layer (bool drawing_context, db::cell_index_type c
std::unique_ptr<lay::Bitmap> opt_bitmap;
lay::Bitmap *vertex_bitmap = dynamic_cast<lay::Bitmap *> (vertex);
if (m_text_lazy_rendering && vertex_bitmap) {
opt_bitmap.reset (new lay::Bitmap (vertex_bitmap->width (), vertex_bitmap->height (), vertex_bitmap->resolution ()));
opt_bitmap.reset (new lay::Bitmap (vertex_bitmap->width (), vertex_bitmap->height (), vertex_bitmap->resolution (), vertex_bitmap->font_resolution ()));
}
for (std::vector<db::Box>::const_iterator b = vp.begin (); b != vp.end (); ++b) {
@ -1991,10 +1991,10 @@ RedrawThreadWorker::draw_layer (int from_level, int to_level, db::cell_index_typ
int width = int (cell_box_trans.width () + 3); // +3 = one pixel for a one-pixel frame at both sides and one for safety
int height = int (cell_box_trans.height () + 3);
cached_cell->second.fill = new lay::Bitmap (width, height, 1.0);
cached_cell->second.frame = new lay::Bitmap (width, height, 1.0);
cached_cell->second.vertex = new lay::Bitmap (width, height, 1.0);
cached_cell->second.text = new lay::Bitmap (width, height, 1.0);
cached_cell->second.fill = new lay::Bitmap (width, height, 1.0, 1.0);
cached_cell->second.frame = new lay::Bitmap (width, height, 1.0, 1.0);
cached_cell->second.vertex = new lay::Bitmap (width, height, 1.0, 1.0);
cached_cell->second.text = new lay::Bitmap (width, height, 1.0, 1.0);
// this object is responsible for doing updates when a snapshot is taken
UpdateSnapshotWithCache update_cached_snapshot (update_snapshot, &trans, &cached_cell->second, fill, frame, vertex, text);

View File

@ -36,7 +36,7 @@ namespace lay
// ----------------------------------------------------------------------------------------------
// Renderer implementation
Renderer::Renderer (unsigned int width, unsigned int height, double resolution)
Renderer::Renderer (unsigned int width, unsigned int height, double resolution, double font_resolution)
: m_draw_texts (true),
m_draw_properties (false),
m_draw_description_property (false),
@ -47,7 +47,8 @@ Renderer::Renderer (unsigned int width, unsigned int height, double resolution)
m_xfill (false),
m_font (db::DefaultFont),
m_width (width), m_height (height),
m_resolution (resolution)
m_resolution (resolution),
m_font_resolution (font_resolution)
{
// .. nothing else ..
}

View File

@ -66,7 +66,7 @@ public:
/**
* @brief The ctor
*/
Renderer (unsigned int width, unsigned int height, double resolution);
Renderer (unsigned int width, unsigned int height, double resolution, double font_resolution);
/**
* @brief The destructor
@ -400,6 +400,17 @@ public:
return m_resolution;
}
/**
* @brief Get the font resolution value
*
* The resolution value is used to convert dimensions on the output device into canvas
* units. This value applies to rendering the "Default" font.
*/
double font_resolution () const
{
return m_font_resolution;
}
protected:
bool m_draw_texts;
bool m_draw_properties;
@ -412,6 +423,7 @@ protected:
db::Font m_font;
unsigned int m_width, m_height;
double m_resolution;
double m_font_resolution;
};
} // namespace lay

View File

@ -33,7 +33,7 @@ TextInfo::TextInfo (const LayoutViewBase *view)
: m_default_text_size (view->default_text_size ()),
m_default_font (db::Font (view->text_font ())),
m_apply_text_trans (view->apply_text_trans ()),
m_resolution (view->canvas ()->resolution ()),
m_resolution (view->canvas ()->font_resolution ()),
m_point_mode (view->text_point_mode ())
{
// .. nothing yet ..

View File

@ -1274,14 +1274,14 @@ ViewObjectUI::mouse_event_viewport () const
// BitmapViewObjectCanvas implementation
BitmapViewObjectCanvas::BitmapViewObjectCanvas ()
: ViewObjectCanvas (), m_renderer (1, 1, 1.0), m_width (1), m_height (1), m_resolution (1.0)
: ViewObjectCanvas (), m_renderer (1, 1, 1.0, 1.0), m_width (1), m_height (1), m_resolution (1.0), m_font_resolution (1.0)
{
// .. nothing yet ..
}
BitmapViewObjectCanvas::BitmapViewObjectCanvas (unsigned int width, unsigned int height, double resolution)
: ViewObjectCanvas (), m_renderer (width, height, resolution),
m_width (width), m_height (height), m_resolution (resolution)
BitmapViewObjectCanvas::BitmapViewObjectCanvas (unsigned int width, unsigned int height, double resolution, double font_resolution)
: ViewObjectCanvas (), m_renderer (width, height, resolution, font_resolution),
m_width (width), m_height (height), m_resolution (resolution), m_font_resolution (font_resolution)
{
// .. nothing yet ..
}
@ -1299,7 +1299,7 @@ BitmapViewObjectCanvas::plane (const lay::ViewOp &style)
// we need to create a new plane
m_fg_bitmap_table.insert (std::make_pair (style, (unsigned int) mp_alloc_bitmaps.size ()));
lay::Bitmap *bm = new lay::Bitmap (m_width, m_height, m_resolution);
lay::Bitmap *bm = new lay::Bitmap (m_width, m_height, m_resolution, m_font_resolution);
mp_fg_bitmaps.push_back (bm);
mp_alloc_bitmaps.push_back (bm);
m_fg_view_ops.push_back (style);
@ -1319,7 +1319,7 @@ BitmapViewObjectCanvas::plane (const std::vector<lay::ViewOp> &style)
// we need to create a new bitmap
m_fgv_bitmap_table.insert (std::make_pair (style, (unsigned int) mp_alloc_bitmaps.size ()));
lay::Bitmap *bm = new lay::Bitmap (m_width, m_height, m_resolution);
lay::Bitmap *bm = new lay::Bitmap (m_width, m_height, m_resolution, m_font_resolution);
mp_alloc_bitmaps.push_back (bm);
for (std::vector<lay::ViewOp>::const_iterator s = style.begin (); s != style.end (); ++s) {
mp_fg_bitmaps.push_back (bm);
@ -1366,26 +1366,27 @@ BitmapViewObjectCanvas::sort_planes ()
}
void
BitmapViewObjectCanvas::set_size (unsigned int width, unsigned int height, double resolution)
BitmapViewObjectCanvas::set_size (unsigned int width, unsigned int height, double resolution, double font_resolution)
{
m_renderer = lay::BitmapRenderer (width, height, resolution);
m_renderer = lay::BitmapRenderer (width, height, resolution, font_resolution);
m_width = width;
m_height = height;
m_resolution = resolution;
m_font_resolution = font_resolution;
}
void
BitmapViewObjectCanvas::set_size (unsigned int width, unsigned int height)
{
m_renderer = lay::BitmapRenderer (width, height, m_resolution);
m_renderer = lay::BitmapRenderer (width, height, m_resolution, m_font_resolution);
m_width = width;
m_height = height;
}
void
BitmapViewObjectCanvas::set_size (double resolution)
BitmapViewObjectCanvas::set_size (double resolution, double font_resolution)
{
m_renderer = lay::BitmapRenderer (m_width, m_height, resolution);
m_renderer = lay::BitmapRenderer (m_width, m_height, resolution, font_resolution);
m_resolution = resolution;
}

View File

@ -1172,6 +1172,13 @@ public:
*/
virtual double resolution () const = 0;
/**
* @brief Get the font resolution
*
* The resolution describes the size of one pixel for the rendering of the "Default" font.
*/
virtual double font_resolution () const = 0;
/**
* @brief CanvasPlane provider
*
@ -1225,7 +1232,7 @@ public:
/**
* @brief Constructor
*/
BitmapViewObjectCanvas (unsigned int width, unsigned int height, double resolution);
BitmapViewObjectCanvas (unsigned int width, unsigned int height, double resolution, double font_resolution);
/**
* @brief The destructor
@ -1276,6 +1283,14 @@ public:
return m_resolution;
}
/**
* @brief Get the font resolution
*/
virtual double font_resolution () const
{
return m_font_resolution;
}
/**
* @brief Return the number of bitmaps stored so far
*/
@ -1330,7 +1345,7 @@ public:
/**
* @brief Set the width and height and resolution
*/
void set_size (unsigned int width, unsigned int height, double resolution);
void set_size (unsigned int width, unsigned int height, double resolution, double font_resolution);
/**
* @brief Set the width and height
@ -1340,7 +1355,7 @@ public:
/**
* @brief Set the resolution
*/
void set_size (double resolution);
void set_size (double resolution, double font_resolution);
/**
* @brief Get the width
@ -1377,6 +1392,7 @@ private:
lay::BitmapRenderer m_renderer;
unsigned int m_width, m_height;
double m_resolution;
double m_font_resolution;
};
} // namespace lay

View File

@ -45,7 +45,7 @@ to_string (const lay::Bitmap &bm)
TEST(1)
{
lay::Bitmap b1 (8, 8, 1.0);
lay::Bitmap b1 (8, 8, 1.0, 1.0);
EXPECT_EQ (to_string (b1), "--------\n"
"--------\n"
"--------\n"
@ -78,7 +78,7 @@ TEST(1)
TEST(2)
{
lay::Bitmap b1 (8, 8, 1.0);
lay::Bitmap b1 (8, 8, 1.0, 1.0);
EXPECT_EQ (to_string (b1), "--------\n"
"--------\n"
"--------\n"
@ -88,7 +88,7 @@ TEST(2)
"--------\n"
"--------\n");
lay::Bitmap b2 (3, 2, 1.0);
lay::Bitmap b2 (3, 2, 1.0, 1.0);
b2.fill (0, 0, 3);
b2.fill (1, 1, 3);
EXPECT_EQ (to_string (b2), "-##\n###\n");
@ -135,7 +135,7 @@ TEST(2)
"--------\n"
"--------\n");
b1 = lay::Bitmap (40, 8, 1.0);
b1 = lay::Bitmap (40, 8, 1.0, 1.0);
EXPECT_EQ (to_string (b1), "----------------------------------------\n"
"----------------------------------------\n"
"----------------------------------------\n"
@ -145,7 +145,7 @@ TEST(2)
"----------------------------------------\n"
"----------------------------------------\n");
b2 = lay::Bitmap (40, 8, 1.0);
b2 = lay::Bitmap (40, 8, 1.0, 1.0);
b2.fill (1, 4, 36);
b2.fill (2, 5, 15);
b2.fill (2, 34, 35);

View File

@ -43,14 +43,14 @@ to_string (const tl::PixelBuffer &img, unsigned int mask)
TEST(1)
{
lay::Bitmap b1 (32, 32, 1.0);
lay::Bitmap b2 (32, 32, 1.0);
lay::Bitmap b3 (32, 32, 1.0);
lay::Bitmap b4 (32, 32, 1.0);
lay::Bitmap b5 (32, 32, 1.0);
lay::Bitmap b6 (32, 32, 1.0);
lay::Bitmap b7 (32, 32, 1.0);
lay::Bitmap b8 (32, 32, 1.0);
lay::Bitmap b1 (32, 32, 1.0, 1.0);
lay::Bitmap b2 (32, 32, 1.0, 1.0);
lay::Bitmap b3 (32, 32, 1.0, 1.0);
lay::Bitmap b4 (32, 32, 1.0, 1.0);
lay::Bitmap b5 (32, 32, 1.0, 1.0);
lay::Bitmap b6 (32, 32, 1.0, 1.0);
lay::Bitmap b7 (32, 32, 1.0, 1.0);
lay::Bitmap b8 (32, 32, 1.0, 1.0);
std::vector<lay::Bitmap *> pbitmaps;
pbitmaps.push_back (&b1);

View File

@ -68,9 +68,9 @@ to_string (const lay::Bitmap &bm, const lay::Bitmap &bf)
TEST(1)
{
lay::Bitmap b1 (16, 16, 1.0);
lay::Bitmap b1 (16, 16, 1.0, 1.0);
lay::BitmapRenderer r (16, 16, 1.0);
lay::BitmapRenderer r (16, 16, 1.0, 1.0);
r.insert (db::DEdge (3.4, 2.1, 12.7, -2.1));
r.insert (db::DEdge (12.7, -2.1, 3.4, 2.1));
r.insert (db::DEdge (3.4, 2.1, 12.7, 2.1));
@ -103,9 +103,9 @@ TEST(1)
TEST(2)
{
lay::Bitmap b1 (16, 16, 1.0);
lay::Bitmap b1 (16, 16, 1.0, 1.0);
lay::BitmapRenderer r(16, 16, 1.0);
lay::BitmapRenderer r(16, 16, 1.0, 1.0);
r.clear ();
r.insert (db::DEdge (3.4, 2.1, 12.7, 12.1));
r.insert (db::DEdge (3.4, 0.1, 100.0, 22.5));
@ -135,7 +135,7 @@ TEST(2)
r.insert (db::DEdge (100.0, 0.1, 3.4, 14.5));
r.insert (db::DEdge (12.7, 5.1, 3.4, 5.1));
r.insert (db::DEdge (15.3, -5.1, -5.1, 5.0));
b1 = lay::Bitmap (16, 16, 1.0);
b1 = lay::Bitmap (16, 16, 1.0, 1.0);
r.render_contour (b1);
EXPECT_EQ (to_string (b1), "---#------------\n"
@ -159,10 +159,10 @@ TEST(2)
TEST(3)
{
lay::Bitmap b1 (16, 16, 1.0);
lay::Bitmap b2 (16, 16, 1.0);
lay::Bitmap b1 (16, 16, 1.0, 1.0);
lay::Bitmap b2 (16, 16, 1.0, 1.0);
lay::BitmapRenderer r(16, 16, 1.0);
lay::BitmapRenderer r(16, 16, 1.0, 1.0);
r.insert (db::DEdge (3.4, 2.1, 12.7, 14.5));
r.insert (db::DEdge (12.7, 14.5, 10.7, 0.6));
r.insert (db::DEdge (10.7, 0.6, 3.4, 2.1));
@ -190,8 +190,8 @@ TEST(3)
r.insert (db::DEdge (3.1, 9.0, 12.7, 14.5));
r.insert (db::DEdge (12.7, 14.5, 10.7, 0.6));
r.insert (db::DEdge (10.7, 0.6, 3.1, 9.0));
b1 = lay::Bitmap (16, 16, 1.0);
b2 = lay::Bitmap (16, 16, 1.0);
b1 = lay::Bitmap (16, 16, 1.0, 1.0);
b2 = lay::Bitmap (16, 16, 1.0, 1.0);
r.render_fill (b1);
r.render_contour (b2);
@ -217,8 +217,8 @@ TEST(3)
r.insert (db::DEdge (3.0, 14.0, 12.0, 14.0));
r.insert (db::DEdge (12.0, 14.0, 12.0, 9.0));
r.insert (db::DEdge (12.0, 9.0, 3.0, 9.0));
b1 = lay::Bitmap (16, 16, 1.0);
b2 = lay::Bitmap (16, 16, 1.0);
b1 = lay::Bitmap (16, 16, 1.0, 1.0);
b2 = lay::Bitmap (16, 16, 1.0, 1.0);
r.render_fill (b1);
// r.render_contour (b2);
@ -250,8 +250,8 @@ TEST(3)
r.insert (db::DEdge (8.8, 6.0, 4.2, 2.9));
r.insert (db::DEdge (4.2, 2.9, 12.2, 0.4));
r.insert (db::DEdge (12.2, 0.4, 0.2, 9.6));
b1 = lay::Bitmap (16, 16, 1.0);
b2 = lay::Bitmap (16, 16, 1.0);
b1 = lay::Bitmap (16, 16, 1.0, 1.0);
b2 = lay::Bitmap (16, 16, 1.0, 1.0);
r.render_fill (b1);
r.render_contour (b2);

View File

@ -237,7 +237,7 @@ GridNet::render_bg (const lay::Viewport &vp, ViewObjectCanvas &canvas)
return;
}
PixelBufferPainter painter (*bmp_canvas->bg_image (), bmp_canvas->canvas_width (), bmp_canvas->canvas_height (), bmp_canvas->resolution ());
PixelBufferPainter painter (*bmp_canvas->bg_image (), bmp_canvas->canvas_width (), bmp_canvas->canvas_height (), bmp_canvas->resolution (), bmp_canvas->font_resolution ());
db::DCplxTrans trans = vp.trans ();
db::DCplxTrans::inverse_trans trans_inv (trans.inverted ());
@ -245,15 +245,14 @@ GridNet::render_bg (const lay::Viewport &vp, ViewObjectCanvas &canvas)
db::DBox dbworld (trans_inv * db::DBox (0.0, 0.0, double (vp.width ()), double (vp.height ())));
// fw is the basic unit of the ruler geometry
const lay::FixedFont &ff = lay::FixedFont::get_font (bmp_canvas->resolution ());
int fw = ff.width ();
int fwr = lay::FixedFont::get_font (bmp_canvas->font_resolution ()).width ();
double dgrid = trans.ctrans (m_grid);
GridStyle style = m_style1;
// compute major grid and switch to secondary style if necessary
int s = 0;
while (dgrid < fw * 4) {
while (dgrid < fwr * 4) {
if (s == 0) {
dgrid *= 2.0;
} else if (s == 1) {
@ -282,9 +281,9 @@ GridNet::render_bg (const lay::Viewport &vp, ViewObjectCanvas &canvas)
if (m_show_ruler && dgrid < vp.width () * 0.2) {
int rh = int (floor (0.5 + fw * 0.8));
int xoffset = int (floor (0.5 + fw * 2.5));
int yoffset = int (floor (0.5 + fw * 2.5));
int rh = int (floor (0.5 + fwr * 0.8));
int xoffset = int (floor (0.5 + fwr * 2.5));
int yoffset = int (floor (0.5 + fwr * 2.5));
painter.fill_rect (db::Point (xoffset, vp.height () - yoffset - rh / 2),
db::Point (xoffset + int (floor (0.5 + dgrid)), vp.height () - yoffset + rh / 2),