void DocumentCanvas::zoom(double factor, bool relativezoom, double userCenterX, double userCenterY, unsigned int deviceX, unsigned int deviceY) { LcPainter &painter = cachedPainter(VIEWER_DOCUMENT); if ((_zoomMax <= painter.scale() && factor > 1.) || (_zoomMin >= painter.scale() && factor < 1.)) { return; } if (relativezoom) { factor = factor * painter.scale(); } // Calculate reference device offset at device location painter.save(); double refX = deviceX; double refY = deviceY; painter.reset_transformations(); painter.scale(factor); painter.device_to_user(&refX, &refY); painter.restore(); // Set translation for (auto i = _cachedPainters.begin(); i != _cachedPainters.end(); i++) { LcPainter *p = i->second; p->reset_transformations(); p->scale(factor); p->translate(refX - userCenterX,-refY + userCenterY); } }
void DocumentCanvas::pan(double move_x, double move_y) { double pan_x=0.; double pan_y=0.; if (_cachedPainters.size() != 0) { LcPainter* p = _cachedPainters.begin()->second; p->getTranslate(&pan_x, &pan_y); } /* FIXME 100.0 should be dynamically calculated, depends on the drawing speed */ if (std::abs(pan_x-move_x) > 100.0 || std::abs(pan_y - move_y) > 100.0 || pan_x == 0.0 || pan_y == 0.0) { pan_x = move_x; pan_y = move_y; } for (auto i = _cachedPainters.begin(); i != _cachedPainters.end(); i++) { LcPainter* p = i->second; p->translate(move_x - pan_x, move_y - pan_y); } pan_x = move_x; pan_y = move_y; }
/** * TODO items for text: * 1) Test multi-line text rendering * 2) Accept color codes during text rendering in the form of \Cx (x is the index color) * 3) Font selection * For testing there is a lua script * * We can increase performance if we pre-calculate some values and cache them so that we * don't have to keep calling text_extends and do some of the calculations * also we shouldn't draw text smaller then XX pixels when rendered on screen. */ void LCVText::draw(LcPainter& painter, const LcDrawOptions &options, const lc::geo::Area& rect) const { bool modified = false; painter.font_size(height()); painter.select_font_face("stick3.ttf"); TextExtends te = painter.text_extends(text_value().c_str()); double alignX = 0.0; double alignY = 0.0; // double alignX, alignY; // The idea of height() * .2 is just a average basline offset. Don't this value to seriously, // we could get it from font exists but that sounds over exaggerating for the moment. switch (valign()) { case lc::TextConst::VAMiddle: alignX += 0.0; alignY += -height() / 2. + (height() * .2); break; case lc::TextConst::VABottom: alignX += 0.0; alignY += -height() + (height() * .2); break; case lc::TextConst::VABaseline: alignX += 0.0; alignY += 0.0; break; case lc::TextConst::VATop: alignX += 0.0; alignY += 0.0 + (height() * .2); break; default: break; } // Horizontal Align: switch (halign()) { case lc::TextConst::HALeft: alignX += - te.width; alignY += 0.; break; case lc::TextConst::HACenter: alignX += - te.width / 2.0; alignY += 0.; break; case lc::TextConst::HAMiddle: alignX += - te.width / 2.0; alignY += 0.; break; case lc::TextConst::HARight: alignX += 0.; alignY += 0.; break; default: break; } painter.save(); painter.translate(insertion_point().x(), -insertion_point().y()); painter.rotate(-angle()); painter.translate(alignX, -alignY); painter.move_to(0., 0.); painter.text(text_value().c_str()); painter.stroke(); painter.restore(); if (modified) { painter.restore(); } }
void DocumentCanvas::transY(int y) { for (auto i = _cachedPainters.begin(); i != _cachedPainters.end(); i++) { LcPainter* p = i->second; p->translate(0, y); } }