("1_6", list(range(277,346)), minor_versions("1.6" , 10)),
("2_0", list(range(346,414)), minor_versions("2.0" , 8)),
("2_1", list(range(414,475)), minor_versions("2.1" , 0)),
- ("2_2", list(range(475,497)), minor_versions("2.2" , 0))
+ ("2_2", list(range(475,498)), minor_versions("2.2" , 0))
]
####################################################################
'''
+import re
import string
from parser_tools import find_token, find_end_of_inset
from unicode_symbols import unicode_reps
return (percent, slen)
+def length_in_bp(length):
+ " Convert a length in LyX format to its value in bp units "
+
+ em_width = 10.0 / 72.27 # assume 10pt font size
+ text_width = 8.27 / 1.7 # assume A4 with default margins
+ # scale factors are taken from Length::inInch()
+ scales = {"bp" : 1.0,
+ "cc" : (72.0 / (72.27 / (12.0 * 0.376 * 2.845))),
+ "cm" : (72.0 / 2.54),
+ "dd" : (72.0 / (72.27 / (0.376 * 2.845))),
+ "em" : (72.0 * em_width),
+ "ex" : (72.0 * em_width * 0.4305),
+ "in" : 72.0,
+ "mm" : (72.0 / 25.4),
+ "mu" : (72.0 * em_width / 18.0),
+ "pc" : (72.0 / (72.27 / 12.0)),
+ "pt" : (72.0 / (72.27)),
+ "sp" : (72.0 / (72.27 * 65536.0)),
+ "text%" : (72.0 * text_width / 100.0),
+ "col%" : (72.0 * text_width / 100.0), # assume 1 column
+ "page%" : (72.0 * text_width * 1.7 / 100.0),
+ "line%" : (72.0 * text_width / 100.0),
+ "theight%" : (72.0 * text_width * 1.787 / 100.0),
+ "pheight%" : (72.0 * text_width * 2.2 / 100.0)}
+
+ rx = re.compile(r'^\s*([^a-zA-Z%]+)([a-zA-Z%]+)\s*$')
+ m = rx.match(length)
+ if not m:
+ document.warning("Invalid length value: " + length + ".")
+ return 0
+ value = m.group(1)
+ unit = m.group(2)
+ if not unit in scales.keys():
+ document.warning("Unknown length unit: " + unit + ".")
+ return value
+ return "%g" % (float(value) * scales[unit])
+
+
def revert_flex_inset(lines, name, LaTeXname):
" Convert flex insets to TeX code "
i = 0
# find_token_backwards, is_in_inset, get_value, get_quoted_value, \
# del_token, check_token, get_option_value
-from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, lyx2latex#, \
+from lyx2lyx_tools import add_to_preamble, put_cmd_in_ert, lyx2latex, \
+ length_in_bp#, \
# insert_to_preamble, latex_length, revert_flex_inset, \
# revert_font_attrs, hex2ratio, str2bool
i = j + 1
+def convert_revert_external_bbox(document, forward):
+ " add units to bounding box of external insets "
+
+ rx = re.compile(r'^\s*boundingBox\s+\S+\s+\S+\s+\S+\s+\S+\s*$')
+ i = 0
+ while True:
+ i = find_token(document.body, "\\begin_inset External", i)
+ if i == -1:
+ break
+ j = find_end_of_inset(document.body, i)
+ if j == -1:
+ document.warning("Malformed LyX document: Can't find end of external inset at line " + str(i))
+ i += 1
+ continue
+ k = find_re(document.body, rx, i, j)
+ if k == -1:
+ i = j + 1
+ continue
+ tokens = document.body[k].split()
+ if forward:
+ for t in range(1, 5):
+ tokens[t] += "bp"
+ else:
+ for t in range(1, 5):
+ tokens[t] = length_in_bp(tokens[t])
+ document.body[k] = "\tboundingBox " + tokens[1] + " " + tokens[2] + " " + \
+ tokens[3] + " " + tokens[4]
+ i = j + 1
+
+
+def convert_external_bbox(document):
+ convert_revert_external_bbox(document, True)
+
+
+def revert_external_bbox(document):
+ convert_revert_external_bbox(document, False)
+
+
##
# Conversion hub
#
[493, []],
[494, []],
[495, [convert_subref]],
- [496, [convert_nounzip]]
+ [496, [convert_nounzip]],
+ [497, [convert_external_bbox]]
]
revert = [
+ [496, [revert_external_bbox]],
[495, []], # nothing to do since the noUnzip parameter was optional
[494, [revert_subref]],
[493, [revert_jss]],
connect(ytED, SIGNAL(textChanged(QString)), this, SLOT(bbChanged()));
connect(xlED, SIGNAL(textChanged(QString)), this, SLOT(bbChanged()));
connect(ybED, SIGNAL(textChanged(QString)), this, SLOT(bbChanged()));
+ connect(xrUnitCO, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(bbChanged()));
+ connect(ytUnitCO, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(bbChanged()));
+ connect(xlUnitCO, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(bbChanged()));
+ connect(ybUnitCO, SIGNAL(selectionChanged(lyx::Length::UNIT)),
+ this, SLOT(bbChanged()));
connect(draftCB, SIGNAL(clicked()), this, SLOT(change_adaptor()));
QIntValidator * validator = new QIntValidator(displayscaleED);
angleED->setValidator(new QDoubleValidator(-360, 360, 2, angleED));
- xlED->setValidator(new QIntValidator(xlED));
- ybED->setValidator(new QIntValidator(ybED));
- xrED->setValidator(new QIntValidator(xrED));
- ytED->setValidator(new QIntValidator(ytED));
+ xlED->setValidator(unsignedLengthValidator(xlED));
+ ybED->setValidator(unsignedLengthValidator(ybED));
+ xrED->setValidator(unsignedLengthValidator(xrED));
+ ytED->setValidator(unsignedLengthValidator(ytED));
widthED->setValidator(unsignedLengthValidator(widthED));
heightED->setValidator(unsignedLengthValidator(heightED));
bc().addReadOnly(xlED);
bc().addReadOnly(xrED);
bc().addReadOnly(ybED);
+ bc().addReadOnly(ytUnitCO);
+ bc().addReadOnly(xlUnitCO);
+ bc().addReadOnly(xrUnitCO);
+ bc().addReadOnly(ybUnitCO);
bc().addReadOnly(extraFormatCO);
bc().addReadOnly(extraED);
bb = "0 0 " + convert<string>(width) + ' ' + convert<string>(height);
}
- xlED->setText(toqstr(token(bb, ' ', 0)));
- ybED->setText(toqstr(token(bb, ' ', 1)));
- xrED->setText(toqstr(token(bb, ' ', 2)));
- ytED->setText(toqstr(token(bb, ' ', 3)));
+ doubleToWidget(xlED, token(bb, ' ', 0));
+ doubleToWidget(ybED, token(bb, ' ', 1));
+ doubleToWidget(xrED, token(bb, ' ', 2));
+ doubleToWidget(ytED, token(bb, ' ', 3));
+ // the values from the file always have the bigpoint-unit bp
+ xlUnitCO->setCurrentIndex(0);
+ ybUnitCO->setCurrentIndex(0);
+ xrUnitCO->setCurrentIndex(0);
+ ytUnitCO->setCurrentIndex(0);
bbChanged_ = false;
}
void setCrop(QCheckBox & clipCB,
QLineEdit & xlED, QLineEdit & ybED,
QLineEdit & xrED, QLineEdit & ytED,
+ LengthCombo & xlUnitCO, LengthCombo & ybUnitCO,
+ LengthCombo & xrUnitCO, LengthCombo & ytUnitCO,
external::ClipData const & data)
{
clipCB.setChecked(data.clip);
- graphics::BoundingBox const & bbox = data.bbox;
- xlED.setText(QString::number(bbox.xl));
- ybED.setText(QString::number(bbox.yb));
- xrED.setText(QString::number(bbox.xr));
- ytED.setText(QString::number(bbox.yt));
+ Length::UNIT const default_unit = data.bbox.xl.zero() ?
+ Length::defaultUnit() : data.bbox.xl.unit();
+ lengthToWidgets(&xlED, &xlUnitCO, data.bbox.xl, default_unit);
+ lengthToWidgets(&ybED, &ybUnitCO, data.bbox.yb, default_unit);
+ lengthToWidgets(&xrED, &xrUnitCO, data.bbox.xr, default_unit);
+ lengthToWidgets(&ytED, &ytUnitCO, data.bbox.yt, default_unit);
}
QCheckBox const & clipCB,
QLineEdit const & xlED, QLineEdit const & ybED,
QLineEdit const & xrED, QLineEdit const & ytED,
+ LengthCombo const & xlUnitCO, LengthCombo const & ybUnitCO,
+ LengthCombo const & xrUnitCO, LengthCombo const & ytUnitCO,
bool bb_changed)
{
data.clip = clipCB.isChecked();
if (!bb_changed)
return;
- data.bbox.xl = xlED.text().toInt();
- data.bbox.yb = ybED.text().toInt();
- data.bbox.xr = xrED.text().toInt();
- data.bbox.yt = ytED.text().toInt();
+ data.bbox.xl = Length(widgetsToLength(&xlED, &xlUnitCO));
+ data.bbox.yb = Length(widgetsToLength(&ybED, &ybUnitCO));
+ data.bbox.xr = Length(widgetsToLength(&xrED, &xrUnitCO));
+ data.bbox.yt = Length(widgetsToLength(&ytED, &ytUnitCO));
}
setSize(*widthED, *widthUnitCO, *heightED, *heightUnitCO,
*aspectratioCB, params_.resizedata);
- setCrop(*clipCB, *xlED, *ybED, *xrED, *ytED, params_.clipdata);
+ setCrop(*clipCB, *xlED, *ybED, *xrED, *ytED,
+ *xlUnitCO, *ybUnitCO, *xrUnitCO, *ytUnitCO, params_.clipdata);
bbChanged_ = !params_.clipdata.bbox.empty();
isValid();
*heightED, *heightUnitCO, *aspectratioCB, usingScale());
if (cropGB->isEnabled())
- getCrop(params_.clipdata, *clipCB, *xlED, *ybED,
- *xrED, *ytED, bbChanged_);
+ getCrop(params_.clipdata, *clipCB, *xlED, *ybED, *xrED, *ytED,
+ *xlUnitCO, *ybUnitCO, *xrUnitCO, *ytUnitCO, bbChanged_);
if (optionsGB->isEnabled()) {
MapType::const_iterator it = extra_.begin();
#if QT_VERSION >= 0x050000
double const pixelRatio = is_transformed_ ? transformed_.devicePixelRatio() : original_.devicePixelRatio();
- int const new_width = static_cast<int>((params.bb.xr - params.bb.xl) * pixelRatio);
- int const new_height = static_cast<int>((params.bb.yt - params.bb.yb) * pixelRatio);
+ int const new_width = static_cast<int>((params.bb.xr.inBP() - params.bb.xl.inBP()) * pixelRatio);
+ int const new_height = static_cast<int>((params.bb.yt.inBP() - params.bb.yb.inBP()) * pixelRatio);
#else
- int const new_width = static_cast<int>((params.bb.xr - params.bb.xl));
- int const new_height = static_cast<int>((params.bb.yt - params.bb.yb));
+ int const new_width = static_cast<int>((params.bb.xr.inBP() - params.bb.xl.inBP()));
+ int const new_height = static_cast<int>((params.bb.yt.inBP() - params.bb.yb.inBP()));
#endif
QImage const & image = is_transformed_ ? transformed_ : original_;
if (new_width == image.width() && new_height == image.height())
return false;
- int const xoffset_l = params.bb.xl;
- int const yoffset_t = (image.height() > int(params.bb.yt))
- ? image.height() - params.bb.yt : 0;
+ int const xoffset_l = params.bb.xl.inBP();
+ int const yoffset_t = (image.height() > params.bb.yt.inBP())
+ ? image.height() - params.bb.yt.inBP() : 0;
transformed_ = image.copy(xoffset_l, yoffset_t, new_width, new_height);
return true;
</property>
</widget>
</item>
- <item row="3" column="1" colspan="2" >
+ <item row="3" column="1" >
<widget class="QLineEdit" name="xlED" >
<property name="toolTip" >
<string/>
</property>
</widget>
</item>
- <item row="2" column="1" colspan="2" >
+ <item row="2" column="1" >
<widget class="QLineEdit" name="xrED" />
</item>
+ <item row="2" column="2" >
+ <widget class="lyx::frontend::LengthCombo" name="xrUnitCO" />
+ </item>
+ <item row="2" column="4" >
+ <widget class="lyx::frontend::LengthCombo" name="ytUnitCO" />
+ </item>
+ <item row="3" column="2" >
+ <widget class="lyx::frontend::LengthCombo" name="xlUnitCO" />
+ </item>
+ <item row="3" column="4" >
+ <widget class="lyx::frontend::LengthCombo" name="ybUnitCO" />
+ </item>
</layout>
</widget>
</item>
#include "GraphicsParams.h"
-#include "Length.h"
-
#include <cstdlib>
#include <sstream>
ostream & operator<<(ostream & os, BoundingBox const & bb)
{
- os << bb.xl << ' ' << bb.yb << ' ' << bb.xr << ' ' << bb.yt;
+ os << bb.xl.asString() << ' ' << bb.yb.asString() << ' '
+ << bb.xr.asString() << ' ' << bb.yt.asString();
return os;
}
BoundingBox::BoundingBox()
- : xl(0), yb(0), xr(0), yt(0)
{}
BoundingBox::BoundingBox(string const & bb)
- : xl(0), yb(0), xr(0), yt(0)
{
if (bb.empty())
return;
string a, b, c, d;
is >> a >> b >> c >> d;
+ Length xl_tmp = Length(a);
+ if (xl_tmp.value() < 0)
+ xl_tmp = Length(-xl_tmp.value(), xl_tmp.unit());
+ Length yb_tmp = Length(b);
+ if (yb_tmp.value() < 0)
+ yb_tmp = Length(-yb_tmp.value(), yb_tmp.unit());
+ Length xr_tmp = Length(c);
+ if (xr_tmp.value() < 0)
+ xr_tmp = Length(-xr_tmp.value(), xr_tmp.unit());
+ Length yt_tmp = Length(d);
+ if (yt_tmp.value() < 0)
+ yt_tmp = Length(-yt_tmp.value(), yt_tmp.unit());
+
// inBP returns the length in Postscript points.
// Note further that there are 72 Postscript pixels per inch.
- unsigned int const xl_tmp = abs(Length(a).inBP());
- unsigned int const yb_tmp = abs(Length(b).inBP());
- unsigned int const xr_tmp = abs(Length(c).inBP());
- unsigned int const yt_tmp = abs(Length(d).inBP());
-
- if (xr_tmp <= xl_tmp || yt_tmp <= yb_tmp)
+ if (xr_tmp.inBP() <= xl_tmp.inBP() || yt_tmp.inBP() <= yb_tmp.inBP())
return;
xl = xl_tmp;
bool BoundingBox::empty() const
{
- return (!xl && !yb && !xr && !yt);
+ return xl.zero() && yb.zero() && xr.zero() && yt.zero();
}
#ifndef GRAPHICSPARAMS_H
#define GRAPHICSPARAMS_H
+#include "Length.h"
+
#include "support/FileName.h"
#include <string>
/// 0 0 0 0 is empty!
bool empty() const;
- unsigned int xl;
- unsigned int yb;
- unsigned int xr;
- unsigned int yt;
+ Length xl;
+ Length yb;
+ Length xr;
+ Length yt;
};
bool operator==(BoundingBox const &, BoundingBox const &);
bool operator!=(BoundingBox const &, BoundingBox const &);
+/// output bounding box in LyX file format
std::ostream & operator<<(std::ostream &, BoundingBox const &);
ostringstream os;
if (!data.bbox.empty())
- os << "bb=" << data.bbox << ',';
+ os << "bb=" << data.bbox.xl.asLatexString() << ' '
+ << data.bbox.yb.asLatexString() << ' '
+ << data.bbox.xr.asLatexString() << ' '
+ << data.bbox.yt.asLatexString() << ',';
if (data.clip)
os << "clip,";
return os.str();
public:
ClipData() : clip(false) {}
+ /// The bounding box
graphics::BoundingBox bbox;
+ /// clip image
bool clip;
};
case EX_BOUNDINGBOX:
lex.next();
- clipdata.bbox.xl = lex.getInteger();
+ clipdata.bbox.xl = Length(lex.getString());
lex.next();
- clipdata.bbox.yb = lex.getInteger();
+ clipdata.bbox.yb = Length(lex.getString());
lex.next();
- clipdata.bbox.xr = lex.getInteger();
+ clipdata.bbox.xr = Length(lex.getString());
lex.next();
- clipdata.bbox.yt = lex.getInteger();
+ clipdata.bbox.yt = Length(lex.getString());
break;
case EX_CLIP:
unsigned int const bb_orig_yb = convert<unsigned int>(token(tmp, ' ', 1));
// new pars.bb values must be >= zero
- if (pars.bb.xl > bb_orig_xl)
- pars.bb.xl -= bb_orig_xl;
+ if (pars.bb.xl.inBP() > static_cast<int>(bb_orig_xl))
+ pars.bb.xl = Length(pars.bb.xl.inBP() - bb_orig_xl, Length::BP);
else
- pars.bb.xl = 0;
+ pars.bb.xl = Length();
- if (pars.bb.xr > bb_orig_xl)
- pars.bb.xr -= bb_orig_xl;
+ if (pars.bb.xr.inBP() > static_cast<int>(bb_orig_xl))
+ pars.bb.xr = Length(pars.bb.xr.inBP() - bb_orig_xl, Length::BP);
else
- pars.bb.xr = 0;
+ pars.bb.xr = Length();
- if (pars.bb.yb > bb_orig_yb)
- pars.bb.yb -= bb_orig_yb;
+ if (pars.bb.yb.inBP() > static_cast<int>(bb_orig_yb))
+ pars.bb.yb = Length(pars.bb.yb.inBP() - bb_orig_yb, Length::BP);
else
- pars.bb.yb = 0;
+ pars.bb.yb = Length();
- if (pars.bb.yt > bb_orig_yb)
- pars.bb.yt -= bb_orig_yb;
+ if (pars.bb.yt.inBP() > static_cast<int>(bb_orig_yb))
+ pars.bb.yt = Length(pars.bb.yt.inBP() - bb_orig_yb, Length::BP);
else
- pars.bb.yt = 0;
+ pars.bb.yt = Length();
}
// Paranoia check.
- int const width = pars.bb.xr - pars.bb.xl;
- int const height = pars.bb.yt - pars.bb.yb;
+ int const width = pars.bb.xr.inBP() - pars.bb.xl.inBP();
+ int const height = pars.bb.yt.inBP() - pars.bb.yb.inBP();
if (width < 0 || height < 0) {
- pars.bb.xl = 0;
- pars.bb.xr = 0;
- pars.bb.yb = 0;
- pars.bb.yt = 0;
+ pars.bb.xl = Length();
+ pars.bb.xr = Length();
+ pars.bb.yb = Length();
+ pars.bb.yt = Length();
}
}
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
#LyX file created by tex2lyx 2.2
-\lyxformat 496
+\lyxformat 497
\begin_document
\begin_header
\origin roundtrip
// Do not remove the comment below, so we get merge conflict in
// independent branches. Instead add your own.
-#define LYX_FORMAT_LYX 496 // gb: remove noUnzip parameter of InsetGraphics
-#define LYX_FORMAT_TEX2LYX 496
+#define LYX_FORMAT_LYX 497 // gb: bounding box of external insets supports units
+#define LYX_FORMAT_TEX2LYX 497
#if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX
#ifndef _MSC_VER