Advanced rules now working.

This commit is contained in:
Matthias Koefferlein 2017-06-27 23:16:59 +02:00
parent 9398b5373a
commit 1b3a49e043
6 changed files with 864 additions and 264 deletions

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>637</width>
<height>311</height>
<width>668</width>
<height>373</height>
</rect>
</property>
<property name="windowTitle">
@ -192,7 +192,14 @@
<property name="spacing">
<number>6</number>
</property>
<item row="6" column="1">
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string> ... position</string>
</property>
</widget>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="t_snap_cbx">
<property name="toolTip">
<string>If checked, snap to edges or vertices of objects unless disabled above</string>
@ -202,85 +209,13 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="outline_cb">
<property name="toolTip">
<string>Specify outline mode of the ruler template</string>
</property>
<item>
<property name="text">
<string>Diagonal</string>
</property>
</item>
<item>
<property name="text">
<string>Horizonal and vertical (in this order)</string>
</property>
</item>
<item>
<property name="text">
<string>Diagonal plus horizonal and vertical (triangle)</string>
</property>
</item>
<item>
<property name="text">
<string>Vertical and horizonal (in this order)</string>
</property>
</item>
<item>
<property name="text">
<string>Diagonal plus vertical and horizontal (triangle)</string>
</property>
</item>
<item>
<property name="text">
<string>Box marker</string>
</property>
</item>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="fmt_y_le">
<property name="toolTip">
<string>Specify the y label format (applicable only for outline modes that have a vertical component, i.e. box)</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Angle constraints</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="7" column="0">
<widget class="QLabel" name="label_17">
<property name="text">
<string>Outline</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Style</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Label format</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="fmt_x_le">
<property name="toolTip">
<string>Specify the x label format (applicable only for outline modes that have a horizontal component, i.e. box)</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="fmt_le">
<property name="toolTip">
@ -288,53 +223,224 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_14">
<item row="0" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>X label format</string>
<string>Label format</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_15">
<item row="8" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Y label format</string>
<string>Angle constraints</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="style_cb">
<item row="2" column="1">
<widget class="QLineEdit" name="fmt_x_le">
<property name="toolTip">
<string>Specify style of the ruler template</string>
<string>Specify the x label format (applicable only for outline modes that have a horizontal component, i.e. box)</string>
</property>
<item>
<property name="text">
<string>Ruler</string>
</property>
</item>
<item>
<property name="text">
<string>Arrow at end</string>
</property>
</item>
<item>
<property name="text">
<string>Arrow at start</string>
</property>
</item>
<item>
<property name="text">
<string>Arrow at both ends</string>
</property>
</item>
<item>
<property name="text">
<string>Plain line</string>
</property>
</item>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="0">
<widget class="QLabel" name="label_16">
<property name="text">
<string>Style</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="fmt_y_le">
<property name="toolTip">
<string>Specify the y label format (applicable only for outline modes that have a vertical component, i.e. box)</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_4">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="1" column="1">
<widget class="QComboBox" name="main_position">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToContents</enum>
</property>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>At first point</string>
</property>
</item>
<item>
<property name="text">
<string>At second point</string>
</property>
</item>
<item>
<property name="text">
<string>At center</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>P</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="5">
<widget class="QLabel" name="label_21">
<property name="text">
<string>V</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QComboBox" name="main_yalign">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>V. center</string>
</property>
</item>
<item>
<property name="text">
<string>Bottom</string>
</property>
</item>
<item>
<property name="text">
<string>Top</string>
</property>
</item>
</widget>
</item>
<item row="1" column="4">
<widget class="QComboBox" name="main_xalign">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>H. center</string>
</property>
</item>
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
</widget>
</item>
<item row="1" column="3">
<widget class="QLabel" name="label_20">
<property name="text">
<string>H</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string> ... position</string>
</property>
</widget>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="t_angle_cb">
<property name="toolTip">
<string>Override the global angle constraint setting for this type of rulers</string>
@ -371,13 +477,345 @@
</item>
</widget>
</item>
<item row="7" column="0" colspan="2">
<item row="4" column="0">
<widget class="QLabel" name="label_15">
<property name="text">
<string>Y label format</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QLabel" name="help_label">
<property name="text">
<string>&lt;html&gt;(See &lt;a href=&quot;int:/manual/ruler_properties.xml&quot;&gt;here&lt;/a&gt; for a description of the properties)&lt;/html&gt;</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="outline_cb">
<property name="toolTip">
<string>Specify outline mode of the ruler template</string>
</property>
<item>
<property name="text">
<string>Diagonal</string>
</property>
</item>
<item>
<property name="text">
<string>Horizonal and vertical (in this order)</string>
</property>
</item>
<item>
<property name="text">
<string>Diagonal plus horizonal and vertical (triangle)</string>
</property>
</item>
<item>
<property name="text">
<string>Vertical and horizonal (in this order)</string>
</property>
</item>
<item>
<property name="text">
<string>Diagonal plus vertical and horizontal (triangle)</string>
</property>
</item>
<item>
<property name="text">
<string>Box marker</string>
</property>
</item>
<item>
<property name="text">
<string>Ellipse</string>
</property>
</item>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="style_cb">
<property name="toolTip">
<string>Specify style of the ruler template</string>
</property>
<item>
<property name="text">
<string>Ruler</string>
</property>
</item>
<item>
<property name="text">
<string>Arrow at end</string>
</property>
</item>
<item>
<property name="text">
<string>Arrow at start</string>
</property>
</item>
<item>
<property name="text">
<string>Arrow at both ends</string>
</property>
</item>
<item>
<property name="text">
<string>Plain line</string>
</property>
</item>
<item>
<property name="text">
<string>Cross at end</string>
</property>
</item>
<item>
<property name="text">
<string>Cross at start</string>
</property>
</item>
<item>
<property name="text">
<string>Cross at both ends</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_14">
<property name="text">
<string>X label format</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string> ... position</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QFrame" name="frame_5">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>148</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_22">
<property name="text">
<string>H</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="xlabel_xalign">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>H. center</string>
</property>
</item>
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_23">
<property name="text">
<string>V</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="xlabel_yalign">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>V. center</string>
</property>
</item>
<item>
<property name="text">
<string>Bottom</string>
</property>
</item>
<item>
<property name="text">
<string>Top</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="1">
<widget class="QFrame" name="frame_6">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>148</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label_28">
<property name="text">
<string>H</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="ylabel_xalign">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>H. center</string>
</property>
</item>
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_27">
<property name="text">
<string>V</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="ylabel_yalign">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>V. center</string>
</property>
</item>
<item>
<property name="text">
<string>Bottom</string>
</property>
</item>
<item>
<property name="text">
<string>Top</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -355,6 +355,14 @@ ConfigPage4::show ()
mp_ui->outline_cb->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].outline ());
mp_ui->t_angle_cb->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].angle_constraint ());
mp_ui->t_snap_cbx->setChecked (m_ruler_templates [m_current_template].snap ());
mp_ui->main_position->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].main_position ());
mp_ui->main_xalign->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].main_xalign ());
mp_ui->main_yalign->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].main_yalign ());
mp_ui->xlabel_xalign->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].xlabel_xalign ());
mp_ui->xlabel_yalign->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].xlabel_yalign ());
mp_ui->ylabel_xalign->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].ylabel_xalign ());
mp_ui->ylabel_yalign->setCurrentIndex ((unsigned int) m_ruler_templates [m_current_template].ylabel_yalign ());
}
void
@ -378,6 +386,14 @@ ConfigPage4::commit ()
m_ruler_templates [m_current_template].angle_constraint (ac);
m_ruler_templates [m_current_template].snap (mp_ui->t_snap_cbx->isChecked ());
m_ruler_templates [m_current_template].set_main_position (Object::position_type (mp_ui->main_position->currentIndex ()));
m_ruler_templates [m_current_template].set_main_xalign (Object::alignment_type (mp_ui->main_xalign->currentIndex ()));
m_ruler_templates [m_current_template].set_main_yalign (Object::alignment_type (mp_ui->main_yalign->currentIndex ()));
m_ruler_templates [m_current_template].set_xlabel_xalign (Object::alignment_type (mp_ui->xlabel_xalign->currentIndex ()));
m_ruler_templates [m_current_template].set_xlabel_yalign (Object::alignment_type (mp_ui->xlabel_yalign->currentIndex ()));
m_ruler_templates [m_current_template].set_ylabel_xalign (Object::alignment_type (mp_ui->ylabel_xalign->currentIndex ()));
m_ruler_templates [m_current_template].set_ylabel_yalign (Object::alignment_type (mp_ui->ylabel_yalign->currentIndex ()));
}
} // namespace ant

View File

@ -63,11 +63,10 @@ Object::Object (const db::DPoint &p1, const db::DPoint &p2, int id, const ant::T
m_fmt_x (t.fmt_x ()), m_fmt_y (t.fmt_y ()), m_fmt (t.fmt ()),
m_style (t.style ()), m_outline (t.outline ()),
m_snap (t.snap ()), m_angle_constraint (t.angle_constraint ()),
// TODO: make this part of the template
m_main_position (POS_auto),
m_main_xalign (AL_auto), m_main_yalign (AL_auto),
m_xlabel_xalign (AL_auto), m_xlabel_yalign (AL_auto),
m_ylabel_xalign (AL_auto), m_ylabel_yalign (AL_auto)
m_main_position (t.main_position ()),
m_main_xalign (t.main_xalign ()), m_main_yalign (t.main_yalign ()),
m_xlabel_xalign (t.xlabel_xalign ()), m_xlabel_yalign (t.xlabel_yalign ()),
m_ylabel_xalign (t.ylabel_xalign ()), m_ylabel_yalign (t.ylabel_yalign ())
{
// .. nothing else ..
}
@ -342,6 +341,7 @@ Object::class_name () const
void
Object::from_string (const char *s)
{
printf("@@@ %s\n", s); fflush(stdout);
tl::Extractor ex (s);
while (! ex.at_end ()) {
@ -555,7 +555,7 @@ Object::to_string () const
r += tl::to_word_or_quoted_string (fmt_y ());
r += ",";
r += "pos=";
r += "position=";
ant::PositionConverter pc;
r += pc.to_string (main_position ());
r += ",";

View File

@ -185,7 +185,8 @@ public:
*/
virtual void transform (const db::DCplxTrans &t)
{
*this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint);
m_p1 = t * m_p1;
m_p2 = t * m_p2;
property_changed ();
}
@ -194,7 +195,8 @@ public:
*/
virtual void transform (const db::DTrans &t)
{
*this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint);
m_p1 = t * m_p1;
m_p2 = t * m_p2;
property_changed ();
}
@ -203,7 +205,8 @@ public:
*/
virtual void transform (const db::DFTrans &t)
{
*this = ant::Object (t * m_p1, t * m_p2, m_id, m_fmt_x, m_fmt_y, m_fmt, m_style, m_outline, m_snap, m_angle_constraint);
m_p1 = t * m_p1;
m_p2 = t * m_p2;
property_changed ();
}

View File

@ -97,19 +97,16 @@ tick_spacings (double d, double min_d, int &minor_ticks, double &ticks)
}
/**
* @brief Draw a ruler with the given parameters
* @brief Draws a ruler with the given parameters
*
* @param q1 The first point in pixel space
* @param q2 The second point in pixel space
* @param length_u The ruler length in micron
* @param min_spc_u The minimum tick spacing in micron
* @param label The label text to draw
* @param sel True to draw ruler in "selected" mode
* @param right True to draw the ruler with ticks to the right (as seem from p1 to p2 in transformed space)
* @param pos The position where to draw the text
* @param style The style with which to draw the ruler
* @param halign The text's horizonal alignment
* @param valign The text's vertical alignment
* @param pos The position where to draw the text
* @param bitmap The bitmap to draw the ruler on
* @param renderer The renderer object
*/
@ -118,13 +115,9 @@ draw_ruler (const db::DPoint &q1,
const db::DPoint &q2,
double length_u,
double min_spc_u,
const std::string &label,
bool sel,
bool right,
ant::Object::style_type style,
ant::Object::position_type pos,
ant::Object::alignment_type halign,
ant::Object::alignment_type valign,
lay::CanvasPlane *bitmap,
lay::Renderer &renderer)
{
@ -145,13 +138,6 @@ draw_ruler (const db::DPoint &q1,
renderer.draw (db::DEdge (q1, q1), 0, bitmap, 0, 0);
}
renderer.draw (db::DBox (q1, q1),
label,
db::DefaultFont,
db::HAlignLeft,
db::VAlignBottom,
db::DFTrans (db::DFTrans::r0), 0, 0, 0, bitmap);
} else {
// compute the tick distribution
@ -284,76 +270,11 @@ draw_ruler (const db::DPoint &q1,
db::DVector tv_short = qq * tf * 0.5;
db::DVector tv_long = qq * tf;
db::HAlign text_halign = db::HAlignCenter;
if (halign == ant::Object::AL_auto) {
if (fabs (qq.x ()) > 1e-6) {
text_halign = qq.x () > 0.0 ? db::HAlignLeft : db::HAlignRight;
} else {
text_halign = q2.x () < q1.x () ? db::HAlignLeft : db::HAlignRight;
}
} else if (halign == ant::Object::AL_left) {
text_halign = db::HAlignLeft;
} else if (halign == ant::Object::AL_right) {
text_halign = db::HAlignRight;
}
db::VAlign text_valign = db::VAlignCenter;
if (valign == ant::Object::AL_auto) {
if (fabs (qq.y ()) > 1e-6) {
text_valign = qq.y () > 0.0 ? db::VAlignBottom : db::VAlignTop;
} else {
text_valign = q1.y () > q2.y () ? db::VAlignBottom : db::VAlignTop;
}
} else if (valign == ant::Object::AL_bottom) {
text_valign = db::VAlignBottom;
} else if (valign == ant::Object::AL_top) {
text_valign = db::VAlignTop;
}
db::DVector tv_text;
if (style == ant::Object::STY_arrow_start || style == ant::Object::STY_arrow_both || style == ant::Object::STY_arrow_end) {
tv_text = qq * (arrow_width * 0.5 + 2.0);
} else if (style == ant::Object::STY_cross_start || style == ant::Object::STY_cross_both || style == ant::Object::STY_cross_end) {
tv_text = qq * (arrow_width + 2.0);
} else if (style == ant::Object::STY_ruler) {
tv_text = qq * (tf + 2.0);
}
if (text_halign == db::HAlignCenter) {
tv_text.set_x (0);
} else if (text_halign == db::HAlignRight) {
tv_text.set_x (std::min (tv_text.x (), 0.0));
} else if (text_halign == db::HAlignLeft){
tv_text.set_x (std::max (tv_text.x (), 0.0));
}
if (text_valign == db::VAlignCenter) {
tv_text.set_y (0);
} else if (text_valign == db::VAlignTop) {
tv_text.set_y (std::min (tv_text.y (), 0.0));
} else if (text_valign == db::VAlignBottom){
tv_text.set_y (std::max (tv_text.y (), 0.0));
}
if (tick_length > 0) {
renderer.draw (db::DEdge (q1, q1 + tv_long), 0, bitmap, 0, 0);
renderer.draw (db::DEdge (q2, q2 + tv_long), 0, bitmap, 0, 0);
}
db::DPoint tp = q2;
if (pos == ant::Object::POS_center) {
tp = q1 + (q2 - q1) * 0.5;
} else if (pos == ant::Object::POS_p1) {
tp = q1;
}
renderer.draw (db::DBox (tp + tv_text, tp + tv_text),
label,
db::DefaultFont,
text_halign,
text_valign,
db::DFTrans (db::DFTrans::r0), 0, 0, 0, bitmap);
if (minor_ticks > 0 && ticks > 0.0) {
db::DVector q = q2 - q1;
@ -379,6 +300,159 @@ draw_ruler (const db::DPoint &q1,
}
}
/**
* @brief Draws a text with the given parameters
*
* @param q1 The first point in pixel space
* @param q2 The second point in pixel space
* @param length_u The ruler length in micron
* @param label The label text to draw
* @param right True to draw the ruler with ticks to the right (as seem from p1 to p2 in transformed space)
* @param style The style with which to draw the ruler
* @param pos The position where to draw the text
* @param halign The text's horizonal alignment
* @param valign The text's vertical alignment
* @param bitmap The bitmap to draw the ruler on
* @param renderer The renderer object
*/
void
draw_text (const db::DPoint &q1,
const db::DPoint &q2,
double length_u,
const std::string &label,
bool right,
ant::Object::style_type style,
ant::Object::position_type pos,
ant::Object::alignment_type halign,
ant::Object::alignment_type valign,
lay::CanvasPlane *bitmap,
lay::Renderer &renderer)
{
if (label.empty ()) {
return;
}
double arrow_width = 8 / renderer.resolution ();
double arrow_length = 12 / renderer.resolution ();
// Currently, "auto" means p2.
if (pos == ant::Object::POS_auto) {
pos = ant::Object::POS_p2;
}
if (length_u < 1e-5 /*micron*/) {
renderer.draw (db::DBox (q1, q1),
label,
db::DefaultFont,
db::HAlignLeft,
db::VAlignBottom,
db::DFTrans (db::DFTrans::r0), 0, 0, 0, bitmap);
} else {
// compute the tick distribution
double tick_length = (style == ant::Object::STY_ruler ? 8 : 0) / renderer.resolution ();
// normal and unit vector
double len = q1.double_distance (q2);
if (style == ant::Object::STY_arrow_end && len < double (arrow_length) * 1.2) {
arrow_length = len / 1.2;
arrow_width = arrow_length * 2.0 / 3.0;
} else if (style == ant::Object::STY_arrow_both && len < double (arrow_length) * 2.4) {
arrow_length = len / 2.4;
arrow_width = arrow_length * 2.0 / 3.0;
}
db::DVector qq (q2.y () - q1.y (), q1.x () - q2.x ());
if (len > 1e-10) {
qq *= 1.0 / len;
} else {
qq = db::DVector (1.0, 0.0);
}
if (!right) {
qq = -qq;
}
db::HAlign text_halign = db::HAlignCenter;
if (halign == ant::Object::AL_auto) {
// Compute a nice alignment depending on the anchor point
if (fabs (qq.x ()) > 1e-6) {
text_halign = qq.x () > 0.0 ? db::HAlignLeft : db::HAlignRight;
} else if (pos == ant::Object::POS_p2) {
text_halign = q2.x () < q1.x () ? db::HAlignLeft : db::HAlignRight;
} else if (pos == ant::Object::POS_p1) {
text_halign = q1.x () < q2.x () ? db::HAlignLeft : db::HAlignRight;
} else {
text_halign = db::HAlignCenter;
}
} else if (halign == ant::Object::AL_left) {
text_halign = db::HAlignLeft;
} else if (halign == ant::Object::AL_right) {
text_halign = db::HAlignRight;
}
db::VAlign text_valign = db::VAlignCenter;
if (valign == ant::Object::AL_auto) {
// Compute a nice alignment depending on the anchor point
if (fabs (qq.y ()) > 1e-6) {
text_valign = qq.y () > 0.0 ? db::VAlignBottom : db::VAlignTop;
} else if (pos == ant::Object::POS_p2) {
text_valign = q1.y () > q2.y () ? db::VAlignBottom : db::VAlignTop;
} else if (pos == ant::Object::POS_p1) {
text_valign = q2.y () > q1.y () ? db::VAlignBottom : db::VAlignTop;
} else {
text_valign = db::VAlignCenter;
}
} else if (valign == ant::Object::AL_bottom) {
text_valign = db::VAlignBottom;
} else if (valign == ant::Object::AL_top) {
text_valign = db::VAlignTop;
}
db::DVector tv_text;
if (style == ant::Object::STY_arrow_start || style == ant::Object::STY_arrow_both || style == ant::Object::STY_arrow_end) {
tv_text = qq * (arrow_width * 0.5 + 2.0);
} else if (style == ant::Object::STY_cross_start || style == ant::Object::STY_cross_both || style == ant::Object::STY_cross_end) {
tv_text = qq * (arrow_width + 2.0);
} else {
tv_text = qq * (tick_length + 2.0);
}
if (text_halign == db::HAlignCenter) {
tv_text.set_x (0);
} else if (text_halign == db::HAlignRight) {
tv_text.set_x (std::min (tv_text.x (), 0.0));
} else if (text_halign == db::HAlignLeft){
tv_text.set_x (std::max (tv_text.x (), 0.0));
}
if (text_valign == db::VAlignCenter) {
tv_text.set_y (0);
} else if (text_valign == db::VAlignTop) {
tv_text.set_y (std::min (tv_text.y (), 0.0));
} else if (text_valign == db::VAlignBottom){
tv_text.set_y (std::max (tv_text.y (), 0.0));
}
db::DPoint tp = q2;
if (pos == ant::Object::POS_center) {
tp = q1 + (q2 - q1) * 0.5;
} else if (pos == ant::Object::POS_p1) {
tp = q1;
}
renderer.draw (db::DBox (tp + tv_text, tp + tv_text),
label,
db::DefaultFont,
text_halign,
text_valign,
db::DFTrans (db::DFTrans::r0), 0, 0, 0, bitmap);
}
}
/**
* @brief Draws an ellipse with the given parameters
*
@ -417,56 +491,53 @@ draw_ellipse (const db::DPoint &q1,
// produce polygon stuff
double rx = fabs ((q2 - q1).x () * 0.5);
double ry = fabs ((q2 - q1).y () * 0.5);
db::DPoint c = q1 + (q2 - q1) * 0.5;
db::DPolygon p;
std::vector<db::DPoint> pts;
pts.reserve (npoints);
if (sel) {
rx += sel_width * 0.5;
ry += sel_width * 0.5;
}
double da = M_PI * 2.0 / double (npoints);
for (int i = 0; i < npoints; ++i) {
double a = da * i;
pts.push_back (c + db::DVector (rx * cos (a), ry * sin (a)));
}
p.assign_hull (pts.begin (), pts.end ());
if (sel) {
double rx = fabs ((q2 - q1).x () * 0.5);
double ry = fabs ((q2 - q1).y () * 0.5);
db::DPoint c = q1 + (q2 - q1) * 0.5;
pts.clear ();
db::DPolygon p;
std::vector<db::DPoint> pts;
pts.reserve (npoints);
if (sel) {
rx += sel_width * 0.5;
ry += sel_width * 0.5;
}
double da = M_PI * 2.0 / double (npoints);
rx -= sel_width;
ry -= sel_width;
for (int i = 0; i < npoints; ++i) {
double a = da * i;
pts.push_back (c + db::DVector (rx * cos (a), ry * sin (a)));
}
p.assign_hull (pts.begin (), pts.end ());
p.insert_hole (pts.begin (), pts.end ());
if (sel) {
renderer.draw (p, bitmap, bitmap, 0, 0);
pts.clear ();
rx -= sel_width;
ry -= sel_width;
for (int i = 0; i < npoints; ++i) {
double a = da * i;
pts.push_back (c + db::DVector (rx * cos (a), ry * sin (a)));
}
p.insert_hole (pts.begin (), pts.end ());
renderer.draw (p, bitmap, bitmap, 0, 0);
} else {
for (db::DPolygon::polygon_edge_iterator e = p.begin_edge (); ! e.at_end (); ++e) {
renderer.draw (*e, 0, bitmap, 0, 0);
}
} else {
for (db::DPolygon::polygon_edge_iterator e = p.begin_edge (); ! e.at_end (); ++e) {
renderer.draw (*e, 0, bitmap, 0, 0);
}
}
}
}
void
@ -483,38 +554,64 @@ draw_ruler (const ant::Object &ruler, const db::DCplxTrans &trans, bool sel, lay
double mu = double (min_tick_spc) / trans.ctrans (1.0);
if (ruler.outline () == Object::OL_diag) {
draw_ruler (q1, q2, lu, mu, ruler.text (), sel, q2.x () < q1.x (), ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
draw_ruler (q1, q2, lu, mu, sel, q2.x () < q1.x (), ruler.style (), bitmap, renderer);
draw_text (q1, q2, lu, ruler.text (), q2.x () < q1.x (), ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
}
if ((!xy_swapped && (ruler.outline () == Object::OL_xy || ruler.outline () == Object::OL_diag_xy)) ||
( xy_swapped && (ruler.outline () == Object::OL_yx || ruler.outline () == Object::OL_diag_yx))) {
bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ());
if (ruler.outline () == Object::OL_diag_xy || ruler.outline () == Object::OL_diag_yx) {
draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
draw_ruler (q1, q2, lu, mu, sel, !r, ruler.style (), bitmap, renderer);
draw_text (q1, q2, lu, ruler.text (), !r, ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
}
draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, sel, r, ruler.style (), bitmap, renderer);
draw_text (q1, db::DPoint (q2.x (), q1.y ()), lu, ruler.text_x (trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, sel, r, ruler.style (), bitmap, renderer);
draw_text (db::DPoint (q2.x (), q1.y ()), q2, lu, ruler.text_y (trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
}
if ((!xy_swapped && (ruler.outline () == Object::OL_yx || ruler.outline () == Object::OL_diag_yx)) ||
( xy_swapped && (ruler.outline () == Object::OL_xy || ruler.outline () == Object::OL_diag_xy))) {
bool r = (q2.x () > q1.x ()) ^ (q2.y () > q1.y ());
if (ruler.outline () == Object::OL_diag_xy || ruler.outline () == Object::OL_diag_yx) {
draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
draw_ruler (q1, q2, lu, mu, sel, !r, ruler.style (), bitmap, renderer);
draw_text (q1, q2, lu, ruler.text (), !r, ruler.style (), ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
}
draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_auto, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, sel, r, ruler.style (), bitmap, renderer);
draw_text (q1, db::DPoint (q1.x (), q2.y ()), lu, ruler.text_y (trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, sel, r, ruler.style (), bitmap, renderer);
draw_text (db::DPoint (q1.x (), q2.y ()), q2, lu, ruler.text_x (trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
}
if (ruler.outline () == Object::OL_box) {
bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ());
draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, ruler.text_y (trans.fp_trans ()), sel, r, ruler.style (), ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, "", sel, !r, ruler.style (), ant::Object::POS_center, ant::Object::AL_auto, ant::Object::AL_auto, bitmap, renderer);
draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, "", sel, !r, ruler.style (), ant::Object::POS_center, ant::Object::AL_auto, ant::Object::AL_auto, bitmap, renderer);
draw_ruler (q1, q2, lu, mu, ruler.text (), sel, !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, sel, r, ruler.style (), bitmap, renderer);
draw_text (q1, db::DPoint (q2.x (), q1.y ()), lu, ruler.text_x (trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, sel, r, ruler.style (), bitmap, renderer);
draw_text (db::DPoint (q2.x (), q1.y ()), q2, lu, ruler.text_y (trans.fp_trans ()), r, ruler.style (), ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
draw_ruler (q1, db::DPoint (q1.x (), q2.y ()), lu, mu, sel, !r, ruler.style (), bitmap, renderer);
draw_ruler (db::DPoint (q1.x (), q2.y ()), q2, lu, mu, sel, !r, ruler.style (), bitmap, renderer);
draw_text (q1, q2, lu, ruler.text (), !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
} else if (ruler.outline () == Object::OL_ellipse) {
draw_ruler (q1, db::DPoint (q2.x (), q1.y ()), lu, mu, ruler.text_x (trans.fp_trans ()), sel, false, ant::Object::STY_none, ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
draw_ruler (db::DPoint (q2.x (), q1.y ()), q2, lu, mu, ruler.text_y (trans.fp_trans ()), sel, false, ant::Object::STY_none, ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
draw_ruler (q1, q2, lu, mu, ruler.text (), sel, false, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
bool r = (q2.x () > q1.x ()) ^ (q2.y () < q1.y ());
draw_text (q1, db::DPoint (q2.x (), q1.y ()), lu, ruler.text_x (trans.fp_trans ()), r, ant::Object::STY_none, ant::Object::POS_center, ruler.xlabel_xalign (), ruler.xlabel_yalign (), bitmap, renderer);
draw_text (db::DPoint (q2.x (), q1.y ()), q2, lu, ruler.text_y (trans.fp_trans ()), r, ant::Object::STY_none, ant::Object::POS_center, ruler.ylabel_xalign (), ruler.ylabel_yalign (), bitmap, renderer);
draw_text (q1, q2, lu, ruler.text (), !r, ant::Object::STY_none, ruler.main_position (), ruler.main_xalign (), ruler.main_yalign (), bitmap, renderer);
draw_ellipse (q1, q2, lu, sel, bitmap, renderer);
}
}
@ -818,26 +915,38 @@ dragging_what (const ant::Object *robj, const db::DBox &search_dbox, ant::Servic
{
db::DPoint p12, p21;
bool has_p12 = false, has_p21 = false;
db::DPoint p11 = robj->p1 (), p22 = robj->p2 ();
db::DPoint c = p11 + (p22 - p11) * 0.5;
if (robj->outline () == ant::Object::OL_xy || robj->outline () == ant::Object::OL_diag_xy || robj->outline () == ant::Object::OL_box) {
p12 = db::DPoint (robj->p2 ().x (), robj->p1 ().y ());
has_p12 = true;
}
if (robj->outline () == ant::Object::OL_yx || robj->outline () == ant::Object::OL_diag_yx || robj->outline () == ant::Object::OL_box) {
p21 = db::DPoint (robj->p1 ().x (), robj->p2 ().y ());
has_p21 = true;
}
// HINT: this was implemented returning a std::pair<MoveMode, db::DPoint>, but
if (robj->outline () == ant::Object::OL_ellipse) {
db::DVector d = (p22 - p11) * 0.5;
p12 = c + db::DVector (d.x (), -d.y ());
p21 = c + db::DVector (-d.x (), d.y ());
has_p12 = true;
has_p21 = true;
}
// HINT: this was implemented returning a std::pair<MoveMode, db::DPoint>, but
// I was not able to get it to work in gcc 4.1.2 in -O3 mode ...
if (search_dbox.contains (robj->p1 ())) {
p1 = robj->p2 ();
if (search_dbox.contains (p11)) {
p1 = p11;
mode = ant::Service::MoveP1;
return true;
}
if (search_dbox.contains (robj->p2 ())) {
p1 = robj->p1 ();
if (search_dbox.contains (p22)) {
p1 = p22;
mode = ant::Service::MoveP2;
return true;
}
@ -851,28 +960,33 @@ dragging_what (const ant::Object *robj, const db::DBox &search_dbox, ant::Servic
mode = ant::Service::MoveP21;
return true;
}
if (has_p12 && search_dbox.touches (db::DBox (p12, robj->p2 ()))) {
if (has_p12 && search_dbox.touches (db::DBox (p12, p22))) {
p1 = db::DPoint (p12.x (), search_dbox.center ().y ());
mode = ant::Service::MoveP2X;
return true;
}
if (has_p21 && search_dbox.touches (db::DBox (p21, robj->p1 ()))) {
if (has_p21 && search_dbox.touches (db::DBox (p21, p11))) {
p1 = db::DPoint (p21.x (), search_dbox.center ().y ());
mode = ant::Service::MoveP1X;
return true;
}
if (has_p12 && search_dbox.touches (db::DBox (p12, robj->p1 ()))) {
if (has_p12 && search_dbox.touches (db::DBox (p12, p11))) {
p1 = db::DPoint (search_dbox.center ().x (), p12.y ());
mode = ant::Service::MoveP1Y;
return true;
}
if (has_p21 && search_dbox.touches (db::DBox (p21, robj->p2 ()))) {
if (has_p21 && search_dbox.touches (db::DBox (p21, p22))) {
p1 = db::DPoint (search_dbox.center ().x (), p21.y ());
mode = ant::Service::MoveP2Y;
return true;
}
if ((robj->outline () == ant::Object::OL_diag || robj->outline () == ant::Object::OL_diag_xy || robj->outline () == ant::Object::OL_diag_yx)
&& db::DEdge (robj->p1 (), robj->p2 ()).distance_abs (search_dbox.center ()) <= search_dbox.width () * 0.5) {
&& db::DEdge (p11, p22).distance_abs (search_dbox.center ()) <= search_dbox.width () * 0.5) {
p1 = search_dbox.center ();
mode = ant::Service::MoveRuler;
return true;
}
if ((robj->outline () == ant::Object::OL_box || robj->outline () == ant::Object::OL_ellipse) && search_dbox.inside (db::DBox (p11, p22))) {
p1 = search_dbox.center ();
mode = ant::Service::MoveRuler;
return true;
@ -1520,6 +1634,33 @@ Service::clear_selection ()
static bool
is_selected (const ant::Object &ruler, const db::DPoint &pos, double enl, double &distance)
{
if (ruler.outline () == ant::Object::OL_ellipse) {
// special handling of the (non-degenerated) ellipse case
db::DBox b (ruler.p1 (), ruler.p2 ());
if (b.height () > 1e-6 && b.width () > 1e-6) {
double dx = (pos.x () - b.center ().x ()) / (b.width () * 0.5);
double dy = (pos.y () - b.center ().y ()) / (b.height () * 0.5);
double dd = sqrt (dx * dx + dy * dy);
if (dd > 1e-6) {
// ref is the cutpoint between the ray between pos and the ellipse center and the ellipse itself
db::DPoint ref = b.center () + db::DVector (dx * b.width () * 0.5 / dd, dy * b.height () * 0.5 / dd);
double d = ref.distance (pos);
if (d < enl) {
distance = d;
return true;
}
}
return false;
}
}
db::DBox b (ruler.p1 (), ruler.p2 ());
// enlarge this box by some pixels
@ -1539,13 +1680,15 @@ is_selected (const ant::Object &ruler, const db::DPoint &pos, double enl, double
}
if (ruler.outline () == ant::Object::OL_xy ||
ruler.outline () == ant::Object::OL_diag_xy ||
ruler.outline () == ant::Object::OL_box) {
ruler.outline () == ant::Object::OL_box ||
ruler.outline () == ant::Object::OL_ellipse) {
edges [nedges++] = db::DEdge (ruler.p1 (), db::DPoint (ruler.p2 ().x (), ruler.p1 ().y ()));
edges [nedges++] = db::DEdge (db::DPoint (ruler.p2 ().x (), ruler.p1 ().y ()), ruler.p2 ());
}
if (ruler.outline () == ant::Object::OL_yx ||
ruler.outline () == ant::Object::OL_diag_yx ||
ruler.outline () == ant::Object::OL_box) {
ruler.outline () == ant::Object::OL_box ||
ruler.outline () == ant::Object::OL_ellipse) {
edges [nedges++] = db::DEdge (ruler.p1 (), db::DPoint (ruler.p1 ().x (), ruler.p2 ().y ()));
edges [nedges++] = db::DEdge (db::DPoint (ruler.p1 ().x (), ruler.p2 ().y ()), ruler.p2 ());
}

View File

@ -289,7 +289,7 @@ Template::to_string (const std::vector<Template> &v)
r += tl::to_word_or_quoted_string (t->fmt_y ());
r += ",";
r += "pos=";
r += "position=";
ant::PositionConverter pc;
r += pc.to_string (t->main_position ());
r += ",";